From d9fd28ab891613bcbe91980acc3c4e4abd179c63 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ferenc=20S=C3=A1rai?= Date: Thu, 23 Jan 2025 09:57:48 +0100 Subject: [PATCH 01/13] feat: add act skeleton --- docs/user-documentation/act.md | 94 ++++++++++++++++++++++++++++++++++ sidebars.js | 3 +- 2 files changed, 96 insertions(+), 1 deletion(-) create mode 100644 docs/user-documentation/act.md diff --git a/docs/user-documentation/act.md b/docs/user-documentation/act.md new file mode 100644 index 00000000..3ecaab6f --- /dev/null +++ b/docs/user-documentation/act.md @@ -0,0 +1,94 @@ +--- +title: Access Control Trie (ACT) +hide_title: true +id: act +slug: /act +sidebar_label: Access Control Trie +--- + +import Tabs from '@theme/Tabs' +import TabItem from '@theme/TabItem' + +## Access Control Trie + +The [Access Control Trie (ACT)](https://solarpunk.buzz/introducing-the-access-control-trie-act-in-swarm/) is an essential feature designed to manage access control in Swarm’s decentralized storage infrastructure. It enables __publishers__ to grant or revoke access to specific content at the chunk level using encrypted session keys. This guide will walk you through the key concepts and practical aspects of using __ACT__ to protect your data in Swarm. + +:::warning Postage stamps + +Uploading to Swarm network require to have Postage stamps for every write operation. To understand better what does it mean see [Bee docs - Keep your data alive](https://docs.ethswarm.org/docs/access-the-swarm/keep-your-data-alive). +::: + +### Data + +The same data structures can be handled with ACT as without ACT. + +### Upload with ACT + +When uploading, we can indicate that we are uploading with ACT in the optional requestOptions of bee-js uploadData method. + +```ts +const beeRequestOptionsUpload = { + act: true, +} +const uploadResultACT = await bee.uploadData( + postageBatchId, "Bee is awesome with ACT!", + beeRequestOptionsUpload) +console.log(uploadResultACT) +``` + +The return value provides a reference and a history reference. Both will be needed for the download. + +```json, title="uploadResultACT" +{ + reference: '97132e8e17831dfa220e73ee083bd82819aaeffce0aaf7e1e0abf8135fcfd2fc', + tagUid: 14, + historyAddress: 'c6cabe3a3b7879ddb182277f3037c02002d4ce33280007cac580ac9256be20ea' +} +``` + +:::info +During the upload, the publisher will be the uploading node. +::: + +### Get Node Public Key + +```js +import { Bee } from "@ethersphere/bee-js" + +const bee = new Bee('http://localhost:1633') +const addr = await bee.getNodeAddresses(); + +// node public key (publisher public key) +const pubk = addr.publicKey +``` + +### Download with ACT + +When downloading, we can indicate that we are downloading with __ACT__ in the optional requestOptions of `bee-js` `downloadData` method. + +:::warning +The download is only possible with the knowledge of the publisher's public key. +::: + +```ts +const beeRequestOptionsDownload = { + baseURL: BEE_API_URL, + timeout: 0, // false converted to number + headers: { + 'swarm-act': 'true', + 'swarm-act-publisher': pubk, // publisher public key + 'swarm-act-history-address': uploadResultACT.historyAddress, + }, + } + + const retrievedData = await bee.downloadData(uploadResultACT.reference, beeRequestOptionsDownload) + console.log(retrievedData) // prints 'Bee is awesome with ACT!' +``` + +### Create Grantee + +### List Grantees + +### Patch Grantees + +### List Grantees after patch diff --git a/sidebars.js b/sidebars.js index 5df1acb7..ba17db0a 100644 --- a/sidebars.js +++ b/sidebars.js @@ -9,7 +9,8 @@ module.exports = { 'user-documentation/upload-download', 'user-documentation/track-upload', 'user-documentation/pss', - 'user-documentation/soc-and-feeds' + 'user-documentation/soc-and-feeds', + 'user-documentation/act' ], collapsed: false }, From 01657ec5ae1f0ae98b3820de0ef235ef570e8a60 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ferenc=20S=C3=A1rai?= Date: Thu, 23 Jan 2025 17:47:59 +0100 Subject: [PATCH 02/13] feat: act upload, download, createGrantees, listGrantees, patchGrantees --- docs/user-documentation/act.md | 165 +++++++++++++++++++++++++-------- 1 file changed, 127 insertions(+), 38 deletions(-) diff --git a/docs/user-documentation/act.md b/docs/user-documentation/act.md index 3ecaab6f..306dc755 100644 --- a/docs/user-documentation/act.md +++ b/docs/user-documentation/act.md @@ -14,81 +14,170 @@ import TabItem from '@theme/TabItem' The [Access Control Trie (ACT)](https://solarpunk.buzz/introducing-the-access-control-trie-act-in-swarm/) is an essential feature designed to manage access control in Swarm’s decentralized storage infrastructure. It enables __publishers__ to grant or revoke access to specific content at the chunk level using encrypted session keys. This guide will walk you through the key concepts and practical aspects of using __ACT__ to protect your data in Swarm. :::warning Postage stamps - -Uploading to Swarm network require to have Postage stamps for every write operation. To understand better what does it mean see [Bee docs - Keep your data alive](https://docs.ethswarm.org/docs/access-the-swarm/keep-your-data-alive). +Uploading to the Swarm network requires Postage stamps for every write operation. To understand this better, see [Bee docs - Keep your data alive](https://docs.ethswarm.org/docs/access-the-swarm/keep-your-data-alive). In the following examples, we assume that we already have a `postageBatchId`. ::: -### Data +We also need an instance of Bee to interact with the Bee node. + +```ts +import { Bee } from "@ethersphere/bee-js" -The same data structures can be handled with ACT as without ACT. +const bee = new Bee('http://localhost:1633') +``` ### Upload with ACT -When uploading, we can indicate that we are uploading with ACT in the optional requestOptions of bee-js uploadData method. +When uploading, we can specify that we are using ACT in the optional `requestOptions` of the `bee-js` `uploadData` method. ```ts const beeRequestOptionsUpload = { act: true, } const uploadResultACT = await bee.uploadData( - postageBatchId, "Bee is awesome with ACT!", - beeRequestOptionsUpload) + postageBatchId, + "Bee is awesome with ACT!", + beeRequestOptionsUpload +) console.log(uploadResultACT) ``` -The return value provides a reference and a history reference. Both will be needed for the download. +The return value provides a `reference` and a `historyAddress`. Both will be needed for the download. -```json, title="uploadResultACT" +```json title="uploadResultACT" { - reference: '97132e8e17831dfa220e73ee083bd82819aaeffce0aaf7e1e0abf8135fcfd2fc', - tagUid: 14, - historyAddress: 'c6cabe3a3b7879ddb182277f3037c02002d4ce33280007cac580ac9256be20ea' + "reference": "97132e8e17831dfa220e73ee083bd82819aaeffce0aaf7e1e0abf8135fcfd2fc", + "tagUid": 14, + "historyAddress": "c6cabe3a3b7879ddb182277f3037c02002d4ce33280007cac580ac9256be20ea" } ``` :::info -During the upload, the publisher will be the uploading node. +During the upload process, the node performing the upload acts as the __publisher__. The __public key__ of this uploading node will be used as the publisher's public key. ::: -### Get Node Public Key +### Download with ACT -```js -import { Bee } from "@ethersphere/bee-js" +When downloading, we can specify that we are using __ACT__ in the optional `requestOptions` of the `bee-js` `downloadData` method. -const bee = new Bee('http://localhost:1633') -const addr = await bee.getNodeAddresses(); +:::warning +Downloading is only possible with the knowledge of the __publisher's__ public key. +::: + +```ts +const addr = await bee.getNodeAddresses() // node public key (publisher public key) const pubk = addr.publicKey -``` -### Download with ACT +const beeRequestOptionsDownload = { + baseURL: BEE_API_URL, + timeout: 0, // false converted to number + headers: { + 'swarm-act': 'true', + 'swarm-act-publisher': pubk, // publisher public key + 'swarm-act-history-address': uploadResultACT.historyAddress, + }, +} + +const retrievedData = await bee.downloadData(uploadResultACT.reference, beeRequestOptionsDownload) +console.log(await retrievedData.text()) // prints 'Bee is awesome with ACT!' +``` -When downloading, we can indicate that we are downloading with __ACT__ in the optional requestOptions of `bee-js` `downloadData` method. +### Create Grantees -:::warning -The download is only possible with the knowledge of the publisher's public key. -::: +To download from another node, we need to create a grantee list for the uploaded data that includes the public key of the downloading node. In the following example, we create a grantee list with three public keys. This list can be modified later using the `patchGrantees` method. ```ts -const beeRequestOptionsDownload = { - baseURL: BEE_API_URL, - timeout: 0, // false converted to number - headers: { - 'swarm-act': 'true', - 'swarm-act-publisher': pubk, // publisher public key - 'swarm-act-history-address': uploadResultACT.historyAddress, - }, - } - - const retrievedData = await bee.downloadData(uploadResultACT.reference, beeRequestOptionsDownload) - console.log(retrievedData) // prints 'Bee is awesome with ACT!' +const granteePublicKeys = [ + "02ceff1422a7026ba54ad89967d81f2805a55eb3d05f64eb5c49ea6024212b12e8", + "02ceff1422a7026ba54ad89967d81f2805a55eb3d05f64eb5c49ea6024212b12e9", + "02ceff1422a7026ba54ad89967d81f2805a55eb3d05f64eb5c49ea6024212b12ee" +] + +// Create Grantees +const granteeResult = await bee.createGrantees(postageBatchId, granteePublicKeys) +console.log(granteeResult) ``` -### Create Grantee +```json title="granteeResult" +{ + "status": 201, + "statusText": "Created", + "ref": "810b802516f3f0d1ded180d19fdf27bbc05b95a5b7ec8448b5a2d90819e06bed8fdf0697efad7074e66f52679a3aa51010d1897f4ce00918f8fd938b0ff35c3a", + "historyref": "4feb7fc56dcea1acaa74c1fb980156d6db9667b223809c082d69542545c67faf" +} +``` ### List Grantees +```ts +// List Grantees +const getGranteesResult = await bee.getGrantees(granteeResult.ref) +console.log(getGranteesResult) +``` + +```json title="getGranteesResult" +{ + "status": 200, + "statusText": "OK", + "data": [ + "02ceff1422a7026ba54ad89967d81f2805a55eb3d05f64eb5c49ea6024212b12e8", + "02ceff1422a7026ba54ad89967d81f2805a55eb3d05f64eb5c49ea6024212b12e9", + "02ceff1422a7026ba54ad89967d81f2805a55eb3d05f64eb5c49ea6024212b12ee" + ] +} +``` + ### Patch Grantees -### List Grantees after patch +The grantee list can be modified with `patchGrantees`. In our example, we add a new element and remove the last two elements from the `granteePublicKeys` list. + +```ts +// Patch Grantees +const patchGrantees = { + add: [ + "02ceff1422a7026ba54ad89967d81f2805a55eb3d05f64eb5c49ea6024212b12e7" + ], + revoke: [ + granteePublicKeys[1], + granteePublicKeys[2], + ] +} +// A short delay is needed if we call it immediately after createGrantees. +await new Promise(resolve => setTimeout(resolve, 1500)) +const granteeResultAfterPatch = await bee.patchGrantees( + postageBatchId, + granteeResult.ref, + granteeResult.historyref, + patchGrantees +) +console.log(granteeResultAfterPatch) +``` + +```json title="granteeResultAfterPatch" +{ + "status": 200, + "statusText": "OK", + "ref": "ae9fd8e0d9158ab9a433bacfde9109bd0545e31a0d8e4f592a5a558e842de59a86f73e08a594874fe38d6a68cfa636a729dcc73b746083b12a384b6578ac5dce", + "historyref": "0a0f709ed9d5ecd46434b8c62aeefc84bffeed7a80741c453d27ffdf67359fff" +} +``` + +After the patch, the grantee list will have a new reference. + +```ts +// List Grantees +const getGranteesResultAfterPatch = await bee.getGrantees(granteeResultAfterPatch.ref) +console.log(getGranteesResultAfterPatch) +``` + +```json title="getGranteesResultAfterPatch" +{ + "status": 200, + "statusText": "OK", + "data": [ + "02ceff1422a7026ba54ad89967d81f2805a55eb3d05f64eb5c49ea6024212b12e8", + "02ceff1422a7026ba54ad89967d81f2805a55eb3d05f64eb5c49ea6024212b12e7" + ] +} +``` From bcb3a30c399c5f8d10c3d694eaeb72e5f6706f54 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ferenc=20S=C3=A1rai?= Date: Mon, 27 Jan 2025 09:15:24 +0100 Subject: [PATCH 03/13] chore: update bee-js subproject commit --- bee-js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/bee-js b/bee-js index 2c8b9d13..9dd071d6 160000 --- a/bee-js +++ b/bee-js @@ -1 +1 @@ -Subproject commit 2c8b9d135b3d5295176fcd3830947de97b7cab55 +Subproject commit 9dd071d6dbedf9984efb5ce58612a8af6eddb60a From 2b874463e1919435f470bf1b6bc3eee856b27bb4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ferenc=20S=C3=A1rai?= Date: Mon, 27 Jan 2025 09:42:37 +0100 Subject: [PATCH 04/13] chore: update swarm-actions to version 1.0.0 in workflow --- .github/workflows/check.yaml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/check.yaml b/.github/workflows/check.yaml index 6d3a5d82..fc5c3db0 100644 --- a/.github/workflows/check.yaml +++ b/.github/workflows/check.yaml @@ -65,7 +65,7 @@ jobs: npx link-checker --url-ignore localhost --allow-hash-href --mkdocs --http-cache /tmp/link-checker --http-always-get --http-timeout 10000 --http-redirects 5 ./build - name: Create preview - uses: ethersphere/swarm-actions/pr-preview@v0 + uses: ethersphere/swarm-actions/pr-preview@v1.0.0 with: bee-url: https://unlimited.gateway.ethswarm.org token: ${{ secrets.REPO_GHA_PAT }} @@ -73,7 +73,7 @@ jobs: headers: "${{ secrets.GATEWAY_AUTHORIZATION_HEADER }}" - name: Upload to testnet - uses: ethersphere/swarm-actions/upload-dir@v0 + uses: ethersphere/swarm-actions/upload-dir@v1.0.0 continue-on-error: true with: index-document: index.html From b0d6e8d1ffcff27accaa2013d150be9b9dc47cf4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ferenc=20S=C3=A1rai?= Date: Mon, 27 Jan 2025 12:00:47 +0100 Subject: [PATCH 05/13] fix: revert "chore: update bee-js subproject commit" This reverts commit bcb3a30c399c5f8d10c3d694eaeb72e5f6706f54. --- bee-js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/bee-js b/bee-js index 9dd071d6..2c8b9d13 160000 --- a/bee-js +++ b/bee-js @@ -1 +1 @@ -Subproject commit 9dd071d6dbedf9984efb5ce58612a8af6eddb60a +Subproject commit 2c8b9d135b3d5295176fcd3830947de97b7cab55 From e9fa46da36be82dec1164693d5e13278c37dc496 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ferenc=20S=C3=A1rai?= Date: Mon, 27 Jan 2025 15:21:09 +0100 Subject: [PATCH 06/13] fix: run with latest bee-js (v8.3.1) but utils/http.ts is patched --- package.json | 1 + patch-http.ts | 52 +++++++++++++++++++++++++++++++++++++++++++++++++++ tsconfig.json | 7 +++++++ typedoc.json | 2 +- 4 files changed, 61 insertions(+), 1 deletion(-) create mode 100644 patch-http.ts create mode 100644 tsconfig.json diff --git a/package.json b/package.json index 2166ba4d..bc045c10 100644 --- a/package.json +++ b/package.json @@ -21,6 +21,7 @@ "scripts": { "docusaurus": "docusaurus", "start": "docusaurus start", + "prebuild": "cp patch-http.ts bee-js/src/utils/http.ts", "build": "docusaurus build", "swizzle": "docusaurus swizzle", "deploy": "docusaurus deploy", diff --git a/patch-http.ts b/patch-http.ts new file mode 100644 index 00000000..d649c84c --- /dev/null +++ b/patch-http.ts @@ -0,0 +1,52 @@ +import axios, { AxiosRequestConfig, AxiosResponse } from 'axios' +import { Objects, Strings } from 'cafe-utility' +import { BeeRequestOptions, BeeResponseError } from '../index' + +const { AxiosError } = axios + +export const DEFAULT_HTTP_CONFIG: AxiosRequestConfig = { + headers: { + accept: 'application/json, text/plain, */*', + }, + maxBodyLength: Infinity, + maxContentLength: Infinity, +} + +/** + * Main function to make HTTP requests. + * @param options User defined settings + * @param config Internal settings and/or Bee settings + */ +export async function http(options: BeeRequestOptions, config: AxiosRequestConfig): Promise> { + try { + const requestConfig: AxiosRequestConfig = Objects.deepMerge3(DEFAULT_HTTP_CONFIG, config, options) + maybeRunOnRequestHook(options, requestConfig) + const response = await axios(requestConfig) + + // TODO: https://github.com/axios/axios/pull/6253 + return response as unknown as AxiosResponse + } catch (e: unknown) { + if (axios.isAxiosError(e)) { + throw new BeeResponseError( + config.method || 'get', + config.url || '', + e.message, + e.response?.data, + e.response?.status, + e.code, + ) + } + throw e + } +} + +function maybeRunOnRequestHook(options: BeeRequestOptions, requestConfig: AxiosRequestConfig) { + if (options.onRequest) { + options.onRequest({ + method: requestConfig.method || 'GET', + url: Strings.joinUrl(requestConfig.baseURL as string, requestConfig.url as string), + headers: { ...requestConfig.headers } as Record, + params: requestConfig.params, + }) + } +} diff --git a/tsconfig.json b/tsconfig.json new file mode 100644 index 00000000..c146aa17 --- /dev/null +++ b/tsconfig.json @@ -0,0 +1,7 @@ +{ + "extends": "./bee-js/tsconfig.json", + "compilerOptions": { + "module": "none", // Override the module option + "moduleResolution": "node" // Ensure this is set to a valid value + } +} \ No newline at end of file diff --git a/typedoc.json b/typedoc.json index d96b9bcd..5add205e 100644 --- a/typedoc.json +++ b/typedoc.json @@ -6,5 +6,5 @@ "out": "api", "allReflectionsHaveOwnDocument": true, "entryPoints": ["./bee-js/src/index.ts"], - "tsconfig": "./bee-js/tsconfig.json" + "tsconfig": "./tsconfig.json" } From 64f2a24f1be1c4f24b5ea86598777107b5160e6e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ferenc=20S=C3=A1rai?= Date: Mon, 27 Jan 2025 15:40:29 +0100 Subject: [PATCH 07/13] chore: update bee-js subproject commit to latest version (v8.3.1) --- bee-js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/bee-js b/bee-js index 2c8b9d13..9dd071d6 160000 --- a/bee-js +++ b/bee-js @@ -1 +1 @@ -Subproject commit 2c8b9d135b3d5295176fcd3830947de97b7cab55 +Subproject commit 9dd071d6dbedf9984efb5ce58612a8af6eddb60a From 11691772bd6dccfe8da524160eff89d7d49a64de Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ferenc=20S=C3=A1rai?= Date: Mon, 3 Feb 2025 07:54:14 +0100 Subject: [PATCH 08/13] fix: revert http.ts patch --- package.json | 1 - patch-http.ts | 52 --------------------------------------------------- 2 files changed, 53 deletions(-) delete mode 100644 patch-http.ts diff --git a/package.json b/package.json index bc045c10..2166ba4d 100644 --- a/package.json +++ b/package.json @@ -21,7 +21,6 @@ "scripts": { "docusaurus": "docusaurus", "start": "docusaurus start", - "prebuild": "cp patch-http.ts bee-js/src/utils/http.ts", "build": "docusaurus build", "swizzle": "docusaurus swizzle", "deploy": "docusaurus deploy", diff --git a/patch-http.ts b/patch-http.ts deleted file mode 100644 index d649c84c..00000000 --- a/patch-http.ts +++ /dev/null @@ -1,52 +0,0 @@ -import axios, { AxiosRequestConfig, AxiosResponse } from 'axios' -import { Objects, Strings } from 'cafe-utility' -import { BeeRequestOptions, BeeResponseError } from '../index' - -const { AxiosError } = axios - -export const DEFAULT_HTTP_CONFIG: AxiosRequestConfig = { - headers: { - accept: 'application/json, text/plain, */*', - }, - maxBodyLength: Infinity, - maxContentLength: Infinity, -} - -/** - * Main function to make HTTP requests. - * @param options User defined settings - * @param config Internal settings and/or Bee settings - */ -export async function http(options: BeeRequestOptions, config: AxiosRequestConfig): Promise> { - try { - const requestConfig: AxiosRequestConfig = Objects.deepMerge3(DEFAULT_HTTP_CONFIG, config, options) - maybeRunOnRequestHook(options, requestConfig) - const response = await axios(requestConfig) - - // TODO: https://github.com/axios/axios/pull/6253 - return response as unknown as AxiosResponse - } catch (e: unknown) { - if (axios.isAxiosError(e)) { - throw new BeeResponseError( - config.method || 'get', - config.url || '', - e.message, - e.response?.data, - e.response?.status, - e.code, - ) - } - throw e - } -} - -function maybeRunOnRequestHook(options: BeeRequestOptions, requestConfig: AxiosRequestConfig) { - if (options.onRequest) { - options.onRequest({ - method: requestConfig.method || 'GET', - url: Strings.joinUrl(requestConfig.baseURL as string, requestConfig.url as string), - headers: { ...requestConfig.headers } as Record, - params: requestConfig.params, - }) - } -} From 94acea6699406e1aa44f9b5cc726eb0322075825 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ferenc=20S=C3=A1rai?= Date: Mon, 3 Feb 2025 13:05:44 +0100 Subject: [PATCH 09/13] fix: remove upload progress --- sidebars.js | 5 ----- 1 file changed, 5 deletions(-) diff --git a/sidebars.js b/sidebars.js index ba17db0a..84c96dc8 100644 --- a/sidebars.js +++ b/sidebars.js @@ -27,11 +27,6 @@ module.exports = { type: 'link', label: 'React Upload application', href: 'https://github.com/ethersphere/examples-js/tree/master/upload-react' - }, - { - type: 'link', - label: 'Upload progress', - href: 'https://github.com/ethersphere/examples-js/tree/master/upload-progress' } ], collapsed: false From 9eb4f7fbfaa6a8c6c5e16e03bb4b63d0b5533003 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ferenc=20S=C3=A1rai?= Date: Mon, 3 Feb 2025 13:17:07 +0100 Subject: [PATCH 10/13] fix: replace broken postage stamps link --- docs/user-documentation/act.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/user-documentation/act.md b/docs/user-documentation/act.md index 306dc755..c75614ec 100644 --- a/docs/user-documentation/act.md +++ b/docs/user-documentation/act.md @@ -14,7 +14,7 @@ import TabItem from '@theme/TabItem' The [Access Control Trie (ACT)](https://solarpunk.buzz/introducing-the-access-control-trie-act-in-swarm/) is an essential feature designed to manage access control in Swarm’s decentralized storage infrastructure. It enables __publishers__ to grant or revoke access to specific content at the chunk level using encrypted session keys. This guide will walk you through the key concepts and practical aspects of using __ACT__ to protect your data in Swarm. :::warning Postage stamps -Uploading to the Swarm network requires Postage stamps for every write operation. To understand this better, see [Bee docs - Keep your data alive](https://docs.ethswarm.org/docs/access-the-swarm/keep-your-data-alive). In the following examples, we assume that we already have a `postageBatchId`. +Uploading to the Swarm network requires Postage stamps for every write operation. To understand this better, see [Bee docs - Postage Stamps](https://docs.ethswarm.org/docs/concepts/incentives/postage-stamps). In the following examples, we assume that we already have a `postageBatchId`. ::: We also need an instance of Bee to interact with the Bee node. From 68309399aaefcf270bf1b91788bdff28d51828b7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ferenc=20S=C3=A1rai?= Date: Mon, 3 Feb 2025 13:32:20 +0100 Subject: [PATCH 11/13] fix: keep your data alive link --- docs/user-documentation/act.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/user-documentation/act.md b/docs/user-documentation/act.md index c75614ec..5db4a03d 100644 --- a/docs/user-documentation/act.md +++ b/docs/user-documentation/act.md @@ -14,7 +14,7 @@ import TabItem from '@theme/TabItem' The [Access Control Trie (ACT)](https://solarpunk.buzz/introducing-the-access-control-trie-act-in-swarm/) is an essential feature designed to manage access control in Swarm’s decentralized storage infrastructure. It enables __publishers__ to grant or revoke access to specific content at the chunk level using encrypted session keys. This guide will walk you through the key concepts and practical aspects of using __ACT__ to protect your data in Swarm. :::warning Postage stamps -Uploading to the Swarm network requires Postage stamps for every write operation. To understand this better, see [Bee docs - Postage Stamps](https://docs.ethswarm.org/docs/concepts/incentives/postage-stamps). In the following examples, we assume that we already have a `postageBatchId`. +Uploading to the Swarm network requires Postage stamps for every write operation. To understand this better, see [Bee docs - Keep your data alive](https://docs.ethswarm.org/docs/develop/access-the-swarm/introduction/#keep-your-data-alive). In the following examples, we assume that we already have a `postageBatchId`. ::: We also need an instance of Bee to interact with the Bee node. From e8c0bca7c5e02c6af91d265f6cf9071a9a3b1e71 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ferenc=20S=C3=A1rai?= Date: Tue, 11 Feb 2025 16:05:43 +0100 Subject: [PATCH 12/13] feat: upcoming bee-js --- docs/user-documentation/act.md | 120 ++++++++++++++++++--------------- 1 file changed, 64 insertions(+), 56 deletions(-) diff --git a/docs/user-documentation/act.md b/docs/user-documentation/act.md index 5db4a03d..833e3af5 100644 --- a/docs/user-documentation/act.md +++ b/docs/user-documentation/act.md @@ -21,33 +21,38 @@ We also need an instance of Bee to interact with the Bee node. ```ts import { Bee } from "@ethersphere/bee-js" +``` -const bee = new Bee('http://localhost:1633') +```ts +const bee = new Bee('http://localhost:1633') // Use BeeDev if running Bee in dev mode locally ``` ### Upload with ACT -When uploading, we can specify that we are using ACT in the optional `requestOptions` of the `bee-js` `uploadData` method. +When uploading, we can specify that we are using ACT in the optional `options: RedundantUploadOptions` of the `bee-js` `uploadData` method. ```ts -const beeRequestOptionsUpload = { - act: true, -} -const uploadResultACT = await bee.uploadData( - postageBatchId, - "Bee is awesome with ACT!", - beeRequestOptionsUpload -) -console.log(uploadResultACT) +const optionsUp = { + act: true, +}; +const uploadResultACT: UploadResult = await bee.uploadData( + postageBatchId, + "Bee is awesome with ACT!", + optionsUp); +console.log('uploadResultACT:', { + ...uploadResultACT, + reference: uploadResultACT.reference.toString(), + historyAddress: uploadResultACT.historyAddress.getOrThrow().toString() +}); ``` The return value provides a `reference` and a `historyAddress`. Both will be needed for the download. ```json title="uploadResultACT" { - "reference": "97132e8e17831dfa220e73ee083bd82819aaeffce0aaf7e1e0abf8135fcfd2fc", - "tagUid": 14, - "historyAddress": "c6cabe3a3b7879ddb182277f3037c02002d4ce33280007cac580ac9256be20ea" + "reference": "85ae50e61155d4a0c9c4563c96074e16c33e5640bacfde1ce488978d602927fa", + "tagUid": 111, + "historyAddress": "97a1f10b344e79cde136353a61877b417af2c8ecea4a20a362b920aedb240dc7" } ``` @@ -57,30 +62,25 @@ During the upload process, the node performing the upload acts as the __publishe ### Download with ACT -When downloading, we can specify that we are using __ACT__ in the optional `requestOptions` of the `bee-js` `downloadData` method. +When downloading, we can specify that we are using __ACT__ in the optional `options: DownloadOptions` of the `bee-js` `downloadData` method. :::warning Downloading is only possible with the knowledge of the __publisher's__ public key. ::: ```ts -const addr = await bee.getNodeAddresses() +const addr = await bee.getNodeAddresses(); // node public key (publisher public key) -const pubk = addr.publicKey - -const beeRequestOptionsDownload = { - baseURL: BEE_API_URL, - timeout: 0, // false converted to number - headers: { - 'swarm-act': 'true', - 'swarm-act-publisher': pubk, // publisher public key - 'swarm-act-history-address': uploadResultACT.historyAddress, - }, -} - -const retrievedData = await bee.downloadData(uploadResultACT.reference, beeRequestOptionsDownload) -console.log(await retrievedData.text()) // prints 'Bee is awesome with ACT!' +const pubk = addr.publicKey; +const optionsDown: DownloadOptions = { + actPublisher: pubk, + actHistoryAddress: uploadResultACT.historyAddress.getOrThrow(), + actTimestamp: 1 +}; + +const retrievedData: Bytes = await bee.downloadData(uploadResultACT.reference, optionsDown); +console.log('retrievedData:', retrievedData.toUtf8()); // prints 'Bee is awesome with ACT!' ``` ### Create Grantees @@ -89,22 +89,26 @@ To download from another node, we need to create a grantee list for the uploaded ```ts const granteePublicKeys = [ - "02ceff1422a7026ba54ad89967d81f2805a55eb3d05f64eb5c49ea6024212b12e8", - "02ceff1422a7026ba54ad89967d81f2805a55eb3d05f64eb5c49ea6024212b12e9", - "02ceff1422a7026ba54ad89967d81f2805a55eb3d05f64eb5c49ea6024212b12ee" -] + "02ceff1422a7026ba54ad89967d81f2805a55eb3d05f64eb5c49ea6024212b12e8", + "02ceff1422a7026ba54ad89967d81f2805a55eb3d05f64eb5c49ea6024212b12e9", + "02ceff1422a7026ba54ad89967d81f2805a55eb3d05f64eb5c49ea6024212b12ee" +]; // Create Grantees -const granteeResult = await bee.createGrantees(postageBatchId, granteePublicKeys) -console.log(granteeResult) +const granteesResult: GranteesResult = await bee.createGrantees(postageBatchId, granteePublicKeys); +console.log('granteesResult:', { + ...granteesResult, + ref: granteesResult.ref.toString(), + historyref: granteesResult.historyref.toString(), +}) ``` ```json title="granteeResult" { "status": 201, "statusText": "Created", - "ref": "810b802516f3f0d1ded180d19fdf27bbc05b95a5b7ec8448b5a2d90819e06bed8fdf0697efad7074e66f52679a3aa51010d1897f4ce00918f8fd938b0ff35c3a", - "historyref": "4feb7fc56dcea1acaa74c1fb980156d6db9667b223809c082d69542545c67faf" + "ref": "30f7ba4fec333227dac0053114f68e70ee64290e095d99470a074fa687f0ad0774370a1e597447fbec7f916c4a2f70d0719150dce3573b290b3fcfe7883ed79d", + "historyref": "81cd33bf01b771ed899cb41f4d5e91b49dc28a42ee28144f8ba1ba59ecc66f09" } ``` @@ -112,15 +116,18 @@ console.log(granteeResult) ```ts // List Grantees -const getGranteesResult = await bee.getGrantees(granteeResult.ref) -console.log(getGranteesResult) +const getGranteesResult: GetGranteesResult = await bee.getGrantees(granteesResult.ref); +console.log('getGranteesResult:', { + ...getGranteesResult, + grantees: getGranteesResult.grantees.map(grantee => grantee.toCompressedHex()) +}); ``` ```json title="getGranteesResult" { "status": 200, "statusText": "OK", - "data": [ + "grantees": [ "02ceff1422a7026ba54ad89967d81f2805a55eb3d05f64eb5c49ea6024212b12e8", "02ceff1422a7026ba54ad89967d81f2805a55eb3d05f64eb5c49ea6024212b12e9", "02ceff1422a7026ba54ad89967d81f2805a55eb3d05f64eb5c49ea6024212b12ee" @@ -144,40 +151,41 @@ const patchGrantees = { ] } // A short delay is needed if we call it immediately after createGrantees. -await new Promise(resolve => setTimeout(resolve, 1500)) -const granteeResultAfterPatch = await bee.patchGrantees( - postageBatchId, - granteeResult.ref, - granteeResult.historyref, - patchGrantees -) -console.log(granteeResultAfterPatch) +await new Promise(resolve => setTimeout(resolve, 1500)); +const granteeResultAfterPatch: GranteesResult = await bee.patchGrantees(postageBatchId, granteesResult.ref, granteesResult.historyref, patch_grantees); +console.log('granteeResultAfterPatch:', { + ...granteeResultAfterPatch, + ref: granteeResultAfterPatch.ref.toString(), + historyref: granteeResultAfterPatch.historyref.toString(), +}) ``` ```json title="granteeResultAfterPatch" { "status": 200, "statusText": "OK", - "ref": "ae9fd8e0d9158ab9a433bacfde9109bd0545e31a0d8e4f592a5a558e842de59a86f73e08a594874fe38d6a68cfa636a729dcc73b746083b12a384b6578ac5dce", - "historyref": "0a0f709ed9d5ecd46434b8c62aeefc84bffeed7a80741c453d27ffdf67359fff" + "ref": "694152dd351a701a0090b82bbdbd892f110a589596f6a504833855af91aacbf127e292a8a49119c53ec46c112501eab6933340c59d05576ec45354e990479e5f", + "historyref": "73a62da4ad3a29f1899b548d3dbe1a96baab11ab73b02e36ce9fec728a5b87d3" } ``` After the patch, the grantee list will have a new reference. ```ts -// List Grantees -const getGranteesResultAfterPatch = await bee.getGrantees(granteeResultAfterPatch.ref) -console.log(getGranteesResultAfterPatch) +const getGranteesResultAfterPatch: GetGranteesResult = await bee.getGrantees(granteeResultAfterPatch.ref); +console.log('getGranteesResultAfterPatch:', { + ...getGranteesResultAfterPatch, + grantees: getGranteesResultAfterPatch.grantees.map(grantee => grantee.toCompressedHex()) +}); ``` ```json title="getGranteesResultAfterPatch" { "status": 200, "statusText": "OK", - "data": [ + "grantees": [ "02ceff1422a7026ba54ad89967d81f2805a55eb3d05f64eb5c49ea6024212b12e8", - "02ceff1422a7026ba54ad89967d81f2805a55eb3d05f64eb5c49ea6024212b12e7" + "02ceff1422a7026ba54ad89967d81f2805a55eb3d05f64eb5c49ea6024212b12e7"' ] } ``` From b59c5ed626a69578665dd990144fc2e4b24533c1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ferenc=20S=C3=A1rai?= Date: Mon, 17 Feb 2025 08:38:14 +0100 Subject: [PATCH 13/13] fix: update typescript for @upcoming/bee-js --- package-lock.json | 15 ++++++++------- package.json | 2 +- 2 files changed, 9 insertions(+), 8 deletions(-) diff --git a/package-lock.json b/package-lock.json index b468f951..5322d626 100644 --- a/package-lock.json +++ b/package-lock.json @@ -22,7 +22,7 @@ }, "devDependencies": { "@commitlint/config-conventional": "^17.0.0", - "typescript": "~4.6.4" + "typescript": "^4.9.5" }, "engines": { "node": ">=14.0.0", @@ -11763,9 +11763,10 @@ } }, "node_modules/typescript": { - "version": "4.6.4", - "resolved": "https://registry.npmjs.org/typescript/-/typescript-4.6.4.tgz", - "integrity": "sha512-9ia/jWHIEbo49HfjrLGfKbZSuWo9iTMwXO+Ca3pRsSpbsMbc7/IU8NKdCZVRRBafVPGnoJeFL76ZOAA84I9fEg==", + "version": "4.9.5", + "resolved": "https://registry.npmjs.org/typescript/-/typescript-4.9.5.tgz", + "integrity": "sha512-1FXk9E2Hm+QzZQ7z+McJiHL4NW1F2EzMu9Nq9i3zAaGqibafqYwCVU6WyWAuyQRRzOlxou8xZSyXLEN8oKj24g==", + "license": "Apache-2.0", "bin": { "tsc": "bin/tsc", "tsserver": "bin/tsserver" @@ -21507,9 +21508,9 @@ } }, "typescript": { - "version": "4.6.4", - "resolved": "https://registry.npmjs.org/typescript/-/typescript-4.6.4.tgz", - "integrity": "sha512-9ia/jWHIEbo49HfjrLGfKbZSuWo9iTMwXO+Ca3pRsSpbsMbc7/IU8NKdCZVRRBafVPGnoJeFL76ZOAA84I9fEg==" + "version": "4.9.5", + "resolved": "https://registry.npmjs.org/typescript/-/typescript-4.9.5.tgz", + "integrity": "sha512-1FXk9E2Hm+QzZQ7z+McJiHL4NW1F2EzMu9Nq9i3zAaGqibafqYwCVU6WyWAuyQRRzOlxou8xZSyXLEN8oKj24g==" }, "ua-parser-js": { "version": "0.7.31", diff --git a/package.json b/package.json index 2166ba4d..b3e7d92d 100644 --- a/package.json +++ b/package.json @@ -40,7 +40,7 @@ "typedoc-plugin-markdown": "~3.12.1" }, "devDependencies": { - "typescript": "~4.6.4", + "typescript": "^4.9.5", "@commitlint/config-conventional": "^17.0.0" }, "browserslist": {