@anywalletkit/protocol-swap2-chainflip 0.0.0-stage → 0.2.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +202 -0
- package/README.md +81 -2
- package/dist/activity.cjs +62 -0
- package/dist/activity.cjs.map +1 -0
- package/dist/activity.d.cts +12 -0
- package/dist/activity.d.ts +12 -0
- package/dist/activity.js +10 -0
- package/dist/activity.js.map +1 -0
- package/dist/chunk-GXHOO3CT.js +54 -0
- package/dist/chunk-GXHOO3CT.js.map +1 -0
- package/dist/chunk-H6GJVVWS.js +22 -0
- package/dist/chunk-H6GJVVWS.js.map +1 -0
- package/dist/chunk-R6EYDH5N.js +142 -0
- package/dist/chunk-R6EYDH5N.js.map +1 -0
- package/dist/chunk-XF7BEBET.js +27 -0
- package/dist/chunk-XF7BEBET.js.map +1 -0
- package/dist/chunk-ZFCYBCOT.js +223 -0
- package/dist/chunk-ZFCYBCOT.js.map +1 -0
- package/dist/codec.cjs +162 -0
- package/dist/codec.cjs.map +1 -0
- package/dist/codec.d.cts +60 -0
- package/dist/codec.d.ts +60 -0
- package/dist/codec.js +25 -0
- package/dist/codec.js.map +1 -0
- package/dist/config.cjs +74 -0
- package/dist/config.cjs.map +1 -0
- package/dist/config.d.cts +46 -0
- package/dist/config.d.ts +46 -0
- package/dist/config.js +19 -0
- package/dist/config.js.map +1 -0
- package/dist/index.cjs +447 -0
- package/dist/index.cjs.map +1 -0
- package/dist/index.d.cts +10 -0
- package/dist/index.d.ts +10 -0
- package/dist/index.js +56 -0
- package/dist/index.js.map +1 -0
- package/dist/protocol.cjs +426 -0
- package/dist/protocol.cjs.map +1 -0
- package/dist/protocol.d.cts +16 -0
- package/dist/protocol.d.ts +16 -0
- package/dist/protocol.js +11 -0
- package/dist/protocol.js.map +1 -0
- package/dist/provider.cjs +412 -0
- package/dist/provider.cjs.map +1 -0
- package/dist/provider.d.cts +12 -0
- package/dist/provider.d.ts +12 -0
- package/dist/provider.js +10 -0
- package/dist/provider.js.map +1 -0
- package/module.json +20 -0
- package/package.json +90 -3
|
@@ -0,0 +1,426 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __defProp = Object.defineProperty;
|
|
3
|
+
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
4
|
+
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
5
|
+
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
6
|
+
var __export = (target, all) => {
|
|
7
|
+
for (var name in all)
|
|
8
|
+
__defProp(target, name, { get: all[name], enumerable: true });
|
|
9
|
+
};
|
|
10
|
+
var __copyProps = (to, from, except, desc) => {
|
|
11
|
+
if (from && typeof from === "object" || typeof from === "function") {
|
|
12
|
+
for (let key of __getOwnPropNames(from))
|
|
13
|
+
if (!__hasOwnProp.call(to, key) && key !== except)
|
|
14
|
+
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
|
|
15
|
+
}
|
|
16
|
+
return to;
|
|
17
|
+
};
|
|
18
|
+
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
|
19
|
+
|
|
20
|
+
// src/protocol.ts
|
|
21
|
+
var protocol_exports = {};
|
|
22
|
+
__export(protocol_exports, {
|
|
23
|
+
ChainflipSwap2Protocol: () => ChainflipSwap2Protocol
|
|
24
|
+
});
|
|
25
|
+
module.exports = __toCommonJS(protocol_exports);
|
|
26
|
+
var import_single = require("@anywalletkit/protocol-swap2-core/swap2/single");
|
|
27
|
+
|
|
28
|
+
// src/config.ts
|
|
29
|
+
var CF_CHAINS = {
|
|
30
|
+
"eip155:1": { name: "Ethereum", id: 1, addrTag: 0 },
|
|
31
|
+
"bitcoin:mainnet": { name: "Bitcoin", id: 3, addrTag: 2 },
|
|
32
|
+
"eip155:42161": { name: "Arbitrum", id: 4, addrTag: 3 },
|
|
33
|
+
"solana:mainnet": { name: "Solana", id: 5, addrTag: 4 },
|
|
34
|
+
"tron:728126428": { name: "Tron", id: 7, addrTag: 6 }
|
|
35
|
+
};
|
|
36
|
+
var CF_ASSETS = [
|
|
37
|
+
{ chain: "Ethereum", asset: "ETH", id: 1, decimals: 18, token: null, minDeposit: 10n ** 16n },
|
|
38
|
+
{ chain: "Ethereum", asset: "USDC", id: 3, decimals: 6, token: "0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48", minDeposit: 20000000n },
|
|
39
|
+
{ chain: "Ethereum", asset: "USDT", id: 8, decimals: 6, token: "0xdAC17F958D2ee523a2206206994597C13D831ec7", minDeposit: 20000000n },
|
|
40
|
+
{ chain: "Ethereum", asset: "WBTC", id: 14, decimals: 8, token: "0x2260FAC5E5542a773Aa44fBCfeDf7C193bc2C599", minDeposit: 40000n },
|
|
41
|
+
{ chain: "Bitcoin", asset: "BTC", id: 5, decimals: 8, token: null, minDeposit: 40000n },
|
|
42
|
+
{ chain: "Arbitrum", asset: "ETH", id: 6, decimals: 18, token: null, minDeposit: 3900000000000000n },
|
|
43
|
+
{ chain: "Arbitrum", asset: "USDC", id: 7, decimals: 6, token: "0xaf88d065e77c8cC2239327C5EDb3A432268e5831", minDeposit: 10000000n },
|
|
44
|
+
{ chain: "Arbitrum", asset: "USDT", id: 15, decimals: 6, token: "0xFd086bC7CD5C481DCC9C85ebE478A1C0b69FCbb9", minDeposit: 10000000n },
|
|
45
|
+
{ chain: "Solana", asset: "SOL", id: 9, decimals: 9, token: null, minDeposit: 68000000n },
|
|
46
|
+
{ chain: "Solana", asset: "USDC", id: 10, decimals: 6, token: "EPjFWdd5AufqSSqeM2qN1xzybapC8G4wEGGkZwyTDt1v", minDeposit: 10000000n },
|
|
47
|
+
{ chain: "Solana", asset: "USDT", id: 16, decimals: 6, token: "Es9vMFrzaCERmJfrF4H2FYD4KCoNkY11McCe8BenwNYB", minDeposit: 10000000n },
|
|
48
|
+
{ chain: "Tron", asset: "TRX", id: 17, decimals: 6, token: null, minDeposit: 30000000n },
|
|
49
|
+
{ chain: "Tron", asset: "USDT", id: 18, decimals: 6, token: "TR7NHqjeKQxGTCi8q8ZY4pL8otSzgjLj6t", minDeposit: 10000000n }
|
|
50
|
+
];
|
|
51
|
+
var CF_VAULTS = {
|
|
52
|
+
"eip155:1": "0xF5e10380213880111522dd0efD3dbb45b9f62Bcc",
|
|
53
|
+
"eip155:42161": "0x79001a5e762f3bEFC8e5871b42F6734e00498920",
|
|
54
|
+
"tron:728126428": "TEcDijvKSXcfWT7S6rd44H5vNgufm7Y4XC"
|
|
55
|
+
};
|
|
56
|
+
var CF_SOURCE_CHAINS = /* @__PURE__ */ new Set(["eip155:1", "eip155:42161", "tron:728126428"]);
|
|
57
|
+
var CF_API_DEFAULT = "https://chainflip-swap.chainflip.io";
|
|
58
|
+
var sameToken = (chain, a, b) => chain.startsWith("eip155:") ? a.toLowerCase() === b.toLowerCase() : a === b;
|
|
59
|
+
var NATIVE = /* @__PURE__ */ new Set(["", "native", "0x0000000000000000000000000000000000000000"]);
|
|
60
|
+
function cfAsset(chain, token) {
|
|
61
|
+
const c = CF_CHAINS[chain];
|
|
62
|
+
if (!c) return void 0;
|
|
63
|
+
const on = CF_ASSETS.filter((a) => a.chain === c.name);
|
|
64
|
+
if (NATIVE.has(token.toLowerCase())) return on.find((a) => a.token === null);
|
|
65
|
+
return on.find((a) => a.token !== null && sameToken(chain, a.token, token) || a.asset === token.toUpperCase());
|
|
66
|
+
}
|
|
67
|
+
var chainflip = {
|
|
68
|
+
supportsChain: (chain) => !!CF_CHAINS[chain],
|
|
69
|
+
supports: (from, to) => CF_SOURCE_CHAINS.has(from) && !!CF_CHAINS[to] && from !== to
|
|
70
|
+
};
|
|
71
|
+
|
|
72
|
+
// src/activity.ts
|
|
73
|
+
var import_activity = require("@anywalletkit/protocol-swap2-core/activity");
|
|
74
|
+
var CHAINFLIP_MODULE = "@anywalletkit/protocol-swap2-chainflip";
|
|
75
|
+
var same = (chain, a, b) => !!a && (chain.startsWith("eip155:") ? a.toLowerCase() === b.toLowerCase() : a === b);
|
|
76
|
+
var CHAIN_ALIAS = { "tron:0x2b6653dc": "tron:728126428" };
|
|
77
|
+
function describeChainflipActivity(tx, ctx) {
|
|
78
|
+
const vault = CF_VAULTS[CHAIN_ALIAS[tx.chain] ?? tx.chain];
|
|
79
|
+
if (!vault) return null;
|
|
80
|
+
const toVault = same(tx.chain, tx.to, vault) || tx.transfers.some((t) => same(tx.chain, t.to, vault) && ctx.own.has(t.from));
|
|
81
|
+
if (!toVault) return null;
|
|
82
|
+
return (0, import_activity.describeSwapLike)(tx, ctx, { protocol: CHAINFLIP_MODULE, subtitle: "Chainflip", kind: "bridge", counterparty: vault, inSuffix: "via Chainflip" });
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
// src/codec.ts
|
|
86
|
+
var import_base = require("@scure/base");
|
|
87
|
+
var import_sha2 = require("@noble/hashes/sha2.js");
|
|
88
|
+
var import_viem = require("viem");
|
|
89
|
+
var Reader = class {
|
|
90
|
+
constructor(b) {
|
|
91
|
+
this.b = b;
|
|
92
|
+
}
|
|
93
|
+
b;
|
|
94
|
+
i = 0;
|
|
95
|
+
need(n) {
|
|
96
|
+
if (this.i + n > this.b.length) throw new Error(`chainflip codec: truncated at ${this.i} (+${n} of ${this.b.length})`);
|
|
97
|
+
}
|
|
98
|
+
u8() {
|
|
99
|
+
this.need(1);
|
|
100
|
+
return this.b[this.i++];
|
|
101
|
+
}
|
|
102
|
+
bytes(n) {
|
|
103
|
+
this.need(n);
|
|
104
|
+
const out = this.b.slice(this.i, this.i + n);
|
|
105
|
+
this.i += n;
|
|
106
|
+
return out;
|
|
107
|
+
}
|
|
108
|
+
uLE(n) {
|
|
109
|
+
const x = this.bytes(n);
|
|
110
|
+
let v = 0n;
|
|
111
|
+
for (let k = n - 1; k >= 0; k--) v = v << 8n | BigInt(x[k]);
|
|
112
|
+
return v;
|
|
113
|
+
}
|
|
114
|
+
/** SCALE compact integer */
|
|
115
|
+
compact() {
|
|
116
|
+
const first = this.u8();
|
|
117
|
+
const mode = first & 3;
|
|
118
|
+
if (mode === 0) return first >> 2;
|
|
119
|
+
if (mode === 1) return (this.u8() << 8 | first) >> 2;
|
|
120
|
+
if (mode === 2) {
|
|
121
|
+
const rest = Number(this.uLE(3));
|
|
122
|
+
return (rest << 8 | first) >>> 2;
|
|
123
|
+
}
|
|
124
|
+
throw new Error("chainflip codec: big compact integers are not used here");
|
|
125
|
+
}
|
|
126
|
+
done() {
|
|
127
|
+
if (this.i !== this.b.length) throw new Error(`chainflip codec: ${this.b.length - this.i} trailing bytes`);
|
|
128
|
+
}
|
|
129
|
+
};
|
|
130
|
+
var toHex = (b) => `0x${[...b].map((x) => x.toString(16).padStart(2, "0")).join("")}`;
|
|
131
|
+
function fromHex(h) {
|
|
132
|
+
const s = h.startsWith("0x") ? h.slice(2) : h;
|
|
133
|
+
if (s.length % 2 || /[^0-9a-f]/i.test(s)) throw new Error("chainflip codec: not hex");
|
|
134
|
+
return Uint8Array.from(s.match(/../g) ?? [], (x) => Number.parseInt(x, 16));
|
|
135
|
+
}
|
|
136
|
+
function decodeCfParameters(bytes, refundLen) {
|
|
137
|
+
const r = new Reader(bytes);
|
|
138
|
+
const p = readCfParameters(r, refundLen);
|
|
139
|
+
r.done();
|
|
140
|
+
return p;
|
|
141
|
+
}
|
|
142
|
+
function readCfParameters(r, refundLen) {
|
|
143
|
+
const version = r.u8();
|
|
144
|
+
if (version !== 1) throw new Error(`chainflip codec: cf parameters version ${version}`);
|
|
145
|
+
const retryDurationBlocks = Number(r.uLE(4));
|
|
146
|
+
const refundAddress = toHex(r.bytes(refundLen));
|
|
147
|
+
const minPriceX128 = r.uLE(32);
|
|
148
|
+
const refundCcm = r.u8() !== 0;
|
|
149
|
+
if (refundCcm) throw new Error("chainflip codec: refund CCM metadata is not expected");
|
|
150
|
+
const maxOraclePriceSlippageBps = r.u8() ? Number(r.uLE(2)) : null;
|
|
151
|
+
const dca = r.u8() ? { chunks: Number(r.uLE(4)), intervalBlocks: Number(r.uLE(4)) } : null;
|
|
152
|
+
const boostFeeBps = r.u8();
|
|
153
|
+
const broker = { account: toHex(r.bytes(32)), feeBps: Number(r.uLE(2)) };
|
|
154
|
+
const n = r.compact();
|
|
155
|
+
const affiliates = Array.from({ length: n }, () => ({ account: r.u8(), feeBps: Number(r.uLE(2)) }));
|
|
156
|
+
return { version, retryDurationBlocks, refundAddress, minPriceX128, refundCcm, maxOraclePriceSlippageBps, dca, boostFeeBps, broker, affiliates };
|
|
157
|
+
}
|
|
158
|
+
var TAG_LEN = { 0: 20, 1: 32, 2: "vec", 3: 20, 4: 32, 5: 32, 6: 20 };
|
|
159
|
+
function decodeTronNote(note) {
|
|
160
|
+
const r = new Reader(fromHex(note));
|
|
161
|
+
const outputAsset = r.u8();
|
|
162
|
+
const destTag = r.u8();
|
|
163
|
+
const len = TAG_LEN[destTag];
|
|
164
|
+
if (len === void 0) throw new Error(`chainflip codec: unknown address tag ${destTag}`);
|
|
165
|
+
const destAddress = len === "vec" ? r.bytes(r.compact()) : r.bytes(len);
|
|
166
|
+
const ccm = r.u8() !== 0;
|
|
167
|
+
if (ccm) throw new Error("chainflip codec: CCM swaps are not expected");
|
|
168
|
+
const paramsLen = r.compact();
|
|
169
|
+
const start = r.i;
|
|
170
|
+
const params = readCfParameters(r, 20);
|
|
171
|
+
if (r.i - start !== paramsLen) throw new Error(`chainflip codec: cf parameters length ${r.i - start} \u2260 declared ${paramsLen}`);
|
|
172
|
+
r.done();
|
|
173
|
+
return { outputAsset, destTag, destAddress, ccm, params };
|
|
174
|
+
}
|
|
175
|
+
var VAULT_ABI = (0, import_viem.parseAbi)([
|
|
176
|
+
"function xSwapNative(uint32 dstChain, bytes dstAddress, uint32 dstToken, bytes cfParameters) payable",
|
|
177
|
+
"function xSwapToken(uint32 dstChain, bytes dstAddress, uint32 dstToken, address srcToken, uint256 amount, bytes cfParameters)"
|
|
178
|
+
]);
|
|
179
|
+
function decodeEvmVaultCall(data) {
|
|
180
|
+
const d = (0, import_viem.decodeFunctionData)({ abi: VAULT_ABI, data });
|
|
181
|
+
if (d.functionName === "xSwapNative") {
|
|
182
|
+
const [dstChain2, dstAddress2, dstToken2, cf2] = d.args;
|
|
183
|
+
return { native: true, dstChain: dstChain2, dstAddress: fromHex(dstAddress2), dstToken: dstToken2, srcToken: null, amount: null, params: decodeCfParameters(fromHex(cf2), 20) };
|
|
184
|
+
}
|
|
185
|
+
const [dstChain, dstAddress, dstToken, srcToken, amount, cf] = d.args;
|
|
186
|
+
return { native: false, dstChain, dstAddress: fromHex(dstAddress), dstToken, srcToken, amount, params: decodeCfParameters(fromHex(cf), 20) };
|
|
187
|
+
}
|
|
188
|
+
function tronToBytes(address) {
|
|
189
|
+
const b = import_base.base58.decode(address);
|
|
190
|
+
if (b.length !== 25 || b[0] !== 65) throw new Error(`not a Tron address: ${address}`);
|
|
191
|
+
const check = (0, import_sha2.sha256)((0, import_sha2.sha256)(b.subarray(0, 21))).subarray(0, 4);
|
|
192
|
+
if (toHex(check) !== toHex(b.subarray(21))) throw new Error(`bad Tron checksum: ${address}`);
|
|
193
|
+
return b.subarray(1, 21);
|
|
194
|
+
}
|
|
195
|
+
function destAddressBytes(chain, address) {
|
|
196
|
+
if (chain.startsWith("eip155:")) return fromHex(address);
|
|
197
|
+
if (chain.startsWith("tron:")) return tronToBytes(address);
|
|
198
|
+
if (chain.startsWith("solana:")) {
|
|
199
|
+
const b = import_base.base58.decode(address);
|
|
200
|
+
if (b.length !== 32) throw new Error(`not a Solana address: ${address}`);
|
|
201
|
+
return b;
|
|
202
|
+
}
|
|
203
|
+
if (chain.startsWith("bitcoin:")) return new TextEncoder().encode(address);
|
|
204
|
+
throw new Error(`chainflip: no address encoding for ${chain}`);
|
|
205
|
+
}
|
|
206
|
+
var sameBytes = (a, b) => a.length === b.length && a.every((x, i) => x === b[i]);
|
|
207
|
+
function minPriceX128For(amountIn, minOut) {
|
|
208
|
+
return (minOut * 2n ** 128n + amountIn - 1n) / amountIn;
|
|
209
|
+
}
|
|
210
|
+
function minOutOf(amountIn, minPriceX128) {
|
|
211
|
+
return amountIn * minPriceX128 / 2n ** 128n;
|
|
212
|
+
}
|
|
213
|
+
|
|
214
|
+
// src/provider.ts
|
|
215
|
+
var import_util = require("@anywalletkit/protocol-swap2-core/util");
|
|
216
|
+
var import_viem2 = require("viem");
|
|
217
|
+
var QUOTE_TTL_MS = 6e4;
|
|
218
|
+
var RETRY_BLOCKS = 50;
|
|
219
|
+
var MAX_RETRY_BLOCKS = 600;
|
|
220
|
+
var ERC20 = (0, import_viem2.parseAbi)(["function transfer(address to, uint256 amount) returns (bool)"]);
|
|
221
|
+
var INTENT_PREFIX = "cfvault:";
|
|
222
|
+
function chainflipProvider(config = {}) {
|
|
223
|
+
config = Object.freeze({ ...config });
|
|
224
|
+
const base = new URL(config.apiUrl ?? CF_API_DEFAULT).toString().replace(/\/$/, "");
|
|
225
|
+
const call = async (path, init = {}, signal) => {
|
|
226
|
+
for (let attempt = 0; ; attempt++) {
|
|
227
|
+
const res = await fetch(`${base}${path}`, { ...init, headers: { accept: "application/json", ...init.body ? { "content-type": "application/json" } : {}, ...init.headers ?? {} }, signal: signal ?? (0, import_util.timeoutSignal)(12e3) });
|
|
228
|
+
const body = await res.json().catch(() => null);
|
|
229
|
+
if (res.status === 429 && attempt === 0 && !signal?.aborted) {
|
|
230
|
+
await new Promise((r) => setTimeout(r, 1200));
|
|
231
|
+
continue;
|
|
232
|
+
}
|
|
233
|
+
return { ok: res.ok, status: res.status, body };
|
|
234
|
+
}
|
|
235
|
+
};
|
|
236
|
+
const checkParams = (p, want) => {
|
|
237
|
+
if (!sameBytes(fromHex(p.refundAddress), want.refund)) return `refund address ${p.refundAddress} is not the sender`;
|
|
238
|
+
if (p.minPriceX128 < want.minPriceX128) return "minimum price is below the one requested";
|
|
239
|
+
if (p.retryDurationBlocks > MAX_RETRY_BLOCKS) return `retry window ${p.retryDurationBlocks} blocks is too long`;
|
|
240
|
+
if (p.maxOraclePriceSlippageBps !== want.oracle) return "oracle slippage guard differs from the request";
|
|
241
|
+
if (p.dca !== null) return "unexpected DCA parameters";
|
|
242
|
+
if (p.boostFeeBps !== 0) return "unexpected boost fee";
|
|
243
|
+
if (p.broker.feeBps !== 0) return `broker takes ${p.broker.feeBps} bps`;
|
|
244
|
+
if (p.affiliates.length) return "unexpected affiliates";
|
|
245
|
+
return null;
|
|
246
|
+
};
|
|
247
|
+
return {
|
|
248
|
+
name: "chainflip",
|
|
249
|
+
describeActivity: describeChainflipActivity,
|
|
250
|
+
enabled: () => config.enabled ?? true,
|
|
251
|
+
supportsChain: (chain) => chainflip.supportsChain(chain),
|
|
252
|
+
supportsChainPair: (from, to) => chainflip.supports(from, to),
|
|
253
|
+
supportsRoute(from, to) {
|
|
254
|
+
if (!chainflip.supports(from.chain, to.chain)) return false;
|
|
255
|
+
const a = cfAsset(from.chain, from.token), b = cfAsset(to.chain, to.token);
|
|
256
|
+
return !!a && !!b && a.id !== b.id;
|
|
257
|
+
},
|
|
258
|
+
async getQuote(params, signal) {
|
|
259
|
+
const dry = params.dry !== false;
|
|
260
|
+
const refuse = (reason) => {
|
|
261
|
+
params.onRefusal?.(`chainflip: ${reason}`);
|
|
262
|
+
return null;
|
|
263
|
+
};
|
|
264
|
+
if (!chainflip.supports(params.sourceChain, params.destChain)) return refuse(`no vault swap ${params.sourceChain} \u2192 ${params.destChain}`);
|
|
265
|
+
const src = cfAsset(params.sourceChain, params.sourceToken);
|
|
266
|
+
const dst = cfAsset(params.destChain, params.destToken);
|
|
267
|
+
if (!src || !dst) return refuse(`asset not listed (${params.sourceToken} on ${params.sourceChain} \u2192 ${params.destToken} on ${params.destChain})`);
|
|
268
|
+
const amountIn = BigInt(params.amountIn);
|
|
269
|
+
if (amountIn < src.minDeposit) return refuse(`below the minimum deposit (${src.minDeposit} ${src.asset})`);
|
|
270
|
+
let destBytes;
|
|
271
|
+
try {
|
|
272
|
+
destBytes = destAddressBytes(params.destChain, params.destAddress);
|
|
273
|
+
} catch (e) {
|
|
274
|
+
return refuse(e.message);
|
|
275
|
+
}
|
|
276
|
+
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" });
|
|
277
|
+
let q;
|
|
278
|
+
try {
|
|
279
|
+
const r = await call(`/v2/quote?${qs.toString()}`, {}, signal);
|
|
280
|
+
if (!r.ok) return refuse(`quote ${r.status}: ${String(r.body?.message ?? "").slice(0, 160)}`);
|
|
281
|
+
q = r.body?.find((x) => x.type === "REGULAR") ?? r.body?.[0];
|
|
282
|
+
} catch (e) {
|
|
283
|
+
return refuse(`quote failed: ${e.message.slice(0, 160)}`);
|
|
284
|
+
}
|
|
285
|
+
if (!q?.egressAmount || !/^\d+$/.test(q.egressAmount)) return refuse("quote without an egress amount");
|
|
286
|
+
if (q.type && q.type !== "REGULAR") return refuse(`${q.type} quotes are not supported`);
|
|
287
|
+
const expected = BigInt(q.egressAmount);
|
|
288
|
+
const slipBps = params.slippageBps ?? Math.round((q.recommendedSlippageTolerancePercent ?? 1) * 100);
|
|
289
|
+
const byTolerance = expected * BigInt(1e4 - Math.min(9999, Math.max(0, slipBps))) / 10000n;
|
|
290
|
+
const callerFloor = params.minAmountOut !== void 0 ? BigInt(params.minAmountOut) : void 0;
|
|
291
|
+
const minOut = callerFloor === void 0 ? byTolerance : params.slippageBps !== void 0 && byTolerance > callerFloor ? byTolerance : callerFloor;
|
|
292
|
+
if (minOut > expected) return refuse(`floor ${minOut} above the expected output ${expected}`);
|
|
293
|
+
const minPriceX128 = minPriceX128For(amountIn, minOut);
|
|
294
|
+
const guaranteed = minOutOf(amountIn, minPriceX128);
|
|
295
|
+
const oracle = config.maxOraclePriceSlippageBps !== void 0 ? config.maxOraclePriceSlippageBps : q.recommendedLivePriceSlippageTolerancePercent !== void 0 ? Math.round(q.recommendedLivePriceSlippageTolerancePercent * 100) : null;
|
|
296
|
+
const fees = (q.includedFees ?? []).map((f) => ({ type: f.type === "NETWORK" ? "protocol" : f.type === "BROKER" ? "affiliate" : "network", amount: f.amount, token: `${f.chain}:${f.asset}`, included: true, description: `Chainflip ${f.type.toLowerCase()} fee` }));
|
|
297
|
+
const stableUsd = (f) => f.asset === "USDC" || f.asset === "USDT" ? Number(f.amount) / 1e6 : 0;
|
|
298
|
+
const common = {
|
|
299
|
+
provider: "chainflip",
|
|
300
|
+
sourceAmount: params.amountIn,
|
|
301
|
+
destAmount: q.egressAmount,
|
|
302
|
+
minDestAmount: guaranteed.toString(),
|
|
303
|
+
feeUsd: (q.includedFees ?? []).reduce((s, f) => s + stableUsd(f), 0),
|
|
304
|
+
fees,
|
|
305
|
+
etaSeconds: Math.round(q.estimatedDurationSeconds ?? 180),
|
|
306
|
+
reliability: q.lowLiquidityWarning ? 0.75 : 0.9,
|
|
307
|
+
validUntilMs: Date.now() + QUOTE_TTL_MS
|
|
308
|
+
};
|
|
309
|
+
if (dry) return { ...common, intentId: `dry:${crypto.randomUUID()}`, depositAddress: "", depositMemo: null };
|
|
310
|
+
if (!params.refundAddress) return refuse("live quote without a refund address");
|
|
311
|
+
let refund;
|
|
312
|
+
try {
|
|
313
|
+
refund = destAddressBytes(params.sourceChain, params.refundAddress);
|
|
314
|
+
} catch (e) {
|
|
315
|
+
return refuse(`refund address: ${e.message}`);
|
|
316
|
+
}
|
|
317
|
+
const body = {
|
|
318
|
+
srcAsset: { chain: src.chain, asset: src.asset },
|
|
319
|
+
destAsset: { chain: dst.chain, asset: dst.asset },
|
|
320
|
+
srcAddress: params.refundAddress,
|
|
321
|
+
destAddress: params.destAddress,
|
|
322
|
+
amount: params.amountIn,
|
|
323
|
+
fillOrKillParams: { retryDurationBlocks: RETRY_BLOCKS, refundAddress: params.refundAddress, minPriceX128: minPriceX128.toString(), maxOraclePriceSlippage: oracle },
|
|
324
|
+
commissionBps: 0
|
|
325
|
+
};
|
|
326
|
+
let enc;
|
|
327
|
+
try {
|
|
328
|
+
const r = await call("/api/encodeVaultSwapData", { method: "POST", body: JSON.stringify(body) }, signal);
|
|
329
|
+
if (!r.ok) return refuse(`encode ${r.status}: ${String(r.body?.message ?? "").slice(0, 160)}`);
|
|
330
|
+
enc = r.body ?? {};
|
|
331
|
+
} catch (e) {
|
|
332
|
+
return refuse(`encode failed: ${e.message.slice(0, 160)}`);
|
|
333
|
+
}
|
|
334
|
+
const want = { refund, minPriceX128, oracle };
|
|
335
|
+
const vault = CF_VAULTS[params.sourceChain];
|
|
336
|
+
const dstChain = CF_CHAINS[params.destChain];
|
|
337
|
+
try {
|
|
338
|
+
if (params.sourceChain.startsWith("eip155:")) {
|
|
339
|
+
if (!enc.to || enc.to.toLowerCase() !== vault.toLowerCase()) return refuse(`encoder targets ${enc.to}, not the ${src.chain} Vault`);
|
|
340
|
+
const v = decodeEvmVaultCall(enc.calldata ?? "0x");
|
|
341
|
+
if (v.dstChain !== dstChain.id || v.dstToken !== dst.id || !sameBytes(v.dstAddress, destBytes)) return refuse("encoded destination differs from the request");
|
|
342
|
+
if (src.token === null) {
|
|
343
|
+
if (!v.native || BigInt(enc.value ?? "0") !== amountIn) return refuse("native vault call with a different amount");
|
|
344
|
+
} else if (v.native || v.srcToken?.toLowerCase() !== src.token.toLowerCase() || v.amount !== amountIn || BigInt(enc.value ?? "0") !== 0n) {
|
|
345
|
+
return refuse("token vault call with a different token or amount");
|
|
346
|
+
}
|
|
347
|
+
const bad2 = checkParams(v.params, want);
|
|
348
|
+
if (bad2) return refuse(bad2);
|
|
349
|
+
return {
|
|
350
|
+
...common,
|
|
351
|
+
intentId: `${INTENT_PREFIX}${params.sourceChain}`,
|
|
352
|
+
depositAddress: "",
|
|
353
|
+
depositMemo: null,
|
|
354
|
+
txRequest: { to: vault, data: enc.calldata, value: src.token === null ? params.amountIn : "0", chainId: Number(params.sourceChain.slice(7)), ...src.token ? { approvalAddress: vault } : {} },
|
|
355
|
+
providerData: { kind: "evm", srcAsset: String(src.id), dstAsset: String(dst.id) }
|
|
356
|
+
};
|
|
357
|
+
}
|
|
358
|
+
if (enc.to !== vault) return refuse(`encoder targets ${enc.to}, not the Tron Vault`);
|
|
359
|
+
if (!enc.note) return refuse("Tron vault swap without a note");
|
|
360
|
+
if (src.token !== null) {
|
|
361
|
+
if (enc.sourceTokenAddress !== src.token) return refuse(`source token ${enc.sourceTokenAddress} is not ${src.asset}`);
|
|
362
|
+
const t = (0, import_viem2.decodeFunctionData)({ abi: ERC20, data: enc.calldata ?? "0x" });
|
|
363
|
+
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");
|
|
364
|
+
}
|
|
365
|
+
const n = decodeTronNote(enc.note);
|
|
366
|
+
if (n.outputAsset !== dst.id || n.destTag !== dstChain.addrTag || !sameBytes(n.destAddress, destBytes)) return refuse("note names another destination");
|
|
367
|
+
const bad = checkParams(n.params, want);
|
|
368
|
+
if (bad) return refuse(bad);
|
|
369
|
+
return {
|
|
370
|
+
...common,
|
|
371
|
+
intentId: `${INTENT_PREFIX}${params.sourceChain}`,
|
|
372
|
+
depositAddress: vault,
|
|
373
|
+
depositMemo: enc.note,
|
|
374
|
+
providerData: { kind: "tron", memoEncoding: "hex", srcAsset: String(src.id), dstAsset: String(dst.id) }
|
|
375
|
+
};
|
|
376
|
+
} catch (e) {
|
|
377
|
+
return refuse(`encoder output does not decode: ${e.message.slice(0, 160)}`);
|
|
378
|
+
}
|
|
379
|
+
},
|
|
380
|
+
async buildDeposit(quote) {
|
|
381
|
+
if (quote.providerData?.kind === "evm") {
|
|
382
|
+
const tx = quote.txRequest;
|
|
383
|
+
if (!tx?.to || !tx.data) throw new Error("chainflip: quote has no vault call");
|
|
384
|
+
return { chain: "", to: tx.to, value: tx.value ?? "0", data: tx.data, ...tx.chainId !== void 0 ? { chainId: tx.chainId } : {}, ...tx.approvalAddress ? { approvalAddress: tx.approvalAddress } : {} };
|
|
385
|
+
}
|
|
386
|
+
if (quote.providerData?.kind === "tron") {
|
|
387
|
+
if (!quote.depositAddress || !quote.depositMemo) throw new Error("chainflip: Tron quote without vault or note");
|
|
388
|
+
return { chain: "", to: quote.depositAddress, value: quote.sourceAmount, memo: quote.depositMemo, memoEncoding: "hex" };
|
|
389
|
+
}
|
|
390
|
+
throw new Error("chainflip: not a live vault-swap quote");
|
|
391
|
+
},
|
|
392
|
+
async trackIntent(ref) {
|
|
393
|
+
if (!ref.sourceTxHash) return { state: "pending" };
|
|
394
|
+
const id = ref.intentId.startsWith(`${INTENT_PREFIX}tron:`) ? ref.sourceTxHash.replace(/^0x/, "") : ref.sourceTxHash;
|
|
395
|
+
try {
|
|
396
|
+
const r = await call(`/v2/swaps/${encodeURIComponent(id)}`);
|
|
397
|
+
if (r.status === 404) return { state: "pending" };
|
|
398
|
+
if (!r.ok) return { state: "pending" };
|
|
399
|
+
const s = r.body ?? {};
|
|
400
|
+
const egress = s.swapEgress?.txRef;
|
|
401
|
+
if (s.state === "COMPLETED" || s.state === "SENT" && egress) return { state: "completed", depositReceived: true, ...egress ? { destTxHash: egress } : {} };
|
|
402
|
+
if (s.state === "FAILED") return s.refundEgress || s.fallbackEgress ? { state: "refunded", depositReceived: true } : { state: "failed", depositReceived: true };
|
|
403
|
+
const received = s.state === "RECEIVING" || s.state === "SWAPPING" || s.state === "SENDING" || s.state === "SENT";
|
|
404
|
+
return { state: "pending", depositReceived: received };
|
|
405
|
+
} catch {
|
|
406
|
+
return { state: "pending" };
|
|
407
|
+
}
|
|
408
|
+
}
|
|
409
|
+
};
|
|
410
|
+
}
|
|
411
|
+
|
|
412
|
+
// src/protocol.ts
|
|
413
|
+
var ChainflipSwap2Protocol = class extends import_single.SingleProviderSwap2 {
|
|
414
|
+
provider;
|
|
415
|
+
constructor(account, config) {
|
|
416
|
+
super(account, config);
|
|
417
|
+
this.provider = chainflipProvider(config);
|
|
418
|
+
}
|
|
419
|
+
chainSupported(caip2) {
|
|
420
|
+
return chainflip.supportsChain(caip2);
|
|
421
|
+
}
|
|
422
|
+
pairSupported(fromChain, toChain) {
|
|
423
|
+
return chainflip.supports(fromChain, toChain);
|
|
424
|
+
}
|
|
425
|
+
};
|
|
426
|
+
//# sourceMappingURL=protocol.cjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/protocol.ts","../src/config.ts","../src/activity.ts","../src/codec.ts","../src/provider.ts"],"sourcesContent":["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","/**\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 */\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 * 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 * 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 /** 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 = Number(this.uLE(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 = Number(r.uLE(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() ? Number(r.uLE(2)) : null;\n const dca = r.u8() ? {chunks: Number(r.uLE(4)), intervalBlocks: Number(r.uLE(4))} : null;\n const boostFeeBps = r.u8();\n const broker = {account: toHex(r.bytes(32)), feeBps: Number(r.uLE(2))};\n const n = r.compact();\n const affiliates = Array.from({length: n}, () => ({account: r.u8(), feeBps: Number(r.uLE(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 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 if (s.state === \"COMPLETED\" || (s.state === \"SENT\" && egress)) return {state: \"completed\", depositReceived: true, ...(egress ? {destTxHash: egress} : {})};\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"],"mappings":"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","names":["dstChain","dstAddress","dstToken","cf","import_viem","bad"]}
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
import * as _anywalletkit_protocol_swap2_core_types from '@anywalletkit/protocol-swap2-core/types';
|
|
2
|
+
import { SingleProviderSwap2 } from '@anywalletkit/protocol-swap2-core/swap2/single';
|
|
3
|
+
import { Swap2EngineConfig, Swap2Account } from '@anywalletkit/protocol-swap2-core/swap2/base';
|
|
4
|
+
import { ChainflipProviderConfig } from './provider.cjs';
|
|
5
|
+
|
|
6
|
+
interface ChainflipSwap2Config extends Swap2EngineConfig, ChainflipProviderConfig {
|
|
7
|
+
}
|
|
8
|
+
/** Standalone Chainflip swap2: vault swaps from Ethereum, Arbitrum and Tron to every Chainflip chain. */
|
|
9
|
+
declare class ChainflipSwap2Protocol extends SingleProviderSwap2 {
|
|
10
|
+
protected readonly provider: _anywalletkit_protocol_swap2_core_types.CrossChainProvider;
|
|
11
|
+
constructor(account: Swap2Account | undefined, config: ChainflipSwap2Config);
|
|
12
|
+
protected chainSupported(caip2: string): boolean;
|
|
13
|
+
protected pairSupported(fromChain: string, toChain: string): boolean;
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
export { type ChainflipSwap2Config, ChainflipSwap2Protocol };
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
import * as _anywalletkit_protocol_swap2_core_types from '@anywalletkit/protocol-swap2-core/types';
|
|
2
|
+
import { SingleProviderSwap2 } from '@anywalletkit/protocol-swap2-core/swap2/single';
|
|
3
|
+
import { Swap2EngineConfig, Swap2Account } from '@anywalletkit/protocol-swap2-core/swap2/base';
|
|
4
|
+
import { ChainflipProviderConfig } from './provider.js';
|
|
5
|
+
|
|
6
|
+
interface ChainflipSwap2Config extends Swap2EngineConfig, ChainflipProviderConfig {
|
|
7
|
+
}
|
|
8
|
+
/** Standalone Chainflip swap2: vault swaps from Ethereum, Arbitrum and Tron to every Chainflip chain. */
|
|
9
|
+
declare class ChainflipSwap2Protocol extends SingleProviderSwap2 {
|
|
10
|
+
protected readonly provider: _anywalletkit_protocol_swap2_core_types.CrossChainProvider;
|
|
11
|
+
constructor(account: Swap2Account | undefined, config: ChainflipSwap2Config);
|
|
12
|
+
protected chainSupported(caip2: string): boolean;
|
|
13
|
+
protected pairSupported(fromChain: string, toChain: string): boolean;
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
export { type ChainflipSwap2Config, ChainflipSwap2Protocol };
|
package/dist/protocol.js
ADDED
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import {
|
|
2
|
+
ChainflipSwap2Protocol
|
|
3
|
+
} from "./chunk-XF7BEBET.js";
|
|
4
|
+
import "./chunk-ZFCYBCOT.js";
|
|
5
|
+
import "./chunk-R6EYDH5N.js";
|
|
6
|
+
import "./chunk-H6GJVVWS.js";
|
|
7
|
+
import "./chunk-GXHOO3CT.js";
|
|
8
|
+
export {
|
|
9
|
+
ChainflipSwap2Protocol
|
|
10
|
+
};
|
|
11
|
+
//# sourceMappingURL=protocol.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":[],"sourcesContent":[],"mappings":"","names":[]}
|