Skip to main content

πŸ”„ Swap Integration

SuperSafe Wallet integrates Bebop's JAM (Just Another Market) protocol and Relay.link for gasless, MEV-protected token swaps and cross-chain swaps across multiple EVM networks.

Swap Overview​

Key Features​

  • βœ… Gasless Swaps: Only pay for token approval (Permit2) via Bebop
  • βœ… MEV Protection: Protected from frontrunning and sandwich attacks
  • βœ… Multi-Chain: Currently supports 6 active networks for Bebop (SuperSeed, Ethereum, Optimism, Base, BNB Chain, Arbitrum)
  • βœ… Cross-Chain Swaps: Relay.link supports swaps across 85+ blockchains
  • βœ… Partner Fees: Configurable revenue sharing (1% default)
  • βœ… Best Prices: Aggregated liquidity sources

Unified Panel Architecture​

Version: 2.0.0
Refactored: November 13, 2025

Design Philosophy​

SuperSafe Wallet implements a unified panel architecture for swap providers, ensuring consistency, maintainability, and scalability across all swap implementations.

Before (v1.0.0 - Monolithic)​

Swap.jsx (2,206 lines)
β”œβ”€ ALL Bebop logic inline
β”œβ”€ ALL Relay logic inline
β”œβ”€ Massive state management
β”œβ”€ Duplicate components
└─ Difficult to maintain

Problems:

  • ❌ 2,206 lines in single file
  • ❌ Mixed concerns (Bebop + Relay + routing)
  • ❌ Hard to test independently
  • ❌ Difficult to add new providers
  • ❌ Code duplication between providers

After (v2.0.0 - Unified Panels)​

Swap.jsx (~115 lines)                    # Container/Orchestrator
β”œβ”€ SwapProviderSelector # Tab selector
β”œβ”€ SlippageControl (shared) # Slippage configuration
└─ Conditional Rendering:
β”œβ”€ BebopSwapPanel.jsx (~1,400 lines)
└─ RelaySwapPanel.jsx (~1,288 lines)

Benefits:

  • βœ… Maintainability: Each panel is self-contained (~1,300 lines each)
  • βœ… Testability: Independent unit testing per provider
  • βœ… Scalability: Add providers without touching existing code
  • βœ… Consistency: Both panels follow same architectural pattern
  • βœ… Separation of Concerns: Clear responsibilities

Component Structure​

1. Swap.jsx (~115 lines)​

Responsibility: Container/Orchestrator only

const Swap = ({ 
onTransactionComplete,
preselectedToken,
onClearPreselection,
walletTokensWithBalance,
nativeTokenBalance
}) => {
const [swapProvider, setSwapProvider] = useState('bebop');
const [slippage, setSlippage] = useState(0.5);

return (
<>
<SwapProviderSelector selected={swapProvider} onChange={setSwapProvider} />
<SlippageControl slippage={slippage} onChange={setSlippage} />

{swapProvider === 'relay' ? (
<RelaySwapPanel {...props} slippage={slippage} />
) : (
<BebopSwapPanel {...props} slippage={slippage} />
)}
</>
);
};

Key Points:

  • Single responsibility: provider selection and routing
  • No swap business logic
  • Minimal state (provider + slippage)
  • Clean, readable, maintainable

2. BebopSwapPanel.jsx (~1,400 lines)​

Responsibility: Complete Bebop swap implementation

Internal Components:

  • LoadingDots - Loading animation
  • PriceDeviationTooltip - USD deviation warnings
  • SwapDetails - Fee breakdown accordion

Key Features:

  • Gasless swaps via Bebop JAM
  • Permit2 approvals (one-time)
  • EIP-712 order signing
  • Status polling
  • Balance validation
  • USD price calculations

Architecture Compliance:

  • βœ… NO ethers imports
  • βœ… Uses SwapAdapter only
  • βœ… Thin client pattern
  • βœ… All crypto in background

3. RelaySwapPanel.jsx (~1,288 lines)​

Responsibility: Complete Relay.link swap implementation

Internal Components:

  • UsdBalanceDisplay - Balance with USD value
  • formatTokenAmount - Helper function

Key Features:

  • Cross-chain swaps
  • Network selection (origin: active, destination: selectable)
  • Route visualization
  • Gas estimation
  • Bridge time estimation
  • Multi-hop support

