Skip to content

feat(bridging): add bridge-then-swap provider abstraction and Bungee implementation - #845

Draft
anxolin wants to merge 1 commit into
mainfrom
feat/bridge-then-swap
Draft

feat(bridging): add bridge-then-swap provider abstraction and Bungee implementation#845
anxolin wants to merge 1 commit into
mainfrom
feat/bridge-then-swap

Conversation

@anxolin

@anxolin anxolin commented Mar 24, 2026

Copy link
Copy Markdown
Contributor

Summary

Extends the bridging package to support the bridge-then-swap flow — the reverse of the existing swap-then-bridge pattern. Users bridge tokens from a source chain to a destination chain, where an OrderFlowFactory contract automatically creates a CoW Protocol order to swap the bridged tokens into the desired token.

  • Adds BridgeThenSwapProvider as a third provider type alongside HookBridgeProvider and ReceiverAccountBridgeProvider
  • Implements BungeeBridgeThenSwapProvider using Bungee's destination zaps (destination execution) to deliver calldata to OrderFlowFactory on the destination chain
  • Adds getQuoteWithBridgeThenSwap orchestration: intermediate token selection -> bridge quote -> destination swap quote -> CREATE2 address computation -> order encoding -> bridge transaction building
  • OrderFlowFactory addresses and OrderFlow init code hash are configurable per-chain via provider options

New files

File Purpose
getQuoteWithBridgeThenSwap.ts 8-step quote orchestration for the reversed flow
BungeeBridgeThenSwapProvider.ts Bungee implementation of BridgeThenSwapProvider
bridgeThenSwap/orderFlowAbi.ts OrderFlowFactory + OrderFlowOrder.Data ABI
bridgeThenSwap/encodeOrderData.ts ABI encoding of order data for destination payload
bridgeThenSwap/computeOrderFlowAddress.ts CREATE2 address computation

Modified files

File Change
types.ts New interfaces: BridgeThenSwapProvider, BridgeThenSwapQuoteAndPost, DestinationOrderParams, BridgeThenSwapTransaction
utils.ts Type guards: isBridgeThenSwapProvider, isBridgeThenSwapQuoteAndPost
getQuoteWithBridge.ts Dispatch for BridgeThenSwapProvider
bungee/types.ts destinationPayload and destinationGasLimit on BungeeQuoteAPIRequest
index.ts Exports for new provider

Test plan

1. Build the bridging package

cd packages/bridging
pnpm build

CJS and ESM should build successfully. DTS has pre-existing errors unrelated to this change (AddressPerChain not found).

2. Run existing tests (regression)

pnpm --filter @cowprotocol/sdk-bridging test

Existing tests should pass -- the new provider type does not affect existing Hook/ReceiverAccount provider flows.

3. Type-check new code

cd packages/bridging
npx tsc --noEmit 2>&1 | grep -E "BridgeThenSwap|getQuoteWithBridgeThenSwap"

Should only show the pre-existing getCorrelatedTokens error (same as getIntermediateSwapResult.ts:71).

4. Verify new provider instantiation

import { BungeeBridgeThenSwapProvider, BridgingSdk, SupportedChainId } from '@cowprotocol/sdk-bridging'

const provider = new BungeeBridgeThenSwapProvider({
  orderFlowFactoryAddresses: {
    [SupportedChainId.ARBITRUM_ONE]: '0x...deployed_factory_address',
  },
  orderFlowInitCodeHash: '0x...init_code_hash',
})

const sdk = new BridgingSdk({ providers: [provider] })

Should instantiate without errors.

5. Verify type guards

import { isBridgeThenSwapProvider, isBridgeThenSwapQuoteAndPost } from '@cowprotocol/sdk-bridging'

// provider.type === 'BridgeThenSwapProvider' should return true
console.log(isBridgeThenSwapProvider(provider)) // true

6. E2E quote flow (requires deployed contracts + Bungee API access)

const quote = await sdk.getQuote({
  kind: OrderKind.SELL,
  amount: 1000000n, // 1 USDC
  sellTokenChainId: SupportedChainId.BASE,
  sellTokenAddress: '0x...usdc_on_base',
  sellTokenDecimals: 6,
  buyTokenChainId: SupportedChainId.ARBITRUM_ONE,
  buyTokenAddress: '0x...arb_token',
  buyTokenDecimals: 18,
  signer: userSigner,
  owner: userAddress,
})

