Advanced Features
This guide covers advanced SwapKit features for building sophisticated DeFi applications.
Multi-Chain Operations
Section titled “Multi-Chain Operations”SwapKit excels at coordinating operations across multiple blockchains simultaneously.
Batch Balance Fetching
Section titled “Batch Balance Fetching”Fetch balances across all connected chains efficiently:
import { function createSwapKit(config?: Parameters<typeof SwapKit>[0]): {
chainflip: {
supportedSwapkitProviders: ProviderName[];
} & {
swap: (swapParams: RequestSwapDepositAddressParams) => Promise<...>;
};
... 5 more ...;
near: {
...;
} & {
...;
};
} & {
...;
} & {
...;
}
createSwapKit, enum Chain
Chain } from '@swapkit/sdk';
import { const SwapKitApi: {
mayachainMidgard: {
getLiquidityPositionRaw: (address: string) => Promise<MemberDetailsMayachain>;
getNameDetails: (name: string) => Promise<THORNameDetails>;
getNamesByAddress: (address: string) => Promise<...>;
getNamesByOwner: (address: string) => Promise<...>;
getLiquidityPosition: (address: string) => Promise<...>;
};
... 14 more ...;
getChainflipDepositChannel(body: BrokerDepositChannelParams): Promise<...>;
}
SwapKitApi } from '@swapkit/helpers/api';
const const swapKit: {
chainflip: {
supportedSwapkitProviders: ProviderName[];
} & {
swap: (swapParams: RequestSwapDepositAddressParams) => Promise<...>;
};
... 5 more ...;
near: {
...;
} & {
...;
};
} & {
...;
} & {
...;
}
swapKit = function createSwapKit(config?: Parameters<typeof SwapKit>[0]): {
chainflip: {
supportedSwapkitProviders: ProviderName[];
} & {
swap: (swapParams: RequestSwapDepositAddressParams) => Promise<...>;
};
... 5 more ...;
near: {
...;
} & {
...;
};
} & {
...;
} & {
...;
}
createSwapKit();
// Connect multiple chains
await const swapKit: {
chainflip: {
supportedSwapkitProviders: ProviderName[];
} & {
swap: (swapParams: RequestSwapDepositAddressParams) => Promise<...>;
};
... 5 more ...;
near: {
...;
} & {
...;
};
} & {
...;
} & {
...;
}
swapKit.connectKeystore: (chains: Chain[], phrase: string, derivationPathMapOrIndex?: number | {
ARB?: DerivationPathArray | undefined;
AVAX?: DerivationPathArray | undefined;
... 21 more ...;
TRX?: DerivationPathArray | undefined;
} | undefined) => Promise<boolean>
connectKeystore(
[enum Chain
Chain.function (enum member) Chain.Ethereum = "ETH"
Ethereum, enum Chain
Chain.function (enum member) Chain.Bitcoin = "BTC"
Bitcoin, enum Chain
Chain.function (enum member) Chain.Avalanche = "AVAX"
Avalanche, enum Chain
Chain.function (enum member) Chain.THORChain = "THOR"
THORChain],
'your mnemonic phrase'
);
// Get all balances in parallel
const const chains: Chain[]
chains = [enum Chain
Chain.function (enum member) Chain.Ethereum = "ETH"
Ethereum, enum Chain
Chain.function (enum member) Chain.Bitcoin = "BTC"
Bitcoin, enum Chain
Chain.function (enum member) Chain.Avalanche = "AVAX"
Avalanche, enum Chain
Chain.function (enum member) Chain.THORChain = "THOR"
THORChain];
const const balances: AssetValue[][]
balances = await var Promise: PromiseConstructor
Represents the completion of an asynchronous operationPromise.PromiseConstructor.all<Promise<AssetValue[]>[]>(values: Promise<AssetValue[]>[]): Promise<AssetValue[][]> (+1 overload)
Creates a Promise that is resolved with an array of results when all of the provided Promises
resolve, or rejected when any Promise is rejected.all(
const chains: Chain[]
chains.Array<Chain>.map<Promise<AssetValue[]>>(callbackfn: (value: Chain, index: number, array: Chain[]) => Promise<AssetValue[]>, thisArg?: any): Promise<...>[]
Calls a defined callback function on each element of an array, and returns an array that contains the results.map(chain: Chain
chain => const swapKit: {
chainflip: {
supportedSwapkitProviders: ProviderName[];
} & {
swap: (swapParams: RequestSwapDepositAddressParams) => Promise<...>;
};
... 5 more ...;
near: {
...;
} & {
...;
};
} & {
...;
} & {
...;
}
swapKit.getBalance: <Chain, true>(chain: Chain, refresh?: true | undefined) => Promise<AssetValue[]>
getBalance(chain: Chain
chain, true))
);
// Flatten and filter significant balances
const const allAssets: AssetValue[]
allAssets = const balances: AssetValue[][]
balances
.Array<AssetValue[]>.flat<AssetValue[][], 1>(this: AssetValue[][], depth?: 1 | undefined): AssetValue[]
Returns a new array with all sub-array elements concatenated into it recursively up to the
specified depth.flat()
.Array<AssetValue>.filter(predicate: (value: AssetValue, index: number, array: AssetValue[]) => unknown, thisArg?: any): AssetValue[] (+1 overload)
Returns the elements of an array that meet the condition specified in a callback function.filter(asset: AssetValue
asset => asset: AssetValue
asset.BigIntArithmetics.getValue<"number">(type: "number", decimal?: number): number
getValue('number') > 0.01);
// Calculate total USD value
const const priceData: {
provider?: string | undefined;
identifier?: string | undefined;
timestamp?: number | undefined;
cg?: {
name: string;
id: string;
market_cap: number;
price_change_24h_usd: number;
price_change_percentage_24h_usd: number;
sparkline_in_7d: number[];
timestamp: string;
total_volume: number;
} | undefined;
price_usd?: number | undefined;
}[]
priceData = await const SwapKitApi: {
mayachainMidgard: {
getLiquidityPositionRaw: (address: string) => Promise<MemberDetailsMayachain>;
getNameDetails: (name: string) => Promise<THORNameDetails>;
getNamesByAddress: (address: string) => Promise<...>;
getNamesByOwner: (address: string) => Promise<...>;
getLiquidityPosition: (address: string) => Promise<...>;
};
... 14 more ...;
getChainflipDepositChannel(body: BrokerDepositChannelParams): Promise<...>;
}
SwapKitApi.function getPrice(body: PriceRequest): Promise<{
provider?: string | undefined;
identifier?: string | undefined;
timestamp?: number | undefined;
cg?: {
name: string;
id: string;
... 5 more ...;
total_volume: number;
} | undefined;
price_usd?: number | undefined;
}[]>
getPrice({
tokens: {
identifier: string;
}[]
tokens: const allAssets: AssetValue[]
allAssets.Array<AssetValue>.map<{
identifier: string;
}>(callbackfn: (value: AssetValue, index: number, array: AssetValue[]) => {
identifier: string;
}, thisArg?: any): {
identifier: string;
}[]
Calls a defined callback function on each element of an array, and returns an array that contains the results.map(a: AssetValue
a => ({ identifier: string
identifier: a: AssetValue
a.AssetValue.toString({ includeSynthProtocol }?: {
includeSynthProtocol?: boolean;
}): string
Returns a string representation of an object.toString() })),
metadata: boolean
metadata: false
});
// Convert array response to a map for easier lookup
const const prices: Record<string, number>
prices = const priceData: {
provider?: string | undefined;
identifier?: string | undefined;
timestamp?: number | undefined;
cg?: {
name: string;
id: string;
market_cap: number;
price_change_24h_usd: number;
price_change_percentage_24h_usd: number;
sparkline_in_7d: number[];
timestamp: string;
total_volume: number;
} | undefined;
price_usd?: number | undefined;
}[]
priceData.Array<{ provider?: string | undefined; identifier?: string | undefined; timestamp?: number | undefined; cg?: { name: string; id: string; market_cap: number; price_change_24h_usd: number; price_change_percentage_24h_usd: number; sparkline_in_7d: number[]; timestamp: string; total_volume: number; } | undefined; price_usd?: number | undefined; }>.reduce<Record<string, number>>(callbackfn: (previousValue: Record<string, number>, currentValue: {
provider?: string | undefined;
identifier?: string | undefined;
timestamp?: number | undefined;
cg?: {
...;
} | undefined;
price_usd?: number | undefined;
}, currentIndex: number, array: {
provider?: string | undefined;
identifier?: string | undefined;
timestamp?: number | undefined;
cg?: {
...;
} | undefined;
price_usd?: number | undefined;
}[]) => Record<...>, initialValue: Record<...>): Record<...> (+2 overloads)
Calls the specified callback function for all the elements in an array. The return value of the callback function is the accumulated result, and is provided as an argument in the next call to the callback function.reduce((acc: Record<string, number>
acc, item: {
provider?: string | undefined;
identifier?: string | undefined;
timestamp?: number | undefined;
cg?: {
name: string;
id: string;
market_cap: number;
price_change_24h_usd: number;
price_change_percentage_24h_usd: number;
sparkline_in_7d: number[];
timestamp: string;
total_volume: number;
} | undefined;
price_usd?: number | undefined;
}
item) => {
if (item: {
provider?: string | undefined;
identifier?: string | undefined;
timestamp?: number | undefined;
cg?: {
name: string;
id: string;
market_cap: number;
price_change_24h_usd: number;
price_change_percentage_24h_usd: number;
sparkline_in_7d: number[];
timestamp: string;
total_volume: number;
} | undefined;
price_usd?: number | undefined;
}
item.identifier?: string | undefined
identifier && item: {
provider?: string | undefined;
identifier?: string | undefined;
timestamp?: number | undefined;
cg?: {
name: string;
id: string;
market_cap: number;
price_change_24h_usd: number;
price_change_percentage_24h_usd: number;
sparkline_in_7d: number[];
timestamp: string;
total_volume: number;
} | undefined;
price_usd?: number | undefined;
}
item.price_usd?: number | undefined
price_usd) {
acc: Record<string, number>
acc[item: {
provider?: string | undefined;
identifier?: string | undefined;
timestamp?: number | undefined;
cg?: {
name: string;
id: string;
market_cap: number;
price_change_24h_usd: number;
price_change_percentage_24h_usd: number;
sparkline_in_7d: number[];
timestamp: string;
total_volume: number;
} | undefined;
price_usd?: number | undefined;
}
item.identifier?: string
identifier] = item: {
provider?: string | undefined;
identifier?: string | undefined;
timestamp?: number | undefined;
cg?: {
name: string;
id: string;
market_cap: number;
price_change_24h_usd: number;
price_change_percentage_24h_usd: number;
sparkline_in_7d: number[];
timestamp: string;
total_volume: number;
} | undefined;
price_usd?: number | undefined;
}
item.price_usd?: number
price_usd;
}
return acc: Record<string, number>
acc;
}, {} as type Record<K extends keyof any, T> = { [P in K]: T; }
Construct a type with a set of properties K of type TRecord<string, number>);
const const totalValue: number
totalValue = const allAssets: AssetValue[]
allAssets.Array<AssetValue>.reduce<number>(callbackfn: (previousValue: number, currentValue: AssetValue, currentIndex: number, array: AssetValue[]) => number, initialValue: number): number (+2 overloads)
Calls the specified callback function for all the elements in an array. The return value of the callback function is the accumulated result, and is provided as an argument in the next call to the callback function.reduce((sum: number
sum, asset: AssetValue
asset) => {
const const price: number
price = const prices: Record<string, number>
prices[asset: AssetValue
asset.AssetValue.toString({ includeSynthProtocol }?: {
includeSynthProtocol?: boolean;
}): string
Returns a string representation of an object.toString()] || 0;
return sum: number
sum + (asset: AssetValue
asset.BigIntArithmetics.getValue<"number">(type: "number", decimal?: number): number
getValue('number') * const price: number
price);
}, 0);
Cross-Chain Transaction Batching
Section titled “Cross-Chain Transaction Batching”Execute multiple transactions across different chains:
import { class AssetValue
AssetValue, enum FeeOption
FeeOption } from '@swapkit/sdk';
// Prepare multiple transactions
const const transactions: {
chain: any;
assetValue: AssetValue;
recipient: string;
}[]
transactions = [
{
chain: any
chain: Cannot find name 'Chain'. Did you mean 'Chai'?Chain.Ethereum,
assetValue: AssetValue
assetValue: class AssetValue
AssetValue.AssetValue.from<{
asset: "ETH.ETH";
value: number;
}>({ value, fromBaseDecimal, asyncTokenLookup, ...fromAssetOrChain }: {
asset: "ETH.ETH";
value: number;
} & AssetValueFromParams): AssetValue
from({ asset: "ETH.ETH"
asset: 'ETH.ETH', value: number
value: 0.1 }),
recipient: string
recipient: '0x...'
},
{
chain: any
chain: Cannot find name 'Chain'. Did you mean 'Chai'?Chain.Bitcoin,
assetValue: AssetValue
assetValue: class AssetValue
AssetValue.AssetValue.from<{
asset: "BTC.BTC";
value: number;
}>({ value, fromBaseDecimal, asyncTokenLookup, ...fromAssetOrChain }: {
asset: "BTC.BTC";
value: number;
} & AssetValueFromParams): AssetValue
from({ asset: "BTC.BTC"
asset: 'BTC.BTC', value: number
value: 0.001 }),
recipient: string
recipient: 'bc1q...'
},
{
chain: any
chain: Cannot find name 'Chain'. Did you mean 'Chai'?Chain.Avalanche,
assetValue: AssetValue
assetValue: class AssetValue
AssetValue.AssetValue.from<{
asset: string;
value: number;
}>({ value, fromBaseDecimal, asyncTokenLookup, ...fromAssetOrChain }: {
asset: string;
value: number;
} & AssetValueFromParams): AssetValue
from({ asset: string
asset: 'AVAX.AVAX', value: number
value: 1 }),
recipient: string
recipient: '0x...'
}
];
// Execute all transactions
const const results: PromiseSettledResult<any>[]
results = await var Promise: PromiseConstructor
Represents the completion of an asynchronous operationPromise.PromiseConstructor.allSettled<any[]>(values: any[]): Promise<PromiseSettledResult<any>[]> (+1 overload)
Creates a Promise that is resolved with an array of results when all
of the provided Promises resolve or reject.allSettled(
const transactions: {
chain: any;
assetValue: AssetValue;
recipient: string;
}[]
transactions.Array<{ chain: any; assetValue: AssetValue; recipient: string; }>.map<any>(callbackfn: (value: {
chain: any;
assetValue: AssetValue;
recipient: string;
}, index: number, array: {
chain: any;
assetValue: AssetValue;
recipient: string;
}[]) => any, thisArg?: any): any[]
Calls a defined callback function on each element of an array, and returns an array that contains the results.map(tx: {
chain: any;
assetValue: AssetValue;
recipient: string;
}
tx =>
Cannot find name 'swapKit'.swapKit.transfer({
...tx: {
chain: any;
assetValue: AssetValue;
recipient: string;
}
tx,
feeOptionKey: FeeOption
feeOptionKey: enum FeeOption
FeeOption.function (enum member) FeeOption.Fast = "fast"
Fast
})
)
);
// Handle results
const results: PromiseSettledResult<any>[]
results.Array<PromiseSettledResult<any>>.forEach(callbackfn: (value: PromiseSettledResult<any>, index: number, array: PromiseSettledResult<any>[]) => void, thisArg?: any): void
Performs the specified action for each element in an array.forEach((result: PromiseSettledResult<any>
result, index: number
index) => {
if (result: PromiseSettledResult<any>
result.status: "rejected" | "fulfilled"
status === 'fulfilled') {
console.Console.log(message?: any, ...optionalParams: any[]): void (+3 overloads)
Prints to `stdout` with newline. Multiple arguments can be passed, with the
first used as the primary message and all additional used as substitution
values similar to [`printf(3)`](http://man7.org/linux/man-pages/man3/printf.3.html)
(the arguments are all passed to [`util.format()`](https://nodejs.org/docs/latest-v24.x/api/util.html#utilformatformat-args)).
```js
const count = 5;
console.log('count: %d', count);
// Prints: count: 5, to stdout
console.log('count:', count);
// Prints: count: 5, to stdout
```
See [`util.format()`](https://nodejs.org/docs/latest-v24.x/api/util.html#utilformatformat-args) for more information.log(`${const transactions: {
chain: any;
assetValue: AssetValue;
recipient: string;
}[]
transactions[index: number
index].chain: any
chain} tx: ${result: PromiseFulfilledResult<any>
result.PromiseFulfilledResult<any>.value: any
value}`);
} else {
console.Console.error(message?: any, ...optionalParams: any[]): void (+3 overloads)
Prints to `stderr` with newline. Multiple arguments can be passed, with the
first used as the primary message and all additional used as substitution
values similar to [`printf(3)`](http://man7.org/linux/man-pages/man3/printf.3.html)
(the arguments are all passed to [`util.format()`](https://nodejs.org/docs/latest-v24.x/api/util.html#utilformatformat-args)).
```js
const code = 5;
console.error('error #%d', code);
// Prints: error #5, to stderr
console.error('error', code);
// Prints: error 5, to stderr
```
If formatting elements (e.g. `%d`) are not found in the first string then
[`util.inspect()`](https://nodejs.org/docs/latest-v24.x/api/util.html#utilinspectobject-options) is called on each argument and the
resulting string values are concatenated. See [`util.format()`](https://nodejs.org/docs/latest-v24.x/api/util.html#utilformatformat-args)
for more information.error(`${const transactions: {
chain: any;
assetValue: AssetValue;
recipient: string;
}[]
transactions[index: number
index].chain: any
chain} failed:`, result: PromiseRejectedResult
result.PromiseRejectedResult.reason: any
reason);
}
});
Synthetic Assets
Section titled “Synthetic Assets”THORChain synthetic assets provide instant swaps without waiting for L1 confirmations.
Understanding Synthetics
Section titled “Understanding Synthetics”Synthetic assets are represented with /
notation:
BTC/BTC
- Synthetic BitcoinETH/ETH
- Synthetic EthereumAVAX/AVAX
- Synthetic Avalanche
Minting Synthetics
Section titled “Minting Synthetics”Convert L1 assets to synthetics for faster swaps:
import { const SwapKitApi: {
mayachainMidgard: {
getLiquidityPositionRaw: (address: string) => Promise<MemberDetailsMayachain>;
getNameDetails: (name: string) => Promise<THORNameDetails>;
getNamesByAddress: (address: string) => Promise<...>;
getNamesByOwner: (address: string) => Promise<...>;
getLiquidityPosition: (address: string) => Promise<...>;
};
... 14 more ...;
getChainflipDepositChannel(body: BrokerDepositChannelParams): Promise<...>;
}
SwapKitApi } from '@swapkit/helpers/api';
// Get quote for minting synthetic BTC
const const mintQuote: {
quoteId: string;
routes: {
sellAsset: string;
buyAsset: string;
destinationAddress: string;
providers: ProviderName[];
sellAmount: string;
expectedBuyAmount: string;
expectedBuyAmountMaxSlippage: string;
... 12 more ...;
estimatedTime?: {
...;
} | undefined;
}[];
error?: string | undefined;
providerErrors?: {
...;
}[] | undefined;
}
mintQuote = await const SwapKitApi: {
mayachainMidgard: {
getLiquidityPositionRaw: (address: string) => Promise<MemberDetailsMayachain>;
getNameDetails: (name: string) => Promise<THORNameDetails>;
getNamesByAddress: (address: string) => Promise<...>;
getNamesByOwner: (address: string) => Promise<...>;
getLiquidityPosition: (address: string) => Promise<...>;
};
... 14 more ...;
getChainflipDepositChannel(body: BrokerDepositChannelParams): Promise<...>;
}
SwapKitApi.function getSwapQuote(json: QuoteRequest): Promise<{
quoteId: string;
routes: {
sellAsset: string;
buyAsset: string;
destinationAddress: string;
providers: ProviderName[];
... 15 more ...;
estimatedTime?: {
...;
} | undefined;
}[];
error?: string | undefined;
providerErrors?: {
...;
}[] | undefined;
}>
getSwapQuote({
sellAsset: string
sellAsset: 'BTC.BTC',
sellAmount: string
sellAmount: '10000000', // 0.1 BTC
buyAsset: string
buyAsset: 'BTC/BTC', // Synthetic BTC
sourceAddress?: string | undefined
sourceAddress: Cannot find name 'swapKit'.swapKitCannot find name 'Chain'. Did you mean 'Chai'?.getAddress(Chain.Bitcoin),
destinationAddress?: string | undefined
destinationAddress: Cannot find name 'swapKit'.swapKitCannot find name 'Chain'. Did you mean 'Chai'?.getAddress(Chain.THORChain),
slippage?: number | undefined
slippage: 3
});
// Execute mint
const const mintTx: any
mintTx = await Cannot find name 'swapKit'.swapKit.swap({
route: {
sellAsset: string;
buyAsset: string;
destinationAddress: string;
providers: ProviderName[];
sellAmount: string;
expectedBuyAmount: string;
expectedBuyAmountMaxSlippage: string;
... 12 more ...;
estimatedTime?: {
...;
} | undefined;
}
route: const mintQuote: {
quoteId: string;
routes: {
sellAsset: string;
buyAsset: string;
destinationAddress: string;
providers: ProviderName[];
sellAmount: string;
expectedBuyAmount: string;
expectedBuyAmountMaxSlippage: string;
... 12 more ...;
estimatedTime?: {
...;
} | undefined;
}[];
error?: string | undefined;
providerErrors?: {
...;
}[] | undefined;
}
mintQuote.routes: {
sellAsset: string;
buyAsset: string;
destinationAddress: string;
providers: ProviderName[];
sellAmount: string;
expectedBuyAmount: string;
expectedBuyAmountMaxSlippage: string;
... 12 more ...;
estimatedTime?: {
...;
} | undefined;
}[]
routes[0]
});
Synth Swaps
Section titled “Synth Swaps”Swap between synthetics instantly:
// Instant swap between synthetics (no L1 wait)
const const synthSwapQuote: any
synthSwapQuote = await Cannot find name 'SwapKitApi'.SwapKitApi.getSwapQuote({
sellAsset: string
sellAsset: 'BTC/BTC', // Synthetic BTC
sellAmount: string
sellAmount: '10000000',
buyAsset: string
buyAsset: 'ETH/ETH', // Synthetic ETH
sourceAddress: any
sourceAddress: Cannot find name 'swapKit'.swapKitCannot find name 'Chain'. Did you mean 'Chai'?.getAddress(Chain.THORChain),
destinationAddress: any
destinationAddress: Cannot find name 'swapKit'.swapKitCannot find name 'Chain'. Did you mean 'Chai'?.getAddress(Chain.THORChain),
slippage: number
slippage: 1 // Lower slippage for synth swaps
});
// This swap is instant!
const const swapTx: any
swapTx = await Cannot find name 'swapKit'.swapKit.swap({
route: any
route: const synthSwapQuote: any
synthSwapQuote.routes[0]
});
Redeeming Synthetics
Section titled “Redeeming Synthetics”Convert synthetics back to L1 assets:
// Redeem synthetic ETH to real ETH
const const redeemQuote: any
redeemQuote = await Cannot find name 'SwapKitApi'.SwapKitApi.getSwapQuote({
sellAsset: string
sellAsset: 'ETH/ETH', // Synthetic ETH
sellAmount: string
sellAmount: '1000000000000000000',
buyAsset: string
buyAsset: 'ETH.ETH', // L1 ETH
sourceAddress: any
sourceAddress: Cannot find name 'swapKit'.swapKitCannot find name 'Chain'. Did you mean 'Chai'?.getAddress(Chain.THORChain),
destinationAddress: any
destinationAddress: Cannot find name 'swapKit'.swapKitCannot find name 'Chain'. Did you mean 'Chai'?.getAddress(Chain.Ethereum),
slippage: number
slippage: 3
});
const const redeemTx: any
redeemTx = await Cannot find name 'swapKit'.swapKit.swap({
route: any
route: const redeemQuote: any
redeemQuote.routes[0]
});
Custom Transaction Memos
Section titled “Custom Transaction Memos”THORChain and Maya use transaction memos for protocol instructions.
Memo Types
Section titled “Memo Types”// Swap memo
const const swapMemo: "SWAP:BTC.BTC:bc1q..."
swapMemo = 'SWAP:BTC.BTC:bc1q...';
// Add liquidity memo
const const addLiquidityMemo: "+:BTC.BTC:bc1q..."
addLiquidityMemo = '+:BTC.BTC:bc1q...';
// Withdraw liquidity memo
const const withdrawMemo: "-:BTC.BTC:10000"
withdrawMemo = '-:BTC.BTC:10000'; // Basis points
// THORName registration
const const thornameeMemo: "~:name:chain:address"
thornameeMemo = '~:name:chain:address';
Building Custom Memos
Section titled “Building Custom Memos”import { function getMemoForDeposit({ chain, symbol, address, ...affiliate }: WithAffiliate<{
chain: Chain;
symbol: string;
address?: string;
}>): string
getMemoForDeposit, function getMemoForWithdraw({ chain, symbol, ticker, basisPoints, targetAsset, }: WithdrawParams): string
WithdrawgetMemoForWithdraw, enum MemoType
MemoType } from '@swapkit/sdk';
// Build deposit (liquidity) memo
const const depositMemo: string
depositMemo = function getMemoForDeposit({ chain, symbol, address, ...affiliate }: WithAffiliate<{
chain: Chain;
symbol: string;
address?: string;
}>): string
getMemoForDeposit({
chain: Chain
chain: Cannot find name 'Chain'. Did you mean 'Chai'?Chain.Bitcoin,
symbol: string
symbol: 'BTC',
address?: string | undefined
address: 'bc1q...', // Optional: asymmetric add
affiliateAddress?: string | undefined
affiliateAddress: 'ss',
affiliateBasisPoints?: number | undefined
affiliateBasisPoints: 50 // 0.5% fee
});
// Build withdraw memo
const const withdrawMemo: string
withdrawMemo = function getMemoForWithdraw({ chain, symbol, ticker, basisPoints, targetAsset, }: WithdrawParams): string
WithdrawgetMemoForWithdraw({
chain: Chain
chain: Cannot find name 'Chain'. Did you mean 'Chai'?Chain.Bitcoin,
symbol: string
symbol: 'BTC',
ticker: string
ticker: 'BTC',
basisPoints: number
basisPoints: 10000, // 100%
targetAsset?: string | undefined
targetAsset: 'ETH.ETH' // Optional: withdraw to different asset
});
Custom Route Building
Section titled “Custom Route Building”Build custom swap routes for specific requirements:
// Get all available routes
const { const routes: any
routes } = await Cannot find name 'SwapKitApi'.SwapKitApi.getSwapQuote({
sellAsset: string
sellAsset: 'ETH.ETH',
sellAmount: string
sellAmount: '1000000000000000000',
buyAsset: string
buyAsset: 'BTC.BTC',
sourceAddress: any
sourceAddress: Cannot find name 'swapKit'.swapKitCannot find name 'Chain'. Did you mean 'Chai'?.getAddress(Chain.Ethereum),
destinationAddress: any
destinationAddress: Cannot find name 'swapKit'.swapKitCannot find name 'Chain'. Did you mean 'Chai'?.getAddress(Chain.Bitcoin),
slippage: number
slippage: 3,
providers: string[]
providers: ['thorchain', 'chainflip', '1inch']
});
// Filter routes by criteria
const const customRoute: any
customRoute = const routes: any
routes.find(Parameter 'route' implicitly has an 'any' type.route => {
// Prefer THORChain for cross-chain
if (route: any
route.providers.includes('THORCHAIN')) return true;
// Use 1inch for same-chain swaps
if (route: any
route.providers.includes('1INCH') &&
route: any
route.sellAsset.split('.')[0] === route: any
route.buyAsset.split('.')[0]) {
return true;
}
return false;
});
// Add custom parameters
const const modifiedRoute: any
modifiedRoute = {
...const customRoute: any
customRoute,
memo: string
memo: const customRoute: any
customRoute.memo + ':ss:50', // Add affiliate
expiration: string
expiration: new var Date: DateConstructor
new (value: number | string | Date) => Date (+4 overloads)
Date(var Date: DateConstructor
Enables basic storage and retrieval of dates and times.Date.DateConstructor.now(): number
Returns the number of milliseconds elapsed since midnight, January 1, 1970 Universal Coordinated Time (UTC).now() + 10 * 60 * 1000).Date.toISOString(): string
Returns a date as a string value in ISO format.toISOString() // 10 min expiry
};
// Execute custom route
await Cannot find name 'swapKit'.swapKit.swap({ route: any
route: const modifiedRoute: any
modifiedRoute });
Gas Optimization
Section titled “Gas Optimization”Optimize gas usage across different chains:
import { const ChainToChainId: {
ARB: ChainId;
AVAX: ChainId;
BASE: ChainId;
BSC: ChainId;
BTC: ChainId;
BCH: ChainId;
GAIA: ChainId;
DASH: ChainId;
... 15 more ...;
TRX: ChainId;
}
ChainToChainId, enum Chain
Chain } from '@swapkit/sdk';
import { const SwapKitApi: {
mayachainMidgard: {
getLiquidityPositionRaw: (address: string) => Promise<MemberDetailsMayachain>;
getNameDetails: (name: string) => Promise<THORNameDetails>;
getNamesByAddress: (address: string) => Promise<...>;
getNamesByOwner: (address: string) => Promise<...>;
getLiquidityPosition: (address: string) => Promise<...>;
};
... 14 more ...;
getChainflipDepositChannel(body: BrokerDepositChannelParams): Promise<...>;
}
SwapKitApi } from '@swapkit/helpers/api';
// Get current gas rates
const const gasRatesArray: {
value: string;
id: number;
chainId: string;
unit: string;
createdAt: string;
}[]
gasRatesArray = await const SwapKitApi: {
mayachainMidgard: {
getLiquidityPositionRaw: (address: string) => Promise<MemberDetailsMayachain>;
getNameDetails: (name: string) => Promise<THORNameDetails>;
getNamesByAddress: (address: string) => Promise<...>;
getNamesByOwner: (address: string) => Promise<...>;
getLiquidityPosition: (address: string) => Promise<...>;
};
... 14 more ...;
getChainflipDepositChannel(body: BrokerDepositChannelParams): Promise<...>;
}
SwapKitApi.function getGasRate(): Promise<{
value: string;
id: number;
chainId: string;
unit: string;
createdAt: string;
}[]>
getGasRate();
// Convert to a map for easier lookup
const const gasRates: Record<string, {
value: string;
id: number;
chainId: string;
unit: string;
createdAt: string;
}>
gasRates = const gasRatesArray: {
value: string;
id: number;
chainId: string;
unit: string;
createdAt: string;
}[]
gasRatesArray.Array<{ value: string; id: number; chainId: string; unit: string; createdAt: string; }>.reduce<Record<string, {
value: string;
id: number;
chainId: string;
unit: string;
createdAt: string;
}>>(callbackfn: (previousValue: Record<string, {
value: string;
id: number;
chainId: string;
unit: string;
createdAt: string;
}>, currentValue: {
value: string;
id: number;
chainId: string;
unit: string;
createdAt: string;
}, currentIndex: number, array: {
value: string;
id: number;
chainId: string;
unit: string;
createdAt: string;
}[]) => Record<...>, initialValue: Record<...>): Record<...> (+2 overloads)
Calls the specified callback function for all the elements in an array. The return value of the callback function is the accumulated result, and is provided as an argument in the next call to the callback function.reduce((acc: Record<string, {
value: string;
id: number;
chainId: string;
unit: string;
createdAt: string;
}>
acc, rate: {
value: string;
id: number;
chainId: string;
unit: string;
createdAt: string;
}
rate) => {
acc: Record<string, {
value: string;
id: number;
chainId: string;
unit: string;
createdAt: string;
}>
acc[rate: {
value: string;
id: number;
chainId: string;
unit: string;
createdAt: string;
}
rate.chainId: string
chainId] = rate: {
value: string;
id: number;
chainId: string;
unit: string;
createdAt: string;
}
rate;
return acc: Record<string, {
value: string;
id: number;
chainId: string;
unit: string;
createdAt: string;
}>
acc;
}, {} as type Record<K extends keyof any, T> = { [P in K]: T; }
Construct a type with a set of properties K of type TRecord<string, typeof const gasRatesArray: {
value: string;
id: number;
chainId: string;
unit: string;
createdAt: string;
}[]
gasRatesArray[0]>);
// Dynamic fee calculation
async function function getOptimalFeeOption(chain: Chain, urgency: "low" | "medium" | "high"): Promise<{
maxFeePerGas: number;
maxPriorityFeePerGas: number;
feeRate?: undefined;
} | {
feeRate: number;
maxFeePerGas?: undefined;
maxPriorityFeePerGas?: undefined;
} | undefined>
getOptimalFeeOption(chain: Chain
chain: enum Chain
Chain, urgency: "low" | "medium" | "high"
urgency: 'low' | 'medium' | 'high') {
const const chainId: ChainId
chainId = const ChainToChainId: {
ARB: ChainId;
AVAX: ChainId;
BASE: ChainId;
BSC: ChainId;
BTC: ChainId;
BCH: ChainId;
GAIA: ChainId;
DASH: ChainId;
... 15 more ...;
TRX: ChainId;
}
ChainToChainId[chain: Chain
chain];
const const gasRate: {
value: string;
id: number;
chainId: string;
unit: string;
createdAt: string;
}
gasRate = const gasRates: Record<string, {
value: string;
id: number;
chainId: string;
unit: string;
createdAt: string;
}>
gasRates[const chainId: ChainId
chainId];
if (!const gasRate: {
value: string;
id: number;
chainId: string;
unit: string;
createdAt: string;
}
gasRate) {
throw new var Error: ErrorConstructor
new (message?: string, options?: ErrorOptions) => Error (+2 overloads)
Error(`Gas rate not found for chain ${chain: Chain
chain}`);
}
// Custom fee multipliers
const const multipliers: {
low: number;
medium: number;
high: number;
}
multipliers = {
low: number
low: 0.8,
medium: number
medium: 1.0,
high: number
high: 1.5
};
const const baseRate: number
baseRate = var Number: NumberConstructor
(value?: any) => number
An object that represents a number of any kind. All JavaScript numbers are 64-bit floating-point numbers.Number(const gasRate: {
value: string;
id: number;
chainId: string;
unit: string;
createdAt: string;
}
gasRate.value: string
value);
return Property 'XRP' does not exist on type '{ ETH: { maxFeePerGas: number; maxPriorityFeePerGas: number; }; BTC: { feeRate: number; }; }'.Property 'XRD' does not exist on type '{ ETH: { maxFeePerGas: number; maxPriorityFeePerGas: number; }; BTC: { feeRate: number; }; }'.Property 'TRX' does not exist on type '{ ETH: { maxFeePerGas: number; maxPriorityFeePerGas: number; }; BTC: { feeRate: number; }; }'.Property 'THOR' does not exist on type '{ ETH: { maxFeePerGas: number; maxPriorityFeePerGas: number; }; BTC: { feeRate: number; }; }'.Property 'SOL' does not exist on type '{ ETH: { maxFeePerGas: number; maxPriorityFeePerGas: number; }; BTC: { feeRate: number; }; }'.Property 'OP' does not exist on type '{ ETH: { maxFeePerGas: number; maxPriorityFeePerGas: number; }; BTC: { feeRate: number; }; }'.Property 'NEAR' does not exist on type '{ ETH: { maxFeePerGas: number; maxPriorityFeePerGas: number; }; BTC: { feeRate: number; }; }'.Property 'MAYA' does not exist on type '{ ETH: { maxFeePerGas: number; maxPriorityFeePerGas: number; }; BTC: { feeRate: number; }; }'.Property 'MATIC' does not exist on type '{ ETH: { maxFeePerGas: number; maxPriorityFeePerGas: number; }; BTC: { feeRate: number; }; }'.Property 'LTC' does not exist on type '{ ETH: { maxFeePerGas: number; maxPriorityFeePerGas: number; }; BTC: { feeRate: number; }; }'.Property 'KUJI' does not exist on type '{ ETH: { maxFeePerGas: number; maxPriorityFeePerGas: number; }; BTC: { feeRate: number; }; }'.Property 'GAIA' does not exist on type '{ ETH: { maxFeePerGas: number; maxPriorityFeePerGas: number; }; BTC: { feeRate: number; }; }'.Property 'FLIP' does not exist on type '{ ETH: { maxFeePerGas: number; maxPriorityFeePerGas: number; }; BTC: { feeRate: number; }; }'.Property 'FIAT' does not exist on type '{ ETH: { maxFeePerGas: number; maxPriorityFeePerGas: number; }; BTC: { feeRate: number; }; }'.Property 'DOT' does not exist on type '{ ETH: { maxFeePerGas: number; maxPriorityFeePerGas: number; }; BTC: { feeRate: number; }; }'.Property 'DOGE' does not exist on type '{ ETH: { maxFeePerGas: number; maxPriorityFeePerGas: number; }; BTC: { feeRate: number; }; }'.Property 'DASH' does not exist on type '{ ETH: { maxFeePerGas: number; maxPriorityFeePerGas: number; }; BTC: { feeRate: number; }; }'.Property 'BSC' does not exist on type '{ ETH: { maxFeePerGas: number; maxPriorityFeePerGas: number; }; BTC: { feeRate: number; }; }'.Property 'BCH' does not exist on type '{ ETH: { maxFeePerGas: number; maxPriorityFeePerGas: number; }; BTC: { feeRate: number; }; }'.Property 'BASE' does not exist on type '{ ETH: { maxFeePerGas: number; maxPriorityFeePerGas: number; }; BTC: { feeRate: number; }; }'.Property 'AVAX' does not exist on type '{ ETH: { maxFeePerGas: number; maxPriorityFeePerGas: number; }; BTC: { feeRate: number; }; }'.Property 'ARB' does not exist on type '{ ETH: { maxFeePerGas: number; maxPriorityFeePerGas: number; }; BTC: { feeRate: number; }; }'.{
[enum Chain
Chain.function (enum member) Chain.Ethereum = "ETH"
Ethereum]: {
maxFeePerGas: number
maxFeePerGas: var Math: Math
An intrinsic object that provides basic mathematics functionality and constants.Math.Math.floor(x: number): number
Returns the greatest integer less than or equal to its numeric argument.floor(const baseRate: number
baseRate * const multipliers: {
low: number;
medium: number;
high: number;
}
multipliers[urgency: "low" | "medium" | "high"
urgency]),
maxPriorityFeePerGas: number
maxPriorityFeePerGas: var Math: Math
An intrinsic object that provides basic mathematics functionality and constants.Math.Math.floor(x: number): number
Returns the greatest integer less than or equal to its numeric argument.floor(const baseRate: number
baseRate * 0.1 * const multipliers: {
low: number;
medium: number;
high: number;
}
multipliers[urgency: "low" | "medium" | "high"
urgency])
},
[enum Chain
Chain.function (enum member) Chain.Bitcoin = "BTC"
Bitcoin]: {
feeRate: number
feeRate: var Math: Math
An intrinsic object that provides basic mathematics functionality and constants.Math.Math.floor(x: number): number
Returns the greatest integer less than or equal to its numeric argument.floor(const baseRate: number
baseRate * const multipliers: {
low: number;
medium: number;
high: number;
}
multipliers[urgency: "low" | "medium" | "high"
urgency])
}
}[chain: Chain
chain];
}
// Use optimized fees
const const customFees: {
maxFeePerGas: number;
maxPriorityFeePerGas: number;
feeRate?: undefined;
} | {
feeRate: number;
maxFeePerGas?: undefined;
maxPriorityFeePerGas?: undefined;
} | undefined
customFees = await function getOptimalFeeOption(chain: Chain, urgency: "low" | "medium" | "high"): Promise<{
maxFeePerGas: number;
maxPriorityFeePerGas: number;
feeRate?: undefined;
} | {
feeRate: number;
maxFeePerGas?: undefined;
maxPriorityFeePerGas?: undefined;
} | undefined>
getOptimalFeeOption(enum Chain
Chain.function (enum member) Chain.Ethereum = "ETH"
Ethereum, 'low');
const const tx: any
tx = await Cannot find name 'swapKit'.swapKit.transfer({
No value exists in scope for the shorthand property 'assetValue'. Either declare one or provide an initializer.assetValue,
No value exists in scope for the shorthand property 'recipient'. Either declare one or provide an initializer.recipient,
customTxFee: {
maxFeePerGas: number;
maxPriorityFeePerGas: number;
feeRate?: undefined;
} | {
feeRate: number;
maxFeePerGas?: undefined;
maxPriorityFeePerGas?: undefined;
} | undefined
customTxFee: const customFees: {
maxFeePerGas: number;
maxPriorityFeePerGas: number;
feeRate?: undefined;
} | {
feeRate: number;
maxFeePerGas?: undefined;
maxPriorityFeePerGas?: undefined;
} | undefined
customFees
});
Token List Management
Section titled “Token List Management”Manage custom token lists and metadata:
import { class AssetValue
AssetValue, enum ProviderName
ProviderName } from '@swapkit/sdk';
import { const SwapKitApi: {
mayachainMidgard: {
getLiquidityPositionRaw: (address: string) => Promise<MemberDetailsMayachain>;
getNameDetails: (name: string) => Promise<THORNameDetails>;
getNamesByAddress: (address: string) => Promise<...>;
getNamesByOwner: (address: string) => Promise<...>;
getLiquidityPosition: (address: string) => Promise<...>;
};
... 14 more ...;
getChainflipDepositChannel(body: BrokerDepositChannelParams): Promise<...>;
}
SwapKitApi } from '@swapkit/helpers/api';
// Get token lists from providers
async function function loadTokenList(provider: ProviderName): Promise<TokenV2[]>
loadTokenList(provider: ProviderName
provider: enum ProviderName
ProviderName) {
const const tokenList: TokensResponseV2
tokenList = await const SwapKitApi: {
mayachainMidgard: {
getLiquidityPositionRaw: (address: string) => Promise<MemberDetailsMayachain>;
getNameDetails: (name: string) => Promise<THORNameDetails>;
getNamesByAddress: (address: string) => Promise<...>;
getNamesByOwner: (address: string) => Promise<...>;
getLiquidityPosition: (address: string) => Promise<...>;
};
... 14 more ...;
getChainflipDepositChannel(body: BrokerDepositChannelParams): Promise<...>;
}
SwapKitApi.function getTokenList(provider: ProviderName): Promise<TokensResponseV2>
getTokenList(provider: ProviderName
provider);
return const tokenList: TokensResponseV2
tokenList.tokens: TokenV2[]
tokens;
}
// Custom token registry with caching
class class TokenRegistry
TokenRegistry {
private TokenRegistry.tokens: Map<string, any>
tokens: interface Map<K, V>
Map<string, any> = new var Map: MapConstructor
new () => Map<any, any> (+3 overloads)
Map();
private TokenRegistry.cache: Map<string, {
data: any;
timestamp: number;
}>
cache: interface Map<K, V>
Map<string, { data: any
data: any; timestamp: number
timestamp: number }> = new var Map: MapConstructor
new () => Map<any, any> (+3 overloads)
Map();
private TokenRegistry.cacheTTL: number
cacheTTL = 3600000; // 1 hour
async TokenRegistry.loadProviderTokens(provider: ProviderName): Promise<any>
loadProviderTokens(provider: ProviderName
provider: enum ProviderName
ProviderName) {
const const cacheKey: string
cacheKey = `provider_${provider: ProviderName
provider}`;
const const cached: {
data: any;
timestamp: number;
} | undefined
cached = this.TokenRegistry.cache: Map<string, {
data: any;
timestamp: number;
}>
cache.Map<string, { data: any; timestamp: number; }>.get(key: string): {
data: any;
timestamp: number;
} | undefined
Returns a specified element from the Map object. If the value that is associated to the provided key is an object, then you will get a reference to that object and any change made to that object will effectively modify it inside the Map.get(const cacheKey: string
cacheKey);
if (const cached: {
data: any;
timestamp: number;
} | undefined
cached && var Date: DateConstructor
Enables basic storage and retrieval of dates and times.Date.DateConstructor.now(): number
Returns the number of milliseconds elapsed since midnight, January 1, 1970 Universal Coordinated Time (UTC).now() - const cached: {
data: any;
timestamp: number;
}
cached.timestamp: number
timestamp < this.TokenRegistry.cacheTTL: number
cacheTTL) {
return const cached: {
data: any;
timestamp: number;
}
cached.data: any
data;
}
const const tokenList: TokensResponseV2
tokenList = await const SwapKitApi: {
mayachainMidgard: {
getLiquidityPositionRaw: (address: string) => Promise<MemberDetailsMayachain>;
getNameDetails: (name: string) => Promise<THORNameDetails>;
getNamesByAddress: (address: string) => Promise<...>;
getNamesByOwner: (address: string) => Promise<...>;
getLiquidityPosition: (address: string) => Promise<...>;
};
... 14 more ...;
getChainflipDepositChannel(body: BrokerDepositChannelParams): Promise<...>;
}
SwapKitApi.function getTokenList(provider: ProviderName): Promise<TokensResponseV2>
getTokenList(provider: ProviderName
provider);
this.TokenRegistry.cache: Map<string, {
data: any;
timestamp: number;
}>
cache.Map<string, { data: any; timestamp: number; }>.set(key: string, value: {
data: any;
timestamp: number;
}): Map<string, {
data: any;
timestamp: number;
}>
Adds a new element with a specified key and value to the Map. If an element with the same key already exists, the element will be updated.set(const cacheKey: string
cacheKey, { data: any
data: const tokenList: TokensResponseV2
tokenList, timestamp: number
timestamp: var Date: DateConstructor
Enables basic storage and retrieval of dates and times.Date.DateConstructor.now(): number
Returns the number of milliseconds elapsed since midnight, January 1, 1970 Universal Coordinated Time (UTC).now() });
// Index tokens by identifier
const tokenList: TokensResponseV2
tokenList.tokens: TokenV2[]
tokens.Array<TokenV2>.forEach(callbackfn: (value: TokenV2, index: number, array: TokenV2[]) => void, thisArg?: any): void
Performs the specified action for each element in an array.forEach(token: TokenV2
token => {
this.TokenRegistry.tokens: Map<string, any>
tokens.Map<string, any>.set(key: string, value: any): Map<string, any>
Adds a new element with a specified key and value to the Map. If an element with the same key already exists, the element will be updated.set(token: TokenV2
token.identifier: string
identifier, token: TokenV2
token);
});
return const tokenList: TokensResponseV2
tokenList;
}
TokenRegistry.addCustomToken(token: {
chain: string;
identifier: string;
symbol: string;
decimals: number;
name?: string;
logoURI?: string;
address?: string;
}): void
addCustomToken(token: {
chain: string;
identifier: string;
symbol: string;
decimals: number;
name?: string;
logoURI?: string;
address?: string;
}
token: {
chain: string
chain: string;
identifier: string
identifier: string;
symbol: string
symbol: string;
decimals: number
decimals: number;
name?: string | undefined
name?: string;
logoURI?: string | undefined
logoURI?: string;
address?: string | undefined
address?: string;
}) {
this.TokenRegistry.tokens: Map<string, any>
tokens.Map<string, any>.set(key: string, value: any): Map<string, any>
Adds a new element with a specified key and value to the Map. If an element with the same key already exists, the element will be updated.set(token: {
chain: string;
identifier: string;
symbol: string;
decimals: number;
name?: string;
logoURI?: string;
address?: string;
}
token.identifier: string
identifier, token: {
chain: string;
identifier: string;
symbol: string;
decimals: number;
name?: string;
logoURI?: string;
address?: string;
}
token);
// Register with AssetValue for proper decimal handling
class AssetValue
AssetValue.AssetValue.setStaticAssets(tokenMap: Map<string, {
tax?: TokenTax;
identifier: string;
chain: Chain;
} & ({
decimal: number;
} | {
decimals: number;
})>): boolean
setStaticAssets(new var Map: MapConstructor
new <string, {
identifier: string;
chain: any;
decimal: number;
}>(iterable?: Iterable<readonly [string, {
identifier: string;
chain: any;
decimal: number;
}]> | null | undefined) => Map<string, {
identifier: string;
chain: any;
decimal: number;
}> (+3 overloads)
Map([[token: {
chain: string;
identifier: string;
symbol: string;
decimals: number;
name?: string;
logoURI?: string;
address?: string;
}
token.identifier: string
identifier, {
identifier: string
identifier: token: {
chain: string;
identifier: string;
symbol: string;
decimals: number;
name?: string;
logoURI?: string;
address?: string;
}
token.identifier: string
identifier,
chain: any
chain: token: {
chain: string;
identifier: string;
symbol: string;
decimals: number;
name?: string;
logoURI?: string;
address?: string;
}
token.chain: string
chain as any,
decimal: number
decimal: token: {
chain: string;
identifier: string;
symbol: string;
decimals: number;
name?: string;
logoURI?: string;
address?: string;
}
token.decimals: number
decimals
}]]));
}
TokenRegistry.getToken(identifier: string): any
getToken(identifier: string
identifier: string) {
return this.TokenRegistry.tokens: Map<string, any>
tokens.Map<string, any>.get(key: string): any
Returns a specified element from the Map object. If the value that is associated to the provided key is an object, then you will get a reference to that object and any change made to that object will effectively modify it inside the Map.get(identifier: string
identifier);
}
}
// Usage
const const registry: TokenRegistry
registry = new constructor TokenRegistry(): TokenRegistry
TokenRegistry();
// Load tokens from a provider
await const registry: TokenRegistry
registry.TokenRegistry.loadProviderTokens(provider: ProviderName): Promise<any>
loadProviderTokens(enum ProviderName
ProviderName.Property 'UNISWAP' does not exist on type 'typeof ProviderName'.UNISWAP);
// Add custom token
const registry: TokenRegistry
registry.TokenRegistry.addCustomToken(token: {
chain: string;
identifier: string;
symbol: string;
decimals: number;
name?: string;
logoURI?: string;
address?: string;
}): void
addCustomToken({
chain: string
chain: 'ETH',
identifier: string
identifier: 'ETH.CUSTOM-0x1234567890123456789012345678901234567890',
symbol: string
symbol: 'CUSTOM',
decimals: number
decimals: 18,
name?: string | undefined
name: 'Custom Token',
logoURI?: string | undefined
logoURI: 'https://example.com/token.png'
});
Transaction Tracking
Section titled “Transaction Tracking”Implement advanced transaction tracking:
import { const ChainToChainId: {
ARB: ChainId;
AVAX: ChainId;
BASE: ChainId;
BSC: ChainId;
BTC: ChainId;
BCH: ChainId;
GAIA: ChainId;
DASH: ChainId;
... 15 more ...;
TRX: ChainId;
}
ChainToChainId } from '@swapkit/sdk';
import { const SwapKitApi: {
mayachainMidgard: {
getLiquidityPositionRaw: (address: string) => Promise<MemberDetailsMayachain>;
getNameDetails: (name: string) => Promise<THORNameDetails>;
getNamesByAddress: (address: string) => Promise<...>;
getNamesByOwner: (address: string) => Promise<...>;
getLiquidityPosition: (address: string) => Promise<...>;
};
... 14 more ...;
getChainflipDepositChannel(body: BrokerDepositChannelParams): Promise<...>;
}
SwapKitApi } from '@swapkit/helpers/api';
class class TransactionTracker
TransactionTracker {
private TransactionTracker.pendingTxs: Map<string, any>
pendingTxs: interface Map<K, V>
Map<string, any> = new var Map: MapConstructor
new () => Map<any, any> (+3 overloads)
Map();
async TransactionTracker.trackTransaction(txHash: string, chain: Chain): Promise<void>
trackTransaction(txHash: string
txHash: string, chain: Chain
chain: Cannot find name 'Chain'.Chain) {
this.TransactionTracker.pendingTxs: Map<string, any>
pendingTxs.Map<string, any>.set(key: string, value: any): Map<string, any>
Adds a new element with a specified key and value to the Map. If an element with the same key already exists, the element will be updated.set(txHash: string
txHash, { chain: Chain
chain, status: string
status: 'pending' });
// Poll for updates
const const interval: NodeJS.Timeout
interval = function setInterval<[]>(callback: () => void, delay?: number): NodeJS.Timeout (+4 overloads)
Schedules repeated execution of `callback` every `delay` milliseconds.
When `delay` is larger than `2147483647` or less than `1` or `NaN`, the `delay`
will be set to `1`. Non-integer delays are truncated to an integer.
If `callback` is not a function, a `TypeError` will be thrown.
This method has a custom variant for promises that is available using
`timersPromises.setInterval()`.setInterval(async () => {
try {
const const chainId: any
chainId = Element implicitly has an 'any' type because expression of type 'Chain' can't be used to index type '{ ARB: ChainId; AVAX: ChainId; BASE: ChainId; BSC: ChainId; BTC: ChainId; BCH: ChainId; GAIA: ChainId; DASH: ChainId; ... 15 more ...; TRX: ChainId; }'.ChainToChainId[chain];
const const status: TrackerResponse
status = await const SwapKitApi: {
mayachainMidgard: {
getLiquidityPositionRaw: (address: string) => Promise<MemberDetailsMayachain>;
getNameDetails: (name: string) => Promise<THORNameDetails>;
getNamesByAddress: (address: string) => Promise<...>;
getNamesByOwner: (address: string) => Promise<...>;
getLiquidityPosition: (address: string) => Promise<...>;
};
... 14 more ...;
getChainflipDepositChannel(body: BrokerDepositChannelParams): Promise<...>;
}
SwapKitApi.function getTrackerDetails(json: TrackerParams): Promise<TrackerResponse>
getTrackerDetails({ hash: string
hash: txHash: string
txHash, chainId: ChainId
chainId });
if (const status: TrackerResponse
status.TransactionProps.status?: TxnStatus | undefined
status === 'completed') {
this.TransactionTracker.pendingTxs: Map<string, any>
pendingTxs.Map<string, any>.set(key: string, value: any): Map<string, any>
Adds a new element with a specified key and value to the Map. If an element with the same key already exists, the element will be updated.set(txHash: string
txHash, { ...const status: TrackerResponse
status, chain: Chain
chain });
function clearInterval(timeout: NodeJS.Timeout | string | number | undefined): void (+3 overloads)
Cancels a `Timeout` object created by `setInterval()`.clearInterval(const interval: NodeJS.Timeout
interval);
this.TransactionTracker.onComplete(txHash: string, status: any): void
onComplete(txHash: string
txHash, const status: TrackerResponse
status);
} else if (This comparison appears to be unintentional because the types 'TxnStatus.unknown | TxnStatus.not_started | TxnStatus.pending | TxnStatus.swapping | undefined' and '"failed"' have no overlap.status.status === 'failed') {
this.TransactionTracker.pendingTxs: Map<string, any>
pendingTxs.Map<string, any>.delete(key: string): boolean
delete(txHash: string
txHash);
function clearInterval(timeout: NodeJS.Timeout | string | number | undefined): void (+3 overloads)
Cancels a `Timeout` object created by `setInterval()`.clearInterval(const interval: NodeJS.Timeout
interval);
this.TransactionTracker.onFailed(txHash: string, status: any): void
onFailed(txHash: string
txHash, const status: TrackerResponse
status);
}
} catch (error) {
// Continue polling
}
}, 10000); // Check every 10 seconds
}
private TransactionTracker.onComplete(txHash: string, status: any): void
onComplete(txHash: string
txHash: string, status: any
status: any) {
console.Console.log(message?: any, ...optionalParams: any[]): void (+3 overloads)
Prints to `stdout` with newline. Multiple arguments can be passed, with the
first used as the primary message and all additional used as substitution
values similar to [`printf(3)`](http://man7.org/linux/man-pages/man3/printf.3.html)
(the arguments are all passed to [`util.format()`](https://nodejs.org/docs/latest-v24.x/api/util.html#utilformatformat-args)).
```js
const count = 5;
console.log('count: %d', count);
// Prints: count: 5, to stdout
console.log('count:', count);
// Prints: count: 5, to stdout
```
See [`util.format()`](https://nodejs.org/docs/latest-v24.x/api/util.html#utilformatformat-args) for more information.log(`Transaction ${txHash: string
txHash} completed!`);
// Update UI, send notifications, etc.
}
private TransactionTracker.onFailed(txHash: string, status: any): void
onFailed(txHash: string
txHash: string, status: any
status: any) {
console.Console.error(message?: any, ...optionalParams: any[]): void (+3 overloads)
Prints to `stderr` with newline. Multiple arguments can be passed, with the
first used as the primary message and all additional used as substitution
values similar to [`printf(3)`](http://man7.org/linux/man-pages/man3/printf.3.html)
(the arguments are all passed to [`util.format()`](https://nodejs.org/docs/latest-v24.x/api/util.html#utilformatformat-args)).
```js
const code = 5;
console.error('error #%d', code);
// Prints: error #5, to stderr
console.error('error', code);
// Prints: error 5, to stderr
```
If formatting elements (e.g. `%d`) are not found in the first string then
[`util.inspect()`](https://nodejs.org/docs/latest-v24.x/api/util.html#utilinspectobject-options) is called on each argument and the
resulting string values are concatenated. See [`util.format()`](https://nodejs.org/docs/latest-v24.x/api/util.html#utilformatformat-args)
for more information.error(`Transaction ${txHash: string
txHash} failed!`);
// Handle failure
}
}
// Usage
const const tracker: TransactionTracker
tracker = new constructor TransactionTracker(): TransactionTracker
TransactionTracker();
// Track a swap
const const txHash: any
txHash = await Cannot find name 'swapKit'.swapKitNo value exists in scope for the shorthand property 'route'. Either declare one or provide an initializer..swap({ route });
await const tracker: TransactionTracker
tracker.TransactionTracker.trackTransaction(txHash: string, chain: Chain): Promise<void>
trackTransaction(const txHash: any
txHash, Cannot find name 'Chain'. Did you mean 'Chai'?Chain.Ethereum);
Error Recovery
Section titled “Error Recovery”Implement robust error handling and recovery:
import { class SwapKitError
SwapKitError } from '@swapkit/sdk';
class class SwapKitRetry
SwapKitRetry {
async SwapKitRetry.executeWithRetry<T>(operation: () => Promise<T>, maxRetries?: number, backoff?: number): Promise<T>
executeWithRetry<function (type parameter) T in SwapKitRetry.executeWithRetry<T>(operation: () => Promise<T>, maxRetries?: number, backoff?: number): Promise<T>
T>(
operation: () => Promise<T>
operation: () => interface Promise<T>
Represents the completion of an asynchronous operationPromise<function (type parameter) T in SwapKitRetry.executeWithRetry<T>(operation: () => Promise<T>, maxRetries?: number, backoff?: number): Promise<T>
T>,
maxRetries: number
maxRetries = 3,
backoff: number
backoff = 1000
): interface Promise<T>
Represents the completion of an asynchronous operationPromise<function (type parameter) T in SwapKitRetry.executeWithRetry<T>(operation: () => Promise<T>, maxRetries?: number, backoff?: number): Promise<T>
T> {
let let lastError: Error
lastError: Error;
for (let let i: number
i = 0; let i: number
i < maxRetries: number
maxRetries; let i: number
i++) {
try {
return await operation: () => Promise<T>
operation();
} catch (error) {
let lastError: Error
lastError = error as Error;
// Don't retry user rejections
if (error instanceof class SwapKitError
SwapKitError &&
function (local var) error: SwapKitError
error.Error.message: string
message === 'wallet_connection_rejected_by_user') {
throw function (local var) error: SwapKitError
error;
}
// Wait before retry with exponential backoff
if (let i: number
i < maxRetries: number
maxRetries - 1) {
await new var Promise: PromiseConstructor
new <unknown>(executor: (resolve: (value: unknown) => void, reject: (reason?: any) => void) => void) => Promise<unknown>
Creates a new Promise.Promise(resolve: (value: unknown) => void
resolve =>
function setTimeout(callback: (_: void) => void, delay?: number): NodeJS.Timeout (+4 overloads)
[MDN Reference](https://developer.mozilla.org/docs/Web/API/Window/setTimeout)setTimeout(resolve: (value: unknown) => void
resolve, backoff: number
backoff * var Math: Math
An intrinsic object that provides basic mathematics functionality and constants.Math.Math.pow(x: number, y: number): number
Returns the value of a base expression taken to a specified power.pow(2, let i: number
i))
);
}
}
}
throw let lastError: Error
lastError!;
}
}
// Usage
const const retry: SwapKitRetry
retry = new constructor SwapKitRetry(): SwapKitRetry
SwapKitRetry();
const const result: any
result = await const retry: SwapKitRetry
retry.SwapKitRetry.executeWithRetry<any>(operation: () => Promise<any>, maxRetries?: number, backoff?: number): Promise<any>
executeWithRetry(async () => {
return await Cannot find name 'swapKit'.swapKitNo value exists in scope for the shorthand property 'route'. Either declare one or provide an initializer..swap({ route });
});
Performance Optimization
Section titled “Performance Optimization”Caching Strategy
Section titled “Caching Strategy”class class SwapKitCache
SwapKitCache {
private SwapKitCache.cache: Map<string, {
data: any;
timestamp: number;
}>
cache = new var Map: MapConstructor
new <string, {
data: any;
timestamp: number;
}>(iterable?: Iterable<readonly [string, {
data: any;
timestamp: number;
}]> | null | undefined) => Map<string, {
data: any;
timestamp: number;
}> (+3 overloads)
Map<string, { data: any
data: any, timestamp: number
timestamp: number }>();
private SwapKitCache.ttl: number
ttl = 60000; // 1 minute
SwapKitCache.set(key: string, data: any): void
set(key: string
key: string, data: any
data: any) {
this.SwapKitCache.cache: Map<string, {
data: any;
timestamp: number;
}>
cache.Map<string, { data: any; timestamp: number; }>.set(key: string, value: {
data: any;
timestamp: number;
}): Map<string, {
data: any;
timestamp: number;
}>
Adds a new element with a specified key and value to the Map. If an element with the same key already exists, the element will be updated.set(key: string
key, { data: any
data, timestamp: number
timestamp: var Date: DateConstructor
Enables basic storage and retrieval of dates and times.Date.DateConstructor.now(): number
Returns the number of milliseconds elapsed since midnight, January 1, 1970 Universal Coordinated Time (UTC).now() });
}
SwapKitCache.get(key: string): any
get(key: string
key: string) {
const const entry: {
data: any;
timestamp: number;
} | undefined
entry = this.SwapKitCache.cache: Map<string, {
data: any;
timestamp: number;
}>
cache.Map<string, { data: any; timestamp: number; }>.get(key: string): {
data: any;
timestamp: number;
} | undefined
Returns a specified element from the Map object. If the value that is associated to the provided key is an object, then you will get a reference to that object and any change made to that object will effectively modify it inside the Map.get(key: string
key);
if (!const entry: {
data: any;
timestamp: number;
} | undefined
entry) return null;
if (var Date: DateConstructor
Enables basic storage and retrieval of dates and times.Date.DateConstructor.now(): number
Returns the number of milliseconds elapsed since midnight, January 1, 1970 Universal Coordinated Time (UTC).now() - const entry: {
data: any;
timestamp: number;
}
entry.timestamp: number
timestamp > this.SwapKitCache.ttl: number
ttl) {
this.SwapKitCache.cache: Map<string, {
data: any;
timestamp: number;
}>
cache.Map<string, { data: any; timestamp: number; }>.delete(key: string): boolean
delete(key: string
key);
return null;
}
return const entry: {
data: any;
timestamp: number;
}
entry.data: any
data;
}
}
// Use cache for quotes
const const cache: SwapKitCache
cache = new constructor SwapKitCache(): SwapKitCache
SwapKitCache();
async function function getCachedQuote(params: any): Promise<any>
getCachedQuote(params: any
params: any) {
const const key: string
key = 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.stringify(params: any
params);
const const cached: any
cached = const cache: SwapKitCache
cache.SwapKitCache.get(key: string): any
get(const key: string
key);
if (const cached: any
cached) return const cached: any
cached;
const const quote: any
quote = await Cannot find name 'SwapKitApi'.SwapKitApi.getSwapQuote(params: any
params);
const cache: SwapKitCache
cache.SwapKitCache.set(key: string, data: any): void
set(const key: string
key, const quote: any
quote);
return const quote: any
quote;
}
Next Steps
Section titled “Next Steps”- Explore THORChain Features for protocol-specific operations
- Review API Reference for all available methods
- Check Examples for real-world implementations