Changelog
All notable changes to this project will be documented in this file.
[3.1.0] - 2025-01-25
Added
- New complete TypeScript definitions- Full TypeScript support for all three implementations (viem, ethersV5, ethers v6)
- TypeScript type exports - Type exports at symphony-sdk/types/viem,symphony-sdk/types/ethersV5,symphony-sdk/types/ethers
Changed
- BREAKING: isRawandoutTokenDecimalsmoved fromslippagetooptionsparameter across all implementations
- BREAKING: Transaction wait behavior standardized - swap()now returns minedTransactionReceiptby default (previously returned pending transaction for ethers and ethers V5 implementations)
- BREAKING: Bps scale for slippage is now base on 10000instead of1000000, to standardize fee basis point scale across the project
- Improved API semantics - Formatting options (isRaw,outTokenDecimals) separated from slippage configuration
- Transaction receipts - All implementations now wait for transaction receipt
- Transaction confirmations - All implementations now use options.waitparameter to adjust blocks waited for transaction to be mined (default: 1 confirmation)
- Error handling standardized - All implementations now use throw errorto preserve stack traces
Deprecated
Technical Details
Slippage Bps
Before v3.1.0:const { swapReceipt, approveReceipt }: SwapResult = await route.swap({
  slippage: {
    slippageAmount: 10000  // %1 slippage -> 1000000bps = 100% ,
    isBps: true,
  },
});const { swapReceipt, approveReceipt }: SwapResult = await route.swap({
  slippage: {
    slippageAmount: 100  // %1 slippage -> 10000bps = 100% ,
    isBps: true,
  },
});isRaw Field Refactor
Moved amount formatting options to improve API clarity:
Before v3.1.0:await swap({
  slippage: {
    slippageAmount: "100",
    isBps: true,
    isRaw: false, // In slippage object
    outTokenDecimals: 18, // In slippage object
  },
});await swap({
  options: {
    isRaw: false, // Now in options
    outTokenDecimals: 18, // Now in options
  },
  slippage: {
    slippageAmount: "100",
    isBps: true, // Only slippage-related fields
  },
});Transaction Wait Standardization
Before v3.1.0 (ethersV5/ethers v6):const result = await swap(...);
const receipt = await result.swapReceipt.wait(); // Required extra stepconst result = await swap(...);
const receipt = result.swapReceipt; // Already waited, returns TransactionReceiptControl confirmations with options.wait:
- wait: 1- Wait for 1 confirmation (default)
- wait: n- Wait for n confirmations
Migration Guide
isRaw and outTokenDecimals Location
// Before v3.1.0
await swap({
  slippage: {
    slippageAmount: "100",
    isBps: true,
    isRaw: false,
    outTokenDecimals: 18,
  },
});
 
// v3.1.0 and later
await swap({
  options: {
    isRaw: false,
    outTokenDecimals: 18,
    // ... other options
  },
  slippage: {
    slippageAmount: "100",
    isBps: true,
  },
});Transaction Wait Pattern
// Before v3.1.0
const result = await swap(...);
const receipt = await result.swapReceipt.wait();
 
// v3.1.0 and later
const result = await swap(...);
const receipt = result.swapReceipt; // Already a TransactionReceipt
 
// To get pending transaction (old behavior)
const result = await swap({
  options: { wait: 0 },
  // ... other params
});
const pending = result.swapReceipt; // ContractTransaction
const receipt = await pending.wait(); // Wait manuallyTypeScript Usage
// Import types for your implementation
import { Route, swap, SwapResult } from "symphony-sdk/viem";
import { RawRoute, SwapSlippageConfig } from "symphony-sdk/types/viem";
 
// For ethersV5
import { Route, swap } from "symphony-sdk/ethersV5";
import { SwapResult, SwapSlippageConfig } from "symphony-sdk/types/ethersV5";
 
