Skip to content

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: isRaw and outTokenDecimals moved from slippage to options parameter across all implementations
  • BREAKING: Transaction wait behavior standardized - swap() now returns mined TransactionReceipt by default (previously returned pending transaction for ethers and ethers V5 implementations)
  • BREAKING: Bps scale for slippage is now base on 10000 instead of 1000000, 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.wait parameter to adjust blocks waited for transaction to be mined (default: 1 confirmation)
  • Error handling standardized - All implementations now use throw error to 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,
  },
});
v3.1.0 and later:
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
  },
});
v3.1.0 and later:
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 step
v3.1.0 and later:
const result = await swap(...);
const receipt = result.swapReceipt; // Already waited, returns TransactionReceipt

Control 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 manually

TypeScript 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 the swapReceipt.

[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() and isTokenListedAsync() 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 requires await across all implementations
  • BREAKING: getTotalAmountIn() is now async and requires await across all implementations
  • BREAKING: getRouteDetails() is now async and requires await across all implementations
  • BREAKING: Route.getTotalAmountOut() is now async and requires await across all implementations
  • BREAKING: Route.getTotalAmountIn() is now async and requires await across all implementations
  • BREAKING: Route.getRouteDetails() is now async and requires await across all implementations
  • BREAKING: feeParams is now based on 10000 instead of 1000
  • 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 - additionalTokens and overrideDefaultTokens now 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 .decimals instead of .address in 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
  • Route entity 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
  • feeParams configuration has changed increments from 1000 to 10000 for 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