Skip to content
SwapKit is a powerful suite of tools for building blockchain applications.

Creating a SwapKit Plugin

SwapKit plugins extend the functionality of the core library to support various DeFi protocols and services. This guide explains how to create a custom plugin for SwapKit.

A SwapKit plugin consists of the following components:

  1. A plugin factory created with createPlugin
  2. Plugin methods that interact with external services or smart contracts
  3. Integration with the SwapKit client

Here’s a simple example of creating a plugin:

import {
  class AssetValueAssetValue,
  enum ChainChain,
  class SwapKitErrorSwapKitError,
  
function createPlugin<const Name extends string, T extends (params: SwapKitPluginParams) => Record<string, unknown>, K extends {
    supportedSwapkitProviders?: (ProviderName | string)[];
}>({ name, properties, methods }: {
    name: Name;
    properties?: K;
    methods: T;
}): { [key in Name]: (pluginParams: SwapKitPluginParams) => K & ReturnType<T>; }
createPlugin
,
type type EVMChain = Chain.Arbitrum | Chain.Avalanche | Chain.Base | Chain.BinanceSmartChain | Chain.Ethereum | Chain.Optimism | Chain.PolygonEVMChain, } from "@swapkit/helpers"; type
type SwapParams = {
    route: {
        sellAsset: string;
        buyAsset: string;
        sellAmount: string;
    };
}
SwapParams
= {
route: {
    sellAsset: string;
    buyAsset: string;
    sellAmount: string;
}
route
: {
sellAsset: stringsellAsset: string; buyAsset: stringbuyAsset: string; sellAmount: stringsellAmount: string; }; }; type
type QuoteParams = {
    sellAsset: string;
    buyAsset: string;
    sellAmount: string;
}
QuoteParams
= {
sellAsset: stringsellAsset: string; buyAsset: stringbuyAsset: string; sellAmount: stringsellAmount: string; }; // Create a simple example plugin export const
const ExamplePlugin: {
    example: (pluginParams: SwapKitPluginParams) => {
        supportedSwapkitProviders: string[];
    } & {
        swap: ({ route }: SwapParams) => Promise<string>;
        getQuote: (params: QuoteParams) => Promise<...>;
    };
}
ExamplePlugin
=
createPlugin<"example", ({ getWallet }: SwapKitPluginParams) => {
    swap: ({ route }: SwapParams) => Promise<string>;
    getQuote: (params: QuoteParams) => Promise<{
        success: boolean;
        data: {};
    }>;
}, {
    ...;
}>({ name, properties, methods }: {
    ...;
}): {
    ...;
}
createPlugin
({
name: "example"name: "example",
properties?: {
    supportedSwapkitProviders: string[];
} | undefined
properties
: {
// Plugin properties/metadata supportedSwapkitProviders: string[]supportedSwapkitProviders: ["your-provider-name"], },
methods: ({ getWallet }: SwapKitPluginParams) => {
    swap: ({ route }: SwapParams) => Promise<string>;
    getQuote: (params: QuoteParams) => Promise<{
        success: boolean;
        data: {};
    }>;
}
methods
: ({ getWallet: <T extends CryptoChain>(chain: T) => FullWallet[T]getWallet }) => ({
// Define plugin methods here swap: ({ route }: SwapParams) => Promise<string>swap: async function function (local function) exampleSwap({ route }: SwapParams): Promise<string>exampleSwap({
route: {
    sellAsset: string;
    buyAsset: string;
    sellAmount: string;
}
route
}:
type SwapParams = {
    route: {
        sellAsset: string;
        buyAsset: string;
        sellAmount: string;
    };
}
SwapParams
) {
// Extract necessary data from the route const { const sellAsset: stringsellAsset, const buyAsset: stringbuyAsset, const sellAmount: stringsellAmount } =
route: {
    sellAsset: string;
    buyAsset: string;
    sellAmount: string;
}
route
;
if (!(const sellAsset: stringsellAsset && const buyAsset: stringbuyAsset)) { throw new
new SwapKitError(errorOrErrorKey: ErrorKeys | {
    errorKey: ErrorKeys;
    info?: Record<string, any>;
}, sourceErrorOrInfo?: any): SwapKitError
SwapKitError
("core_swap_asset_not_recognized");
} // Create an asset value from the sell asset const const assetValue: AssetValueassetValue = await class AssetValueAssetValue.
AssetValue.from<{
    asyncTokenLookup: true;
    asset: string;
    value: string;
}>({ value, fromBaseDecimal, asyncTokenLookup, ...fromAssetOrChain }: {
    asyncTokenLookup: true;
    asset: string;
    value: string;
} & AssetValueFromParams): Promise<AssetValue>
from
({
asyncTokenLookup: trueasyncTokenLookup: true, asset: stringasset: const sellAsset: stringsellAsset, value: stringvalue: const sellAmount: stringsellAmount, }); // Get the wallet for the source chain const
const wallet: (ChainWallet<Chain.Arbitrum> & {
    estimateTransactionFee: ({ feeOption, chain, ...txObject }: EIP1559TxParams & {
        feeOption: FeeOption;
        chain: EVMChain;
    }) => Promise<...>;
    ... 20 more ...;
    validateAddress: (address: string) => boolean;
}) | ... 5 more ... | (ChainWallet<...> & {
    ...;
})
wallet
=
getWallet: <EVMChain>(chain: EVMChain) => (ChainWallet<Chain.Arbitrum> & {
    estimateTransactionFee: ({ feeOption, chain, ...txObject }: EIP1559TxParams & {
        feeOption: FeeOption;
        chain: EVMChain;
    }) => Promise<...>;
    ... 20 more ...;
    validateAddress: (address: string) => boolean;
}) | ... 5 more ... | (ChainWallet<...> & {
    ...;
})
getWallet
(const assetValue: AssetValueassetValue.AssetValue.chain: Chainchain as type EVMChain = Chain.Arbitrum | Chain.Avalanche | Chain.Base | Chain.BinanceSmartChain | Chain.Ethereum | Chain.Optimism | Chain.PolygonEVMChain);
if (!
const wallet: (ChainWallet<Chain.Arbitrum> & {
    estimateTransactionFee: ({ feeOption, chain, ...txObject }: EIP1559TxParams & {
        feeOption: FeeOption;
        chain: EVMChain;
    }) => Promise<...>;
    ... 20 more ...;
    validateAddress: (address: string) => boolean;
}) | ... 5 more ... | (ChainWallet<...> & {
    ...;
})
wallet
) {
throw new
new SwapKitError(errorOrErrorKey: ErrorKeys | {
    errorKey: ErrorKeys;
    info?: Record<string, any>;
}, sourceErrorOrInfo?: any): SwapKitError
SwapKitError
("core_wallet_connection_not_found");
} // Custom swap logic goes here - this is where you would // connect to your DeFi protocol or service // For this example, we'll just transfer the funds to simulate a swap if ('transfer' in
const wallet: (ChainWallet<Chain.Arbitrum> & {
    estimateTransactionFee: ({ feeOption, chain, ...txObject }: EIP1559TxParams & {
        feeOption: FeeOption;
        chain: EVMChain;
    }) => Promise<...>;
    ... 20 more ...;
    validateAddress: (address: string) => boolean;
}) | ... 5 more ... | (ChainWallet<...> & {
    ...;
})
wallet
) {
const const txHash: stringtxHash = await
const wallet: (ChainWallet<Chain.Arbitrum> & {
    estimateTransactionFee: ({ feeOption, chain, ...txObject }: EIP1559TxParams & {
        feeOption: FeeOption;
        chain: EVMChain;
    }) => Promise<...>;
    ... 20 more ...;
    validateAddress: (address: string) => boolean;
}) | ... 5 more ... | (ChainWallet<...> & {
    ...;
})
wallet
.transfer: ({ assetValue, memo, recipient, feeOptionKey, sender, ...tx }: EVMTransferParams) => Promise<string>transfer({
assetValue: AssetValueassetValue, from:
const wallet: (ChainWallet<Chain.Arbitrum> & {
    estimateTransactionFee: ({ feeOption, chain, ...txObject }: EIP1559TxParams & {
        feeOption: FeeOption;
        chain: EVMChain;
    }) => Promise<...>;
    ... 20 more ...;
    validateAddress: (address: string) => boolean;
}) | ... 5 more ... | (ChainWallet<...> & {
    ...;
})
wallet
.address: stringaddress,
Object literal may only specify known properties, and 'from' does not exist in type 'EVMTransferParams'.
recipient: stringrecipient: "0x742d35Cc6634C0532925a3b844Bc454e4438f44e", // Example recipient }); return const txHash: stringtxHash; } throw new
var Error: ErrorConstructor
new (message?: string, options?: ErrorOptions) => Error (+2 overloads)
Error
("Wallet does not support transfer");
}, // Add additional methods as needed
getQuote: (params: QuoteParams) => Promise<{
    success: boolean;
    data: {};
}>
getQuote
: async function
function (local function) getExampleQuote(params: QuoteParams): Promise<{
    success: boolean;
    data: {};
}>
getExampleQuote
(params: QuoteParamsparams:
type QuoteParams = {
    sellAsset: string;
    buyAsset: string;
    sellAmount: string;
}
QuoteParams
) {
// Custom quote logic here return { // Return quote data success: booleansuccess: true, data: {}data: { // Quote details } }; }, }), });

Here’s a more realistic example of an EVM-based plugin that integrates with an exchange:


import {
  enum ApproveModeApproveMode,
  class AssetValueAssetValue,
  enum ChainChain,
  type EVMChain = Chain.Arbitrum | Chain.Avalanche | Chain.Base | Chain.BinanceSmartChain | Chain.Ethereum | Chain.Optimism | Chain.PolygonEVMChain,
  enum ProviderNameProviderName,
  class SwapKitErrorSwapKitError,
  
function createPlugin<const Name extends string, T extends (params: SwapKitPluginParams) => Record<string, unknown>, K extends {
    supportedSwapkitProviders?: (ProviderName | string)[];
}>({ name, properties, methods }: {
    name: Name;
    properties?: K;
    methods: T;
}): { [key in Name]: (pluginParams: SwapKitPluginParams) => K & ReturnType<T>; }
createPlugin
} from "@swapkit/helpers"; import {
const SwapKitApi: {
    mayachainMidgard: {
        getLiquidityPositionRaw: (address: string) => Promise<MemberDetailsMayachain>;
        getBorrowerDetailRaw: (address: string) => Promise<...>;
        ... 6 more ...;
        getLiquidityPosition: (address: string) => Promise<...>;
    };
    ... 14 more ...;
    getChainflipDepositChannel(body: BrokerDepositChannelParams): Promise<...>;
}
SwapKitApi
, type
type QuoteResponseRoute = {
    sellAsset: string;
    buyAsset: string;
    destinationAddress: string;
    providers: ProviderName[];
    sellAmount: string;
    expectedBuyAmount: string;
    expectedBuyAmountMaxSlippage: string;
    ... 12 more ...;
    estimatedTime?: {
        ...;
    } | undefined;
}
QuoteResponseRoute
} from "@swapkit/helpers/api";
// Helper function for approval handling const
const approve: ({ approveMode, getWallet }: {
    approveMode: any;
    getWallet: any;
}) => ({ assetValue }: {
    assetValue: any;
}) => Promise<any>
approve
= ({ approveMode: anyapproveMode, getWallet: anygetWallet }) =>
async function({ assetValue: anyassetValue }) { const const evmChain: EVMChainevmChain = assetValue: anyassetValue.chain as type EVMChain = Chain.Arbitrum | Chain.Avalanche | Chain.Base | Chain.BinanceSmartChain | Chain.Ethereum | Chain.Optimism | Chain.PolygonEVMChain; const const wallet: anywallet = getWallet: anygetWallet(const evmChain: EVMChainevmChain); if (!const wallet: anywallet) { throw new
new SwapKitError(errorOrErrorKey: ErrorKeys | {
    errorKey: ErrorKeys;
    info?: Record<string, any>;
}, sourceErrorOrInfo?: any): SwapKitError
SwapKitError
("core_wallet_connection_not_found");
} // Get the router contract address from your protocol const const routerAddress: "0x1234567890123456789012345678901234567890"routerAddress = "0x1234567890123456789012345678901234567890"; // Handle the approval based on the mode if (approveMode: anyapproveMode === enum ApproveModeApproveMode.function (enum member) ApproveMode.CheckOnly = "checkOnly"CheckOnly) { return const wallet: anywallet.isApproved({ amount: anyamount: assetValue: anyassetValue.getBaseValue("bigint"), assetAddress: anyassetAddress: assetValue: anyassetValue.address, from: anyfrom: const wallet: anywallet.address, spenderAddress: stringspenderAddress: const routerAddress: "0x1234567890123456789012345678901234567890"routerAddress, }); } return const wallet: anywallet.approve({ amount: anyamount: assetValue: anyassetValue.getBaseValue("bigint"), assetAddress: anyassetAddress: assetValue: anyassetValue.address, from: anyfrom: const wallet: anywallet.address, spenderAddress: stringspenderAddress: const routerAddress: "0x1234567890123456789012345678901234567890"routerAddress, }); }; // Create the exchange plugin export const
const ExchangePlugin: {
    exchange: (pluginParams: SwapKitPluginParams) => {
        supportedSwapkitProviders: any[];
    } & {
        approveAssetValue: ({ assetValue }: {
            assetValue: any;
        }) => Promise<...>;
        isAssetValueApproved: ({ assetValue }: {
            assetValue: any;
        }) => Promise<...>;
        swap: ({ route }: {
            ...;
        }) => Promise<...>;
        getQuote: ({ sellAsset, buyAsset, sellAmount, slippage, }: {
            ...;
        }) => Promise<...>;
    };
}
ExchangePlugin
=
createPlugin<"exchange", ({ getWallet }: SwapKitPluginParams) => {
    approveAssetValue: ({ assetValue }: {
        assetValue: any;
    }) => Promise<any>;
    isAssetValueApproved: ({ assetValue }: {
        assetValue: any;
    }) => Promise<any>;
    swap: ({ route }: {
        ...;
    }) => Promise<...>;
    getQuote: ({ sellAsset, buyAsset, sellAmount, slippage, }: {
        ...;
    }) => Promise<...>;
}, {
    ...;
}>({ name, properties, methods }: {
    ...;
}): {
    ...;
}
createPlugin
({
name: "exchange"name: "exchange",
properties?: {
    supportedSwapkitProviders: any[];
} | undefined
properties
: {
supportedSwapkitProviders: any[]supportedSwapkitProviders: [enum ProviderNameProviderName.CUSTOM_EXCHANGE], },
methods: ({ getWallet }: SwapKitPluginParams) => {
    approveAssetValue: ({ assetValue }: {
        assetValue: any;
    }) => Promise<any>;
    isAssetValueApproved: ({ assetValue }: {
        assetValue: any;
    }) => Promise<any>;
    swap: ({ route }: {
        ...;
    }) => Promise<...>;
    getQuote: ({ sellAsset, buyAsset, sellAmount, slippage, }: {
        ...;
    }) => Promise<...>;
}
methods
: ({ getWallet: <T extends CryptoChain>(chain: T) => FullWallet[T]getWallet }) => ({
// Approval methods
approveAssetValue: ({ assetValue }: {
    assetValue: any;
}) => Promise<any>
approveAssetValue
:
const approve: ({ approveMode, getWallet }: {
    approveMode: any;
    getWallet: any;
}) => ({ assetValue }: {
    assetValue: any;
}) => Promise<any>
approve
({ approveMode: anyapproveMode: enum ApproveModeApproveMode.function (enum member) ApproveMode.Approve = "approve"Approve, getWallet: anygetWallet }),
isAssetValueApproved: ({ assetValue }: {
    assetValue: any;
}) => Promise<any>
isAssetValueApproved
:
const approve: ({ approveMode, getWallet }: {
    approveMode: any;
    getWallet: any;
}) => ({ assetValue }: {
    assetValue: any;
}) => Promise<any>
approve
({ approveMode: anyapproveMode: enum ApproveModeApproveMode.function (enum member) ApproveMode.CheckOnly = "checkOnly"CheckOnly, getWallet: anygetWallet }),
// Swap method
swap: ({ route }: {
    route: any;
}) => Promise<string>
swap
: async function
function (local function) exchangeSwap({ route }: {
    route: any;
}): Promise<string>
exchangeSwap
({ route: anyroute }) {
const { const tx: anytx, const sellAsset: anysellAsset } = route: anyroute; if (!const tx: anytx) { throw new
new SwapKitError(errorOrErrorKey: ErrorKeys | {
    errorKey: ErrorKeys;
    info?: Record<string, any>;
}, sourceErrorOrInfo?: any): SwapKitError
SwapKitError
("core_swap_invalid_params");
} const const assetValue: AssetValueassetValue = await class AssetValueAssetValue.
AssetValue.from<{
    asset: any;
    asyncTokenLookup: true;
}>({ value, fromBaseDecimal, asyncTokenLookup, ...fromAssetOrChain }: {
    asset: any;
    asyncTokenLookup: true;
} & AssetValueFromParams): Promise<AssetValue>
from
({
asset: anyasset: const sellAsset: anysellAsset, asyncTokenLookup: trueasyncTokenLookup: true }); const const evmChain: EVMChainevmChain = const assetValue: AssetValueassetValue.AssetValue.chain: Chainchain as type EVMChain = Chain.Arbitrum | Chain.Avalanche | Chain.Base | Chain.BinanceSmartChain | Chain.Ethereum | Chain.Optimism | Chain.PolygonEVMChain; const
const wallet: (ChainWallet<Chain.Arbitrum> & {
    estimateTransactionFee: ({ feeOption, chain, ...txObject }: EIP1559TxParams & {
        feeOption: FeeOption;
        chain: EVMChain;
    }) => Promise<...>;
    ... 20 more ...;
    validateAddress: (address: string) => boolean;
}) | ... 5 more ... | (ChainWallet<...> & {
    ...;
})
wallet
=
getWallet: <EVMChain>(chain: EVMChain) => (ChainWallet<Chain.Arbitrum> & {
    estimateTransactionFee: ({ feeOption, chain, ...txObject }: EIP1559TxParams & {
        feeOption: FeeOption;
        chain: EVMChain;
    }) => Promise<...>;
    ... 20 more ...;
    validateAddress: (address: string) => boolean;
}) | ... 5 more ... | (ChainWallet<...> & {
    ...;
})
getWallet
(const evmChain: EVMChainevmChain);
if (!
const wallet: (ChainWallet<Chain.Arbitrum> & {
    estimateTransactionFee: ({ feeOption, chain, ...txObject }: EIP1559TxParams & {
        feeOption: FeeOption;
        chain: EVMChain;
    }) => Promise<...>;
    ... 20 more ...;
    validateAddress: (address: string) => boolean;
}) | ... 5 more ... | (ChainWallet<...> & {
    ...;
})
wallet
) {
throw new
new SwapKitError(errorOrErrorKey: ErrorKeys | {
    errorKey: ErrorKeys;
    info?: Record<string, any>;
}, sourceErrorOrInfo?: any): SwapKitError
SwapKitError
("core_wallet_connection_not_found");
} // Send the transaction const { const from: anyfrom, const to: anyto, const data: anydata, const value: anyvalue } = const tx: anytx; return
const wallet: (ChainWallet<Chain.Arbitrum> & {
    estimateTransactionFee: ({ feeOption, chain, ...txObject }: EIP1559TxParams & {
        feeOption: FeeOption;
        chain: EVMChain;
    }) => Promise<...>;
    ... 20 more ...;
    validateAddress: (address: string) => boolean;
}) | ... 5 more ... | (ChainWallet<...> & {
    ...;
})
wallet
.
sendTransaction: ({ feeOptionKey, ...tx }: EVMTxParams & {
    feeOptionKey?: FeeOption;
}) => Promise<string>
sendTransaction
({
from?: string | undefinedfrom, to?: string | undefinedto, data?: string | undefineddata, value?: bigint | undefinedvalue:
var BigInt: BigIntConstructor
(value: bigint | boolean | number | string) => bigint
BigInt
(const value: anyvalue || 0)
}); }, // Get a quote from the exchange
getQuote: ({ sellAsset, buyAsset, sellAmount, slippage, }: {
    sellAsset: any;
    buyAsset: any;
    sellAmount: any;
    slippage?: number | undefined;
}) => Promise<{
    success: boolean;
    data: {
        routes: {
            sellAsset: string;
            buyAsset: string;
            destinationAddress: string;
            ... 16 more ...;
            estimatedTime?: {
                ...;
            } | undefined;
        }[];
    };
    error?: undefined;
} | {
    ...;
}>
getQuote
: async function
function (local function) getExchangeQuote({ sellAsset, buyAsset, sellAmount, slippage, }: {
    sellAsset: any;
    buyAsset: any;
    sellAmount: any;
    slippage?: number | undefined;
}): Promise<{
    success: boolean;
    data: {
        routes: {
            sellAsset: string;
            buyAsset: string;
            destinationAddress: string;
            ... 16 more ...;
            estimatedTime?: {
                ...;
            } | undefined;
        }[];
    };
    error?: undefined;
} | {
    ...;
}>
getExchangeQuote
({
sellAsset: anysellAsset, buyAsset: anybuyAsset, sellAmount: anysellAmount, slippage: numberslippage = 1, // 1% default slippage }) { try { // Call your exchange API to get a quote const const response: Responseresponse = await function fetch(input: string | URL | globalThis.Request, init?: RequestInit): Promise<Response> (+3 overloads)
[MDN Reference](https://developer.mozilla.org/docs/Web/API/Window/fetch)
fetch
("https://api.your-exchange.com/quote", {
RequestInit.method?: string | undefined
A string to set request's method.
method
: "POST",
RequestInit.headers?: HeadersInit | undefined
A Headers object, an object literal, or an array of two-item arrays to set request's headers.
headers
: { "Content-Type": "application/json" },
RequestInit.body?: BodyInit | null | undefined
A BodyInit object or null to set request's body.
body
: var JSON: JSON
An intrinsic object that provides functions to convert JavaScript values to and from the JavaScript Object Notation (JSON) format.
JSON
.JSON.stringify(value: any, replacer?: (this: any, key: string, value: any) => any, space?: string | number): string (+1 overload)
Converts a JavaScript value to a JavaScript Object Notation (JSON) string.
@paramvalue A JavaScript value, usually an object or array, to be converted.@paramreplacer A function that transforms the results.@paramspace Adds indentation, white space, and line break characters to the return-value JSON text to make it easier to read.
stringify
({
sellAsset: anysellAsset, buyAsset: anybuyAsset, sellAmount: anysellAmount, slippage: numberslippage, }), }); if (!const response: Responseresponse.Response.ok: boolean
[MDN Reference](https://developer.mozilla.org/docs/Web/API/Response/ok)
ok
) {
throw new
var Error: ErrorConstructor
new (message?: string, options?: ErrorOptions) => Error (+2 overloads)
Error
(`API error: ${const response: Responseresponse.Response.status: number
[MDN Reference](https://developer.mozilla.org/docs/Web/API/Response/status)
status
}`);
} const const quoteData: anyquoteData = await const response: Responseresponse.Body.json(): Promise<any> (+1 overload)
[MDN Reference](https://developer.mozilla.org/docs/Web/API/Request/json)
json
();
// Format the response to match SwapKit's expected format return { success: booleansuccess: true,
data: {
    routes: {
        sellAsset: string;
        buyAsset: string;
        destinationAddress: string;
        providers: ProviderName[];
        sellAmount: string;
        expectedBuyAmount: string;
        expectedBuyAmountMaxSlippage: string;
        ... 12 more ...;
        estimatedTime?: {
            ...;
        } | undefined;
    }[];
}
data
: {
routes: {
    sellAsset: string;
    buyAsset: string;
    destinationAddress: string;
    providers: ProviderName[];
    sellAmount: string;
    expectedBuyAmount: string;
    expectedBuyAmountMaxSlippage: string;
    ... 12 more ...;
    estimatedTime?: {
        ...;
    } | undefined;
}[]
routes
: [
{ sellAsset: stringsellAsset, buyAsset: stringbuyAsset, sellAmount: stringsellAmount, buyAmount: anybuyAmount: const quoteData: anyquoteData.buyAmount, // Include the transaction data needed for the swap
tx?: string | {
    value: string;
    to: string;
    from: string;
    data: string;
} | {
    memo: string;
    accountNumber: number;
    sequence: number;
    chainId: ChainId;
    msgs: {
        typeUrl: string;
        value?: unknown;
    }[];
    fee: {
        amount: {
            ...;
        }[];
        gas: string;
    };
} | undefined
tx
: {
from: stringfrom: const quoteData: anyquoteData.from, to: stringto: const quoteData: anyquoteData.to, data: stringdata: const quoteData: anyquoteData.data, value: stringvalue: const quoteData: anyquoteData.value, }, providers: ProviderName[]providers: [enum ProviderNameProviderName.CUSTOM_EXCHANGE], } as
type QuoteResponseRoute = {
    sellAsset: string;
    buyAsset: string;
    destinationAddress: string;
    providers: ProviderName[];
    sellAmount: string;
    expectedBuyAmount: string;
    expectedBuyAmountMaxSlippage: string;
    ... 12 more ...;
    estimatedTime?: {
        ...;
    } | undefined;
}
QuoteResponseRoute
,
], }, }; } catch (function (local var) error: unknownerror) { return { success: booleansuccess: false, error: stringerror:
var String: StringConstructor
(value?: any) => string
Allows manipulation and formatting of text strings and determination and location of substrings within strings.
String
(function (local var) error: unknownerror),
}; } }, }), });

Once you’ve created your plugin, you can use it with the SwapKit client:

import { 
function SwapKit<Plugins extends ReturnType<typeof createPlugin>, Wallets extends ReturnType<typeof createWallet>>({ config, plugins, wallets, }?: {
    config?: SKConfigState;
    plugins?: Plugins;
    wallets?: Wallets;
}): { [key in keyof Plugins]: ReturnType<...>; } & ... 1 more ... & {
    ...;
}
SwapKit
, enum ChainChain } from "@swapkit/core";
import {
const keystoreWallet: {
    connectKeystore: {
        connectWallet: (connectParams: {
            addChain: AddChainType;
        }) => (chains: Chain[], phrase: string, derivationPathMapOrIndex?: number | {
            ARB?: DerivationPathArray | undefined;
            ... 21 more ...;
            SOL?: DerivationPathArray | undefined;
        } | undefined) => Promise<boolean>;
        supportedChains: (Chain.Arbitrum | ... 18 more ... | Chain.Solana)[];
    };
}
keystoreWallet
} from "@swapkit/wallets/keystore";
// @ts-ignore import { import ExamplePluginExamplePlugin } from "./example-plugin"; // Initialize SwapKit with your plugin const
const swapKit: {
    examplePlugin: any;
} & {
    connectKeystore: (chains: Chain[], phrase: string, derivationPathMapOrIndex?: number | {
        ARB?: DerivationPathArray | undefined;
        AVAX?: DerivationPathArray | undefined;
        ... 20 more ...;
        SOL?: DerivationPathArray | undefined;
    } | undefined) => Promise<boolean>;
} & {
    ...;
}
swapKit
=
SwapKit<{
    examplePlugin: any;
}, {
    connectKeystore: {
        connectWallet: (connectParams: {
            addChain: AddChainType;
        }) => (chains: Chain[], phrase: string, derivationPathMapOrIndex?: number | {
            ...;
        } | undefined) => Promise<boolean>;
        supportedChains: (Chain.Arbitrum | ... 18 more ... | Chain.Solana)[];
    };
}>({ config, plugins, wallets, }?: {
    ...;
}): {
    ...;
} & ... 1 more ... & {
    ...;
}
SwapKit
({
plugins?: {
    examplePlugin: any;
} | undefined
plugins
: { examplePlugin: anyexamplePlugin: import ExamplePluginExamplePlugin },
wallets?: {
    connectKeystore: {
        connectWallet: (connectParams: {
            addChain: AddChainType;
        }) => (chains: Chain[], phrase: string, derivationPathMapOrIndex?: number | {
            ARB?: DerivationPathArray | undefined;
            ... 21 more ...;
            SOL?: DerivationPathArray | undefined;
        } | undefined) => Promise<boolean>;
        supportedChains: (Chain.Arbitrum | ... 18 more ... | Chain.Solana)[];
    };
} | undefined
wallets
: { ...
const keystoreWallet: {
    connectKeystore: {
        connectWallet: (connectParams: {
            addChain: AddChainType;
        }) => (chains: Chain[], phrase: string, derivationPathMapOrIndex?: number | {
            ARB?: DerivationPathArray | undefined;
            ... 21 more ...;
            SOL?: DerivationPathArray | undefined;
        } | undefined) => Promise<boolean>;
        supportedChains: (Chain.Arbitrum | ... 18 more ... | Chain.Solana)[];
    };
}
keystoreWallet
},
}); // Connect a wallet async function function connectAndUsePlugin(): Promise<void>connectAndUsePlugin() { // Connect a wallet first await
const swapKit: {
    examplePlugin: any;
} & {
    connectKeystore: (chains: Chain[], phrase: string, derivationPathMapOrIndex?: number | {
        ARB?: DerivationPathArray | undefined;
        AVAX?: DerivationPathArray | undefined;
        ... 20 more ...;
        SOL?: DerivationPathArray | undefined;
    } | undefined) => Promise<boolean>;
} & {
    ...;
}
swapKit
.
connectKeystore: (chains: Chain[], phrase: string, derivationPathMapOrIndex?: number | {
    ARB?: DerivationPathArray | undefined;
    AVAX?: DerivationPathArray | undefined;
    ... 20 more ...;
    SOL?: DerivationPathArray | undefined;
} | undefined) => Promise<boolean>
connectKeystore
(
[enum ChainChain.function (enum member) Chain.Bitcoin = "BTC"Bitcoin, enum ChainChain.function (enum member) Chain.Ethereum = "ETH"Ethereum], // Chains to connect "your secret phrase here" ); // Get a quote from your plugin const const quoteResponse: anyquoteResponse = await
const swapKit: {
    examplePlugin: any;
} & {
    connectKeystore: (chains: Chain[], phrase: string, derivationPathMapOrIndex?: number | {
        ARB?: DerivationPathArray | undefined;
        AVAX?: DerivationPathArray | undefined;
        ... 20 more ...;
        SOL?: DerivationPathArray | undefined;
    } | undefined) => Promise<boolean>;
} & {
    ...;
}
swapKit
.examplePlugin: anyexamplePlugin.getQuote({
sellAsset: stringsellAsset: "ETH.ETH", buyAsset: stringbuyAsset: "ETH.USDC-0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48", sellAmount: stringsellAmount: "0.1", }); if (const quoteResponse: anyquoteResponse.success) { // Execute the swap using the first route from the quote const const txHash: anytxHash = await
const swapKit: {
    examplePlugin: any;
} & {
    connectKeystore: (chains: Chain[], phrase: string, derivationPathMapOrIndex?: number | {
        ARB?: DerivationPathArray | undefined;
        AVAX?: DerivationPathArray | undefined;
        ... 20 more ...;
        SOL?: DerivationPathArray | undefined;
    } | undefined) => Promise<boolean>;
} & {
    ...;
}
swapKit
.
swap: <"examplePlugin">({ route, pluginName, ...rest }: SwapParams<"examplePlugin", {
    providers: ProviderName[];
    sellAsset: string;
    sellAmount: string;
    buyAsset: string;
    expectedBuyAmount: string;
    expectedBuyAmountMaxSlippage: string;
    ... 13 more ...;
    estimatedTime?: {
        ...;
    } | undefined;
}>) => any
swap
({
route: {
    providers: ProviderName[];
    sellAsset: string;
    sellAmount: string;
    buyAsset: string;
    expectedBuyAmount: string;
    expectedBuyAmountMaxSlippage: string;
    sourceAddress: string;
    ... 12 more ...;
    estimatedTime?: {
        ...;
    } | undefined;
}
route
: const quoteResponse: anyquoteResponse.data.routes[0] });
} }

When creating a SwapKit plugin, follow these best practices:

  1. Error Handling: Use SwapKitError for consistent error reporting
  2. Type Safety: Leverage TypeScript to provide proper type definitions
  3. Documentation: Document your plugin methods and parameters
  4. Testing: Create comprehensive tests for all functionality
  5. Validation: Validate inputs to prevent runtime errors
  6. Security: Be careful with sensitive data and external API calls

By following this guide, you should be able to create, test, and integrate custom plugins with SwapKit.