Architecture Compliance:

  • βœ… NO ethers imports
  • βœ… Uses RelayAdapter only
  • βœ… Thin client pattern
  • βœ… All crypto in background

Shared Components (src/components/swap/)​

These components are used by both panels:

ComponentPurposeUsed By
CompactNetworkSelector.jsxNetwork dropdownRelay (cross-chain)
RouteVisualization.jsxVisual route displayRelay (multi-hop)
BridgeTimeDisplay.jsxBridge time estimationRelay (cross-chain)
GasEstimateDisplay.jsxGas cost displayRelay (all swaps)
LoadingDots.jsxLoading animationBoth (separate versions)

Performance Metrics​

MetricBefore (v1.0)After (v2.0)Improvement
File Size2,206 lines115 lines95% reduction
Build Time6.8s6.5s4% faster
Bundle SizeSameSameNo change
MaintainabilityLowHighβœ… Significantly improved
TestabilityHardEasyβœ… Unit tests possible

Bebop Integration​

Active Network Support​

NetworkChain IDBebop APISwap EnabledContracts
SuperSeed5330JAM v2βœ… ActiveCustom deployment
Ethereum1JAM v2 + RFQ v3βœ… ActiveStandard EVM
Optimism10JAM v2 + RFQ v3βœ… ActiveStandard EVM
Base8453JAM v2 + RFQ v3βœ… ActiveStandard EVM
BNB Chain56JAM v2 + RFQ v3βœ… ActiveStandard EVM
Arbitrum One42161JAM v2 + RFQ v3βœ… ActiveStandard EVM

Note: All active networks support Bebop swaps except Shardeum (chainId: 8118), which does not have swap support enabled.

Bebop Contracts​

// Location: src/utils/networks.js
export const BEBOP_CONTRACTS = {
// Standard EVM chains
STANDARD_EVM: {
JAM_SETTLEMENT_ADDRESS: "0xbEbEbEb035351f58602E0C1C8B59ECBfF5d5f47b",
BALANCE_MANAGER_ADDRESS: "0xfE96910cF84318d1B8a5e2a6962774711467C0be"
},

// SuperSeed (custom deployment)
SUPERSEED: {
JAM_SETTLEMENT_ADDRESS: "0xbeb0b0623f66bE8cE162EbDfA2ec543A522F4ea6",
BALANCE_MANAGER_ADDRESS: "0xC5a350853E4e36b73EB0C24aaA4b8816C9A3579a"
},

// Universal Permit2
PERMIT2: {
CONTRACT_ADDRESS: "0x000000000022D473030F116dDEE9F6B43aC78BA3"
}
};

Overview​

As of November 4, 2025, SuperSafe Wallet now integrates Relay.link as an alternative swap provider, enabling cross-chain swaps and bridge functionality across 85+ blockchains.

Key Features​

  • βœ… Cross-Chain Swaps: Swap tokens between different networks in one transaction
  • βœ… AppFees Support: Configurable partner fees (1% default) collected in stablecoins
  • βœ… Meta-Aggregation: Best prices across multiple DEXs and bridges
  • βœ… 85+ Chains: Wide blockchain support including all SuperSafe networks
  • βœ… Instant Bridging: Fast cross-chain transfers via relayer network
  • βœ… Optimized Gas: Reduced costs through optimized routing

Active Network Support​

All SuperSafe EVM networks are supported by Relay.link (except Shardeum):

NetworkChain IDRelay Chain IDCross-ChainStatus
SuperSeed53305330βœ… Enabledβœ… Active
Ethereum11βœ… Enabledβœ… Active
Optimism1010βœ… Enabledβœ… Active
Base84538453βœ… Enabledβœ… Active
BNB Chain5656βœ… Enabledβœ… Active
Arbitrum One4216142161βœ… Enabledβœ… Active
Shardeum81188118❌ Not supportedβœ… Active (no Relay)

AppFees Configuration​

πŸ”„ UNIFIED FEE SYSTEM - Relay.link uses the same fee configuration as Bebop:

Located in src/background/config/relayConfig.js:

// βœ… Reads from environment variables
export const RELAY_CONFIG = loadRelayConfigFromEnv();

