@velocity-exchange/sdk 0.8.0 → 0.10.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 (74) hide show
  1. package/lib/browser/adminClient.d.ts +13 -10
  2. package/lib/browser/adminClient.js +16 -21
  3. package/lib/browser/decode/user.js +3 -1
  4. package/lib/browser/equityFloorManager.d.ts +154 -0
  5. package/lib/browser/equityFloorManager.js +283 -0
  6. package/lib/browser/idl/velocity.d.ts +85 -10
  7. package/lib/browser/idl/velocity.json +85 -10
  8. package/lib/browser/index.d.ts +4 -0
  9. package/lib/browser/index.js +5 -0
  10. package/lib/browser/jupiter/jupiterClient.d.ts +31 -27
  11. package/lib/browser/jupiter/jupiterClient.js +84 -37
  12. package/lib/browser/math/margin.d.ts +28 -0
  13. package/lib/browser/math/margin.js +43 -1
  14. package/lib/browser/math/superStake.d.ts +9 -9
  15. package/lib/browser/math/superStake.js +8 -8
  16. package/lib/browser/swap/UnifiedSwapClient.d.ts +38 -76
  17. package/lib/browser/swap/UnifiedSwapClient.js +53 -110
  18. package/lib/browser/swap/routeInstructions.d.ts +19 -0
  19. package/lib/browser/swap/routeInstructions.js +43 -0
  20. package/lib/browser/swap/types.d.ts +196 -0
  21. package/lib/browser/swap/types.js +88 -0
  22. package/lib/browser/titan/titanClient.d.ts +37 -67
  23. package/lib/browser/titan/titanClient.js +160 -103
  24. package/lib/browser/types.d.ts +6 -2
  25. package/lib/browser/types.js +2 -0
  26. package/lib/browser/user.d.ts +43 -18
  27. package/lib/browser/user.js +94 -45
  28. package/lib/browser/velocityClient.d.ts +86 -103
  29. package/lib/browser/velocityClient.js +157 -298
  30. package/lib/node/adminClient.d.ts +13 -10
  31. package/lib/node/adminClient.d.ts.map +1 -1
  32. package/lib/node/adminClient.js +16 -21
  33. package/lib/node/decode/user.d.ts.map +1 -1
  34. package/lib/node/decode/user.js +3 -1
  35. package/lib/node/equityFloorManager.d.ts +155 -0
  36. package/lib/node/equityFloorManager.d.ts.map +1 -0
  37. package/lib/node/equityFloorManager.js +283 -0
  38. package/lib/node/idl/velocity.d.ts +85 -10
  39. package/lib/node/idl/velocity.d.ts.map +1 -1
  40. package/lib/node/idl/velocity.json +85 -10
  41. package/lib/node/index.d.ts +4 -0
  42. package/lib/node/index.d.ts.map +1 -1
  43. package/lib/node/index.js +5 -0
  44. package/lib/node/jupiter/jupiterClient.d.ts +31 -27
  45. package/lib/node/jupiter/jupiterClient.d.ts.map +1 -1
  46. package/lib/node/jupiter/jupiterClient.js +84 -37
  47. package/lib/node/math/margin.d.ts +28 -0
  48. package/lib/node/math/margin.d.ts.map +1 -1
  49. package/lib/node/math/margin.js +43 -1
  50. package/lib/node/math/superStake.d.ts +9 -9
  51. package/lib/node/math/superStake.d.ts.map +1 -1
  52. package/lib/node/math/superStake.js +8 -8
  53. package/lib/node/swap/UnifiedSwapClient.d.ts +38 -76
  54. package/lib/node/swap/UnifiedSwapClient.d.ts.map +1 -1
  55. package/lib/node/swap/UnifiedSwapClient.js +53 -110
  56. package/lib/node/swap/routeInstructions.d.ts +20 -0
  57. package/lib/node/swap/routeInstructions.d.ts.map +1 -0
  58. package/lib/node/swap/routeInstructions.js +43 -0
  59. package/lib/node/swap/types.d.ts +197 -0
  60. package/lib/node/swap/types.d.ts.map +1 -0
  61. package/lib/node/swap/types.js +88 -0
  62. package/lib/node/titan/titanClient.d.ts +37 -67
  63. package/lib/node/titan/titanClient.d.ts.map +1 -1
  64. package/lib/node/titan/titanClient.js +160 -103
  65. package/lib/node/types.d.ts +6 -2
  66. package/lib/node/types.d.ts.map +1 -1
  67. package/lib/node/types.js +2 -0
  68. package/lib/node/user.d.ts +43 -18
  69. package/lib/node/user.d.ts.map +1 -1
  70. package/lib/node/user.js +94 -45
  71. package/lib/node/velocityClient.d.ts +86 -103
  72. package/lib/node/velocityClient.d.ts.map +1 -1
  73. package/lib/node/velocityClient.js +157 -298
  74. package/package.json +1 -1
