@atomiqlabs/sdk-lib
Version:
Basic SDK functionality library for atomiq
99 lines (89 loc) • 4.24 kB
text/typescript
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);
}
}