if (isBridgeThenSwapQuoteAndPost(quote)) {
  console.log('Bridge tx:', quote.bridgeTransaction)
  console.log('OrderFlow address:', quote.orderFlowAddress)
  console.log('Destination swap estimate:', quote.destinationSwap)
  // Submit: await quote.submitBridgeTransaction(signer)
}

Summary by CodeRabbit

  • New Features

    • Added bridge-then-swap functionality enabling users to bridge assets and swap them on the destination chain in a single flow.
    • Introduced Bungee provider support for bridge-then-swap operations with automated intermediate token selection.
    • Extended bridging SDK with destination-chain swap execution and order flow management capabilities.
  • Tests

    • Updated test fixtures with explicit type definitions.

…implementation

Extend the bridging package to support the reverse cross-chain flow:
bridge tokens from a source chain first, then automatically create a
CoW Protocol order on the destination chain via OrderFlowFactory.

- Add BridgeThenSwapProvider interface as a third provider type
- Add BridgeThenSwapQuoteAndPost result type with bridge tx + destination swap estimate
- Implement getQuoteWithBridgeThenSwap orchestration (8-step flow)
- Implement BungeeBridgeThenSwapProvider using Bungee destination zaps
- Add CREATE2 address computation and order data ABI encoding utilities
- Wire dispatch in getQuoteWithBridge for the new provider type
@coderabbitai

coderabbitai Bot commented Mar 24, 2026

Copy link
Copy Markdown
Contributor
📝 Walkthrough

Walkthrough

The PR introduces a bridge-then-swap flow to the bridging SDK, enabling sequential cross-chain bridge and swap operations. It adds a new getQuoteWithBridgeThenSwap function, a BungeeBridgeThenSwapProvider implementation with supporting utilities for OrderFlow address computation and destination order encoding, and updates core routing and type definitions.

Changes

Cohort / File(s) Summary
Core SDK Routing & New Flow Handler
getQuoteWithBridge.ts, getQuoteWithBridge.test.ts
Updated getQuoteWithBridge to route BridgeThenSwapProvider requests to getQuoteWithBridgeThenSwap; return type expanded to Promise<BridgeQuoteAndPost | BridgeThenSwapQuoteAndPost>. Test helper updated with explicit type casting.
Bridge-Then-Swap Implementation
BridgingSdk/getQuoteWithBridgeThenSwap.ts, BridgingSdk/types.ts
New getQuoteWithBridgeThenSwap function orchestrating sequential quote building: bridge quote retrieval, intermediate token selection, destination-chain swap quote, OrderFlow address computation, destination order encoding, and gas estimation. New GetQuoteWithBridgeThenSwapParams type defined.
BungeeBridgeThenSwap Provider
providers/bungee/BungeeBridgeThenSwapProvider.ts
New provider implementing bridge-then-swap flow with quote building, Bungee API integration, destination payload construction, gas estimation, and bridging state management via event retrieval.
OrderFlow Utilities
providers/bungee/bridgeThenSwap/computeOrderFlowAddress.ts, providers/bungee/bridgeThenSwap/encodeOrderData.ts, providers/bungee/bridgeThenSwap/orderFlowAbi.ts
New utilities for computing deterministic OrderFlow contract addresses via CREATE2, ABI-encoding destination order data, and defining OrderFlowFactory contract interface.
Type System & Exports
types.ts, utils.ts, index.ts, providers/bungee/types.ts
Extended BridgeProviderType to include 'BridgeThenSwapProvider'; added BridgeThenSwapProvider<Q>, BridgeThenSwapQuoteAndPost, and DestinationOrderParams interfaces; updated union types for cross-chain quotes; added type guards (isBridgeThenSwapProvider, isBridgeThenSwapQuoteAndPost); re-exported new provider and types from public SDK entrypoint; extended Bungee API request with destination payload and gas limit fields.

Sequence Diagram