@@ -12466,6 +12466,10 @@ export type Velocity = {
12466
12466
  {
12467
12467
  "name": "equityFloor";
12468
12468
  "type": "u64";
12469
+ },
12470
+ {
12471
+ "name": "equityFloorBuffer";
12472
+ "type": "u64";
12469
12473
  }
12470
12474
  ];
12471
12475
  },
@@ -12887,6 +12891,63 @@ export type Velocity = {
12887
12891
  ];
12888
12892
  "args": [];
12889
12893
  },
12894
+ {
12895
+ "name": "updateUserVaultOwned";
12896
+ "docs": [
12897
+ "Mark a User as vault-owned (its authority is a vault PDA and its equity",
12898
+ "prices vault depositor shares). Set-only and authority-gated: only the",
12899
+ "User's authority may call it, and it is CPI'd by the vaults program at",
12900
+ "vault init. A vault-owned User is skipped by the revenue-share sweep so a",
12901
+ "builder/referral reward can never enter vault NAV (OtterSec #91/#92/#93)."
12902
+ ];
12903
+ "discriminator": [
12904
+ 50,
12905
+ 156,
12906
+ 218,
12907
+ 143,
12908
+ 216,
12909
+ 94,
12910
+ 68,
12911
+ 93
12912
+ ];
12913
+ "accounts": [
12914
+ {
12915
+ "name": "user";
12916
+ "writable": true;
12917
+ "pda": {
12918
+ "seeds": [
12919
+ {
12920
+ "kind": "const";
12921
+ "value": [
12922
+ 117,
12923
+ 115,
12924
+ 101,
12925
+ 114
12926
+ ];
12927
+ },
12928
+ {
12929
+ "kind": "account";
12930
+ "path": "authority";
12931
+ },
12932
+ {
12933
+ "kind": "arg";
12934
+ "path": "subAccountId";
12935
+ }
12936
+ ];
12937
+ };
12938
+ },
12939
+ {
12940
+ "name": "authority";
12941
+ "signer": true;
12942
+ }
12943
+ ];
12944
+ "args": [
12945
+ {
12946
+ "name": "subAccountId";
12947
+ "type": "u16";
12948
+ }
12949
+ ];
12950
+ },
12890
12951
  {
12891
12952
  "name": "updateWarmAdmin";
12892
12953
  "discriminator": [
@@ -16299,6 +16360,16 @@ export type Velocity = {
16299
16360
  "code": 6364;
16300
16361
  "name": "dailyDepositLimit";
16301
16362
  "msg": "Spot market daily deposit limit hit";
16363
+ },
16364
+ {
16365
+ "code": 6365;
16366
+ "name": "reservedSpotMarketName";
16367
+ "msg": "The name 'USDT' is reserved for the quote spot market (index 0)";
16368
+ },
16369
+ {
16370
+ "code": 6366;
16371
+ "name": "cannotModifyBuilderOrder";
16372
+ "msg": "Cannot modify a builder-coded order; cancel and re-place instead";
16302
16373
  }
16303
16374
  ];
16304
16375
  "types": [
@@ -24065,21 +24136,25 @@ export type Velocity = {
24065
24136
  {
24066
24137
  "name": "equityFloor";
24067
24138
  "docs": [
24068
- "Minimum account equity (cross-margin total collateral) required for",
24069
- "risk-increasing orders, fills, withdrawals and deposit transfers.",
24070
- "Settable only by the warm/cold admin; 0 disables the check.",
24139
+ "Minimum account net equity (unweighted assets plus perp pnl minus",
24140
+ "spot liabilities, see `calculate_user_equity`). Below this the",
24141
+ "permissionless breaker can trip. Risk-increasing orders, fills,",
24142
+ "withdrawals and deposit transfers must clear `equity_floor +",
24143
+ "equity_floor_buffer`. Settable only by the warm/cold admin; 0 disables",
24144
+ "both checks.",
24071
24145
  "precision: QUOTE_PRECISION"
24072
24146
  ];
24073
24147
  "type": "u64";
24074
24148
  },
24075
24149
  {
24076
- "name": "padding2";
24077
- "type": {
24078
- "array": [
24079
- "u8",
24080
- 8
24081
- ];
24082
- };
24150
+ "name": "equityFloorBuffer";
24151
+ "docs": [
24152
+ "Extra headroom above `equity_floor` required by risk-increasing",
24153
+ "actions, so an account cannot legally end an action at the trip",
24154
+ "threshold. No effect while `equity_floor` is 0.",
24155
+ "precision: QUOTE_PRECISION"
24156
+ ];
24157
+ "type": "u64";
24083
24158
  }
24084
24159
  ];
24085
24160
  };
@@ -12460,6 +12460,10 @@
12460
12460
  {
12461
12461
  "name": "equity_floor",
12462
12462
  "type": "u64"
12463
+ },
12464
+ {
12465
+ "name": "equity_floor_buffer",
12466
+ "type": "u64"
12463
12467
  }
12464
12468
  ]
