@renegade-fi/renegade-sdk 1.0.2 → 2.0.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 (39) hide show
  1. package/dist/client.js +156 -386
  2. package/dist/client.js.map +1 -1
  3. package/dist/http.js +0 -2
  4. package/dist/http.js.map +1 -1
  5. package/dist/index.js.map +1 -1
  6. package/dist/types/client.d.ts +31 -183
  7. package/dist/types/client.d.ts.map +1 -1
  8. package/dist/types/fixedPoint.js +6 -0
  9. package/dist/types/fixedPoint.js.map +1 -1
  10. package/dist/types/http.d.ts.map +1 -1
  11. package/dist/types/index.d.ts +2 -1
  12. package/dist/types/index.d.ts.map +1 -1
  13. package/dist/types/index.js +25 -3
  14. package/dist/types/index.js.map +1 -1
  15. package/dist/types/malleableMatch.js +92 -225
  16. package/dist/types/malleableMatch.js.map +1 -1
  17. package/dist/types/types/fixedPoint.d.ts +4 -0
  18. package/dist/types/types/fixedPoint.d.ts.map +1 -1
  19. package/dist/types/types/index.d.ts +8 -3
  20. package/dist/types/types/index.d.ts.map +1 -1
  21. package/dist/types/types/malleableMatch.d.ts +48 -120
  22. package/dist/types/types/malleableMatch.d.ts.map +1 -1
  23. package/dist/types/types/v2Types.d.ts +120 -0
  24. package/dist/types/types/v2Types.d.ts.map +1 -0
  25. package/dist/types/v1Conversions.d.ts +16 -0
  26. package/dist/types/v1Conversions.d.ts.map +1 -0
  27. package/dist/types/v2Types.js +232 -0
  28. package/dist/types/v2Types.js.map +1 -0
  29. package/dist/v1Conversions.js +276 -0
  30. package/dist/v1Conversions.js.map +1 -0
  31. package/package.json +1 -1
  32. package/src/client.ts +214 -442
  33. package/src/http.ts +0 -2
  34. package/src/index.ts +11 -0
  35. package/src/types/fixedPoint.ts +7 -0
  36. package/src/types/index.ts +15 -1
  37. package/src/types/malleableMatch.ts +126 -290
  38. package/src/types/v2Types.ts +392 -0
  39. package/src/v1Conversions.ts +372 -0
package/dist/client.js CHANGED
@@ -5,47 +5,36 @@
5
5
  * assembling matches, and executing trades.
6
6
  */
7
7
  import { RelayerHttpClient } from "./http.js";
8
- import { ExchangeMetadataResponse, ExternalMatchResponse, GetDepthForAllPairsResponse, MalleableExternalMatchResponse, OrderBookDepth, SignedExternalQuote, } from "./types/index.js";
8
+ import { ExchangeMetadataResponse, MalleableExternalMatchResponse, } from "./types/index.js";
9
+ import { deserializeMarketDepthResponse, deserializeMarketDepthsResponse, deserializeMarketsResponse, deserializeMatchResponseV2, deserializeQuoteResponseV2, serializeAssembleRequestV2, serializeQuoteRequestV2, } from "./types/v2Types.js";
10
+ import { marketDepthsToV1, marketDepthToV1, marketsToSupportedTokens, marketsToTokenPrices, v1OrderToV2, v1QuoteToV2, v2QuoteToV1, v2ResponseToV1NonMalleable, } from "./v1Conversions.js";
9
11
  import { VERSION } from "./version.js";
10
- // Constants for API URLs
11
- const ARBITRUM_SEPOLIA_BASE_URL = "https://arbitrum-sepolia.auth-server.renegade.fi";
12
- const ARBITRUM_ONE_BASE_URL = "https://arbitrum-one.auth-server.renegade.fi";
13
- const BASE_SEPOLIA_BASE_URL = "https://base-sepolia.auth-server.renegade.fi";
14
- const BASE_MAINNET_BASE_URL = "https://base-mainnet.auth-server.renegade.fi";
15
- const ARBITRUM_SEPOLIA_RELAYER_URL = "https://arbitrum-sepolia.relayer.renegade.fi";
16
- const ARBITRUM_ONE_RELAYER_URL = "https://arbitrum-one.relayer.renegade.fi";
17
- const BASE_SEPOLIA_RELAYER_URL = "https://base-sepolia.relayer.renegade.fi";
18
- const BASE_MAINNET_RELAYER_URL = "https://base-mainnet.relayer.renegade.fi";
12
+ // Constants for auth server URLs
13
+ const ARBITRUM_SEPOLIA_BASE_URL = "https://arbitrum-sepolia.v2.auth-server.renegade.fi";
14
+ const ARBITRUM_ONE_BASE_URL = "https://arbitrum-one.v2.auth-server.renegade.fi";
15
+ const BASE_SEPOLIA_BASE_URL = "https://base-sepolia.v2.auth-server.renegade.fi";
16
+ const BASE_MAINNET_BASE_URL = "https://base-mainnet.v2.auth-server.renegade.fi";
17
+ // Constants for relayer URLs
18
+ const ARBITRUM_SEPOLIA_RELAYER_URL = "https://arbitrum-sepolia.v2.relayer.renegade.fi";
19
+ const ARBITRUM_ONE_RELAYER_URL = "https://arbitrum-one.v2.relayer.renegade.fi";
20
+ const BASE_SEPOLIA_RELAYER_URL = "https://base-sepolia.v2.relayer.renegade.fi";
21
+ const BASE_MAINNET_RELAYER_URL = "https://base-mainnet.v2.relayer.renegade.fi";
19
22
  // Header constants