sequenceDiagram
    participant SDK as BridgingSdk
    participant Provider as BungeeBridgeThenSwapProvider
    participant Bridge as Bridge Service
    participant TradingSdk as TradingSdk
    participant DestChain as Destination Chain

    SDK->>Provider: getQuoteWithBridgeThenSwap(params)
    Provider->>Provider: Validate order type & owner
    Provider->>Provider: determineIntermediateToken()
    Provider->>Bridge: Request bridge quote<br/>(sell token → intermediate)
    Bridge-->>Provider: Bridge quote + buyAmount
    Provider->>TradingSdk: getQuoteResults<br/>(intermediate → buy token)
    TradingSdk-->>Provider: Destination swap quote
    Provider->>Provider: computeOrderFlowAddress(owner)
    Provider->>Provider: encodeOrderData(destination order)
    Provider->>DestChain: getDestinationGasLimit(order)
    DestChain-->>Provider: Gas estimate + buffer
    Provider->>Bridge: getBridgeTransaction<br/>(bridge quote, destination payload)
    Bridge-->>Provider: Built transaction (bridge + execution)
    Provider-->>SDK: BridgeThenSwapQuoteAndPost<br/>(bridge quote, destination swap,<br/>transaction, submitHelper)
Loading

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~60 minutes

Possibly related PRs

Suggested reviewers

  • alfetopito
  • limitofzero

Poem

🐰 A bridge so grand, a swap so swift,
Cross chains we hop with careful gift,
OrderFlow addresses computed with care,
Destination payloads floating through air,
Bridge-then-swap, a quantum pair! ✨🌉