12465
12469
  },
@@ -12881,6 +12885,63 @@
12881
12885
  ],
12882
12886
  "args": []
12883
12887
  },
12888
+ {
12889
+ "name": "update_user_vault_owned",
12890
+ "docs": [
12891
+ "Mark a User as vault-owned (its authority is a vault PDA and its equity",
12892
+ "prices vault depositor shares). Set-only and authority-gated: only the",
12893
+ "User's authority may call it, and it is CPI'd by the vaults program at",
12894
+ "vault init. A vault-owned User is skipped by the revenue-share sweep so a",
12895
+ "builder/referral reward can never enter vault NAV (OtterSec #91/#92/#93)."
12896
+ ],
12897
+ "discriminator": [
12898
+ 50,
12899
+ 156,
12900
+ 218,
12901
+ 143,
12902
+ 216,
12903
+ 94,
12904
+ 68,
12905
+ 93
12906
+ ],
12907
+ "accounts": [
12908
+ {
12909
+ "name": "user",
12910
+ "writable": true,
12911
+ "pda": {
12912
+ "seeds": [
12913
+ {
12914
+ "kind": "const",
12915
+ "value": [
12916
+ 117,
12917
+ 115,
12918
+ 101,
12919
+ 114
12920
+ ]
12921
+ },
12922
+ {
12923
+ "kind": "account",
12924
+ "path": "authority"
12925
+ },
12926
+ {
12927
+ "kind": "arg",
12928
+ "path": "sub_account_id"
12929
+ }
12930
+ ]
12931
+ }
12932
+ },
12933
+ {
12934
+ "name": "authority",
12935
+ "signer": true
12936
+ }
12937
+ ],
12938
+ "args": [
12939
+ {
12940
+ "name": "_sub_account_id",
12941
+ "type": "u16"
12942
+ }
12943
+ ]
12944
+ },
12884
12945
  {
12885
12946
  "name": "update_warm_admin",
12886
12947
  "discriminator": [
@@ -16293,6 +16354,16 @@
16293
16354
  "code": 6364,
16294
16355
  "name": "DailyDepositLimit",
16295
16356
  "msg": "Spot market daily deposit limit hit"
16357
+ },
16358
+ {
16359
+ "code": 6365,
16360
+ "name": "ReservedSpotMarketName",
16361
+ "msg": "The name 'USDT' is reserved for the quote spot market (index 0)"
16362
+ },
16363
+ {
16364
+ "code": 6366,
16365
+ "name": "CannotModifyBuilderOrder",
16366
+ "msg": "Cannot modify a builder-coded order; cancel and re-place instead"
16296
16367
  }
16297
16368
  ],
16298
16369
  "types": [
@@ -24059,21 +24130,25 @@
24059
24130
  {
24060
24131
  "name": "equity_floor",
24061
24132
  "docs": [
24062
- "Minimum account equity (cross-margin total collateral) required for",
24063
- "risk-increasing orders, fills, withdrawals and deposit transfers.",
24064
- "Settable only by the warm/cold admin; 0 disables the check.",
24133
+ "Minimum account net equity (unweighted assets plus perp pnl minus",
24134
+ "spot liabilities, see `calculate_user_equity`). Below this the",
24135
+ "permissionless breaker can trip. Risk-increasing orders, fills,",
24136
+ "withdrawals and deposit transfers must clear `equity_floor +",
24137
+ "equity_floor_buffer`. Settable only by the warm/cold admin; 0 disables",
24138
+ "both checks.",
24065
24139
  "precision: QUOTE_PRECISION"
24066
24140
  ],
24067
24141
  "type": "u64"
24068
24142
  },
24069
24143
  {
24070
- "name": "padding2",
24071
- "type": {
24072
- "array": [
24073
- "u8",
24074
- 8
24075
- ]
24076
- }
24144
+ "name": "equity_floor_buffer",
24145
+ "docs": [
24146
+ "Extra headroom above `equity_floor` required by risk-increasing",
24147
+ "actions, so an account cannot legally end an action at the trip",
24148
+ "threshold. No effect while `equity_floor` is 0.",
24149
+ "precision: QUOTE_PRECISION"
24150
+ ],
24151
+ "type": "u64"
24077
24152
  }
24078
24153
  ]