20
23
  const RENEGADE_API_KEY_HEADER = "x-renegade-api-key";
21
24
  const RENEGADE_SDK_VERSION_HEADER = "x-renegade-sdk-version";
22
- // API Routes
23
- const REQUEST_EXTERNAL_QUOTE_ROUTE = "/v0/matching-engine/quote";
24
- const ASSEMBLE_EXTERNAL_MATCH_ROUTE = "/v0/matching-engine/assemble-external-match";
25
- /**
26
- * The route used to assemble an external match into a malleable bundle
27
- */
28
- const ASSEMBLE_MALLEABLE_EXTERNAL_MATCH_ROUTE = "/v0/matching-engine/assemble-malleable-external-match";
29
- const REQUEST_EXTERNAL_MATCH_ROUTE = "/v0/matching-engine/request-external-match";
30
- /**
31
- * The route used to request a malleable external match directly
32
- */
33
- const REQUEST_MALLEABLE_EXTERNAL_MATCH_ROUTE = "/v0/matching-engine/request-malleable-external-match";
34
- const ORDER_BOOK_DEPTH_ROUTE = "/v0/order_book/depth";
35
- /** Returns the supported tokens list */
36
- const SUPPORTED_TOKENS_ROUTE = "/v0/supported-tokens";
37
- /** Returns the token prices */
38
- const TOKEN_PRICES_ROUTE = "/v0/token-prices";
39
- /** Returns the exchange metadata */
40
- const EXCHANGE_METADATA_ROUTE = "/v0/exchange-metadata";
25
+ // V2 API Routes
26
+ const GET_QUOTE_ROUTE = "/v2/external-matches/get-quote";
27
+ const ASSEMBLE_MATCH_BUNDLE_ROUTE = "/v2/external-matches/assemble-match-bundle";
28
+ const GET_MARKETS_ROUTE = "/v2/markets";
29
+ const GET_MARKET_DEPTH_BY_MINT_ROUTE = "/v2/markets"; // /{mint}/depth appended dynamically
30
+ const GET_MARKETS_DEPTH_ROUTE = "/v2/markets/depth";
31
+ const GET_EXCHANGE_METADATA_ROUTE = "/v2/metadata/exchange";
41
32
  // Query Parameters
42
33
  const DISABLE_GAS_SPONSORSHIP_QUERY_PARAM = "disable_gas_sponsorship";
43
34
  const GAS_REFUND_ADDRESS_QUERY_PARAM = "refund_address";
44
35
  const REFUND_NATIVE_ETH_QUERY_PARAM = "refund_native_eth";
45
36
  /**
46
37
  * Get the SDK version string.
47
- *
48
- * @returns The SDK version prefixed with "typescript-v"
49
38
  */
50
39
  function getSdkVersion() {
51
40
  return `typescript-v${VERSION}`;
@@ -74,36 +63,21 @@ export class RequestQuoteOptions {
74
63
  value: false
75
64
  });
76
65
  }
77
- /**
78
- * Create a new instance of RequestQuoteOptions.
79
- */
80
66
  static new() {
81
67
  return new RequestQuoteOptions();
82
68
  }
83
- /**
84
- * Set whether gas sponsorship should be disabled.
85
- */
86
69
  withGasSponsorshipDisabled(disableGasSponsorship) {
87
70
  this.disableGasSponsorship = disableGasSponsorship;
88
71
  return this;
89
72
  }
90
- /**
91
- * Set the gas refund address.
92
- */
93
73
  withGasRefundAddress(gasRefundAddress) {
94
74
  this.gasRefundAddress = gasRefundAddress;
95
75
  return this;
96
76
  }
97
- /**
98
- * Set whether to refund in native ETH.
99
- */
100
77
  withRefundNativeEth(refundNativeEth) {
101
78
  this.refundNativeEth = refundNativeEth;
102
79
  return this;
103
80
  }
104
- /**
105
- * Build the request path with query parameters.
106
- */
107
81
  buildRequestPath() {
108
82
  const params = new URLSearchParams();
109
83
  params.set(DISABLE_GAS_SPONSORSHIP_QUERY_PARAM, this.disableGasSponsorship.toString());
@@ -113,7 +87,7 @@ export class RequestQuoteOptions {
113
87
  if (this.refundNativeEth) {
114
88
  params.set(REFUND_NATIVE_ETH_QUERY_PARAM, this.refundNativeEth.toString());
115
89
  }
116
- return `${REQUEST_EXTERNAL_QUOTE_ROUTE}?${params.toString()}`;
90
+ return `${GET_QUOTE_ROUTE}?${params.toString()}`;
117
91
  }
118
92
  }
