diff --git a/package-lock.json b/package-lock.json index c83c419b..6a350361 100644 --- a/package-lock.json +++ b/package-lock.json @@ -10,7 +10,7 @@ "license": "BSD-3-Clause", "dependencies": { "@ethersphere/bee-js": "^6.2.0", - "@fairdatasociety/fdp-contracts-js": "^3.10.0", + "@fairdatasociety/fdp-contracts-js": "^3.10.1", "crypto-js": "^4.2.0", "elliptic": "^6.5.4", "ethers": "^5.5.2", @@ -3296,9 +3296,9 @@ } }, "node_modules/@fairdatasociety/fdp-contracts-js": { - "version": "3.10.0", - "resolved": "https://registry.npmjs.org/@fairdatasociety/fdp-contracts-js/-/fdp-contracts-js-3.10.0.tgz", - "integrity": "sha512-kaHu9UZBs2s58PQZ6o2SUn4vtswLBPLkIdFt8WH+6uHO8WA73gOGK5Ue9/WIN1tYu/bcgQpNNiO5xhQn99mW5g==", + "version": "3.10.1", + "resolved": "https://registry.npmjs.org/@fairdatasociety/fdp-contracts-js/-/fdp-contracts-js-3.10.1.tgz", + "integrity": "sha512-letk0QcHlv2nNrM7ZF0iazT07IWseM+T0iC9Ax61/dHeR0j/aLkGFv/IiFbMTEXs6xc2iFp+Thoa4x5bmd51Jw==", "peerDependencies": { "ethers": ">=5.6.4" } @@ -17552,9 +17552,9 @@ } }, "@fairdatasociety/fdp-contracts-js": { - "version": "3.10.0", - "resolved": "https://registry.npmjs.org/@fairdatasociety/fdp-contracts-js/-/fdp-contracts-js-3.10.0.tgz", - "integrity": "sha512-kaHu9UZBs2s58PQZ6o2SUn4vtswLBPLkIdFt8WH+6uHO8WA73gOGK5Ue9/WIN1tYu/bcgQpNNiO5xhQn99mW5g==", + "version": "3.10.1", + "resolved": "https://registry.npmjs.org/@fairdatasociety/fdp-contracts-js/-/fdp-contracts-js-3.10.1.tgz", + "integrity": "sha512-letk0QcHlv2nNrM7ZF0iazT07IWseM+T0iC9Ax61/dHeR0j/aLkGFv/IiFbMTEXs6xc2iFp+Thoa4x5bmd51Jw==", "requires": {} }, "@fluffy-spoon/substitute": { diff --git a/package.json b/package.json index 7d254267..8dbf3a4a 100644 --- a/package.json +++ b/package.json @@ -55,7 +55,7 @@ }, "dependencies": { "@ethersphere/bee-js": "^6.2.0", - "@fairdatasociety/fdp-contracts-js": "^3.10.0", + "@fairdatasociety/fdp-contracts-js": "^3.10.1", "crypto-js": "^4.2.0", "elliptic": "^6.5.4", "ethers": "^5.5.2", diff --git a/src/directory/directory.ts b/src/directory/directory.ts index 555c5f32..36f5d3d3 100644 --- a/src/directory/directory.ts +++ b/src/directory/directory.ts @@ -22,6 +22,8 @@ import { uploadData } from '../file/handler' import { assertNodeFileInfo, isBrowserFileInfo } from './types' import { DirectoryItem } from '../content-items/types' import { prepareEthAddress } from '../utils/wallet' +import { PodShareInfo } from '../pod/types' +import { Utils } from '@ethersphere/bee-js' /** * Directory related class @@ -99,6 +101,31 @@ export class Directory { } } + /** + * Get files and directories under the given path from a shared pod + * + * Account is required, postage batch id is not required + * + * @param pod a PodShareInfo object + * @param path path to start searching from + * @param isRecursive search with recursion or not + */ + async readFromShared(pod: PodShareInfo, path: string, isRecursive?: boolean): Promise { + const { podName, podAddress, password } = pod + assertAccount(this.accountData) + assertPodName(pod.podName) + + return await readDirectory( + this.accountData, + podName, + path, + prepareEthAddress(podAddress), + Utils.hexToBytes(password), + isRecursive, + this.accountData.connection.options?.requestOptions, + ) + } + /** * Creates a directory * diff --git a/src/file/file.ts b/src/file/file.ts index 5c6b4b9f..7a15418e 100644 --- a/src/file/file.ts +++ b/src/file/file.ts @@ -12,7 +12,13 @@ import { uploadBytes, } from './utils' import { writeFeedData } from '../feed/api' -import { downloadData, getFileMetadataWithBlocks, uploadData, uploadDataBlock } from './handler' +import { + downloadArbitraryPodData, + downloadData, + getFileMetadataWithBlocks, + uploadData, + uploadDataBlock, +} from './handler' import { getFileMetadataRawBytes, rawFileMetadataToFileMetadata } from './adapter' import { DataDownloadOptions, @@ -23,7 +29,7 @@ import { FileShareInfo, } from './types' import { addEntryToDirectory, DEFAULT_UPLOAD_OPTIONS, removeEntryFromDirectory } from '../content-items/handler' -import { BeeRequestOptions, Reference } from '@ethersphere/bee-js' +import { BeeRequestOptions, Reference, Utils } from '@ethersphere/bee-js' import { getRawMetadata } from '../content-items/utils' import { assertRawFileMetadata, combine, splitPath } from '../directory/utils' import { assertEncryptedReference, EncryptedReference } from '../utils/hex' @@ -59,6 +65,35 @@ export class File { ) } + /** + * Downloads file content from any pod + * + * Account is required, postage batch id is not required + * + * @param podAddress pod address + * @param podPassword pod password + * @param fullPath full path of the file + * @param options download options + */ + async downloadArbitraryPodData( + podAddress: string, + podPassword: string, + fullPath: string, + options?: DataDownloadOptions, + ): Promise { + assertAccount(this.accountData) + assertFullPathWithName(fullPath) + + return downloadArbitraryPodData( + this.accountData, + prepareEthAddress(podAddress), + Utils.hexToBytes(podPassword), + fullPath, + this.accountData.connection.options?.requestOptions, + options, + ) + } + /** * Uploads file content * diff --git a/src/file/handler.ts b/src/file/handler.ts index 4a81bbdc..76a9e414 100644 --- a/src/file/handler.ts +++ b/src/file/handler.ts @@ -100,8 +100,33 @@ export async function getFileMetadataWithBlocks( dataDownloadOptions = dataDownloadOptions ?? {} updateDownloadProgress(dataDownloadOptions, DownloadProgressType.GetPodInfo) const { podAddress, pod } = await getExtendedPodsListByAccountData(accountData, podName) + + return getFileMetadataWithBlocksAndPod(bee, accountData, podAddress, pod.password, fullPath, downloadOptions) +} + +/** + * Gets file metadata with blocks + * + * @param bee Bee + * @param accountData account data + * @param podAddress pod address + * @param podPassword pod password + * @param fullPath full path to the file + * @param downloadOptions download options + * @param dataDownloadOptions data download options + */ +export async function getFileMetadataWithBlocksAndPod( + bee: Bee, + accountData: AccountData, + podAddress: EthAddress, + podPassword: PodPasswordBytes, + fullPath: string, + downloadOptions?: BeeRequestOptions, + dataDownloadOptions?: DataDownloadOptions, +): Promise { + dataDownloadOptions = dataDownloadOptions ?? {} updateDownloadProgress(dataDownloadOptions, DownloadProgressType.GetPathInfo) - const fileMetadata = await getFileMetadata(bee, fullPath, podAddress, pod.password, downloadOptions) + const fileMetadata = await getFileMetadata(bee, fullPath, podAddress, podPassword, downloadOptions) updateDownloadProgress(dataDownloadOptions, DownloadProgressType.DownloadBlocksMeta) const blocks = await downloadBlocksManifest(bee, fileMetadata.blocksReference, downloadOptions) await prepareDataByMeta(fileMetadata, blocks.blocks, accountData.connection.bee, downloadOptions) @@ -191,6 +216,39 @@ export async function downloadData( return prepareDataByMeta(fileMeta, fileMeta.blocks, bee, downloadOptions, dataDownloadOptions) } +/** + * Downloads file parts and compile them into Data + * + * @param accountData account data + * @param podAddress pod address + * @param podPassword pod password + * @param fullPath full path to the file + * @param downloadOptions download options + * @param dataDownloadOptions data download options + */ +export async function downloadArbitraryPodData( + accountData: AccountData, + podAddress: EthAddress, + podPassword: PodPasswordBytes, + fullPath: string, + downloadOptions?: BeeRequestOptions, + dataDownloadOptions?: DataDownloadOptions, +): Promise { + dataDownloadOptions = dataDownloadOptions ?? {} + const bee = accountData.connection.bee + const fileMeta = await getFileMetadataWithBlocksAndPod( + bee, + accountData, + podAddress, + podPassword, + fullPath, + downloadOptions, + dataDownloadOptions, + ) + + return prepareDataByMeta(fileMeta, fileMeta.blocks, bee, downloadOptions, dataDownloadOptions) +} + /** * Interface representing information about blocks. * @interface diff --git a/src/pod/api.ts b/src/pod/api.ts index 55e39e5b..a8d969f1 100644 --- a/src/pod/api.ts +++ b/src/pod/api.ts @@ -75,3 +75,37 @@ export async function getExtendedPodsList( epoch, } } + +/** + * Gets pods list with pod addresses + * + * @param accountData account data + * @param bee Bee client + * @param userWallet root wallet for downloading and decrypting data + * @param seed seed of wallet owns the FDP account + * @param downloadOptions request options + */ +export async function getPodListExtended( + accountData: AccountData, + bee: Bee, + userWallet: utils.HDNode, + seed: Uint8Array, + downloadOptions?: DownloadOptions, +): Promise { + const { podsList, epoch } = await getPodsListCached(accountData, bee, userWallet, downloadOptions) + + const extendedPodList: ExtendedPodInfo[] = [] + + for (const pod of podsList.pods) { + const podWallet = await getWalletByIndex(seed, pod.index, downloadOptions?.cacheInfo) + + extendedPodList.push({ + pod, + podAddress: prepareEthAddress(podWallet.address), + podWallet, + epoch, + }) + } + + return extendedPodList +} diff --git a/src/pod/personal-storage.ts b/src/pod/personal-storage.ts index fd1990f7..4a268863 100644 --- a/src/pod/personal-storage.ts +++ b/src/pod/personal-storage.ts @@ -16,8 +16,9 @@ import { podsListPreparedToPodsList, sharedPodPreparedToSharedPod, uploadPodDataV2, + ExtendedPodInfo, } from './utils' -import { getExtendedPodsList } from './api' +import { getExtendedPodsList, getPodListExtended } from './api' import { uploadBytes } from '../file/utils' import { bytesToString, stringToBytes } from '../utils/bytes' import { Reference, Utils } from '@ethersphere/bee-js' @@ -74,6 +75,21 @@ export class PersonalStorage { return podsListPreparedToPodsList(podsList) } + async listExtended(): Promise { + assertAccount(this.accountData) + + return getPodListExtended( + this.accountData, + this.accountData.connection.bee, + this.accountData.wallet!, + this.accountData.seed!, + { + requestOptions: this.accountData.connection.options?.requestOptions, + cacheInfo: this.accountData.connection.cacheInfo, + }, + ) + } + /** * Creates new pod with passed name *