var __awaiter = this && this.__awaiter || function (thisArg, _arguments, P, generator) { function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); } return new (P || (P = Promise))(function (resolve, reject) { function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } } function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } } function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); } step((generator = generator.apply(thisArg, _arguments || [])).next()); }); }; import * as connectivity from "./modules/debug/connectivity.js"; import * as balance from "./modules/debug/balance.js"; import * as chequebook from "./modules/debug/chequebook.js"; import * as settlements from "./modules/debug/settlements.js"; import * as status from "./modules/debug/status.js"; import * as transactions from "./modules/debug/transactions.js"; import * as states from "./modules/debug/states.js"; import { BeeArgumentError, BeeError } from "./utils/error.js"; import { assertBeeUrl, stripLastSlash } from "./utils/url.js"; import { assertAddress, assertBatchId, assertCashoutOptions, assertNonNegativeInteger, assertPositiveInteger, assertPostageBatchOptions, assertRequestOptions, assertTransactionHash, isTag } from "./utils/type.js"; import { STAMPS_DEPTH_MAX, STAMPS_DEPTH_MIN } from "./types/index.js"; import * as tag from "./modules/debug/tag.js"; import * as stamps from "./modules/debug/stamps.js"; import { makeDefaultKy, wrapRequestClosure, wrapResponseClosure } from "./utils/http.js"; import { sleep } from "./utils/sleep.js"; export class BeeDebug { constructor(url, options) { var _a; assertBeeUrl(url); // Remove last slash if present, as our endpoint strings starts with `/...` // which could lead to double slash in URL to which Bee responds with // unnecessary redirects. this.url = stripLastSlash(url); const kyOptions = { prefixUrl: this.url, timeout: (_a = options === null || options === void 0 ? void 0 : options.timeout) !== null && _a !== void 0 ? _a : false, retry: options === null || options === void 0 ? void 0 : options.retry, fetch: options === null || options === void 0 ? void 0 : options.fetch, hooks: { beforeRequest: [], afterResponse: [] } }; if (options === null || options === void 0 ? void 0 : options.defaultHeaders) { kyOptions.headers = options.defaultHeaders; } if (options === null || options === void 0 ? void 0 : options.onRequest) { kyOptions.hooks.beforeRequest.push(wrapRequestClosure(options.onRequest)); } if (options === null || options === void 0 ? void 0 : options.onResponse) { kyOptions.hooks.afterResponse.push(wrapResponseClosure(options.onResponse)); } this.ky = makeDefaultKy(kyOptions); } getNodeAddresses(options) { return __awaiter(this, void 0, void 0, function* () { assertRequestOptions(options); return connectivity.getNodeAddresses(this.getKy(options)); }); } getBlocklist(options) { return __awaiter(this, void 0, void 0, function* () { assertRequestOptions(options); return connectivity.getBlocklist(this.getKy(options)); }); } /** * Retrieve tag extended information from Bee node * * @param tagUid UID or tag object to be retrieved * @throws TypeError if tagUid is in not correct format * * @see [Bee docs - Syncing / Tags](https://docs.ethswarm.org/docs/access-the-swarm/syncing) * @see [Bee API reference - `GET /tags/{uid}`](https://docs.ethswarm.org/debug-api/#tag/Tag) * */ retrieveExtendedTag(tagUid, options) { return __awaiter(this, void 0, void 0, function* () { assertRequestOptions(options); if (isTag(tagUid)) { tagUid = tagUid.uid; } else if (typeof tagUid === 'number') { assertNonNegativeInteger(tagUid, 'UID'); } else { throw new TypeError('tagUid has to be either Tag or a number (UID)!'); } return tag.retrieveExtendedTag(this.getKy(options), tagUid); }); } /** * Get list of peers for this node */ getPeers(options) { return __awaiter(this, void 0, void 0, function* () { assertRequestOptions(options); return connectivity.getPeers(this.getKy(options)); }); } removePeer(peer, options) { return __awaiter(this, void 0, void 0, function* () { assertRequestOptions(options); assertAddress(peer); return connectivity.removePeer(this.getKy(options), peer); }); } getTopology(options) { return __awaiter(this, void 0, void 0, function* () { assertRequestOptions(options); return connectivity.getTopology(this.getKy(options)); }); } pingPeer(peer, options) { return __awaiter(this, void 0, void 0, function* () { assertRequestOptions(options); assertAddress(peer); return connectivity.pingPeer(this.getKy(options), peer); }); } /* * Balance endpoints */ /** * Get the balances with all known peers including prepaid services */ getAllBalances(options) { return __awaiter(this, void 0, void 0, function* () { assertRequestOptions(options); return balance.getAllBalances(this.getKy(options)); }); } /** * Get the balances with a specific peer including prepaid services * * @param address Swarm address of peer */ getPeerBalance(address, options) { return __awaiter(this, void 0, void 0, function* () { assertRequestOptions(options); assertAddress(address); return balance.getPeerBalance(this.getKy(options), address); }); } /** * Get the past due consumption balances with all known peers */ getPastDueConsumptionBalances(options) { return __awaiter(this, void 0, void 0, function* () { assertRequestOptions(options); return balance.getPastDueConsumptionBalances(this.getKy(options)); }); } /** * Get the past due consumption balance with a specific peer * * @param address Swarm address of peer */ getPastDueConsumptionPeerBalance(address, options) { return __awaiter(this, void 0, void 0, function* () { assertRequestOptions(options); assertAddress(address); return balance.getPastDueConsumptionPeerBalance(this.getKy(options), address); }); } /* * Chequebook endpoints */ /** * Get the address of the chequebook contract used. * * **Warning:** The address is returned with 0x prefix unlike all other calls. * https://github.com/ethersphere/bee/issues/1443 */ getChequebookAddress(options) { return __awaiter(this, void 0, void 0, function* () { assertRequestOptions(options); return chequebook.getChequebookAddress(this.getKy(options)); }); } /** * Get the balance of the chequebook */ getChequebookBalance(options) { return __awaiter(this, void 0, void 0, function* () { assertRequestOptions(options); return chequebook.getChequebookBalance(this.getKy(options)); }); } /** * Get last cheques for all peers */ getLastCheques(options) { return __awaiter(this, void 0, void 0, function* () { assertRequestOptions(options); return chequebook.getLastCheques(this.getKy(options)); }); } /** * Get last cheques for the peer * * @param address Swarm address of peer */ getLastChequesForPeer(address, options) { return __awaiter(this, void 0, void 0, function* () { assertRequestOptions(options); assertAddress(address); return chequebook.getLastChequesForPeer(this.getKy(options), address); }); } /** * Get last cashout action for the peer * * @param address Swarm address of peer */ getLastCashoutAction(address, options) { return __awaiter(this, void 0, void 0, function* () { assertRequestOptions(options); assertAddress(address); return chequebook.getLastCashoutAction(this.getKy(options), address); }); } /** * Cashout the last cheque for the peer * * @param address Swarm address of peer * @param options * @param options.gasPrice Gas price for the cashout transaction in WEI * @param options.gasLimit Gas limit for the cashout transaction in WEI */ cashoutLastCheque(address, options) { return __awaiter(this, void 0, void 0, function* () { assertCashoutOptions(options); assertAddress(address); return chequebook.cashoutLastCheque(this.getKy(options), address, options); }); } /** * Deposit tokens from overlay address into chequebook * * @param amount Amount of tokens to deposit (must be positive integer) * @param gasPrice Gas Price in WEI for the transaction call * @return string Hash of the transaction */ depositTokens(amount, gasPrice, options) { return __awaiter(this, void 0, void 0, function* () { assertRequestOptions(options); assertNonNegativeInteger(amount); if (gasPrice) { assertNonNegativeInteger(gasPrice); } return chequebook.depositTokens(this.getKy(options), amount, gasPrice); }); } /** * Withdraw tokens from the chequebook to the overlay address * * @param amount Amount of tokens to withdraw (must be positive integer) * @param gasPrice Gas Price in WEI for the transaction call * @return string Hash of the transaction */ withdrawTokens(amount, gasPrice, options) { return __awaiter(this, void 0, void 0, function* () { assertRequestOptions(options); assertNonNegativeInteger(amount); if (gasPrice) { assertNonNegativeInteger(gasPrice); } return chequebook.withdrawTokens(this.getKy(options), amount, gasPrice); }); } /* * Settlements endpoint */ /** * Get amount of sent and received from settlements with a peer * * @param address Swarm address of peer */ getSettlements(address, options) { return __awaiter(this, void 0, void 0, function* () { assertRequestOptions(options); assertAddress(address); return settlements.getSettlements(this.getKy(options), address); }); } /** * Get settlements with all known peers and total amount sent or received */ getAllSettlements(options) { return __awaiter(this, void 0, void 0, function* () { assertRequestOptions(options); return settlements.getAllSettlements(this.getKy(options)); }); } /** * Get health of node */ getHealth(options) { return __awaiter(this, void 0, void 0, function* () { assertRequestOptions(options); return status.getHealth(this.getKy(options)); }); } /** * Get mode information of node */ getNodeInfo(options) { return __awaiter(this, void 0, void 0, function* () { assertRequestOptions(options); return status.getNodeInfo(this.getKy(options)); }); } /** * Connnects to a node and checks if it is a supported Bee version by the bee-js * * @returns true if the Bee node version is supported * @deprecated Use `BeeDebug.isSupportedExactVersion()` instead */ isSupportedVersion(options) { return __awaiter(this, void 0, void 0, function* () { assertRequestOptions(options); return status.isSupportedVersion(this.getKy(options)); }); } /** * Connects to a node and checks if its version matches with the one that bee-js supports. * * Be aware that this is the most strict version check and most probably * you will want to use more relaxed API-versions based checks like * `BeeDebug.isSupportedApiVersion()`, `BeeDebug.isSupportedMainApiVersion()` or `BeeDebug.isSupportedDebugApiVersion()` * based on your use-case. * * @param options */ isSupportedExactVersion(options) { return __awaiter(this, void 0, void 0, function* () { assertRequestOptions(options); return status.isSupportedExactVersion(this.getKy(options)); }); } /** * Connects to a node and checks if its main's API version matches with the one that bee-js supports. * * This is useful if you are not using `BeeDebug` class (for anything else then this check) * and want to make sure about compatibility. * * @param options */ isSupportedMainApiVersion(options) { return __awaiter(this, void 0, void 0, function* () { assertRequestOptions(options); return status.isSupportedMainApiVersion(this.getKy(options)); }); } /** * Connects to a node and checks if its Debug API version matches with the one that bee-js supports. * * This is useful if you are not using `Bee` class in your application and want to make sure * about compatibility. * * @param options */ isSupportedDebugApiVersion(options) { return __awaiter(this, void 0, void 0, function* () { assertRequestOptions(options); return status.isSupportedDebugApiVersion(this.getKy(options)); }); } /** * * Connects to a node and checks if its Main and Debug API versions matches with the one that bee-js supports. * * This should be the main way how to check compatibility for your app and Bee node. * * @param options */ isSupportedApiVersion(options) { return __awaiter(this, void 0, void 0, function* () { assertRequestOptions(options); return status.isSupportedDebugApiVersion(this.getKy(options)); }); } /** * Returns object with all versions specified by the connected Bee node (properties prefixed with `bee*`) * and versions that bee-js supports (properties prefixed with `supported*`). * * @param options */ getVersions(options) { return __awaiter(this, void 0, void 0, function* () { assertRequestOptions(options); return status.getVersions(this.getKy(options)); }); } /** * Get reserve state */ getReserveState(options) { return __awaiter(this, void 0, void 0, function* () { assertRequestOptions(options); return states.getReserveState(this.getKy(options)); }); } /** * Get chain state */ getChainState(options) { return __awaiter(this, void 0, void 0, function* () { assertRequestOptions(options); return states.getChainState(this.getKy(options)); }); } /** * Get wallet balances for xDai and BZZ of the Bee node * * @param options */ getWalletBalance(options) { return __awaiter(this, void 0, void 0, function* () { assertRequestOptions(options); return states.getWalletBalance(this.getKy(options)); }); } /** * Creates new postage batch from the funds that the node has available in its Ethereum account. * * For better understanding what each parameter means and what are the optimal values please see * [Bee docs - Keep your data alive / Postage stamps](https://docs.ethswarm.org/docs/access-the-swarm/keep-your-data-alive). * * **WARNING: THIS CREATES TRANSACTIONS THAT SPENDS MONEY** * * @param amount Amount that represents the value per chunk, has to be greater or equal zero. * @param depth Logarithm of the number of chunks that can be stamped with the batch. * @param options Options for creation of postage batch * @throws BeeArgumentError when negative amount or depth is specified * @throws TypeError if non-integer value is passed to amount or depth * * @see [Bee docs - Keep your data alive / Postage stamps](https://docs.ethswarm.org/docs/access-the-swarm/keep-your-data-alive) * @see [Bee Debug API reference - `POST /stamps`](https://docs.ethswarm.org/debug-api/#tag/Postage-Stamps/paths/~1stamps~1{amount}~1{depth}/post) */ createPostageBatch(amount, depth, options) { return __awaiter(this, void 0, void 0, function* () { assertPostageBatchOptions(options); assertPositiveInteger(amount); assertNonNegativeInteger(depth); if (depth < STAMPS_DEPTH_MIN) { throw new BeeArgumentError(`Depth has to be at least ${STAMPS_DEPTH_MIN}`, depth); } if (depth > STAMPS_DEPTH_MAX) { throw new BeeArgumentError(`Depth has to be at most ${STAMPS_DEPTH_MAX}`, depth); } const stamp = yield stamps.createPostageBatch(this.getKy(options), amount, depth, options); if (options === null || options === void 0 ? void 0 : options.waitForUsable) { yield this.waitForUsablePostageStamp(stamp, options === null || options === void 0 ? void 0 : options.waitForUsableTimeout); } return stamp; }); } /** * Topup a fresh amount of BZZ to given Postage Batch. * * For better understanding what each parameter means and what are the optimal values please see * [Bee docs - Keep your data alive / Postage stamps](https://docs.ethswarm.org/docs/access-the-swarm/keep-your-data-alive). * * **WARNING: THIS CREATES TRANSACTIONS THAT SPENDS MONEY** * * @param postageBatchId Batch ID * @param amount Amount to be added to the batch * @param options Request options * * @see [Bee docs - Keep your data alive / Postage stamps](https://docs.ethswarm.org/docs/access-the-swarm/keep-your-data-alive) * @see [Bee Debug API reference - `PATCH /stamps/topup/${id}/${amount}`](https://docs.ethswarm.org/debug-api/#tag/Postage-Stamps/paths/~1stamps~1topup~1{id}~1{amount}/patch) */ topUpBatch(postageBatchId, amount, options) { return __awaiter(this, void 0, void 0, function* () { assertRequestOptions(options); assertNonNegativeInteger(amount, 'Amount'); assertBatchId(postageBatchId); yield stamps.topUpBatch(this.getKy(options), postageBatchId, amount); }); } /** * Dilute given Postage Batch with new depth (that has to be bigger then the original depth), which allows * the Postage Batch to be used for more chunks. * * For better understanding what each parameter means and what are the optimal values please see * [Bee docs - Keep your data alive / Postage stamps](https://docs.ethswarm.org/docs/access-the-swarm/keep-your-data-alive). * * **WARNING: THIS CREATES TRANSACTIONS THAT SPENDS MONEY** * * @param postageBatchId Batch ID * @param depth Amount to be added to the batch * @param options Request options * * @see [Bee docs - Keep your data alive / Postage stamps](https://docs.ethswarm.org/docs/access-the-swarm/keep-your-data-alive) * @see [Bee Debug API reference - `PATCH /stamps/topup/${id}/${amount}`](https://docs.ethswarm.org/debug-api/#tag/Postage-Stamps/paths/~1stamps~1topup~1{id}~1{amount}/patch) */ diluteBatch(postageBatchId, depth, options) { return __awaiter(this, void 0, void 0, function* () { assertRequestOptions(options); assertNonNegativeInteger(depth, 'Depth'); assertBatchId(postageBatchId); yield stamps.diluteBatch(this.getKy(options), postageBatchId, depth); }); } /** * Return details for specific postage batch. * * @param postageBatchId Batch ID * * @see [Bee docs - Keep your data alive / Postage stamps](https://docs.ethswarm.org/docs/access-the-swarm/keep-your-data-alive) * @see [Bee Debug API reference - `GET /stamps/${id}`](https://docs.ethswarm.org/debug-api/#tag/Postage-Stamps/paths/~1stamps~1{id}/get) */ getPostageBatch(postageBatchId, options) { return __awaiter(this, void 0, void 0, function* () { assertRequestOptions(options); assertBatchId(postageBatchId); return stamps.getPostageBatch(this.getKy(options), postageBatchId); }); } /** * Return detailed information related to buckets for specific postage batch. * * @param postageBatchId Batch ID * * @see [Bee docs - Keep your data alive / Postage stamps](https://docs.ethswarm.org/docs/access-the-swarm/keep-your-data-alive) * @see [Bee Debug API reference - `GET /stamps/${id}/buckets`](https://docs.ethswarm.org/debug-api/#tag/Postage-Stamps/paths/~1stamps~1{id}~1buckets/get) */ getPostageBatchBuckets(postageBatchId, options) { return __awaiter(this, void 0, void 0, function* () { assertRequestOptions(options); assertBatchId(postageBatchId); return stamps.getPostageBatchBuckets(this.getKy(options), postageBatchId); }); } /** * Return all postage batches that has the node available. * * @see [Bee docs - Keep your data alive / Postage stamps](https://docs.ethswarm.org/docs/access-the-swarm/keep-your-data-alive) * @see [Bee Debug API reference - `GET /stamps`](https://docs.ethswarm.org/debug-api/#tag/Postage-Stamps/paths/~1stamps/get) */ getAllPostageBatch(options) { return __awaiter(this, void 0, void 0, function* () { assertRequestOptions(options); return stamps.getAllPostageBatches(this.getKy(options)); }); } /** * Return lists of all current pending transactions that the Bee made */ getAllPendingTransactions(options) { return __awaiter(this, void 0, void 0, function* () { assertRequestOptions(options); return transactions.getAllTransactions(this.getKy(options)); }); } /** * Return transaction information for specific transaction * @param transactionHash */ getPendingTransaction(transactionHash, options) { return __awaiter(this, void 0, void 0, function* () { assertRequestOptions(options); assertTransactionHash(transactionHash); return transactions.getTransaction(this.getKy(options), transactionHash); }); } /** * Rebroadcast already created transaction. * This is mainly needed when your transaction fall off mempool from other reason is not incorporated into block. * * @param transactionHash */ rebroadcastPendingTransaction(transactionHash, options) { return __awaiter(this, void 0, void 0, function* () { assertRequestOptions(options); assertTransactionHash(transactionHash); return transactions.rebroadcastTransaction(this.getKy(options), transactionHash); }); } /** * Cancel currently pending transaction * @param transactionHash * @param gasPrice */ cancelPendingTransaction(transactionHash, gasPrice, options) { return __awaiter(this, void 0, void 0, function* () { assertRequestOptions(options); assertTransactionHash(transactionHash); if (gasPrice) { assertNonNegativeInteger(gasPrice); } return transactions.cancelTransaction(this.getKy(options), transactionHash, gasPrice); }); } waitForUsablePostageStamp(id, timeout = 120000) { return __awaiter(this, void 0, void 0, function* () { const TIME_STEP = 1500; for (let time = 0; time < timeout; time += TIME_STEP) { const stamp = yield this.getPostageBatch(id); if (stamp.usable) { return; } yield sleep(TIME_STEP); } throw new BeeError('Timeout on waiting for postage stamp to become usable'); }); } getKy(options) { if (!options) { return this.ky; } return this.ky.extend(options); } }