Migrate to v4
This guide provides a comprehensive overview of all breaking changes and migration steps from SwapKit v3 to v4.
Major Breaking Changes
Section titled “Major Breaking Changes”1. Package Restructuring
Section titled “1. Package Restructuring”v4 fundamentally changes how packages are organized:
v3 Structure: Individual packages for each component
@swapkit/plugin-chainflip@swapkit/plugin-evm@swapkit/toolbox-cosmos@swapkit/wallet-keystore@swapkit/api
v4 Structure: Consolidated monolithic packages with submodule exports
@swapkit/plugins/* # All plugins in one package@swapkit/toolboxes/* # All toolboxes in one package@swapkit/wallets/* # All wallets in one package@swapkit/helpers # Utilities and API (previously @swapkit/api)@swapkit/sdk # Complete bundle with everything
2. Import Path Changes
Section titled “2. Import Path Changes”All imports must be updated:
// Plugins import { ChainflipPlugin } from "@swapkit/plugin-chainflip"; import { EVMPlugin } from "@swapkit/plugin-evm"; import { ChainflipPlugin } from "@swapkit/plugins/chainflip"; import { EVMPlugin } from "@swapkit/plugins/evm";
// Toolboxes import { getToolboxByChain } from "@swapkit/toolbox-cosmos"; import { EVMToolbox } from "@swapkit/toolbox-evm"; import { getCosmosToolbox } from "@swapkit/toolboxes/cosmos"; import { getEvmToolbox } from "@swapkit/toolboxes/evm";
// Wallets import { keystoreWallet } from "@swapkit/wallet-keystore"; import { keystoreWallet } from "@swapkit/wallets/keystore";
// API (moved to helpers) import { SwapKitApi } from "@swapkit/api"; import { SwapKitApi } from "@swapkit/helpers/api";
3. Client Initialization Changes
Section titled “3. Client Initialization Changes”The SwapKit client initialization has changed:
// v3 import { SwapKit } from "@swapkit/core"; const client = SwapKit({ apis: { /* custom APIs */ }, rpcUrls: { /* RPC URLs */ }, config: { stagenet: false }, plugins: { ...ThorchainPlugin }, wallets: { ...keystoreWallet } });
// v4 import { SwapKit } from "@swapkit/core"; const client = SwapKit({ config: { rpcUrls: { /* RPC URLs */ }, apiKeys: { /* API keys */ } }, plugins: { ...ThorchainPlugin }, wallets: { ...keystoreWallet } });
4. Configuration System (SKConfig)
Section titled “4. Configuration System (SKConfig)”v4 introduces a centralized configuration system:
// v3 - Direct configuration const client = SwapKit({ apis: { [Chain.Ethereum]: customEthApi }, rpcUrls: { [Chain.Ethereum]: "https://eth-rpc.com" } });
// v4 - SKConfig system import { SKConfig } from "@swapkit/helpers"; SKConfig.set({ rpcUrls: { [Chain.Ethereum]: "https://eth-rpc.com" }, apiKeys: { blockchair: "YOUR_KEY", swapKit: "YOUR_KEY" } });
5. Plugin Interface Changes
Section titled “5. Plugin Interface Changes”Plugins now use the createPlugin
helper:
// v3 export function plugin({ getWallet, config }: SwapKitPluginParams<ConnectConfig>) { return { swap, supportedSwapkitProviders: [ProviderName.THORCHAIN] }; }
// v4 import { createPlugin } from "@swapkit/helpers"; export const MyPlugin = createPlugin({ name: "myPlugin", properties: { supportedSwapkitProviders: [ProviderName.THORCHAIN] }, methods: ({ getWallet }) => ({ swap }) });
6. Wallet Interface Changes
Section titled “6. Wallet Interface Changes”Wallets now use the createWallet
helper:
// v3 export const keystoreWallet: SwapKitWallet<[chains: CryptoChain[], phrase: string]> = ({ addChain, apis, rpcUrls }) => { return async (chains, phrase) => { /* ... */ }; };
// v4 import { createWallet } from "@swapkit/helpers"; export const keystoreWallet = createWallet({ name: "keystore", hooks: ({ config }) => ({ async connectWallet(chains: Chain[], phrase: string) { /* ... */ } }) });
7. Toolbox Constructor Changes
Section titled “7. Toolbox Constructor Changes”Toolboxes no longer accept RPC URLs directly:
// v3 const toolbox = getToolboxByChain(chain, { api: customApi, rpcUrl: "https://rpc.url", signer });
// v4 - RPC URLs from SKConfig only const toolbox = getEvmToolbox(chain, { signer });// RPC URL automatically retrieved from SKConfig
8. Type Changes
Section titled “8. Type Changes”Several type imports have changed:
// Wallet types import type { EVMWallets } from "@swapkit/toolbox-evm"; import type { EVMToolboxes } from "@swapkit/toolboxes/evm";
// API types import type { QuoteRequest } from "@swapkit/api"; import type { QuoteRequest } from "@swapkit/helpers/api";
// Plugin params simplified SwapKitPluginParams<ConnectConfig> SwapKitPluginParams
9. Removed Features
Section titled “9. Removed Features”ChainApis
type: Use SKConfig system instead- Direct API parameter: Configure via SKConfig
walletAddressValidator
helper: Removed from core exports- Individual package installations: Must use consolidated packages
Migration Steps
Section titled “Migration Steps”Step 1: Update Dependencies
Section titled “Step 1: Update Dependencies”# Remove v3 packagesbun remove @swapkit/plugin-* @swapkit/toolbox-* @swapkit/wallet-*
# Install v4 packagesbun add @swapkit/sdk# or individual packagesbun add @swapkit/core @swapkit/plugins @swapkit/toolboxes @swapkit/wallets
# Remove v3 packagespnpm remove @swapkit/plugin-* @swapkit/toolbox-* @swapkit/wallet-*
# Install v4 packagespnpm add @swapkit/sdk# or individual packagespnpm add @swapkit/core @swapkit/plugins @swapkit/toolboxes @swapkit/wallets
# Remove v3 packagesnpm uninstall @swapkit/plugin-* @swapkit/toolbox-* @swapkit/wallet-*
# Install v4 packagesnpm install @swapkit/sdk# or individual packagesnpm install @swapkit/core @swapkit/plugins @swapkit/toolboxes @swapkit/wallets
# Remove v3 packagesyarn remove @swapkit/plugin-* @swapkit/toolbox-* @swapkit/wallet-*
# Install v4 packagesyarn add @swapkit/sdk# or individual packagesyarn add @swapkit/core @swapkit/plugins @swapkit/toolboxes @swapkit/wallets
Step 2: Update Imports
Section titled “Step 2: Update Imports”Replace all v3 imports with v4 equivalents:
import { THORChainPlugin } from "@swapkit/plugin-thorchain";import { EVMToolbox } from "@swapkit/toolbox-evm";import { ledgerWallet } from "@swapkit/wallet-ledger";
import { ThorchainPlugin } from "@swapkit/plugins/thorchain";import { getEvmToolbox } from "@swapkit/toolboxes/evm";import { ledgerWallet } from "@swapkit/wallets/ledger";
Step 3: Update Client Initialization
Section titled “Step 3: Update Client Initialization”import { SwapKitCore } from "@swapkit/core";import { createSwapKit } from "@swapkit/sdk";
const client = new SwapKitCore({const client = createSwapKit({ // config});
Step 4: Update Wallet Connections
Section titled “Step 4: Update Wallet Connections”The wallet connection pattern remains similar but uses the new import paths:
// @noErrorValidationimport { createSwapKit, Chain } from "@swapkit/sdk";
const client = createSwapKit({ // your config});
// Connect EVM walletawait client.connectEVMWallet([Chain.Ethereum]);
// Connect keystore walletconst chains = [Chain.Bitcoin, Chain.Ethereum, Chain.Cosmos];const phrase = "your mnemonic phrase here";await client.connectKeystore(chains, phrase);
New Features in v4
Section titled “New Features in v4”1. Runtime Configuration Updates (Major Improvement)
Section titled “1. Runtime Configuration Updates (Major Improvement)”The biggest improvement in v4 is the ability to update configuration at runtime without recreating the SwapKit client.
v3 Approach (Client Recreation Required)
Section titled “v3 Approach (Client Recreation Required)”// v3 - Had to recreate entire client for config changesconst client1 = SwapKit({ rpcUrls: { [Chain.Ethereum]: "https://public-rpc.com" }, apis: { [Chain.Bitcoin]: customBtcApi }});
// To change RPC URL, needed to create new clientconst client2 = SwapKit({ rpcUrls: { [Chain.Ethereum]: "https://premium-rpc.com" }, apis: { [Chain.Bitcoin]: customBtcApi }});
v4 Approach (Runtime Updates)
Section titled “v4 Approach (Runtime Updates)”import { createSwapKit, SKConfig, Chain } from '@swapkit/sdk';
// Create client onceconst swapKit = createSwapKit({ config: { rpcUrls: { [Chain.Ethereum]: "https://public-rpc.com" }, apiKeys: { blockchair: "basic-key" } }});
// Update configuration at runtime - client continues working with new configSKConfig.setRpcUrl(Chain.Ethereum, "https://premium-rpc.com");SKConfig.setApiKey("blockchair", "premium-api-key");
// Switch to testnet modeSKConfig.setEnv("isStagenet", true);
// All subsequent operations automatically use new configuration!const balance = await swapKit.getBalance(Chain.Ethereum); // Uses premium RPC
2. Individual Configuration Updates
Section titled “2. Individual Configuration Updates”Update specific parts of configuration without affecting others:
// Update API keys individuallySKConfig.setApiKey("swapKit", "your-swapkit-api-key");SKConfig.setApiKey("walletConnectProjectId", "your-wc-project-id");SKConfig.setApiKey("blockchair", "your-blockchair-key");
// Update RPC URLs for specific chainsSKConfig.setRpcUrl(Chain.Ethereum, "https://ethereum-rpc.com");SKConfig.setRpcUrl(Chain.Arbitrum, "https://arbitrum-rpc.com");SKConfig.setRpcUrl(Chain.Avalanche, "https://avalanche-rpc.com");
// Update environment settingsSKConfig.setEnv("isDev", false);SKConfig.setEnv("isStagenet", true);
// Update integration configurationsSKConfig.setIntegrationConfig("radix", { dAppDefinitionAddress: "account_rdx...", applicationName: "My DeFi App", applicationVersion: "1.0.0", network: { networkId: 1, networkName: "mainnet" }});
3. Bulk Configuration Updates
Section titled “3. Bulk Configuration Updates”Update multiple configurations at once:
// Update multiple settings simultaneouslySKConfig.set({ rpcUrls: { [Chain.Ethereum]: "https://ethereum-rpc.com", [Chain.Arbitrum]: "https://arbitrum-rpc.com", [Chain.Avalanche]: "https://avalanche-rpc.com" }, apiKeys: { blockchair: "premium-blockchair-key", swapKit: "premium-swapkit-key", walletConnectProjectId: "your-project-id" }, envs: { isStagenet: false, isDev: false }});
4. Dynamic Environment Switching
Section titled “4. Dynamic Environment Switching”Switch between mainnet and testnet without recreating client:
// Start on mainnetconst swapKit = createSwapKit();
// Switch to testnet for testingSKConfig.setEnv("isStagenet", true);SKConfig.setRpcUrl(Chain.THORChain, "https://stagenet-thornode.ninerealms.com");
// All operations now use testnetawait swapKit.connectKeystore([Chain.THORChain], phrase);const balance = await swapKit.getBalance(Chain.THORChain); // Testnet balance
// Switch back to mainnetSKConfig.setEnv("isStagenet", false);SKConfig.setRpcUrl(Chain.THORChain, "https://thornode.ninerealms.com");
5. How Toolboxes Automatically Use Updated Config
Section titled “5. How Toolboxes Automatically Use Updated Config”All toolboxes in v4 dynamically retrieve configuration from SKConfig:
// When you call this...const ethToolbox = await getEvmToolbox(Chain.Ethereum);
// Internally, it gets the RPC URL from SKConfigconst rpcUrl = SKConfig.get("rpcUrls")[Chain.Ethereum];const provider = new JsonRpcProvider(rpcUrl);
// So when you update the RPC URL...SKConfig.setRpcUrl(Chain.Ethereum, "https://new-rpc.com");
// The next toolbox instance automatically uses the new URLconst newEthToolbox = await getEvmToolbox(Chain.Ethereum); // Uses new RPC!
6. Standardized Creation Helpers
Section titled “6. Standardized Creation Helpers”createPlugin
: Streamlined plugin creation with consistent interfacecreateWallet
: Simplified wallet adapter development
7. Enhanced Chain Support
Section titled “7. Enhanced Chain Support”- Improved Solana Support: Jupiter API integration for real-time token metadata
- Dynamic Cosmos Fees: Automatic fee estimation when not provided
- Ripple Support: Full XRP toolbox implementation
- OneKey Wallet: New wallet integration
8. Configuration State Preservation
Section titled “8. Configuration State Preservation”Updates preserve existing configuration:
// Set initial API keySKConfig.setApiKey("swapKit", "key1");
// Add another API key - preserves existing onesSKConfig.setApiKey("blockchair", "key2");
// Both keys are now availableconst apiKeys = SKConfig.get("apiKeys");console.log(apiKeys.swapKit); // "key1"console.log(apiKeys.blockchair); // "key2"
Common Migration Issues
Section titled “Common Migration Issues”1. TypeScript Errors
Section titled “1. TypeScript Errors”// @errors: 2305// Error: Module '@swapkit/api' has no exported member 'SwapKitApi'
// Solution: Update importimport { SwapKitApi } from "@swapkit/sdk";
2. Missing RPC URL Parameter
Section titled “2. Missing RPC URL Parameter”// @noErrorValidation// Error: Argument of type '{ signer }' is not assignable...
// Solution: Configure via SKConfigimport { SKConfig, Chain, getEvmToolbox } from "@swapkit/sdk";
SKConfig.set({ rpcUrls: { [Chain.Ethereum]: "https://..." } });const signer = /* your signer instance */;const toolbox = getEvmToolbox(Chain.Ethereum, { signer });
3. Plugin Interface Mismatch
Section titled “3. Plugin Interface Mismatch”// @noErrorValidation// Error: Type '{ swap }' is not assignable...
// Solution: Use createPlugin helperimport { createPlugin } from "@swapkit/sdk";
const swap = async (params) => { /* implementation */ };
export const MyPlugin = createPlugin({ name: "myPlugin", methods: ({ getWallet }) => ({ swap })});
Migration Checklist
Section titled “Migration Checklist”- Update all package dependencies
- Replace all import paths
- Update client initialization code
- Configure SKConfig for RPC URLs and API keys
- Update custom plugins to use
createPlugin
- Update custom wallets to use
createWallet
- Remove direct API/RPC parameters from toolboxes
- Test all functionality thoroughly
Need Help?
Section titled “Need Help?”- 💬 Join our Discord for migration support
- 🐛 Report issues on GitHub
- 📚 Check the Getting Started guide for v4 patterns