// For ethers v6
import { Route, swap } from "symphony-sdk/ethers";
import { SwapResult, SwapSlippageConfig } from "symphony-sdk/types/ethers";Performance Improvements
- Type safety - Full TypeScript support enables better IDE completion and compile-time error checking
- Consistent behavior - All three implementations now behave identically
- Clear Errors - Standardized error handling
Backward Compatibility
- TypeScript optional - JavaScript users can continue using the SDK without TypeScript
- All Implementations - No changes needed if you do not use bps slippage on swaps,isRaw field to use raw(wei) values.
- Ethers and Ethers V5 - If you are using wait()to get receipt, you can now just use theswapReceipt.
[3.0.0] - 2025-08-03
Added
- Contract Address Change - Symphony's contract address is now 0xC340F8C5C58f4f99B4e43673eba07Cf378047DD2. It is a proxy contract. From now on, contract address changes will not take place frequently
- New tokenService- Centralized async token management service for fetching live token data from Symphony Assetlist API
- Async token methods - getTokenListAsync()andisTokenListedAsync()methods to Symphony class across all implementations
- Proactive cache warming - Background token fetching during SDK initialization for improved performance
- Live token data - Real-time token information provided by Symphony
- Intelligent fallback - Automatic fallback to static tokens when API is unavailable
- Race condition protection - Promise caching prevents duplicate API calls
- Enhanced error handling - Comprehensive logging and graceful degradation
- Cross-implementation parity - Identical functionality across viem, ethersV5, and ethers v6+ implementations
- Custom amount approval override - giveApproval()now supports custom amount parameter to override route's default amount across all implementations
- Flexible approval amounts - Support for both raw (wei) and formatted amounts in custom approvals with automatic decimal conversion
Changed
- BREAKING: getTotalAmountOut()is now async and requiresawaitacross all implementations
- BREAKING: getTotalAmountIn()is now async and requiresawaitacross all implementations
- BREAKING: getRouteDetails()is now async and requiresawaitacross all implementations
- BREAKING: Route.getTotalAmountOut()is now async and requiresawaitacross all implementations
- BREAKING: Route.getTotalAmountIn()is now async and requiresawaitacross all implementations
- BREAKING: Route.getRouteDetails()is now async and requiresawaitacross all implementations
- BREAKING: feeParamsis now based on10000instead of1000
- Improved performance - Token list access is ~90% faster after initial cache warming, near zero delay for end users/frontend applications, zero delay on subsequent calls
- Enhanced configuration - additionalTokensandoverrideDefaultTokensnow work with both static and async token methods
- Better token validation - Centralized token structure validation and address normalization
Fixed
- Decimal parsing bug - Fixed incorrect usage of .decimalsinstead of.addressin approval functions on 'isRaw=true' configuration
Deprecated
- Sync token methods (getTokenList(),isTokenListed()) are still supported but async methods are recommended for live data
Technical Details
Core Functions Migrated
- checkApproval.js- Now uses async tokenService with user configuration
- getRoute.js- Migrated to async tokenService with- await getRouteDetails()
- giveApproval.js- Updated to use async tokenService with- await getTotalAmountIn()
Helper Functions Made Async
- getTotalAmountOut.js- Function signature changed to- async getTotalAmountOut(route)
- getTotalAmountIn.js- Function signature changed to- async getTotalAmountIn(route)
- getRouteDetails.js- Function signature changed to- async getRouteDetails(route)
Dependent Functions Updated
- calculateAmountOutMin.js- Updated to- await getTotalAmountOut()
- swap.js- Updated to- await getTotalAmountIn()for token amount calculations
- generateCalldata.js- Updated to- await getTotalAmountIn()for token values
- Routeentity methods - Made async where they call async helpers
Configuration Changes
- config.js- Refactored to delegate token operations to tokenService
- Token validation and merging logic moved to centralized tokenService
- Native address handling improved across all implementations
- feeParamsconfiguration has changed increments from- 1000to- 10000for granular control over fees
Migration Guide
For Direct Helper Function Usage
// Before v3.0.0
const amountOut = getTotalAmountOut(route);
const amountIn = getTotalAmountIn(route);
const details = getRouteDetails(route);
 
// v3.0.0 and later
const amountOut = await getTotalAmountOut(route);
const amountIn = await getTotalAmountIn(route);
const details = await getRouteDetails(route);For Route Entity Usage
// Before v3.0.0
const amountOut = route.getTotalAmountOut();
const amountIn = route.getTotalAmountIn();
const details = route.getRouteDetails();
 
// v3.0.0 and later
const amountOut = await route.getTotalAmountOut();
const amountIn = await route.getTotalAmountIn();
const details = await route.getRouteDetails();For Live Token Data
// New in v3.0.0 - Live token data
const liveTokens = await symphony.getTokenListAsync();
const isListed = await symphony.isTokenListedAsync("0x...");
 
// Still supported - Static token data
const staticTokens = symphony.getTokenList();
const isListedStatic = symphony.isTokenListed("0x...");For Fee Parameters
// Before v3.0.0
SymphonySDK.setConfig({
  feeParams: {
    paramFee: "100", // =10% fees cut from out amount
    feeAddress: "your-fee-receiver-address",
    feeSharePercentage: "800", // = 80% of fees cut sent to your fee receiver address
  },
});
 
// After v3.0.0
SymphonySDK.setConfig({
  feeParams: {
    paramFee: "1000", // =10% fees cut from out amount
    feeAddress: "your-fee-receiver-address",
    feeSharePercentage: "8000", // = 80% of fees cut sent to your fee receiver address
  },
});For Fee Parameters
// Before v3.0.0
SymphonySDK.setConfig({
  feeParams: {
    paramFee: "100", // =10% fees cut from out amount
    feeAddress: "your-fee-receiver-address",
    feeSharePercentage: "800", // = 80% of fees cut sent to your fee receiver address
  },
});
 
// After v3.0.0
SymphonySDK.setConfig({
  feeParams: {
    paramFee: "1000", // =10% fees cut from out amount
    feeAddress: "your-fee-receiver-address",
    feeSharePercentage: "8000", // = 80% of fees cut sent to your fee receiver address
  },
});For Custom Approval Amounts
// New in v3.0.0 - Custom amount override
// Use route's default amount (existing behavior)
await route.giveApproval();
 
// Override with custom raw amount (wei)
await route.giveApproval({
  amount: "1000000000000000000", // 1 token in wei
  options: { isRaw: true },
});
 
// Override with custom formatted amount
await route.giveApproval({
  amount: "1.05", // 1.05 tokens
  options: { isRaw: false },
});
 
// Works across all implementations (viem, ethersV5, ethers)Performance Improvements
- First async call: ~50-300ms (API fetch + cache)
- Subsequent calls: ~0ms (served from cache for each session)
- Background warming: No impact on SDK initialization time
- Memory usage: Optimized caching with efficient cleanup
Backward Compatibility
- All existing sync methods continue to work without changes
- No breaking changes for users who don't directly call helper functions
- Fee parameters should be updated to fit more granular fee controls
- Gradual migration path available
- Full configuration parity maintained

