UNPKG

@atomiqlabs/sdk-lib

Version:

Basic SDK functionality library for atomiq

99 lines (89 loc) 4.24 kB
import {IToBTCSwap, ToBTCSwapState} from "./IToBTCSwap"; import {ChainType, ClaimEvent, InitializeEvent, RefundEvent, SwapCommitStatus} from "@atomiqlabs/base"; import {AmountData, ISwapWrapper, ISwapWrapperOptions} from "../ISwapWrapper"; import {tryWithRetries} from "../../utils/Utils"; import {Intermediary, SingleChainReputationType} from "../../intermediaries/Intermediary"; import {IntermediaryError} from "../../errors/IntermediaryError"; export abstract class IToBTCWrapper< T extends ChainType, S extends IToBTCSwap<T> = IToBTCSwap<T>, O extends ISwapWrapperOptions = ISwapWrapperOptions > extends ISwapWrapper<T, S, O> { /** * Pre-fetches intermediary's reputation, doesn't throw, instead aborts via abortController and returns null * * @param amountData * @param lp Intermediary * @param abortController * @protected * @returns Intermediary's reputation or null if failed * @throws {IntermediaryError} If the intermediary vault doesn't exist */ protected preFetchIntermediaryReputation( amountData: Omit<AmountData, "amount">, lp: Intermediary, abortController: AbortController ): Promise<SingleChainReputationType | null> { return lp.getReputation(this.chainIdentifier, this.contract, [amountData.token.toString()], abortController.signal).then(res => { if(res==null) throw new IntermediaryError("Invalid data returned - invalid LP vault"); return res; }).catch(e => { this.logger.warn("preFetchIntermediaryReputation(): Error: ", e); abortController.abort(e); return null; }); } /** * Pre-fetches feeRate for a given swap * * @param signer Address of the swap initiator * @param amountData * @param claimHash optional hash of the swap or null * @param abortController * @protected * @returns Fee rate */ protected preFetchFeeRate(signer: string, amountData: Omit<AmountData, "amount">, claimHash: string | null, abortController: AbortController): Promise<any | null> { return tryWithRetries( () => this.contract.getInitPayInFeeRate(signer, null, amountData.token, claimHash), null, null, abortController.signal ).catch(e => { this.logger.warn("preFetchFeeRate(): Error: ", e); abortController.abort(e); return null; }); } public readonly pendingSwapStates = [ ToBTCSwapState.CREATED, ToBTCSwapState.QUOTE_SOFT_EXPIRED, ToBTCSwapState.COMMITED, ToBTCSwapState.SOFT_CLAIMED, ToBTCSwapState.REFUNDABLE ]; public readonly tickSwapState = [ToBTCSwapState.CREATED, ToBTCSwapState.COMMITED, ToBTCSwapState.SOFT_CLAIMED]; public readonly refundableSwapStates = [ToBTCSwapState.REFUNDABLE]; protected async processEventInitialize(swap: S, event: InitializeEvent<T["Data"]>): Promise<boolean> { if(swap.state===ToBTCSwapState.CREATED || swap.state===ToBTCSwapState.QUOTE_SOFT_EXPIRED) { const swapData = await event.swapData(); if(swap.data!=null && !swap.data.equals(swapData)) return false; if(swap.state===ToBTCSwapState.CREATED || swap.state===ToBTCSwapState.QUOTE_SOFT_EXPIRED) swap.state = ToBTCSwapState.COMMITED; swap.data = swapData; return true; } } protected processEventClaim(swap: S, event: ClaimEvent<T["Data"]>): Promise<boolean> { if(swap.state!==ToBTCSwapState.REFUNDED) { swap.state = ToBTCSwapState.CLAIMED; swap._setPaymentResult({secret: event.result, txId: Buffer.from(event.result, "hex").reverse().toString("hex")}); return Promise.resolve(true); } return Promise.resolve(false); } protected processEventRefund(swap: S, event: RefundEvent<T["Data"]>): Promise<boolean> { if(swap.state!==ToBTCSwapState.CLAIMED) { swap.state = ToBTCSwapState.REFUNDED; return Promise.resolve(true); } return Promise.resolve(false); } }