@anywalletkit/protocol-swap2-jupiter 0.0.0-stage → 0.2.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (58) hide show
  1. package/LICENSE +202 -0
  2. package/README.md +94 -2
  3. package/dist/activity.cjs +46 -0
  4. package/dist/activity.cjs.map +1 -0
  5. package/dist/activity.d.cts +14 -0
  6. package/dist/activity.d.ts +14 -0
  7. package/dist/activity.js +10 -0
  8. package/dist/activity.js.map +1 -0
  9. package/dist/chunk-5JXNDQHW.js +56 -0
  10. package/dist/chunk-5JXNDQHW.js.map +1 -0
  11. package/dist/chunk-5L7BPEQL.js +51 -0
  12. package/dist/chunk-5L7BPEQL.js.map +1 -0
  13. package/dist/chunk-H4SP5E76.js +20 -0
  14. package/dist/chunk-H4SP5E76.js.map +1 -0
  15. package/dist/chunk-NESHFKWY.js +240 -0
  16. package/dist/chunk-NESHFKWY.js.map +1 -0
  17. package/dist/chunk-OVLAYYGP.js +44 -0
  18. package/dist/chunk-OVLAYYGP.js.map +1 -0
  19. package/dist/chunk-RSAOKVP2.js +27 -0
  20. package/dist/chunk-RSAOKVP2.js.map +1 -0
  21. package/dist/codec.cjs +76 -0
  22. package/dist/codec.cjs.map +1 -0
  23. package/dist/codec.d.cts +27 -0
  24. package/dist/codec.d.ts +27 -0
  25. package/dist/codec.js +23 -0
  26. package/dist/codec.js.map +1 -0
  27. package/dist/config.cjs +64 -0
  28. package/dist/config.cjs.map +1 -0
  29. package/dist/config.d.cts +23 -0
  30. package/dist/config.d.ts +23 -0
  31. package/dist/config.js +31 -0
  32. package/dist/config.js.map +1 -0
  33. package/dist/index.cjs +390 -0
  34. package/dist/index.cjs.map +1 -0
  35. package/dist/index.d.cts +10 -0
  36. package/dist/index.d.ts +10 -0
  37. package/dist/index.js +70 -0
  38. package/dist/index.js.map +1 -0
  39. package/dist/protocol.cjs +362 -0
  40. package/dist/protocol.cjs.map +1 -0
  41. package/dist/protocol.d.cts +16 -0
  42. package/dist/protocol.d.ts +16 -0
  43. package/dist/protocol.js +12 -0
  44. package/dist/protocol.js.map +1 -0
  45. package/dist/provider.cjs +348 -0
  46. package/dist/provider.cjs.map +1 -0
  47. package/dist/provider.d.cts +20 -0
  48. package/dist/provider.d.ts +20 -0
  49. package/dist/provider.js +11 -0
  50. package/dist/provider.js.map +1 -0
  51. package/dist/transaction.cjs +75 -0
  52. package/dist/transaction.cjs.map +1 -0
  53. package/dist/transaction.d.cts +23 -0
  54. package/dist/transaction.d.ts +23 -0
  55. package/dist/transaction.js +9 -0
  56. package/dist/transaction.js.map +1 -0
  57. package/module.json +16 -0
  58. package/package.json +96 -3