// βœ… AppFees use unified system with Bebop
import { getFeeConfiguration as getBebopFeeConfiguration } from '../utils/feeConfig.js';

export function getAppFeesConfig() {
const bebopFeeConfig = getBebopFeeConfiguration();

return {
feeBps: bebopFeeConfig.feeBps, // Same as Bebop
recipient: bebopFeeConfig.partnerInfo.receiverAddress // Same recipient
};
}

Benefits of Unified System:

  • βœ… Single point of configuration
  • βœ… Consistent fee rates across providers
  • βœ… Simplified management
  • βœ… No hardcoded values

Relay Swap Flow​

sequenceDiagram
participant U as User
participant UI as RelaySwapPanel
participant RA as RelayAdapter
participant BG as Background
participant RS as RelayStreamHandler
participant R as Relay SDK
participant BC as Blockchain

U->>UI: Select networks & tokens
UI->>UI: Auto-fetch quote (debounced)
UI->>RA: getQuote()
RA->>BG: RELAY_GET_QUOTE
BG->>RS: Handle get quote
RS->>R: Request quote with AppFees
R->>RS: Return quote with steps
RS->>BG: Return quote
BG->>UI: Display quote & fees

U->>UI: Confirm swap
UI->>RA: executeSwap()
RA->>BG: RELAY_EXECUTE_SWAP
BG->>RS: Handle execute swap
RS->>R: Execute swap steps
R->>BC: Submit transactions
BC->>R: Return tx hash
R->>RS: Execution complete
RS->>BG: Return result
BG->>UI: Display success

UI->>RA: checkStatus() (polling)
RA->>BG: RELAY_GET_STATUS
BG->>BC: Get tx receipt
BC->>BG: Confirmation status
BG->>UI: Update status

Network Selection Architecture (v2.0.0)​

Updated: November 12, 2025

Relay.link swap panel implements a restricted origin network model where the origin (Pay) network is always the active wallet network:

Design Rules:

  • Origin (Pay): Always uses active network - cannot be changed within panel
  • Destination (Receive): User can select any supported network via dropdown
  • To swap FROM a different network: User must switch active network via AppHeader first

Rationale:

  • βœ… Origin must be active network (required for transaction signing)
  • βœ… Consistent with Bebop and standard wallet behavior (MetaMask, Rainbow, etc.)
  • βœ… Balances always available for origin tokens (cached in Dashboard)
  • βœ… Eliminates cross-chain address mismatches
  • βœ… Prevents balance fetching issues for non-active networks

Differences from Bebop​

FeatureBebopRelay.link
Cross-Chain❌ Noβœ… Yes
Networks6 EVM chains85+ chains
Gaslessβœ… Yes (Permit2)⚠️ Gas required
MEV Protectionβœ… Yes⚠️ Partial
ApprovalOne-time Permit2Per-token ERC20
Partner FeesJAM order signatureAppFees API parameter
Quote Expiry30 seconds30 seconds

Swap Flow​

Complete Swap Sequence​

sequenceDiagram
participant U as User
participant UI as Swap UI
participant SA as SwapAdapter
participant BG as Background
participant B as Bebop API
participant BC as Blockchain

U->>UI: Enter swap amount
UI->>SA: getSwapQuote()
SA->>BG: SWAP_GET_QUOTE
BG->>B: Fetch quote with fees
B->>BG: Return quote
BG->>UI: Display quote

U->>UI: Confirm swap
UI->>SA: signAndSubmitOrder()

alt Token Requires Approval
SA->>BG: Check ERC20 allowance
BG->>BC: contract.allowance()
BC->>BG: Current allowance

alt Insufficient Allowance
BG->>BG: Sign approval tx
BG->>BC: Send approval
BC->>BG: Approval confirmed
end
end

SA->>BG: SWAP_SIGN_AND_SUBMIT
BG->>BG: Sign EIP-712 order
BG->>B: Submit signed order
B->>BG: Order accepted
BG->>UI: Show success

loop Poll Status
UI->>SA: checkOrderStatus()
SA->>BG: SWAP_CHECK_STATUS
BG->>B: Query status
B->>BG: Status update
BG->>UI: Update UI
end

Partner Fee System​

Fee Configuration​

