@atomiqlabs/sdk
Version:
atomiq labs SDK for cross-chain swaps between smart chains and bitcoin
173 lines (172 loc) • 6.39 kB
JavaScript
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.IEscrowSwap = exports.isIEscrowSwapInit = void 0;
const ISwap_1 = require("../ISwap");
const base_1 = require("@atomiqlabs/base");
const buffer_1 = require("buffer");
const TimeoutUtils_1 = require("../../utils/TimeoutUtils");
function isIEscrowSwapInit(obj) {
return typeof obj === 'object' &&
(obj.data == null || typeof obj.data === 'object') &&
(0, ISwap_1.isISwapInit)(obj);
}
exports.isIEscrowSwapInit = isIEscrowSwapInit;
/**
* Base class for escrow-based swaps (i.e. swaps utilizing PrTLC and HTLC primitives)
*
* @category Swaps/Abstract
*/
class IEscrowSwap extends ISwap_1.ISwap {
constructor(wrapper, swapInitOrObj) {
super(wrapper, swapInitOrObj);
if (isIEscrowSwapInit(swapInitOrObj)) {
this._data = swapInitOrObj.data;
}
else {
if (swapInitOrObj.data != null)
this._data = new (wrapper._swapDataDeserializer(this._contractVersion))(swapInitOrObj.data);
this._commitTxId = swapInitOrObj.commitTxId;
this._claimTxId = swapInitOrObj.claimTxId;
this._refundTxId = swapInitOrObj.refundTxId;
}
this._contract = wrapper._contract(this._contractVersion);
}
//////////////////////////////
//// Identifiers
/**
* Returns the identification hash of the swap, usually claim data hash, but can be overriden, e.g. for
* lightning swaps the identifier hash is used instead of claim data hash
*
* @internal
*/
getIdentifierHash() {
const claimHashBuffer = buffer_1.Buffer.from(this.getClaimHash(), "hex");
if (this._randomNonce == null)
return claimHashBuffer;
return buffer_1.Buffer.concat([claimHashBuffer, buffer_1.Buffer.from(this._randomNonce, "hex")]);
}
/**
* Returns the identification hash of the swap, usually claim data hash, but can be overriden, e.g. for
* lightning swaps the identifier hash is used instead of claim data hash
*
* @internal
*/
getIdentifierHashString() {
const identifierHash = this.getIdentifierHash();
return identifierHash.toString("hex");
}
/**
* @inheritDoc
* @internal
*/
_getEscrowHash() {
return this._data?.getEscrowHash() ?? null;
}
/**
* Returns the escrow hash - i.e. hash of the escrow data
*/
getEscrowHash() {
return this._getEscrowHash();
}
/**
* Returns the claim data hash specifying the claim path of the escrow - i.e. hash passed to the claim handler
*/
getClaimHash() {
return this.getSwapData().getClaimHash();
}
/**
* @inheritDoc
*/
getId() {
return this.getIdentifierHashString();
}
/**
* Returns the smart chain transaction ID of the tx that initiated the escrow
*/
getEscrowInitTxId() {
return this._commitTxId;
}
/**
* Returns the smart chain transaction ID of the tx that claimed (settled) the escrow
*/
getEscrowClaimTxId() {
return this._claimTxId;
}
/**
* Returns the smart chain transaction ID of the tx that refunded the escrow
*/
getEscrowRefundTxId() {
return this._refundTxId;
}
//////////////////////////////
//// Watchdogs
/**
* Periodically checks the chain to see whether the swap is committed
*
* @param intervalSeconds How often to check (in seconds), default to 5s
* @param abortSignal
* @internal
*/
async watchdogWaitTillCommited(intervalSeconds, abortSignal) {
if (this._data == null)
throw new Error("Tried to await commitment but data is null, invalid state?");
intervalSeconds ??= 5;
let status = { type: base_1.SwapCommitStateType.NOT_COMMITED };
while (status?.type === base_1.SwapCommitStateType.NOT_COMMITED) {
await (0, TimeoutUtils_1.timeoutPromise)(intervalSeconds * 1000, abortSignal);
try {
status = await this._contract.getCommitStatus(this._getInitiator(), this._data);
if (status?.type === base_1.SwapCommitStateType.NOT_COMMITED &&
await this._verifyQuoteDefinitelyExpired())
return null;
}
catch (e) {
this.logger.error("watchdogWaitTillCommited(): Error when fetching commit status or signature expiry: ", e);
}
}
if (abortSignal != null)
abortSignal.throwIfAborted();
return status?.type === base_1.SwapCommitStateType.EXPIRED
? null
: status;
}
/**
* Periodically checks the chain to see whether the swap was finished (claimed or refunded)
*
* @param intervalSeconds How often to check (in seconds), default to 5s
* @param abortSignal
* @internal
*/
async watchdogWaitTillResult(intervalSeconds, abortSignal) {
if (this._data == null)
throw new Error("Tried to await result but data is null, invalid state?");
intervalSeconds ??= 5;
let status = { type: base_1.SwapCommitStateType.COMMITED };
while (status?.type === base_1.SwapCommitStateType.COMMITED || status?.type === base_1.SwapCommitStateType.REFUNDABLE) {
await (0, TimeoutUtils_1.timeoutPromise)(intervalSeconds * 1000, abortSignal);
try {
status = await this._contract.getCommitStatus(this._getInitiator(), this._data);
}
catch (e) {
this.logger.error("watchdogWaitTillResult(): Error when fetching commit status: ", e);
}
}
if (abortSignal != null)
abortSignal.throwIfAborted();
return status;
}
/**
* @inheritDoc
*/
serialize() {
return {
...super.serialize(),
data: this._data != null ? this._data.serialize() : null,
commitTxId: this._commitTxId,
claimTxId: this._claimTxId,
refundTxId: this._refundTxId
};
}
;
}
exports.IEscrowSwap = IEscrowSwap;