UNPKG

@atomiqlabs/sdk

Version:

atomiq labs SDK for cross-chain swaps between smart chains and bitcoin

108 lines (100 loc) 4.08 kB
import {ISwapWrapperOptions} from "../../ISwapWrapper"; import {Intermediary} from "../../../intermediaries/Intermediary"; import {IntermediaryError} from "../../../errors/IntermediaryError"; import {mapArrayToObject, randomBytes} from "../../../utils/Utils"; import {BigIntBufferUtils, ChainType} from "@atomiqlabs/base"; import {IEscrowSwapDefinition, IEscrowSwapWrapper} from "../IEscrowSwapWrapper"; import {IEscrowSwap} from "../IEscrowSwap"; import {AmountData} from "../../../types/AmountData"; export type IFromBTCDefinition<T extends ChainType, W extends IFromBTCWrapper<T, any>, S extends IEscrowSwap<T>> = IEscrowSwapDefinition<T, W, S>; /** * Base class for wrappers of escrow-based Bitcoin (on-chain & lightning) -> Smart chain swaps * * @category Swaps/Abstract */ export abstract class IFromBTCWrapper< T extends ChainType, D extends IFromBTCDefinition<T, IFromBTCWrapper<T, D>, IEscrowSwap<T, D>>, O extends ISwapWrapperOptions = ISwapWrapperOptions > extends IEscrowSwapWrapper<T, D, O> { /** * Returns a random sequence to be used for swaps * * @returns Random 64-bit sequence number * * @internal */ protected getRandomSequence(): bigint { return BigIntBufferUtils.fromBuffer(randomBytes(8)); } /** * Pre-fetches smart chain fee rate for initiating a swap escrow on the smart chain side * * @param signer Address initiating the swap * @param amountData * @param claimHash optional claim hash of the swap or null * @param abortController * * @param contractVersions * @returns Fee rate * * @internal */ protected preFetchFeeRate( signer: string, amountData: AmountData, claimHash: {[contractVersion: string]: string} | undefined, abortController: AbortController, contractVersions: string[] ): {[contractVersion: string]: Promise<string | undefined>} { return mapArrayToObject(contractVersions, (contractVersion) => { return this._contract(contractVersion).getInitFeeRate(this._chain.randomAddress(), signer, amountData.token, claimHash?.[contractVersion]) .catch(e => { this.logger.warn("preFetchFeeRate(): Error: ", e); abortController.abort(e); return undefined; }); }); } /** * Pre-fetches intermediary (LP) available smart chain liquidity * * @param amountData * @param lp Intermediary * @param abortController * * @param contractVersion * @returns Intermediary's liquidity balance * * @internal */ protected preFetchIntermediaryLiquidity( amountData: AmountData, lp: Intermediary, abortController: AbortController, contractVersion: string ): Promise<bigint | undefined> { return lp.getLiquidity(this.chainIdentifier, this._contract(contractVersion), amountData.token.toString(), abortController.signal).catch(e => { this.logger.warn("preFetchIntermediaryLiquidity(): Error: ", e); abortController.abort(e); return undefined; }) } /** * Verifies whether the intermediary (LP) has enough available liquidity such that we can initiate the swap * * @param amount Swap amount that the recipient should receive * @param liquidityPromise pre-fetched liquidity promise as obtained from {@link preFetchIntermediaryLiquidity} * * @throws {IntermediaryError} if intermediary's liquidity is lower than what's required for the swap * * @internal */ protected async verifyIntermediaryLiquidity( amount: bigint, liquidityPromise: Promise<bigint> ): Promise<void> { const liquidity = await liquidityPromise; if(liquidity < amount) throw new IntermediaryError("Intermediary doesn't have enough liquidity"); } }