Location: src/background/utils/feeConfig.js

const FEE_CONFIG = {
// Fee in basis points (100 bps = 1%)
feeBps: 100, // 1% partner fee

// Partner information
partnerInfo: {
name: 'SuperSafe',
receiverAddress: '0x742d35Cc6634C0532925a3b844Bc9e7595f0bEb', // SuperSafe fee receiver
website: 'https://supersafe.xyz'
},

// Fee validation
minFeeBps: 0,
maxFeeBps: 300 // Max 3%
};

export function getFeeConfiguration() {
return {
feeBps: FEE_CONFIG.feeBps,
partnerInfo: FEE_CONFIG.partnerInfo
};
}

Fee Calculation Example​

User swaps 100 USDC for ETH
Quote returns: 0.05 ETH

With 1% partner fee:
- User receives: 0.0495 ETH (99%)
- Partner receives: 0.0005 ETH (1%)

Fee is taken from buy token (ETH in this case)

Multi-Chain Support​

Network-Specific Configuration​

// Location: src/utils/networks.js
export const NETWORKS = {
superseed: {
// ... network config
bebop: {
bebopName: 'superseed',
displayName: 'SuperSeed',
apiSupport: ['JAM'], // No RFQ on SuperSeed
jamApi: 'https://api.bebop.xyz/jam/superseed/v2/',
rfqApi: null,
swapEnabled: true,
contracts: {
jamSettlement: '0xbeb0b0623f66bE8cE162EbDfA2ec543A522F4ea6',
balanceManager: '0xC5a350853E4e36b73EB0C24aaA4b8816C9A3579a',
permit2: '0x000000000022D473030F116dDEE9F6B43aC78BA3'
}
},
relay: {
enabled: true,
relayChainId: 5330,
crossChainEnabled: true
}
},

optimism: {
// ... network config
bebop: {
bebopName: 'optimism',
displayName: 'Optimism',
apiSupport: ['JAM', 'RFQ'],
jamApi: 'https://api.bebop.xyz/jam/optimism/v2/',
rfqApi: 'https://api.bebop.xyz/pmm/optimism/',
swapEnabled: true,
contracts: {
jamSettlement: '0xbEbEbEb035351f58602E0C1C8B59ECBfF5d5f47b',
balanceManager: '0xfE96910cF84318d1B8a5e2a6962774711467C0be',
permit2: '0x000000000022D473030F116dDEE9F6B43aC78BA3'
}
},
relay: {
enabled: true,
relayChainId: 10,
crossChainEnabled: true
}
}
};

Validation System​

export function validateSwapNetwork(networkKey) {
const network = NETWORKS[networkKey];

if (!network) {
return {
valid: false,
reason: 'Network not supported'
};
}

if (!network.bebop || !network.bebop.swapEnabled) {
return {
valid: false,
reason: `Swaps not available on ${network.name}`
};
}

return { valid: true };
}

Adding New Providers​

To add a new swap provider (e.g., Uniswap):

  1. Create src/components/swap/UniswapSwapPanel.jsx (~1,300 lines)
  2. Follow same structure as BebopSwapPanel.jsx or RelaySwapPanel.jsx
  3. Create UniswapAdapter.js in src/utils/
  4. Add provider to SwapProviderSelector.jsx
  5. Add conditional rendering in Swap.jsx:
{swapProvider === 'uniswap' ? (
<UniswapSwapPanel {...props} />
) : swapProvider === 'relay' ? (
<RelaySwapPanel {...props} />
) : (
<BebopSwapPanel {...props} />
)}

That's it! No changes to existing panels required.


Future Enhancements​

  • Add Uniswap provider panel
  • Add 1inch aggregator panel
  • Implement provider comparison mode
  • Add swap history per provider
  • Implement best price routing across providers

Document Status: βœ… Current as of November 15, 2025
Code Version: v5.0.0+ (Unified Panel Architecture)
Last Code Update: November 15, 2025
Major Changes:

  • πŸ†• Unified Panel Architecture: Refactored monolithic Swap.jsx (2,206 lines) into clean architecture
  • πŸ†• Relay.link Integration: Cross-chain swaps across 85+ blockchains
  • Updated Network Support: Bebop supports 6 active networks, Relay supports 6 active networks