24079
24154
  }
@@ -45,6 +45,7 @@ export * from './adminClient';
45
45
  export * from './assert/assert';
46
46
  export { PythLazerSubscriber, type PythLazerPriceFeedArray, type PriceUpdateAccount, } from './pyth';
47
47
  export * from './testClient';
48
+ export * from './equityFloorManager';
48
49
  export * from './user';
49
50
  export * from './userConfig';
50
51
  export * from './userStats';
@@ -64,6 +65,8 @@ export * from './events/parse';
64
65
  export * from './events/pollingLogProvider';
65
66
  export * from './jupiter/jupiterClient';
66
67
  export * from './swap/UnifiedSwapClient';
68
+ export * from './swap/types';
69
+ export * from './swap/routeInstructions';
67
70
  export * from './math/auction';
68
71
  export * from './math/builder';
69
72
  export * from './math/spotMarket';
@@ -109,6 +112,7 @@ export * from './tx/priorityFeeCalculator';
109
112
  export * from './tx/types';
110
113
  export * from './tx/txHandler';
111
114
  export * from './tx/txParamProcessor';
115
+ export * from './tx/utils';
112
116
  export * from './util/computeUnits';
113
117
  export * from './util/digest';
114
118
  export * from './util/promiseTimeout';
@@ -75,6 +75,7 @@ __exportStar(require("./assert/assert"), exports);
75
75
  var pyth_1 = require("./pyth");
76
76
  Object.defineProperty(exports, "PythLazerSubscriber", { enumerable: true, get: function () { return pyth_1.PythLazerSubscriber; } });
77
77
  __exportStar(require("./testClient"), exports);
78
+ __exportStar(require("./equityFloorManager"), exports);
78
79
  __exportStar(require("./user"), exports);
79
80
  __exportStar(require("./userConfig"), exports);
80
81
  __exportStar(require("./userStats"), exports);
@@ -95,6 +96,9 @@ __exportStar(require("./events/pollingLogProvider"), exports);
95
96
  __exportStar(require("./jupiter/jupiterClient"), exports);
96
97
  // Primary swap client interface - use this for all swap operations
97
98
  __exportStar(require("./swap/UnifiedSwapClient"), exports);
99
+ // The SwapProvider contract both providers implement, and the shared route filter
100
+ __exportStar(require("./swap/types"), exports);
101
+ __exportStar(require("./swap/routeInstructions"), exports);
98
102
  __exportStar(require("./math/auction"), exports);
99
103
  __exportStar(require("./math/builder"), exports);
100
104
  __exportStar(require("./math/spotMarket"), exports);
@@ -140,6 +144,7 @@ __exportStar(require("./tx/priorityFeeCalculator"), exports);
140
144
  __exportStar(require("./tx/types"), exports);
141
145
  __exportStar(require("./tx/txHandler"), exports);
142
146
  __exportStar(require("./tx/txParamProcessor"), exports);
147
+ __exportStar(require("./tx/utils"), exports);
143
148
  __exportStar(require("./util/computeUnits"), exports);
144
149
  __exportStar(require("./util/digest"), exports);
145
150
  __exportStar(require("./util/promiseTimeout"), exports);
@@ -1,6 +1,5 @@
1
1
  import { AddressLookupTableAccount, Connection, PublicKey, TransactionInstruction, TransactionMessage, VersionedTransaction } from '@solana/web3.js';
