@ethersphere/bee-js 8.3.1 → 9.0.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (224) hide show
  1. package/README.md +192 -50
  2. package/dist/cjs/bee-dev.js +78 -0
  3. package/dist/cjs/bee.js +341 -417
  4. package/dist/cjs/chunk/bmt.js +15 -32
  5. package/dist/cjs/chunk/cac.js +26 -36
  6. package/dist/cjs/chunk/soc.js +56 -51
  7. package/dist/cjs/feed/identifier.js +3 -28
  8. package/dist/cjs/feed/index.js +95 -44
  9. package/dist/cjs/feed/retrievable.js +11 -22
  10. package/dist/cjs/index.js +17 -1
  11. package/dist/cjs/manifest/manifest.js +369 -0
  12. package/dist/cjs/modules/bytes.js +24 -12
  13. package/dist/cjs/modules/bzz.js +24 -34
  14. package/dist/cjs/modules/chunk.js +13 -7
  15. package/dist/cjs/modules/debug/balance.js +29 -4
  16. package/dist/cjs/modules/debug/chequebook.js +60 -16
  17. package/dist/cjs/modules/debug/connectivity.js +82 -4
  18. package/dist/cjs/modules/debug/settlements.js +22 -2
  19. package/dist/cjs/modules/debug/stake.js +29 -11
  20. package/dist/cjs/modules/debug/stamps.js +88 -7
  21. package/dist/cjs/modules/debug/states.js +25 -3
  22. package/dist/cjs/modules/debug/status.js +45 -47
  23. package/dist/cjs/modules/debug/transactions.js +27 -5
  24. package/dist/cjs/modules/envelope.js +8 -6
  25. package/dist/cjs/modules/feed.js +25 -10
  26. package/dist/cjs/modules/grantee.js +18 -12
  27. package/dist/cjs/modules/gsoc.js +24 -0
  28. package/dist/cjs/modules/pinning.js +13 -2
  29. package/dist/cjs/modules/pss.js +9 -3
  30. package/dist/cjs/modules/soc.js +9 -4
  31. package/dist/cjs/modules/stewardship.js +7 -3
  32. package/dist/cjs/modules/tag.js +35 -3
  33. package/dist/cjs/package.json +1 -0
  34. package/dist/cjs/stamper/stamper.js +43 -0
  35. package/dist/cjs/types/debug.js +16 -1
  36. package/dist/cjs/types/index.js +2 -24
  37. package/dist/cjs/utils/bytes.js +67 -115
  38. package/dist/cjs/utils/chunk-size.js +17 -0
  39. package/dist/cjs/utils/chunk-stream.browser.js +85 -0
  40. package/dist/cjs/utils/chunk-stream.js +84 -0
  41. package/dist/cjs/utils/cid.js +5 -6
  42. package/dist/cjs/utils/collection.browser.js +2 -2
  43. package/dist/cjs/utils/collection.js +3 -2
  44. package/dist/cjs/utils/collection.node.js +0 -2
  45. package/dist/cjs/utils/constants.js +7 -3
  46. package/dist/cjs/utils/data.browser.js +6 -3
  47. package/dist/cjs/utils/data.js +8 -4
  48. package/dist/cjs/utils/duration.js +51 -0
  49. package/dist/cjs/utils/expose.js +11 -40
  50. package/dist/cjs/utils/headers.js +79 -52
  51. package/dist/cjs/utils/http.js +34 -10
  52. package/dist/cjs/utils/mime.js +78 -0
  53. package/dist/cjs/utils/pss.js +3 -4
  54. package/dist/cjs/utils/redundancy.js +18 -14
  55. package/dist/cjs/utils/resource-locator.js +17 -0
  56. package/dist/cjs/utils/size.js +35 -0
  57. package/dist/cjs/utils/stamps.js +67 -51
  58. package/dist/cjs/utils/tar-uploader.browser.js +2 -2
  59. package/dist/cjs/utils/tar-uploader.js +2 -2
  60. package/dist/cjs/utils/tokens.js +144 -0
  61. package/dist/cjs/utils/type.js +142 -350
  62. package/dist/cjs/utils/typed-bytes.js +179 -0
  63. package/dist/cjs/utils/upload-progress.js +2 -0
  64. package/dist/cjs/utils/url.js +0 -4
  65. package/dist/cjs/utils/workaround.js +27 -0
  66. package/dist/index.browser.min.js +1 -2
  67. package/dist/index.browser.min.js.map +1 -1
  68. package/dist/mjs/bee-dev.js +98 -0
  69. package/dist/mjs/bee.js +367 -411
  70. package/dist/mjs/chunk/bmt.js +13 -29
  71. package/dist/mjs/chunk/cac.js +26 -34
  72. package/dist/mjs/chunk/soc.js +57 -53
  73. package/dist/mjs/feed/identifier.js +3 -26
  74. package/dist/mjs/feed/index.js +98 -51
  75. package/dist/mjs/feed/retrievable.js +12 -23
  76. package/dist/mjs/index.js +10 -1
  77. package/dist/mjs/manifest/manifest.js +371 -0
  78. package/dist/mjs/modules/bytes.js +27 -15
  79. package/dist/mjs/modules/bzz.js +25 -32
  80. package/dist/mjs/modules/chunk.js +16 -8
  81. package/dist/mjs/modules/debug/balance.js +61 -4
  82. package/dist/mjs/modules/debug/chequebook.js +116 -16
  83. package/dist/mjs/modules/debug/connectivity.js +144 -3
  84. package/dist/mjs/modules/debug/settlements.js +46 -2
  85. package/dist/mjs/modules/debug/stake.js +69 -11
  86. package/dist/mjs/modules/debug/stamps.js +184 -7
  87. package/dist/mjs/modules/debug/states.js +55 -3
  88. package/dist/mjs/modules/debug/status.js +97 -45
  89. package/dist/mjs/modules/debug/transactions.js +61 -5
  90. package/dist/mjs/modules/envelope.js +11 -9
  91. package/dist/mjs/modules/feed.js +26 -10
  92. package/dist/mjs/modules/grantee.js +35 -13
  93. package/dist/mjs/modules/gsoc.js +16 -0
  94. package/dist/mjs/modules/pinning.js +23 -2
  95. package/dist/mjs/modules/pss.js +10 -4
  96. package/dist/mjs/modules/soc.js +10 -5
  97. package/dist/mjs/modules/stewardship.js +14 -4
  98. package/dist/mjs/modules/tag.js +93 -3
  99. package/dist/mjs/package.json +2 -1
  100. package/dist/mjs/stamper/stamper.js +39 -0
  101. package/dist/mjs/types/debug.js +15 -1
  102. package/dist/mjs/types/index.js +2 -24
  103. package/dist/mjs/utils/bytes.js +63 -104
  104. package/dist/mjs/utils/chunk-size.js +13 -0
  105. package/dist/mjs/utils/chunk-stream.browser.js +85 -0
  106. package/dist/mjs/utils/chunk-stream.js +87 -0
  107. package/dist/mjs/utils/cid.js +5 -6
  108. package/dist/mjs/utils/collection.browser.js +2 -2
  109. package/dist/mjs/utils/collection.js +2 -2
  110. package/dist/mjs/utils/collection.node.js +0 -2
  111. package/dist/mjs/utils/constants.js +6 -2
  112. package/dist/mjs/utils/data.browser.js +9 -3
  113. package/dist/mjs/utils/data.js +12 -4
  114. package/dist/mjs/utils/duration.js +47 -0
  115. package/dist/mjs/utils/expose.js +2 -7
  116. package/dist/mjs/utils/headers.js +73 -48
  117. package/dist/mjs/utils/http.js +33 -11
  118. package/dist/mjs/utils/mime.js +75 -0
  119. package/dist/mjs/utils/pss.js +3 -4
  120. package/dist/mjs/utils/redundancy.js +18 -8
  121. package/dist/mjs/utils/resource-locator.js +13 -0
  122. package/dist/mjs/utils/size.js +31 -0
  123. package/dist/mjs/utils/stamps.js +47 -44
  124. package/dist/mjs/utils/tar-uploader.browser.js +2 -2
  125. package/dist/mjs/utils/tar-uploader.js +2 -2
  126. package/dist/mjs/utils/tokens.js +139 -0
  127. package/dist/mjs/utils/type.js +216 -310
  128. package/dist/mjs/utils/typed-bytes.js +160 -0
  129. package/dist/mjs/utils/upload-progress.js +1 -0
  130. package/dist/mjs/utils/url.js +0 -4
  131. package/dist/mjs/utils/workaround.js +22 -0
  132. package/dist/types/bee-dev.d.ts +5 -0
  133. package/dist/types/bee.d.ts +88 -165
  134. package/dist/types/chunk/bmt.d.ts +2 -2
  135. package/dist/types/chunk/cac.d.ts +7 -24
  136. package/dist/types/chunk/soc.d.ts +15 -15
  137. package/dist/types/feed/identifier.d.ts +2 -4
  138. package/dist/types/feed/index.d.ts +14 -18
  139. package/dist/types/feed/retrievable.d.ts +3 -4
  140. package/dist/types/index.d.ts +28 -1
  141. package/dist/types/manifest/manifest.d.ts +106 -0
  142. package/dist/types/modules/bytes.d.ts +8 -5
  143. package/dist/types/modules/bzz.d.ts +8 -10
  144. package/dist/types/modules/chunk.d.ts +4 -3
  145. package/dist/types/modules/debug/balance.d.ts +3 -2
  146. package/dist/types/modules/debug/chequebook.d.ts +7 -6
  147. package/dist/types/modules/debug/connectivity.d.ts +5 -3
  148. package/dist/types/modules/debug/settlements.d.ts +2 -1
  149. package/dist/types/modules/debug/stake.d.ts +4 -2
  150. package/dist/types/modules/debug/stamps.d.ts +5 -4
  151. package/dist/types/modules/debug/status.d.ts +6 -25
  152. package/dist/types/modules/debug/transactions.d.ts +5 -4
  153. package/dist/types/modules/envelope.d.ts +3 -2
  154. package/dist/types/modules/feed.d.ts +20 -16
  155. package/dist/types/modules/grantee.d.ts +7 -6
  156. package/dist/types/modules/gsoc.d.ts +7 -0
  157. package/dist/types/modules/pinning.d.ts +2 -4
  158. package/dist/types/modules/pss.d.ts +4 -3
  159. package/dist/types/modules/soc.d.ts +3 -2
  160. package/dist/types/modules/stewardship.d.ts +4 -4
  161. package/dist/types/modules/tag.d.ts +2 -1
  162. package/dist/types/stamper/stamper.d.ts +15 -0
  163. package/dist/types/types/debug.d.ts +63 -115
  164. package/dist/types/types/index.d.ts +103 -204
  165. package/dist/types/utils/bytes.d.ts +16 -90
  166. package/dist/types/utils/chunk-size.d.ts +1 -0
  167. package/dist/types/utils/chunk-stream.browser.d.ts +6 -0
  168. package/dist/types/utils/chunk-stream.d.ts +6 -0
  169. package/dist/types/utils/cid.d.ts +3 -2
  170. package/dist/types/utils/collection.browser.d.ts +2 -2
  171. package/dist/types/utils/collection.d.ts +2 -1
  172. package/dist/types/utils/collection.node.d.ts +0 -1
  173. package/dist/types/utils/constants.d.ts +4 -1
  174. package/dist/types/utils/duration.d.ts +17 -0
  175. package/dist/types/utils/error.d.ts +2 -2
  176. package/dist/types/utils/expose.d.ts +2 -7
  177. package/dist/types/utils/headers.d.ts +3 -4
  178. package/dist/types/utils/mime.d.ts +1 -0
  179. package/dist/types/utils/pss.d.ts +2 -2
  180. package/dist/types/utils/resource-locator.d.ts +6 -0
  181. package/dist/types/utils/size.d.ts +16 -0
  182. package/dist/types/utils/stamps.d.ts +27 -33
  183. package/dist/types/utils/tar-uploader.browser.d.ts +3 -4
  184. package/dist/types/utils/tar-uploader.d.ts +3 -4
  185. package/dist/types/utils/tokens.d.ts +77 -0
  186. package/dist/types/utils/type.d.ts +20 -52
  187. package/dist/types/utils/typed-bytes.d.ts +68 -0
  188. package/dist/types/utils/upload-progress.d.ts +4 -0
  189. package/dist/types/utils/workaround.d.ts +2 -0
  190. package/package.json +11 -17
  191. package/dist/cjs/chunk/signer.js +0 -126
  192. package/dist/cjs/chunk/span.js +0 -25
  193. package/dist/cjs/feed/json.js +0 -28
  194. package/dist/cjs/feed/topic.js +0 -25
  195. package/dist/cjs/feed/type.js +0 -15
  196. package/dist/cjs/modules/debug/chunk.js +0 -21
  197. package/dist/cjs/modules/debug/tag.js +0 -19
  198. package/dist/cjs/utils/eth.js +0 -216
  199. package/dist/cjs/utils/hash.js +0 -21
  200. package/dist/cjs/utils/hex.js +0 -150
  201. package/dist/cjs/utils/reference.js +0 -36
  202. package/dist/index.browser.min.js.LICENSE.txt +0 -8
  203. package/dist/mjs/chunk/signer.js +0 -114
  204. package/dist/mjs/chunk/span.js +0 -21
  205. package/dist/mjs/feed/json.js +0 -26
  206. package/dist/mjs/feed/topic.js +0 -19
  207. package/dist/mjs/feed/type.js +0 -10
  208. package/dist/mjs/modules/debug/chunk.js +0 -17
  209. package/dist/mjs/modules/debug/tag.js +0 -15
  210. package/dist/mjs/utils/eth.js +0 -192
  211. package/dist/mjs/utils/hash.js +0 -16
  212. package/dist/mjs/utils/hex.js +0 -135
  213. package/dist/mjs/utils/reference.js +0 -29
  214. package/dist/types/chunk/signer.d.ts +0 -31
  215. package/dist/types/chunk/span.d.ts +0 -10
  216. package/dist/types/feed/json.d.ts +0 -4
  217. package/dist/types/feed/topic.d.ts +0 -3
  218. package/dist/types/feed/type.d.ts +0 -6
  219. package/dist/types/modules/debug/chunk.d.ts +0 -10
  220. package/dist/types/modules/debug/tag.d.ts +0 -8
  221. package/dist/types/utils/eth.d.ts +0 -67
  222. package/dist/types/utils/hash.d.ts +0 -9
  223. package/dist/types/utils/hex.d.ts +0 -86
  224. package/dist/types/utils/reference.d.ts +0 -2