119
93
  /**
@@ -152,50 +126,29 @@ export class RequestExternalMatchOptions {
152
126
  value: void 0
153
127
  });
154
128
  }
155
- /**
156
- * Create a new instance of RequestExternalMatchOptions.
157
- */
158
129
  static new() {
159
130
  return new RequestExternalMatchOptions();
160
131
  }
161
- /**
162
- * Set whether gas sponsorship should be disabled.
163
- */
164
132
  withGasSponsorshipDisabled(disableGasSponsorship) {
165
133
  this.disableGasSponsorship = disableGasSponsorship;
166
134
  return this;
167
135
  }
168
- /**
169
- * Set the gas refund address.
170
- */
171
136
  withGasRefundAddress(gasRefundAddress) {
172
137
  this.gasRefundAddress = gasRefundAddress;
173
138
  return this;
174
139
  }
175
- /**
176
- * Set whether to refund in native ETH.
177
- */
178
140
  withRefundNativeEth(refundNativeEth) {
179
141
  this.refundNativeEth = refundNativeEth;
180
142
  return this;
181
143
  }
182
- /**
183
- * Set whether the relayer should include gas estimation in the response.
184
- */
185
144
  withGasEstimation(doGasEstimation) {
186
145
  this.doGasEstimation = doGasEstimation;
187
146
  return this;
188
147
  }
189
- /**
190
- * Set the receiver address for the match.
191
- */
192
148
  withReceiverAddress(receiverAddress) {
193
149
  this.receiverAddress = receiverAddress;
194
150
  return this;
195
151
  }
196
- /**
197
- * Build the request path with query parameters.
198
- */
199
152
  buildRequestPath() {
200
153
  const params = new URLSearchParams();
201
154
  params.set(DISABLE_GAS_SPONSORSHIP_QUERY_PARAM, this.disableGasSponsorship.toString());
@@ -207,25 +160,8 @@ export class RequestExternalMatchOptions {
207
160
  }
208
161
  const query = params.toString();
209
162
  return query.length > 0
210
- ? `${REQUEST_EXTERNAL_MATCH_ROUTE}?${query}`
211
- : REQUEST_EXTERNAL_MATCH_ROUTE;
212
- }
213
- /**
214
- * Build the request path for malleable external match with query parameters.
215
- */
216
- buildMalleableRequestPath() {
217
- const params = new URLSearchParams();
218
- params.set(DISABLE_GAS_SPONSORSHIP_QUERY_PARAM, this.disableGasSponsorship.toString());
219
- if (this.gasRefundAddress) {
220
- params.set(GAS_REFUND_ADDRESS_QUERY_PARAM, this.gasRefundAddress);
221
- }
222
- if (this.refundNativeEth) {
223
- params.set(REFUND_NATIVE_ETH_QUERY_PARAM, this.refundNativeEth.toString());
224
- }
225
- const query = params.toString();
226
- return query.length > 0
227
- ? `${REQUEST_MALLEABLE_EXTERNAL_MATCH_ROUTE}?${query}`
228
- : REQUEST_MALLEABLE_EXTERNAL_MATCH_ROUTE;
163
+ ? `${ASSEMBLE_MATCH_BUNDLE_ROUTE}?${query}`
164
+ : ASSEMBLE_MATCH_BUNDLE_ROUTE;
229
165
  }
230
166
  }
231
167
  /**
@@ -239,12 +175,6 @@ export class AssembleExternalMatchOptions {
239
175
  writable: true,
240
176
  value: false
241
177
  });
242
- Object.defineProperty(this, "allowShared", {
243
- enumerable: true,
244
- configurable: true,
245
- writable: true,
246
- value: false
247
- });
248
178
  Object.defineProperty(this, "receiverAddress", {
249
179
  enumerable: true,
250
180
  configurable: true,
@@ -257,116 +187,33 @@ export class AssembleExternalMatchOptions {
257
187
  writable: true,
258
188
  value: void 0
259
189
  });
260
- Object.defineProperty(this, "requestGasSponsorship", {
261
- enumerable: true,
262
- configurable: true,
263
- writable: true,
264
- value: false
265
- });
266
- Object.defineProperty(this, "gasRefundAddress", {
267
- enumerable: true,
268
- configurable: true,
269
- writable: true,
270
- value: void 0
271
- });
272
190
  }
273
- /**
274
- * Create a new instance of AssembleExternalMatchOptions.
275
- */
276
191
  static new() {
277
192
  return new AssembleExternalMatchOptions();
278
193
  }
279
- /**
280
- * Set whether to do gas estimation.
281
- */
282
194
  withGasEstimation(doGasEstimation) {
283
195
  this.doGasEstimation = doGasEstimation;
284
196
  return this;
285
197
  }
286
- /**
287
- * Set whether to allow shared gas sponsorship.
288
- */
289
- withAllowShared(allowShared) {
290
- this.allowShared = allowShared;
291
- return this;
292
- }
293
- /**
294
- * Set the receiver address.
295
- */
296
198
  withReceiverAddress(receiverAddress) {
297
199
  this.receiverAddress = receiverAddress;
298
200
  return this;
299
201
  }
