kuber-client
Version:
Javascript client library for kuber server
148 lines • 7.09 kB
JavaScript
Object.defineProperty(exports, "__esModule", { value: true });
exports.KuberProvider = void 0;
const serialization_1 = require("libcardano/cardano/serialization");
const cip30_1 = require("libcardano-wallet/cip30");
const cbor_rpc_1 = require("cbor-rpc");
class KuberProvider {
/**
* Build a transaction with kuber. This function adds the available Utxos in the wallet to selection
* @param cip30Instance Browser cip30 provider instance obtained with enable()
* @param buildRequest Object following Kuber's transaction builder JSON spec
* @param autoAddCollateral Add collateral from provider. Kuber automatically picks collateral.
* set this to true if you want to specify exact collateral utxo.
* minimumLovelace
* @returns A new rejected Promise.
*/
async buildWithWallet(cip30OrProvider, buildRequest, autoAddCollateral = false, estimatedSpending) {
const cip30 = cip30OrProvider.toProtableCip30
? cip30OrProvider.toProtableCip30()
: cip30OrProvider;
const walletUtxos = await cip30.getUtxos();
let selectedUtxos = walletUtxos;
if (estimatedSpending) {
let toBigInt = (x) => {
if (typeof x == "number")
return BigInt(x);
else
return x;
};
estimatedSpending = toBigInt(estimatedSpending);
let adaValue = BigInt(0);
let minimumSelections = 1;
walletUtxos.forEach((utxo) => {
const utxoDecoded = cbor_rpc_1.cborBackend.decode(Buffer.from(utxo, "hex"));
const txOut = serialization_1.Output.fromCborObject(utxoDecoded[1]);
adaValue += txOut.value.lovelace;
if (adaValue >= estimatedSpending) {
selectedUtxos = walletUtxos.slice(0, minimumSelections);
return;
}
minimumSelections++;
});
}
function concat(source, target) {
if (source) {
if (Array.isArray(source)) {
return target.concat(source);
}
else {
target.push(source);
return target;
}
}
else {
return target;
}
}
if (buildRequest.selection) {
buildRequest.selection = concat(buildRequest.selection, selectedUtxos);
}
else {
buildRequest.selections = concat(buildRequest.selections, selectedUtxos);
}
if (!buildRequest.changeAddress) {
buildRequest.changeAddress = await cip30.getChangeAddress();
}
if (!buildRequest.inputs && !buildRequest.selections) {
throw Error("Expectation Failed : No Utxos available as `input` or `selection`");
}
if (autoAddCollateral && cip30.getCollateral) {
if (!buildRequest.collateral && !buildRequest.collaterals) {
buildRequest.collaterals = await cip30.getCollateral();
}
}
return this.buildTx(buildRequest, false);
}
async buildAndSignWithWallet(cip30OrProvider, buildRequest, autoAddCollateral = false, estimatedSpending) {
const cip30 = cip30OrProvider.toProtableCip30
? cip30OrProvider
: new cip30_1.Cip30ProviderWrapper(cip30OrProvider);
const built = await this.buildWithWallet(cip30OrProvider, buildRequest, autoAddCollateral, estimatedSpending);
return cip30.signTx(built.cborHex, true);
}
async buildAndSubmitWithWallet(cip30OrProvider, buildRequest, autoAddCollateral = false, estimatedSpending) {
const signed = await this.buildAndSignWithWallet(cip30OrProvider, buildRequest, autoAddCollateral, estimatedSpending);
await cip30OrProvider.submitTx(cbor_rpc_1.cborBackend.encode(signed.updatedTx).toString("hex"));
return signed;
}
/**
* Waits for a transaction output to vanish.
* @param utxo The transaction ID or UTxO identifier.
* @param pollIntervalMs The interval in milliseconds to poll for the UTxO.
* @param timeoutMs The maximum time in milliseconds to wait.
* @returns A promise that resolves with the total time spent waiting in milliseconds when the UTxO vanishes.
*/
async waitForUtxoConsumption(txin, timeoutMs = 80000, logPoll = false, pollIntervalMs = 5000) {
const startTime = Date.now();
const txHash = txin.txHash.toString("hex");
const utxo = txHash + "#" + txin.index;
while (Date.now() - startTime < timeoutMs) {
const utxos = await this.queryUTxOByTxIn(utxo);
// UTxO type has txIn which contains txHash (Buffer) and index.
// We need to check for both to uniquely identify a UTxO.
const txExists = utxos.some((utxo) => utxo.txIn.txHash.compare(txin.txHash) === 0 && utxo.txIn.index === txin.index);
if (logPoll) {
console.log(`Checking UTxO: ${utxo}. Is not spent.`);
}
if (!txExists) {
return Date.now() - startTime; // UTxO has vanished
}
await new Promise((resolve) => setTimeout(resolve, pollIntervalMs));
}
throw new Error(`Timeout waiting for UTxO ${utxo} to be spent.`);
}
/**
* Waits for a transaction to be confirmed by querying UTxO by TxIn.
* Confirmation is determined by checking if the query returns more than one UTxO.
*
* @param txHash - The transaction hash (without the #0).
* @param timeoutMs - Timeout in milliseconds.
* @param pollIntervalMs - Polling interval in milliseconds (default: 3000ms).
* @param logPoll - If true, logs the polling status.
* @returns A Promise that resolves with the total time spent waiting in milliseconds if confirmed, or rejects on timeout.
*/
async waitForTxConfirmation(txHash, timeoutMs = 80000, logPoll = false, pollIntervalMs = 5000) {
const txIn = `${txHash}#0`;
const start = Date.now();
while (Date.now() - start < timeoutMs) {
try {
const result = await this.queryUTxOByTxIn(txIn);
if (logPoll) {
console.log(`Polling for confirmation of tx: ${txHash}. Result length: ${result.length}`);
}
if (Array.isArray(result) && result.length > 1) {
return Date.now() - start; // Transaction confirmed
}
}
catch (err) {
console.warn(`Error while querying UTxO for tx ${txHash}:`, err.message);
// Optional: continue retrying even if one call fails
}
await new Promise((resolve) => setTimeout(resolve, pollIntervalMs));
}
throw new Error(`Timeout waiting for transaction ${txHash} confirmation.`);
}
}
exports.KuberProvider = KuberProvider;
//# sourceMappingURL=KuberProvider.js.map
;