Swapper Integration Skill
You are helping integrate a new DEX aggregator, swapper, or bridge into ShapeShift Web. This skill guides you through the complete process from research to testing.
When This Skill Activates
Use this skill when the user wants to:
- "Integrate [SwapperName] swapper"
- "Add support for [Protocol]"
- "Implement [DEX] integration"
- "Add [Aggregator] as a swapper"
Overview
ShapeShift Web supports multiple swap aggregators through a unified swapper interface located in packages/swapper/src/swappers/. Each swapper follows consistent patterns, but has variations based on its type (EVM, Solana, cross-chain, gasless, etc.).
Your task: Research existing swappers to understand patterns, then adapt them for the new integration.
Workflow
Phase 1: Information Gathering
Before starting implementation, collect ALL required information from the user.
Use the AskUserQuestion tool to interactively gather this information with structured prompts.
Ask the user for:
- API Documentation
- Link to official API documentation (main docs)
- Link to Swagger/OpenAPI specification (separate link, if available)
- API base URL
- Authentication method (API key? signature? none?)
- If API key needed: Obtain production API key to add to
.env.base - Rate limiting details
- Supported Networks
- Which blockchains (Ethereum, Polygon, Arbitrum, Solana, etc.)?
- Any network-specific limitations?
- Chain naming convention (e.g., "ethereum" vs "1" vs "mainnet")
- API Behavior
- CRITICAL: How does slippage work? (percentage like 1=1%? decimal like 0.01=1%? basis points like 100=1%?)
- Does it require checksummed addresses?
- How are native tokens handled? (special marker address? omit field?)
- Minimum/maximum trade amounts?
- Quote expiration time?
- Brand Assets
- Official swapper name (exact capitalization)
- Logo/icon file or link (PNG preferred, 128x128 or larger)
- Brand colors (optional)
- Reference Materials (helpful but optional)
- Example integrations on GitHub
- Sample curl requests + responses from their dApp
- Known quirks or gotchas
- Community/support contact
Action: Stop and gather this information before proceeding. Missing details cause bugs later.
Phase 2: Research & Understanding
IMPORTANT: Don't guess at implementation details. Research thoroughly before coding.
Step 0: Study the API Documentation
Before looking at code, understand the swapper's API:
- Read the official docs (link from Phase 1)
- How does the API work?
- What endpoints are available?
- What's the request/response format?
- Any special requirements or quirks?
- Study the Swagger/OpenAPI spec (if available)
- Exact request parameters
- Response schema
- Error formats
- Example requests/responses
- Key things to verify:
- How is slippage formatted in requests?
- Are addresses checksummed in examples?
- How are native tokens represented?
- What does a successful quote response look like?
- What error responses can occur?
Try making a test curl request if possible to see real responses.
Step 1: Explore Existing Swappers
Now that you understand the API, see how existing swappers work:
Step 1: Explore the swappers directory
# List all existing swappers
ls packages/swapper/src/swappers/
You'll see swappers like:
- BebopSwapper
- ZrxSwapper
- CowSwapper
- PortalsSwapper
- JupiterSwapper
- ThorchainSwapper
- And others...
Step 2: Identify similar swappers
Based on what you gathered in Phase 1, determine which swapper type yours is:
EVM Single-Hop (most common):
- Same-chain swaps only
- Standard transaction signing
- Examples: BebopSwapper, ZrxSwapper, PortalsSwapper
Gasless / Order-Based:
- Sign message instead of transaction
- No gas fees
- Examples: CowSwapper
Solana-Only:
- Solana ecosystem
- Different execution model
- Examples: JupiterSwapper
Cross-Chain / Multi-Hop:
- Bridge or cross-chain swaps
- May have multiple steps
- Examples: ThorchainSwapper, ChainflipSwapper
Bridge-Specific:
- Focus on bridging, not swapping
- Examples: ArbitrumBridgeSwapper, RelaySwapper
Step 3: Study similar swappers
Pick 2-3 similar swappers and read their implementations:
# Example: If building an EVM aggregator, study these:
@packages/swapper/src/swappers/BebopSwapper/BebopSwapper.ts
@packages/swapper/src/swappers/BebopSwapper/endpoints.ts
@packages/swapper/src/swappers/BebopSwapper/types.ts
@packages/swapper/src/swappers/BebopSwapper/INTEGRATION.md
@packages/swapper/src/swappers/ZrxSwapper/ZrxSwapper.ts
@packages/swapper/src/swappers/PortalsSwapper/PortalsSwapper.ts
Pay attention to:
- File structure
- How they call their APIs
- How they handle errors
- How they calculate rates and fees
- Special handling (checksumming, hex conversion, etc.)
Step 4: Read supporting documentation
Consult the skill's reference materials:
@reference.md- General swapper architecture and patterns@common-gotchas.md- Critical bugs to avoid@examples.md- Code templates
Phase 3: Implementation
Follow the pattern established by similar swappers. Don't reinvent the wheel.
Step 1: Create directory structure
Create packages/swapper/src/swappers/[SwapperName]Swapper/
For most EVM swappers, create:
[SwapperName]Swapper/
├── index.ts
├── [SwapperName]Swapper.ts
├── endpoints.ts
├── types.ts
├── get[SwapperName]TradeQuote/
│ └── get[SwapperName]TradeQuote.ts
├── get[SwapperName]TradeRate/
│ └── get[SwapperName]TradeRate.ts
└── utils/
├── constants.ts
├── [swapperName]Service.ts
├── fetchFrom[SwapperName].ts
└── helpers/
└── helpers.ts
Check @examples.md for structure templates.
Step 2: Implement core files
Order (follow this sequence):
types.ts: Define TypeScript interfaces based on API responsesutils/constants.ts: Supported chains, default slippage, native token markersutils/helpers/helpers.ts: Helper functions (validation, rate calculation)utils/[swapperName]Service.ts: HTTP service wrapperutils/fetchFrom[SwapperName].ts: API fetch functionsget[SwapperName]TradeQuote.ts: Quote logicget[SwapperName]TradeRate.ts: Rate logicendpoints.ts: Wire up SwapperApi interface[SwapperName]Swapper.ts: Main swapper classindex.ts: Exports
Refer to @examples.md for code templates. Copy patterns from similar existing swappers.
Step 3: Add Swapper-Specific Metadata (ONLY if needed)
When is metadata needed?
- Deposit-to-address swappers (Chainflip, NEAR Intents) - need deposit address, swap ID for status polling
- Order-based swappers (CowSwap) - need order ID for status tracking
- Any swapper that requires tracking state between quote → execution → status polling
When is metadata NOT needed?
- Direct transaction swappers (Bebop, 0x, Portals) - transaction is built from quote, no async tracking needed
- Same-chain aggregators where transaction hash is sufficient for status tracking
- Most EVM-only swappers that return transaction data directly
If your swapper doesn't need async status polling or deposit addresses, skip this step!
Three places to add metadata:
a. Define types (packages/swapper/src/types.ts):
Add to TradeQuoteStep type:
export type TradeQuoteStep = {
// ... existing fields
[swapperName]Specific?: {
depositAddress: string
swapId: number
// ... other swapper-specific fields
}
}
Add to SwapperSpecificMetadata type (for swap storage):
export type SwapperSpecificMetadata = {
chainflipSwapId: number | undefined
nearIntentsSpecific?: {
depositAddress: string
depositMemo?: string
timeEstimate: number
deadline: strin