300
- /**
301
- * Set the updated order.
302
- */
303
202
  withUpdatedOrder(updatedOrder) {
304
203
  this.updatedOrder = updatedOrder;
305
204
  return this;
306
205
  }
307
- /**
308
- * Set whether to request gas sponsorship.
309
- * @deprecated Request gas sponsorship when requesting a quote instead
310
- */
311
- withGasSponsorship(requestGasSponsorship) {
312
- this.requestGasSponsorship = requestGasSponsorship;
313
- return this;
314
- }
315
- /**
316
- * Set the gas refund address.
317
- * @deprecated Request gas sponsorship when requesting a quote instead
318
- */
319
- withGasRefundAddress(gasRefundAddress) {
320
- this.gasRefundAddress = gasRefundAddress;
321
- return this;
322
- }
323
- /**
324
- * Build the request path with query parameters.
325
- */
326
206
  buildRequestPath() {
327
- // If no query parameters are needed, return the base path
328
- if (!this.requestGasSponsorship && !this.gasRefundAddress) {
329
- return ASSEMBLE_EXTERNAL_MATCH_ROUTE;
330
- }
331
- const params = new URLSearchParams();
332
- if (this.requestGasSponsorship) {
333
- // We only write this query parameter if it was explicitly set
334
- params.set(DISABLE_GAS_SPONSORSHIP_QUERY_PARAM, (!this.requestGasSponsorship).toString());
335
- }
336
- if (this.gasRefundAddress) {
337
- params.set(GAS_REFUND_ADDRESS_QUERY_PARAM, this.gasRefundAddress);
338
- }
339
- return `${ASSEMBLE_EXTERNAL_MATCH_ROUTE}?${params.toString()}`;
207
+ return ASSEMBLE_MATCH_BUNDLE_ROUTE;
340
208
  }
341
209
  }
342
210
  /**
343
211
  * Options for assembling a malleable external match.
344
212
  */
345
213
  export class AssembleMalleableExternalMatchOptions extends AssembleExternalMatchOptions {
346
- /**
347
- * Create a new instance of AssembleExternalMatchOptions.
348
- */
349
214
  static new() {
350
215
  return new AssembleMalleableExternalMatchOptions();
351
216
  }
352
- /**
353
- * Build the request path with query parameters.
354
- */
355
- buildRequestPath() {
356
- // If no query parameters are needed, return the base path
357
- if (!this.requestGasSponsorship && !this.gasRefundAddress) {
358
- return ASSEMBLE_MALLEABLE_EXTERNAL_MATCH_ROUTE;
359
- }
360
- const params = new URLSearchParams();
361
- if (this.requestGasSponsorship) {
362
- // We only write this query parameter if it was explicitly set
363
- params.set(DISABLE_GAS_SPONSORSHIP_QUERY_PARAM, (!this.requestGasSponsorship).toString());
364
- }
365
- if (this.gasRefundAddress) {
366
- params.set(GAS_REFUND_ADDRESS_QUERY_PARAM, this.gasRefundAddress);
367
- }
368
- return `${ASSEMBLE_MALLEABLE_EXTERNAL_MATCH_ROUTE}?${params.toString()}`;
369
- }
370
217
  }
371
218
  /**
372
219
  * Validate that an external order has the required fields and exactly one sizing field set.
@@ -411,6 +258,19 @@ export class ExternalMatchClientError extends Error {
411
258
  this.statusCode = statusCode;
412
259
  }
413
260
  }
261
+ /**
262
+ * Build a v2 assemble request for a direct order.
263
+ */
264
+ function buildDirectOrderRequest(v2Order, options) {
265
+ return {
266
+ do_gas_estimation: options.doGasEstimation,
267
+ receiver_address: options.receiverAddress,
268
+ order: {
269
+ type: "direct-order",
270
+ external_order: v2Order,
271
+ },
272
+ };
273
+ }
414
274
  /**
415
275
  * Client for interacting with the Renegade external matching API.
416
276
  */
@@ -420,9 +280,10 @@ export class ExternalMatchClient {
420
280
  *
421
281
  * @param apiKey The API key for authentication
422
282
  * @param apiSecret The API secret for request signing
423
- * @param baseUrl The base URL of the Renegade API
283
+ * @param baseUrl The base URL of the auth server API
284
+ * @param relayerBaseUrl The base URL of the relayer API (for market endpoints)
424
285
  */
425
- constructor(apiKey, apiSecret, baseUrl, relayerUrl) {
286
+ constructor(apiKey, apiSecret, baseUrl, relayerBaseUrl) {
426
287
  Object.defineProperty(this, "apiKey", {
427
288
  enumerable: true,
428
289
  configurable: true,
@@ -443,93 +304,91 @@ export class ExternalMatchClient {
443
304
  });
444
305
  this.apiKey = apiKey;
445
306
  this.httpClient = new RelayerHttpClient(baseUrl, apiSecret);
446
- this.relayerHttpClient = new RelayerHttpClient(relayerUrl);
447
- }
448
- /**
449
- * Create a new client configured for the Arbitrum Sepolia testnet.
450
- *
451
- * @deprecated Use {@link ExternalMatchClient.newArbitrumSepoliaClient} instead
452
- */
453
- static newSepoliaClient(apiKey, apiSecret) {
454
- return ExternalMatchClient.newArbitrumSepoliaClient(apiKey, apiSecret);
307
+ if (relayerBaseUrl) {
308
+ this.relayerHttpClient = new RelayerHttpClient(relayerBaseUrl, apiSecret);
309
+ }
455
310
  }
456
311
  /**
457
312
  * Create a new client configured for the Arbitrum Sepolia testnet.
458
- *
459
- * @param apiKey The API key for authentication
460
- * @param apiSecret The API secret for request signing
461
- * @param relayerUrl The relayer URL for the client
462
- * @returns A new ExternalMatchClient configured for Sepolia
463
313
  */
464
314
  static newArbitrumSepoliaClient(apiKey, apiSecret) {
465
315
  return new ExternalMatchClient(apiKey, apiSecret, ARBITRUM_SEPOLIA_BASE_URL, ARBITRUM_SEPOLIA_RELAYER_URL);
466
316
  }
467
317
  /**
468
318
  * Create a new client configured for the Base Sepolia testnet.
469
- *
470
- * @param apiKey The API key for authentication
471
- * @param apiSecret The API secret for request signing
472
- * @returns A new ExternalMatchClient configured for Sepolia
473
319
  */
474
320
  static newBaseSepoliaClient(apiKey, apiSecret) {
475
321
  return new ExternalMatchClient(apiKey, apiSecret, BASE_SEPOLIA_BASE_URL, BASE_SEPOLIA_RELAYER_URL);
476
322
  }
477
323
  /**
478
324
  * Create a new client configured for the Arbitrum One mainnet.
479
- *
480
- * @deprecated Use {@link ExternalMatchClient.newArbitrumOneClient} instead
481
- */
482
- static newMainnetClient(apiKey, apiSecret) {
483
- return ExternalMatchClient.newArbitrumOneClient(apiKey, apiSecret);
484
- }
485
- /**
486
- * Create a new client configured for the Arbitrum One mainnet.
487
- *
488
- * @param apiKey The API key for authentication
489
- * @param apiSecret The API secret for request signing
490
- * @returns A new ExternalMatchClient configured for mainnet
491
325
  */
492
326
  static newArbitrumOneClient(apiKey, apiSecret) {
493
327
  return new ExternalMatchClient(apiKey, apiSecret, ARBITRUM_ONE_BASE_URL, ARBITRUM_ONE_RELAYER_URL);
494
328
  }
495
329
  /**
496
330
  * Create a new client configured for the Base mainnet.
497
- *
498
- * @param apiKey The API key for authentication
499
- * @param apiSecret The API secret for request signing
500
- * @returns A new ExternalMatchClient configured for mainnet
501
331
  */
502
332
  static newBaseMainnetClient(apiKey, apiSecret) {
503
333
  return new ExternalMatchClient(apiKey, apiSecret, BASE_MAINNET_BASE_URL, BASE_MAINNET_RELAYER_URL);
504
334
  }
335
+ // --- Quote methods (v1 signature, v2 internally) ---
505
336
  /**
506
337
  * Request a quote for the given order.
507
- *
508
- * @param order The order to request a quote for
509
- * @returns A promise that resolves to a signed quote if one is available, null otherwise
510
- * @throws ExternalMatchClientError if the request fails
511
338
  */
512
339
  async requestQuote(order) {
513
340
  return this.requestQuoteWithOptions(order, RequestQuoteOptions.new());
514
341
  }
515
342
  /**
516
343
  * Request a quote for the given order with custom options.
517
- *
518
- * @param order The order to request a quote for
519
- * @param options Custom options for the quote request
520
- * @returns A promise that resolves to a signed quote if one is available, null otherwise
521
- * @throws ExternalMatchClientError if the request fails
522
344
  */
523
345
  async requestQuoteWithOptions(order, options) {
524
346
  validateExternalOrder(order);
347
+ const v2Order = v1OrderToV2(order);
348
+ const body = serializeQuoteRequestV2({ external_order: v2Order });
349
+ const path = options.buildRequestPath();
350
+ const headers = this.getHeaders();
351
+ const response = await this.httpClient.post(path, body, headers);
352
+ return this.handleOptionalResponse(response, (data) => {
353
+ const v2Response = deserializeQuoteResponseV2(data);
354
+ return v2QuoteToV1(v2Response, order);
355
+ });
356
+ }
357
+ // --- Assemble methods (v1 signature, v2 internally) ---
358
+ /**
359
+ * Assemble a quote into a match bundle with default options.
360
+ */
361
+ async assembleQuote(quote) {
362
+ return this.assembleQuoteWithOptions(quote, AssembleExternalMatchOptions.new());
363
+ }
364
+ /**
365
+ * Assemble a quote into a match bundle with custom options.
366
+ */
367
+ async assembleQuoteWithOptions(quote, options) {
368
+ if (options.updatedOrder) {
369
+ validateExternalOrder(options.updatedOrder);
370
+ }
371
+ const direction = quote.quote.order.side;
372
+ const v2SignedQuote = v1QuoteToV2(quote);
525
373
  const request = {
526
- external_order: order,
374
+ do_gas_estimation: options.doGasEstimation,
375
+ receiver_address: options.receiverAddress,
376
+ order: {
377
+ type: "quoted-order",
378
+ signed_quote: v2SignedQuote,
379
+ updated_order: options.updatedOrder ? v1OrderToV2(options.updatedOrder) : undefined,
380
+ },
527
381
  };
528
- const path = options.buildRequestPath();
382
+ const body = serializeAssembleRequestV2(request);
383
+ const path = ASSEMBLE_MATCH_BUNDLE_ROUTE;
529
384
  const headers = this.getHeaders();
530
- const response = await this.httpClient.post(path, request, headers);
531
- return this.handleOptionalResponse(response, SignedExternalQuote.deserialize);
385
+ const response = await this.httpClient.post(path, body, headers);
386
+ return this.handleOptionalResponse(response, (data) => {
387
+ const v2Resp = deserializeMatchResponseV2(data);
388
+ return v2ResponseToV1NonMalleable(v2Resp, direction);
389
+ });
532
390
  }
391
+ // --- Direct match methods (v1 signature, v2 internally) ---
533
392
  /**
534
393
  * Request an external match directly with default options.
535
394
  */
@@ -541,91 +400,39 @@ export class ExternalMatchClient {
541
400
  */
542
401
  async requestExternalMatchWithOptions(order, options) {
543
402
  validateExternalOrder(order);
544
- const request = {
545
- do_gas_estimation: options.doGasEstimation,
546
- receiver_address: options.receiverAddress,
547
- external_order: order,
548
- };
403
+ const v2Order = v1OrderToV2(order);
404
+ const request = buildDirectOrderRequest(v2Order, options);
405
+ const body = serializeAssembleRequestV2(request);
549
406
  const path = options.buildRequestPath();
550
407
  const headers = this.getHeaders();
551
- const response = await this.httpClient.post(path, request, headers);
552
- return this.handleOptionalResponse(response, ExternalMatchResponse.deserialize);
408
+ const response = await this.httpClient.post(path, body, headers);
409
+ return this.handleOptionalResponse(response, (data) => {
410
+ const v2Resp = deserializeMatchResponseV2(data);
411
+ return v2ResponseToV1NonMalleable(v2Resp, order.side);
412
+ });
553
413
  }
414
+ // --- Malleable match methods (v1 input, v2 response — breaking) ---
554
415
  /**
555
416
  * Request a malleable external match directly with default options.
556
- *
557
- * @param order The order to request a malleable match for
558
- * @returns A promise that resolves to a malleable match response if one is available, null otherwise
559
- * @throws ExternalMatchClientError if the request fails
560
417
  */
561
418
  async requestMalleableExternalMatch(order) {
562
419
  return this.requestMalleableExternalMatchWithOptions(order, RequestExternalMatchOptions.new());
563
420
  }
564
421
  /**
565
422
  * Request a malleable external match directly with custom options.
566
- *
567
- * @param order The order to request a malleable match for
568
- * @param options Custom options for the malleable match request
569
- * @returns A promise that resolves to a malleable match response if one is available, null otherwise
570
- * @throws ExternalMatchClientError if the request fails
571
423
  */
572
424
  async requestMalleableExternalMatchWithOptions(order, options) {
573
425
  validateExternalOrder(order);
574
- const request = {
575
- do_gas_estimation: options.doGasEstimation,
576
- receiver_address: options.receiverAddress,
577
- external_order: order,
578
- };
579
- const path = options.buildMalleableRequestPath();
580
- const headers = this.getHeaders();
581
- const response = await this.httpClient.post(path, request, headers);
582
- return this.handleOptionalResponse(response, MalleableExternalMatchResponse.deserialize);
583
- }
584
- /**
585
- * Assemble a quote into a match bundle with default options.
586
- *
587
- * @param quote The signed quote to assemble
588
- * @returns A promise that resolves to a match response if assembly succeeds, null otherwise
589
- * @throws ExternalMatchClientError if the request fails
590
- */
591
- async assembleQuote(quote) {
592
- return this.assembleQuoteWithOptions(quote, AssembleExternalMatchOptions.new());
593
- }
594
- /**
595
- * Assemble a quote into a match bundle with custom options.
596
- *
597
- * @param quote The signed quote to assemble
598
- * @param options Custom options for quote assembly
599
- * @returns A promise that resolves to a match response if assembly succeeds, null otherwise
600
- * @throws ExternalMatchClientError if the request fails
601
- */
602
- async assembleQuoteWithOptions(quote, options) {
603
- if (options.updatedOrder) {
604
- validateExternalOrder(options.updatedOrder);
605
- }
606
- const signedQuote = {
607
- quote: quote.quote,
608
- signature: quote.signature,
609
- deadline: quote.deadline,
610
- };
611
- const request = {
612
- do_gas_estimation: options.doGasEstimation,
613
- allow_shared: options.allowShared,
614
- receiver_address: options.receiverAddress,
615
- signed_quote: signedQuote,
616
- updated_order: options.updatedOrder,
617
- };
426
+ const v2Order = v1OrderToV2(order);
427
+ const request = buildDirectOrderRequest(v2Order, options);
428
+ const body = serializeAssembleRequestV2(request);
618
429
  const path = options.buildRequestPath();
619
430
  const headers = this.getHeaders();
620
- const response = await this.httpClient.post(path, request, headers);
621
- return this.handleOptionalResponse(response, ExternalMatchResponse.deserialize);
431
+ const response = await this.httpClient.post(path, body, headers);
432
+ return this.handleOptionalResponse(response, MalleableExternalMatchResponse.deserialize);
622
433
  }
623
434
  /**
624
435
  * Assemble a quote into a malleable match bundle with default options.
625
- *
626
- * @param quote The signed quote to assemble
627
- * @returns A promise that resolves to a match response if assembly succeeds, null otherwise
628
- * @throws ExternalMatchClientError if the request fails
629
436
  */
630
437
  async assembleMalleableQuote(quote) {
631
438
  return this.assembleMalleableQuoteWithOptions(quote, AssembleMalleableExternalMatchOptions.new());
@@ -637,121 +444,96 @@ export class ExternalMatchClient {
637
444
  if (options.updatedOrder) {
638
445
  validateExternalOrder(options.updatedOrder);
639
446
  }
640
- const signedQuote = {
641
- quote: quote.quote,
642
- signature: quote.signature,
643
- deadline: quote.deadline,
644
- };
447
+ const v2SignedQuote = v1QuoteToV2(quote);
645
448
  const request = {
646
449
  do_gas_estimation: options.doGasEstimation,
647
- allow_shared: options.allowShared,
648
450
  receiver_address: options.receiverAddress,
649
- signed_quote: signedQuote,
650
- updated_order: options.updatedOrder,
451
+ order: {
452
+ type: "quoted-order",
453
+ signed_quote: v2SignedQuote,
454
+ updated_order: options.updatedOrder ? v1OrderToV2(options.updatedOrder) : undefined,
455
+ },
651
456
  };
652
- const path = options.buildRequestPath();
457
+ const body = serializeAssembleRequestV2(request);
458
+ const path = ASSEMBLE_MATCH_BUNDLE_ROUTE;
653
459
  const headers = this.getHeaders();
654
- const response = await this.httpClient.post(path, request, headers);
460
+ const response = await this.httpClient.post(path, body, headers);
655
461
  return this.handleOptionalResponse(response, MalleableExternalMatchResponse.deserialize);
656
462
  }
463
+ // --- New v2 market methods ---
657
464
  /**
658
- * Get order book depth for a given base token mint.
659
- *
660
- * @param mint The base token mint address
661
- * @returns A promise that resolves to the order book depth
662
- * @throws ExternalMatchClientError if the request fails
465
+ * Get all tradable markets.
663
466
  */
664
- async getOrderBookDepth(mint) {
665
- const path = `${ORDER_BOOK_DEPTH_ROUTE}/${mint}`;
666
- const headers = this.getHeaders();
667
- try {
668
- const response = await this.httpClient.get(path, headers);
669
- if (response.status !== 200 || !response.data) {
670
- throw new ExternalMatchClientError("Failed to get order book depth", response.status);
671
- }
672
- return this.handleOptionalResponse(response, OrderBookDepth.deserialize);
673
- }
674
- catch (error) {
675
- throw new ExternalMatchClientError(error.message || "Failed to get order book depth", error.status);
467
+ async getMarkets() {
468
+ const client = this.relayerHttpClient ?? this.httpClient;
469
+ const response = await client.get(GET_MARKETS_ROUTE);
470
+ if (response.status !== 200 || !response.data) {
471
+ throw new ExternalMatchClientError("Failed to get markets", response.status);
676
472
  }
473
+ return deserializeMarketsResponse(response.data);
677
474
  }
678
475
  /**
679
- * Get order book depth for all pairs
680
- * @returns A promise that resolves to the order book depth for all pairs
681
- * @throws ExternalMatchClientError if the request fails
476
+ * Get market depth for a given base token mint.
682
477
  */
683
- async getOrderBookDepthAllPairs() {
684
- const path = `${ORDER_BOOK_DEPTH_ROUTE}`;
478
+ async getMarketDepth(mint) {
479
+ const path = `${GET_MARKET_DEPTH_BY_MINT_ROUTE}/${mint}/depth`;
685
480
  const headers = this.getHeaders();
686
- try {
687
- const response = await this.httpClient.get(path, headers);
688
- if (response.status !== 200 || !response.data) {
689
- throw new ExternalMatchClientError("Failed to get order book depth", response.status);
690
- }
691
- return this.handleOptionalResponse(response, GetDepthForAllPairsResponse.deserialize);
692
- }
693
- catch (error) {
694
- throw new ExternalMatchClientError(error.message || "Failed to get order book depth", error.status);
481
+ const response = await this.httpClient.get(path, headers);
482
+ if (response.status !== 200 || !response.data) {
483
+ throw new ExternalMatchClientError("Failed to get market depth", response.status);
695
484
  }
485
+ return deserializeMarketDepthResponse(response.data);
696
486
  }
697
487
  /**
698
- * Get a list of supported tokens for external matches
488
+ * Get market depth for all pairs.
699
489
  */
700
- async getSupportedTokens() {
701
- const path = `${SUPPORTED_TOKENS_ROUTE}`;
490
+ async getMarketDepthsAllPairs() {
702
491
  const headers = this.getHeaders();
703
- try {
704
- const response = await this.relayerHttpClient.get(path, headers);
705
- if (response.status !== 200 || !response.data) {
706
- throw new ExternalMatchClientError("Failed to get supported tokens", response.status);
707
- }
708
- return response.data;
709
- }
710
- catch (error) {
711
- throw new ExternalMatchClientError(error.message || "Failed to get supported tokens", error.status);
492
+ const response = await this.httpClient.get(GET_MARKETS_DEPTH_ROUTE, headers);
493
+ if (response.status !== 200 || !response.data) {
494
+ throw new ExternalMatchClientError("Failed to get market depths", response.status);
712
495
  }
496
+ return deserializeMarketDepthsResponse(response.data);
497
+ }
498
+ // --- Deprecated v1 methods (shimmed through v2) ---
499
+ /**
500
+ * @deprecated Use getMarkets() instead
501
+ */
502
+ async getSupportedTokens() {
503
+ const resp = await this.getMarkets();
504
+ return marketsToSupportedTokens(resp);
713
505
  }
714
506
  /**
715
- * Get a list of token prices
507
+ * @deprecated Use getMarkets() instead
716
508
  */
717
509
  async getTokenPrices() {
718
- const path = `${TOKEN_PRICES_ROUTE}`;
719
- const headers = this.getHeaders();
720
- try {
721
- const response = await this.relayerHttpClient.get(path, headers);
722
- if (response.status !== 200 || !response.data) {
723
- throw new ExternalMatchClientError("Failed to get token prices", response.status);
724
- }
725
- return {
726
- ...response.data,
727
- token_prices: response.data.token_prices.map((tokenPrice) => ({
728
- ...tokenPrice,
729
- price: Number.parseFloat(tokenPrice.price.toString()),
730
- })),
731
- };
732
- }
733
- catch (error) {
734
- throw new ExternalMatchClientError(error.message || "Failed to get token prices", error.status);
735
- }
510
+ const resp = await this.getMarkets();
511
+ return marketsToTokenPrices(resp);
512
+ }
513
+ /**
514
+ * @deprecated Use getMarketDepth() instead
515
+ */
516
+ async getOrderBookDepth(mint) {
517
+ const resp = await this.getMarketDepth(mint);
518
+ return marketDepthToV1(resp);
519
+ }
520
+ /**
521
+ * @deprecated Use getMarketDepthsAllPairs() instead
522
+ */
523
+ async getOrderBookDepthAllPairs() {
524
+ const resp = await this.getMarketDepthsAllPairs();
525
+ return marketDepthsToV1(resp);
736
526
  }
737
527
  /**
738
528
  * Get exchange metadata including chain ID, settlement contract address, and supported tokens
739
529
  */
740
530
  async getExchangeMetadata() {
741
- const path = `${EXCHANGE_METADATA_ROUTE}`;
531
+ const path = GET_EXCHANGE_METADATA_ROUTE;
742
532
  const headers = this.getHeaders();
743
533
  const response = await this.httpClient.get(path, headers);
744
534
  return this.handleOptionalResponse(response, ExchangeMetadataResponse.deserialize);
745
535
  }
746
- /**
747
- * Handle an optional HTTP response, returning null for 204, deserializing for 200,
748
- * and throwing an error for other status codes.
749
- *
750
- * @param response The HTTP response
751
- * @param deserialize Function to deserialize the response data
752
- * @returns The deserialized response or null for 204
753
- * @throws ExternalMatchClientError for non-200/204 status codes
754
- */
536
+ // --- Private helpers ---
755
537
  handleOptionalResponse(response, deserialize) {
756
538
  if (response.status === 204) {
757
539
  return null;
@@ -762,24 +544,12 @@ export class ExternalMatchClient {
762
544
  const errorMessage = this.extractErrorMessage(response.data);
763
545
  throw new ExternalMatchClientError(errorMessage, response.status);
764
546
  }
765
- /**
766
- * Extract error message from an error response.
767
- * Per OpenAPI spec, error responses follow the ErrorResponse schema with an "error" field.
768
- *
769
- * @param data The response data (may be ErrorResponse object, string, or other)
770
- * @returns The extracted error message
771
- */
772
547
  extractErrorMessage(data) {
773
548
  if (data && typeof data === "object" && "error" in data && typeof data.error === "string") {
774
549
  return data.error;
775
550
  }
776
551
  return typeof data === "string" ? data : JSON.stringify(data);
777
552
  }
778
- /**
779
- * Get the headers required for API requests.
780
- *
781
- * @returns Headers containing the API key and SDK version
782
- */
783
553
  getHeaders() {
784
554
  return {
785
555
  [RENEGADE_API_KEY_HEADER]: this.apiKey,