1083 lines
42 KiB
JavaScript
1083 lines
42 KiB
JavaScript
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 bzz from "./modules/bzz.js";
|
|
import * as stewardship from "./modules/stewardship.js";
|
|
import * as tag from "./modules/tag.js";
|
|
import * as pinning from "./modules/pinning.js";
|
|
import * as bytes from "./modules/bytes.js";
|
|
import * as chunk from "./modules/chunk.js";
|
|
import * as pss from "./modules/pss.js";
|
|
import * as status from "./modules/status.js";
|
|
import { BeeArgumentError, BeeError } from "./utils/error.js";
|
|
import { prepareWebsocketData } from "./utils/data.js";
|
|
import { fileArrayBuffer, isFile } from "./utils/file.js";
|
|
import { makeFeedReader, makeFeedWriter } from "./feed/index.js";
|
|
import { makeSigner } from "./chunk/signer.js";
|
|
import { assertFeedType, DEFAULT_FEED_TYPE } from "./feed/type.js";
|
|
import { downloadSingleOwnerChunk, uploadSingleOwnerChunkData } from "./chunk/soc.js";
|
|
import { makeTopic, makeTopicFromString } from "./feed/topic.js";
|
|
import { createFeedManifest } from "./modules/feed.js";
|
|
import { assertBeeUrl, stripLastSlash } from "./utils/url.js";
|
|
import { makeEthAddress, makeHexEthAddress } from "./utils/eth.js";
|
|
import { wrapBytesWithHelpers } from "./utils/bytes.js";
|
|
import { addCidConversionFunction, assertAddressPrefix, assertAllTagsOptions, assertBatchId, assertCollectionUploadOptions, assertData, assertFileData, assertFileUploadOptions, assertPssMessageHandler, assertPublicKey, assertReference, assertReferenceOrEns, assertRequestOptions, assertUploadOptions, makeReferenceOrEns, makeTagUid } from "./utils/type.js";
|
|
import { getJsonData, setJsonData } from "./feed/json.js";
|
|
import { assertCollection, makeCollectionFromFileList } from "./utils/collection.js";
|
|
import { makeCollectionFromFS } from "./utils/collection.node.js";
|
|
import { CHUNK_SIZE, SPAN_SIZE } from "./types/index.js";
|
|
import { makeDefaultKy, wrapRequestClosure, wrapResponseClosure } from "./utils/http.js";
|
|
import { isReadable } from "./utils/stream.js";
|
|
import { areAllSequentialFeedsUpdateRetrievable } from "./feed/retrievable.js";
|
|
import { ReferenceType } from '@ethersphere/swarm-cid';
|
|
/**
|
|
* The main component that abstracts operations available on the main Bee API.
|
|
*
|
|
* Not all methods are always available as it depends in what mode is Bee node launched in.
|
|
* For example gateway mode and light node mode has only limited set of endpoints enabled.
|
|
*/
|
|
|
|
export class Bee {
|
|
/**
|
|
* @param url URL on which is the main API of Bee node exposed
|
|
* @param options
|
|
*/
|
|
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);
|
|
|
|
if (options === null || options === void 0 ? void 0 : options.signer) {
|
|
this.signer = makeSigner(options.signer);
|
|
}
|
|
|
|
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);
|
|
}
|
|
/**
|
|
* Upload data to a Bee node
|
|
*
|
|
* @param postageBatchId Postage BatchId to be used to upload the data with
|
|
* @param data Data to be uploaded
|
|
* @param options Additional options like tag, encryption, pinning, content-type and request options
|
|
*
|
|
* @returns reference is a content hash of the data
|
|
* @see [Bee docs - Upload and download](https://docs.ethswarm.org/docs/access-the-swarm/upload-and-download)
|
|
* @see [Bee API reference - `POST /bytes`](https://docs.ethswarm.org/api/#tag/Bytes/paths/~1bytes/post)
|
|
*/
|
|
|
|
|
|
uploadData(postageBatchId, data, options) {
|
|
return __awaiter(this, void 0, void 0, function* () {
|
|
assertBatchId(postageBatchId);
|
|
assertData(data);
|
|
if (options) assertUploadOptions(options);
|
|
return bytes.upload(this.getKy(options), data, postageBatchId, options);
|
|
});
|
|
}
|
|
/**
|
|
* Download data as a byte array
|
|
*
|
|
* @param reference Bee data reference in hex string (either 64 or 128 chars long) or ENS domain.
|
|
* @param options Options that affects the request behavior
|
|
* @throws TypeError if some of the input parameters is not expected type
|
|
* @throws BeeArgumentError if there is passed ENS domain with invalid unicode characters
|
|
* @see [Bee docs - Upload and download](https://docs.ethswarm.org/docs/access-the-swarm/upload-and-download)
|
|
* @see [Bee API reference - `GET /bytes`](https://docs.ethswarm.org/api/#tag/Bytes/paths/~1bytes~1{reference}/get)
|
|
*/
|
|
|
|
|
|
downloadData(reference, options) {
|
|
return __awaiter(this, void 0, void 0, function* () {
|
|
assertRequestOptions(options);
|
|
assertReferenceOrEns(reference);
|
|
return bytes.download(this.getKy(options), reference);
|
|
});
|
|
}
|
|
/**
|
|
* Download data as a Readable stream
|
|
*
|
|
* @param reference Bee data reference in hex string (either 64 or 128 chars long) or ENS domain.
|
|
* @param options Options that affects the request behavior
|
|
* @throws TypeError if some of the input parameters is not expected type
|
|
* @throws BeeArgumentError if there is passed ENS domain with invalid unicode characters
|
|
* @see [Bee docs - Upload and download](https://docs.ethswarm.org/docs/access-the-swarm/upload-and-download)
|
|
* @see [Bee API reference - `GET /bytes`](https://docs.ethswarm.org/api/#tag/Bytes/paths/~1bytes~1{reference}/get)
|
|
*/
|
|
|
|
|
|
downloadReadableData(reference, options) {
|
|
return __awaiter(this, void 0, void 0, function* () {
|
|
assertRequestOptions(options);
|
|
assertReferenceOrEns(reference);
|
|
return bytes.downloadReadable(this.getKy(options), reference);
|
|
});
|
|
}
|
|
/**
|
|
* Upload chunk to a Bee node
|
|
*
|
|
* @param postageBatchId Postage BatchId to be used to upload the chunk with
|
|
* @param data Raw chunk to be uploaded
|
|
* @param options Additional options like tag, encryption, pinning, content-type and request options
|
|
*
|
|
* @returns reference is a content hash of the data
|
|
* @see [Bee docs - Upload and download](https://docs.ethswarm.org/docs/access-the-swarm/upload-and-download)
|
|
* @see [Bee API reference - `POST /chunks`](https://docs.ethswarm.org/api/#tag/Chunk/paths/~1chunks/post)
|
|
*/
|
|
|
|
|
|
uploadChunk(postageBatchId, data, options) {
|
|
return __awaiter(this, void 0, void 0, function* () {
|
|
assertBatchId(postageBatchId);
|
|
|
|
if (!(data instanceof Uint8Array)) {
|
|
throw new TypeError('Data has to be Uint8Array instance!');
|
|
}
|
|
|
|
if (data.length < SPAN_SIZE) {
|
|
throw new BeeArgumentError(`Chunk has to have size of at least ${SPAN_SIZE}.`, data);
|
|
}
|
|
|
|
if (data.length > CHUNK_SIZE + SPAN_SIZE) {
|
|
throw new BeeArgumentError(`Chunk has to have size of at most ${CHUNK_SIZE}.`, data);
|
|
}
|
|
|
|
if (options) assertUploadOptions(options);
|
|
return chunk.upload(this.getKy(options), data, postageBatchId, options);
|
|
});
|
|
}
|
|
/**
|
|
* Download chunk as a byte array
|
|
*
|
|
* @param reference Bee chunk reference in hex string (either 64 or 128 chars long) or ENS domain.
|
|
* @param options Options that affects the request behavior
|
|
* @throws TypeError if some of the input parameters is not expected type
|
|
* @throws BeeArgumentError if there is passed ENS domain with invalid unicode characters
|
|
* @see [Bee docs - Upload and download](https://docs.ethswarm.org/docs/access-the-swarm/upload-and-download)
|
|
* @see [Bee API reference - `GET /chunks`](https://docs.ethswarm.org/api/#tag/Chunk/paths/~1chunks~1{reference}/get)
|
|
*/
|
|
|
|
|
|
downloadChunk(reference, options) {
|
|
return __awaiter(this, void 0, void 0, function* () {
|
|
assertRequestOptions(options);
|
|
assertReferenceOrEns(reference);
|
|
return chunk.download(this.getKy(options), reference);
|
|
});
|
|
}
|
|
/**
|
|
* Upload single file to a Bee node.
|
|
*
|
|
* **To make sure that you won't loose critical data it is highly recommended to also
|
|
* locally pin the data with `options.pin = true`**
|
|
*
|
|
* @param postageBatchId Postage BatchId to be used to upload the data with
|
|
* @param data Data or file to be uploaded
|
|
* @param name Optional name of the uploaded file
|
|
* @param options Additional options like tag, encryption, pinning, content-type and 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 docs - Upload and download](https://docs.ethswarm.org/docs/access-the-swarm/upload-and-download)
|
|
* @see [Bee API reference - `POST /bzz`](https://docs.ethswarm.org/api/#tag/File/paths/~1bzz/post)
|
|
* @returns reference is a content hash of the file
|
|
*/
|
|
|
|
|
|
uploadFile(postageBatchId, data, name, options) {
|
|
return __awaiter(this, void 0, void 0, function* () {
|
|
assertBatchId(postageBatchId);
|
|
assertFileData(data);
|
|
if (options) assertFileUploadOptions(options);
|
|
|
|
if (name && typeof name !== 'string') {
|
|
throw new TypeError('name has to be string or undefined!');
|
|
}
|
|
|
|
if (isFile(data)) {
|
|
const fileData = yield fileArrayBuffer(data);
|
|
const fileName = name !== null && name !== void 0 ? name : data.name;
|
|
const contentType = data.type;
|
|
const fileOptions = Object.assign({
|
|
contentType
|
|
}, options);
|
|
return addCidConversionFunction(yield bzz.uploadFile(this.getKy(options), fileData, postageBatchId, fileName, fileOptions), ReferenceType.MANIFEST);
|
|
} else if (isReadable(data) && (options === null || options === void 0 ? void 0 : options.tag) && !options.size) {
|
|
// TODO: Needed until https://github.com/ethersphere/bee/issues/2317 is resolved
|
|
const result = yield bzz.uploadFile(this.getKy(options), data, postageBatchId, name, options);
|
|
yield this.updateTag(options.tag, result.reference);
|
|
return addCidConversionFunction(result, ReferenceType.MANIFEST);
|
|
} else {
|
|
return addCidConversionFunction(yield bzz.uploadFile(this.getKy(options), data, postageBatchId, name, options), ReferenceType.MANIFEST);
|
|
}
|
|
});
|
|
}
|
|
/**
|
|
* Download single file.
|
|
*
|
|
* @param reference Bee file reference in hex string (either 64 or 128 chars long), ENS domain or Swarm CID.
|
|
* @param path If reference points to manifest, then this parameter defines path to the file
|
|
* @param options Options that affects the request behavior
|
|
* @throws TypeError if some of the input parameters is not expected type
|
|
* @throws BeeArgumentError if there is passed ENS domain with invalid unicode characters
|
|
* @see Data
|
|
* @see [Bee docs - Upload and download](https://docs.ethswarm.org/docs/access-the-swarm/upload-and-download)
|
|
* @see [Bee API reference - `GET /bzz`](https://docs.ethswarm.org/api/#tag/Collection/paths/~1bzz~1{reference}~1{path}/get)
|
|
*/
|
|
|
|
|
|
downloadFile(reference, path = '', options) {
|
|
return __awaiter(this, void 0, void 0, function* () {
|
|
assertRequestOptions(options);
|
|
reference = makeReferenceOrEns(reference, ReferenceType.MANIFEST);
|
|
return bzz.downloadFile(this.getKy(options), reference, path);
|
|
});
|
|
}
|
|
/**
|
|
* Download single file as a readable stream
|
|
*
|
|
* @param reference Bee file reference in hex string (either 64 or 128 chars long), ENS domain or Swarm CID.
|
|
* @param path If reference points to manifest / collections, then this parameter defines path to the file
|
|
* @param options Options that affects the request behavior
|
|
* @throws TypeError if some of the input parameters is not expected type
|
|
* @throws BeeArgumentError if there is passed ENS domain with invalid unicode characters
|
|
*
|
|
* @see [Bee docs - Upload and download](https://docs.ethswarm.org/docs/access-the-swarm/upload-and-download)
|
|
* @see [Bee API reference - `GET /bzz`](https://docs.ethswarm.org/api/#tag/Collection/paths/~1bzz~1{reference}~1{path}/get)
|
|
*/
|
|
|
|
|
|
downloadReadableFile(reference, path = '', options) {
|
|
return __awaiter(this, void 0, void 0, function* () {
|
|
assertRequestOptions(options);
|
|
reference = makeReferenceOrEns(reference, ReferenceType.MANIFEST);
|
|
return bzz.downloadFileReadable(this.getKy(options), reference, path);
|
|
});
|
|
}
|
|
/**
|
|
* Upload collection of files to a Bee node
|
|
*
|
|
* Uses the FileList API from the browser.
|
|
*
|
|
* The returned `UploadResult.tag` might be undefined if called in CORS-enabled environment.
|
|
* This will be fixed upon next Bee release. https://github.com/ethersphere/bee-js/issues/406
|
|
*
|
|
* @param postageBatchId Postage BatchId to be used to upload the data with
|
|
* @param fileList list of files to be uploaded
|
|
* @param options Additional options like tag, encryption, pinning and 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 docs - Upload directory](https://docs.ethswarm.org/docs/access-the-swarm/upload-a-directory/)
|
|
* @see [Bee API reference - `POST /bzz`](https://docs.ethswarm.org/api/#tag/Collection/paths/~1bzz/post)
|
|
*/
|
|
|
|
|
|
uploadFiles(postageBatchId, fileList, options) {
|
|
return __awaiter(this, void 0, void 0, function* () {
|
|
assertBatchId(postageBatchId);
|
|
if (options) assertCollectionUploadOptions(options);
|
|
const data = yield makeCollectionFromFileList(fileList);
|
|
return addCidConversionFunction(yield bzz.uploadCollection(this.getKy(options), data, postageBatchId, options), ReferenceType.MANIFEST);
|
|
});
|
|
}
|
|
/**
|
|
* Upload Collection that you can assembly yourself.
|
|
*
|
|
* The returned `UploadResult.tag` might be undefined if called in CORS-enabled environment.
|
|
* This will be fixed upon next Bee release. https://github.com/ethersphere/bee-js/issues/406
|
|
*
|
|
* @param postageBatchId
|
|
* @param collection
|
|
* @param options Collections and request options
|
|
*/
|
|
|
|
|
|
uploadCollection(postageBatchId, collection, options) {
|
|
return __awaiter(this, void 0, void 0, function* () {
|
|
assertBatchId(postageBatchId);
|
|
assertCollection(collection);
|
|
if (options) assertCollectionUploadOptions(options);
|
|
return addCidConversionFunction(yield bzz.uploadCollection(this.ky, collection, postageBatchId, options), ReferenceType.MANIFEST);
|
|
});
|
|
}
|
|
/**
|
|
* Upload collection of files.
|
|
*
|
|
* Available only in Node.js as it uses the `fs` module.
|
|
*
|
|
* The returned `UploadResult.tag` might be undefined if called in CORS-enabled environment.
|
|
* This will be fixed upon next Bee release. https://github.com/ethersphere/bee-js/issues/406
|
|
*
|
|
* @param postageBatchId Postage BatchId to be used to upload the data with
|
|
* @param dir the path of the files to be uploaded
|
|
* @param options Additional options like tag, encryption, pinning and 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 docs - Upload directory](https://docs.ethswarm.org/docs/access-the-swarm/upload-a-directory/)
|
|
* @see [Bee API reference - `POST /bzz`](https://docs.ethswarm.org/api/#tag/Collection/paths/~1bzz/post)
|
|
*/
|
|
|
|
|
|
uploadFilesFromDirectory(postageBatchId, dir, options) {
|
|
return __awaiter(this, void 0, void 0, function* () {
|
|
assertBatchId(postageBatchId);
|
|
if (options) assertCollectionUploadOptions(options);
|
|
const data = yield makeCollectionFromFS(dir);
|
|
return addCidConversionFunction(yield bzz.uploadCollection(this.getKy(options), data, postageBatchId, options), ReferenceType.MANIFEST);
|
|
});
|
|
}
|
|
/**
|
|
* Create a new Tag which is meant for tracking progres of syncing data across network.
|
|
*
|
|
* **Warning! Not allowed when node is in Gateway mode!**
|
|
*
|
|
* @param options Options that affects the request behavior
|
|
* @see [Bee docs - Syncing / Tags](https://docs.ethswarm.org/docs/access-the-swarm/syncing)
|
|
* @see [Bee API reference - `POST /tags`](https://docs.ethswarm.org/api/#tag/Tag/paths/~1tags/post)
|
|
*/
|
|
|
|
|
|
createTag(options) {
|
|
return __awaiter(this, void 0, void 0, function* () {
|
|
assertRequestOptions(options);
|
|
return tag.createTag(this.getKy(options));
|
|
});
|
|
}
|
|
/**
|
|
* Fetches all tags.
|
|
*
|
|
* The listing is limited by options.limit. So you have to iterate using options.offset to get all tags.
|
|
*
|
|
* **Warning! Not allowed when node is in Gateway mode!**
|
|
*
|
|
* @param options Options that affects the request behavior
|
|
* @throws TypeError if limit or offset are not numbers or undefined
|
|
* @throws BeeArgumentError if limit or offset have invalid options
|
|
*
|
|
* @see [Bee docs - Syncing / Tags](https://docs.ethswarm.org/docs/access-the-swarm/syncing)
|
|
* @see [Bee API reference - `GET /tags`](https://docs.ethswarm.org/api/#tag/Tag/paths/~1tags/get)
|
|
*/
|
|
|
|
|
|
getAllTags(options) {
|
|
return __awaiter(this, void 0, void 0, function* () {
|
|
assertRequestOptions(options);
|
|
assertAllTagsOptions(options);
|
|
return tag.getAllTags(this.getKy(options), options === null || options === void 0 ? void 0 : options.offset, options === null || options === void 0 ? void 0 : options.limit);
|
|
});
|
|
}
|
|
/**
|
|
* Retrieve tag information from Bee node
|
|
*
|
|
* **Warning! Not allowed when node is in Gateway mode!**
|
|
*
|
|
* @param tagUid UID or tag object to be retrieved
|
|
* @param options Options that affects the request behavior
|
|
* @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/api/#tag/Tag/paths/~1tags~1{uid}/get)
|
|
*
|
|
*/
|
|
|
|
|
|
retrieveTag(tagUid, options) {
|
|
return __awaiter(this, void 0, void 0, function* () {
|
|
assertRequestOptions(options);
|
|
tagUid = makeTagUid(tagUid);
|
|
return tag.retrieveTag(this.getKy(options), tagUid);
|
|
});
|
|
}
|
|
/**
|
|
* Delete Tag
|
|
*
|
|
* **Warning! Not allowed when node is in Gateway mode!**
|
|
*
|
|
* @param tagUid UID or tag object to be retrieved
|
|
* @param options Options that affects the request behavior
|
|
* @throws TypeError if tagUid is in not correct format
|
|
* @throws BeeResponse error if something went wrong on the Bee node side while deleting the tag.
|
|
*
|
|
* @see [Bee docs - Syncing / Tags](https://docs.ethswarm.org/docs/access-the-swarm/syncing)
|
|
* @see [Bee API reference - `DELETE /tags/{uid}`](https://docs.ethswarm.org/api/#tag/Tag/paths/~1tags~1{uid}/delete)
|
|
*/
|
|
|
|
|
|
deleteTag(tagUid, options) {
|
|
return __awaiter(this, void 0, void 0, function* () {
|
|
assertRequestOptions(options);
|
|
tagUid = makeTagUid(tagUid);
|
|
return tag.deleteTag(this.getKy(options), tagUid);
|
|
});
|
|
}
|
|
/**
|
|
* Update tag's total chunks count.
|
|
*
|
|
* This is important if you are uploading individual chunks with a tag. Then upon finishing the final root chunk,
|
|
* you can use this method to update the total chunks count for the tag.
|
|
*
|
|
* **Warning! Not allowed when node is in Gateway mode!**
|
|
*
|
|
* @param tagUid UID or tag object to be retrieved
|
|
* @param reference The root reference that contains all the chunks to be counted
|
|
* @param options Options that affects the request behavior
|
|
* @throws TypeError if tagUid is in not correct format
|
|
* @throws BeeResponse error if something went wrong on the Bee node side while deleting the tag.
|
|
*
|
|
* @see [Bee docs - Syncing / Tags](https://docs.ethswarm.org/docs/access-the-swarm/syncing)
|
|
* @see [Bee API reference - `PATCH /tags/{uid}`](https://docs.ethswarm.org/api/#tag/Tag/paths/~1tags~1{uid}/patch)
|
|
*/
|
|
|
|
|
|
updateTag(tagUid, reference, options) {
|
|
return __awaiter(this, void 0, void 0, function* () {
|
|
assertReference(reference);
|
|
assertRequestOptions(options);
|
|
tagUid = makeTagUid(tagUid);
|
|
return tag.updateTag(this.getKy(options), tagUid, reference);
|
|
});
|
|
}
|
|
/**
|
|
* Pin local data with given reference
|
|
*
|
|
* **Warning! Not allowed when node is in Gateway mode!**
|
|
*
|
|
* @param reference Data reference
|
|
* @param options Options that affects the request behavior
|
|
* @throws TypeError if reference is in not correct format
|
|
*
|
|
* @see [Bee docs - Pinning](https://docs.ethswarm.org/docs/access-the-swarm/pinning)
|
|
*/
|
|
|
|
|
|
pin(reference, options) {
|
|
return __awaiter(this, void 0, void 0, function* () {
|
|
assertRequestOptions(options);
|
|
assertReference(reference);
|
|
return pinning.pin(this.getKy(options), reference);
|
|
});
|
|
}
|
|
/**
|
|
* Unpin local data with given reference
|
|
*
|
|
* **Warning! Not allowed when node is in Gateway mode!**
|
|
*
|
|
* @param reference Data reference
|
|
* @param options Options that affects the request behavior
|
|
* @throws TypeError if reference is in not correct format
|
|
*
|
|
* @see [Bee docs - Pinning](https://docs.ethswarm.org/docs/access-the-swarm/pinning)
|
|
*/
|
|
|
|
|
|
unpin(reference, options) {
|
|
return __awaiter(this, void 0, void 0, function* () {
|
|
assertRequestOptions(options);
|
|
assertReference(reference);
|
|
return pinning.unpin(this.getKy(options), reference);
|
|
});
|
|
}
|
|
/**
|
|
* Get list of all locally pinned references
|
|
*
|
|
* **Warning! Not allowed when node is in Gateway mode!**
|
|
*
|
|
* @param options Options that affects the request behavior
|
|
* @see [Bee docs - Pinning](https://docs.ethswarm.org/docs/access-the-swarm/pinning)
|
|
*/
|
|
|
|
|
|
getAllPins(options) {
|
|
return __awaiter(this, void 0, void 0, function* () {
|
|
assertRequestOptions(options);
|
|
return pinning.getAllPins(this.getKy(options));
|
|
});
|
|
}
|
|
/**
|
|
* Get pinning status of chunk with given reference
|
|
*
|
|
* **Warning! Not allowed when node is in Gateway mode!**
|
|
*
|
|
* @param reference Bee data reference in hex string (either 64 or 128 chars long) or ENS domain.
|
|
* @param options Options that affects the request behavior
|
|
* @throws TypeError if some of the input parameters is not expected type
|
|
* @throws BeeArgumentError if there is passed ENS domain with invalid unicode characters
|
|
*
|
|
* @see [Bee docs - Pinning](https://docs.ethswarm.org/docs/access-the-swarm/pinning)
|
|
*/
|
|
|
|
|
|
getPin(reference, options) {
|
|
return __awaiter(this, void 0, void 0, function* () {
|
|
assertRequestOptions(options);
|
|
assertReference(reference);
|
|
return pinning.getPin(this.getKy(options), reference);
|
|
});
|
|
}
|
|
/**
|
|
* Instructs the Bee node to reupload a locally pinned data into the network.
|
|
*
|
|
* @param reference Bee data reference to be re-uploaded in hex string (either 64 or 128 chars long) or ENS domain.
|
|
* @param options Options that affects the request behavior
|
|
* @throws BeeArgumentError if the reference is not locally pinned
|
|
* @throws TypeError if some of the input parameters is not expected type
|
|
* @throws BeeArgumentError if there is passed ENS domain with invalid unicode characters
|
|
*
|
|
* @see [Bee API reference - `PUT /stewardship`](https://docs.ethswarm.org/api/#tag/Stewardship/paths/~1stewardship~1{reference}/put)
|
|
*/
|
|
|
|
|
|
reuploadPinnedData(reference, options) {
|
|
return __awaiter(this, void 0, void 0, function* () {
|
|
assertRequestOptions(options);
|
|
assertReferenceOrEns(reference);
|
|
yield stewardship.reupload(this.getKy(options), reference);
|
|
});
|
|
}
|
|
/**
|
|
* Checks if content specified by reference is retrievable from the network.
|
|
*
|
|
* @param reference Bee data reference to be checked in hex string (either 64 or 128 chars long) or ENS domain.
|
|
* @param options Options that affects the request behavior
|
|
* @throws TypeError if some of the input parameters is not expected type
|
|
* @throws BeeArgumentError if there is passed ENS domain with invalid unicode characters
|
|
*
|
|
* @see [Bee API reference - `GET /stewardship`](https://docs.ethswarm.org/api/#tag/Stewardship/paths/~1stewardship~1{reference}/get)
|
|
*/
|
|
|
|
|
|
isReferenceRetrievable(reference, options) {
|
|
return __awaiter(this, void 0, void 0, function* () {
|
|
assertRequestOptions(options);
|
|
assertReferenceOrEns(reference);
|
|
return stewardship.isRetrievable(this.getKy(options), reference);
|
|
});
|
|
}
|
|
/**
|
|
* Functions that validates if feed is retrievable in the network.
|
|
*
|
|
* If no index is passed then it check for "latest" update, which is a weaker guarantee as nobody can be really
|
|
* sure what is the "latest" update.
|
|
*
|
|
* If index is passed then it validates all previous sequence index chunks if they are available as they are required
|
|
* to correctly resolve the feed upto the given index update.
|
|
*
|
|
* @param type
|
|
* @param owner
|
|
* @param topic
|
|
* @param index
|
|
* @param options
|
|
*/
|
|
|
|
|
|
isFeedRetrievable(type, owner, topic, index, options) {
|
|
return __awaiter(this, void 0, void 0, function* () {
|
|
const canonicalOwner = makeEthAddress(owner);
|
|
const canonicalTopic = makeTopic(topic);
|
|
|
|
if (!index) {
|
|
try {
|
|
yield this.makeFeedReader(type, canonicalTopic, canonicalOwner).download();
|
|
return true;
|
|
} catch (e) {
|
|
const err = e; // Only if the error is "not-found" then we return false otherwise we re-throw the error
|
|
|
|
if ((err === null || err === void 0 ? void 0 : err.status) === 404) {
|
|
return false;
|
|
}
|
|
|
|
throw e;
|
|
}
|
|
}
|
|
|
|
if (type !== 'sequence') {
|
|
throw new BeeError('Only Sequence type of Feeds is supported at the moment');
|
|
}
|
|
|
|
return areAllSequentialFeedsUpdateRetrievable(this, canonicalOwner, canonicalTopic, index, options);
|
|
});
|
|
}
|
|
/**
|
|
* Send data to recipient or target with Postal Service for Swarm.
|
|
*
|
|
* Because sending a PSS message is slow and CPU intensive,
|
|
* it is not supposed to be used for general messaging but
|
|
* most likely for setting up an encrypted communication
|
|
* channel by sending an one-off message.
|
|
*
|
|
* **Warning! Not allowed when node is in Gateway mode!**
|
|
*
|
|
* **Warning! If the recipient Bee node is a light node, then he will never receive the message!**
|
|
* This is because light nodes does not fully participate in the data exchange in Swarm network and hence the message won't arrive to them.
|
|
*
|
|
* @param postageBatchId Postage BatchId that will be assigned to sent message
|
|
* @param topic Topic name
|
|
* @param target Target message address prefix. Has a limit on length. Recommend to use `Utils.Pss.makeMaxTarget()` to get the most specific target that Bee node will accept.
|
|
* @param data Message to be sent
|
|
* @param recipient Recipient public key
|
|
* @param options Options that affects the request behavior
|
|
* @throws TypeError if `data`, `batchId`, `target` or `recipient` are in invalid format
|
|
*
|
|
* @see [Bee docs - PSS](https://docs.ethswarm.org/docs/dapps-on-swarm/pss)
|
|
* @see [Bee API reference - `POST /pss`](https://docs.ethswarm.org/api/#tag/Postal-Service-for-Swarm/paths/~1pss~1send~1{topic}~1{targets}/post)
|
|
*/
|
|
|
|
|
|
pssSend(postageBatchId, topic, target, data, recipient, options) {
|
|
return __awaiter(this, void 0, void 0, function* () {
|
|
assertRequestOptions(options);
|
|
assertData(data);
|
|
assertBatchId(postageBatchId);
|
|
assertAddressPrefix(target);
|
|
|
|
if (typeof topic !== 'string') {
|
|
throw new TypeError('topic has to be an string!');
|
|
}
|
|
|
|
if (recipient) {
|
|
assertPublicKey(recipient);
|
|
return pss.send(this.getKy(options), topic, target, data, postageBatchId, recipient);
|
|
} else {
|
|
return pss.send(this.getKy(options), topic, target, data, postageBatchId);
|
|
}
|
|
});
|
|
}
|
|
/**
|
|
* Subscribe to messages for given topic with Postal Service for Swarm
|
|
*
|
|
* **Warning! Not allowed when node is in Gateway mode!**
|
|
*
|
|
* **Warning! If connected Bee node is a light node, then he will never receive any message!**
|
|
* This is because light nodes does not fully participate in the data exchange in Swarm network and hence the message won't arrive to them.
|
|
*
|
|
* @param topic Topic name
|
|
* @param handler Message handler interface
|
|
*
|
|
* @returns Subscription to a given topic
|
|
*
|
|
* @see [Bee docs - PSS](https://docs.ethswarm.org/docs/dapps-on-swarm/pss)
|
|
* @see [Bee API reference - `GET /pss`](https://docs.ethswarm.org/api/#tag/Postal-Service-for-Swarm/paths/~1pss~1subscribe~1{topic}/get)
|
|
*/
|
|
|
|
|
|
pssSubscribe(topic, handler) {
|
|
assertPssMessageHandler(handler);
|
|
|
|
if (typeof topic !== 'string') {
|
|
throw new TypeError('topic has to be an string!');
|
|
}
|
|
|
|
const ws = pss.subscribe(this.url, topic);
|
|
let cancelled = false;
|
|
|
|
const cancel = () => {
|
|
if (cancelled === false) {
|
|
cancelled = true; // although the WebSocket API offers a `close` function, it seems that
|
|
// with the library that we are using (isomorphic-ws) it doesn't close
|
|
// the websocket properly, whereas `terminate` does
|
|
|
|
if (ws.terminate) ws.terminate();else ws.close(); // standard Websocket in browser does not have terminate function
|
|
}
|
|
};
|
|
|
|
const subscription = {
|
|
topic,
|
|
cancel
|
|
};
|
|
|
|
ws.onmessage = ev => __awaiter(this, void 0, void 0, function* () {
|
|
const data = yield prepareWebsocketData(ev.data); // ignore empty messages
|
|
|
|
if (data.length > 0) {
|
|
handler.onMessage(wrapBytesWithHelpers(data), subscription);
|
|
}
|
|
});
|
|
|
|
ws.onerror = ev => {
|
|
// ignore errors after subscription was cancelled
|
|
if (!cancelled) {
|
|
handler.onError(new BeeError(ev.message), subscription);
|
|
}
|
|
};
|
|
|
|
return subscription;
|
|
}
|
|
/**
|
|
* Receive message with Postal Service for Swarm
|
|
*
|
|
* Because sending a PSS message is slow and CPU intensive,
|
|
* it is not supposed to be used for general messaging but
|
|
* most likely for setting up an encrypted communication
|
|
* channel by sending an one-off message.
|
|
*
|
|
* This is a helper function to wait for exactly one message to
|
|
* arrive and then cancel the subscription. Additionally a
|
|
* timeout can be provided for the message to arrive or else
|
|
* an error will be thrown.
|
|
*
|
|
* **Warning! Not allowed when node is in Gateway mode!**
|
|
*
|
|
* **Warning! If connected Bee node is a light node, then he will never receive any message!**
|
|
* This is because light nodes does not fully participate in the data exchange in Swarm network and hence the message won't arrive to them.
|
|
*
|
|
* @param topic Topic name
|
|
* @param timeoutMsec Timeout in milliseconds
|
|
*
|
|
* @returns Message in byte array
|
|
*
|
|
* @see [Bee docs - PSS](https://docs.ethswarm.org/docs/dapps-on-swarm/pss)
|
|
* @see [Bee API reference - `GET /pss`](https://docs.ethswarm.org/api/#tag/Postal-Service-for-Swarm/paths/~1pss~1subscribe~1{topic}/get)
|
|
*/
|
|
|
|
|
|
pssReceive(topic, timeoutMsec = 0) {
|
|
return __awaiter(this, void 0, void 0, function* () {
|
|
if (typeof topic !== 'string') {
|
|
throw new TypeError('topic has to be an string!');
|
|
}
|
|
|
|
if (typeof timeoutMsec !== 'number') {
|
|
throw new TypeError('timeoutMsc parameter has to be a number!');
|
|
}
|
|
|
|
return new Promise((resolve, reject) => {
|
|
let timeout;
|
|
const subscription = this.pssSubscribe(topic, {
|
|
onError: error => {
|
|
clearTimeout(timeout);
|
|
subscription.cancel();
|
|
reject(error.message);
|
|
},
|
|
onMessage: message => {
|
|
clearTimeout(timeout);
|
|
subscription.cancel();
|
|
resolve(message);
|
|
}
|
|
});
|
|
|
|
if (timeoutMsec > 0) {
|
|
// we need to cast the type because Typescript is getting confused with Node.js'
|
|
// alternative type definitions
|
|
timeout = setTimeout(() => {
|
|
subscription.cancel();
|
|
reject(new BeeError('pssReceive timeout'));
|
|
}, timeoutMsec);
|
|
}
|
|
});
|
|
});
|
|
}
|
|
/**
|
|
* Create feed manifest chunk and return the reference to it.
|
|
*
|
|
* Feed manifest chunk allows for a feed to be able to be resolved through `/bzz` endpoint.
|
|
*
|
|
* @param postageBatchId Postage BatchId to be used to create the Feed Manifest
|
|
* @param type The type of the feed, can be 'epoch' or 'sequence'
|
|
* @param topic Topic in hex or bytes
|
|
* @param owner Owner's ethereum address in hex or bytes
|
|
* @param options Options that affects the request behavior
|
|
*
|
|
* @see [Bee docs - Feeds](https://docs.ethswarm.org/docs/dapps-on-swarm/feeds)
|
|
* @see [Bee API reference - `POST /feeds`](https://docs.ethswarm.org/api/#tag/Feed/paths/~1feeds~1{owner}~1{topic}/post)
|
|
* TODO: Once breaking add support for Feed CID
|
|
*/
|
|
|
|
|
|
createFeedManifest(postageBatchId, type, topic, owner, options) {
|
|
return __awaiter(this, void 0, void 0, function* () {
|
|
assertRequestOptions(options);
|
|
assertFeedType(type);
|
|
assertBatchId(postageBatchId);
|
|
const canonicalTopic = makeTopic(topic);
|
|
const canonicalOwner = makeHexEthAddress(owner);
|
|
return createFeedManifest(this.getKy(options), canonicalOwner, canonicalTopic, postageBatchId, {
|
|
type
|
|
});
|
|
});
|
|
}
|
|
/**
|
|
* Make a new feed reader for downloading feed updates.
|
|
*
|
|
* @param type The type of the feed, can be 'epoch' or 'sequence'
|
|
* @param topic Topic in hex or bytes
|
|
* @param owner Owner's ethereum address in hex or bytes
|
|
* @param options Options that affects the request behavior
|
|
*
|
|
* @see [Bee docs - Feeds](https://docs.ethswarm.org/docs/dapps-on-swarm/feeds)
|
|
*/
|
|
|
|
|
|
makeFeedReader(type, topic, owner, options) {
|
|
assertRequestOptions(options);
|
|
assertFeedType(type);
|
|
const canonicalTopic = makeTopic(topic);
|
|
const canonicalOwner = makeHexEthAddress(owner);
|
|
return makeFeedReader(this.getKy(options), type, canonicalTopic, canonicalOwner);
|
|
}
|
|
/**
|
|
* Make a new feed writer for updating feeds
|
|
*
|
|
* @param type The type of the feed, can be 'epoch' or 'sequence'
|
|
* @param topic Topic in hex or bytes
|
|
* @param signer The signer's private key or a Signer instance that can sign data
|
|
* @param options Options that affects the request behavior
|
|
*
|
|
* @see [Bee docs - Feeds](https://docs.ethswarm.org/docs/dapps-on-swarm/feeds)
|
|
*/
|
|
|
|
|
|
makeFeedWriter(type, topic, signer, options) {
|
|
assertRequestOptions(options);
|
|
assertFeedType(type);
|
|
const canonicalTopic = makeTopic(topic);
|
|
const canonicalSigner = this.resolveSigner(signer);
|
|
return makeFeedWriter(this.getKy(options), type, canonicalTopic, canonicalSigner);
|
|
}
|
|
/**
|
|
* High-level function that allows you to easily set JSON data to feed.
|
|
* JSON-like data types are supported.
|
|
*
|
|
* The default Signer of Bee instance is used if `options.signer` is not specified.
|
|
* If none of those two is set error is thrown.
|
|
*
|
|
* @param postageBatchId Postage BatchId to be used to upload the data with
|
|
* @param topic Human readable string, that is internally hashed so there are no constrains there.
|
|
* @param data JSON compatible data
|
|
* @param options
|
|
* @param options.signer Custom instance of Signer or string with private key.
|
|
* @param options.type Type of Feed
|
|
*
|
|
* @throws BeeError if `options.signer` is not specified nor the default Signer on Bee's instance is specified.
|
|
*
|
|
* @see [Bee docs - Feeds](https://docs.ethswarm.org/docs/dapps-on-swarm/feeds)
|
|
*/
|
|
|
|
|
|
setJsonFeed(postageBatchId, topic, data, options) {
|
|
var _a;
|
|
|
|
return __awaiter(this, void 0, void 0, function* () {
|
|
assertRequestOptions(options, 'JsonFeedOptions');
|
|
assertBatchId(postageBatchId);
|
|
const hashedTopic = this.makeFeedTopic(topic);
|
|
const feedType = (_a = options === null || options === void 0 ? void 0 : options.type) !== null && _a !== void 0 ? _a : DEFAULT_FEED_TYPE;
|
|
const writer = this.makeFeedWriter(feedType, hashedTopic, options === null || options === void 0 ? void 0 : options.signer, options);
|
|
return setJsonData(this, writer, postageBatchId, data, options);
|
|
});
|
|
}
|
|
/**
|
|
* High-level function that allows you to easily get data from feed.
|
|
* Returned data are parsed using JSON.parse().
|
|
*
|
|
* This method also supports specification of `signer` object passed to constructor. The order of evaluation is:
|
|
* - `options.address`
|
|
* - `options.signer`
|
|
* - `this.signer`
|
|
*
|
|
* At least one of these has to be specified!
|
|
*
|
|
* @param topic Human readable string, that is internally hashed so there are no constrains there.
|
|
* @param options
|
|
* @param options.signer Custom instance of Signer or string with private key. This option is exclusive with `address` option.
|
|
* @param options.address Ethereum address of owner of the feed that signed it. This option is exclusive with `signer` option.
|
|
* @param options.type Type of Feed
|
|
*
|
|
* @see [Bee docs - Feeds](https://docs.ethswarm.org/docs/dapps-on-swarm/feeds)
|
|
*/
|
|
|
|
|
|
getJsonFeed(topic, options) {
|
|
var _a;
|
|
|
|
return __awaiter(this, void 0, void 0, function* () {
|
|
assertRequestOptions(options, 'JsonFeedOptions');
|
|
const hashedTopic = this.makeFeedTopic(topic);
|
|
const feedType = (_a = options === null || options === void 0 ? void 0 : options.type) !== null && _a !== void 0 ? _a : DEFAULT_FEED_TYPE;
|
|
|
|
if ((options === null || options === void 0 ? void 0 : options.signer) && (options === null || options === void 0 ? void 0 : options.address)) {
|
|
throw new BeeError('Both options "signer" and "address" can not be specified at one time!');
|
|
}
|
|
|
|
let address;
|
|
|
|
if (options === null || options === void 0 ? void 0 : options.address) {
|
|
address = makeEthAddress(options === null || options === void 0 ? void 0 : options.address);
|
|
} else {
|
|
try {
|
|
address = this.resolveSigner(options === null || options === void 0 ? void 0 : options.signer).address;
|
|
} catch (e) {
|
|
if (e instanceof BeeError) {
|
|
throw new BeeError('Either address, signer or default signer has to be specified!');
|
|
} else {
|
|
throw e;
|
|
}
|
|
}
|
|
}
|
|
|
|
const reader = this.makeFeedReader(feedType, hashedTopic, address, options);
|
|
return getJsonData(this, reader);
|
|
});
|
|
}
|
|
/**
|
|
* Make a new feed topic from a string
|
|
*
|
|
* Because the topic has to be 32 bytes long this function
|
|
* hashes the input string to create a topic string of arbitrary length.
|
|
*
|
|
* @param topic The input string
|
|
*/
|
|
|
|
|
|
makeFeedTopic(topic) {
|
|
return makeTopicFromString(topic);
|
|
}
|
|
/**
|
|
* Returns an object for reading single owner chunks
|
|
*
|
|
* @param ownerAddress The ethereum address of the owner
|
|
* @param options Options that affects the request behavior
|
|
* @see [Bee docs - Chunk Types](https://docs.ethswarm.org/docs/dapps-on-swarm/chunk-types#single-owner-chunks)
|
|
*/
|
|
|
|
|
|
makeSOCReader(ownerAddress, options) {
|
|
assertRequestOptions(options);
|
|
const canonicalOwner = makeEthAddress(ownerAddress);
|
|
return {
|
|
owner: makeHexEthAddress(canonicalOwner),
|
|
download: downloadSingleOwnerChunk.bind(null, this.getKy(options), canonicalOwner)
|
|
};
|
|
}
|
|
/**
|
|
* Returns an object for reading and writing single owner chunks
|
|
*
|
|
* @param signer The signer's private key or a Signer instance that can sign data
|
|
* @param options Options that affects the request behavior
|
|
* @see [Bee docs - Chunk Types](https://docs.ethswarm.org/docs/dapps-on-swarm/chunk-types#single-owner-chunks)
|
|
*/
|
|
|
|
|
|
makeSOCWriter(signer, options) {
|
|
assertRequestOptions(options);
|
|
const canonicalSigner = this.resolveSigner(signer);
|
|
return Object.assign(Object.assign({}, this.makeSOCReader(canonicalSigner.address, options)), {
|
|
upload: uploadSingleOwnerChunkData.bind(null, this.getKy(options), canonicalSigner)
|
|
});
|
|
}
|
|
/**
|
|
* Ping the Bee node to see if there is a live Bee node on the given URL.
|
|
*
|
|
* @param options Options that affects the request behavior
|
|
* @throws If connection was not successful throw error
|
|
*/
|
|
|
|
|
|
checkConnection(options) {
|
|
return __awaiter(this, void 0, void 0, function* () {
|
|
assertRequestOptions(options, 'PostageBatchOptions');
|
|
return status.checkConnection(this.getKy(options));
|
|
});
|
|
}
|
|
/**
|
|
* Ping the Bee node to see if there is a live Bee node on the given URL.
|
|
*
|
|
* @param options Options that affects the request behavior
|
|
* @returns true if successful, false on error
|
|
*/
|
|
|
|
|
|
isConnected(options) {
|
|
return __awaiter(this, void 0, void 0, function* () {
|
|
assertRequestOptions(options, 'PostageBatchOptions');
|
|
|
|
try {
|
|
yield status.checkConnection(this.getKy(options));
|
|
} catch (e) {
|
|
return false;
|
|
}
|
|
|
|
return true;
|
|
});
|
|
}
|
|
/**
|
|
* @param signer
|
|
* @private
|
|
* @throws BeeError if either no Signer was passed or no default Signer was specified for the instance
|
|
*/
|
|
|
|
|
|
resolveSigner(signer) {
|
|
if (signer) {
|
|
return makeSigner(signer);
|
|
}
|
|
|
|
if (this.signer) {
|
|
return this.signer;
|
|
}
|
|
|
|
throw new BeeError('You have to pass Signer as property to either the method call or constructor! Non found.');
|
|
}
|
|
|
|
getKy(options) {
|
|
if (!options) {
|
|
return this.ky;
|
|
}
|
|
|
|
return this.ky.extend(options);
|
|
}
|
|
|
|
} |