@cowprotocol/sdk-bridging 0.2.0-beta.0 → 0.2.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -85,7 +85,7 @@ if (confirm(`You will get at least: ${buyAmount}, ok?`)) {
85
85
  }
86
86
  ```
87
87
 
88
- ### Usage with Umbrella SDK
88
+ ### Usage with CoW SDK
89
89
 
90
90
  ```typescript
91
91
  import {
@@ -132,7 +132,6 @@ const parameters: QuoteBridgeRequest = {
132
132
  appCode: 'YOUR_APP_CODE',
133
133
  }
134
134
 
135
- // Access bridging through the umbrella SDK
136
135
  const quoteResult = await sdk.bridging.getQuote(parameters)
137
136
  assertIsBridgeQuoteAndPost(quoteResult)
138
137
  const { swap, bridge, postSwapOrderFromQuote } = quoteResult
package/dist/index.d.mts CHANGED
@@ -5,6 +5,29 @@ import { QuoterParameters, TraderParameters, TradeOptionalParameters, QuoteAndPo
5
5
  import { AccountAddress, SignerLike, AbstractProviderAdapter } from '@cowprotocol/sdk-common';
6
6
  import { CowShedSdk, CowShedSdkOptions } from '@cowprotocol/sdk-cow-shed';
7
7
 
8
+ declare enum BridgeQuoteErrors {
9
+ NO_INTERMEDIATE_TOKENS = "NO_INTERMEDIATE_TOKENS",
10
+ API_ERROR = "API_ERROR",
11
+ INVALID_API_JSON_RESPONSE = "INVALID_API_JSON_RESPONSE",
12
+ ONLY_SELL_ORDER_SUPPORTED = "ONLY_SELL_ORDER_SUPPORTED",
13
+ TX_BUILD_ERROR = "TX_BUILD_ERROR",
14
+ QUOTE_ERROR = "QUOTE_ERROR",
15
+ NO_ROUTES = "NO_ROUTES",
16
+ INVALID_BRIDGE = "INVALID_BRIDGE"
17
+ }
18
+ declare class BridgeProviderQuoteError extends Error {
19
+ readonly context?: unknown | undefined;
20
+ constructor(message: BridgeQuoteErrors, context?: unknown | undefined);
21
+ }
22
+ declare class BridgeProviderError extends Error {
23
+ readonly context: unknown;
24
+ constructor(message: string, context: unknown);
25
+ }
26
+ declare class BridgeOrderParsingError extends Error {
27
+ readonly context?: unknown | undefined;
28
+ constructor(message: string, context?: unknown | undefined);
29
+ }
30
+
8
31
  interface BridgeProviderInfo {
9
32
  name: string;
10
33
  logoUrl: string;
@@ -327,28 +350,15 @@ interface CrossChainOrder {
327
350
  tradeTxHash: string;
328
351
  explorerUrl?: string;
329
352
  }
330
-
331
- declare enum BridgeQuoteErrors {
332
- NO_INTERMEDIATE_TOKENS = "NO_INTERMEDIATE_TOKENS",
333
- API_ERROR = "API_ERROR",
334
- INVALID_API_JSON_RESPONSE = "INVALID_API_JSON_RESPONSE",
335
- ONLY_SELL_ORDER_SUPPORTED = "ONLY_SELL_ORDER_SUPPORTED",
336
- TX_BUILD_ERROR = "TX_BUILD_ERROR",
337
- QUOTE_ERROR = "QUOTE_ERROR",
338
- NO_ROUTES = "NO_ROUTES",
339
- INVALID_BRIDGE = "INVALID_BRIDGE"
340
- }
341
- declare class BridgeProviderQuoteError extends Error {
342
- readonly context?: unknown | undefined;
343
- constructor(message: BridgeQuoteErrors, context?: unknown | undefined);
344
- }
345
- declare class BridgeProviderError extends Error {
346
- readonly context: unknown;
347
- constructor(message: string, context: unknown);
353
+ interface MultiQuoteResult {
354
+ providerDappId: string;
355
+ quote: CrossChainQuoteAndPost | null;
356
+ error?: BridgeProviderError;
348
357
  }
349
- declare class BridgeOrderParsingError extends Error {
350
- readonly context?: unknown | undefined;
351
- constructor(message: string, context?: unknown | undefined);
358
+ interface MultiQuoteRequest {
359
+ quoteBridgeRequest: QuoteBridgeRequest;
360
+ providerDappIds?: string[];
361
+ advancedSettings?: SwapAdvancedSettings;
352
362
  }
353
363
 
354
364
  declare function isBridgeQuoteAndPost(quote: CrossChainQuoteAndPost): quote is BridgeQuoteAndPost;
@@ -436,9 +446,20 @@ declare class BridgingSdk {
436
446
  * @throws Error if no path is found
437
447
  */
438
448
  getQuote(quoteBridgeRequest: QuoteBridgeRequest, advancedSettings?: SwapAdvancedSettings): Promise<CrossChainQuoteAndPost>;
449
+ /**
450
+ * Get quotes from multiple bridge providers in parallel.
451
+ *
452
+ * This method is specifically for cross-chain bridging quotes. For single-chain swaps, use getQuote() instead.
453
+ *
454
+ * @param request - The multi-quote request containing quote parameters and optional provider dappIds
455
+ * @returns Array of results, one for each provider (successful quotes or errors)
456
+ * @throws Error if the request is for a single-chain swap (sellTokenChainId === buyTokenChainId)
457
+ */
458
+ getMultiQuotes(request: MultiQuoteRequest): Promise<MultiQuoteResult[]>;
439
459
  getOrder(params: GetOrderParams): Promise<CrossChainOrder | null>;
440
460
  getOrderBridgingStatus(bridgingId: string, originChainId: SupportedChainId): Promise<BridgeStatusResult>;
441
461
  getProviderFromAppData(fullAppData: string): BridgeProvider<BridgeQuoteResult> | undefined;
462
+ getProviderByDappId(dappId: string): BridgeProvider<BridgeQuoteResult> | undefined;
442
463
  }
443
464
 
444
465
  declare const RAW_PROVIDERS_FILES_PATH = "https://raw.githubusercontent.com/cowprotocol/cow-sdk/refs/heads/main/src/bridging/providers";
@@ -1011,6 +1032,7 @@ declare class BungeeApi {
1011
1032
  }): Promise<BungeeEvent[]>;
1012
1033
  getAcrossStatus(depositTxHash: string): Promise<AcrossStatus>;
1013
1034
  private getSupportedBridges;
1035
+ private shouldAddAffiliate;
1014
1036
  private makeApiCall;
1015
1037
  }
1016
1038
 
@@ -1047,4 +1069,4 @@ declare class BungeeBridgeProvider implements BridgeProvider<BungeeQuoteResult>
1047
1069
  private isExtraGasRequired;
1048
1070
  }
1049
1071
 
1050
- export { AcrossBridgeProvider, type AcrossBridgeProviderOptions, type AcrossQuoteResult, type BridgeCallDetails, type BridgeCosts, type BridgeDeposit, type BridgeHook, BridgeOrderParsingError, type BridgeProvider, BridgeProviderError, type BridgeProviderInfo, BridgeProviderQuoteError, type BridgeQuoteAmountsAndCosts, type BridgeQuoteAndPost, BridgeQuoteErrors, type BridgeQuoteResult, type BridgeQuoteResults, BridgeStatus, type BridgeStatusResult, type BridgingDepositParams, BridgingSdk, type BridgingSdkConfig, type BridgingSdkOptions, BungeeBridgeProvider, type BungeeBridgeProviderOptions, type BungeeQuoteResult, type BuyTokensParams, COW_SHED_PROXY_CREATION_GAS, type CrossChainOrder, type CrossChainQuoteAndPost, DEFAULT_EXTRA_GAS_FOR_HOOK_ESTIMATION, DEFAULT_EXTRA_GAS_PROXY_CREATION, DEFAULT_GAS_COST_FOR_HOOK_ESTIMATION, type GetOrderParams, type GetProviderBuyTokens, HOOK_DAPP_BRIDGE_PROVIDER_PREFIX, type QuoteBridgeRequest, type QuoteBridgeRequestWithoutAmount, RAW_PROVIDERS_FILES_PATH, assertIsBridgeQuoteAndPost, assertIsQuoteAndPost, getCrossChainOrder, getPostHooks, isAppDoc, isBridgeQuoteAndPost, isQuoteAndPost };
1072
+ export { AcrossBridgeProvider, type AcrossBridgeProviderOptions, type AcrossQuoteResult, type BridgeCallDetails, type BridgeCosts, type BridgeDeposit, type BridgeHook, BridgeOrderParsingError, type BridgeProvider, BridgeProviderError, type BridgeProviderInfo, BridgeProviderQuoteError, type BridgeQuoteAmountsAndCosts, type BridgeQuoteAndPost, BridgeQuoteErrors, type BridgeQuoteResult, type BridgeQuoteResults, BridgeStatus, type BridgeStatusResult, type BridgingDepositParams, BridgingSdk, type BridgingSdkConfig, type BridgingSdkOptions, BungeeBridgeProvider, type BungeeBridgeProviderOptions, type BungeeQuoteResult, type BuyTokensParams, COW_SHED_PROXY_CREATION_GAS, type CrossChainOrder, type CrossChainQuoteAndPost, DEFAULT_EXTRA_GAS_FOR_HOOK_ESTIMATION, DEFAULT_EXTRA_GAS_PROXY_CREATION, DEFAULT_GAS_COST_FOR_HOOK_ESTIMATION, type GetOrderParams, type GetProviderBuyTokens, HOOK_DAPP_BRIDGE_PROVIDER_PREFIX, type MultiQuoteRequest, type MultiQuoteResult, type QuoteBridgeRequest, type QuoteBridgeRequestWithoutAmount, RAW_PROVIDERS_FILES_PATH, assertIsBridgeQuoteAndPost, assertIsQuoteAndPost, getCrossChainOrder, getPostHooks, isAppDoc, isBridgeQuoteAndPost, isQuoteAndPost };
package/dist/index.d.ts CHANGED
@@ -5,6 +5,29 @@ import { QuoterParameters, TraderParameters, TradeOptionalParameters, QuoteAndPo
5
5
  import { AccountAddress, SignerLike, AbstractProviderAdapter } from '@cowprotocol/sdk-common';
6
6
  import { CowShedSdk, CowShedSdkOptions } from '@cowprotocol/sdk-cow-shed';
7
7
 
8
+ declare enum BridgeQuoteErrors {
9
+ NO_INTERMEDIATE_TOKENS = "NO_INTERMEDIATE_TOKENS",
10
+ API_ERROR = "API_ERROR",
11
+ INVALID_API_JSON_RESPONSE = "INVALID_API_JSON_RESPONSE",
12
+ ONLY_SELL_ORDER_SUPPORTED = "ONLY_SELL_ORDER_SUPPORTED",
13
+ TX_BUILD_ERROR = "TX_BUILD_ERROR",
14
+ QUOTE_ERROR = "QUOTE_ERROR",
15
+ NO_ROUTES = "NO_ROUTES",
16
+ INVALID_BRIDGE = "INVALID_BRIDGE"
17
+ }
18
+ declare class BridgeProviderQuoteError extends Error {
19
+ readonly context?: unknown | undefined;
20
+ constructor(message: BridgeQuoteErrors, context?: unknown | undefined);
21
+ }
22
+ declare class BridgeProviderError extends Error {
23
+ readonly context: unknown;
24
+ constructor(message: string, context: unknown);
25
+ }
26
+ declare class BridgeOrderParsingError extends Error {
27
+ readonly context?: unknown | undefined;
28
+ constructor(message: string, context?: unknown | undefined);
29
+ }
30
+
8
31
  interface BridgeProviderInfo {
9
32
  name: string;
10
33
  logoUrl: string;
@@ -327,28 +350,15 @@ interface CrossChainOrder {
327
350
  tradeTxHash: string;
328
351
  explorerUrl?: string;
329
352
  }
330
-
331
- declare enum BridgeQuoteErrors {
332
- NO_INTERMEDIATE_TOKENS = "NO_INTERMEDIATE_TOKENS",
333
- API_ERROR = "API_ERROR",
334
- INVALID_API_JSON_RESPONSE = "INVALID_API_JSON_RESPONSE",
335
- ONLY_SELL_ORDER_SUPPORTED = "ONLY_SELL_ORDER_SUPPORTED",
336
- TX_BUILD_ERROR = "TX_BUILD_ERROR",
337
- QUOTE_ERROR = "QUOTE_ERROR",
338
- NO_ROUTES = "NO_ROUTES",
339
- INVALID_BRIDGE = "INVALID_BRIDGE"
340
- }
341
- declare class BridgeProviderQuoteError extends Error {
342
- readonly context?: unknown | undefined;
343
- constructor(message: BridgeQuoteErrors, context?: unknown | undefined);
344
- }
345
- declare class BridgeProviderError extends Error {
346
- readonly context: unknown;
347
- constructor(message: string, context: unknown);
353
+ interface MultiQuoteResult {
354
+ providerDappId: string;
355
+ quote: CrossChainQuoteAndPost | null;
356
+ error?: BridgeProviderError;
348
357
  }
349
- declare class BridgeOrderParsingError extends Error {
350
- readonly context?: unknown | undefined;
351
- constructor(message: string, context?: unknown | undefined);
358
+ interface MultiQuoteRequest {
359
+ quoteBridgeRequest: QuoteBridgeRequest;
360
+ providerDappIds?: string[];
361
+ advancedSettings?: SwapAdvancedSettings;
352
362
  }
353
363
 
354
364
  declare function isBridgeQuoteAndPost(quote: CrossChainQuoteAndPost): quote is BridgeQuoteAndPost;
@@ -436,9 +446,20 @@ declare class BridgingSdk {
436
446
  * @throws Error if no path is found
437
447
  */
438
448
  getQuote(quoteBridgeRequest: QuoteBridgeRequest, advancedSettings?: SwapAdvancedSettings): Promise<CrossChainQuoteAndPost>;
449
+ /**
450
+ * Get quotes from multiple bridge providers in parallel.
451
+ *
452
+ * This method is specifically for cross-chain bridging quotes. For single-chain swaps, use getQuote() instead.
453
+ *
454
+ * @param request - The multi-quote request containing quote parameters and optional provider dappIds
455
+ * @returns Array of results, one for each provider (successful quotes or errors)
456
+ * @throws Error if the request is for a single-chain swap (sellTokenChainId === buyTokenChainId)
457
+ */
458
+ getMultiQuotes(request: MultiQuoteRequest): Promise<MultiQuoteResult[]>;
439
459
  getOrder(params: GetOrderParams): Promise<CrossChainOrder | null>;
440
460
  getOrderBridgingStatus(bridgingId: string, originChainId: SupportedChainId): Promise<BridgeStatusResult>;
441
461
  getProviderFromAppData(fullAppData: string): BridgeProvider<BridgeQuoteResult> | undefined;
462
+ getProviderByDappId(dappId: string): BridgeProvider<BridgeQuoteResult> | undefined;
442
463
  }
443
464
 
444
465
  declare const RAW_PROVIDERS_FILES_PATH = "https://raw.githubusercontent.com/cowprotocol/cow-sdk/refs/heads/main/src/bridging/providers";
@@ -1011,6 +1032,7 @@ declare class BungeeApi {
1011
1032
  }): Promise<BungeeEvent[]>;
1012
1033
  getAcrossStatus(depositTxHash: string): Promise<AcrossStatus>;
1013
1034
  private getSupportedBridges;
1035
+ private shouldAddAffiliate;
1014
1036
  private makeApiCall;
1015
1037
  }
1016
1038
 
@@ -1047,4 +1069,4 @@ declare class BungeeBridgeProvider implements BridgeProvider<BungeeQuoteResult>
1047
1069
  private isExtraGasRequired;
1048
1070
  }
1049
1071
 
1050
- export { AcrossBridgeProvider, type AcrossBridgeProviderOptions, type AcrossQuoteResult, type BridgeCallDetails, type BridgeCosts, type BridgeDeposit, type BridgeHook, BridgeOrderParsingError, type BridgeProvider, BridgeProviderError, type BridgeProviderInfo, BridgeProviderQuoteError, type BridgeQuoteAmountsAndCosts, type BridgeQuoteAndPost, BridgeQuoteErrors, type BridgeQuoteResult, type BridgeQuoteResults, BridgeStatus, type BridgeStatusResult, type BridgingDepositParams, BridgingSdk, type BridgingSdkConfig, type BridgingSdkOptions, BungeeBridgeProvider, type BungeeBridgeProviderOptions, type BungeeQuoteResult, type BuyTokensParams, COW_SHED_PROXY_CREATION_GAS, type CrossChainOrder, type CrossChainQuoteAndPost, DEFAULT_EXTRA_GAS_FOR_HOOK_ESTIMATION, DEFAULT_EXTRA_GAS_PROXY_CREATION, DEFAULT_GAS_COST_FOR_HOOK_ESTIMATION, type GetOrderParams, type GetProviderBuyTokens, HOOK_DAPP_BRIDGE_PROVIDER_PREFIX, type QuoteBridgeRequest, type QuoteBridgeRequestWithoutAmount, RAW_PROVIDERS_FILES_PATH, assertIsBridgeQuoteAndPost, assertIsQuoteAndPost, getCrossChainOrder, getPostHooks, isAppDoc, isBridgeQuoteAndPost, isQuoteAndPost };
1072
+ export { AcrossBridgeProvider, type AcrossBridgeProviderOptions, type AcrossQuoteResult, type BridgeCallDetails, type BridgeCosts, type BridgeDeposit, type BridgeHook, BridgeOrderParsingError, type BridgeProvider, BridgeProviderError, type BridgeProviderInfo, BridgeProviderQuoteError, type BridgeQuoteAmountsAndCosts, type BridgeQuoteAndPost, BridgeQuoteErrors, type BridgeQuoteResult, type BridgeQuoteResults, BridgeStatus, type BridgeStatusResult, type BridgingDepositParams, BridgingSdk, type BridgingSdkConfig, type BridgingSdkOptions, BungeeBridgeProvider, type BungeeBridgeProviderOptions, type BungeeQuoteResult, type BuyTokensParams, COW_SHED_PROXY_CREATION_GAS, type CrossChainOrder, type CrossChainQuoteAndPost, DEFAULT_EXTRA_GAS_FOR_HOOK_ESTIMATION, DEFAULT_EXTRA_GAS_PROXY_CREATION, DEFAULT_GAS_COST_FOR_HOOK_ESTIMATION, type GetOrderParams, type GetProviderBuyTokens, HOOK_DAPP_BRIDGE_PROVIDER_PREFIX, type MultiQuoteRequest, type MultiQuoteResult, type QuoteBridgeRequest, type QuoteBridgeRequestWithoutAmount, RAW_PROVIDERS_FILES_PATH, assertIsBridgeQuoteAndPost, assertIsQuoteAndPost, getCrossChainOrder, getPostHooks, isAppDoc, isBridgeQuoteAndPost, isQuoteAndPost };
package/dist/index.js CHANGED
@@ -478,8 +478,8 @@ var BridgingSdk = class {
478
478
  (0, import_sdk_common4.setGlobalAdapter)(adapter);
479
479
  }
480
480
  const { providers, ...restOptions } = options;
481
- if (!providers || providers.length !== 1) {
482
- throw new Error("Current implementation only supports a single bridge provider");
481
+ if (!providers || providers.length === 0) {
482
+ throw new Error("At least one bridge provider is required");
483
483
  }
484
484
  if (options.enableLogging !== void 0) {
485
485
  (0, import_sdk_common4.enableLogging)(options.enableLogging);
@@ -561,6 +561,58 @@ var BridgingSdk = class {
561
561
  });
562
562
  }
563
563
  }
564
+ /**
565
+ * Get quotes from multiple bridge providers in parallel.
566
+ *
567
+ * This method is specifically for cross-chain bridging quotes. For single-chain swaps, use getQuote() instead.
568
+ *
569
+ * @param request - The multi-quote request containing quote parameters and optional provider dappIds
570
+ * @returns Array of results, one for each provider (successful quotes or errors)
571
+ * @throws Error if the request is for a single-chain swap (sellTokenChainId === buyTokenChainId)
572
+ */
573
+ async getMultiQuotes(request) {
574
+ const { quoteBridgeRequest, providerDappIds, advancedSettings } = request;
575
+ const { sellTokenChainId, buyTokenChainId } = quoteBridgeRequest;
576
+ if (sellTokenChainId === buyTokenChainId) {
577
+ throw new BridgeProviderError(
578
+ "getMultiQuotes() is only for cross-chain bridging. For single-chain swaps, use getQuote() instead.",
579
+ { config: this.config }
580
+ );
581
+ }
582
+ const providersToQuery = providerDappIds ? providerDappIds.map((dappId) => {
583
+ const provider = this.getProviderByDappId(dappId);
584
+ if (!provider) {
585
+ throw new BridgeProviderError(
586
+ `Provider with dappId '${dappId}' not found. Available providers: ${this.config.providers.map((p) => p.info.dappId).join(", ")}`,
587
+ { config: this.config }
588
+ );
589
+ }
590
+ return provider;
591
+ }) : this.config.providers;
592
+ const quotePromises = providersToQuery.map(async (provider) => {
593
+ try {
594
+ const quote = await getQuoteWithBridge({
595
+ swapAndBridgeRequest: quoteBridgeRequest,
596
+ advancedSettings,
597
+ tradingSdk: this.config.tradingSdk,
598
+ provider,
599
+ bridgeHookSigner: advancedSettings?.quoteSigner
600
+ });
601
+ return {
602
+ providerDappId: provider.info.dappId,
603
+ quote,
604
+ error: void 0
605
+ };
606
+ } catch (error) {
607
+ return {
608
+ providerDappId: provider.info.dappId,
609
+ quote: null,
610
+ error: error instanceof BridgeProviderError ? error : new BridgeProviderError(String(error), {})
611
+ };
612
+ }
613
+ });
614
+ return Promise.all(quotePromises);
615
+ }
564
616
  async getOrder(params) {
565
617
  const { orderBookApi } = this.config;
566
618
  const { chainId, orderId, env = orderBookApi.context.env } = params;
@@ -578,6 +630,9 @@ var BridgingSdk = class {
578
630
  getProviderFromAppData(fullAppData) {
579
631
  return findBridgeProviderFromHook(fullAppData, this.getProviders());
580
632
  }
633
+ getProviderByDappId(dappId) {
634
+ return this.config.providers.find((provider) => provider.info.dappId === dappId);
635
+ }
581
636
  };
582
637
 
583
638
  // src/providers/across/AcrossApi.ts
@@ -3203,7 +3258,7 @@ var SocketVerifierAddresses = {
3203
3258
  [import_sdk_config6.SupportedChainId.SEPOLIA]: void 0,
3204
3259
  [import_sdk_config6.AdditionalTargetChainId.OPTIMISM]: SOCKET_VERIFIER_ADDRESS
3205
3260
  };
3206
- var BUNGEE_APPROVE_AND_BRIDGE_V1_ADDRESS = "0x936fa1cfd96849329B18b915773E176718A64b95";
3261
+ var BUNGEE_APPROVE_AND_BRIDGE_V1_ADDRESS = "0xD06a673fe1fa27B1b9E5BA0be980AB15Dbce85cc";
3207
3262
  var BungeeApproveAndBridgeV1Addresses = {
3208
3263
  [import_sdk_config6.SupportedChainId.MAINNET]: BUNGEE_APPROVE_AND_BRIDGE_V1_ADDRESS,
3209
3264
  [import_sdk_config6.SupportedChainId.GNOSIS_CHAIN]: BUNGEE_APPROVE_AND_BRIDGE_V1_ADDRESS,
@@ -3680,6 +3735,10 @@ var BungeeApi = class {
3680
3735
  getSupportedBridges(bridges) {
3681
3736
  return bridges ?? this.options.includeBridges ?? SUPPORTED_BRIDGES;
3682
3737
  }
3738
+ shouldAddAffiliate(apiType, baseUrl) {
3739
+ const isBungeeApi = apiType === "bungee" || apiType === "bungee-manual";
3740
+ return !baseUrl.includes(BUNGEE_BASE_URL) && isBungeeApi;
3741
+ }
3683
3742
  async makeApiCall(apiType, path, params, isValidResponse) {
3684
3743
  const baseUrlMap = {
3685
3744
  bungee: this.options.apiBaseUrl || BUNGEE_API_URL,
@@ -3690,7 +3749,7 @@ var BungeeApi = class {
3690
3749
  const baseUrl = baseUrlMap[apiType];
3691
3750
  const url = `${baseUrl}${path}?${new URLSearchParams(params).toString()}`;
3692
3751
  const headers = {};
3693
- if (this.options.affiliate && !baseUrl.includes(BUNGEE_BASE_URL)) {
3752
+ if (this.shouldAddAffiliate(apiType, baseUrl) && this.options.affiliate) {
3694
3753
  headers["affiliate"] = this.options.affiliate;
3695
3754
  }
3696
3755
  (0, import_sdk_common12.log)(`Fetching ${apiType} API: GET ${url}. Params: ${JSON.stringify(params)}`);
@@ -3832,7 +3891,7 @@ async function createBungeeDepositCall(params) {
3832
3891
 
3833
3892
  // src/providers/bungee/getBridgingStatusFromEvents.ts
3834
3893
  async function getBridgingStatusFromEvents(events, getAcrossStatus) {
3835
- if (!events?.length) {
3894
+ if (!events?.length || !events?.[0]) {
3836
3895
  return { status: "unknown" /* UNKNOWN */ };
3837
3896
  }
3838
3897
  const event = events[0];
package/dist/index.mjs CHANGED
@@ -436,8 +436,8 @@ var BridgingSdk = class {
436
436
  setGlobalAdapter(adapter);
437
437
  }
438
438
  const { providers, ...restOptions } = options;
439
- if (!providers || providers.length !== 1) {
440
- throw new Error("Current implementation only supports a single bridge provider");
439
+ if (!providers || providers.length === 0) {
440
+ throw new Error("At least one bridge provider is required");
441
441
  }
442
442
  if (options.enableLogging !== void 0) {
443
443
  enableLogging(options.enableLogging);
@@ -519,6 +519,58 @@ var BridgingSdk = class {
519
519
  });
520
520
  }
521
521
  }
522
+ /**
523
+ * Get quotes from multiple bridge providers in parallel.
524
+ *
525
+ * This method is specifically for cross-chain bridging quotes. For single-chain swaps, use getQuote() instead.
526
+ *
527
+ * @param request - The multi-quote request containing quote parameters and optional provider dappIds
528
+ * @returns Array of results, one for each provider (successful quotes or errors)
529
+ * @throws Error if the request is for a single-chain swap (sellTokenChainId === buyTokenChainId)
530
+ */
531
+ async getMultiQuotes(request) {
532
+ const { quoteBridgeRequest, providerDappIds, advancedSettings } = request;
533
+ const { sellTokenChainId, buyTokenChainId } = quoteBridgeRequest;
534
+ if (sellTokenChainId === buyTokenChainId) {
535
+ throw new BridgeProviderError(
536
+ "getMultiQuotes() is only for cross-chain bridging. For single-chain swaps, use getQuote() instead.",
537
+ { config: this.config }
538
+ );
539
+ }
540
+ const providersToQuery = providerDappIds ? providerDappIds.map((dappId) => {
541
+ const provider = this.getProviderByDappId(dappId);
542
+ if (!provider) {
543
+ throw new BridgeProviderError(
544
+ `Provider with dappId '${dappId}' not found. Available providers: ${this.config.providers.map((p) => p.info.dappId).join(", ")}`,
545
+ { config: this.config }
546
+ );
547
+ }
548
+ return provider;
549
+ }) : this.config.providers;
550
+ const quotePromises = providersToQuery.map(async (provider) => {
551
+ try {
552
+ const quote = await getQuoteWithBridge({
553
+ swapAndBridgeRequest: quoteBridgeRequest,
554
+ advancedSettings,
555
+ tradingSdk: this.config.tradingSdk,
556
+ provider,
557
+ bridgeHookSigner: advancedSettings?.quoteSigner
558
+ });
559
+ return {
560
+ providerDappId: provider.info.dappId,
561
+ quote,
562
+ error: void 0
563
+ };
564
+ } catch (error) {
565
+ return {
566
+ providerDappId: provider.info.dappId,
567
+ quote: null,
568
+ error: error instanceof BridgeProviderError ? error : new BridgeProviderError(String(error), {})
569
+ };
570
+ }
571
+ });
572
+ return Promise.all(quotePromises);
573
+ }
522
574
  async getOrder(params) {
523
575
  const { orderBookApi } = this.config;
524
576
  const { chainId, orderId, env = orderBookApi.context.env } = params;
@@ -536,6 +588,9 @@ var BridgingSdk = class {
536
588
  getProviderFromAppData(fullAppData) {
537
589
  return findBridgeProviderFromHook(fullAppData, this.getProviders());
538
590
  }
591
+ getProviderByDappId(dappId) {
592
+ return this.config.providers.find((provider) => provider.info.dappId === dappId);
593
+ }
539
594
  };
540
595
 
541
596
  // src/providers/across/AcrossApi.ts
@@ -3167,7 +3222,7 @@ var SocketVerifierAddresses = {
3167
3222
  [SupportedChainId5.SEPOLIA]: void 0,
3168
3223
  [AdditionalTargetChainId2.OPTIMISM]: SOCKET_VERIFIER_ADDRESS
3169
3224
  };
3170
- var BUNGEE_APPROVE_AND_BRIDGE_V1_ADDRESS = "0x936fa1cfd96849329B18b915773E176718A64b95";
3225
+ var BUNGEE_APPROVE_AND_BRIDGE_V1_ADDRESS = "0xD06a673fe1fa27B1b9E5BA0be980AB15Dbce85cc";
3171
3226
  var BungeeApproveAndBridgeV1Addresses = {
3172
3227
  [SupportedChainId5.MAINNET]: BUNGEE_APPROVE_AND_BRIDGE_V1_ADDRESS,
3173
3228
  [SupportedChainId5.GNOSIS_CHAIN]: BUNGEE_APPROVE_AND_BRIDGE_V1_ADDRESS,
@@ -3644,6 +3699,10 @@ var BungeeApi = class {
3644
3699
  getSupportedBridges(bridges) {
3645
3700
  return bridges ?? this.options.includeBridges ?? SUPPORTED_BRIDGES;
3646
3701
  }
3702
+ shouldAddAffiliate(apiType, baseUrl) {
3703
+ const isBungeeApi = apiType === "bungee" || apiType === "bungee-manual";
3704
+ return !baseUrl.includes(BUNGEE_BASE_URL) && isBungeeApi;
3705
+ }
3647
3706
  async makeApiCall(apiType, path, params, isValidResponse) {
3648
3707
  const baseUrlMap = {
3649
3708
  bungee: this.options.apiBaseUrl || BUNGEE_API_URL,
@@ -3654,7 +3713,7 @@ var BungeeApi = class {
3654
3713
  const baseUrl = baseUrlMap[apiType];
3655
3714
  const url = `${baseUrl}${path}?${new URLSearchParams(params).toString()}`;
3656
3715
  const headers = {};
3657
- if (this.options.affiliate && !baseUrl.includes(BUNGEE_BASE_URL)) {
3716
+ if (this.shouldAddAffiliate(apiType, baseUrl) && this.options.affiliate) {
3658
3717
  headers["affiliate"] = this.options.affiliate;
3659
3718
  }
3660
3719
  log5(`Fetching ${apiType} API: GET ${url}. Params: ${JSON.stringify(params)}`);
@@ -3796,7 +3855,7 @@ async function createBungeeDepositCall(params) {
3796
3855
 
3797
3856
  // src/providers/bungee/getBridgingStatusFromEvents.ts
3798
3857
  async function getBridgingStatusFromEvents(events, getAcrossStatus) {
3799
- if (!events?.length) {
3858
+ if (!events?.length || !events?.[0]) {
3800
3859
  return { status: "unknown" /* UNKNOWN */ };
3801
3860
  }
3802
3861
  const event = events[0];
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@cowprotocol/sdk-bridging",
3
- "version": "0.2.0-beta.0",
3
+ "version": "0.2.0",
4
4
  "description": "Bridging for CoW Protocol",
5
5
  "main": "./dist/index.js",
6
6
  "module": "./dist/index.mjs",
@@ -13,33 +13,17 @@
13
13
  "publishConfig": {
14
14
  "access": "public"
15
15
  },
16
- "scripts": {
17
- "build": "tsup src/index.ts --format esm,cjs --dts",
18
- "lint": "eslint src/**/*.ts",
19
- "clean": "rm -rf .turbo && rm -rf node_modules && rm -rf dist",
20
- "test": "jest",
21
- "test:coverage": "jest --coverage --json --outputFile=jest.results.json && npx coveralls < ./coverage/lcov.info",
22
- "test:coverage:html": "jest --silent=false --coverage --coverageReporters html",
23
- "test:bungeeGnosisBridge": "yarn test --testPathPattern=BungeeGnosisBridge",
24
- "typecheck": "tsc --noEmit",
25
- "prepublishOnly": "npm run build"
26
- },
27
16
  "dependencies": {
28
- "@cowprotocol/sdk-app-data": "workspace:*",
29
- "@cowprotocol/sdk-common": "workspace:*",
30
- "@cowprotocol/sdk-config": "workspace:*",
31
- "@cowprotocol/sdk-contracts-ts": "workspace:*",
32
- "@cowprotocol/sdk-cow-shed": "workspace:*",
33
- "@cowprotocol/sdk-order-book": "workspace:*",
34
- "@cowprotocol/sdk-trading": "workspace:*",
35
- "@cowprotocol/sdk-weiroll": "workspace:*"
17
+ "@cowprotocol/sdk-app-data": "4.0.0",
18
+ "@cowprotocol/sdk-config": "0.1.0",
19
+ "@cowprotocol/sdk-cow-shed": "0.1.1",
20
+ "@cowprotocol/sdk-contracts-ts": "0.1.1",
21
+ "@cowprotocol/sdk-order-book": "0.1.0",
22
+ "@cowprotocol/sdk-trading": "0.1.1",
23
+ "@cowprotocol/sdk-common": "0.1.0",
24
+ "@cowprotocol/sdk-weiroll": "0.1.0"
36
25
  },
37
26
  "devDependencies": {
38
- "@cowprotocol/sdk-order-signing": "workspace:*",
39
- "@cow-sdk/typescript-config": "workspace:*",
40
- "@cowprotocol/sdk-ethers-v5-adapter": "workspace:*",
41
- "@cowprotocol/sdk-ethers-v6-adapter": "workspace:*",
42
- "@cowprotocol/sdk-viem-adapter": "workspace:*",
43
27
  "ethers-v5": "npm:ethers@^5.7.2",
44
28
  "ethers-v6": "npm:ethers@^6.13.7",
45
29
  "@types/jest": "^29.4.0",
@@ -51,6 +35,21 @@
51
35
  "jest-fetch-mock": "^3.0.3",
52
36
  "ts-jest": "^29.0.0",
53
37
  "ethers": "^5.7.2",
54
- "viem": "^2.28.4"
38
+ "viem": "^2.28.4",
39
+ "@cow-sdk/typescript-config": "0.0.0-beta.0",
40
+ "@cowprotocol/sdk-order-signing": "0.1.1",
41
+ "@cowprotocol/sdk-ethers-v6-adapter": "0.1.0",
42
+ "@cowprotocol/sdk-viem-adapter": "0.1.0",
43
+ "@cowprotocol/sdk-ethers-v5-adapter": "0.1.0"
44
+ },
45
+ "scripts": {
46
+ "build": "tsup src/index.ts --format esm,cjs --dts",
47
+ "lint": "eslint src/**/*.ts",
48
+ "clean": "rm -rf .turbo && rm -rf node_modules && rm -rf dist",
49
+ "test": "jest",
50
+ "test:coverage": "jest --coverage --json --outputFile=jest.results.json && npx coveralls < ./coverage/lcov.info",
51
+ "test:coverage:html": "jest --silent=false --coverage --coverageReporters html",
52
+ "test:bungeeGnosisBridge": "yarn test --testPathPattern=BungeeGnosisBridge",
53
+ "typecheck": "tsc --noEmit"
55
54
  }
56
- }
55
+ }