🚥 Pre-merge checks | ✅ 2 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 18.75% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (2 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title accurately and specifically describes the main change: adding a new bridge-then-swap provider abstraction with a Bungee implementation, which aligns with the core feature additions across the changeset.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch feat/bridge-then-swap

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

@github-actions

Copy link
Copy Markdown
Contributor

📦 GitHub Packages Published

Last updated: Mar 24, 2026, 03:42:52 PM UTC

The following packages have been published to GitHub Packages with pre-release version pr-845-674c4201:

  • @cowprotocol/cow-sdk@8.0.4-pr-845-674c4201.0
  • @cowprotocol/sdk-app-data@4.6.12-pr-845-674c4201.0
  • @cowprotocol/sdk-bridging@3.2.0-pr-845-674c4201.0
  • @cowprotocol/sdk-common@0.8.2-pr-845-674c4201.0
  • @cowprotocol/sdk-composable@0.2.3-pr-845-674c4201.0
  • @cowprotocol/sdk-config@1.1.2-pr-845-674c4201.0
  • @cowprotocol/sdk-contracts-ts@2.2.0-pr-845-674c4201.0
  • @cowprotocol/sdk-cow-shed@0.3.3-pr-845-674c4201.0
  • @cowprotocol/sdk-ethers-v5-adapter@0.4.0-pr-845-674c4201.0
  • @cowprotocol/sdk-ethers-v6-adapter@0.4.0-pr-845-674c4201.0
  • @cowprotocol/sdk-flash-loans@2.0.4-pr-845-674c4201.0
  • @cowprotocol/sdk-order-book@2.0.3-pr-845-674c4201.0
  • @cowprotocol/sdk-order-signing@0.2.3-pr-845-674c4201.0
  • @cowprotocol/sdk-subgraph@1.0.3-pr-845-674c4201.0
  • @cowprotocol/sdk-trading@1.2.0-pr-845-674c4201.0
  • @cowprotocol/sdk-viem-adapter@0.3.14-pr-845-674c4201.0
  • @cowprotocol/sdk-weiroll@0.1.26-pr-845-674c4201.0

Installation

These packages require authentication to install from GitHub Packages. First, create a .npmrc file:

# Create .npmrc file in your project root
echo "@cowprotocol:registry=https://npm.pkg.github.com" > .npmrc
echo "//npm.pkg.github.com/:_authToken=YOUR_GITHUB_TOKEN" >> .npmrc

To get your GitHub token:

  1. Go to https://github.com/settings/tokens
  2. Click "Generate new token (classic)"
  3. Check only the "read:packages" scope
  4. Copy the token and replace YOUR_GITHUB_TOKEN in the .npmrc file

Then install any of the packages above, either by exact version (i.e. @cowprotocol/cow-sdk@8.0.4-pr-845-674c4201.0) or more conveniently by using the tag (@cowprotocol/cow-sdk@pr-845):

# Yarn
yarn add npm:@cowprotocol/cow-sdk@pr-845

# pnpm
pnpm install npm:@cowprotocol/cow-sdk@pr-845

# NPM
npm install npm:@cowprotocol/cow-sdk@pr-845

Update to the latest version (only if you used the tag)

Every commit will publish a new package. To upgrade to the latest version, run:

# Yarn
yarn upgrade @cowprotocol/cow-sdk

# pnpm
pnpm update @cowprotocol/cow-sdk

# NPM
npm update @cowprotocol/cow-sdk

View Packages

You can view the published packages at: https://github.com/cowprotocol/cow-sdk/packages

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 4

🧹 Nitpick comments (1)
packages/bridging/src/BridgingSdk/getQuoteWithBridgeThenSwap.ts (1)

129-131: Consider making the validity window configurable.

The hardcoded 1-hour validity (validTo) might be insufficient for slower bridges combined with order settlement time. Consider accepting this as a configurable parameter through advancedSettings or provider options.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@packages/bridging/src/BridgingSdk/getQuoteWithBridgeThenSwap.ts` around lines
129 - 131, The hardcoded 1-hour validity window set via the validTo calculation
in getQuoteWithBridgeThenSwap should be made configurable; add an optional
parameter (e.g., advancedSettings.validityWindowSeconds or
providerOptions.validToSeconds) and use it to compute validTo with a sensible
default of 3600 if unset, update call sites and any types/interfaces for
getQuoteWithBridgeThenSwap and related provider functions to accept and
propagate this option, and ensure unit tests or consumers still default to
current behavior when the option is omitted.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@packages/bridging/src/BridgingSdk/getQuoteWithBridge.ts`:
- Line 19: Remove the unused type import BridgeThenSwapProvider from the import
list (it's causing the ESLint error) while keeping the runtime type guard
isBridgeThenSwapProvider intact; locate the import that currently includes
BridgeThenSwapProvider and delete that symbol from the import clause so only
used symbols remain, then run lint to verify the ESLint error is resolved.

In `@packages/bridging/src/BridgingSdk/getQuoteWithBridgeThenSwap.ts`:
- Around line 180-186: The buyTokenInfo object incorrectly assigns name and
symbol from destinationSwapResult.swapResult.tradeParameters.buyToken (which is
the token address); update the construction of buyTokenInfo so name and symbol
come from actual token metadata (e.g., use provided request metadata fields if
available, or fetch token details from a registry/service using buyTokenAddress
and buyTokenChainId), and if metadata is not available set name and symbol to
undefined/null or a safe placeholder; locate this change around the buyTokenInfo
variable and references to buyTokenAddress and
destinationSwapResult.swapResult.tradeParameters.buyToken.

In `@packages/bridging/src/providers/bungee/BungeeBridgeThenSwapProvider.ts`:
- Around line 193-212: getBridgeTransaction and the earlier getQuote do not pass
or use destinationPayload/destinationGasLimit, so the destination execution data
is never sent to Bungee; update the bungeeQuoteRequest construction in getQuote
to include destinationPayload and destinationGasLimit (ensure the keys match
Bungee API expectations) or re-request buildTx with those params so the returned
BungeeBridgeThenSwapQuoteResult.buildTx contains the destination execution data,
then modify getBridgeTransaction to return buildTx.txData (or the newly fetched
buildTx) that includes the destination payload and gas limit so the returned
BridgeThenSwapTransaction to/from values carry the destination execution info.

In `@packages/bridging/src/types.ts`:
- Around line 471-478: The types for quoteId are inconsistent between
destinationSwap (quoteId?: string) and DestinationOrderParams (quoteId?:
number); update one so both use the same type across the module — e.g., change
DestinationOrderParams.quoteId to quoteId?: string (or alternatively change
destinationSwap.quoteId to number) and update any code that constructs/parses
these fields to convert types accordingly; ensure references to destinationSwap
and DestinationOrderParams compile after the change.

---

Nitpick comments:
In `@packages/bridging/src/BridgingSdk/getQuoteWithBridgeThenSwap.ts`:
- Around line 129-131: The hardcoded 1-hour validity window set via the validTo
calculation in getQuoteWithBridgeThenSwap should be made configurable; add an
optional parameter (e.g., advancedSettings.validityWindowSeconds or
providerOptions.validToSeconds) and use it to compute validTo with a sensible
default of 3600 if unset, update call sites and any types/interfaces for
getQuoteWithBridgeThenSwap and related provider functions to accept and
propagate this option, and ensure unit tests or consumers still default to
current behavior when the option is omitted.

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: e0bd70b7-fd77-47b2-a4bf-1abc791746c4

📥 Commits

Reviewing files that changed from the base of the PR and between 7b41c2d and 674c420.

📒 Files selected for processing (12)
  • packages/bridging/src/BridgingSdk/getQuoteWithBridge.test.ts
  • packages/bridging/src/BridgingSdk/getQuoteWithBridge.ts
  • packages/bridging/src/BridgingSdk/getQuoteWithBridgeThenSwap.ts
  • packages/bridging/src/BridgingSdk/types.ts
  • packages/bridging/src/index.ts
  • packages/bridging/src/providers/bungee/BungeeBridgeThenSwapProvider.ts
  • packages/bridging/src/providers/bungee/bridgeThenSwap/computeOrderFlowAddress.ts
  • packages/bridging/src/providers/bungee/bridgeThenSwap/encodeOrderData.ts
  • packages/bridging/src/providers/bungee/bridgeThenSwap/orderFlowAbi.ts
  • packages/bridging/src/providers/bungee/types.ts
  • packages/bridging/src/types.ts
  • packages/bridging/src/utils.ts

BridgeQuoteAndPost,
BridgeQuoteResult,
BridgeQuoteResults,
BridgeThenSwapProvider,

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟡 Minor

Remove unused import BridgeThenSwapProvider to fix ESLint error.

The BridgeThenSwapProvider type is imported but never used in this file. The type guard isBridgeThenSwapProvider (line 33) is used instead for the runtime check. This unused import is causing the ESLint pipeline failure.

🔧 Proposed fix
 import {
   BridgeQuoteAndPost,
   BridgeQuoteResult,
   BridgeQuoteResults,
-  BridgeThenSwapProvider,
   BridgeThenSwapQuoteAndPost,
   QuoteBridgeRequest,
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
BridgeThenSwapProvider,
import {
BridgeQuoteAndPost,
BridgeQuoteResult,
BridgeQuoteResults,
BridgeThenSwapQuoteAndPost,
QuoteBridgeRequest,
🧰 Tools
🪛 GitHub Actions: ESLint check

[error] 19-3: ESLint (@typescript-eslint/no-unused-vars): 'BridgeThenSwapProvider' is defined but never used. Allowed unused vars must match /^_/u


[error] lint step failed: eslint src/**/*.ts

🪛 GitHub Check: eslint

[failure] 19-19:
'BridgeThenSwapProvider' is defined but never used


[failure] 19-19:
'BridgeThenSwapProvider' is defined but never used. Allowed unused vars must match /^_/u

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@packages/bridging/src/BridgingSdk/getQuoteWithBridge.ts` at line 19, Remove
the unused type import BridgeThenSwapProvider from the import list (it's causing
the ESLint error) while keeping the runtime type guard isBridgeThenSwapProvider
intact; locate the import that currently includes BridgeThenSwapProvider and
delete that symbol from the import clause so only used symbols remain, then run
lint to verify the ESLint error is resolved.

Comment on lines +180 to +186
const buyTokenInfo: TokenInfo = {
address: buyTokenAddress,
decimals: buyTokenDecimals,
chainId: buyTokenChainId,
name: destinationSwapResult.swapResult.tradeParameters.buyToken,
symbol: destinationSwapResult.swapResult.tradeParameters.buyToken,
}

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟡 Minor

buyTokenInfo.name and symbol are set to the token address, not actual metadata.

tradeParameters.buyToken is the token address string, not the token name or symbol. This will result in incorrect metadata in the returned buyTokenInfo.

🛠️ Proposed fix

Consider passing token metadata from the request or fetching it separately:

   // Build buy token info
   const buyTokenInfo: TokenInfo = {
     address: buyTokenAddress,
     decimals: buyTokenDecimals,
     chainId: buyTokenChainId,
-    name: destinationSwapResult.swapResult.tradeParameters.buyToken,
-    symbol: destinationSwapResult.swapResult.tradeParameters.buyToken,
+    name: swapAndBridgeRequest.buyTokenName,
+    symbol: swapAndBridgeRequest.buyTokenSymbol,
   }

Alternatively, if the metadata isn't available in the request, you could leave these fields as undefined or fetch token info from a registry.

🧰 Tools
🪛 GitHub Actions: ESLint check

[error] lint step failed: eslint src/**/*.ts

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@packages/bridging/src/BridgingSdk/getQuoteWithBridgeThenSwap.ts` around lines
180 - 186, The buyTokenInfo object incorrectly assigns name and symbol from
destinationSwapResult.swapResult.tradeParameters.buyToken (which is the token
address); update the construction of buyTokenInfo so name and symbol come from
actual token metadata (e.g., use provided request metadata fields if available,
or fetch token details from a registry/service using buyTokenAddress and
buyTokenChainId), and if metadata is not available set name and symbol to
undefined/null or a safe placeholder; locate this change around the buyTokenInfo
variable and references to buyTokenAddress and
destinationSwapResult.swapResult.tradeParameters.buyToken.

Comment on lines +193 to +212
async getBridgeTransaction(params: {
bridgeQuote: BungeeBridgeThenSwapQuoteResult
destinationPayload: string
destinationGasLimit: number
}): Promise<BridgeThenSwapTransaction> {
const { bridgeQuote } = params
const { buildTx } = bridgeQuote

// The build-tx from Bungee already contains the bridge transaction.
// For destination execution, we need to re-request with the destination payload.
// However, since the quote was already obtained with the factory as receiver,
// we use the build-tx directly. The destination payload is included in the
// Bungee quote request params (destinationPayload, destinationGasLimit).
return {
to: buildTx.txData.to,
data: buildTx.txData.data,
value: buildTx.txData.value,
chainId: buildTx.txData.chainId,
}
}

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟠 Major

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
# Check if BungeeQuoteAPIRequest type supports destinationPayload and destinationGasLimit
ast-grep --pattern $'interface BungeeQuoteAPIRequest {
  $$$
}'

# Also check how other Bungee providers use these fields
rg -n "destinationPayload|destinationGasLimit" --type=ts packages/bridging/src/providers/bungee/

Repository: cowprotocol/cow-sdk

Length of output: 2159


🌐 Web query:

Bungee Socket API destination payload destinationCallData parameter

💡 Result:

The Bungee Socket API (legacy Socket API used by Bungee Exchange, a cross-chain bridge and swap aggregator powered by Socket Protocol) includes a "destination payload" in its route/quote responses and request parameters. This payload enables "zaps" or arbitrary contract execution on the destination chain after the bridged funds arrive. The parameter is named destinationPayload (hex-encoded calldata, e.g., "0x1234acbd") in the Bungee /api/v1/bungee/quote API, used alongside destinationGasLimit. No source explicitly names it destinationCallData, but it serves the same purpose: the calldata for the destination call. In Socket Protocol's broader context (underlying Bungee), cross-chain messages use a payload parameter for arbitrary data execution on destination chains. Example quote request with destination payload: curl "https://public-backend.bungee.exchange/api/v1/bungee/quote?originChainId=1&destinationChainId=8453&inputToken=0xa0b86991c6218b36c1d19d4a2e9eb0ce3606eb48&outputToken=0xd9aaec86b65d86f6a7b5b1b0c42ffa531710b6ca&inputAmount=100000000&userAddress=0xd8da6bf26964af9d7eed9e03e53415d37aa96045&receiverAddress=0xd8da6bf26964af9d7eed9e03e53415d37aa96045&destinationPayload=0x1234acbd&destinationGasLimit=100000" This executes the specified calldata on the destination chain post-transfer, enabling use cases like vault deposits, staking, or LP additions without extra user steps.

Citations:


🏁 Script executed:

#!/bin/bash
# Get the getQuote method implementation in BungeeBridgeThenSwapProvider.ts
cat -n packages/bridging/src/providers/bungee/BungeeBridgeThenSwapProvider.ts | sed -n '133,180p'

Repository: cowprotocol/cow-sdk

Length of output: 2188


🏁 Script executed:

#!/bin/bash
# Check the BungeeBridgeThenSwapQuoteResult type definition
rg -n "BungeeBridgeThenSwapQuoteResult" --type=ts packages/bridging/src/providers/bungee/ -A 15

Repository: cowprotocol/cow-sdk

Length of output: 8082


🏁 Script executed:

#!/bin/bash
# Check if there are any calls to getQuote to see how destinationPayload is passed
rg -n "getQuote" --type=ts packages/bridging/src/providers/bungee/ -B 3 -A 10

Repository: cowprotocol/cow-sdk

Length of output: 9399


The destination payload and gas limit parameters are unused and not passed to the Bungee API.

The getBridgeTransaction method receives destinationPayload and destinationGasLimit but doesn't include them in the returned transaction. More critically, the getQuote method (lines 146-158) doesn't pass these parameters to the Bungee API either—only basic routing parameters are sent. The comment claiming "destination payload is included in the Bungee quote request params" is incorrect; the bungeeQuoteRequest object does not contain destinationPayload or destinationGasLimit.

As a result, the bridge transaction won't include the destination execution data, and the computed destination payload will never be transmitted to Bungee or executed on the destination chain.

🧰 Tools
🪛 GitHub Actions: ESLint check

[error] lint step failed: eslint src/**/*.ts

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@packages/bridging/src/providers/bungee/BungeeBridgeThenSwapProvider.ts`
around lines 193 - 212, getBridgeTransaction and the earlier getQuote do not
pass or use destinationPayload/destinationGasLimit, so the destination execution
data is never sent to Bungee; update the bungeeQuoteRequest construction in
getQuote to include destinationPayload and destinationGasLimit (ensure the keys
match Bungee API expectations) or re-request buildTx with those params so the
returned BungeeBridgeThenSwapQuoteResult.buildTx contains the destination
execution data, then modify getBridgeTransaction to return buildTx.txData (or
the newly fetched buildTx) that includes the destination payload and gas limit
so the returned BridgeThenSwapTransaction to/from values carry the destination
execution info.

Comment on lines +471 to +478
destinationSwap: {
sellToken: TokenInfo
buyToken: TokenInfo
estimatedBuyAmount: bigint
minBuyAmount: bigint
validTo: number
quoteId?: string
}

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟡 Minor

Type inconsistency: quoteId is string here but number in DestinationOrderParams.

In destinationSwap.quoteId, the type is string?, but in DestinationOrderParams.quoteId (Line 372), it's number?. This inconsistency could cause type mismatches when passing data between these structures.

🛠️ Proposed fix

Align the types:

   destinationSwap: {
     sellToken: TokenInfo
     buyToken: TokenInfo
     estimatedBuyAmount: bigint
     minBuyAmount: bigint
     validTo: number
-    quoteId?: string
+    quoteId?: number
   }
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
destinationSwap: {
sellToken: TokenInfo
buyToken: TokenInfo
estimatedBuyAmount: bigint
minBuyAmount: bigint
validTo: number
quoteId?: string
}
destinationSwap: {
sellToken: TokenInfo
buyToken: TokenInfo
estimatedBuyAmount: bigint
minBuyAmount: bigint
validTo: number
quoteId?: number
}
🧰 Tools
🪛 GitHub Actions: ESLint check

[error] lint step failed: eslint src/**/*.ts

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@packages/bridging/src/types.ts` around lines 471 - 478, The types for quoteId
are inconsistent between destinationSwap (quoteId?: string) and
DestinationOrderParams (quoteId?: number); update one so both use the same type
across the module — e.g., change DestinationOrderParams.quoteId to quoteId?:
string (or alternatively change destinationSwap.quoteId to number) and update
any code that constructs/parses these fields to convert types accordingly;
ensure references to destinationSwap and DestinationOrderParams compile after
the change.

@anxolin
anxolin marked this pull request as draft March 24, 2026 15:56
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant