UNPKG

@swingby-protocol/sdk

Version:

An implementation of the Swingby standard development kit for NodeJS and JavaScript.

294 lines (266 loc) 7.17 kB
import type { SkybridgeMode } from '../modes'; import type { SkybridgeBridge } from '../bridges'; import type { SkybridgeResource } from '../resources'; import type { SkybridgeDirection } from '../directions'; export type SkybridgeApiCoin = 'BTC' | 'WBTC' | 'sbBTC' | 'BTCB' | 'SKYPOOL'; const COINS = { swap: { btc_erc: { test: { in: ['BTC', 'WBTC', 'sbBTC'], out: ['BTC', 'WBTC'], }, production: { in: ['BTC', 'WBTC', 'sbBTC'], out: ['BTC', 'WBTC'], }, }, btc_bep20: { test: { in: [], out: [], }, production: { in: ['BTC', 'BTCB.BEP20', 'sbBTC.BEP20'], out: ['BTC', 'BTCB.BEP20'], }, }, }, pool: { btc_erc: { test: { in: ['BTC', 'WBTC'], out: ['sbBTC'], }, production: { in: ['BTC', 'WBTC'], out: ['sbBTC'], }, }, btc_bep20: { test: { in: [], out: [], }, production: { in: ['BTC', 'BTCB.BEP20'], out: ['sbBTC.BEP20'], }, }, }, withdrawal: { btc_erc: { test: { in: ['sbBTC'], out: ['BTC', 'WBTC'], }, production: { in: ['sbBTC'], out: ['BTC', 'WBTC'], }, }, btc_bep20: { test: { in: ['sbBTC.BEP20'], out: ['BTC', 'BTCB.BEP20'], }, production: { in: ['sbBTC.BEP20'], out: ['BTC', 'BTCB.BEP20'], }, }, }, } as const; export type SkybridgeCoin< A extends SkybridgeResource = SkybridgeResource, M extends SkybridgeMode = SkybridgeMode, D extends SkybridgeDirection = SkybridgeDirection, B extends SkybridgeBridge = SkybridgeBridge > = typeof COINS[A][B][M][D][number]; const typedKeys = <T>(obj: T): Array<keyof T> => Object.keys(obj) as Array<keyof T>; export const getCoinsFor = < A extends SkybridgeResource, M extends SkybridgeMode, D extends SkybridgeDirection, B extends SkybridgeBridge >({ context: { mode } = {}, bridge, direction, resource, }: { context?: { mode?: M }; bridge?: B; direction?: D; resource?: A; } = {}): SkybridgeCoin<A, M, D, B>[] => { const result: SkybridgeCoin<A, M, D, B>[] = []; typedKeys(COINS).forEach((resourceIt) => { typedKeys(COINS[resourceIt]).forEach((bridgeIt) => { typedKeys(COINS[resourceIt][bridgeIt]).forEach((modeIt) => { typedKeys(COINS[resourceIt][bridgeIt][modeIt]).forEach((directionIt) => { if (resource && resource !== resourceIt) return; if (bridge && bridge !== bridgeIt) return; if (mode && mode !== modeIt) return; if (direction && direction !== directionIt) return; // if (mode === 'test' && bridge === 'btc_bep20') return; result.push(...COINS[resourceIt][bridgeIt][modeIt][directionIt]); }); }); }); }); return Array.from(new Set(result)); }; export const getBridgesForCoin = < A extends SkybridgeResource, M extends SkybridgeMode, D extends SkybridgeDirection >({ context: { mode } = {}, coin, direction, resource, }: { context?: { mode?: M }; coin: SkybridgeCoin; direction?: D; resource?: A; }): SkybridgeBridge[] => { const result = new Set<SkybridgeBridge>(); typedKeys(COINS).forEach((resourceIt) => { typedKeys(COINS[resourceIt]).forEach((bridgeIt) => { typedKeys(COINS[resourceIt][bridgeIt]).forEach((modeIt) => { typedKeys(COINS[resourceIt][bridgeIt][modeIt]).forEach((directionIt) => { if (resource && resource !== resourceIt) return; if (mode && mode !== modeIt) return; if (direction && direction !== directionIt) return; if ( ((COINS[resourceIt][bridgeIt][modeIt][directionIt] as unknown) as string[]).includes( coin, ) ) { result.add(bridgeIt); } }); }); }); }); return Array.from(result); }; export const getSwapableFrom = < A extends SkybridgeResource, M extends SkybridgeMode, B extends SkybridgeBridge >({ context: { mode }, coin, bridge, resource, }: { context: { mode: M }; coin: SkybridgeCoin; bridge?: B; resource: A; }): SkybridgeCoin<A, M, 'out', B>[] => { const result: SkybridgeCoin<A, M, 'out', B>[] = []; typedKeys(COINS).forEach((resourceIt) => { typedKeys(COINS[resourceIt]).forEach((bridgeIt) => { typedKeys(COINS[resourceIt][bridgeIt]).forEach((modeIt) => { if (resource && resource !== resourceIt) return; if (bridge && bridge !== bridgeIt) return; if (mode && mode !== modeIt) return; if (((COINS[resourceIt][bridgeIt][modeIt].in as unknown) as string[]).includes(coin)) { result.push(...COINS[resourceIt][bridgeIt][modeIt].out); } }); }); }); const set = new Set(result); set.delete(coin as any); return Array.from(set); }; export const getSwapableTo = < A extends SkybridgeResource, M extends SkybridgeMode, B extends SkybridgeBridge >({ context: { mode }, coin, bridge, resource, }: { context: { mode: M }; coin: SkybridgeCoin; bridge?: B; resource: A; }): SkybridgeCoin<A, M, 'in', B>[] => { const result: SkybridgeCoin<A, M, 'in', B>[] = []; typedKeys(COINS).forEach((resourceIt) => { typedKeys(COINS[resourceIt]).forEach((bridgeIt) => { typedKeys(COINS[resourceIt][bridgeIt]).forEach((modeIt) => { if (resource && resource !== resourceIt) return; if (bridge && bridge !== bridgeIt) return; if (mode && mode !== modeIt) return; if (((COINS[resourceIt][bridgeIt][modeIt].out as unknown) as string[]).includes(coin)) { result.push(...COINS[resourceIt][bridgeIt][modeIt].in); } }); }); }); const set = new Set(result); set.delete(coin as any); return Array.from(set); }; export const getDisplayNameForCoin = ({ coin }: { coin: SkybridgeCoin }): string => { switch (coin) { case 'BTC': return 'BTC'; case 'BTCB.BEP20': return 'BTCB (BEP20)'; case 'sbBTC.BEP20': return 'sbBTC (BEP20)'; case 'WBTC': return 'WBTC (ERC20)'; case 'sbBTC': return 'sbBTC (ERC20)'; } }; export const toApiCoin = ({ coin }: { coin: SkybridgeCoin }): SkybridgeApiCoin => { switch (coin) { case 'BTC': return 'BTC'; case 'BTCB.BEP20': return 'BTCB'; case 'WBTC': return 'WBTC'; case 'sbBTC.BEP20': case 'sbBTC': return 'sbBTC'; } }; export const fromApiCoin = ({ coin, bridge, }: { coin: SkybridgeApiCoin; bridge: SkybridgeBridge; }): SkybridgeCoin => { if (bridge === 'btc_erc') { if ((coin as any) === 'BTCE') return 'WBTC'; if (coin === 'SKYPOOL') return 'WBTC'; return coin as SkybridgeCoin; } if (bridge === 'btc_bep20') { switch (coin) { case 'BTC': return 'BTC'; case 'BTCB': return 'BTCB.BEP20'; case 'sbBTC': return 'sbBTC.BEP20'; case 'SKYPOOL': return 'BTCB.BEP20'; } } throw new Error(`Could not find SDK coin ID for "${coin}" in bridge "${bridge}"`); };