@@ -0,0 +1,240 @@
1
+ import {
2
+ assembleTransaction
3
+ } from "./chunk-5L7BPEQL.js";
4
+ import {
5
+ decodeComputeBudget,
6
+ decodeSwapArgs,
7
+ fromBase64,
8
+ minOutOf
9
+ } from "./chunk-5JXNDQHW.js";
10
+ import {
11
+ describeJupiterActivity
12
+ } from "./chunk-H4SP5E76.js";
13
+ import {
14
+ COMPUTE_BUDGET_PROGRAM,
15
+ JUPITER_API_DEFAULT,
16
+ JUPITER_PROGRAM,
17
+ JUPITER_TX_PROGRAMS,
18
+ SOLANA_CAIP2,
19
+ WSOL_MINT,
20
+ jupiter,
21
+ jupiterMint
22
+ } from "./chunk-OVLAYYGP.js";
23
+
24
+ // src/provider.ts
25
+ import { timeoutSignal } from "@anywalletkit/protocol-swap2-core/util";
26
+ var DEFAULT_SLIPPAGE_BPS = 50;
27
+ var MAX_SLIPPAGE_BPS = 1e3;
28
+ var QUOTE_TTL_MS = 3e4;
29
+ var MAX_COMPUTE_UNITS = 14e5;
30
+ var DEFAULT_MAX_CU_PRICE = 2000000n;
31
+ var BASE_FEE_LAMPORTS = 5000n;
32
+ var DRY_TAKER = "9WzDXwBbmkg8ZTbNMqUxvQRAyrZzDsGYdLVL9zYtAWWM";
33
+ var BASE58 = /^[1-9A-HJ-NP-Za-km-z]{32,44}$/;
34
+ var INTENT_PREFIX = "jup:";
35
+ function jupiterProvider(config = {}) {
36
+ config = Object.freeze({ ...config });
37
+ const base = (config.apiUrl ?? JUPITER_API_DEFAULT).replace(/\/$/, "");
38
+ const maxPrice = config.maxComputeUnitPrice ?? DEFAULT_MAX_CU_PRICE;
39
+ const rpcUrls = config.rpcUrls ?? [];
40
+ const get = async (path, signal) => {
41
+ for (let attempt = 0; ; attempt++) {
42
+ const res = await fetch(`${base}${path}`, { headers: { accept: "application/json", ...config.apiKey ? { "x-api-key": config.apiKey } : {} }, signal: signal ?? timeoutSignal(12e3) });
43
+ const body = await res.json().catch(() => null);
44
+ if (res.status === 429 && attempt === 0 && !signal?.aborted) {
45
+ const reset = Number(res.headers.get("x-ratelimit-reset"));
46
+ const wait = Number.isFinite(reset) && reset > 0 ? Math.min(3e3, Math.max(250, reset * 1e3 - Date.now())) : 1200;
47
+ await new Promise((r) => setTimeout(r, wait));
48
+ continue;
49
+ }
50
+ return { ok: res.ok, status: res.status, body };
51
+ }
52
+ };
53
+ const rpc = async (method, params) => {
54
+ let last = new Error("no Solana RPC configured");
55
+ for (const url of rpcUrls) {
56
+ try {
57
+ const res = await fetch(url, { method: "POST", headers: { "content-type": "application/json" }, body: JSON.stringify({ jsonrpc: "2.0", id: 1, method, params }), signal: timeoutSignal(1e4) });
58
+ const body = await res.json();
59
+ if (body.error) throw new Error(body.error.message ?? "rpc error");
60
+ return body.result;
61
+ } catch (e) {
62
+ last = e;
63
+ }
64
+ }
65
+ throw last;
66
+ };
67
+ const vet = (b, want) => {
68
+ if (b.swapMode && b.swapMode !== "ExactIn") throw new Error(`swap mode ${b.swapMode}`);
69
+ if (b.inputMint !== want.inputMint || b.outputMint !== want.outputMint) throw new Error("the answer names other mints");
70
+ if (b.inAmount !== want.amountIn.toString()) throw new Error(`the answer spends ${b.inAmount}, not ${want.amountIn}`);
71
+ if (String(b.transactionVersion ?? "0") !== "0") throw new Error(`transaction version ${b.transactionVersion}`);
72
+ if (b.tipInstruction) throw new Error("unexpected tip instruction");
73
+ if (!b.swapInstruction) throw new Error("no swap instruction");
74
+ if (b.swapInstruction.programId !== JUPITER_PROGRAM) throw new Error(`swap instruction targets ${b.swapInstruction.programId}`);
75
+ const args = decodeSwapArgs(fromBase64(b.swapInstruction.data));
76
+ if (args.inAmount !== want.amountIn) throw new Error(`swap instruction spends ${args.inAmount}, not ${want.amountIn}`);
77
+ if (String(args.quotedOutAmount) !== b.outAmount) throw new Error("swap instruction's quoted output differs from the answer");
78
+ if (args.slippageBps !== want.slippageBps) throw new Error(`swap instruction allows ${args.slippageBps} bps slippage, not ${want.slippageBps}`);
79
+ if (args.platformFeeBps !== 0 || args.positiveSlippageBps !== 0) throw new Error("swap instruction takes a platform fee");
80
+ let price = 0n;
81
+ for (const ix of b.computeBudgetInstructions ?? []) {
82
+ if (ix.programId !== COMPUTE_BUDGET_PROGRAM) throw new Error(`compute-budget slot holds ${ix.programId}`);
83
+ const d = decodeComputeBudget(fromBase64(ix.data));
84
+ if (d.price !== void 0) price = d.price;
85
+ }
86
+ const instructions = [...b.setupInstructions ?? [], b.swapInstruction, ...b.cleanupInstruction ? [b.cleanupInstruction] : [], ...b.otherInstructions ?? []];
87
+ for (const ix of instructions) {
88
+ if (!JUPITER_TX_PROGRAMS.has(ix.programId) || ix.programId === COMPUTE_BUDGET_PROGRAM) throw new Error(`instruction for program ${ix.programId}`);
89
+ for (const a of ix.accounts) if (a.isSigner && a.pubkey !== want.taker) throw new Error(`instruction needs signer ${a.pubkey}`);
90
+ }
91
+ return { instructions, price: price > maxPrice ? maxPrice : price, quotedOut: args.quotedOutAmount };
92
+ };
93
+ const simulateUnits = async (wire) => {
94
+ if (!rpcUrls.length) return null;
95
+ let r;
96
+ try {
97
+ r = await rpc("simulateTransaction", [wire, { encoding: "base64", sigVerify: false, replaceRecentBlockhash: true, commitment: "processed" }]);
98
+ } catch {
99
+ return null;
100
+ }
101
+ if (r?.value?.err) {
102
+ const log = (r.value.logs ?? []).filter((l) => /error|failed|insufficient/i.test(l)).slice(-1)[0] ?? "";
103
+ const err = JSON.stringify(r.value.err);
104
+ const jupiterCode = /JUP6LkbZbjS1jKKwapdHNy74zcZ3tLUZoi5QNyVTaV4 failed/.test(log) ? /"Custom":(\d+)/.exec(err)?.[1] : void 0;
105
+ if (jupiterCode === "6024" || jupiterCode === "6025" || /"Custom":1\}/.test(err) && /Program 11111111111111111111111111111111 failed/.test(log)) {
106
+ throw new Error(`not enough of the input token in the wallet${jupiterCode === "6025" ? " (no token account for it)" : ""} \u2014 simulation fails: ${err}`);
107
+ }
108
+ throw new Error(`simulation fails: ${err}${log ? ` (${log.slice(0, 160)})` : ""}`);
109
+ }
110
+ const used = r?.value?.unitsConsumed;
111
+ return used ? Math.min(MAX_COMPUTE_UNITS, Math.ceil(used * 1.2)) : null;
112
+ };
113
+ return {
114
+ name: "jupiter",
115
+ describeActivity: describeJupiterActivity,
116
+ enabled: () => config.enabled ?? true,
117
+ supportsSameChain: true,
118
+ supportsChain: (chain) => jupiter.supportsChain(chain),
119
+ supportsChainPair: (from, to) => jupiter.supports(from, to),
120
+ supportsRoute(from, to) {
121
+ if (!jupiter.supports(from.chain, to.chain)) return false;
122
+ const a = jupiterMint(from.token), b = jupiterMint(to.token);
123
+ return !!a && !!b && a !== b;
124
+ },
125
+ async getQuote(params, signal) {
126
+ const dry = params.dry !== false;
127
+ const refuse = (reason) => {
128
+ params.onRefusal?.(`jupiter: ${reason}`);
129
+ return null;
130
+ };
131
+ if (!jupiter.supports(params.sourceChain, params.destChain)) return refuse(`same-chain Solana only (${params.sourceChain} \u2192 ${params.destChain})`);
132
+ if (params.flex) return refuse("amount-flexible deposits are not supported");
133
+ const inputMint = jupiterMint(params.sourceToken), outputMint = jupiterMint(params.destToken);
134
+ if (!inputMint || !outputMint) return refuse(`unknown token (${params.sourceToken} \u2192 ${params.destToken})`);
135
+ if (inputMint === outputMint) return refuse("same token on both sides");
136
+ const amountIn = BigInt(params.amountIn);
137
+ if (amountIn <= 0n) return refuse("amount must be positive");
138
+ const slippageBps = params.slippageBps ?? config.defaultSlippageBps ?? DEFAULT_SLIPPAGE_BPS;
139
+ if (!Number.isInteger(slippageBps) || slippageBps < 0 || slippageBps > MAX_SLIPPAGE_BPS) return refuse(`slippage ${slippageBps} bps is out of range`);
140
+ const self = params.refundAddress || params.destAddress;
141
+ if (!dry) {
142
+ if (!self || !BASE58.test(self)) return refuse("live quote without the signer's address");
143
+ if (params.destAddress && params.destAddress !== self) return refuse("the recipient must be the signing wallet (Jupiter pays the taker)");
144
+ }
145
+ const taker = self && BASE58.test(self) ? self : DRY_TAKER;
146
+ const qs = new URLSearchParams({ inputMint, outputMint, amount: params.amountIn, taker, slippageBps: String(slippageBps) });
147
+ if (config.computeUnitPricePercentile) qs.set("computeUnitPricePercentile", config.computeUnitPricePercentile);
148
+ let b;
149
+ try {
150
+ const r = await get(`/build?${qs.toString()}`, signal);
151
+ if (!r.ok) return refuse(`build ${r.status}: ${String(r.body?.error ?? "").slice(0, 160)}`);
152
+ b = r.body ?? {};
153
+ } catch (e) {
154
+ return refuse(`build failed: ${e.message.slice(0, 160)}`);
155
+ }
156
+ if (!b.outAmount || !/^\d+$/.test(b.outAmount)) return refuse("answer without an output amount");
157
+ let vetted;
158
+ try {
159
+ vetted = vet(b, { taker, inputMint, outputMint, amountIn, slippageBps });
160
+ } catch (e) {
161
+ return refuse(e.message);
162
+ }
163
+ const minOut = minOutOf(vetted.quotedOut, slippageBps);
164
+ if (params.minAmountOut !== void 0 && minOut < BigInt(params.minAmountOut)) {
165
+ return refuse(`guaranteed ${minOut} is below the floor ${params.minAmountOut} at ${slippageBps} bps`);
166
+ }
167
+ const route = (b.routePlan ?? []).map((s) => s.swapInfo?.label).filter(Boolean).join(" + ");
168
+ const impact = Number(b.priceImpactPct ?? 0);
169
+ const common = {
170
+ provider: "jupiter",
171
+ depositAddress: "",
172
+ depositMemo: null,
173
+ sourceAmount: params.amountIn,
174
+ destAmount: b.outAmount,
175
+ minDestAmount: minOut.toString(),
176
+ feeUsd: 0,
177
+ etaSeconds: 15,
178
+ reliability: impact > 0.05 ? 0.8 : 0.97,
179
+ validUntilMs: Date.now() + QUOTE_TTL_MS
180
+ };
181
+ if (dry) {
182
+ return { ...common, intentId: `dry:${INTENT_PREFIX}${Date.now().toString(36)}`, fees: [{ type: "network", amount: BASE_FEE_LAMPORTS.toString(), token: "native", included: false, description: "Solana base fee" }], ...route ? { providerData: { route } } : {} };
183
+ }
184
+ const blockhash = b.blockhashWithMetadata?.blockhash;
185
+ const lastValid = b.blockhashWithMetadata?.lastValidBlockHeight;
186
+ if (!blockhash || blockhash.length !== 32 || !lastValid) return refuse("answer without a blockhash");
187
+ const assemble = (limit2) => assembleTransaction({
188
+ taker,
189
+ instructions: vetted.instructions,
190
+ computeUnitLimit: limit2,
191
+ computeUnitPrice: vetted.price,
192
+ blockhash: Uint8Array.from(blockhash),
193
+ lastValidBlockHeight: lastValid,
194
+ addressesByLookupTableAddress: b.addressesByLookupTableAddress
195
+ });
196
+ let wire, limit = MAX_COMPUTE_UNITS;
197
+ try {
198
+ wire = assemble(MAX_COMPUTE_UNITS);
199
+ const units = await simulateUnits(wire);
200
+ if (units) {
201
+ limit = units;
202
+ wire = assemble(units);
203
+ }
204
+ } catch (e) {
205
+ return refuse(e.message.slice(0, 240));
206
+ }
207
+ const priority = (vetted.price * BigInt(limit) + 999999n) / 1000000n;
208
+ return {
209
+ ...common,
210
+ intentId: `${INTENT_PREFIX}${lastValid}:${Date.now().toString(36)}`,
211
+ // `value` declares the native SOL the transaction may take: the input for a SOL source (Jupiter wraps it), none for a token.
212
+ txRequest: { serializedTx: wire, value: inputMint === WSOL_MINT ? params.amountIn : "0" },
213
+ fees: [{ type: "network", amount: (BASE_FEE_LAMPORTS + priority).toString(), token: "native", included: false, description: `Solana base + priority fee (${limit} CU at ${vetted.price} \xB5lamports)` }],
214
+ providerData: { inputMint, outputMint, slippageBps: String(slippageBps), computeUnits: String(limit), ...route ? { route } : {} }
215
+ };
216
+ },
217
+ async buildDeposit(quote) {
218
+ const tx = quote.txRequest?.serializedTx;
219
+ if (!tx || quote.intentId.startsWith("dry:")) throw new Error("jupiter: not a live quote");
220
+ return { chain: SOLANA_CAIP2, to: "", value: quote.txRequest.value ?? "0", serializedTx: tx };
221
+ },
222
+ async trackIntent(ref) {
223
+ if (!ref.sourceTxHash || !rpcUrls.length) return { state: "pending" };
224
+ try {
225
+ const r = await rpc("getSignatureStatuses", [[ref.sourceTxHash], { searchTransactionHistory: true }]);
226
+ const s = r?.value?.[0];
227
+ if (!s) return { state: "pending" };
228
+ if (s.err) return { state: "failed" };
229
+ return s.confirmationStatus === "confirmed" || s.confirmationStatus === "finalized" ? { state: "completed", destTxHash: ref.sourceTxHash } : { state: "pending" };
230
+ } catch {
231
+ return { state: "pending" };
232
+ }
233
+ }
234
+ };
235
+ }
236
+
237
+ export {
238
+ jupiterProvider
239
+ };
240
+ //# sourceMappingURL=chunk-NESHFKWY.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/provider.ts"],"sourcesContent":["/**\n * Jupiter provider — Swap API V2 Router path, same-chain Solana swaps:\n * quote + instructions GET /swap/v2/build?inputMint&outputMint&amount&taker&slippageBps\n * status getSignatureStatuses on the caller's own Solana RPC (optional)\n * Routing is Metis (Jupiter's on-chain router); the Router path charges no Jupiter swap fee. Keyless access works at\n * 0.5 RPS; pass `apiKey` (sent as `x-api-key`) for a plan's rate limit.\n *\n * Nothing from the API is trusted as-is. Before a live quote is handed out, every instruction is checked: only the\n * Jupiter program and the token / system / ATA / compute-budget plumbing, the taker is the only signer, no tip, and\n * the swap instruction's own arguments (decoded) carry exactly our input amount, the quoted output, our slippage and\n * a zero platform fee — those are what the program enforces on-chain. The compute budget is rebuilt here: a unit price\n * capped by `maxComputeUnitPrice`, and a unit limit from a simulation (1.2× the units used) when `rpcUrls` is given.\n * The account then executes the assembled transaction through its serialized-transaction guard (simulation +\n * balance proof against the quote) and broadcasts it through its own RPC.\n */\nimport {describeJupiterActivity} from \"./activity.js\";\nimport {JUPITER_API_DEFAULT, JUPITER_PROGRAM, JUPITER_TX_PROGRAMS, COMPUTE_BUDGET_PROGRAM, SOLANA_CAIP2, WSOL_MINT, jupiter as cfg, jupiterMint} from \"./config.js\";\nimport {decodeComputeBudget, decodeSwapArgs, fromBase64, minOutOf} from \"./codec.js\";\nimport {assembleTransaction, type JupiterInstruction} from \"./transaction.js\";\nimport {timeoutSignal} from \"@anywalletkit/protocol-swap2-core/util\";\nimport type {Asset, CrossChainProvider, IntentRef, IntentStatus, Quote, QuoteParams, UnsignedTx} from \"@anywalletkit/protocol-swap2-core/types\";\n\nconst DEFAULT_SLIPPAGE_BPS = 50;\nconst MAX_SLIPPAGE_BPS = 1_000;\n/** A /build blockhash lives ~60–90 s; the quote must be signed well inside it. */\nconst QUOTE_TTL_MS = 30_000;\nconst MAX_COMPUTE_UNITS = 1_400_000;\n/** 2 000 000 µlamports/CU: at 1.4 M CU the priority fee is ≤ 0.0028 SOL. */\nconst DEFAULT_MAX_CU_PRICE = 2_000_000n;\nconst BASE_FEE_LAMPORTS = 5_000n;\n/** Taker for a dry quote with no address yet: /build needs one, the price does not depend on it. */\nconst DRY_TAKER = \"9WzDXwBbmkg8ZTbNMqUxvQRAyrZzDsGYdLVL9zYtAWWM\";\nconst BASE58 = /^[1-9A-HJ-NP-Za-km-z]{32,44}$/;\n\nexport interface JupiterProviderConfig {\n enabled?: boolean;\n /** Swap API base (default https://api.jup.ag/swap/v2). */\n apiUrl?: string;\n /** Jupiter Developer Platform key, sent as `x-api-key`. Keyless works at 0.5 RPS. */\n apiKey?: string;\n /** Solana JSON-RPC endpoints: compute-unit simulation and status. Without them the limit is 1.4 M CU and status stays pending. */\n rpcUrls?: readonly string[];\n /** Ceiling on the compute-unit price Jupiter suggests, micro-lamports (default 2 000 000). */\n maxComputeUnitPrice?: bigint;\n /** Passed to /build: \"medium\" | \"high\" | \"veryHigh\" or a percentile in bps (default: Jupiter's 50th percentile). */\n computeUnitPricePercentile?: string;\n /** Slippage when the caller names none, bps (default 50). */\n defaultSlippageBps?: number;\n}\n\ninterface BuildResponse {\n inputMint?: string;\n outputMint?: string;\n inAmount?: string;\n outAmount?: string;\n otherAmountThreshold?: string;\n swapMode?: string;\n slippageBps?: number;\n priceImpactPct?: string;\n routePlan?: {bps?: number; swapInfo?: {label?: string}}[];\n computeBudgetInstructions?: JupiterInstruction[];\n setupInstructions?: JupiterInstruction[];\n swapInstruction?: JupiterInstruction;\n cleanupInstruction?: JupiterInstruction | null;\n otherInstructions?: JupiterInstruction[];\n tipInstruction?: JupiterInstruction | null;\n addressesByLookupTableAddress?: Record<string, string[]> | null;\n transactionVersion?: number | string;\n blockhashWithMetadata?: {blockhash?: number[]; lastValidBlockHeight?: number};\n error?: string;\n}\n\nconst INTENT_PREFIX = \"jup:\";\n\nexport function jupiterProvider(config: JupiterProviderConfig = {}): CrossChainProvider {\n config = Object.freeze({...config});\n const base = (config.apiUrl ?? JUPITER_API_DEFAULT).replace(/\\/$/, \"\");\n const maxPrice = config.maxComputeUnitPrice ?? DEFAULT_MAX_CU_PRICE;\n const rpcUrls = config.rpcUrls ?? [];\n\n /** One GET with a single back-off on 429 (keyless traffic is 0.5 RPS), waiting for `x-ratelimit-reset` when given. */\n const get = async (path: string, signal?: AbortSignal): Promise<{ok: boolean; status: number; body: unknown}> => {\n for (let attempt = 0; ; attempt++) {\n const res = await fetch(`${base}${path}`, {headers: {accept: \"application/json\", ...(config.apiKey ? {\"x-api-key\": config.apiKey} : {})}, signal: signal ?? timeoutSignal(12_000)});\n const body = await res.json().catch(() => null);\n if (res.status === 429 && attempt === 0 && !signal?.aborted) {\n const reset = Number(res.headers.get(\"x-ratelimit-reset\"));\n const wait = Number.isFinite(reset) && reset > 0 ? Math.min(3_000, Math.max(250, reset * 1000 - Date.now())) : 1_200;\n await new Promise((r) => setTimeout(r, wait));\n continue;\n }\n return {ok: res.ok, status: res.status, body};\n }\n };\n\n const rpc = async (method: string, params: unknown[]): Promise<unknown> => {\n let last: unknown = new Error(\"no Solana RPC configured\");\n for (const url of rpcUrls) {\n try {\n const res = await fetch(url, {method: \"POST\", headers: {\"content-type\": \"application/json\"}, body: JSON.stringify({jsonrpc: \"2.0\", id: 1, method, params}), signal: timeoutSignal(10_000)});\n const body = (await res.json()) as {result?: unknown; error?: {message?: string}};\n if (body.error) throw new Error(body.error.message ?? \"rpc error\");\n return body.result;\n } catch (e) { last = e; }\n }\n throw last;\n };\n\n /** Every instruction the API returned, checked; returns the ordered list to assemble and the suggested unit price. */\n const vet = (b: BuildResponse, want: {taker: string; inputMint: string; outputMint: string; amountIn: bigint; slippageBps: number}): {instructions: JupiterInstruction[]; price: bigint; quotedOut: bigint} => {\n if (b.swapMode && b.swapMode !== \"ExactIn\") throw new Error(`swap mode ${b.swapMode}`);\n if (b.inputMint !== want.inputMint || b.outputMint !== want.outputMint) throw new Error(\"the answer names other mints\");\n if (b.inAmount !== want.amountIn.toString()) throw new Error(`the answer spends ${b.inAmount}, not ${want.amountIn}`);\n if (String(b.transactionVersion ?? \"0\") !== \"0\") throw new Error(`transaction version ${b.transactionVersion}`);\n if (b.tipInstruction) throw new Error(\"unexpected tip instruction\");\n if (!b.swapInstruction) throw new Error(\"no swap instruction\");\n if (b.swapInstruction.programId !== JUPITER_PROGRAM) throw new Error(`swap instruction targets ${b.swapInstruction.programId}`);\n const args = decodeSwapArgs(fromBase64(b.swapInstruction.data));\n if (args.inAmount !== want.amountIn) throw new Error(`swap instruction spends ${args.inAmount}, not ${want.amountIn}`);\n if (String(args.quotedOutAmount) !== b.outAmount) throw new Error(\"swap instruction's quoted output differs from the answer\");\n if (args.slippageBps !== want.slippageBps) throw new Error(`swap instruction allows ${args.slippageBps} bps slippage, not ${want.slippageBps}`);\n if (args.platformFeeBps !== 0 || args.positiveSlippageBps !== 0) throw new Error(\"swap instruction takes a platform fee\");\n let price = 0n;\n for (const ix of b.computeBudgetInstructions ?? []) {\n if (ix.programId !== COMPUTE_BUDGET_PROGRAM) throw new Error(`compute-budget slot holds ${ix.programId}`);\n const d = decodeComputeBudget(fromBase64(ix.data));\n if (d.price !== undefined) price = d.price;\n }\n const instructions = [...(b.setupInstructions ?? []), b.swapInstruction, ...(b.cleanupInstruction ? [b.cleanupInstruction] : []), ...(b.otherInstructions ?? [])];\n for (const ix of instructions) {\n if (!JUPITER_TX_PROGRAMS.has(ix.programId) || ix.programId === COMPUTE_BUDGET_PROGRAM) throw new Error(`instruction for program ${ix.programId}`);\n for (const a of ix.accounts) if (a.isSigner && a.pubkey !== want.taker) throw new Error(`instruction needs signer ${a.pubkey}`);\n }\n return {instructions, price: price > maxPrice ? maxPrice : price, quotedOut: args.quotedOutAmount};\n };\n\n /** 1.2× the units a simulation uses (capped); null when no RPC answers. A failing simulation refuses the quote. */\n const simulateUnits = async (wire: string): Promise<number | null> => {\n if (!rpcUrls.length) return null;\n let r: {value?: {err?: unknown; unitsConsumed?: number; logs?: string[]}};\n try {\n r = (await rpc(\"simulateTransaction\", [wire, {encoding: \"base64\", sigVerify: false, replaceRecentBlockhash: true, commitment: \"processed\"}])) as typeof r;\n } catch {\n return null;\n }\n if (r?.value?.err) {\n const log = (r.value.logs ?? []).filter((l) => /error|failed|insufficient/i.test(l)).slice(-1)[0] ?? \"\";\n const err = JSON.stringify(r.value.err);\n // The usual reason, said plainly: the wallet lacks the input. Confirmed 2026-10-24 by building the same\n // USDS / LINK / WBTC → USDC swaps from an empty wallet (6025) and from real holders (built fine).\n // Jupiter 6024 = insufficient funds, 6025 = no token account for the input; System Program 1 = not enough SOL.\n const jupiterCode = /JUP6LkbZbjS1jKKwapdHNy74zcZ3tLUZoi5QNyVTaV4 failed/.test(log) ? /\"Custom\":(\\d+)/.exec(err)?.[1] : undefined;\n if (jupiterCode === \"6024\" || jupiterCode === \"6025\" || (/\"Custom\":1\\}/.test(err) && /Program 11111111111111111111111111111111 failed/.test(log))) {\n throw new Error(`not enough of the input token in the wallet${jupiterCode === \"6025\" ? \" (no token account for it)\" : \"\"} — simulation fails: ${err}`);\n }\n throw new Error(`simulation fails: ${err}${log ? ` (${log.slice(0, 160)})` : \"\"}`);\n }\n const used = r?.value?.unitsConsumed;\n return used ? Math.min(MAX_COMPUTE_UNITS, Math.ceil(used * 1.2)) : null;\n };\n\n return {\n name: \"jupiter\",\n describeActivity: describeJupiterActivity,\n enabled: () => config.enabled ?? true,\n supportsSameChain: 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 = jupiterMint(from.token), b = jupiterMint(to.token);\n return !!a && !!b && a !== b;\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?.(`jupiter: ${reason}`);\n return null;\n };\n if (!cfg.supports(params.sourceChain, params.destChain)) return refuse(`same-chain Solana only (${params.sourceChain} → ${params.destChain})`);\n if (params.flex) return refuse(\"amount-flexible deposits are not supported\");\n const inputMint = jupiterMint(params.sourceToken), outputMint = jupiterMint(params.destToken);\n if (!inputMint || !outputMint) return refuse(`unknown token (${params.sourceToken} → ${params.destToken})`);\n if (inputMint === outputMint) return refuse(\"same token on both sides\");\n const amountIn = BigInt(params.amountIn);\n if (amountIn <= 0n) return refuse(\"amount must be positive\");\n const slippageBps = params.slippageBps ?? config.defaultSlippageBps ?? DEFAULT_SLIPPAGE_BPS;\n if (!Number.isInteger(slippageBps) || slippageBps < 0 || slippageBps > MAX_SLIPPAGE_BPS) return refuse(`slippage ${slippageBps} bps is out of range`);\n\n // The swap pays the taker's own token account: a live quote must be for the signer's own address.\n const self = params.refundAddress || params.destAddress;\n if (!dry) {\n if (!self || !BASE58.test(self)) return refuse(\"live quote without the signer's address\");\n if (params.destAddress && params.destAddress !== self) return refuse(\"the recipient must be the signing wallet (Jupiter pays the taker)\");\n }\n const taker = self && BASE58.test(self) ? self : DRY_TAKER;\n\n const qs = new URLSearchParams({inputMint, outputMint, amount: params.amountIn, taker, slippageBps: String(slippageBps)});\n if (config.computeUnitPricePercentile) qs.set(\"computeUnitPricePercentile\", config.computeUnitPricePercentile);\n let b: BuildResponse;\n try {\n const r = await get(`/build?${qs.toString()}`, signal);\n if (!r.ok) return refuse(`build ${r.status}: ${String((r.body as BuildResponse | null)?.error ?? \"\").slice(0, 160)}`);\n b = (r.body ?? {}) as BuildResponse;\n } catch (e) { return refuse(`build failed: ${(e as Error).message.slice(0, 160)}`); }\n if (!b.outAmount || !/^\\d+$/.test(b.outAmount)) return refuse(\"answer without an output amount\");\n\n let vetted: ReturnType<typeof vet>;\n try { vetted = vet(b, {taker, inputMint, outputMint, amountIn, slippageBps}); } catch (e) { return refuse((e as Error).message); }\n const minOut = minOutOf(vetted.quotedOut, slippageBps);\n if (params.minAmountOut !== undefined && minOut < BigInt(params.minAmountOut)) {\n return refuse(`guaranteed ${minOut} is below the floor ${params.minAmountOut} at ${slippageBps} bps`);\n }\n const route = (b.routePlan ?? []).map((s) => s.swapInfo?.label).filter(Boolean).join(\" + \");\n const impact = Number(b.priceImpactPct ?? 0);\n const common = {\n provider: \"jupiter\",\n depositAddress: \"\",\n depositMemo: null,\n sourceAmount: params.amountIn,\n destAmount: b.outAmount,\n minDestAmount: minOut.toString(),\n feeUsd: 0,\n etaSeconds: 15,\n reliability: impact > 0.05 ? 0.8 : 0.97,\n validUntilMs: Date.now() + QUOTE_TTL_MS,\n };\n if (dry) {\n return {...common, intentId: `dry:${INTENT_PREFIX}${Date.now().toString(36)}`, fees: [{type: \"network\" as const, amount: BASE_FEE_LAMPORTS.toString(), token: \"native\", included: false, description: \"Solana base fee\"}], ...(route ? {providerData: {route}} : {})};\n }\n\n const blockhash = b.blockhashWithMetadata?.blockhash;\n const lastValid = b.blockhashWithMetadata?.lastValidBlockHeight;\n if (!blockhash || blockhash.length !== 32 || !lastValid) return refuse(\"answer without a blockhash\");\n const assemble = (limit: number) => assembleTransaction({\n taker, instructions: vetted.instructions, computeUnitLimit: limit, computeUnitPrice: vetted.price,\n blockhash: Uint8Array.from(blockhash), lastValidBlockHeight: lastValid, addressesByLookupTableAddress: b.addressesByLookupTableAddress,\n });\n let wire: string, limit = MAX_COMPUTE_UNITS;\n try {\n wire = assemble(MAX_COMPUTE_UNITS);\n const units = await simulateUnits(wire);\n if (units) { limit = units; wire = assemble(units); }\n } catch (e) { return refuse((e as Error).message.slice(0, 240)); }\n const priority = (vetted.price * BigInt(limit) + 999_999n) / 1_000_000n;\n return {\n ...common,\n intentId: `${INTENT_PREFIX}${lastValid}:${Date.now().toString(36)}`,\n // `value` declares the native SOL the transaction may take: the input for a SOL source (Jupiter wraps it), none for a token.\n txRequest: {serializedTx: wire, value: inputMint === WSOL_MINT ? params.amountIn : \"0\"},\n fees: [{type: \"network\", amount: (BASE_FEE_LAMPORTS + priority).toString(), token: \"native\", included: false, description: `Solana base + priority fee (${limit} CU at ${vetted.price} µlamports)`}],\n providerData: {inputMint, outputMint, slippageBps: String(slippageBps), computeUnits: String(limit), ...(route ? {route} : {})},\n };\n },\n\n async buildDeposit(quote: Quote): Promise<UnsignedTx> {\n const tx = quote.txRequest?.serializedTx;\n if (!tx || quote.intentId.startsWith(\"dry:\")) throw new Error(\"jupiter: not a live quote\");\n return {chain: SOLANA_CAIP2, to: \"\", value: quote.txRequest!.value ?? \"0\", serializedTx: tx};\n },\n\n async trackIntent(ref: IntentRef): Promise<IntentStatus> {\n if (!ref.sourceTxHash || !rpcUrls.length) return {state: \"pending\"};\n try {\n const r = (await rpc(\"getSignatureStatuses\", [[ref.sourceTxHash], {searchTransactionHistory: true}])) as {value?: ({err?: unknown; confirmationStatus?: string} | null)[]};\n const s = r?.value?.[0];\n if (!s) return {state: \"pending\"};\n if (s.err) return {state: \"failed\"};\n return s.confirmationStatus === \"confirmed\" || s.confirmationStatus === \"finalized\" ? {state: \"completed\", destTxHash: ref.sourceTxHash} : {state: \"pending\"};\n } catch {\n return {state: \"pending\"};\n }\n },\n };\n}\n"],"mappings":"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","names":["limit"]}
@@ -0,0 +1,44 @@
1
+ // src/config.ts
2
+ import { ccAsset, ccAssetByToken } from "@anywalletkit/swap2-assets";
3
+ var JUPITER_API_DEFAULT = "https://api.jup.ag/swap/v2";
4
+ var JUPITER_PROGRAM = "JUP6LkbZbjS1jKKwapdHNy74zcZ3tLUZoi5QNyVTaV4";
5
+ var COMPUTE_BUDGET_PROGRAM = "ComputeBudget111111111111111111111111111111";
6
+ var SYSTEM_PROGRAM = "11111111111111111111111111111111";
7
+ var TOKEN_PROGRAM = "TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA";
8
+ var TOKEN_2022_PROGRAM = "TokenzQdBNbLqP5VEhdkAS6EPFLC1PHnBqCXEpPxuEb";
9
+ var ATA_PROGRAM = "ATokenGPvbdGVxr1b2hvZbsiqW5xWH25efTNsLJA8knL";
10
+ var WSOL_MINT = "So11111111111111111111111111111111111111112";
11
+ var JUPITER_TX_PROGRAMS = /* @__PURE__ */ new Set([JUPITER_PROGRAM, COMPUTE_BUDGET_PROGRAM, SYSTEM_PROGRAM, TOKEN_PROGRAM, TOKEN_2022_PROGRAM, ATA_PROGRAM]);
12
+ var SOLANA_CAIP2 = "solana:mainnet";
13
+ var SOLANA_CHAINS = /* @__PURE__ */ new Set([SOLANA_CAIP2, "solana:5eykt4UsFv8P8NJdTREpY1vzqKqZKvdp"]);
14
+ var BASE58 = /^[1-9A-HJ-NP-Za-km-z]{32,44}$/;
15
+ var NATIVE = /* @__PURE__ */ new Set(["", "native", "sol", SYSTEM_PROGRAM, WSOL_MINT.toLowerCase(), "0x0000000000000000000000000000000000000000"]);
16
+ function jupiterMint(token) {
17
+ if (NATIVE.has(token.toLowerCase()) || /^0x0+$/.test(token)) return WSOL_MINT;
18
+ const bySymbol = ccAsset(SOLANA_CAIP2, token);
19
+ if (bySymbol) return bySymbol.contract ?? WSOL_MINT;
20
+ const byMint = BASE58.test(token) ? ccAssetByToken(SOLANA_CAIP2, token) : void 0;
21
+ if (byMint) return byMint.contract ?? WSOL_MINT;
22
+ return BASE58.test(token) ? token : null;
23
+ }
24
+ var jupiter = {
25
+ supportsChain: (chain) => chain === SOLANA_CAIP2,
26
+ supports: (from, to) => from === SOLANA_CAIP2 && to === SOLANA_CAIP2
27
+ };
28
+
29
+ export {
30
+ JUPITER_API_DEFAULT,
31
+ JUPITER_PROGRAM,
32
+ COMPUTE_BUDGET_PROGRAM,
33
+ SYSTEM_PROGRAM,
34
+ TOKEN_PROGRAM,
35
+ TOKEN_2022_PROGRAM,
36
+ ATA_PROGRAM,
37
+ WSOL_MINT,
38
+ JUPITER_TX_PROGRAMS,
39
+ SOLANA_CAIP2,
40
+ SOLANA_CHAINS,
41
+ jupiterMint,
42
+ jupiter
43
+ };
44
+ //# sourceMappingURL=chunk-OVLAYYGP.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/config.ts"],"sourcesContent":["/**\n * Jupiter (Solana) — Swap API V2, Router path (`GET /swap/v2/build`): Metis on-chain routing, raw instructions, no\n * Jupiter swap fee. The transaction is assembled here and executed by the account's serialized-transaction guard\n * (simulation + balance proof), then broadcast through the wallet's own RPC — Jupiter never lands it for us.\n * Same-chain only: Solana → Solana.\n */\nimport {ccAsset, ccAssetByToken} from \"@anywalletkit/swap2-assets\";\n\nexport const JUPITER_API_DEFAULT = \"https://api.jup.ag/swap/v2\";\n\n/** Jupiter Aggregator v6 — the only program a swap instruction may target. */\nexport const JUPITER_PROGRAM = \"JUP6LkbZbjS1jKKwapdHNy74zcZ3tLUZoi5QNyVTaV4\";\nexport const COMPUTE_BUDGET_PROGRAM = \"ComputeBudget111111111111111111111111111111\";\nexport const SYSTEM_PROGRAM = \"11111111111111111111111111111111\";\nexport const TOKEN_PROGRAM = \"TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA\";\nexport const TOKEN_2022_PROGRAM = \"TokenzQdBNbLqP5VEhdkAS6EPFLC1PHnBqCXEpPxuEb\";\nexport const ATA_PROGRAM = \"ATokenGPvbdGVxr1b2hvZbsiqW5xWH25efTNsLJA8knL\";\n/** Wrapped SOL: Jupiter's name for native SOL (it wraps / unwraps around the swap). */\nexport const WSOL_MINT = \"So11111111111111111111111111111111111111112\";\n\n/** Programs the /build instructions may invoke; anything else refuses the quote before the wallet sees it. */\nexport const JUPITER_TX_PROGRAMS: ReadonlySet<string> = new Set([JUPITER_PROGRAM, COMPUTE_BUDGET_PROGRAM, SYSTEM_PROGRAM, TOKEN_PROGRAM, TOKEN_2022_PROGRAM, ATA_PROGRAM]);\n\n/** swap2 names Solana `solana:mainnet`; wallet history uses the genesis-hash form. */\nexport const SOLANA_CAIP2 = \"solana:mainnet\";\nexport const SOLANA_CHAINS: ReadonlySet<string> = new Set([SOLANA_CAIP2, \"solana:5eykt4UsFv8P8NJdTREpY1vzqKqZKvdp\"]);\n\nconst BASE58 = /^[1-9A-HJ-NP-Za-km-z]{32,44}$/;\nconst NATIVE = new Set([\"\", \"native\", \"sol\", SYSTEM_PROGRAM, WSOL_MINT.toLowerCase(), \"0x0000000000000000000000000000000000000000\"]);\n\n/** A swap2 token ref on Solana (catalog symbol, mint, or a native marker) → the mint Jupiter quotes; null when unknown. */\nexport function jupiterMint(token: string): string | null {\n if (NATIVE.has(token.toLowerCase()) || /^0x0+$/.test(token)) return WSOL_MINT;\n const bySymbol = ccAsset(SOLANA_CAIP2, token);\n if (bySymbol) return bySymbol.contract ?? WSOL_MINT;\n const byMint = BASE58.test(token) ? ccAssetByToken(SOLANA_CAIP2, token) : undefined;\n if (byMint) return byMint.contract ?? WSOL_MINT;\n return BASE58.test(token) ? token : null;\n}\n\nexport const jupiter = {\n supportsChain: (chain: string) => chain === SOLANA_CAIP2,\n supports: (from: string, to: string) => from === SOLANA_CAIP2 && to === SOLANA_CAIP2,\n};\n"],"mappings":";AAMA,SAAQ,SAAS,sBAAqB;AAE/B,IAAM,sBAAsB;AAG5B,IAAM,kBAAkB;AACxB,IAAM,yBAAyB;AAC/B,IAAM,iBAAiB;AACvB,IAAM,gBAAgB;AACtB,IAAM,qBAAqB;AAC3B,IAAM,cAAc;AAEpB,IAAM,YAAY;AAGlB,IAAM,sBAA2C,oBAAI,IAAI,CAAC,iBAAiB,wBAAwB,gBAAgB,eAAe,oBAAoB,WAAW,CAAC;AAGlK,IAAM,eAAe;AACrB,IAAM,gBAAqC,oBAAI,IAAI,CAAC,cAAc,yCAAyC,CAAC;AAEnH,IAAM,SAAS;AACf,IAAM,SAAS,oBAAI,IAAI,CAAC,IAAI,UAAU,OAAO,gBAAgB,UAAU,YAAY,GAAG,4CAA4C,CAAC;AAG5H,SAAS,YAAY,OAA8B;AACxD,MAAI,OAAO,IAAI,MAAM,YAAY,CAAC,KAAK,SAAS,KAAK,KAAK,EAAG,QAAO;AACpE,QAAM,WAAW,QAAQ,cAAc,KAAK;AAC5C,MAAI,SAAU,QAAO,SAAS,YAAY;AAC1C,QAAM,SAAS,OAAO,KAAK,KAAK,IAAI,eAAe,cAAc,KAAK,IAAI;AAC1E,MAAI,OAAQ,QAAO,OAAO,YAAY;AACtC,SAAO,OAAO,KAAK,KAAK,IAAI,QAAQ;AACtC;AAEO,IAAM,UAAU;AAAA,EACrB,eAAe,CAAC,UAAkB,UAAU;AAAA,EAC5C,UAAU,CAAC,MAAc,OAAe,SAAS,gBAAgB,OAAO;AAC1E;","names":[]}
@@ -0,0 +1,27 @@
1
+ import {
2
+ jupiterProvider
3
+ } from "./chunk-NESHFKWY.js";
4
+ import {
5
+ jupiter
6
+ } from "./chunk-OVLAYYGP.js";
7
+
8
+ // src/protocol.ts
9
+ import { SingleProviderSwap2 } from "@anywalletkit/protocol-swap2-core/swap2/single";
10
+ var JupiterSwap2Protocol = class extends SingleProviderSwap2 {
11
+ provider;
12
+ constructor(account, config) {
13
+ super(account, config);
14
+ this.provider = jupiterProvider(config);
15
+ }
16
+ chainSupported(caip2) {
17
+ return jupiter.supportsChain(caip2);
18
+ }
19
+ pairSupported(fromChain, toChain) {
20
+ return jupiter.supports(fromChain, toChain);
21
+ }
22
+ };
23
+
24
+ export {
25
+ JupiterSwap2Protocol
26
+ };
27
+ //# sourceMappingURL=chunk-RSAOKVP2.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/protocol.ts"],"sourcesContent":["import {SingleProviderSwap2} from \"@anywalletkit/protocol-swap2-core/swap2/single\";\nimport type {Swap2Account, Swap2EngineConfig} from \"@anywalletkit/protocol-swap2-core/swap2/base\";\nimport {jupiter as jupCfg} from \"./config.js\";\nimport {jupiterProvider, type JupiterProviderConfig} from \"./provider.js\";\n\nexport interface JupiterSwap2Config extends Swap2EngineConfig, JupiterProviderConfig {}\n\n/** Standalone Jupiter swap2: same-chain Solana swaps (Metis routing, /build, no Jupiter fee). */\nexport class JupiterSwap2Protocol extends SingleProviderSwap2 {\n protected readonly provider;\n constructor(account: Swap2Account | undefined, config: JupiterSwap2Config) {\n super(account, config);\n this.provider = jupiterProvider(config);\n }\n protected override chainSupported(caip2: string): boolean {\n return jupCfg.supportsChain(caip2);\n }\n protected override pairSupported(fromChain: string, toChain: string): boolean {\n return jupCfg.supports(fromChain, toChain);\n }\n}\n"],"mappings":";;;;;;;;AAAA,SAAQ,2BAA0B;AAQ3B,IAAM,uBAAN,cAAmC,oBAAoB;AAAA,EACzC;AAAA,EACnB,YAAY,SAAmC,QAA4B;AACzE,UAAM,SAAS,MAAM;AACrB,SAAK,WAAW,gBAAgB,MAAM;AAAA,EACxC;AAAA,EACmB,eAAe,OAAwB;AACxD,WAAO,QAAO,cAAc,KAAK;AAAA,EACnC;AAAA,EACmB,cAAc,WAAmB,SAA0B;AAC5E,WAAO,QAAO,SAAS,WAAW,OAAO;AAAA,EAC3C;AACF;","names":[]}
package/dist/codec.cjs ADDED
@@ -0,0 +1,76 @@
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/codec.ts
21
+ var codec_exports = {};
22
+ __export(codec_exports, {
23
+ ROUTE_V2: () => ROUTE_V2,
24
+ SHARED_ACCOUNTS_ROUTE_V2: () => SHARED_ACCOUNTS_ROUTE_V2,
25
+ decodeComputeBudget: () => decodeComputeBudget,
26
+ decodeSwapArgs: () => decodeSwapArgs,
27
+ fromBase64: () => fromBase64,
28
+ minOutOf: () => minOutOf,
29
+ setComputeUnitLimit: () => setComputeUnitLimit,
30
+ setComputeUnitPrice: () => setComputeUnitPrice,
31
+ toBase64: () => toBase64
32
+ });
33
+ module.exports = __toCommonJS(codec_exports);
34
+ var import_base = require("@scure/base");
35
+ var ROUTE_V2 = "bb64facc31c4af14";
36
+ var SHARED_ACCOUNTS_ROUTE_V2 = "d19853937cfed8e9";
37
+ var hex = (b) => Array.from(b, (x) => x.toString(16).padStart(2, "0")).join("");
38
+ var u64 = (d, o) => new DataView(d.buffer, d.byteOffset + o, 8).getBigUint64(0, true);
39
+ var u16 = (d, o) => new DataView(d.buffer, d.byteOffset + o, 2).getUint16(0, true);
40
+ var fromBase64 = (s) => import_base.base64.decode(s);
41
+ var toBase64 = (b) => import_base.base64.encode(b);
42
+ function decodeSwapArgs(data) {
43
+ const disc = hex(data.subarray(0, 8));
44
+ const at = disc === ROUTE_V2 ? 8 : disc === SHARED_ACCOUNTS_ROUTE_V2 ? 9 : -1;
45
+ if (at < 0) throw new Error(`unsupported Jupiter instruction ${disc}`);
46
+ if (data.length < at + 22 + 4) throw new Error("Jupiter swap instruction is truncated");
47
+ return {
48
+ kind: at === 8 ? "route_v2" : "shared_accounts_route_v2",
49
+ inAmount: u64(data, at),
50
+ quotedOutAmount: u64(data, at + 8),
51
+ slippageBps: u16(data, at + 16),
52
+ platformFeeBps: u16(data, at + 18),
53
+ positiveSlippageBps: u16(data, at + 20)
54
+ };
55
+ }
56
+ function minOutOf(quotedOut, slippageBps) {
57
+ return quotedOut * BigInt(1e4 - slippageBps) / 10000n;
58
+ }
59
+ function decodeComputeBudget(data) {
60
+ if (data[0] === 2 && data.length === 5) return { limit: new DataView(data.buffer, data.byteOffset + 1, 4).getUint32(0, true) };
61
+ if (data[0] === 3 && data.length === 9) return { price: u64(data, 1) };
62
+ throw new Error(`unexpected compute-budget instruction ${data[0]}`);
63
+ }
64
+ function setComputeUnitLimit(units) {
65
+ const d = new Uint8Array(5);
66
+ d[0] = 2;
67
+ new DataView(d.buffer).setUint32(1, units, true);
68
+ return d;
69
+ }
70
+ function setComputeUnitPrice(microLamports) {
71
+ const d = new Uint8Array(9);
72
+ d[0] = 3;
73
+ new DataView(d.buffer).setBigUint64(1, microLamports, true);
74
+ return d;
75
+ }
76
+ //# sourceMappingURL=codec.cjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/codec.ts"],"sourcesContent":["/**\n * Byte-level checks of what `/build` returns. The swap instruction is Jupiter v6's Anchor `route_v2` /\n * `shared_accounts_route_v2` (ExactIn): its arguments carry the input amount, the quoted output, the slippage and the\n * platform-fee split that the program enforces on-chain — so they are read back here and must equal the request\n * before the transaction is assembled. Discriminators = sha256(\"global:<name>\")[0..8] (verified 2026-10-23 against\n * live /build answers).\n */\nimport {base64} from \"@scure/base\";\n\n/** `route_v2(in_amount u64, quoted_out_amount u64, slippage_bps u16, platform_fee_bps u16, positive_slippage_bps u16, route_plan Vec)` */\nexport const ROUTE_V2 = \"bb64facc31c4af14\";\n/** `shared_accounts_route_v2(id u8, …the same arguments…)` */\nexport const SHARED_ACCOUNTS_ROUTE_V2 = \"d19853937cfed8e9\";\n\nexport interface JupiterSwapArgs {\n kind: \"route_v2\" | \"shared_accounts_route_v2\";\n inAmount: bigint;\n quotedOutAmount: bigint;\n slippageBps: number;\n platformFeeBps: number;\n positiveSlippageBps: number;\n}\n\nconst hex = (b: Uint8Array) => Array.from(b, (x) => x.toString(16).padStart(2, \"0\")).join(\"\");\nconst u64 = (d: Uint8Array, o: number) => new DataView(d.buffer, d.byteOffset + o, 8).getBigUint64(0, true);\nconst u16 = (d: Uint8Array, o: number) => new DataView(d.buffer, d.byteOffset + o, 2).getUint16(0, true);\n\nexport const fromBase64 = (s: string): Uint8Array => base64.decode(s);\nexport const toBase64 = (b: Uint8Array): string => base64.encode(b);\n\n/** Decode the swap instruction's fixed arguments; throws for any other instruction (ExactOut, legacy v1 routes…). */\nexport function decodeSwapArgs(data: Uint8Array): JupiterSwapArgs {\n const disc = hex(data.subarray(0, 8));\n const at = disc === ROUTE_V2 ? 8 : disc === SHARED_ACCOUNTS_ROUTE_V2 ? 9 : -1;\n if (at < 0) throw new Error(`unsupported Jupiter instruction ${disc}`);\n if (data.length < at + 22 + 4) throw new Error(\"Jupiter swap instruction is truncated\");\n return {\n kind: at === 8 ? \"route_v2\" : \"shared_accounts_route_v2\",\n inAmount: u64(data, at),\n quotedOutAmount: u64(data, at + 8),\n slippageBps: u16(data, at + 16),\n platformFeeBps: u16(data, at + 18),\n positiveSlippageBps: u16(data, at + 20),\n };\n}\n\n/** The worst output the program accepts: quoted · (10 000 − slippage) / 10 000, rounded down (never above the on-chain check). */\nexport function minOutOf(quotedOut: bigint, slippageBps: number): bigint {\n return (quotedOut * BigInt(10_000 - slippageBps)) / 10_000n;\n}\n\n/** ComputeBudget instructions: 2 = SetComputeUnitLimit(u32), 3 = SetComputeUnitPrice(u64 micro-lamports). */\nexport function decodeComputeBudget(data: Uint8Array): {limit?: number; price?: bigint} {\n if (data[0] === 2 && data.length === 5) return {limit: new DataView(data.buffer, data.byteOffset + 1, 4).getUint32(0, true)};\n if (data[0] === 3 && data.length === 9) return {price: u64(data, 1)};\n throw new Error(`unexpected compute-budget instruction ${data[0]}`);\n}\n\nexport function setComputeUnitLimit(units: number): Uint8Array {\n const d = new Uint8Array(5);\n d[0] = 2;\n new DataView(d.buffer).setUint32(1, units, true);\n return d;\n}\n\nexport function setComputeUnitPrice(microLamports: bigint): Uint8Array {\n const d = new Uint8Array(9);\n d[0] = 3;\n new DataView(d.buffer).setBigUint64(1, microLamports, true);\n return d;\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAOA,kBAAqB;AAGd,IAAM,WAAW;AAEjB,IAAM,2BAA2B;AAWxC,IAAM,MAAM,CAAC,MAAkB,MAAM,KAAK,GAAG,CAAC,MAAM,EAAE,SAAS,EAAE,EAAE,SAAS,GAAG,GAAG,CAAC,EAAE,KAAK,EAAE;AAC5F,IAAM,MAAM,CAAC,GAAe,MAAc,IAAI,SAAS,EAAE,QAAQ,EAAE,aAAa,GAAG,CAAC,EAAE,aAAa,GAAG,IAAI;AAC1G,IAAM,MAAM,CAAC,GAAe,MAAc,IAAI,SAAS,EAAE,QAAQ,EAAE,aAAa,GAAG,CAAC,EAAE,UAAU,GAAG,IAAI;AAEhG,IAAM,aAAa,CAAC,MAA0B,mBAAO,OAAO,CAAC;AAC7D,IAAM,WAAW,CAAC,MAA0B,mBAAO,OAAO,CAAC;AAG3D,SAAS,eAAe,MAAmC;AAChE,QAAM,OAAO,IAAI,KAAK,SAAS,GAAG,CAAC,CAAC;AACpC,QAAM,KAAK,SAAS,WAAW,IAAI,SAAS,2BAA2B,IAAI;AAC3E,MAAI,KAAK,EAAG,OAAM,IAAI,MAAM,mCAAmC,IAAI,EAAE;AACrE,MAAI,KAAK,SAAS,KAAK,KAAK,EAAG,OAAM,IAAI,MAAM,uCAAuC;AACtF,SAAO;AAAA,IACL,MAAM,OAAO,IAAI,aAAa;AAAA,IAC9B,UAAU,IAAI,MAAM,EAAE;AAAA,IACtB,iBAAiB,IAAI,MAAM,KAAK,CAAC;AAAA,IACjC,aAAa,IAAI,MAAM,KAAK,EAAE;AAAA,IAC9B,gBAAgB,IAAI,MAAM,KAAK,EAAE;AAAA,IACjC,qBAAqB,IAAI,MAAM,KAAK,EAAE;AAAA,EACxC;AACF;AAGO,SAAS,SAAS,WAAmB,aAA6B;AACvE,SAAQ,YAAY,OAAO,MAAS,WAAW,IAAK;AACtD;AAGO,SAAS,oBAAoB,MAAoD;AACtF,MAAI,KAAK,CAAC,MAAM,KAAK,KAAK,WAAW,EAAG,QAAO,EAAC,OAAO,IAAI,SAAS,KAAK,QAAQ,KAAK,aAAa,GAAG,CAAC,EAAE,UAAU,GAAG,IAAI,EAAC;AAC3H,MAAI,KAAK,CAAC,MAAM,KAAK,KAAK,WAAW,EAAG,QAAO,EAAC,OAAO,IAAI,MAAM,CAAC,EAAC;AACnE,QAAM,IAAI,MAAM,yCAAyC,KAAK,CAAC,CAAC,EAAE;AACpE;AAEO,SAAS,oBAAoB,OAA2B;AAC7D,QAAM,IAAI,IAAI,WAAW,CAAC;AAC1B,IAAE,CAAC,IAAI;AACP,MAAI,SAAS,EAAE,MAAM,EAAE,UAAU,GAAG,OAAO,IAAI;AAC/C,SAAO;AACT;AAEO,SAAS,oBAAoB,eAAmC;AACrE,QAAM,IAAI,IAAI,WAAW,CAAC;AAC1B,IAAE,CAAC,IAAI;AACP,MAAI,SAAS,EAAE,MAAM,EAAE,aAAa,GAAG,eAAe,IAAI;AAC1D,SAAO;AACT;","names":[]}
@@ -0,0 +1,27 @@
1
+ /** `route_v2(in_amount u64, quoted_out_amount u64, slippage_bps u16, platform_fee_bps u16, positive_slippage_bps u16, route_plan Vec)` */
2
+ declare const ROUTE_V2 = "bb64facc31c4af14";
3
+ /** `shared_accounts_route_v2(id u8, …the same arguments…)` */
4
+ declare const SHARED_ACCOUNTS_ROUTE_V2 = "d19853937cfed8e9";
5
+ interface JupiterSwapArgs {
6
+ kind: "route_v2" | "shared_accounts_route_v2";
7
+ inAmount: bigint;
8
+ quotedOutAmount: bigint;
9
+ slippageBps: number;
10
+ platformFeeBps: number;
11
+ positiveSlippageBps: number;
12
+ }
13
+ declare const fromBase64: (s: string) => Uint8Array;
14
+ declare const toBase64: (b: Uint8Array) => string;
15
+ /** Decode the swap instruction's fixed arguments; throws for any other instruction (ExactOut, legacy v1 routes…). */
16
+ declare function decodeSwapArgs(data: Uint8Array): JupiterSwapArgs;
17
+ /** The worst output the program accepts: quoted · (10 000 − slippage) / 10 000, rounded down (never above the on-chain check). */
18
+ declare function minOutOf(quotedOut: bigint, slippageBps: number): bigint;
19
+ /** ComputeBudget instructions: 2 = SetComputeUnitLimit(u32), 3 = SetComputeUnitPrice(u64 micro-lamports). */
20
+ declare function decodeComputeBudget(data: Uint8Array): {
21
+ limit?: number;
22
+ price?: bigint;
23
+ };
24
+ declare function setComputeUnitLimit(units: number): Uint8Array;
25
+ declare function setComputeUnitPrice(microLamports: bigint): Uint8Array;
26
+
27
+ export { type JupiterSwapArgs, ROUTE_V2, SHARED_ACCOUNTS_ROUTE_V2, decodeComputeBudget, decodeSwapArgs, fromBase64, minOutOf, setComputeUnitLimit, setComputeUnitPrice, toBase64 };
@@ -0,0 +1,27 @@
1
+ /** `route_v2(in_amount u64, quoted_out_amount u64, slippage_bps u16, platform_fee_bps u16, positive_slippage_bps u16, route_plan Vec)` */
2
+ declare const ROUTE_V2 = "bb64facc31c4af14";
3
+ /** `shared_accounts_route_v2(id u8, …the same arguments…)` */
4
+ declare const SHARED_ACCOUNTS_ROUTE_V2 = "d19853937cfed8e9";
5
+ interface JupiterSwapArgs {
6
+ kind: "route_v2" | "shared_accounts_route_v2";
7
+ inAmount: bigint;
8
+ quotedOutAmount: bigint;
9
+ slippageBps: number;
10
+ platformFeeBps: number;
11
+ positiveSlippageBps: number;
12
+ }
13
+ declare const fromBase64: (s: string) => Uint8Array;
14
+ declare const toBase64: (b: Uint8Array) => string;
15
+ /** Decode the swap instruction's fixed arguments; throws for any other instruction (ExactOut, legacy v1 routes…). */
16
+ declare function decodeSwapArgs(data: Uint8Array): JupiterSwapArgs;
17
+ /** The worst output the program accepts: quoted · (10 000 − slippage) / 10 000, rounded down (never above the on-chain check). */
18
+ declare function minOutOf(quotedOut: bigint, slippageBps: number): bigint;
19
+ /** ComputeBudget instructions: 2 = SetComputeUnitLimit(u32), 3 = SetComputeUnitPrice(u64 micro-lamports). */
20
+ declare function decodeComputeBudget(data: Uint8Array): {
21
+ limit?: number;
22
+ price?: bigint;
23
+ };
24
+ declare function setComputeUnitLimit(units: number): Uint8Array;
25
+ declare function setComputeUnitPrice(microLamports: bigint): Uint8Array;
26
+
27
+ export { type JupiterSwapArgs, ROUTE_V2, SHARED_ACCOUNTS_ROUTE_V2, decodeComputeBudget, decodeSwapArgs, fromBase64, minOutOf, setComputeUnitLimit, setComputeUnitPrice, toBase64 };
package/dist/codec.js ADDED
@@ -0,0 +1,23 @@
1
+ import {
2
+ ROUTE_V2,
3
+ SHARED_ACCOUNTS_ROUTE_V2,
4
+ decodeComputeBudget,
5
+ decodeSwapArgs,
6
+ fromBase64,
7
+ minOutOf,
8
+ setComputeUnitLimit,
9
+ setComputeUnitPrice,
10
+ toBase64
11
+ } from "./chunk-5JXNDQHW.js";
12
+ export {
13
+ ROUTE_V2,
14
+ SHARED_ACCOUNTS_ROUTE_V2,
15
+ decodeComputeBudget,
16
+ decodeSwapArgs,
17
+ fromBase64,
18
+ minOutOf,
19
+ setComputeUnitLimit,
20
+ setComputeUnitPrice,
21
+ toBase64
22
+ };
23
+ //# sourceMappingURL=codec.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":[],"sourcesContent":[],"mappings":"","names":[]}
@@ -0,0 +1,64 @@
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/config.ts
21
+ var config_exports = {};
22
+ __export(config_exports, {
23
+ ATA_PROGRAM: () => ATA_PROGRAM,
24
+ COMPUTE_BUDGET_PROGRAM: () => COMPUTE_BUDGET_PROGRAM,
25
+ JUPITER_API_DEFAULT: () => JUPITER_API_DEFAULT,
26
+ JUPITER_PROGRAM: () => JUPITER_PROGRAM,
27
+ JUPITER_TX_PROGRAMS: () => JUPITER_TX_PROGRAMS,
28
+ SOLANA_CAIP2: () => SOLANA_CAIP2,
29
+ SOLANA_CHAINS: () => SOLANA_CHAINS,
30
+ SYSTEM_PROGRAM: () => SYSTEM_PROGRAM,
31
+ TOKEN_2022_PROGRAM: () => TOKEN_2022_PROGRAM,
32
+ TOKEN_PROGRAM: () => TOKEN_PROGRAM,
33
+ WSOL_MINT: () => WSOL_MINT,
34
+ jupiter: () => jupiter,
35
+ jupiterMint: () => jupiterMint
36
+ });
37
+ module.exports = __toCommonJS(config_exports);
38
+ var import_swap2_assets = require("@anywalletkit/swap2-assets");
39
+ var JUPITER_API_DEFAULT = "https://api.jup.ag/swap/v2";
40
+ var JUPITER_PROGRAM = "JUP6LkbZbjS1jKKwapdHNy74zcZ3tLUZoi5QNyVTaV4";
41
+ var COMPUTE_BUDGET_PROGRAM = "ComputeBudget111111111111111111111111111111";
42
+ var SYSTEM_PROGRAM = "11111111111111111111111111111111";
43
+ var TOKEN_PROGRAM = "TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA";
44
+ var TOKEN_2022_PROGRAM = "TokenzQdBNbLqP5VEhdkAS6EPFLC1PHnBqCXEpPxuEb";
45
+ var ATA_PROGRAM = "ATokenGPvbdGVxr1b2hvZbsiqW5xWH25efTNsLJA8knL";
46
+ var WSOL_MINT = "So11111111111111111111111111111111111111112";
47
+ var JUPITER_TX_PROGRAMS = /* @__PURE__ */ new Set([JUPITER_PROGRAM, COMPUTE_BUDGET_PROGRAM, SYSTEM_PROGRAM, TOKEN_PROGRAM, TOKEN_2022_PROGRAM, ATA_PROGRAM]);
48
+ var SOLANA_CAIP2 = "solana:mainnet";
49
+ var SOLANA_CHAINS = /* @__PURE__ */ new Set([SOLANA_CAIP2, "solana:5eykt4UsFv8P8NJdTREpY1vzqKqZKvdp"]);
50
+ var BASE58 = /^[1-9A-HJ-NP-Za-km-z]{32,44}$/;
51
+ var NATIVE = /* @__PURE__ */ new Set(["", "native", "sol", SYSTEM_PROGRAM, WSOL_MINT.toLowerCase(), "0x0000000000000000000000000000000000000000"]);
52
+ function jupiterMint(token) {
53
+ if (NATIVE.has(token.toLowerCase()) || /^0x0+$/.test(token)) return WSOL_MINT;
54
+ const bySymbol = (0, import_swap2_assets.ccAsset)(SOLANA_CAIP2, token);
55
+ if (bySymbol) return bySymbol.contract ?? WSOL_MINT;
56
+ const byMint = BASE58.test(token) ? (0, import_swap2_assets.ccAssetByToken)(SOLANA_CAIP2, token) : void 0;
57
+ if (byMint) return byMint.contract ?? WSOL_MINT;
58
+ return BASE58.test(token) ? token : null;
59
+ }
60
+ var jupiter = {
61
+ supportsChain: (chain) => chain === SOLANA_CAIP2,
62
+ supports: (from, to) => from === SOLANA_CAIP2 && to === SOLANA_CAIP2
63
+ };
64
+ //# sourceMappingURL=config.cjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/config.ts"],"sourcesContent":["/**\n * Jupiter (Solana) — Swap API V2, Router path (`GET /swap/v2/build`): Metis on-chain routing, raw instructions, no\n * Jupiter swap fee. The transaction is assembled here and executed by the account's serialized-transaction guard\n * (simulation + balance proof), then broadcast through the wallet's own RPC — Jupiter never lands it for us.\n * Same-chain only: Solana → Solana.\n */\nimport {ccAsset, ccAssetByToken} from \"@anywalletkit/swap2-assets\";\n\nexport const JUPITER_API_DEFAULT = \"https://api.jup.ag/swap/v2\";\n\n/** Jupiter Aggregator v6 — the only program a swap instruction may target. */\nexport const JUPITER_PROGRAM = \"JUP6LkbZbjS1jKKwapdHNy74zcZ3tLUZoi5QNyVTaV4\";\nexport const COMPUTE_BUDGET_PROGRAM = \"ComputeBudget111111111111111111111111111111\";\nexport const SYSTEM_PROGRAM = \"11111111111111111111111111111111\";\nexport const TOKEN_PROGRAM = \"TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA\";\nexport const TOKEN_2022_PROGRAM = \"TokenzQdBNbLqP5VEhdkAS6EPFLC1PHnBqCXEpPxuEb\";\nexport const ATA_PROGRAM = \"ATokenGPvbdGVxr1b2hvZbsiqW5xWH25efTNsLJA8knL\";\n/** Wrapped SOL: Jupiter's name for native SOL (it wraps / unwraps around the swap). */\nexport const WSOL_MINT = \"So11111111111111111111111111111111111111112\";\n\n/** Programs the /build instructions may invoke; anything else refuses the quote before the wallet sees it. */\nexport const JUPITER_TX_PROGRAMS: ReadonlySet<string> = new Set([JUPITER_PROGRAM, COMPUTE_BUDGET_PROGRAM, SYSTEM_PROGRAM, TOKEN_PROGRAM, TOKEN_2022_PROGRAM, ATA_PROGRAM]);\n\n/** swap2 names Solana `solana:mainnet`; wallet history uses the genesis-hash form. */\nexport const SOLANA_CAIP2 = \"solana:mainnet\";\nexport const SOLANA_CHAINS: ReadonlySet<string> = new Set([SOLANA_CAIP2, \"solana:5eykt4UsFv8P8NJdTREpY1vzqKqZKvdp\"]);\n\nconst BASE58 = /^[1-9A-HJ-NP-Za-km-z]{32,44}$/;\nconst NATIVE = new Set([\"\", \"native\", \"sol\", SYSTEM_PROGRAM, WSOL_MINT.toLowerCase(), \"0x0000000000000000000000000000000000000000\"]);\n\n/** A swap2 token ref on Solana (catalog symbol, mint, or a native marker) → the mint Jupiter quotes; null when unknown. */\nexport function jupiterMint(token: string): string | null {\n if (NATIVE.has(token.toLowerCase()) || /^0x0+$/.test(token)) return WSOL_MINT;\n const bySymbol = ccAsset(SOLANA_CAIP2, token);\n if (bySymbol) return bySymbol.contract ?? WSOL_MINT;\n const byMint = BASE58.test(token) ? ccAssetByToken(SOLANA_CAIP2, token) : undefined;\n if (byMint) return byMint.contract ?? WSOL_MINT;\n return BASE58.test(token) ? token : null;\n}\n\nexport const jupiter = {\n supportsChain: (chain: string) => chain === SOLANA_CAIP2,\n supports: (from: string, to: string) => from === SOLANA_CAIP2 && to === SOLANA_CAIP2,\n};\n"],"mappings":";;;;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAMA,0BAAsC;AAE/B,IAAM,sBAAsB;AAG5B,IAAM,kBAAkB;AACxB,IAAM,yBAAyB;AAC/B,IAAM,iBAAiB;AACvB,IAAM,gBAAgB;AACtB,IAAM,qBAAqB;AAC3B,IAAM,cAAc;AAEpB,IAAM,YAAY;AAGlB,IAAM,sBAA2C,oBAAI,IAAI,CAAC,iBAAiB,wBAAwB,gBAAgB,eAAe,oBAAoB,WAAW,CAAC;AAGlK,IAAM,eAAe;AACrB,IAAM,gBAAqC,oBAAI,IAAI,CAAC,cAAc,yCAAyC,CAAC;AAEnH,IAAM,SAAS;AACf,IAAM,SAAS,oBAAI,IAAI,CAAC,IAAI,UAAU,OAAO,gBAAgB,UAAU,YAAY,GAAG,4CAA4C,CAAC;AAG5H,SAAS,YAAY,OAA8B;AACxD,MAAI,OAAO,IAAI,MAAM,YAAY,CAAC,KAAK,SAAS,KAAK,KAAK,EAAG,QAAO;AACpE,QAAM,eAAW,6BAAQ,cAAc,KAAK;AAC5C,MAAI,SAAU,QAAO,SAAS,YAAY;AAC1C,QAAM,SAAS,OAAO,KAAK,KAAK,QAAI,oCAAe,cAAc,KAAK,IAAI;AAC1E,MAAI,OAAQ,QAAO,OAAO,YAAY;AACtC,SAAO,OAAO,KAAK,KAAK,IAAI,QAAQ;AACtC;AAEO,IAAM,UAAU;AAAA,EACrB,eAAe,CAAC,UAAkB,UAAU;AAAA,EAC5C,UAAU,CAAC,MAAc,OAAe,SAAS,gBAAgB,OAAO;AAC1E;","names":[]}