2
- import { BN } from '../isomorphic/anchor';
3
- import { SwapMode } from '../swap/UnifiedSwapClient';
2
+ import { GetRouteInstructionsParams, SwapMode, SwapProvider, SwapQuote, SwapQuoteParams, SwapRouteInstructions } from '../swap/types';
4
3
  export interface MarketInfo {
5
4
  id: string;
6
5
  inAmount: number;
@@ -207,14 +206,17 @@ export interface QuoteResponse {
207
206
  */
208
207
  errorCode?: string;
209
208
  }
209
+ /** A Jupiter quote plus the payload {@link JupiterClient.getRouteInstructions} needs. */
210
+ export type JupiterSwapQuote = QuoteResponse & SwapQuote;
210
211
  export declare const RECOMMENDED_JUPITER_API_VERSION = "/v1";
211
212
  /** @deprecated Use RECOMMENDED_JUPITER_API instead. lite-api.jup.ag requires migration to api.jup.ag with API key. */
212
213
  export declare const LEGACY_JUPITER_API = "https://lite-api.jup.ag/swap";
213
214
  export declare const RECOMMENDED_JUPITER_API = "https://api.jup.ag/swap";
214
- export declare class JupiterClient {
215
+ export declare class JupiterClient implements SwapProvider {
216
+ readonly providerName: "jupiter";
215
217
  url: string;
216
218
  connection: Connection;
217
- lookupTableCahce: Map<string, AddressLookupTableAccount>;
219
+ lookupTableCache: Map<string, AddressLookupTableAccount>;
218
220
  private apiKey?;
219
221
  /**
220
222
  * Create a Jupiter client
@@ -240,31 +242,34 @@ export declare class JupiterClient {
240
242
  * @param swapMode the swap mode (ExactIn or ExactOut)
241
243
  * @param onlyDirectRoutes whether to only return direct routes
242
244
  */
243
- getQuote({ inputMint, outputMint, amount, maxAccounts, // 50 is an estimated amount with buffer
244
- slippageBps, swapMode, onlyDirectRoutes, excludeDexes, autoSlippage, maxAutoSlippageBps, usdEstimate, }: {
245
- inputMint: PublicKey;
246
- outputMint: PublicKey;
247
- amount: BN;
248
- maxAccounts?: number;
249
- slippageBps?: number;
250
- swapMode?: SwapMode;
251
- onlyDirectRoutes?: boolean;
252
- excludeDexes?: string[];
253
- autoSlippage?: boolean;
254
- maxAutoSlippageBps?: number;
255
- usdEstimate?: number;
256
- }): Promise<QuoteResponse>;
245
+ getQuote({ inputMint, outputMint, amount, maxAccounts, slippageBps, swapMode, onlyDirectRoutes, excludeDexes, autoSlippage, maxAutoSlippageBps, usdEstimate, }: SwapQuoteParams): Promise<JupiterSwapQuote>;
257
246
  /**
258
247
  * Get a swap transaction for quote
259
- * @param quoteResponse quote to perform swap
248
+ * @param quote quote to perform swap, from {@link getQuote}
260
249
  * @param userPublicKey the signer's wallet public key
261
- * @param slippageBps the slippage tolerance in basis points
250
+ *
251
+ * Always builds at the quote's own slippage — the price the caller was
252
+ * shown. Re-quote to change it rather than overriding it here.
262
253
  */
263
- getSwap({ quote, userPublicKey, slippageBps, }: {
264
- quote: QuoteResponse;
254
+ getSwap({ quote, userPublicKey, }: {
255
+ quote: QuoteResponse | JupiterSwapQuote;
265
256
  userPublicKey: PublicKey;
266
- slippageBps?: number;
267
257
  }): Promise<VersionedTransaction>;
258
+ /**
259
+ * The standalone transaction Jupiter's `/swap` endpoint returns, setup and
260
+ * teardown included.
261
+ * @throws If the quote came from a different provider or a different wallet.
262
+ */
263
+ getSwapTransaction({ quote, userPublicKey, }: GetRouteInstructionsParams): Promise<VersionedTransaction>;
264
+ /**
265
+ * Builds the route instructions for a quote returned by {@link getQuote}.
266
+ *
267
+ * The quote carries its own route payload, so this reads no client state
268
+ * and two quotes in flight can never be confused for one another. The swap
269
+ * is built at the slippage the quote was priced at — re-quote to change it.
270
+ * @throws If the quote came from a different provider or a different wallet.
271
+ */
272
+ getRouteInstructions({ quote, userPublicKey, }: GetRouteInstructionsParams): Promise<SwapRouteInstructions>;
268
273
  /**
269
274
  * Get the transaction message and lookup tables for a transaction
270
275
  * @param transaction
@@ -277,10 +282,9 @@ export declare class JupiterClient {
277
282
  }>;
278
283
  getLookupTable(accountKey: PublicKey): Promise<AddressLookupTableAccount | undefined>;
279
284
  /**
280
- * Get the jupiter instructions from transaction by filtering out instructions to compute budget and associated token programs
281
- * @param transactionMessage the transaction message
282
- * @param inputMint the input mint
283
- * @param outputMint the output mint
285
+ * Strips the setup/teardown Jupiter wraps around its route.
286
+ * @deprecated Use {@link getRouteInstructions}, which quotes and filters in
287
+ * one step. Kept for callers holding a decompiled message of their own.
284
288
  */
285
289
  getJupiterInstructions({ transactionMessage, inputMint, outputMint, }: {
286
290
  transactionMessage: TransactionMessage;
@@ -6,6 +6,8 @@ Object.defineProperty(exports, "__esModule", { value: true });
6
6
  exports.JupiterClient = exports.RECOMMENDED_JUPITER_API = exports.LEGACY_JUPITER_API = exports.RECOMMENDED_JUPITER_API_VERSION = void 0;
7
7
  const web3_js_1 = require("@solana/web3.js");
8
8
  const node_fetch_1 = __importDefault(require("node-fetch"));
9
+ const routeInstructions_1 = require("../swap/routeInstructions");
10
+ const types_1 = require("../swap/types");
9
11
  exports.RECOMMENDED_JUPITER_API_VERSION = '/v1';
10
12
  /** @deprecated Use RECOMMENDED_JUPITER_API instead. lite-api.jup.ag requires migration to api.jup.ag with API key. */
11
13
  exports.LEGACY_JUPITER_API = 'https://lite-api.jup.ag/swap';
@@ -18,7 +20,8 @@ class JupiterClient {
18
20
  * @param apiKey - API key for Jupiter API. Required for api.jup.ag (free tier available at https://portal.jup.ag)
19
21
  */
20
22
  constructor({ connection, url, apiKey, }) {
21
- this.lookupTableCahce = new Map();
23
+ this.providerName = 'jupiter';
24
+ this.lookupTableCache = new Map();
22
25
  this.connection = connection;
23
26
  this.url = url !== null && url !== void 0 ? url : exports.RECOMMENDED_JUPITER_API;
24
27
  this.apiKey = apiKey;
@@ -45,8 +48,8 @@ class JupiterClient {
45
48
  * @param swapMode the swap mode (ExactIn or ExactOut)
46
49
  * @param onlyDirectRoutes whether to only return direct routes
47
50
  */
48
- async getQuote({ inputMint, outputMint, amount, maxAccounts = 50, // 50 is an estimated amount with buffer
49
- slippageBps = 50, swapMode = 'ExactIn', onlyDirectRoutes = false, excludeDexes, autoSlippage = false, maxAutoSlippageBps, usdEstimate, }) {
51
+ async getQuote({ inputMint, outputMint, amount, maxAccounts = types_1.DEFAULT_SWAP_MAX_ACCOUNTS, slippageBps = 50, swapMode = 'ExactIn', onlyDirectRoutes = false, excludeDexes, autoSlippage = false, maxAutoSlippageBps, usdEstimate, }) {
52
+ var _a;
50
53
  if (autoSlippage && maxAutoSlippageBps === undefined) {
51
54
  throw new Error('JupiterClient.getQuote: maxAutoSlippageBps is required when autoSlippage is enabled');
52
55
  }
@@ -78,20 +81,40 @@ class JupiterClient {
78
81
  : '';
79
82
  const headers = this.getHeaders();
80
83
  const fetchOptions = Object.keys(headers).length > 0 ? { headers } : {};
81
- const quote = await (await (0, node_fetch_1.default)(`${this.url}${apiVersionParam}/quote?${params.toString()}`, fetchOptions)).json();
82
- return quote;
84
+ const response = await (0, node_fetch_1.default)(`${this.url}${apiVersionParam}/quote?${params.toString()}`, fetchOptions);
85
+ const quote = (await response.json().catch(() => undefined));
86
+ // A failed quote still returns parseable JSON — an `{ error, errorCode }`
87
+ // body with no mints or amounts. Returning it unchecked pushes the failure
88
+ // downstream to /swap, which rejects it with an opaque deserialization
89
+ // error ("missing field `inputMint`") that hides the real cause.
90
+ if (!response.ok || !quote) {
91
+ throw new Error(`Jupiter quote failed: ${response.status} ${(quote === null || quote === void 0 ? void 0 : quote.error) || (quote === null || quote === void 0 ? void 0 : quote.errorCode) || response.statusText}`);
92
+ }
93
+ if (quote.error || quote.errorCode) {
94
+ throw new Error(`Jupiter quote failed: ${(_a = quote.error) !== null && _a !== void 0 ? _a : quote.errorCode}`);
95
+ }
96
+ if (!quote.inputMint || !quote.outputMint || !quote.outAmount) {
97
+ throw new Error('Jupiter quote failed: response is missing route fields');
98
+ }
99
+ // Jupiter's /swap endpoint takes the quote body back verbatim, so the
100
+ // quote is its own route payload.
101
+ return (0, types_1.buildSwapQuote)(quote, { provider: 'jupiter', quote });
83
102
  }
84
103
  /**
85
104
  * Get a swap transaction for quote
86
- * @param quoteResponse quote to perform swap
105
+ * @param quote quote to perform swap, from {@link getQuote}
87
106
  * @param userPublicKey the signer's wallet public key
88
- * @param slippageBps the slippage tolerance in basis points
107
+ *
108
+ * Always builds at the quote's own slippage — the price the caller was
109
+ * shown. Re-quote to change it rather than overriding it here.
89
110
  */
90
- async getSwap({ quote, userPublicKey, slippageBps = 50, }) {
111
+ async getSwap({ quote, userPublicKey, }) {
91
112
  var _a;
92
113
  if (!quote) {
93
114
  throw new Error('Jupiter swap quote not provided. Please try again.');
94
115
  }
116
+ // `providerRoute` is our own wrapper, not part of Jupiter's quote body.
117
+ const { providerRoute: _providerRoute, ...quoteResponse } = quote;
95
118
  const apiVersionParam = this.url === exports.RECOMMENDED_JUPITER_API || this.url === exports.LEGACY_JUPITER_API
96
119
  ? exports.RECOMMENDED_JUPITER_API_VERSION
97
120
  : '';
@@ -99,9 +122,9 @@ class JupiterClient {
99
122
  method: 'POST',
100
123
  headers: this.getHeaders('application/json'),
101
124
  body: JSON.stringify({
102
- quoteResponse: quote,
125
+ quoteResponse,
103
126
  userPublicKey,
104
- slippageBps,
127
+ slippageBps: quoteResponse.slippageBps,
105
128
  }),
106
129
  })).json();
107
130
  if (!('swapTransaction' in resp)) {
@@ -116,6 +139,41 @@ class JupiterClient {
116
139
  throw new Error('Something went wrong with creating the Jupiter swap transaction. Please try again.');
117
140
  }
118
141
  }
142
+ /**
143
+ * The standalone transaction Jupiter's `/swap` endpoint returns, setup and
144
+ * teardown included.
145
+ * @throws If the quote came from a different provider or a different wallet.
146
+ */
147
+ async getSwapTransaction({ quote, userPublicKey, }) {
148
+ const jupiterQuote = (0, types_1.expectProviderRoute)(quote, 'jupiter', userPublicKey)
149
+ .quote;
150
+ return this.getSwap({ quote: jupiterQuote, userPublicKey });
151
+ }
152
+ /**
153
+ * Builds the route instructions for a quote returned by {@link getQuote}.
154
+ *
155
+ * The quote carries its own route payload, so this reads no client state
156
+ * and two quotes in flight can never be confused for one another. The swap
157
+ * is built at the slippage the quote was priced at — re-quote to change it.
158
+ * @throws If the quote came from a different provider or a different wallet.
159
+ */
160
+ async getRouteInstructions({ quote, userPublicKey, }) {
161
+ const jupiterQuote = (0, types_1.expectProviderRoute)(quote, 'jupiter', userPublicKey)
162
+ .quote;
163
+ const transaction = await this.getSwap({
164
+ quote: jupiterQuote,
165
+ userPublicKey,
166
+ });
167
+ const { transactionMessage, lookupTables } = await this.getTransactionMessageAndLookupTables({ transaction });
168
+ return {
169
+ instructions: (0, routeInstructions_1.filterRouteInstructions)({
170
+ instructions: transactionMessage.instructions,
171
+ inputMint: new web3_js_1.PublicKey(quote.inputMint),
172
+ outputMint: new web3_js_1.PublicKey(quote.outputMint),
173
+ }),
174
+ lookupTables,
175
+ };
176
+ }
119
177
  /**
120
178
  * Get the transaction message and lookup tables for a transaction
121
179
  * @param transaction
@@ -134,40 +192,29 @@ class JupiterClient {
134
192
  };
135
193
  }
136
194
  async getLookupTable(accountKey) {
137
- var _a;
138
- const cached = this.lookupTableCahce.get(accountKey.toString());
195
+ const cached = this.lookupTableCache.get(accountKey.toString());
139
196
  if (cached !== undefined) {
140
197
  return cached;
141
198
  }
142
- return ((_a = (await this.connection.getAddressLookupTable(accountKey)).value) !== null && _a !== void 0 ? _a : undefined);
199
+ const lookupTable = (await this.connection.getAddressLookupTable(accountKey)).value;
200
+ if (!lookupTable) {
201
+ return undefined;
202
+ }
203
+ // Populate the cache — without this every route re-fetches the same tables,
204
+ // which is a large share of the RPC calls a swap makes.
205
+ this.lookupTableCache.set(accountKey.toString(), lookupTable);
206
+ return lookupTable;
143
207
  }
144
208
  /**
145
- * Get the jupiter instructions from transaction by filtering out instructions to compute budget and associated token programs
146
- * @param transactionMessage the transaction message
147
- * @param inputMint the input mint
148
- * @param outputMint the output mint
209
+ * Strips the setup/teardown Jupiter wraps around its route.
210
+ * @deprecated Use {@link getRouteInstructions}, which quotes and filters in
211
+ * one step. Kept for callers holding a decompiled message of their own.
149
212
  */
150
213
  getJupiterInstructions({ transactionMessage, inputMint, outputMint, }) {
151
- return transactionMessage.instructions.filter((instruction) => {
152
- if (instruction.programId.toString() ===
153
- 'ComputeBudget111111111111111111111111111111') {
154
- return false;
155
- }
156
- if (instruction.programId.toString() ===
157
- 'TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA') {
158
- return false;
159
- }
160
- if (instruction.programId.toString() === '11111111111111111111111111111111') {
161
- return false;
162
- }
163
- if (instruction.programId.toString() ===
164
- 'ATokenGPvbdGVxr1b2hvZbsiqW5xWH25efTNsLJA8knL') {
165
- const mint = instruction.keys[3].pubkey;
166
- if (mint.equals(inputMint) || mint.equals(outputMint)) {
167
- return false;
168
- }
169
- }
170
- return true;
214
+ return (0, routeInstructions_1.filterRouteInstructions)({
215
+ instructions: transactionMessage.instructions,
216
+ inputMint,
217
+ outputMint,
171
218
  });
172
219
  }
173
220
  }
@@ -100,3 +100,31 @@ export declare function calculateMarginUSDCRequiredForTrade(velocityClient: Velo
100
100
  * @returns Collateral amount required, in `collateralIndex`'s own spot-market precision (via `velocityClient.convertToSpotPrecision`).
101
101
  */
102
102
  export declare function calculateCollateralDepositRequiredForTrade(velocityClient: VelocityClient, targetMarketIndex: number, baseSize: BN, collateralIndex: number, userMaxMarginRatio?: number, estEntryPrice?: BN): BN;
103
+ /**
104
+ * Minimal equity floor to carry along with a quote transfer of `amount` out
105
+ * of a subaccount so the debited side ends at/above its buffered floor
106
+ * (`equityFloor + equityFloorBuffer`): the first
107
+ * `netEquity - (floor + buffer)` of the transfer carries no floor, the
108
+ * remainder carries floor one-for-one, capped at the floor the subaccount
109
+ * actually holds. `netEquity` is `User.getNetUsdValue()`, the metric the
110
+ * onchain floor checks use. Returns zero when no floor is set. The result
111
+ * never exceeds `amount`, so a credited side that met its own buffered floor
112
+ * before the transfer still meets it after. All values QUOTE_PRECISION.
113
+ */
114
+ export declare function calculateEquityFloorAutoDelta(amount: BN, netEquity: BN, equityFloor: BN, equityFloorBuffer: BN): BN;
115
+ /**
116
+ * Severity of a subaccount's equity relative to its floor, most to least
117
+ * severe. `breached`: below the floor, the permissionless breaker can trip.
118
+ * `critical`: below `floor + buffer`, risk-increasing actions are rejecting.
119
+ * `warning`: within `warningBufferMultiple * buffer` of the floor.
120
+ * `healthy`: above all thresholds. `disabled`: no floor set.
121
+ */
122
+ export type EquityFloorLevel = 'breached' | 'critical' | 'warning' | 'healthy' | 'disabled';
123
+ /**
124
+ * Classifies `netEquity` (`User.getNetUsdValue()`) against the floor
125
+ * thresholds. Used by the `EquityFloorManager` and the equity-floor guard bot
126
+ * so both report the same levels. `warningBufferMultiple` scales the warning
127
+ * threshold above the floor (default 2: warn inside `floor + 2 * buffer`).
128
+ * All QUOTE_PRECISION.
129
+ */
130
+ export declare function getEquityFloorLevel(netEquity: BN, equityFloor: BN, equityFloorBuffer: BN, warningBufferMultiple?: number): EquityFloorLevel;