@atomiqlabs/sdk
Version:
atomiq labs SDK for cross-chain swaps between smart chains and bitcoin
765 lines (764 loc) • 40.2 kB
JavaScript
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.IntermediaryAPI = exports.TrustedAddressStatusResponseCodes = exports.TrustedInvoiceStatusResponseCodes = exports.InvoiceStatusResponseCodes = exports.PaymentAuthorizationResponseCodes = exports.RefundAuthorizationResponseCodes = void 0;
const RequestError_1 = require("../../errors/RequestError");
const SchemaVerifier_1 = require("../../http/paramcoders/SchemaVerifier");
const StreamingFetchPromise_1 = require("../../http/paramcoders/client/StreamingFetchPromise");
const Utils_1 = require("../../utils/Utils");
const HttpUtils_1 = require("../../http/HttpUtils");
const RetryUtils_1 = require("../../utils/RetryUtils");
var RefundAuthorizationResponseCodes;
(function (RefundAuthorizationResponseCodes) {
RefundAuthorizationResponseCodes[RefundAuthorizationResponseCodes["EXPIRED"] = 20010] = "EXPIRED";
RefundAuthorizationResponseCodes[RefundAuthorizationResponseCodes["REFUND_DATA"] = 20000] = "REFUND_DATA";
RefundAuthorizationResponseCodes[RefundAuthorizationResponseCodes["NOT_FOUND"] = 20007] = "NOT_FOUND";
RefundAuthorizationResponseCodes[RefundAuthorizationResponseCodes["PENDING"] = 20008] = "PENDING";
RefundAuthorizationResponseCodes[RefundAuthorizationResponseCodes["PAID"] = 20006] = "PAID";
})(RefundAuthorizationResponseCodes = exports.RefundAuthorizationResponseCodes || (exports.RefundAuthorizationResponseCodes = {}));
var PaymentAuthorizationResponseCodes;
(function (PaymentAuthorizationResponseCodes) {
PaymentAuthorizationResponseCodes[PaymentAuthorizationResponseCodes["AUTH_DATA"] = 10000] = "AUTH_DATA";
PaymentAuthorizationResponseCodes[PaymentAuthorizationResponseCodes["EXPIRED"] = 10001] = "EXPIRED";
PaymentAuthorizationResponseCodes[PaymentAuthorizationResponseCodes["PAID"] = 10002] = "PAID";
PaymentAuthorizationResponseCodes[PaymentAuthorizationResponseCodes["PENDING"] = 10003] = "PENDING";
PaymentAuthorizationResponseCodes[PaymentAuthorizationResponseCodes["ALREADY_COMMITTED"] = 10004] = "ALREADY_COMMITTED";
})(PaymentAuthorizationResponseCodes = exports.PaymentAuthorizationResponseCodes || (exports.PaymentAuthorizationResponseCodes = {}));
var InvoiceStatusResponseCodes;
(function (InvoiceStatusResponseCodes) {
InvoiceStatusResponseCodes[InvoiceStatusResponseCodes["PAID"] = 10000] = "PAID";
InvoiceStatusResponseCodes[InvoiceStatusResponseCodes["EXPIRED"] = 10001] = "EXPIRED";
InvoiceStatusResponseCodes[InvoiceStatusResponseCodes["SETTLED"] = 10002] = "SETTLED";
InvoiceStatusResponseCodes[InvoiceStatusResponseCodes["PENDING"] = 10003] = "PENDING";
})(InvoiceStatusResponseCodes = exports.InvoiceStatusResponseCodes || (exports.InvoiceStatusResponseCodes = {}));
const SwapResponseSchema = {
data: SchemaVerifier_1.FieldTypeEnum.Any,
prefix: SchemaVerifier_1.FieldTypeEnum.String,
timeout: SchemaVerifier_1.FieldTypeEnum.String,
signature: SchemaVerifier_1.FieldTypeEnum.String
};
/////////////////////////
///// To BTC
const ToBTCResponseSchema = {
amount: SchemaVerifier_1.FieldTypeEnum.BigInt,
address: SchemaVerifier_1.FieldTypeEnum.String,
satsPervByte: SchemaVerifier_1.FieldTypeEnum.BigInt,
networkFee: SchemaVerifier_1.FieldTypeEnum.BigInt,
swapFee: SchemaVerifier_1.FieldTypeEnum.BigInt,
totalFee: SchemaVerifier_1.FieldTypeEnum.BigInt,
total: SchemaVerifier_1.FieldTypeEnum.BigInt,
minRequiredExpiry: SchemaVerifier_1.FieldTypeEnum.BigInt,
...SwapResponseSchema
};
/////////////////////////
///// To BTCLN
const ToBTCLNResponseSchema = {
maxFee: SchemaVerifier_1.FieldTypeEnum.BigInt,
swapFee: SchemaVerifier_1.FieldTypeEnum.BigInt,
total: SchemaVerifier_1.FieldTypeEnum.BigInt,
confidence: SchemaVerifier_1.FieldTypeEnum.Number,
address: SchemaVerifier_1.FieldTypeEnum.String,
routingFeeSats: SchemaVerifier_1.FieldTypeEnum.BigInt,
...SwapResponseSchema
};
const ToBTCLNPrepareExactInSchema = {
amount: SchemaVerifier_1.FieldTypeEnum.BigInt,
reqId: SchemaVerifier_1.FieldTypeEnum.String
};
/////////////////////////
///// From BTC
const FromBTCResponseSchema = {
amount: SchemaVerifier_1.FieldTypeEnum.BigInt,
btcAddress: SchemaVerifier_1.FieldTypeEnum.String,
address: SchemaVerifier_1.FieldTypeEnum.String,
swapFee: SchemaVerifier_1.FieldTypeEnum.BigInt,
total: SchemaVerifier_1.FieldTypeEnum.BigInt,
confirmations: SchemaVerifier_1.FieldTypeEnum.Number,
...SwapResponseSchema
};
/////////////////////////
///// From BTCLN
const FromBTCLNResponseSchema = {
pr: SchemaVerifier_1.FieldTypeEnum.String,
swapFee: SchemaVerifier_1.FieldTypeEnum.BigInt,
total: SchemaVerifier_1.FieldTypeEnum.BigInt,
intermediaryKey: SchemaVerifier_1.FieldTypeEnum.String,
securityDeposit: SchemaVerifier_1.FieldTypeEnum.BigInt
};
/////////////////////////
///// From BTCLN Auto
const FromBTCLNAutoResponseSchema = {
intermediaryKey: SchemaVerifier_1.FieldTypeEnum.String,
pr: SchemaVerifier_1.FieldTypeEnum.String,
btcAmountSwap: SchemaVerifier_1.FieldTypeEnum.BigInt,
btcAmountGas: SchemaVerifier_1.FieldTypeEnum.BigInt,
total: SchemaVerifier_1.FieldTypeEnum.BigInt,
totalGas: SchemaVerifier_1.FieldTypeEnum.BigInt,
totalFeeBtc: SchemaVerifier_1.FieldTypeEnum.BigInt,
swapFeeBtc: SchemaVerifier_1.FieldTypeEnum.BigInt,
swapFee: SchemaVerifier_1.FieldTypeEnum.BigInt,
gasSwapFeeBtc: SchemaVerifier_1.FieldTypeEnum.BigInt,
gasSwapFee: SchemaVerifier_1.FieldTypeEnum.BigInt,
claimerBounty: SchemaVerifier_1.FieldTypeEnum.BigInt
};
/////////////////////////
///// Spv vault from BTC
const SpvFromBTCPrepareResponseSchema = {
quoteId: SchemaVerifier_1.FieldTypeEnum.String,
expiry: SchemaVerifier_1.FieldTypeEnum.Number,
address: SchemaVerifier_1.FieldTypeEnum.String,
vaultId: SchemaVerifier_1.FieldTypeEnum.BigInt,
vaultBtcAddress: SchemaVerifier_1.FieldTypeEnum.String,
btcAddress: SchemaVerifier_1.FieldTypeEnum.String,
btcUtxo: SchemaVerifier_1.FieldTypeEnum.String,
btcFeeRate: SchemaVerifier_1.FieldTypeEnum.Number,
btcAmount: SchemaVerifier_1.FieldTypeEnum.BigInt,
btcAmountSwap: SchemaVerifier_1.FieldTypeEnum.BigInt,
btcAmountGas: SchemaVerifier_1.FieldTypeEnum.BigInt,
total: SchemaVerifier_1.FieldTypeEnum.BigInt,
totalGas: SchemaVerifier_1.FieldTypeEnum.BigInt,
totalFeeBtc: SchemaVerifier_1.FieldTypeEnum.BigInt,
swapFeeBtc: SchemaVerifier_1.FieldTypeEnum.BigInt,
swapFee: SchemaVerifier_1.FieldTypeEnum.BigInt,
gasSwapFeeBtc: SchemaVerifier_1.FieldTypeEnum.BigInt,
gasSwapFee: SchemaVerifier_1.FieldTypeEnum.BigInt,
callerFeeShare: SchemaVerifier_1.FieldTypeEnum.BigInt,
frontingFeeShare: SchemaVerifier_1.FieldTypeEnum.BigInt,
executionFeeShare: SchemaVerifier_1.FieldTypeEnum.BigInt,
usedUtxoInputCalculation: SchemaVerifier_1.FieldTypeEnum.BooleanOptional
};
const SpvFromBTCInitResponseSchema = {
txId: SchemaVerifier_1.FieldTypeEnum.String
};
/////////////////////////
///// Trusted from BTCLN
var TrustedInvoiceStatusResponseCodes;
(function (TrustedInvoiceStatusResponseCodes) {
TrustedInvoiceStatusResponseCodes[TrustedInvoiceStatusResponseCodes["EXPIRED"] = 10001] = "EXPIRED";
TrustedInvoiceStatusResponseCodes[TrustedInvoiceStatusResponseCodes["PAID"] = 10000] = "PAID";
TrustedInvoiceStatusResponseCodes[TrustedInvoiceStatusResponseCodes["AWAIT_PAYMENT"] = 10010] = "AWAIT_PAYMENT";
TrustedInvoiceStatusResponseCodes[TrustedInvoiceStatusResponseCodes["PENDING"] = 10011] = "PENDING";
TrustedInvoiceStatusResponseCodes[TrustedInvoiceStatusResponseCodes["TX_SENT"] = 10012] = "TX_SENT";
})(TrustedInvoiceStatusResponseCodes = exports.TrustedInvoiceStatusResponseCodes || (exports.TrustedInvoiceStatusResponseCodes = {}));
const TrustedFromBTCLNResponseSchema = {
pr: SchemaVerifier_1.FieldTypeEnum.String,
swapFee: SchemaVerifier_1.FieldTypeEnum.BigInt,
swapFeeSats: SchemaVerifier_1.FieldTypeEnum.BigInt,
total: SchemaVerifier_1.FieldTypeEnum.BigInt
};
/////////////////////////
///// Trusted from BTC
var TrustedAddressStatusResponseCodes;
(function (TrustedAddressStatusResponseCodes) {
TrustedAddressStatusResponseCodes[TrustedAddressStatusResponseCodes["EXPIRED"] = 10001] = "EXPIRED";
TrustedAddressStatusResponseCodes[TrustedAddressStatusResponseCodes["PAID"] = 10000] = "PAID";
TrustedAddressStatusResponseCodes[TrustedAddressStatusResponseCodes["AWAIT_PAYMENT"] = 10010] = "AWAIT_PAYMENT";
TrustedAddressStatusResponseCodes[TrustedAddressStatusResponseCodes["AWAIT_CONFIRMATION"] = 10011] = "AWAIT_CONFIRMATION";
TrustedAddressStatusResponseCodes[TrustedAddressStatusResponseCodes["PENDING"] = 10013] = "PENDING";
TrustedAddressStatusResponseCodes[TrustedAddressStatusResponseCodes["TX_SENT"] = 10012] = "TX_SENT";
TrustedAddressStatusResponseCodes[TrustedAddressStatusResponseCodes["REFUNDED"] = 10014] = "REFUNDED";
TrustedAddressStatusResponseCodes[TrustedAddressStatusResponseCodes["DOUBLE_SPENT"] = 10015] = "DOUBLE_SPENT";
TrustedAddressStatusResponseCodes[TrustedAddressStatusResponseCodes["REFUNDABLE"] = 10016] = "REFUNDABLE";
})(TrustedAddressStatusResponseCodes = exports.TrustedAddressStatusResponseCodes || (exports.TrustedAddressStatusResponseCodes = {}));
const TrustedFromBTCResponseSchema = {
paymentHash: SchemaVerifier_1.FieldTypeEnum.String,
sequence: SchemaVerifier_1.FieldTypeEnum.BigInt,
btcAddress: SchemaVerifier_1.FieldTypeEnum.String,
amountSats: SchemaVerifier_1.FieldTypeEnum.BigInt,
swapFeeSats: SchemaVerifier_1.FieldTypeEnum.BigInt,
swapFee: SchemaVerifier_1.FieldTypeEnum.BigInt,
total: SchemaVerifier_1.FieldTypeEnum.BigInt,
intermediaryKey: SchemaVerifier_1.FieldTypeEnum.String,
recommendedFee: SchemaVerifier_1.FieldTypeEnum.Number,
expiresAt: SchemaVerifier_1.FieldTypeEnum.Number
};
class IntermediaryAPI {
constructor(requestHeaders) {
this.requestHeaders = requestHeaders;
}
httpGet(url, timeout, abortSignal, allowNon200 = false) {
const headers = this.requestHeaders == null ? {} : this.requestHeaders("GET", url);
return (0, HttpUtils_1.httpGet)(url, timeout, abortSignal, allowNon200, headers);
}
httpPost(url, body, timeout, abortSignal) {
const headers = this.requestHeaders == null ? {} : this.requestHeaders("POST", url, body);
return (0, HttpUtils_1.httpPost)(url, body, timeout, abortSignal, headers);
}
streamingFetchPromise(url, body, schema, timeout, signal, streamRequest) {
const headers = this.requestHeaders == null ? {} : this.requestHeaders("POST", url);
return (0, StreamingFetchPromise_1.streamingFetchPromise)(url, body, schema, timeout, signal, streamRequest, headers);
}
/**
* Returns the information about a specific intermediary
*
* @param baseUrl Base URL of the intermediary
* @param timeout Timeout in milliseconds for the HTTP request
* @param abortSignal
*
* @throws {RequestError} If non-200 http response code is returned
* @throws {Error} If the supplied nonce doesn't match the response
*/
async getIntermediaryInfo(baseUrl, timeout, abortSignal) {
const nonce = (0, Utils_1.randomBytes)(32).toString("hex");
const abortController = (0, Utils_1.extendAbortController)(abortSignal);
//We don't know whether the node supports only POST or also has GET info support enabled
// here we try both, and abort when the first one returns (which should be GET)
const response = await Promise.any([
this.httpGet(baseUrl + "/info?nonce=" + nonce, timeout, abortController.signal),
this.httpPost(baseUrl + "/info", {
nonce,
}, timeout, abortController.signal)
]);
abortController.abort();
const info = JSON.parse(response.envelope);
if (nonce !== info.nonce)
throw new Error("Invalid response - nonce");
return response;
}
/**
* Returns the information about an outcome of the To BTC swap
*
* @param url URL of the intermediary
* @param paymentHash Payment hash of the swap
* @param sequence Swap's sequence number
* @param timeout Timeout in milliseconds for the HTTP request
* @param abortSignal
*
* @throws {RequestError} If non-200 http response code is returned
*/
async getRefundAuthorization(url, paymentHash, sequence, timeout, abortSignal) {
return (0, RetryUtils_1.tryWithRetries)(() => this.httpGet(url + "/getRefundAuthorization" +
"?paymentHash=" + encodeURIComponent(paymentHash) +
"&sequence=" + encodeURIComponent(sequence.toString(10)), timeout, abortSignal), undefined, RequestError_1.RequestError, abortSignal);
}
/**
* Returns the information about the payment of the From BTCLN swaps
*
* @param url URL of the intermediary
* @param paymentHash Payment hash of the swap
* @param timeout Timeout in milliseconds for the HTTP request
* @param abortSignal
*
* @throws {RequestError} If non-200 http response code is returned
*/
async getPaymentAuthorization(url, paymentHash, timeout, abortSignal) {
return (0, RetryUtils_1.tryWithRetries)(() => this.httpGet(url + "/getInvoicePaymentAuth" +
"?paymentHash=" + encodeURIComponent(paymentHash), timeout, abortSignal), undefined, RequestError_1.RequestError, abortSignal);
}
/**
* Returns the status of the payment of the From BTCLN swaps
*
* @param url URL of the intermediary
* @param paymentHash Payment hash of the swap
* @param timeout Timeout in milliseconds for the HTTP request
* @param abortSignal
*
* @throws {RequestError} If non-200 http response code is returned
*/
async getInvoiceStatus(url, paymentHash, timeout, abortSignal) {
return (0, RetryUtils_1.tryWithRetries)(() => this.httpGet(url + "/getInvoiceStatus" +
"?paymentHash=" + encodeURIComponent(paymentHash), timeout, abortSignal), undefined, RequestError_1.RequestError, abortSignal);
}
/**
* Initiate To BTC swap with an intermediary
*
* @param chainIdentifier
* @param baseUrl Base URL of the intermediary
* @param init Swap initialization parameters
* @param timeout Timeout in milliseconds for the HTTP request
* @param abortSignal
* @param streamRequest Whether to force streaming (or not streaming) the request, default is autodetect
*
* @throws {RequestError} If non-200 http response code is returned
*/
initToBTC(chainIdentifier, baseUrl, init, timeout, abortSignal, streamRequest) {
const responseBodyPromise = this.streamingFetchPromise(baseUrl + "/tobtc/payInvoice?chain=" + encodeURIComponent(chainIdentifier), {
...init.additionalParams,
address: init.btcAddress,
amount: init.amount.toString(10),
exactIn: init.exactIn,
confirmationTarget: init.confirmationTarget,
confirmations: init.confirmations,
nonce: init.nonce.toString(10),
token: init.token,
offerer: init.offerer,
feeRate: init.feeRate
}, {
code: SchemaVerifier_1.FieldTypeEnum.Number,
msg: SchemaVerifier_1.FieldTypeEnum.String,
data: SchemaVerifier_1.FieldTypeEnum.AnyOptional,
signDataPrefetch: SchemaVerifier_1.FieldTypeEnum.AnyOptional
}, timeout, abortSignal, streamRequest);
return {
signDataPrefetch: responseBodyPromise.then(responseBody => responseBody.signDataPrefetch),
response: responseBodyPromise.then((responseBody) => Promise.all([
responseBody.code,
responseBody.msg,
responseBody.data,
])).then(([code, msg, data]) => {
if (code !== 20000) {
throw RequestError_1.RequestError.parse(JSON.stringify({ code, msg, data }), 400);
}
const result = (0, SchemaVerifier_1.verifySchema)(data, ToBTCResponseSchema);
if (result == null)
throw new RequestError_1.RequestError("Cannot parse the response with the expected schema", 200);
return result;
})
};
}
/**
* Initiate From BTC swap with an intermediary
*
* @param chainIdentifier
* @param baseUrl Base URL of the intermediary
* @param depositToken
* @param init Swap initialization parameters
* @param timeout Timeout in milliseconds for the HTTP request
* @param abortSignal
* @param streamRequest Whether to force streaming (or not streaming) the request, default is autodetect
*
* @throws {RequestError} If non-200 http response code is returned
*/
initFromBTC(chainIdentifier, baseUrl, depositToken, init, timeout, abortSignal, streamRequest) {
const responseBodyPromise = this.streamingFetchPromise(baseUrl + "/frombtc/getAddress?chain=" + encodeURIComponent(chainIdentifier) + "&depositToken=" + encodeURIComponent(depositToken), {
...init.additionalParams,
address: init.claimer,
amount: init.amount.toString(10),
token: init.token,
exactOut: init.exactOut,
sequence: init.sequence.toString(10),
claimerBounty: init.claimerBounty.then(claimerBounty => {
return {
feePerBlock: claimerBounty.feePerBlock.toString(10),
safetyFactor: claimerBounty.safetyFactor.toString(10),
startTimestamp: claimerBounty.startTimestamp.toString(10),
addBlock: claimerBounty.addBlock.toString(10),
addFee: claimerBounty.addFee.toString(10)
};
}),
feeRate: init.feeRate
}, {
code: SchemaVerifier_1.FieldTypeEnum.Number,
msg: SchemaVerifier_1.FieldTypeEnum.String,
data: SchemaVerifier_1.FieldTypeEnum.AnyOptional,
signDataPrefetch: SchemaVerifier_1.FieldTypeEnum.AnyOptional
}, timeout, abortSignal, streamRequest);
return {
signDataPrefetch: responseBodyPromise.then(responseBody => responseBody.signDataPrefetch),
response: responseBodyPromise.then((responseBody) => Promise.all([
responseBody.code,
responseBody.msg,
responseBody.data,
])).then(([code, msg, data]) => {
if (code !== 20000) {
throw RequestError_1.RequestError.parse(JSON.stringify({ code, msg, data }), 400);
}
const result = (0, SchemaVerifier_1.verifySchema)(data, FromBTCResponseSchema);
if (result == null)
throw new RequestError_1.RequestError("Cannot parse the response with the expected schema", 200);
return result;
})
};
}
/**
* Initiate From BTCLN swap with an intermediary
*
* @param chainIdentifier
* @param baseUrl Base URL of the intermediary
* @param depositToken
* @param init Swap initialization parameters
* @param timeout Timeout in milliseconds for the HTTP request
* @param abortSignal
* @param streamRequest Whether to force streaming (or not streaming) the request, default is autodetect
*
* @throws {RequestError} If non-200 http response code is returned
*/
initFromBTCLN(chainIdentifier, baseUrl, depositToken, init, timeout, abortSignal, streamRequest) {
const responseBodyPromise = this.streamingFetchPromise(baseUrl + "/frombtcln/createInvoice?chain=" + encodeURIComponent(chainIdentifier) + "&depositToken=" + encodeURIComponent(depositToken), {
...init.additionalParams,
paymentHash: init.paymentHash.toString("hex"),
amount: init.amount.toString(),
address: init.claimer,
token: init.token,
description: init.description ?? null,
descriptionHash: init.descriptionHash == null ? null : init.descriptionHash.toString("hex"),
exactOut: init.exactOut,
feeRate: init.feeRate
}, {
code: SchemaVerifier_1.FieldTypeEnum.Number,
msg: SchemaVerifier_1.FieldTypeEnum.String,
data: SchemaVerifier_1.FieldTypeEnum.AnyOptional,
lnPublicKey: SchemaVerifier_1.FieldTypeEnum.StringOptional
}, timeout, abortSignal, streamRequest);
return {
lnPublicKey: responseBodyPromise.then(responseBody => responseBody.lnPublicKey),
response: responseBodyPromise.then((responseBody) => Promise.all([
responseBody.code,
responseBody.msg,
responseBody.data,
])).then(([code, msg, data]) => {
if (code !== 20000) {
throw RequestError_1.RequestError.parse(JSON.stringify({ code, msg, data }), 400);
}
const result = (0, SchemaVerifier_1.verifySchema)(data, FromBTCLNResponseSchema);
if (result == null)
throw new RequestError_1.RequestError("Cannot parse the response with the expected schema", 200);
return result;
})
};
}
/**
* Initiate From BTCLN swap with auto-initilization by an intermediary
*
* @param chainIdentifier
* @param baseUrl Base URL of the intermediary
* @param init Swap initialization parameters
* @param timeout Timeout in milliseconds for the HTTP request
* @param abortSignal
* @param streamRequest Whether to force streaming (or not streaming) the request, default is autodetect
*
* @throws {RequestError} If non-200 http response code is returned
*/
initFromBTCLNAuto(chainIdentifier, baseUrl, init, timeout, abortSignal, streamRequest) {
const responseBodyPromise = this.streamingFetchPromise(baseUrl + "/frombtcln_auto/createInvoice?chain=" + encodeURIComponent(chainIdentifier), {
...init.additionalParams,
paymentHash: init.paymentHash.toString("hex"),
amount: init.amount.toString(),
address: init.claimer,
token: init.token,
description: init.description ?? null,
descriptionHash: init.descriptionHash == null ? null : init.descriptionHash.toString("hex"),
exactOut: init.exactOut,
gasToken: init.gasToken,
gasAmount: init.gasAmount?.toString(10) ?? "0",
claimerBounty: init.claimerBounty?.then(val => val.toString(10)) ?? "0"
}, {
code: SchemaVerifier_1.FieldTypeEnum.Number,
msg: SchemaVerifier_1.FieldTypeEnum.String,
data: SchemaVerifier_1.FieldTypeEnum.AnyOptional,
lnPublicKey: SchemaVerifier_1.FieldTypeEnum.StringOptional
}, timeout, abortSignal, streamRequest);
return {
lnPublicKey: responseBodyPromise.then(responseBody => responseBody.lnPublicKey),
response: responseBodyPromise.then((responseBody) => Promise.all([
responseBody.code,
responseBody.msg,
responseBody.data,
])).then(([code, msg, data]) => {
if (code !== 20000) {
throw RequestError_1.RequestError.parse(JSON.stringify({ code, msg, data }), 400);
}
const result = (0, SchemaVerifier_1.verifySchema)(data, FromBTCLNAutoResponseSchema);
if (result == null)
throw new RequestError_1.RequestError("Cannot parse the response with the expected schema", 200);
return result;
})
};
}
/**
* Initiate To BTCLN swap with an intermediary
*
* @param chainIdentifier
* @param baseUrl Base URL of the intermediary
* @param init Swap initialization parameters
* @param timeout Timeout in milliseconds for the HTTP request
* @param abortSignal
* @param streamRequest Whether to force streaming (or not streaming) the request, default is autodetect
*
* @throws {RequestError} If non-200 http response code is returned
*/
initToBTCLN(chainIdentifier, baseUrl, init, timeout, abortSignal, streamRequest) {
const responseBodyPromise = this.streamingFetchPromise(baseUrl + "/tobtcln/payInvoice?chain=" + encodeURIComponent(chainIdentifier), {
exactIn: false,
...init.additionalParams,
pr: init.pr,
maxFee: init.maxFee.toString(10),
expiryTimestamp: init.expiryTimestamp.toString(10),
token: init.token,
offerer: init.offerer,
feeRate: init.feeRate,
amount: null
}, {
code: SchemaVerifier_1.FieldTypeEnum.Number,
msg: SchemaVerifier_1.FieldTypeEnum.String,
data: SchemaVerifier_1.FieldTypeEnum.AnyOptional,
signDataPrefetch: SchemaVerifier_1.FieldTypeEnum.AnyOptional
}, timeout, abortSignal, streamRequest);
return {
signDataPrefetch: responseBodyPromise.then(responseBody => responseBody.signDataPrefetch),
response: responseBodyPromise.then((responseBody) => Promise.all([
responseBody.code,
responseBody.msg,
responseBody.data,
])).then(([code, msg, data]) => {
if (code !== 20000) {
throw RequestError_1.RequestError.parse(JSON.stringify({ code, msg, data }), 400);
}
const result = (0, SchemaVerifier_1.verifySchema)(data, ToBTCLNResponseSchema);
if (result == null)
throw new RequestError_1.RequestError("Cannot parse the response with the expected schema", 200);
return result;
})
};
}
/**
* Initiate To BTCLN exact in swap with an intermediary
*
* @param baseUrl Base URL of the intermediary
* @param init Swap initialization parameters
* @param timeout Timeout in milliseconds for the HTTP request
* @param abortSignal
* @param streamRequest Whether to force streaming (or not streaming) the request, default is autodetect
*
* @throws {RequestError} If non-200 http response code is returned
*/
async initToBTCLNExactIn(baseUrl, init, timeout, abortSignal, streamRequest) {
const responseBody = await this.streamingFetchPromise(baseUrl + "/tobtcln/payInvoiceExactIn", {
...init.additionalParams,
pr: init.pr,
reqId: init.reqId,
feeRate: init.feeRate
}, {
code: SchemaVerifier_1.FieldTypeEnum.Number,
msg: SchemaVerifier_1.FieldTypeEnum.String,
data: SchemaVerifier_1.FieldTypeEnum.AnyOptional
}, timeout, abortSignal, streamRequest);
const [code, msg, data] = await Promise.all([
responseBody.code,
responseBody.msg,
responseBody.data,
]);
if (code !== 20000)
throw RequestError_1.RequestError.parse(JSON.stringify({ code, msg, data }), 400);
const result = (0, SchemaVerifier_1.verifySchema)(data, ToBTCLNResponseSchema);
if (result == null)
throw new RequestError_1.RequestError("Cannot parse the response with the expected schema", 200);
return result;
}
/**
* Prepare To BTCLN exact in swap with an intermediary
*
* @param chainIdentifier
* @param baseUrl Base URL of the intermediary
* @param init Swap initialization parameters
* @param timeout Timeout in milliseconds for the HTTP request
* @param abortSignal
* @param streamRequest Whether to force streaming (or not streaming) the request, default is autodetect
*
* @throws {RequestError} If non-200 http response code is returned
*/
prepareToBTCLNExactIn(chainIdentifier, baseUrl, init, timeout, abortSignal, streamRequest) {
const responseBodyPromise = this.streamingFetchPromise(baseUrl + "/tobtcln/payInvoice?chain=" + encodeURIComponent(chainIdentifier), {
exactIn: true,
...init.additionalParams,
pr: init.pr,
maxFee: init.maxFee.toString(10),
expiryTimestamp: init.expiryTimestamp.toString(10),
token: init.token,
offerer: init.offerer,
amount: init.amount.toString(10)
}, {
code: SchemaVerifier_1.FieldTypeEnum.Number,
msg: SchemaVerifier_1.FieldTypeEnum.String,
data: SchemaVerifier_1.FieldTypeEnum.AnyOptional,
signDataPrefetch: SchemaVerifier_1.FieldTypeEnum.AnyOptional
}, timeout, abortSignal, streamRequest);
return {
signDataPrefetch: responseBodyPromise.then(responseBody => responseBody.signDataPrefetch),
response: responseBodyPromise.then((responseBody) => Promise.all([
responseBody.code,
responseBody.msg,
responseBody.data,
])).then(([code, msg, data]) => {
if (code !== 20000) {
throw RequestError_1.RequestError.parse(JSON.stringify({ code, msg, data }), 400);
}
const result = (0, SchemaVerifier_1.verifySchema)(data, ToBTCLNPrepareExactInSchema);
if (result == null)
throw new RequestError_1.RequestError("Cannot parse the response with the expected schema", 200);
return result;
})
};
}
/**
* Prepare From BTC swap via new spv vault swaps with an intermediary
*
* @param chainIdentifier
* @param baseUrl Base URL of the intermediary
* @param init Swap initialization parameters
* @param timeout Timeout in milliseconds for the HTTP request
* @param abortSignal
* @param streamRequest Whether to force streaming (or not streaming) the request, default is autodetect
*
* @throws {RequestError} If non-200 http response code is returned
*/
prepareSpvFromBTC(chainIdentifier, baseUrl, init, timeout, abortSignal, streamRequest) {
//We need to make sure we only send the amount parameter after the amountUtxos and amountFeeRate resolve
// this is needed, because in the LP code to maintain backwards compatibility the amountUtxos and amountFeeRate
// params are checked immediately after the amount param (and other params) are received, if amount were sent
// first without the amountUtxos or amountFeeRate populated these fields would've been skipped altogether
const amountPromise = (async () => {
if (init.amountUtxos != null)
await init.amountUtxos;
if (init.amountFeeRate != null)
await init.amountFeeRate;
const amount = await init.amount;
return amount.toString(10);
})();
const responseBodyPromise = this.streamingFetchPromise(baseUrl + "/frombtc_spv/getQuote?chain=" + encodeURIComponent(chainIdentifier), {
exactOut: init.exactOut,
...init.additionalParams,
address: init.address,
amount: amountPromise,
token: init.token,
gasAmount: init.gasAmount.toString(10),
gasToken: init.gasToken,
frontingFeeRate: init.frontingFeeRate.toString(10),
callerFeeRate: init.callerFeeRate.then(val => val.toString(10)),
stickyAddress: init.stickyAddress,
amountUtxos: init.amountUtxos,
amountFeeRate: init.amountFeeRate
}, {
code: SchemaVerifier_1.FieldTypeEnum.Number,
msg: SchemaVerifier_1.FieldTypeEnum.String,
data: SchemaVerifier_1.FieldTypeEnum.AnyOptional
}, timeout, abortSignal, streamRequest);
return responseBodyPromise.then((responseBody) => Promise.all([
responseBody.code,
responseBody.msg,
responseBody.data,
])).then(([code, msg, data]) => {
if (code !== 20000) {
throw RequestError_1.RequestError.parse(JSON.stringify({ code, msg, data }), 400);
}
const result = (0, SchemaVerifier_1.verifySchema)(data, SpvFromBTCPrepareResponseSchema);
if (result == null)
throw new RequestError_1.RequestError("Cannot parse the response with the expected schema", 200);
return result;
});
}
/**
* Prepare From BTC swap via new spv vault swaps with an intermediary
*
* @param chainIdentifier
* @param url
* @param init Swap initialization parameters
* @param timeout Timeout in milliseconds for the HTTP request
* @param abortSignal
* @param streamRequest Whether to force streaming (or not streaming) the request, default is autodetect
*
* @throws {RequestError} If non-200 http response code is returned
*/
initSpvFromBTC(chainIdentifier, url, init, timeout, abortSignal, streamRequest) {
const responseBodyPromise = this.streamingFetchPromise(url + "/postQuote?chain=" + encodeURIComponent(chainIdentifier), {
quoteId: init.quoteId,
psbtHex: init.psbtHex
}, {
code: SchemaVerifier_1.FieldTypeEnum.Number,
msg: SchemaVerifier_1.FieldTypeEnum.String,
data: SchemaVerifier_1.FieldTypeEnum.AnyOptional
}, timeout, abortSignal, streamRequest);
return responseBodyPromise.then((responseBody) => Promise.all([
responseBody.code,
responseBody.msg,
responseBody.data,
])).then(([code, msg, data]) => {
if (code !== 20000) {
throw RequestError_1.RequestError.parse(JSON.stringify({ code, msg, data }), 400);
}
const result = (0, SchemaVerifier_1.verifySchema)(data, SpvFromBTCInitResponseSchema);
if (result == null)
throw new RequestError_1.RequestError("Cannot parse the response with the expected schema", 200);
return result;
});
}
/**
* Fetches the invoice status from the intermediary node
*
* @param url Url of the trusted intermediary
* @param paymentHash Payment hash of the lightning invoice
* @param timeout Timeout in milliseconds
* @param abortSignal
* @throws {RequestError} if non-200 http response is returned
*/
async getTrustedInvoiceStatus(url, paymentHash, timeout, abortSignal) {
return (0, RetryUtils_1.tryWithRetries)(() => this.httpGet(url + "/getInvoiceStatus?paymentHash=" + encodeURIComponent(paymentHash), timeout, abortSignal), undefined, RequestError_1.RequestError, abortSignal);
}
/**
* Initiate a trusted swap from BTCLN to SC native currency, retries!
*
* @param chainIdentifier
* @param baseUrl Base url of the trusted swap intermediary
* @param init Initialization parameters
* @param timeout Timeout in milliseconds for the request
* @param abortSignal
* @throws {RequestError} If the response is non-200
*/
async initTrustedFromBTCLN(chainIdentifier, baseUrl, init, timeout, abortSignal) {
const resp = await (0, RetryUtils_1.tryWithRetries)(() => this.httpGet(baseUrl + "/lnforgas/createInvoice" +
"?address=" + encodeURIComponent(init.address) +
"&amount=" + encodeURIComponent(init.amount.toString(10)) +
"&chain=" + encodeURIComponent(chainIdentifier) +
"&token=" + encodeURIComponent(init.token), timeout, abortSignal), undefined, RequestError_1.RequestError, abortSignal);
if (resp.code !== 10000)
throw RequestError_1.RequestError.parse(JSON.stringify(resp), 400);
const res = (0, SchemaVerifier_1.verifySchema)(resp.data, TrustedFromBTCLNResponseSchema);
if (res == null)
throw new Error("Invalid response returned from LP");
return res;
}
/**
* Fetches the address status from the intermediary node
*
* @param url Url of the trusted intermediary
* @param paymentHash Payment hash of the swap
* @param sequence Sequence number of the swap
* @param timeout Timeout in milliseconds
* @param abortSignal
* @throws {RequestError} if non-200 http response is returned
*/
async getTrustedAddressStatus(url, paymentHash, sequence, timeout, abortSignal) {
return (0, RetryUtils_1.tryWithRetries)(() => this.httpGet(url + "/getAddressStatus?paymentHash=" + encodeURIComponent(paymentHash) + "&sequence=" + encodeURIComponent(sequence.toString(10)), timeout, abortSignal), undefined, RequestError_1.RequestError, abortSignal);
}
/**
* Sets the refund address for an on-chain gas swap
*
* @param url Url of the trusted intermediary
* @param paymentHash Payment hash of the swap
* @param sequence Sequence number of the swap
* @param refundAddress Refund address to set for the swap
* @param timeout Timeout in milliseconds
* @param abortSignal
* @throws {RequestError} if non-200 http response is returned
*/
async setTrustedRefundAddress(url, paymentHash, sequence, refundAddress, timeout, abortSignal) {
return (0, RetryUtils_1.tryWithRetries)(() => this.httpGet(url + "/setRefundAddress" +
"?paymentHash=" + encodeURIComponent(paymentHash) +
"&sequence=" + encodeURIComponent(sequence.toString(10)) +
"&refundAddress=" + encodeURIComponent(refundAddress), timeout, abortSignal), undefined, RequestError_1.RequestError, abortSignal);
}
/**
* Initiate a trusted swap from BTC to SC native currency, retries!
*
* @param chainIdentifier
* @param baseUrl Base url of the trusted swap intermediary
* @param init Initialization parameters
* @param timeout Timeout in milliseconds for the request
* @param abortSignal
* @throws {RequestError} If the response is non-200
*/
async initTrustedFromBTC(chainIdentifier, baseUrl, init, timeout, abortSignal) {
const resp = await (0, RetryUtils_1.tryWithRetries)(() => this.httpGet(baseUrl + "/frombtc_trusted/getAddress?chain=" + encodeURIComponent(chainIdentifier) +
"&address=" + encodeURIComponent(init.address) +
"&amount=" + encodeURIComponent(init.amount.toString(10)) +
(init.refundAddress == null ? "" : "&refundAddress=" + encodeURIComponent(init.refundAddress)) +
"&exactIn=true" +
"&token=" + encodeURIComponent(init.token), timeout, abortSignal), undefined, RequestError_1.RequestError, abortSignal);
if (resp.code !== 10000)
throw RequestError_1.RequestError.parse(JSON.stringify(resp), 400);
const res = (0, SchemaVerifier_1.verifySchema)(resp.data, TrustedFromBTCResponseSchema);
if (res == null)
throw new Error("Invalid response returned from LP");
return res;
}
}
exports.IntermediaryAPI = IntermediaryAPI;