@anywalletkit/protocol-swap2-jupiter 0.3.7 → 0.3.9

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/provider.cjs CHANGED
@@ -137,6 +137,7 @@ function assembleTransaction(input) {
137
137
  }
138
138
 
139
139
  // src/provider.ts
140
+ var import_errors = require("@anywalletkit/protocol-swap2-core/errors");
140
141
  var import_util = require("@anywalletkit/protocol-swap2-core/util");
141
142
  var DEFAULT_SLIPPAGE_BPS = 50;
142
143
  var MAX_SLIPPAGE_BPS = 1e3;
@@ -146,12 +147,37 @@ var DEFAULT_MAX_CU_PRICE = 2000000n;
146
147
  var BASE_FEE_LAMPORTS = 5000n;
147
148
  var DRY_TAKER = "9WzDXwBbmkg8ZTbNMqUxvQRAyrZzDsGYdLVL9zYtAWWM";
148
149
  var BASE582 = /^[1-9A-HJ-NP-Za-km-z]{32,44}$/;
150
+ var RETRY_AFTER_MAX_MS = 864e5;
149
151
  var INTENT_PREFIX = "jup:";
152
+ var notes = (0, import_errors.refusalNotes)();
153
+ function buildRefusal(status, body, retryAfter, rateReset) {
154
+ const byStatus = (0, import_errors.httpRefusal)(status, retryAfter);
155
+ if (byStatus?.reason === "rate_limited") {
156
+ if (byStatus.retryAfterMs !== void 0 || rateReset === null) return byStatus;
157
+ const wait = Number(rateReset) * 1e3 - Date.now();
158
+ return Number.isFinite(wait) && wait > 0 ? { ...byStatus, retryAfterMs: Math.min(Math.ceil(wait), RETRY_AFTER_MAX_MS) } : byStatus;
159
+ }
160
+ const said = answerReason(body);
161
+ return said && said !== byStatus?.reason ? { reason: said } : byStatus;
162
+ }
163
+ function answerReason(body) {
164
+ const b = body;
165
+ const text = `${typeof b?.errorCode === "string" ? b.errorCode : ""} ${typeof b?.error === "string" ? b.error : ""}`;
166
+ if (/COULD_NOT_FIND_ANY_ROUTE|NO_ROUTES_FOUND|could not find any route|no routes? found/i.test(text)) return "no_route";
167
+ if (/ROUTE_PLAN_DOES_NOT_CONSUME_ALL_THE_AMOUNT|liquidity/i.test(text)) return "insufficient_liquidity";
168
+ if (/TOKEN_NOT_TRADABLE|not tradable|MARKET_NOT_FOUND|CIRCULAR_ARBITRAGE|not supported|unsupported/i.test(text)) return "unsupported_pair";
169
+ if (/too small|too low|below the minimum/i.test(text)) return "amount_too_small";
170
+ if (/too large|too big|above the maximum/i.test(text)) return "amount_too_large";
171
+ if (/rate.?limit|too many requests/i.test(text)) return "rate_limited";
172
+ if (/api.?key|unauthori[sz]ed/i.test(text)) return "key_rejected";
173
+ return void 0;
174
+ }
150
175
  function jupiterProvider(config = {}) {
151
176
  config = Object.freeze({ ...config });
152
177
  const base = (config.apiUrl ?? JUPITER_API_DEFAULT).replace(/\/$/, "");
153
178
  const maxPrice = config.maxComputeUnitPrice ?? DEFAULT_MAX_CU_PRICE;
154
179
  const rpcUrls = config.rpcUrls ?? [];
180
+ const baseIsUrl = /^(?:https?:\/\/[^/\s]+|\/)/i.test(base);
155
181
  const get = async (path, signal) => {
156
182
  for (let attempt = 0; ; attempt++) {
157
183
  const res = await fetch(`${base}${path}`, { headers: { accept: "application/json", ...config.apiKey ? { "x-api-key": config.apiKey } : {} }, signal: signal ?? (0, import_util.timeoutSignal)(12e3) });
@@ -162,7 +188,7 @@ function jupiterProvider(config = {}) {
162
188
  await new Promise((r) => setTimeout(r, wait));
163
189
  continue;
164
190
  }
165
- return { ok: res.ok, status: res.status, body };
191
+ return { ok: res.ok, status: res.status, body, retryAfter: res.headers?.get?.("retry-after") ?? null, rateReset: res.headers?.get?.("x-ratelimit-reset") ?? null };
166
192
  }
167
193
  };
168
194
  const rpc = async (method, params) => {
@@ -183,60 +209,63 @@ function jupiterProvider(config = {}) {
183
209
  const data = fromBase64(ix.data ?? "");
184
210
  const acc = (i) => ix.accounts[i]?.pubkey;
185
211
  if (ix.programId === ATA_PROGRAM) {
186
- if (data.length !== 1 || data[0] !== 1) return "an associated-token instruction other than CreateIdempotent";
187
- if (acc(0) !== want.taker || acc(2) !== want.taker) return "an associated token account for someone else";
212
+ if (data.length !== 1 || data[0] !== 1) return notes.note("an associated-token instruction other than CreateIdempotent", "policy_refused");
213
+ if (acc(0) !== want.taker || acc(2) !== want.taker) return notes.note("an associated token account for someone else", "recipient_mismatch");
188
214
  return null;
189
215
  }
190
216
  if (ix.programId === SYSTEM_PROGRAM) {
191
- if (data.length !== 12 || data[0] !== 2 || data[1] !== 0 || data[2] !== 0 || data[3] !== 0) return "a System instruction other than Transfer";
192
- if (want.inputMint !== WSOL_MINT) return "a SOL transfer on a token-source swap";
217
+ if (data.length !== 12 || data[0] !== 2 || data[1] !== 0 || data[2] !== 0 || data[3] !== 0) return notes.note("a System instruction other than Transfer", "policy_refused");
218
+ if (want.inputMint !== WSOL_MINT) return notes.note("a SOL transfer on a token-source swap", "policy_refused");
193
219
  const lamports = new DataView(data.buffer, data.byteOffset + 4, 8).getBigUint64(0, true);
194
- if (acc(0) !== want.taker || acc(1) !== want.wsolAta) return `a SOL transfer to ${acc(1)}, not the taker's wSOL account`;
195
- if (lamports !== want.amountIn) return `a SOL transfer of ${lamports}, not the ${want.amountIn} input`;
220
+ if (acc(0) !== want.taker || acc(1) !== want.wsolAta) return notes.note(`a SOL transfer to ${acc(1)}, not the taker's wSOL account`, "recipient_mismatch");
221
+ if (lamports !== want.amountIn) return notes.note(`a SOL transfer of ${lamports}, not the ${want.amountIn} input`, "policy_refused");
196
222
  return null;
197
223
  }
198
224
  if (ix.programId === TOKEN_PROGRAM) {
199
- if (data.length === 1 && data[0] === 17) return acc(0) === want.wsolAta ? null : "SyncNative on another account";
225
+ if (data.length === 1 && data[0] === 17) return acc(0) === want.wsolAta ? null : notes.note("SyncNative on another account", "policy_refused");
200
226
  if (data.length === 1 && data[0] === 9) {
201
- return acc(0) === want.wsolAta && acc(1) === want.taker && acc(2) === want.taker ? null : "a CloseAccount that is not the taker's wSOL account back to the taker";
227
+ return acc(0) === want.wsolAta && acc(1) === want.taker && acc(2) === want.taker ? null : notes.note("a CloseAccount that is not the taker's wSOL account back to the taker", "recipient_mismatch");
202
228
  }
203
229
  if (data.length === 33 && data[0] === 18) {
204
- return bytesEqual(data.subarray(1), (0, import_kit2.getAddressEncoder)().encode((0, import_kit2.address)(want.taker))) ? null : "a token account initialized for someone else";
230
+ return bytesEqual(data.subarray(1), (0, import_kit2.getAddressEncoder)().encode((0, import_kit2.address)(want.taker))) ? null : notes.note("a token account initialized for someone else", "recipient_mismatch");
205
231
  }
206
- return `a Token instruction (tag ${data[0] ?? "none"}) the swap does not need`;
232
+ return notes.note(`a Token instruction (tag ${data[0] ?? "none"}) the swap does not need`, "policy_refused");
207
233
  }
208
- if (ix.programId === JUPITER_PROGRAM) return "a second Jupiter instruction";
209
- return `instruction for program ${ix.programId}`;
234
+ if (ix.programId === JUPITER_PROGRAM) return notes.note("a second Jupiter instruction", "policy_refused");
235
+ return notes.note(`instruction for program ${ix.programId}`, "policy_refused");
210
236
  };
211
237
  const vet = (b, want) => {
212
- if (b.swapMode && b.swapMode !== "ExactIn") throw new Error(`swap mode ${b.swapMode}`);
213
- if (b.inputMint !== want.inputMint || b.outputMint !== want.outputMint) throw new Error("the answer names other mints");
214
- if (b.inAmount !== want.amountIn.toString()) throw new Error(`the answer spends ${b.inAmount}, not ${want.amountIn}`);
215
- if (String(b.transactionVersion ?? "0") !== "0") throw new Error(`transaction version ${b.transactionVersion}`);
216
- if (b.tipInstruction) throw new Error("unexpected tip instruction");
217
- if (!b.swapInstruction) throw new Error("no swap instruction");
218
- if (b.swapInstruction.programId !== JUPITER_PROGRAM) throw new Error(`swap instruction targets ${b.swapInstruction.programId}`);
238
+ if (b.swapMode && b.swapMode !== "ExactIn") throw (0, import_errors.refusal)("policy_refused", `swap mode ${b.swapMode}`);
239
+ if (b.inputMint !== want.inputMint || b.outputMint !== want.outputMint) throw (0, import_errors.refusal)("policy_refused", "the answer names other mints");
240
+ if (b.inAmount !== want.amountIn.toString()) throw (0, import_errors.refusal)("policy_refused", `the answer spends ${b.inAmount}, not ${want.amountIn}`);
241
+ if (String(b.transactionVersion ?? "0") !== "0") throw (0, import_errors.refusal)("policy_refused", `transaction version ${b.transactionVersion}`);
242
+ if (b.tipInstruction) throw (0, import_errors.refusal)("policy_refused", "unexpected tip instruction");
243
+ if (!b.swapInstruction) throw (0, import_errors.refusal)("upstream_unavailable", "no swap instruction");
244
+ if (b.swapInstruction.programId !== JUPITER_PROGRAM) throw (0, import_errors.refusal)("vault_mismatch", `swap instruction targets ${b.swapInstruction.programId}`);
219
245
  const args = decodeSwapArgs(fromBase64(b.swapInstruction.data));
220
- if (args.inAmount !== want.amountIn) throw new Error(`swap instruction spends ${args.inAmount}, not ${want.amountIn}`);
221
- if (String(args.quotedOutAmount) !== b.outAmount) throw new Error("swap instruction's quoted output differs from the answer");
222
- if (args.slippageBps !== want.slippageBps) throw new Error(`swap instruction allows ${args.slippageBps} bps slippage, not ${want.slippageBps}`);
223
- if (args.platformFeeBps !== 0 || args.positiveSlippageBps !== 0) throw new Error("swap instruction takes a platform fee");
246
+ if (args.inAmount !== want.amountIn) throw (0, import_errors.refusal)("policy_refused", `swap instruction spends ${args.inAmount}, not ${want.amountIn}`);
247
+ if (String(args.quotedOutAmount) !== b.outAmount) throw (0, import_errors.refusal)("price_check_failed", "swap instruction's quoted output differs from the answer");
248
+ if (args.slippageBps !== want.slippageBps) throw (0, import_errors.refusal)("price_check_failed", `swap instruction allows ${args.slippageBps} bps slippage, not ${want.slippageBps}`);
249
+ if (args.platformFeeBps !== 0 || args.positiveSlippageBps !== 0) throw (0, import_errors.refusal)("policy_refused", "swap instruction takes a platform fee");
224
250
  let price = 0n;
225
251
  for (const ix of b.computeBudgetInstructions ?? []) {
226
- if (ix.programId !== COMPUTE_BUDGET_PROGRAM) throw new Error(`compute-budget slot holds ${ix.programId}`);
252
+ if (ix.programId !== COMPUTE_BUDGET_PROGRAM) throw (0, import_errors.refusal)("policy_refused", `compute-budget slot holds ${ix.programId}`);
227
253
  const d = decodeComputeBudget(fromBase64(ix.data));
228
254
  if (d.price !== void 0) price = d.price;
229
255
  }
230
256
  const instructions = [...b.setupInstructions ?? [], b.swapInstruction, ...b.cleanupInstruction ? [b.cleanupInstruction] : [], ...b.otherInstructions ?? []];
231
257
  let funded = false;
232
258
  for (const ix of instructions) {
233
- if (!JUPITER_TX_PROGRAMS.has(ix.programId) || ix.programId === COMPUTE_BUDGET_PROGRAM) throw new Error(`instruction for program ${ix.programId}`);
234
- for (const a of ix.accounts) if (a.isSigner && a.pubkey !== want.taker) throw new Error(`instruction needs signer ${a.pubkey}`);
259
+ if (!JUPITER_TX_PROGRAMS.has(ix.programId) || ix.programId === COMPUTE_BUDGET_PROGRAM) throw (0, import_errors.refusal)("policy_refused", `instruction for program ${ix.programId}`);
260
+ for (const a of ix.accounts) if (a.isSigner && a.pubkey !== want.taker) throw (0, import_errors.refusal)("policy_refused", `instruction needs signer ${a.pubkey}`);
235
261
  if (ix === b.swapInstruction) continue;
236
262
  const why = shapeRefusal(ix, want);
237
- if (why) throw new Error(why);
263
+ if (why) {
264
+ const info = notes.reasonOf(why);
265
+ throw info ? (0, import_errors.withReason)(new Error(why), info) : new Error(why);
266
+ }
238
267
  if (ix.programId === SYSTEM_PROGRAM) {
239
- if (funded) throw new Error("a second SOL transfer");
268
+ if (funded) throw (0, import_errors.refusal)("policy_refused", "a second SOL transfer");
240
269
  funded = true;
241
270
  }
242
271
  }
@@ -255,9 +284,9 @@ function jupiterProvider(config = {}) {
255
284
  const err = JSON.stringify(r.value.err);
256
285
  const jupiterCode = /JUP6LkbZbjS1jKKwapdHNy74zcZ3tLUZoi5QNyVTaV4 failed/.test(log) ? /"Custom":(\d+)/.exec(err)?.[1] : void 0;
257
286
  if (jupiterCode === "6024" || jupiterCode === "6025" || /"Custom":1\}/.test(err) && /Program 11111111111111111111111111111111 failed/.test(log)) {
258
- throw new Error(`not enough of the input token in the wallet${jupiterCode === "6025" ? " (no token account for it)" : ""} \u2014 simulation fails: ${err}`);
287
+ throw (0, import_errors.refusal)("simulation_failed", `not enough of the input token in the wallet${jupiterCode === "6025" ? " (no token account for it)" : ""} \u2014 simulation fails: ${err}`);
259
288
  }
260
- throw new Error(`simulation fails: ${err}${log ? ` (${log.slice(0, 160)})` : ""}`);
289
+ throw (0, import_errors.refusal)("simulation_failed", `simulation fails: ${err}${log ? ` (${log.slice(0, 160)})` : ""}`);
261
290
  }
262
291
  const used = r?.value?.unitsConsumed;
263
292
  return used ? Math.min(MAX_COMPUTE_UNITS, Math.ceil(used * 1.2)) : null;
@@ -276,23 +305,25 @@ function jupiterProvider(config = {}) {
276
305
  },
277
306
  async getQuote(params, signal) {
278
307
  const dry = params.dry !== false;
279
- const refuse = (reason) => {
280
- params.onRefusal?.(`jupiter: ${reason}`);
308
+ const refuse = (reason, why) => {
309
+ const info = typeof why === "string" ? { reason: why } : why;
310
+ if (info) params.onRefusal?.(`jupiter: ${reason}`, info);
311
+ else params.onRefusal?.(`jupiter: ${reason}`);
281
312
  return null;
282
313
  };
283
- if (!jupiter.supports(params.sourceChain, params.destChain)) return refuse(`same-chain Solana only (${params.sourceChain} \u2192 ${params.destChain})`);
284
- if (params.flex) return refuse("amount-flexible deposits are not supported");
314
+ if (!jupiter.supports(params.sourceChain, params.destChain)) return refuse(`same-chain Solana only (${params.sourceChain} \u2192 ${params.destChain})`, "unsupported_pair");
315
+ if (params.flex) return refuse("amount-flexible deposits are not supported", "unsupported_pair");
285
316
  const inputMint = jupiterMint(params.sourceToken), outputMint = jupiterMint(params.destToken);
286
- if (!inputMint || !outputMint) return refuse(`unknown token (${params.sourceToken} \u2192 ${params.destToken})`);
287
- if (inputMint === outputMint) return refuse("same token on both sides");
317
+ if (!inputMint || !outputMint) return refuse(`unknown token (${params.sourceToken} \u2192 ${params.destToken})`, "unsupported_pair");
318
+ if (inputMint === outputMint) return refuse("same token on both sides", "unsupported_pair");
288
319
  const amountIn = BigInt(params.amountIn);
289
- if (amountIn <= 0n) return refuse("amount must be positive");
320
+ if (amountIn <= 0n) return refuse("amount must be positive", "amount_too_small");
290
321
  const slippageBps = params.slippageBps ?? config.defaultSlippageBps ?? DEFAULT_SLIPPAGE_BPS;
291
- if (!Number.isInteger(slippageBps) || slippageBps < 0 || slippageBps > MAX_SLIPPAGE_BPS) return refuse(`slippage ${slippageBps} bps is out of range`);
322
+ if (!Number.isInteger(slippageBps) || slippageBps < 0 || slippageBps > MAX_SLIPPAGE_BPS) return refuse(`slippage ${slippageBps} bps is out of range`, params.slippageBps !== void 0 && Number.isInteger(slippageBps) && slippageBps > MAX_SLIPPAGE_BPS ? "policy_refused" : void 0);
292
323
  const self = params.refundAddress || params.destAddress;
293
324
  if (!dry) {
294
- if (!self || !BASE582.test(self)) return refuse("live quote without the signer's address");
295
- if (params.destAddress && params.destAddress !== self) return refuse("the recipient must be the signing wallet (Jupiter pays the taker)");
325
+ if (!self || !BASE582.test(self)) return refuse("live quote without the signer's address", !self ? "policy_refused" : void 0);
326
+ if (params.destAddress && params.destAddress !== self) return refuse("the recipient must be the signing wallet (Jupiter pays the taker)", "unsupported_pair");
296
327
  }
297
328
  const taker = self && BASE582.test(self) ? self : DRY_TAKER;
298
329
  const qs = new URLSearchParams({ inputMint, outputMint, amount: params.amountIn, taker, slippageBps: String(slippageBps) });
@@ -300,22 +331,22 @@ function jupiterProvider(config = {}) {
300
331
  let b;
301
332
  try {
302
333
  const r = await get(`/build?${qs.toString()}`, signal);
303
- if (!r.ok) return refuse(`build ${r.status}: ${String(r.body?.error ?? "").slice(0, 160)}`);
334
+ if (!r.ok) return refuse(`build ${r.status}: ${String(r.body?.error ?? "").slice(0, 160)}`, buildRefusal(r.status, r.body, r.retryAfter, r.rateReset));
304
335
  b = r.body ?? {};
305
336
  } catch (e) {
306
- return refuse(`build failed: ${e.message.slice(0, 160)}`);
337
+ return refuse(`build failed: ${e.message.slice(0, 160)}`, signal?.aborted || !baseIsUrl ? void 0 : "upstream_unavailable");
307
338
  }
308
- if (!b.outAmount || !/^\d+$/.test(b.outAmount)) return refuse("answer without an output amount");
339
+ if (!b.outAmount || !/^\d+$/.test(b.outAmount)) return refuse("answer without an output amount", answerReason(b) ?? (signal?.aborted ? void 0 : "upstream_unavailable"));
309
340
  let vetted;
310
341
  const [wsolAta] = await (0, import_kit2.getProgramDerivedAddress)({ programAddress: (0, import_kit2.address)(ATA_PROGRAM), seeds: [(0, import_kit2.getAddressEncoder)().encode((0, import_kit2.address)(taker)), (0, import_kit2.getAddressEncoder)().encode((0, import_kit2.address)(TOKEN_PROGRAM)), (0, import_kit2.getAddressEncoder)().encode((0, import_kit2.address)(WSOL_MINT))] });
311
342
  try {
312
343
  vetted = vet(b, { taker, inputMint, outputMint, amountIn, slippageBps, wsolAta });
313
344
  } catch (e) {
314
- return refuse(e.message);
345
+ return refuse(e.message, (0, import_errors.refusalOf)(e) ?? "upstream_unavailable");
315
346
  }
316
347
  const minOut = minOutOf(vetted.quotedOut, slippageBps);
317
348
  if (params.minAmountOut !== void 0 && minOut < BigInt(params.minAmountOut)) {
318
- return refuse(`guaranteed ${minOut} is below the floor ${params.minAmountOut} at ${slippageBps} bps`);
349
+ return refuse(`guaranteed ${minOut} is below the floor ${params.minAmountOut} at ${slippageBps} bps`, "price_check_failed");
319
350
  }
320
351
  const route = (b.routePlan ?? []).map((s) => s.swapInfo?.label).filter(Boolean).join(" + ");
321
352
  const impact = Number(b.priceImpactPct ?? 0);
@@ -336,7 +367,7 @@ function jupiterProvider(config = {}) {
336
367
  }
337
368
  const blockhash = b.blockhashWithMetadata?.blockhash;
338
369
  const lastValid = b.blockhashWithMetadata?.lastValidBlockHeight;
339
- if (!blockhash || blockhash.length !== 32 || !lastValid) return refuse("answer without a blockhash");
370
+ if (!blockhash || blockhash.length !== 32 || !lastValid) return refuse("answer without a blockhash", "upstream_unavailable");
340
371
  const assemble = (limit2) => assembleTransaction({
341
372
  taker,
342
373
  instructions: vetted.instructions,
@@ -355,7 +386,7 @@ function jupiterProvider(config = {}) {
355
386
  wire = assemble(units);
356
387
  }
357
388
  } catch (e) {
358
- return refuse(e.message.slice(0, 240));
389
+ return refuse(e.message.slice(0, 240), (0, import_errors.refusalOf)(e) ?? "upstream_unavailable");
359
390
  }
360
391
  const priority = (vetted.price * BigInt(limit) + 999999n) / 1000000n;
361
392
  return {
@@ -369,7 +400,7 @@ function jupiterProvider(config = {}) {
369
400
  },
370
401
  async buildDeposit(quote) {
371
402
  const tx = quote.txRequest?.serializedTx;
372
- if (!tx || quote.intentId.startsWith("dry:")) throw new Error("jupiter: not a live quote");
403
+ if (!tx || quote.intentId.startsWith("dry:")) throw (0, import_errors.refusal)("policy_refused", "jupiter: not a live quote");
373
404
  return { chain: SOLANA_CAIP2, to: "", value: quote.txRequest.value ?? "0", serializedTx: tx };
374
405
  },
375
406
  async trackIntent(ref) {
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/provider.ts","../src/activity.ts","../src/config.ts","../src/codec.ts","../src/transaction.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 {ATA_PROGRAM, JUPITER_API_DEFAULT, JUPITER_PROGRAM, JUPITER_TX_PROGRAMS, COMPUTE_BUDGET_PROGRAM, SOLANA_CAIP2, SYSTEM_PROGRAM, TOKEN_PROGRAM, WSOL_MINT, jupiter as cfg, jupiterMint} from \"./config.js\";\nimport {address, getAddressEncoder, getProgramDerivedAddress} from \"@solana/kit\";\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 /**\n * The setup / cleanup / other instructions /build may carry, by exact shape (scan 2026-10-27 modules, F32/F33):\n * creating the taker's own ATAs, funding the taker's wSOL account with exactly the input (a SOL source), syncing and\n * closing it back to the taker. Anything else — a System transfer elsewhere, a token transfer, a second Jupiter call —\n * is refused; the wallet's balance proof alone let a few hundredths of a SOL and the slippage band leave per swap.\n */\n const shapeRefusal = (ix: JupiterInstruction, want: {taker: string; inputMint: string; amountIn: bigint; wsolAta: string}): string | null => {\n const data = fromBase64(ix.data ?? \"\");\n const acc = (i: number) => ix.accounts[i]?.pubkey;\n if (ix.programId === ATA_PROGRAM) {\n // CreateIdempotent: [payer, ata, owner, mint, system, token program] — the taker pays for its own account.\n if (data.length !== 1 || data[0] !== 1) return \"an associated-token instruction other than CreateIdempotent\";\n if (acc(0) !== want.taker || acc(2) !== want.taker) return \"an associated token account for someone else\";\n return null;\n }\n if (ix.programId === SYSTEM_PROGRAM) {\n // Transfer: u32 LE 2 + u64 lamports, [from, to] — only the input, into the taker's own wSOL account.\n if (data.length !== 12 || data[0] !== 2 || data[1] !== 0 || data[2] !== 0 || data[3] !== 0) return \"a System instruction other than Transfer\";\n if (want.inputMint !== WSOL_MINT) return \"a SOL transfer on a token-source swap\";\n const lamports = new DataView(data.buffer, data.byteOffset + 4, 8).getBigUint64(0, true);\n if (acc(0) !== want.taker || acc(1) !== want.wsolAta) return `a SOL transfer to ${acc(1)}, not the taker's wSOL account`;\n if (lamports !== want.amountIn) return `a SOL transfer of ${lamports}, not the ${want.amountIn} input`;\n return null;\n }\n if (ix.programId === TOKEN_PROGRAM) {\n if (data.length === 1 && data[0] === 17) return acc(0) === want.wsolAta ? null : \"SyncNative on another account\"; // SyncNative\n if (data.length === 1 && data[0] === 9) { // CloseAccount: [account, destination, owner]\n return acc(0) === want.wsolAta && acc(1) === want.taker && acc(2) === want.taker ? null : \"a CloseAccount that is not the taker's wSOL account back to the taker\";\n }\n if (data.length === 33 && data[0] === 18) { // InitializeAccount3(owner): an account the taker owns\n return bytesEqual(data.subarray(1), getAddressEncoder().encode(address(want.taker))) ? null : \"a token account initialized for someone else\";\n }\n return `a Token instruction (tag ${data[0] ?? \"none\"}) the swap does not need`;\n }\n if (ix.programId === JUPITER_PROGRAM) return \"a second Jupiter instruction\";\n return `instruction for program ${ix.programId}`;\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; wsolAta: string}): {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 let funded = false;\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 if (ix === b.swapInstruction) continue;\n const why = shapeRefusal(ix, want);\n if (why) throw new Error(why);\n if (ix.programId === SYSTEM_PROGRAM) {\n if (funded) throw new Error(\"a second SOL transfer\");\n funded = true;\n }\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 const [wsolAta] = await getProgramDerivedAddress({programAddress: address(ATA_PROGRAM), seeds: [getAddressEncoder().encode(address(taker)), getAddressEncoder().encode(address(TOKEN_PROGRAM)), getAddressEncoder().encode(address(WSOL_MINT))]});\n try { vetted = vet(b, {taker, inputMint, outputMint, amountIn, slippageBps, wsolAta}); } 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\nfunction bytesEqual(a: ArrayLike<number>, b: ArrayLike<number>): boolean {\n if (a.length !== b.length) return false;\n for (let i = 0; i < a.length; i++) if (a[i] !== b[i]) return false;\n return true;\n}\n","/**\n * Activity recognition for Jupiter swaps. Solana history (wallet-solana) names the first non-plumbing program a\n * transaction runs as `call.to`: a swap sent to Jupiter v6 directly (this module's /build transactions, jup.ag) has it\n * there. A route that only passes through Jupiter inside another program (an aggregator or bridge CPI-ing into it) names\n * that program instead and is left to its module. The owner must both give and receive an asset: a leg that only sends\n * (a bridge's source leg with a Jupiter pre-swap) is not called a swap.\n */\nimport type {ActivityItem, ChainTx, DescribeActivityContext} from \"@anywalletkit/core\";\nimport {describeSwapLike} from \"@anywalletkit/protocol-swap2-core/activity\";\nimport {JUPITER_PROGRAM, SOLANA_CHAINS} from \"./config.js\";\n\nexport const JUPITER_MODULE = \"@anywalletkit/protocol-swap2-jupiter\";\n\nexport function describeJupiterActivity(tx: ChainTx, ctx: DescribeActivityContext): ActivityItem | null {\n if (!SOLANA_CHAINS.has(tx.chain) || tx.call?.to !== JUPITER_PROGRAM) return null;\n const item = describeSwapLike(tx, ctx, {protocol: JUPITER_MODULE, subtitle: \"Jupiter\", kind: \"swap\", counterparty: JUPITER_PROGRAM});\n if (item && tx.status !== \"failed\" && (item.assetsIn.length === 0 || item.assetsOut.length === 0)) return null;\n return item;\n}\n","/**\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","/**\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","/**\n * Assemble the v0 transaction from `/build` instructions: our compute budget (limit + capped price), Jupiter's setup,\n * swap, cleanup and other instructions, compressed with the lookup tables the response names, fee payer = the taker,\n * lifetime = the blockhash Jupiter fetched. Signatures stay empty; the account signs after its own guard.\n */\nimport {\n AccountRole, address, appendTransactionMessageInstructions, compileTransaction, compressTransactionMessageUsingAddressLookupTables,\n createTransactionMessage, getBase58Decoder, getBase64EncodedWireTransaction, pipe, setTransactionMessageFeePayer,\n setTransactionMessageLifetimeUsingBlockhash, type Address, type Blockhash, type Instruction,\n} from \"@solana/kit\";\nimport {COMPUTE_BUDGET_PROGRAM} from \"./config.js\";\nimport {fromBase64, setComputeUnitLimit, setComputeUnitPrice} from \"./codec.js\";\n\nexport interface JupiterInstruction {\n programId: string;\n accounts: {pubkey: string; isSigner: boolean; isWritable: boolean}[];\n data: string;\n}\n\nexport interface AssembleInput {\n taker: string;\n /** setup → swap → cleanup → other, in that order; compute-budget instructions are ours and come first. */\n instructions: JupiterInstruction[];\n computeUnitLimit: number;\n computeUnitPrice: bigint;\n blockhash: Uint8Array | string;\n lastValidBlockHeight: number | bigint;\n addressesByLookupTableAddress: Record<string, string[]> | null | undefined;\n}\n\nconst role = (a: {isSigner: boolean; isWritable: boolean}): AccountRole =>\n a.isSigner ? (a.isWritable ? AccountRole.WRITABLE_SIGNER : AccountRole.READONLY_SIGNER) : a.isWritable ? AccountRole.WRITABLE : AccountRole.READONLY;\n\nconst toInstruction = (ix: JupiterInstruction): Instruction => ({\n programAddress: address(ix.programId),\n accounts: ix.accounts.map((a) => ({address: address(a.pubkey), role: role(a)})),\n data: fromBase64(ix.data),\n});\n\n/** The unsigned transaction as base64 wire bytes (what `TxRequest.serializedTx` carries). */\nexport function assembleTransaction(input: AssembleInput): string {\n const budget: Instruction[] = [\n {programAddress: address(COMPUTE_BUDGET_PROGRAM), data: setComputeUnitLimit(input.computeUnitLimit)},\n {programAddress: address(COMPUTE_BUDGET_PROGRAM), data: setComputeUnitPrice(input.computeUnitPrice)},\n ];\n const blockhash = (typeof input.blockhash === \"string\" ? input.blockhash : getBase58Decoder().decode(input.blockhash)) as Blockhash;\n const tables: Record<Address, Address[]> = {};\n for (const [table, list] of Object.entries(input.addressesByLookupTableAddress ?? {})) tables[address(table)] = list.map((a) => address(a));\n const message = pipe(\n createTransactionMessage({version: 0}),\n (m) => setTransactionMessageFeePayer(address(input.taker), m),\n (m) => setTransactionMessageLifetimeUsingBlockhash({blockhash, lastValidBlockHeight: BigInt(input.lastValidBlockHeight)}, m),\n (m) => appendTransactionMessageInstructions([...budget, ...input.instructions.map(toInstruction)], m),\n (m) => (Object.keys(tables).length ? compressTransactionMessageUsingAddressLookupTables(m, tables) : m),\n );\n return getBase64EncodedWireTransaction(compileTransaction(message));\n}\n"],"mappings":"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","names":["import_kit","BASE58","limit"]}
1
+ {"version":3,"sources":["../src/provider.ts","../src/activity.ts","../src/config.ts","../src/codec.ts","../src/transaction.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 {ATA_PROGRAM, JUPITER_API_DEFAULT, JUPITER_PROGRAM, JUPITER_TX_PROGRAMS, COMPUTE_BUDGET_PROGRAM, SOLANA_CAIP2, SYSTEM_PROGRAM, TOKEN_PROGRAM, WSOL_MINT, jupiter as cfg, jupiterMint} from \"./config.js\";\nimport {address, getAddressEncoder, getProgramDerivedAddress} from \"@solana/kit\";\nimport {decodeComputeBudget, decodeSwapArgs, fromBase64, minOutOf} from \"./codec.js\";\nimport {assembleTransaction, type JupiterInstruction} from \"./transaction.js\";\nimport {httpRefusal, refusal, refusalNotes, refusalOf, withReason, type Swap2RefusalInfo, type Swap2RefusalReason} from \"@anywalletkit/protocol-swap2-core/errors\";\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/** Longest `retryAfterMs` passed on: a day, core's own ceiling. */\nconst RETRY_AFTER_MAX_MS = 86_400_000;\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\n/** The reason behind each text `shapeRefusal` returns. */\nconst notes = refusalNotes();\n\n/**\n * What a failed /build answer means: Jupiter's own error first (no route, an untradable token, too little liquidity,\n * limits), else the status (429 with Retry-After or `x-ratelimit-reset`, 401 / 403, 408 / 425 / 5xx). Undefined when\n * neither says.\n */\nfunction buildRefusal(status: number, body: unknown, retryAfter: string | null, rateReset: string | null): Swap2RefusalInfo | undefined {\n const byStatus = httpRefusal(status, retryAfter);\n if (byStatus?.reason === \"rate_limited\") {\n if (byStatus.retryAfterMs !== undefined || rateReset === null) return byStatus;\n const wait = Number(rateReset) * 1000 - Date.now();\n // Capped at a day like core's Retry-After: a reset far ahead (or given in milliseconds) is no wait of centuries.\n return Number.isFinite(wait) && wait > 0 ? {...byStatus, retryAfterMs: Math.min(Math.ceil(wait), RETRY_AFTER_MAX_MS)} : byStatus;\n }\n const said = answerReason(body);\n return said && said !== byStatus?.reason ? {reason: said} : byStatus;\n}\nfunction answerReason(body: unknown): Swap2RefusalReason | undefined {\n const b = body as {error?: unknown; errorCode?: unknown} | null;\n const text = `${typeof b?.errorCode === \"string\" ? b.errorCode : \"\"} ${typeof b?.error === \"string\" ? b.error : \"\"}`;\n if (/COULD_NOT_FIND_ANY_ROUTE|NO_ROUTES_FOUND|could not find any route|no routes? found/i.test(text)) return \"no_route\";\n if (/ROUTE_PLAN_DOES_NOT_CONSUME_ALL_THE_AMOUNT|liquidity/i.test(text)) return \"insufficient_liquidity\";\n if (/TOKEN_NOT_TRADABLE|not tradable|MARKET_NOT_FOUND|CIRCULAR_ARBITRAGE|not supported|unsupported/i.test(text)) return \"unsupported_pair\";\n if (/too small|too low|below the minimum/i.test(text)) return \"amount_too_small\";\n if (/too large|too big|above the maximum/i.test(text)) return \"amount_too_large\";\n if (/rate.?limit|too many requests/i.test(text)) return \"rate_limited\";\n if (/api.?key|unauthori[sz]ed/i.test(text)) return \"key_rejected\";\n return undefined;\n}\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 // An apiUrl that is neither an http(s) URL nor a same-origin path is a configuration error: its fetch failures are no refusal.\n const baseIsUrl = /^(?:https?:\\/\\/[^/\\s]+|\\/)/i.test(base);\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; retryAfter: string | null; rateReset: string | null}> => {\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, retryAfter: res.headers?.get?.(\"retry-after\") ?? null, rateReset: res.headers?.get?.(\"x-ratelimit-reset\") ?? null};\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 /**\n * The setup / cleanup / other instructions /build may carry, by exact shape (scan 2026-10-27 modules, F32/F33):\n * creating the taker's own ATAs, funding the taker's wSOL account with exactly the input (a SOL source), syncing and\n * closing it back to the taker. Anything else — a System transfer elsewhere, a token transfer, a second Jupiter call —\n * is refused; the wallet's balance proof alone let a few hundredths of a SOL and the slippage band leave per swap.\n */\n const shapeRefusal = (ix: JupiterInstruction, want: {taker: string; inputMint: string; amountIn: bigint; wsolAta: string}): string | null => {\n const data = fromBase64(ix.data ?? \"\");\n const acc = (i: number) => ix.accounts[i]?.pubkey;\n if (ix.programId === ATA_PROGRAM) {\n // CreateIdempotent: [payer, ata, owner, mint, system, token program] — the taker pays for its own account.\n if (data.length !== 1 || data[0] !== 1) return notes.note(\"an associated-token instruction other than CreateIdempotent\", \"policy_refused\");\n if (acc(0) !== want.taker || acc(2) !== want.taker) return notes.note(\"an associated token account for someone else\", \"recipient_mismatch\");\n return null;\n }\n if (ix.programId === SYSTEM_PROGRAM) {\n // Transfer: u32 LE 2 + u64 lamports, [from, to] — only the input, into the taker's own wSOL account.\n if (data.length !== 12 || data[0] !== 2 || data[1] !== 0 || data[2] !== 0 || data[3] !== 0) return notes.note(\"a System instruction other than Transfer\", \"policy_refused\");\n if (want.inputMint !== WSOL_MINT) return notes.note(\"a SOL transfer on a token-source swap\", \"policy_refused\");\n const lamports = new DataView(data.buffer, data.byteOffset + 4, 8).getBigUint64(0, true);\n if (acc(0) !== want.taker || acc(1) !== want.wsolAta) return notes.note(`a SOL transfer to ${acc(1)}, not the taker's wSOL account`, \"recipient_mismatch\");\n if (lamports !== want.amountIn) return notes.note(`a SOL transfer of ${lamports}, not the ${want.amountIn} input`, \"policy_refused\");\n return null;\n }\n if (ix.programId === TOKEN_PROGRAM) {\n if (data.length === 1 && data[0] === 17) return acc(0) === want.wsolAta ? null : notes.note(\"SyncNative on another account\", \"policy_refused\"); // SyncNative\n if (data.length === 1 && data[0] === 9) { // CloseAccount: [account, destination, owner]\n return acc(0) === want.wsolAta && acc(1) === want.taker && acc(2) === want.taker ? null : notes.note(\"a CloseAccount that is not the taker's wSOL account back to the taker\", \"recipient_mismatch\");\n }\n if (data.length === 33 && data[0] === 18) { // InitializeAccount3(owner): an account the taker owns\n return bytesEqual(data.subarray(1), getAddressEncoder().encode(address(want.taker))) ? null : notes.note(\"a token account initialized for someone else\", \"recipient_mismatch\");\n }\n return notes.note(`a Token instruction (tag ${data[0] ?? \"none\"}) the swap does not need`, \"policy_refused\");\n }\n if (ix.programId === JUPITER_PROGRAM) return notes.note(\"a second Jupiter instruction\", \"policy_refused\");\n return notes.note(`instruction for program ${ix.programId}`, \"policy_refused\");\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; wsolAta: string}): {instructions: JupiterInstruction[]; price: bigint; quotedOut: bigint} => {\n if (b.swapMode && b.swapMode !== \"ExactIn\") throw refusal(\"policy_refused\", `swap mode ${b.swapMode}`);\n if (b.inputMint !== want.inputMint || b.outputMint !== want.outputMint) throw refusal(\"policy_refused\", \"the answer names other mints\");\n if (b.inAmount !== want.amountIn.toString()) throw refusal(\"policy_refused\", `the answer spends ${b.inAmount}, not ${want.amountIn}`);\n if (String(b.transactionVersion ?? \"0\") !== \"0\") throw refusal(\"policy_refused\", `transaction version ${b.transactionVersion}`);\n if (b.tipInstruction) throw refusal(\"policy_refused\", \"unexpected tip instruction\");\n if (!b.swapInstruction) throw refusal(\"upstream_unavailable\", \"no swap instruction\");\n if (b.swapInstruction.programId !== JUPITER_PROGRAM) throw refusal(\"vault_mismatch\", `swap instruction targets ${b.swapInstruction.programId}`);\n const args = decodeSwapArgs(fromBase64(b.swapInstruction.data));\n if (args.inAmount !== want.amountIn) throw refusal(\"policy_refused\", `swap instruction spends ${args.inAmount}, not ${want.amountIn}`);\n if (String(args.quotedOutAmount) !== b.outAmount) throw refusal(\"price_check_failed\", \"swap instruction's quoted output differs from the answer\");\n if (args.slippageBps !== want.slippageBps) throw refusal(\"price_check_failed\", `swap instruction allows ${args.slippageBps} bps slippage, not ${want.slippageBps}`);\n if (args.platformFeeBps !== 0 || args.positiveSlippageBps !== 0) throw refusal(\"policy_refused\", \"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 refusal(\"policy_refused\", `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 let funded = false;\n for (const ix of instructions) {\n if (!JUPITER_TX_PROGRAMS.has(ix.programId) || ix.programId === COMPUTE_BUDGET_PROGRAM) throw refusal(\"policy_refused\", `instruction for program ${ix.programId}`);\n for (const a of ix.accounts) if (a.isSigner && a.pubkey !== want.taker) throw refusal(\"policy_refused\", `instruction needs signer ${a.pubkey}`);\n if (ix === b.swapInstruction) continue;\n const why = shapeRefusal(ix, want);\n if (why) {\n const info = notes.reasonOf(why);\n throw info ? withReason(new Error(why), info) : new Error(why);\n }\n if (ix.programId === SYSTEM_PROGRAM) {\n if (funded) throw refusal(\"policy_refused\", \"a second SOL transfer\");\n funded = true;\n }\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 refusal(\"simulation_failed\", `not enough of the input token in the wallet${jupiterCode === \"6025\" ? \" (no token account for it)\" : \"\"} — simulation fails: ${err}`);\n }\n throw refusal(\"simulation_failed\", `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, why?: Swap2RefusalReason | Swap2RefusalInfo): null => {\n const info = typeof why === \"string\" ? {reason: why} : why;\n if (info) params.onRefusal?.(`jupiter: ${reason}`, info);\n else 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})`, \"unsupported_pair\");\n if (params.flex) return refuse(\"amount-flexible deposits are not supported\", \"unsupported_pair\");\n const inputMint = jupiterMint(params.sourceToken), outputMint = jupiterMint(params.destToken);\n if (!inputMint || !outputMint) return refuse(`unknown token (${params.sourceToken} → ${params.destToken})`, \"unsupported_pair\");\n if (inputMint === outputMint) return refuse(\"same token on both sides\", \"unsupported_pair\");\n const amountIn = BigInt(params.amountIn);\n if (amountIn <= 0n) return refuse(\"amount must be positive\", \"amount_too_small\");\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`, params.slippageBps !== undefined && Number.isInteger(slippageBps) && slippageBps > MAX_SLIPPAGE_BPS ? \"policy_refused\" : undefined);\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 // No address at all is the policy; one that is not a Solana address is the caller's argument (unclassified).\n if (!self || !BASE58.test(self)) return refuse(\"live quote without the signer's address\", !self ? \"policy_refused\" : undefined);\n if (params.destAddress && params.destAddress !== self) return refuse(\"the recipient must be the signing wallet (Jupiter pays the taker)\", \"unsupported_pair\");\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 // A network failure or our own timeout is Jupiter's; the caller's abort is not.\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)}`, buildRefusal(r.status, r.body, r.retryAfter, r.rateReset));\n b = (r.body ?? {}) as BuildResponse;\n } catch (e) { return refuse(`build failed: ${(e as Error).message.slice(0, 160)}`, signal?.aborted || !baseIsUrl ? undefined : \"upstream_unavailable\"); }\n // A body the caller's abort cut short reads as null: that is no answer of another shape.\n if (!b.outAmount || !/^\\d+$/.test(b.outAmount)) return refuse(\"answer without an output amount\", answerReason(b) ?? (signal?.aborted ? undefined : \"upstream_unavailable\"));\n\n let vetted: ReturnType<typeof vet>;\n const [wsolAta] = await getProgramDerivedAddress({programAddress: address(ATA_PROGRAM), seeds: [getAddressEncoder().encode(address(taker)), getAddressEncoder().encode(address(TOKEN_PROGRAM)), getAddressEncoder().encode(address(WSOL_MINT))]});\n // A check that fails names its reason; an answer the decoders cannot read is one of another shape.\n try { vetted = vet(b, {taker, inputMint, outputMint, amountIn, slippageBps, wsolAta}); } catch (e) { return refuse((e as Error).message, refusalOf(e) ?? \"upstream_unavailable\"); }\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`, \"price_check_failed\");\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\", \"upstream_unavailable\");\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 // The simulation's verdict, else a transaction the answer's instructions or lookup tables cannot assemble.\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), refusalOf(e) ?? \"upstream_unavailable\"); }\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 refusal(\"policy_refused\", \"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\nfunction bytesEqual(a: ArrayLike<number>, b: ArrayLike<number>): boolean {\n if (a.length !== b.length) return false;\n for (let i = 0; i < a.length; i++) if (a[i] !== b[i]) return false;\n return true;\n}\n","/**\n * Activity recognition for Jupiter swaps. Solana history (wallet-solana) names the first non-plumbing program a\n * transaction runs as `call.to`: a swap sent to Jupiter v6 directly (this module's /build transactions, jup.ag) has it\n * there. A route that only passes through Jupiter inside another program (an aggregator or bridge CPI-ing into it) names\n * that program instead and is left to its module. The owner must both give and receive an asset: a leg that only sends\n * (a bridge's source leg with a Jupiter pre-swap) is not called a swap.\n */\nimport type {ActivityItem, ChainTx, DescribeActivityContext} from \"@anywalletkit/core\";\nimport {describeSwapLike} from \"@anywalletkit/protocol-swap2-core/activity\";\nimport {JUPITER_PROGRAM, SOLANA_CHAINS} from \"./config.js\";\n\nexport const JUPITER_MODULE = \"@anywalletkit/protocol-swap2-jupiter\";\n\nexport function describeJupiterActivity(tx: ChainTx, ctx: DescribeActivityContext): ActivityItem | null {\n if (!SOLANA_CHAINS.has(tx.chain) || tx.call?.to !== JUPITER_PROGRAM) return null;\n const item = describeSwapLike(tx, ctx, {protocol: JUPITER_MODULE, subtitle: \"Jupiter\", kind: \"swap\", counterparty: JUPITER_PROGRAM});\n if (item && tx.status !== \"failed\" && (item.assetsIn.length === 0 || item.assetsOut.length === 0)) return null;\n return item;\n}\n","/**\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","/**\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","/**\n * Assemble the v0 transaction from `/build` instructions: our compute budget (limit + capped price), Jupiter's setup,\n * swap, cleanup and other instructions, compressed with the lookup tables the response names, fee payer = the taker,\n * lifetime = the blockhash Jupiter fetched. Signatures stay empty; the account signs after its own guard.\n */\nimport {\n AccountRole, address, appendTransactionMessageInstructions, compileTransaction, compressTransactionMessageUsingAddressLookupTables,\n createTransactionMessage, getBase58Decoder, getBase64EncodedWireTransaction, pipe, setTransactionMessageFeePayer,\n setTransactionMessageLifetimeUsingBlockhash, type Address, type Blockhash, type Instruction,\n} from \"@solana/kit\";\nimport {COMPUTE_BUDGET_PROGRAM} from \"./config.js\";\nimport {fromBase64, setComputeUnitLimit, setComputeUnitPrice} from \"./codec.js\";\n\nexport interface JupiterInstruction {\n programId: string;\n accounts: {pubkey: string; isSigner: boolean; isWritable: boolean}[];\n data: string;\n}\n\nexport interface AssembleInput {\n taker: string;\n /** setup → swap → cleanup → other, in that order; compute-budget instructions are ours and come first. */\n instructions: JupiterInstruction[];\n computeUnitLimit: number;\n computeUnitPrice: bigint;\n blockhash: Uint8Array | string;\n lastValidBlockHeight: number | bigint;\n addressesByLookupTableAddress: Record<string, string[]> | null | undefined;\n}\n\nconst role = (a: {isSigner: boolean; isWritable: boolean}): AccountRole =>\n a.isSigner ? (a.isWritable ? AccountRole.WRITABLE_SIGNER : AccountRole.READONLY_SIGNER) : a.isWritable ? AccountRole.WRITABLE : AccountRole.READONLY;\n\nconst toInstruction = (ix: JupiterInstruction): Instruction => ({\n programAddress: address(ix.programId),\n accounts: ix.accounts.map((a) => ({address: address(a.pubkey), role: role(a)})),\n data: fromBase64(ix.data),\n});\n\n/** The unsigned transaction as base64 wire bytes (what `TxRequest.serializedTx` carries). */\nexport function assembleTransaction(input: AssembleInput): string {\n const budget: Instruction[] = [\n {programAddress: address(COMPUTE_BUDGET_PROGRAM), data: setComputeUnitLimit(input.computeUnitLimit)},\n {programAddress: address(COMPUTE_BUDGET_PROGRAM), data: setComputeUnitPrice(input.computeUnitPrice)},\n ];\n const blockhash = (typeof input.blockhash === \"string\" ? input.blockhash : getBase58Decoder().decode(input.blockhash)) as Blockhash;\n const tables: Record<Address, Address[]> = {};\n for (const [table, list] of Object.entries(input.addressesByLookupTableAddress ?? {})) tables[address(table)] = list.map((a) => address(a));\n const message = pipe(\n createTransactionMessage({version: 0}),\n (m) => setTransactionMessageFeePayer(address(input.taker), m),\n (m) => setTransactionMessageLifetimeUsingBlockhash({blockhash, lastValidBlockHeight: BigInt(input.lastValidBlockHeight)}, m),\n (m) => appendTransactionMessageInstructions([...budget, ...input.instructions.map(toInstruction)], m),\n (m) => (Object.keys(tables).length ? compressTransactionMessageUsingAddressLookupTables(m, tables) : m),\n );\n return getBase64EncodedWireTransaction(compileTransaction(message));\n}\n"],"mappings":"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","names":["import_kit","BASE58","limit"]}
package/dist/provider.js CHANGED
@@ -1,6 +1,6 @@
1
1
  import {
2
2
  jupiterProvider
3
- } from "./chunk-EY2HJJXY.js";
3
+ } from "./chunk-4V65GQY2.js";
4
4
  import "./chunk-5L7BPEQL.js";
5
5
  import "./chunk-5JXNDQHW.js";
6
6
  import "./chunk-H4SP5E76.js";
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@anywalletkit/protocol-swap2-jupiter",
3
- "version": "0.3.7",
3
+ "version": "0.3.9",
4
4
  "description": "Jupiter same-chain Solana swaps for the swap2 engine through Swap API V2's Router path (GET /swap/v2/build): Metis routing, no Jupiter swap fee, keyless or with an API key. The transaction is assembled locally from raw instructions after every instruction is vetted (Jupiter v6 + token/system/ATA plumbing only, taker the only signer, swap arguments decoded: our amount, the quoted output, our slippage, zero platform fee); the account executes it through its serialized-transaction guard and its own RPC.",
5
5
  "license": "Apache-2.0",
6
6
  "homepage": "https://docs.anywallet.tech",
@@ -66,7 +66,7 @@
66
66
  "dependencies": {
67
67
  "@scure/base": "^2.4.0",
68
68
  "@solana/kit": "^8.4.0",
69
- "@anywalletkit/protocol-swap2-core": "0.11.0",
69
+ "@anywalletkit/protocol-swap2-core": "0.13.0",
70
70
  "@anywalletkit/swap2-assets": "0.3.0"
71
71
  },
72
72
  "peerDependencies": {
@@ -75,9 +75,9 @@
75
75
  "devDependencies": {
76
76
  "@types/node": "^22",
77
77
  "vitest": "^5.1.0",
78
- "@anywalletkit/conformance": "0.5.1",
79
- "@anywalletkit/protocol-swap2-router": "0.5.5",
78
+ "@anywalletkit/conformance": "0.6.0",
80
79
  "@anywalletkit/core": "0.8.0",
80
+ "@anywalletkit/protocol-swap2-router": "0.6.1",
81
81
  "@anywalletkit/wallet-solana": "0.6.2"
82
82
  },
83
83
  "keywords": [