UNPKG

@swingby-protocol/sdk

Version:

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

134 lines (120 loc) 4.25 kB
import { fetch } from '../fetch'; import type { SkybridgeMode } from '../modes'; import type { SkybridgeParams, SkybridgeStatus } from '../common-params'; import type { SkybridgeResource } from '../resources'; import { fromApiCoin, SkybridgeCoin } from '../coins'; import { SkybridgeBridge } from '../bridges'; type ServerReturnType<R extends SkybridgeResource, M extends SkybridgeMode> = { items: Array< Pick<SkybridgeParams<R, M>, 'hash'> & { currencyIn: SkybridgeCoin<R, M, 'in'>; currencyOut: SkybridgeCoin<R, M, 'out'>; amountIn: string; amountOut: string; feeCurrency: SkybridgeCoin<R, M>; addressDeposit: string; fee: string; status: SkybridgeStatus; txIdIn: string; txIdOut: string; timestamp: number; addressIn?: string; addressOut: string; skypools?: boolean; } >; }; type ReturnType<R extends SkybridgeResource, M extends SkybridgeMode> = Pick< SkybridgeParams<R, M>, | 'addressDeposit' | 'addressReceiving' | 'amountDeposit' | 'amountReceiving' | 'currencyDeposit' | 'currencyReceiving' | 'hash' | 'status' | 'timestamp' | 'feeTotal' | 'feeCurrency' | 'addressSending' | 'isSkypoolsSwap' > & { txDepositId: SkybridgeParams<R, M>['txDepositId'] | null; txReceivingId: SkybridgeParams<R, M>['txReceivingId'] | null; }; const bridgeCache = new Map<string, SkybridgeBridge>(); export const getDetails = async <R extends SkybridgeResource, M extends SkybridgeMode>({ resource, context, hash, }: { resource: R } & Pick<SkybridgeParams<R, M>, 'context' | 'hash'>): Promise< ReturnType<R, M> > => { const result = await (async () => { const bridge = bridgeCache.get(hash); if (bridge) { try { const result = await fetch<ServerReturnType<R, M>>( `${context.servers.swapNode[bridge]}/api/v1/${ resource === 'pool' ? 'floats' : 'swaps' }/query?hash=${hash}`, ); if (result.ok && result.response.items.length > 0) { bridgeCache.set(hash, bridge); return { bridge, data: result.response.items[0] }; } throw new Error(); } catch (e) { throw new Error(`Could not find swap with hash "${hash}"`); } } const results = await Promise.all( (Object.keys(context.servers.swapNode) as SkybridgeBridge[]).map(async (bridge) => { try { const result = await fetch<ServerReturnType<R, M>>( `${context.servers.swapNode[bridge]}/api/v1/${ resource === 'pool' ? 'floats' : 'swaps' }/query?hash=${hash}`, ); if (result.ok && result.response.items.length > 0) { bridgeCache.set(hash, bridge); return { bridge, data: result.response.items[0] }; } return null; } catch (e) { return null; } }), ); const result = results.find((it) => !!it); if (!result) { throw new Error(`Could not find swap with hash "${hash}"`); } return result; })(); if (resource === 'withdrawal' && !/^sbBTC/.test(result.data.currencyIn)) { throw new Error(`"${hash}" is not a withdrawal, it is a swap.`); } return ({ addressReceiving: result.data.addressOut, addressDeposit: result.data.addressDeposit, addressSending: result.data.addressIn || null, amountDeposit: result.data.amountIn, amountReceiving: result.data.amountOut || null, // Temporarily fixes API bug where it retuns `BTCE` instead of `WBTC` currencyDeposit: fromApiCoin({ bridge: result.bridge, coin: result.data.currencyIn as any }), currencyReceiving: fromApiCoin({ bridge: result.bridge, coin: result.data.currencyOut as any }), hash: result.data.hash || undefined, status: result.data.status, txDepositId: result.data.txIdIn || null, txReceivingId: result.data.txIdOut || null, timestamp: new Date(result.data.timestamp * 1000), feeCurrency: fromApiCoin({ bridge: result.bridge, coin: (result.data.feeCurrency as any) || null, }), feeTotal: result.data.fee, isSkypoolsSwap: resource === 'swap' && result.data.skypools === true, } as unknown) as ReturnType<R, M>; };