@@ -1,14 +1,8 @@
1
- // For ESM compatibility
2
- import pkg from 'js-sha3';
3
- const {
4
- keccak256
5
- } = pkg;
1
+ import { Binary } from 'cafe-utility';
6
2
  import { BeeArgumentError } from "../utils/error.js";
7
- import { keccak256Hash } from "../utils/hash.js";
3
+ import { Reference, Span } from "../utils/typed-bytes.js";
8
4
  const MAX_CHUNK_PAYLOAD_SIZE = 4096;
9
5
  const SEGMENT_SIZE = 32;
10
- const SEGMENT_PAIR_SIZE = 2 * SEGMENT_SIZE;
11
- const HASH_SIZE = 32;
12
6
  /**
13
7
  * Calculate a Binary Merkle Tree hash for a chunk
14
8
  *
@@ -23,28 +17,18 @@ const HASH_SIZE = 32;
23
17
  *
24
18
  * @returns the keccak256 hash in a byte array
25
19
  */
26
- export function bmtHash(chunkContent) {
27
- const span = chunkContent.slice(0, 8);
28
- const payload = chunkContent.slice(8);
29
- const rootHash = bmtRootHash(payload);
30
- const chunkHashInput = new Uint8Array([...span, ...rootHash]);
31
- const chunkHash = keccak256Hash(chunkHashInput);
32
- return chunkHash;
20
+ export function calculateChunkAddress(chunkContent) {
21
+ const span = chunkContent.slice(0, Span.LENGTH);
22
+ const payload = chunkContent.slice(Span.LENGTH);
23
+ const rootHash = calculateBmtRootHash(payload);
24
+ const chunkHash = Binary.keccak256(Binary.concatBytes(span, rootHash));
25
+ return new Reference(chunkHash);
33
26
  }
34
- function bmtRootHash(payload) {
27
+ function calculateBmtRootHash(payload) {
35
28
  if (payload.length > MAX_CHUNK_PAYLOAD_SIZE) {
36
- throw new BeeArgumentError('invalid data length', payload);
29
+ throw new BeeArgumentError(`payload size ${payload.length} exceeds maximum chunk payload size ${MAX_CHUNK_PAYLOAD_SIZE}`, payload);
37
30
  }
38
- // create an input buffer padded with zeros
39
- let input = new Uint8Array([...payload, ...new Uint8Array(MAX_CHUNK_PAYLOAD_SIZE - payload.length)]);
40
- while (input.length !== HASH_SIZE) {
41
- const output = new Uint8Array(input.length / 2);
42
- // in each round we hash the segment pairs together
43
- for (let offset = 0; offset < input.length; offset += SEGMENT_PAIR_SIZE) {
44
- const hashNumbers = keccak256.array(input.slice(offset, offset + SEGMENT_PAIR_SIZE));
45
- output.set(hashNumbers, offset / 2);
46
- }
47
- input = output;
48
- }
49
- return input;
31
+ const input = new Uint8Array(MAX_CHUNK_PAYLOAD_SIZE);
32
+ input.set(payload);
33
+ return Binary.log2Reduce(Binary.partition(input, SEGMENT_SIZE), (a, b) => Binary.keccak256(Binary.concatBytes(a, b)));
50
34
  }
@@ -1,49 +1,41 @@
1
1
  import { Binary } from 'cafe-utility';
2
- import { assertFlexBytes, bytesEqual, flexBytesAtOffset } from "../utils/bytes.js";
3
- import { BeeError } from "../utils/error.js";
4
- import { bmtHash } from "./bmt.js";
5
- import { SPAN_SIZE, makeSpan } from "./span.js";
2
+ import { Bytes } from "../utils/bytes.js";
3
+ import { Span } from "../utils/typed-bytes.js";
4
+ import { calculateChunkAddress } from "./bmt.js";
6
5
  export const MIN_PAYLOAD_SIZE = 1;
7
6
  export const MAX_PAYLOAD_SIZE = 4096;
8
- const CAC_SPAN_OFFSET = 0;
9
- const CAC_PAYLOAD_OFFSET = CAC_SPAN_OFFSET + SPAN_SIZE;
7
+ const ENCODER = new TextEncoder();
10
8
  /**
11
9
  * Creates a content addressed chunk and verifies the payload size.
12
10
  *
13
11
  * @param payloadBytes the data to be stored in the chunk
14
12
  */
15
13
  export function makeContentAddressedChunk(payloadBytes) {
16
- const span = makeSpan(payloadBytes.length);
17
- assertFlexBytes(payloadBytes, MIN_PAYLOAD_SIZE, MAX_PAYLOAD_SIZE);
18
- const data = Binary.concatBytes(span, payloadBytes);
14
+ if (!(payloadBytes instanceof Uint8Array)) {
15
+ payloadBytes = ENCODER.encode(payloadBytes);
16
+ }
17
+ if (payloadBytes.length < MIN_PAYLOAD_SIZE || payloadBytes.length > MAX_PAYLOAD_SIZE) {
18
+ throw new RangeError(`payload size ${payloadBytes.length} exceeds limits [${MIN_PAYLOAD_SIZE}, ${MAX_PAYLOAD_SIZE}]`);
19
+ }
20
+ const span = Span.fromBigInt(BigInt(payloadBytes.length));
21
+ const data = Binary.concatBytes(span.toUint8Array(), payloadBytes);
19
22
  return {
20
23
  data,
21
- span: () => span,
22
- payload: () => flexBytesAtOffset(data, CAC_PAYLOAD_OFFSET, MIN_PAYLOAD_SIZE, MAX_PAYLOAD_SIZE),
23
- address: () => bmtHash(data)
24
+ span,
25
+ payload: Bytes.fromSlice(data, Span.LENGTH),
26
+ address: calculateChunkAddress(data)
24
27
  };
25
28
  }
26
- /**
27
- * Type guard for valid content addressed chunk data
28
- *
29
- * @param data The chunk data
30
- * @param chunkAddress The address of the chunk
31
- */
32
- export function isValidChunkData(data, chunkAddress) {
33
- if (!(data instanceof Uint8Array)) return false;
34
- const address = bmtHash(data);
35
- return bytesEqual(address, chunkAddress);
36
- }
37
- /**
38
- * Asserts if data are representing given address of its chunk.
39
- *
40
- * @param data The chunk data
41
- * @param chunkAddress The address of the chunk
42
- *
43
- * @returns a valid content addressed chunk or throws error
44
- */
45
- export function assertValidChunkData(data, chunkAddress) {
46
- if (!isValidChunkData(data, chunkAddress)) {
47
- throw new BeeError('Address of content address chunk does not match given data!');
29
+ export function asContentAddressedChunk(chunkBytes) {
30
+ if (chunkBytes.length < MIN_PAYLOAD_SIZE + Span.LENGTH || chunkBytes.length > MAX_PAYLOAD_SIZE + Span.LENGTH) {
31
+ throw new RangeError(`chunk size ${chunkBytes.length} exceeds limits [${MIN_PAYLOAD_SIZE + Span.LENGTH}, ${Span.LENGTH}]`);
48
32
  }
33
+ const span = Span.fromSlice(chunkBytes, 0);
34
+ const data = Binary.concatBytes(span.toUint8Array(), chunkBytes.slice(Span.LENGTH));
35
+ return {
36
+ data,
37
+ span,
38
+ payload: Bytes.fromSlice(data, Span.LENGTH),
39
+ address: calculateChunkAddress(data)
40
+ };
49
41
  }
@@ -1,27 +1,21 @@
1
1
  import { Binary } from 'cafe-utility';
2
2
  import * as chunkAPI from "../modules/chunk.js";
3
3
  import * as socAPI from "../modules/soc.js";
4
- import { bytesAtOffset, bytesEqual, flexBytesAtOffset } from "../utils/bytes.js";
4
+ import { Bytes } from "../utils/bytes.js";
5
5
  import { BeeError } from "../utils/error.js";
6
- import { keccak256Hash } from "../utils/hash.js";
7
- import { bytesToHex } from "../utils/hex.js";
8
- import { bmtHash } from "./bmt.js";
9
- import { MAX_PAYLOAD_SIZE, MIN_PAYLOAD_SIZE, assertValidChunkData, makeContentAddressedChunk } from "./cac.js";
10
- import { recoverAddress, sign } from "./signer.js";
11
- import { SPAN_SIZE } from "./span.js";
12
- const IDENTIFIER_SIZE = 32;
13
- const SIGNATURE_SIZE = 65;
14
- const SOC_IDENTIFIER_OFFSET = 0;
15
- const SOC_SIGNATURE_OFFSET = SOC_IDENTIFIER_OFFSET + IDENTIFIER_SIZE;
16
- const SOC_SPAN_OFFSET = SOC_SIGNATURE_OFFSET + SIGNATURE_SIZE;
17
- const SOC_PAYLOAD_OFFSET = SOC_SPAN_OFFSET + SPAN_SIZE;
6
+ import { EthAddress, Identifier, PrivateKey, Reference, Signature, Span } from "../utils/typed-bytes.js";
7
+ import { calculateChunkAddress } from "./bmt.js";
8
+ import { asContentAddressedChunk, makeContentAddressedChunk } from "./cac.js";
9
+ const SOC_SIGNATURE_OFFSET = Identifier.LENGTH;
10
+ const SOC_SPAN_OFFSET = SOC_SIGNATURE_OFFSET + Signature.LENGTH;
11
+ const SOC_PAYLOAD_OFFSET = SOC_SPAN_OFFSET + Span.LENGTH;
18
12
  function recoverChunkOwner(data) {
19
13
  const cacData = data.slice(SOC_SPAN_OFFSET);
20
- const chunkAddress = bmtHash(cacData);
21
- const signature = bytesAtOffset(data, SOC_SIGNATURE_OFFSET, SIGNATURE_SIZE);
22
- const identifier = bytesAtOffset(data, SOC_IDENTIFIER_OFFSET, IDENTIFIER_SIZE);
23
- const digest = keccak256Hash(identifier, chunkAddress);
24
- const ownerAddress = recoverAddress(signature, digest);
14
+ const chunkAddress = calculateChunkAddress(cacData);
15
+ const signature = Signature.fromSlice(data, SOC_SIGNATURE_OFFSET);
16
+ const identifier = Bytes.fromSlice(data, 0, Identifier.LENGTH);
17
+ const digest = Binary.concatBytes(identifier.toUint8Array(), chunkAddress.toUint8Array());
18
+ const ownerAddress = signature.recoverPublicKey(digest).address();
25
19
  return ownerAddress;
26
20
  }
27
21
  /**
@@ -33,50 +27,53 @@ function recoverChunkOwner(data) {
33
27
  * @returns a single owner chunk or throws error
34
28
  */
35
29
  export function makeSingleOwnerChunkFromData(data, address) {
30
+ data = data instanceof Bytes ? data.toUint8Array() : data;
31
+ address = new Reference(address);
36
32
  const ownerAddress = recoverChunkOwner(data);
37
- const identifier = bytesAtOffset(data, SOC_IDENTIFIER_OFFSET, IDENTIFIER_SIZE);
38
- const socAddress = keccak256Hash(identifier, ownerAddress);
39
- if (!bytesEqual(address, socAddress)) {
33
+ const identifier = Bytes.fromSlice(data, 0, Identifier.LENGTH);
34
+ const socAddress = new Reference(Binary.keccak256(Binary.concatBytes(identifier.toUint8Array(), ownerAddress.toUint8Array())));
35
+ if (!Binary.equals(address.toUint8Array(), socAddress.toUint8Array())) {
40
36
  throw new BeeError('SOC Data does not match given address!');
41
37
  }
42
- const signature = () => bytesAtOffset(data, SOC_SIGNATURE_OFFSET, SIGNATURE_SIZE);
43
- const span = () => bytesAtOffset(data, SOC_SPAN_OFFSET, SPAN_SIZE);
44
- const payload = () => flexBytesAtOffset(data, SOC_PAYLOAD_OFFSET, MIN_PAYLOAD_SIZE, MAX_PAYLOAD_SIZE);
38
+ const signature = Signature.fromSlice(data, SOC_SIGNATURE_OFFSET);
39
+ const span = Span.fromSlice(data, SOC_SPAN_OFFSET);
40
+ const payload = Bytes.fromSlice(data, SOC_PAYLOAD_OFFSET);
45
41
  return {
46
42
  data,
47
- identifier: () => identifier,
43
+ identifier,
48
44
  signature,
49
45
  span,
50
46
  payload,
51
- address: () => socAddress,
52
- owner: () => ownerAddress
47
+ address: socAddress,
48
+ owner: ownerAddress
53
49
  };
54
50
  }
55
51
  export function makeSOCAddress(identifier, address) {
56
- return keccak256Hash(identifier, address);
52
+ return new Reference(Binary.keccak256(Binary.concatBytes(identifier.toUint8Array(), address.toUint8Array())));
57
53
  }
58
54
  /**
59
55
  * Creates a single owner chunk object
60
56
  *
61
57
  * @param chunk A chunk object used for the span and payload
62
58
  * @param identifier The identifier of the chunk
63
- * @param signer The singer interface for signing the chunk
59
+ * @param signer The signer interface for signing the chunk
64
60
  */
65
- export async function makeSingleOwnerChunk(chunk, identifier, signer) {
66
- const chunkAddress = chunk.address();
67
- assertValidChunkData(chunk.data, chunkAddress);
68
- const digest = keccak256Hash(identifier, chunkAddress);
69
- const signature = await sign(signer, digest);
70
- const data = Binary.concatBytes(identifier, signature, chunk.span(), chunk.payload());
71
- const address = makeSOCAddress(identifier, signer.address);
61
+ export function makeSingleOwnerChunk(chunk, identifier, signer) {
62
+ identifier = new Identifier(identifier);
63
+ signer = new PrivateKey(signer);
64
+ const address = makeSOCAddress(identifier, signer.publicKey().address());
65
+ const signature = signer.sign(Binary.concatBytes(identifier.toUint8Array(), chunk.address.toUint8Array()));
66
+ const data = Binary.concatBytes(identifier.toUint8Array(), signature.toUint8Array(), chunk.data);
67
+ const span = Span.fromSlice(chunk.data, 0);
68
+ const payload = Bytes.fromSlice(chunk.data, Span.LENGTH);
72
69
  return {
73
70
  data,
74
- identifier: () => identifier,
75
- signature: () => signature,
76
- span: () => chunk.span(),
77
- payload: () => chunk.payload(),
78
- address: () => address,
79
- owner: () => signer.address
71
+ identifier,
72
+ signature,
73
+ span,
74
+ payload,
75
+ address,
76
+ owner: signer.publicKey().address()
80
77
  };
81
78
  }
82
79
  /**
@@ -86,40 +83,47 @@ export async function makeSingleOwnerChunk(chunk, identifier, signer) {
86
83
  *
87
84
  * @param requestOptions Options for making requests
88
85
  * @param chunk A chunk object
89
- * @param postageBatchId Postage BatchId that will be assigned to uploaded data
86
+ * @param stamp Postage BatchId that will be assigned to uploaded data
90
87
  * @param options Upload options
91
88
  */
92
89
  export async function uploadSingleOwnerChunk(requestOptions, chunk, stamp, options) {
93
- const owner = bytesToHex(chunk.owner());
94
- const identifier = bytesToHex(chunk.identifier());
95
- const signature = bytesToHex(chunk.signature());
96
- const data = Binary.concatBytes(chunk.span(), chunk.payload());
97
- return socAPI.upload(requestOptions, owner, identifier, signature, data, stamp, options);
90
+ const data = Binary.concatBytes(chunk.span.toUint8Array(), chunk.payload.toUint8Array());
91
+ return socAPI.upload(requestOptions, chunk.owner, chunk.identifier, chunk.signature, data, stamp, options);
98
92
  }
99
93
  /**
100
94
  * Helper function to create and upload SOC.
101
95
  *
102
96
  * @param requestOptions Options for making requests
103
- * @param signer The singer interface for signing the chunk
97
+ * @param signer The signer interface for signing the chunk
104
98
  * @param postageBatchId
105
99
  * @param identifier The identifier of the chunk
106
100
  * @param data The chunk data
107
101
  * @param options
108
102
  */
109
103
  export async function uploadSingleOwnerChunkData(requestOptions, signer, stamp, identifier, data, options) {
104
+ signer = new PrivateKey(signer);
105
+ identifier = new Identifier(identifier);
110
106
  const cac = makeContentAddressedChunk(data);
111
- const soc = await makeSingleOwnerChunk(cac, identifier, signer);
107
+ const soc = makeSingleOwnerChunk(cac, identifier, signer);
108
+ return uploadSingleOwnerChunk(requestOptions, soc, stamp, options);
109
+ }
110
+ export async function uploadSingleOwnerChunkWithWrappedChunk(requestOptions, signer, stamp, identifier, rootChunk, options) {
111
+ signer = new PrivateKey(signer);
112
+ identifier = new Identifier(identifier);
113
+ const soc = makeSingleOwnerChunk(asContentAddressedChunk(rootChunk), identifier, signer);
112
114
  return uploadSingleOwnerChunk(requestOptions, soc, stamp, options);
113
115
  }
114
116
  /**
115
117
  * Helper function to download SOC.
116
118
  *
117
119
  * @param url The url of the Bee service
118
- * @param ownerAddress The singer interface for signing the chunk
120
+ * @param ownerAddress The signer interface for signing the chunk
119
121
  * @param identifier The identifier of the chunk
120
122
  */
121
123
  export async function downloadSingleOwnerChunk(requestOptions, ownerAddress, identifier) {
124
+ identifier = new Identifier(identifier);
125
+ ownerAddress = new EthAddress(ownerAddress);
122
126
  const address = makeSOCAddress(identifier, ownerAddress);
123
- const data = await chunkAPI.download(requestOptions, bytesToHex(address));
124
- return makeSingleOwnerChunkFromData(data, address);
127
+ const cac = await chunkAPI.download(requestOptions, address.toHex());
128
+ return makeSingleOwnerChunkFromData(cac, address);
125
129
  }
@@ -1,29 +1,6 @@
1
1
  import { Binary } from 'cafe-utility';
2
- import { FEED_INDEX_HEX_LENGTH } from "../types/index.js";
3
- import { keccak256Hash } from "../utils/hash.js";
4
- import { hexToBytes, makeHexString } from "../utils/hex.js";
5
- function isEpoch(epoch) {
6
- return typeof epoch === 'object' && epoch !== null && 'time' in epoch && 'level' in epoch;
7
- }
8
- function hashFeedIdentifier(topic, index) {
9
- return keccak256Hash(hexToBytes(topic), index);
10
- }
11
- function makeSequentialFeedIdentifier(topic, index) {
12
- const indexBytes = Binary.numberToUint64BE(index);
13
- return hashFeedIdentifier(topic, indexBytes);
14
- }
15
- function makeFeedIndexBytes(s) {
16
- const hex = makeHexString(s, FEED_INDEX_HEX_LENGTH);
17
- return hexToBytes(hex);
18
- }
2
+ import { FeedIndex, Identifier } from "../utils/typed-bytes.js";
19
3
  export function makeFeedIdentifier(topic, index) {
20
- if (typeof index === 'number') {
21
- return makeSequentialFeedIdentifier(topic, index);
22
- } else if (typeof index === 'string') {
23
- const indexBytes = makeFeedIndexBytes(index);
24
- return hashFeedIdentifier(topic, indexBytes);
25
- } else if (isEpoch(index)) {
26
- throw new TypeError('epoch is not yet implemented');
27
- }
28
- return hashFeedIdentifier(topic, index);
4
+ index = typeof index === 'number' ? FeedIndex.fromBigInt(BigInt(index)) : index;
5
+ return new Identifier(Binary.keccak256(Binary.concatBytes(topic.toUint8Array(), index.toUint8Array())));
29
6
  }
@@ -1,86 +1,133 @@
1
- import { Binary } from 'cafe-utility';
2
- import { makeSingleOwnerChunkFromData, uploadSingleOwnerChunkData } from "../chunk/soc.js";
1
+ import { Binary, Optional, Types } from 'cafe-utility';
2
+ import { asContentAddressedChunk } from "../chunk/cac.js";
3
+ import { makeSingleOwnerChunkFromData, uploadSingleOwnerChunkData, uploadSingleOwnerChunkWithWrappedChunk } from "../chunk/soc.js";
4
+ import * as bytes from "../modules/bytes.js";
3
5
  import * as chunkAPI from "../modules/chunk.js";
4
- import { fetchLatestFeedUpdate } from "../modules/feed.js";
5
- import { FEED_INDEX_HEX_LENGTH } from "../types/index.js";
6
- import { bytesAtOffset, makeBytes } from "../utils/bytes.js";
6
+ import { fetchLatestFeedUpdate, probeFeed } from "../modules/feed.js";
7
+ import { Bytes } from "../utils/bytes.js";
7
8
  import { BeeResponseError } from "../utils/error.js";
8
- import { makeHexEthAddress } from "../utils/eth.js";
9
- import { keccak256Hash } from "../utils/hash.js";
10
- import { bytesToHex, hexToBytes, makeHexString } from "../utils/hex.js";
11
- import { makeBytesReference } from "../utils/reference.js";
12
- import { assertAddress } from "../utils/type.js";
9
+ import { ResourceLocator } from "../utils/resource-locator.js";
10
+ import { FeedIndex, Identifier, Reference, Signature } from "../utils/typed-bytes.js";
13
11
  import { makeFeedIdentifier } from "./identifier.js";
14
12
  const TIMESTAMP_PAYLOAD_OFFSET = 0;
15
13
  const TIMESTAMP_PAYLOAD_SIZE = 8;
16
14
  const REFERENCE_PAYLOAD_OFFSET = TIMESTAMP_PAYLOAD_SIZE;
17
- export async function findNextIndex(requestOptions, owner, topic, options) {
15
+ export async function findNextIndex(requestOptions, owner, topic) {
18
16
  try {
19
- const feedUpdate = await fetchLatestFeedUpdate(requestOptions, owner, topic, options);
20
- return makeHexString(feedUpdate.feedIndexNext, FEED_INDEX_HEX_LENGTH);
17
+ const feedUpdate = await fetchLatestFeedUpdate(requestOptions, owner, topic);
18
+ if (!feedUpdate.feedIndexNext) {
19
+ throw Error('Feed index next is not defined. This should happen when fetching an exact index.');
20
+ }
21
+ return feedUpdate.feedIndexNext;
21
22
  } catch (e) {
22
23
  if (e instanceof BeeResponseError) {
23
- return bytesToHex(makeBytes(8));
24
+ return FeedIndex.fromBigInt(0n);
24
25
  }
25
26
  throw e;
26
27
  }
27
28
  }
28
- export async function updateFeed(requestOptions, signer, topic, reference, postageBatchId, options) {
29
- const ownerHex = makeHexEthAddress(signer.address);
30
- const nextIndex = options?.index ?? (await findNextIndex(requestOptions, ownerHex, topic, options));
29
+ export async function updateFeedWithReference(requestOptions, signer, topic, reference, postageBatchId, options) {
30
+ reference = new Reference(reference);
31
+ const nextIndex = options?.index ?? (await findNextIndex(requestOptions, signer.publicKey().address(), topic));
31
32
  const identifier = makeFeedIdentifier(topic, nextIndex);
32
33
  const at = options?.at ?? Date.now() / 1000.0;
33
- const timestamp = Binary.numberToUint64BE(Math.floor(at));
34
- const payloadBytes = Binary.concatBytes(timestamp, reference);
34
+ const timestamp = Binary.numberToUint64(BigInt(Math.floor(at)), 'BE');
35
+ const payloadBytes = Binary.concatBytes(timestamp, reference.toUint8Array());
35
36
  return uploadSingleOwnerChunkData(requestOptions, signer, postageBatchId, identifier, payloadBytes, options);
36
37
  }
38
+ export async function updateFeedWithPayload(requestOptions, signer, topic, data, postageBatchId, options) {
39
+ const nextIndex = options?.index ?? (await findNextIndex(requestOptions, signer.publicKey().address(), topic));
40
+ const identifier = makeFeedIdentifier(topic, nextIndex);
41
+ if (data.length > 4096) {
42
+ const uploadResult = await bytes.upload(requestOptions, data, postageBatchId, options);
43
+ const rootChunk = await chunkAPI.download(requestOptions, uploadResult.reference);
44
+ return uploadSingleOwnerChunkWithWrappedChunk(requestOptions, signer, postageBatchId, identifier, rootChunk, options);
45
+ }
46
+ return uploadSingleOwnerChunkData(requestOptions, signer, postageBatchId, identifier, Types.isString(data) ? Bytes.fromUtf8(data).toUint8Array() : data, options);
47
+ }
37
48
  export function getFeedUpdateChunkReference(owner, topic, index) {
38
49
  const identifier = makeFeedIdentifier(topic, index);
39
- return keccak256Hash(identifier, owner);
50
+ return new Reference(Binary.keccak256(Binary.concatBytes(identifier.toUint8Array(), owner.toUint8Array())));
40
51
  }
41
- export async function downloadFeedUpdate(requestOptions, owner, topic, index) {
52
+ export async function downloadFeedUpdate(requestOptions, owner, topic, index, hasTimestamp = false) {
53
+ index = typeof index === 'number' ? FeedIndex.fromBigInt(BigInt(index)) : index;
42
54
  const address = getFeedUpdateChunkReference(owner, topic, index);
43
- const addressHex = bytesToHex(address);
44
- const data = await chunkAPI.download(requestOptions, addressHex);
55
+ const data = await chunkAPI.download(requestOptions, address.toHex());
45
56
  const soc = makeSingleOwnerChunkFromData(data, address);
46
- const payload = soc.payload();
47
- const timestampBytes = bytesAtOffset(payload, TIMESTAMP_PAYLOAD_OFFSET, TIMESTAMP_PAYLOAD_SIZE);
48
- const timestamp = Binary.uint64BEToNumber(timestampBytes);
49
- const reference = makeBytesReference(payload, REFERENCE_PAYLOAD_OFFSET);
57
+ let timestamp = Optional.empty();
58
+ if (hasTimestamp) {
59
+ const timestampBytes = Bytes.fromSlice(soc.payload.toUint8Array(), TIMESTAMP_PAYLOAD_OFFSET, TIMESTAMP_PAYLOAD_SIZE);
60
+ timestamp = Optional.of(Number(Binary.uint64ToNumber(timestampBytes.toUint8Array(), 'BE')));
61
+ }
50
62
  return {
51
63
  timestamp,
52
- reference
64
+ payload: new Bytes(soc.payload.offset(hasTimestamp ? REFERENCE_PAYLOAD_OFFSET : 0))
53
65
  };
54
66
  }
55
- export function makeFeedReader(requestOptions, type, topic, owner) {
67
+ export async function downloadFeedUpdateAsCAC(requestOptions, owner, topic, index) {
68
+ index = typeof index === 'number' ? FeedIndex.fromBigInt(BigInt(index)) : index;
69
+ const address = getFeedUpdateChunkReference(owner, topic, index);
70
+ const data = await chunkAPI.download(requestOptions, address);
71
+ return asContentAddressedChunk(data.slice(Identifier.LENGTH + Signature.LENGTH));
72
+ }
73
+ export function makeFeedReader(requestOptions, topic, owner) {
74
+ // TODO: remove after enough time has passed in deprecated version
75
+ const download = async options => {
76
+ if (options?.index === undefined) {
77
+ return fetchLatestFeedUpdate(requestOptions, owner, topic);
78
+ }
79
+ const update = await downloadFeedUpdate(requestOptions, owner, topic, options.index, options.hasTimestamp ?? true);
80
+ const feedIndex = typeof options.index === 'number' ? FeedIndex.fromBigInt(BigInt(options.index)) : options.index;
81
+ return {
82
+ payload: update.payload,
83
+ feedIndex
84
+ };
85
+ };
86
+ const downloadPayload = async options => {
87
+ if (options?.index === undefined) {
88
+ return fetchLatestFeedUpdate(requestOptions, owner, topic);
89
+ }
90
+ const cac = await downloadFeedUpdateAsCAC(requestOptions, owner, topic, options.index);
91
+ const payload = cac.span.toBigInt() <= 4096n ? cac.payload : await bytes.download(requestOptions, new ResourceLocator(cac.address));
92
+ const feedIndex = typeof options.index === 'number' ? FeedIndex.fromBigInt(BigInt(options.index)) : options.index;
93
+ return {
94
+ payload,
95
+ feedIndex
96
+ };
97
+ };
98
+ const downloadReference = async options => {
99
+ let index = options?.index;
100
+ if (index === undefined) {
101
+ index = (await probeFeed(requestOptions, owner, topic)).feedIndex;
102
+ }
103
+ const payload = await download({
104
+ ...options,
105
+ index: index
106
+ });
107
+ return {
108
+ reference: new Reference(payload.payload.toUint8Array()),
109
+ feedIndex: payload.feedIndex
110
+ };
111
+ };
56
112
  return {
57
- type,
113
+ download,
114
+ downloadPayload,
115
+ downloadReference,
58
116
  owner,
59
- topic,
60
- async download(options) {
61
- if (!options?.index && options?.index !== 0) {
62
- return fetchLatestFeedUpdate(requestOptions, owner, topic);
63
- }
64
- const update = await downloadFeedUpdate(requestOptions, hexToBytes(owner), topic, options.index);
65
- return {
66
- reference: bytesToHex(update.reference),
67
- feedIndex: options.index,
68
- feedIndexNext: ''
69
- };
70
- }
117
+ topic
71
118
  };
72
119
  }
73
- export function makeFeedWriter(requestOptions, type, topic, signer) {
120
+ export function makeFeedWriter(requestOptions, topic, signer) {
74
121
  const upload = async (postageBatchId, reference, options) => {
75
- assertAddress(postageBatchId);
76
- const canonicalReference = makeBytesReference(reference);
77
- return updateFeed(requestOptions, signer, topic, canonicalReference, postageBatchId, {
78
- ...options,
79
- type
80
- });
122
+ return updateFeedWithReference(requestOptions, signer, topic, reference, postageBatchId, options);
123
+ };
124
+ const uploadPayload = async (postageBatchId, data, options) => {
125
+ return updateFeedWithPayload(requestOptions, signer, topic, data, postageBatchId, options);
81
126
  };
82
127
  return {
83
- ...makeFeedReader(requestOptions, type, topic, makeHexEthAddress(signer.address)),
84
- upload
128
+ ...makeFeedReader(requestOptions, topic, signer.publicKey().address()),
129
+ upload,
130
+ uploadReference: upload,
131
+ uploadPayload
85
132
  };
86
133
  }
@@ -1,18 +1,6 @@
1
- import { Binary } from 'cafe-utility';
2
- import { bytesToHex } from "../utils/hex.js";
1
+ import { Objects } from 'cafe-utility';
2
+ import { FeedIndex } from "../utils/typed-bytes.js";
3
3
  import { getFeedUpdateChunkReference } from "./index.js";
4
- function makeNumericIndex(index) {
5
- if (index instanceof Uint8Array) {
6
- return Binary.uint64BEToNumber(index);
7
- }
8
- if (typeof index === 'string') {
9
- return parseInt(index);
10
- }
11
- if (typeof index === 'number') {
12
- return index;
13
- }
14
- throw new TypeError('Unknown type of index!');
15
- }
16
4
  /**
17
5
  * Function that checks if a chunk is retrievable by actually downloading it.
18
6
  * The /stewardship/{reference} endpoint does not support verification of chunks, but only manifest's references.
@@ -21,12 +9,13 @@ function makeNumericIndex(index) {
21
9
  * @param ref
22
10
  * @param options
23
11
  */
24
- async function isChunkRetrievable(bee, ref, requestOptions) {
12
+ async function isChunkRetrievable(bee, reference, options, requestOptions) {
25
13
  try {
26
- await bee.downloadChunk(ref, requestOptions);
14
+ await bee.downloadChunk(reference, options, requestOptions);
27
15
  return true;
28
16
  } catch (e) {
29
- if (e?.status === 404 || e?.status === 500) {
17
+ const status = Objects.getDeep(e, 'status');
18
+ if (status === 404 || status === 500) {
30
19
  return false;
31
20
  }
32
21
  throw e;
@@ -40,14 +29,14 @@ async function isChunkRetrievable(bee, ref, requestOptions) {
40
29
  * @param index
41
30
  */
42
31
  function getAllSequenceUpdateReferences(owner, topic, index) {
43
- const numIndex = makeNumericIndex(index);
44
- const updateReferences = new Array(numIndex + 1);
45
- for (let i = 0; i <= numIndex; i++) {
46
- updateReferences[i] = bytesToHex(getFeedUpdateChunkReference(owner, topic, i));
32
+ const count = index.toBigInt();
33
+ const updateReferences = [];
34
+ for (let i = 0n; i <= count; i++) {
35
+ updateReferences.push(getFeedUpdateChunkReference(owner, topic, FeedIndex.fromBigInt(i)));
47
36
  }
48
37
  return updateReferences;
49
38
  }
50
- export async function areAllSequentialFeedsUpdateRetrievable(bee, owner, topic, index, requestOptions) {
51
- const chunkRetrievablePromises = getAllSequenceUpdateReferences(owner, topic, index).map(async ref => isChunkRetrievable(bee, ref, requestOptions));
39
+ export async function areAllSequentialFeedsUpdateRetrievable(bee, owner, topic, index, options, requestOptions) {
40
+ const chunkRetrievablePromises = getAllSequenceUpdateReferences(owner, topic, index).map(async reference => isChunkRetrievable(bee, reference, options, requestOptions));
52
41
  return (await Promise.all(chunkRetrievablePromises)).every(result => result);
53
42
  }
package/dist/mjs/index.js CHANGED
@@ -1,7 +1,16 @@
1
1
  import { Bee } from "./bee.js";
2
+ import { BeeDev } from "./bee-dev.js";
3
+ import { Stamper } from "./stamper/stamper.js";
4
+ export { MerkleTree } from 'cafe-utility';
5
+ export { MantarayNode } from "./manifest/manifest.js";
2
6
  export { SUPPORTED_BEE_VERSION, SUPPORTED_BEE_VERSION_EXACT } from "./modules/debug/status.js";
3
7
  export * from "./types/index.js";
8
+ export { Bytes } from "./utils/bytes.js";
4
9
  export * from "./utils/constants.js";
10
+ export { Duration } from "./utils/duration.js";
5
11
  export * from "./utils/error.js";
6
12
  export * as Utils from "./utils/expose.js";
7
- export { Bee };
13
+ export { Size } from "./utils/size.js";
14
+ export * from "./utils/tokens.js";
15
+ export * from "./utils/typed-bytes.js";
16
+ export { Bee, BeeDev, Stamper };