@solarpunkltd/swarm-id 0.0.0-stage → 0.8.0
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.
- package/LICENSE +202 -0
- package/README.md +86 -2
- package/dist/bus/account-bus.d.ts +104 -0
- package/dist/bus/account-delta.d.ts +52 -0
- package/dist/bus/bus-context.d.ts +7 -0
- package/dist/bus/envelope.d.ts +9 -0
- package/dist/bus/messages.d.ts +241 -0
- package/dist/bus/presence.d.ts +62 -0
- package/dist/bus/signaling-transport.d.ts +79 -0
- package/dist/chunk/bmt.d.ts +16 -0
- package/dist/chunk/cac.d.ts +17 -0
- package/dist/chunk/constants.d.ts +10 -0
- package/dist/chunk/encrypted-cac.d.ts +47 -0
- package/dist/chunk/encryption.d.ts +85 -0
- package/dist/chunk/index.d.ts +5 -0
- package/dist/chunks/chat-binding-DlH_ZkTn.js +23 -0
- package/dist/chunks/chat-binding-DlH_ZkTn.js.map +1 -0
- package/dist/errors.d.ts +35 -0
- package/dist/index.d.ts +27 -0
- package/dist/internal.d.ts +49 -0
- package/dist/internal.esm.js +2 -0
- package/dist/internal.esm.js.map +1 -0
- package/dist/proxy/act/act.d.ts +58 -0
- package/dist/proxy/act/crypto.d.ts +46 -0
- package/dist/proxy/act/grantee-list.d.ts +81 -0
- package/dist/proxy/act/history.d.ts +182 -0
- package/dist/proxy/act/index.d.ts +114 -0
- package/dist/proxy/app-stamp-limits.d.ts +62 -0
- package/dist/proxy/chunk-upload-stream.d.ts +37 -0
- package/dist/proxy/chunking.d.ts +15 -0
- package/dist/proxy/collection.d.ts +38 -0
- package/dist/proxy/download-data.d.ts +27 -0
- package/dist/proxy/errors.d.ts +8 -0
- package/dist/proxy/feed-manifest.d.ts +60 -0
- package/dist/proxy/feeds/epochs/async-finder.d.ts +70 -0
- package/dist/proxy/feeds/epochs/epoch.d.ts +79 -0
- package/dist/proxy/feeds/epochs/finder.d.ts +60 -0
- package/dist/proxy/feeds/epochs/index.d.ts +30 -0
- package/dist/proxy/feeds/epochs/types.d.ts +110 -0
- package/dist/proxy/feeds/epochs/updater.d.ts +76 -0
- package/dist/proxy/feeds/epochs/utils.d.ts +21 -0
- package/dist/proxy/feeds/index.d.ts +4 -0
- package/dist/proxy/feeds/sequence/async-finder.d.ts +14 -0
- package/dist/proxy/feeds/sequence/finder.d.ts +11 -0
- package/dist/proxy/feeds/sequence/index.d.ts +22 -0
- package/dist/proxy/feeds/sequence/types.d.ts +82 -0
- package/dist/proxy/feeds/sequence/updater.d.ts +20 -0
- package/dist/proxy/index.d.ts +5 -0
- package/dist/proxy/manifest-builder.d.ts +164 -0
- package/dist/proxy/mantaray.d.ts +76 -0
- package/dist/proxy/soc-restamp-slots.d.ts +48 -0
- package/dist/proxy/stamp-chunk.d.ts +45 -0
- package/dist/proxy/stamp-worker-handler.d.ts +32 -0
- package/dist/proxy/stamp-worker-pool.d.ts +52 -0
- package/dist/proxy/stamp-worker.d.ts +1 -0
- package/dist/proxy/types.d.ts +38 -0
- package/dist/proxy/upload.d.ts +207 -0
- package/dist/schemas.d.ts +665 -0
- package/dist/stamp-worker.iife.js +1 -0
- package/dist/storage/debounced-uploader.d.ts +61 -0
- package/dist/storage/utilization-store.d.ts +113 -0
- package/dist/swarm-id-client.d.ts +1114 -0
- package/dist/swarm-id-proxy.d.ts +1031 -0
- package/dist/swarm-id.esm.js +2 -0
- package/dist/swarm-id.esm.js.map +1 -0
- package/dist/sync/batch-write-coordinator.d.ts +347 -0
- package/dist/sync/device-roster.d.ts +59 -0
- package/dist/sync/device-state.d.ts +199 -0
- package/dist/sync/fold-account-from-swarm.d.ts +53 -0
- package/dist/sync/index.d.ts +11 -0
- package/dist/sync/merge-snapshot.d.ts +57 -0
- package/dist/sync/partition-intent.d.ts +218 -0
- package/dist/sync/partition-lease.d.ts +531 -0
- package/dist/sync/partition-lock.d.ts +218 -0
- package/dist/sync/partition-state.d.ts +287 -0
- package/dist/sync/session-check.d.ts +29 -0
- package/dist/sync/store-interfaces.d.ts +48 -0
- package/dist/sync/sync-account.d.ts +45 -0
- package/dist/sync/timing-constants.d.ts +32 -0
- package/dist/sync/types.d.ts +18 -0
- package/dist/types.d.ts +3007 -0
- package/dist/utils/account-state-snapshot.d.ts +43 -0
- package/dist/utils/active-devices.d.ts +45 -0
- package/dist/utils/avatar.d.ts +30 -0
- package/dist/utils/batch-utilization.d.ts +840 -0
- package/dist/utils/batch-write-lock.d.ts +12 -0
- package/dist/utils/bee-error.d.ts +11 -0
- package/dist/utils/chat-binding.d.ts +113 -0
- package/dist/utils/coalesced-task.d.ts +28 -0
- package/dist/utils/collection.d.ts +6 -0
- package/dist/utils/connection-info.d.ts +11 -0
- package/dist/utils/constants.d.ts +28 -0
- package/dist/utils/device-id.d.ts +109 -0
- package/dist/utils/hex.d.ts +31 -0
- package/dist/utils/json-rpc.d.ts +34 -0
- package/dist/utils/key-derivation.d.ts +124 -0
- package/dist/utils/lock-soc.d.ts +35 -0
- package/dist/utils/postage-contract.d.ts +143 -0
- package/dist/utils/postage-stamp-association.d.ts +39 -0
- package/dist/utils/promise.d.ts +37 -0
- package/dist/utils/sealed-values.d.ts +23 -0
- package/dist/utils/seed-encryption.d.ts +17 -0
- package/dist/utils/site-allow-list.d.ts +54 -0
- package/dist/utils/stamp-lifespan.d.ts +37 -0
- package/dist/utils/storage-managers.d.ts +62 -0
- package/dist/utils/storage-probe.d.ts +40 -0
- package/dist/utils/tag.d.ts +11 -0
- package/dist/utils/ttl.d.ts +120 -0
- package/dist/utils/url.d.ts +47 -0
- package/dist/utils/versioned-storage.d.ts +183 -0
- package/package.json +91 -3
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
import type { UploadOptions } from "@ethersphere/bee-js";
|
|
2
|
+
import { type UploadTarget } from "./upload";
|
|
3
|
+
/**
|
|
4
|
+
* Options for creating a feed manifest
|
|
5
|
+
*/
|
|
6
|
+
export interface CreateFeedManifestOptions {
|
|
7
|
+
/**
|
|
8
|
+
* Whether to encrypt the manifest.
|
|
9
|
+
* Default: true (encrypted)
|
|
10
|
+
*/
|
|
11
|
+
encrypt?: boolean;
|
|
12
|
+
/**
|
|
13
|
+
* Feed type: "Sequence" for sequential feeds, "Epoch" for epoch feeds.
|
|
14
|
+
* Default: "Sequence"
|
|
15
|
+
*/
|
|
16
|
+
feedType?: "Sequence" | "Epoch";
|
|
17
|
+
}
|
|
18
|
+
/**
|
|
19
|
+
* Result of creating a feed manifest
|
|
20
|
+
*/
|
|
21
|
+
export interface CreateFeedManifestResult {
|
|
22
|
+
/**
|
|
23
|
+
* Reference to the feed manifest.
|
|
24
|
+
* - Encrypted: 128 hex chars (64 bytes = address + encryption key)
|
|
25
|
+
* - Unencrypted: 64 hex chars (32 bytes = address)
|
|
26
|
+
*/
|
|
27
|
+
reference: string;
|
|
28
|
+
/**
|
|
29
|
+
* Tag UID if a tag was created during upload
|
|
30
|
+
*/
|
|
31
|
+
tagUid?: number;
|
|
32
|
+
}
|
|
33
|
+
/**
|
|
34
|
+
* Create a feed manifest directly using chunk upload
|
|
35
|
+
*
|
|
36
|
+
* Instead of using bee.createFeedManifest() which calls the /feeds endpoint,
|
|
37
|
+
* this function builds the manifest locally as a MantarayNode and uploads it
|
|
38
|
+
* via the encrypted chunk endpoint (or plain chunk endpoint if encrypt=false).
|
|
39
|
+
*
|
|
40
|
+
* Feed manifests have a single "/" path with metadata:
|
|
41
|
+
* - swarm-feed-owner: Owner's ethereum address (40 hex chars, no 0x)
|
|
42
|
+
* - swarm-feed-topic: Topic hash (64 hex chars)
|
|
43
|
+
* - swarm-feed-type: "Sequence" for sequential feeds
|
|
44
|
+
*
|
|
45
|
+
* IMPORTANT: This function implements client-side "saveRecursively" logic:
|
|
46
|
+
* 1. Upload the "/" child node first and get its address
|
|
47
|
+
* 2. Set the child's selfAddress to the uploaded address
|
|
48
|
+
* 3. Then upload the root node (which references the child's address)
|
|
49
|
+
*
|
|
50
|
+
* Without this, Bee's /bzz/ endpoint returns 404 because the "/" child chunk
|
|
51
|
+
* doesn't exist (only its calculated hash was stored in the root manifest).
|
|
52
|
+
*
|
|
53
|
+
* @param target - Upload target (stamper or subsidised mode)
|
|
54
|
+
* @param topic - Topic hex string (64 chars)
|
|
55
|
+
* @param owner - Owner hex string (40 chars, no 0x prefix)
|
|
56
|
+
* @param options - Options for creating the manifest (encrypt, etc.)
|
|
57
|
+
* @param uploadOptions - Upload options (tag, deferred, etc.)
|
|
58
|
+
* @returns Reference to the feed manifest
|
|
59
|
+
*/
|
|
60
|
+
export declare function createFeedManifestDirect(target: UploadTarget, topic: string, owner: string, options?: CreateFeedManifestOptions, uploadOptions?: UploadOptions): Promise<CreateFeedManifestResult>;
|
|
@@ -0,0 +1,70 @@
|
|
|
1
|
+
import { EthAddress, Topic } from "@ethersphere/bee-js";
|
|
2
|
+
import type { ChunkDownloader } from "../../download-data";
|
|
3
|
+
import type { EpochFinder, EpochLookupResult } from "./types";
|
|
4
|
+
/**
|
|
5
|
+
* Async concurrent finder for epoch-based feeds
|
|
6
|
+
*
|
|
7
|
+
* Launches parallel chunk fetches along the epoch tree path
|
|
8
|
+
* to find the feed update valid at a specific timestamp.
|
|
9
|
+
*
|
|
10
|
+
* Implements the EpochFinder interface.
|
|
11
|
+
*/
|
|
12
|
+
export declare class AsyncEpochFinder implements EpochFinder {
|
|
13
|
+
private readonly bee;
|
|
14
|
+
private readonly topic;
|
|
15
|
+
private readonly owner;
|
|
16
|
+
private readonly encryptionKey?;
|
|
17
|
+
constructor(bee: ChunkDownloader, topic: Topic, owner: EthAddress, encryptionKey?: Uint8Array | undefined);
|
|
18
|
+
/**
|
|
19
|
+
* Find the feed update valid at time `at`
|
|
20
|
+
* @param at - Target unix timestamp (seconds)
|
|
21
|
+
* @param after - Hint of latest known update timestamp (0 if unknown)
|
|
22
|
+
* @returns 32-byte Swarm reference, or undefined if no update found
|
|
23
|
+
*/
|
|
24
|
+
findAt(at: bigint, after?: bigint): Promise<Uint8Array | undefined>;
|
|
25
|
+
/**
|
|
26
|
+
* Recursively find update at epoch, with parallel fetching
|
|
27
|
+
*
|
|
28
|
+
* @param at - Target timestamp
|
|
29
|
+
* @param epoch - Current epoch to check
|
|
30
|
+
* @param currentBest - Best result found so far
|
|
31
|
+
* @returns Reference if found, undefined otherwise
|
|
32
|
+
*/
|
|
33
|
+
private findAtEpoch;
|
|
34
|
+
/**
|
|
35
|
+
* Fetch chunk for a specific epoch
|
|
36
|
+
*
|
|
37
|
+
* @param at - Target timestamp for validation
|
|
38
|
+
* @param epoch - Epoch to fetch
|
|
39
|
+
* @returns Chunk payload
|
|
40
|
+
* @throws Error if chunk not found
|
|
41
|
+
*/
|
|
42
|
+
private getEpochChunk;
|
|
43
|
+
/**
|
|
44
|
+
* Find the feed update valid at time `at` with full metadata
|
|
45
|
+
* Used by updater to calculate next epoch when no hints provided
|
|
46
|
+
*
|
|
47
|
+
* @param at - Target unix timestamp (seconds)
|
|
48
|
+
* @returns EpochLookupResult with reference, epoch, and timestamp, or undefined if no update found
|
|
49
|
+
*/
|
|
50
|
+
findAtWithMetadata(at: bigint): Promise<EpochLookupResult | undefined>;
|
|
51
|
+
/**
|
|
52
|
+
* Recursively find update at epoch with full metadata tracking
|
|
53
|
+
*
|
|
54
|
+
* @param at - Target timestamp
|
|
55
|
+
* @param epoch - Current epoch to check
|
|
56
|
+
* @param currentBest - Best result found so far
|
|
57
|
+
* @returns EpochLookupResult if found, undefined otherwise
|
|
58
|
+
*/
|
|
59
|
+
private findAtEpochWithMetadata;
|
|
60
|
+
/**
|
|
61
|
+
* Fetch chunk for a specific epoch and return full metadata
|
|
62
|
+
*
|
|
63
|
+
* @param at - Target timestamp for validation
|
|
64
|
+
* @param epoch - Epoch to fetch
|
|
65
|
+
* @returns Object with reference and timestamp, or undefined if timestamp > at
|
|
66
|
+
* @throws Error if chunk not found
|
|
67
|
+
*/
|
|
68
|
+
private getEpochChunkWithMetadata;
|
|
69
|
+
private findPreviousLeaf;
|
|
70
|
+
}
|
|
@@ -0,0 +1,79 @@
|
|
|
1
|
+
/** Maximum epoch level (2^32 seconds ≈ 136 years) */
|
|
2
|
+
export declare const MAX_LEVEL = 32;
|
|
3
|
+
/**
|
|
4
|
+
* Epoch interface - represents a time slot in the epoch tree
|
|
5
|
+
*/
|
|
6
|
+
export interface Epoch {
|
|
7
|
+
start: bigint;
|
|
8
|
+
level: number;
|
|
9
|
+
}
|
|
10
|
+
/**
|
|
11
|
+
* EpochIndex class - implements epoch-based feed indexing
|
|
12
|
+
*
|
|
13
|
+
* Each epoch represents a time range:
|
|
14
|
+
* - start: beginning timestamp of the epoch
|
|
15
|
+
* - level: determines the epoch's time span (2^level seconds)
|
|
16
|
+
*
|
|
17
|
+
* Epochs form a binary tree structure for efficient sparse updates.
|
|
18
|
+
*/
|
|
19
|
+
export declare class EpochIndex implements Epoch {
|
|
20
|
+
readonly start: bigint;
|
|
21
|
+
readonly level: number;
|
|
22
|
+
constructor(start: bigint, level: number);
|
|
23
|
+
/**
|
|
24
|
+
* Marshal epoch to binary format for hashing
|
|
25
|
+
* Returns Keccak256 hash of start (8 bytes big-endian) + level (1 byte)
|
|
26
|
+
*/
|
|
27
|
+
marshalBinary(): Promise<Uint8Array>;
|
|
28
|
+
/**
|
|
29
|
+
* Calculate the next epoch for a new update
|
|
30
|
+
* @param last - Timestamp of last update
|
|
31
|
+
* @param at - Timestamp of new update
|
|
32
|
+
*/
|
|
33
|
+
next(last: bigint, at: bigint): EpochIndex;
|
|
34
|
+
/**
|
|
35
|
+
* Calculate epoch length in seconds (2^level)
|
|
36
|
+
*/
|
|
37
|
+
length(): bigint;
|
|
38
|
+
/**
|
|
39
|
+
* Get parent epoch
|
|
40
|
+
* UNSAFE: Do not call on top-level epoch (level 32)
|
|
41
|
+
*/
|
|
42
|
+
parent(): EpochIndex;
|
|
43
|
+
/**
|
|
44
|
+
* Get left sibling epoch
|
|
45
|
+
* UNSAFE: Do not call on left sibling (when start is aligned to 2*length)
|
|
46
|
+
*/
|
|
47
|
+
left(): EpochIndex;
|
|
48
|
+
/**
|
|
49
|
+
* Get child epoch containing timestamp `at`
|
|
50
|
+
* UNSAFE: Do not call with `at` outside this epoch's range
|
|
51
|
+
*/
|
|
52
|
+
childAt(at: bigint): EpochIndex;
|
|
53
|
+
/**
|
|
54
|
+
* Check if this epoch is a left child of its parent
|
|
55
|
+
*/
|
|
56
|
+
isLeft(): boolean;
|
|
57
|
+
/**
|
|
58
|
+
* String representation: "start/level"
|
|
59
|
+
*/
|
|
60
|
+
toString(): string;
|
|
61
|
+
}
|
|
62
|
+
/**
|
|
63
|
+
* Calculate Lowest Common Ancestor epoch for two timestamps
|
|
64
|
+
*
|
|
65
|
+
* The LCA is the smallest epoch that contains both `at` and `after`.
|
|
66
|
+
* This is used to find the optimal starting point for feed lookups.
|
|
67
|
+
*
|
|
68
|
+
* @param at - Target timestamp
|
|
69
|
+
* @param after - Reference timestamp (0 if no previous update)
|
|
70
|
+
* @returns LCA epoch
|
|
71
|
+
*/
|
|
72
|
+
export declare function lca(at: bigint, after: bigint): EpochIndex;
|
|
73
|
+
/**
|
|
74
|
+
* Helper function to get next epoch for update, handling null previous epoch
|
|
75
|
+
* @param prevEpoch - Previous epoch (null if first update)
|
|
76
|
+
* @param last - Timestamp of last update
|
|
77
|
+
* @param at - Timestamp of new update
|
|
78
|
+
*/
|
|
79
|
+
export declare function next(prevEpoch: EpochIndex | undefined, last: bigint, at: bigint): EpochIndex;
|
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
import { EthAddress, Topic } from "@ethersphere/bee-js";
|
|
2
|
+
import type { ChunkDownloader } from "../../download-data";
|
|
3
|
+
import type { EpochFinder } from "./types";
|
|
4
|
+
/**
|
|
5
|
+
* Synchronous recursive finder for epoch-based feeds
|
|
6
|
+
*
|
|
7
|
+
* Traverses the epoch tree recursively to find the feed update
|
|
8
|
+
* valid at a specific timestamp.
|
|
9
|
+
*
|
|
10
|
+
* Implements the EpochFinder interface.
|
|
11
|
+
*/
|
|
12
|
+
export declare class SyncEpochFinder implements EpochFinder {
|
|
13
|
+
private readonly bee;
|
|
14
|
+
private readonly topic;
|
|
15
|
+
private readonly owner;
|
|
16
|
+
constructor(bee: ChunkDownloader, topic: Topic, owner: EthAddress);
|
|
17
|
+
/**
|
|
18
|
+
* Find the feed update valid at time `at`
|
|
19
|
+
* @param at - Target unix timestamp (seconds)
|
|
20
|
+
* @param after - Hint of latest known update timestamp (0 if unknown)
|
|
21
|
+
* @returns 32-byte Swarm reference, or undefined if no update found
|
|
22
|
+
*/
|
|
23
|
+
findAt(at: bigint, after?: bigint): Promise<Uint8Array | undefined>;
|
|
24
|
+
/**
|
|
25
|
+
* Find the lowest common ancestor epoch with an existing chunk
|
|
26
|
+
*
|
|
27
|
+
* Traverses UP the epoch tree from the LCA until finding a chunk,
|
|
28
|
+
* or reaching the top level.
|
|
29
|
+
*
|
|
30
|
+
* @param at - Target timestamp
|
|
31
|
+
* @param after - Reference timestamp
|
|
32
|
+
* @returns Epoch and chunk found at that epoch (if any)
|
|
33
|
+
*/
|
|
34
|
+
private common;
|
|
35
|
+
/**
|
|
36
|
+
* Recursive descent to find exact update at timestamp
|
|
37
|
+
*
|
|
38
|
+
* Traverses DOWN the epoch tree, handling left/right branches
|
|
39
|
+
* to find the most recent update not later than `at`.
|
|
40
|
+
*
|
|
41
|
+
* @param at - Target timestamp
|
|
42
|
+
* @param epoch - Current epoch being examined
|
|
43
|
+
* @param currentChunk - Best chunk found so far
|
|
44
|
+
* @returns Final chunk reference, or undefined
|
|
45
|
+
*/
|
|
46
|
+
private atEpoch;
|
|
47
|
+
/**
|
|
48
|
+
* Fetch chunk for a specific epoch
|
|
49
|
+
*
|
|
50
|
+
* Calculates the chunk address from topic, epoch, and owner,
|
|
51
|
+
* then downloads it from the Bee node.
|
|
52
|
+
*
|
|
53
|
+
* @param at - Target timestamp for validation
|
|
54
|
+
* @param epoch - Epoch to fetch
|
|
55
|
+
* @returns Chunk reference (32 or 64 bytes), or undefined if timestamp invalid
|
|
56
|
+
* @throws Error if chunk not found or network error
|
|
57
|
+
*/
|
|
58
|
+
private getEpochChunk;
|
|
59
|
+
private findPreviousLeaf;
|
|
60
|
+
}
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Epoch-Based Feeds
|
|
3
|
+
*
|
|
4
|
+
* Time-based feed indexing using a binary tree structure for efficient
|
|
5
|
+
* sparse updates across long time periods.
|
|
6
|
+
*/
|
|
7
|
+
export { EpochIndex, lca, next, MAX_LEVEL, type Epoch } from "./epoch";
|
|
8
|
+
export type { EpochFinder, EpochUpdater, EpochFeedOptions, EpochFeedWriterOptions, EpochLookupResult, } from "./types";
|
|
9
|
+
export { SyncEpochFinder } from "./finder";
|
|
10
|
+
export { AsyncEpochFinder } from "./async-finder";
|
|
11
|
+
export { BasicEpochUpdater, epochSocAddress, makeEpochIdentifier, } from "./updater";
|
|
12
|
+
import type { EpochFinder, EpochUpdater, EpochFeedOptions, EpochFeedWriterOptions } from "./types";
|
|
13
|
+
/**
|
|
14
|
+
* Create a synchronous epoch feed finder (non-concurrent)
|
|
15
|
+
*
|
|
16
|
+
* @returns EpochFinder implementation
|
|
17
|
+
*/
|
|
18
|
+
export declare function createSyncEpochFinder(options: EpochFeedOptions): EpochFinder;
|
|
19
|
+
/**
|
|
20
|
+
* Create an async epoch feed finder (concurrent)
|
|
21
|
+
*
|
|
22
|
+
* @returns EpochFinder implementation
|
|
23
|
+
*/
|
|
24
|
+
export declare function createAsyncEpochFinder(options: EpochFeedOptions): EpochFinder;
|
|
25
|
+
/**
|
|
26
|
+
* Create an epoch feed updater
|
|
27
|
+
*
|
|
28
|
+
* @returns EpochUpdater implementation
|
|
29
|
+
*/
|
|
30
|
+
export declare function createEpochUpdater(options: EpochFeedWriterOptions): EpochUpdater;
|
|
@@ -0,0 +1,110 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Types for Epoch-Based Feeds
|
|
3
|
+
*/
|
|
4
|
+
import type { EthAddress, Topic, PrivateKey } from "@ethersphere/bee-js";
|
|
5
|
+
import type { ChunkDownloader } from "../../download-data";
|
|
6
|
+
import type { UploadTarget } from "../../upload";
|
|
7
|
+
import type { EpochIndex } from "./epoch";
|
|
8
|
+
/**
|
|
9
|
+
* Options for creating an epoch feed reader
|
|
10
|
+
*/
|
|
11
|
+
export interface EpochFeedOptions {
|
|
12
|
+
/** Chunk reader — a `Bee`, or anything else that can `downloadChunk` */
|
|
13
|
+
bee: ChunkDownloader;
|
|
14
|
+
/** Feed topic (32 bytes) */
|
|
15
|
+
topic: Topic;
|
|
16
|
+
/** Feed owner address */
|
|
17
|
+
owner: EthAddress;
|
|
18
|
+
/** Optional encryption key for encrypted feed updates */
|
|
19
|
+
encryptionKey?: Uint8Array;
|
|
20
|
+
}
|
|
21
|
+
/**
|
|
22
|
+
* Options for creating an epoch feed writer
|
|
23
|
+
*/
|
|
24
|
+
export interface EpochFeedWriterOptions extends EpochFeedOptions {
|
|
25
|
+
/** Private key for signing chunks */
|
|
26
|
+
signer: PrivateKey;
|
|
27
|
+
}
|
|
28
|
+
/**
|
|
29
|
+
* Result from an epoch feed lookup
|
|
30
|
+
*/
|
|
31
|
+
export interface EpochLookupResult {
|
|
32
|
+
/** Swarm reference (32 bytes) */
|
|
33
|
+
reference: Uint8Array;
|
|
34
|
+
/** Epoch where the update was found */
|
|
35
|
+
epoch: EpochIndex;
|
|
36
|
+
/** Timestamp of the update */
|
|
37
|
+
timestamp: bigint;
|
|
38
|
+
}
|
|
39
|
+
/**
|
|
40
|
+
* Hints for calculating the next epoch in a stateless manner.
|
|
41
|
+
* Callers should store these after each update and pass them to subsequent updates.
|
|
42
|
+
*/
|
|
43
|
+
export interface EpochUpdateHints {
|
|
44
|
+
/** Previous epoch (for calculating next) */
|
|
45
|
+
lastEpoch?: {
|
|
46
|
+
start: bigint;
|
|
47
|
+
level: number;
|
|
48
|
+
};
|
|
49
|
+
/** Timestamp of last update */
|
|
50
|
+
lastTimestamp?: bigint;
|
|
51
|
+
}
|
|
52
|
+
/**
|
|
53
|
+
* Result from an epoch feed update, including epoch info for subsequent updates.
|
|
54
|
+
*/
|
|
55
|
+
export interface EpochUpdateResult {
|
|
56
|
+
/** SOC address of the uploaded chunk */
|
|
57
|
+
socAddress: Uint8Array;
|
|
58
|
+
/** Epoch used for this update (for caller to store as hint) */
|
|
59
|
+
epoch: {
|
|
60
|
+
start: bigint;
|
|
61
|
+
level: number;
|
|
62
|
+
};
|
|
63
|
+
/** Timestamp used (for caller to store as hint) */
|
|
64
|
+
timestamp: bigint;
|
|
65
|
+
}
|
|
66
|
+
/**
|
|
67
|
+
* Interface for epoch feed finders (readers)
|
|
68
|
+
*
|
|
69
|
+
* Implementations: SyncEpochFinder, AsyncEpochFinder
|
|
70
|
+
*/
|
|
71
|
+
export interface EpochFinder {
|
|
72
|
+
/**
|
|
73
|
+
* Find the feed update valid at time `at`
|
|
74
|
+
*
|
|
75
|
+
* @param at - Target unix timestamp (seconds)
|
|
76
|
+
* @param after - Hint of latest known update timestamp (0 if unknown)
|
|
77
|
+
* @returns 32 or 64-byte Swarm reference, or undefined if no update found
|
|
78
|
+
*/
|
|
79
|
+
findAt(at: bigint, after?: bigint): Promise<Uint8Array | undefined>;
|
|
80
|
+
}
|
|
81
|
+
/**
|
|
82
|
+
* Interface for epoch feed updaters (writers)
|
|
83
|
+
*
|
|
84
|
+
* Implementation: BasicEpochUpdater
|
|
85
|
+
*
|
|
86
|
+
* Implements Bee-compatible stateless epoch calculation.
|
|
87
|
+
* Each update uses hints from the previous update to calculate the next epoch,
|
|
88
|
+
* creating a proper epoch tree that Bee's finder can traverse.
|
|
89
|
+
*/
|
|
90
|
+
export interface EpochUpdater {
|
|
91
|
+
/**
|
|
92
|
+
* Update feed with a reference at given timestamp
|
|
93
|
+
*
|
|
94
|
+
* Calculates the appropriate epoch based on hints:
|
|
95
|
+
* - First update (no hints): uses root epoch (level 32, start 0)
|
|
96
|
+
* - Subsequent updates: calculates next epoch using LCA-based algorithm
|
|
97
|
+
*
|
|
98
|
+
* @param at - Unix timestamp for this update (seconds)
|
|
99
|
+
* @param reference - 32 or 64-byte Swarm reference to store
|
|
100
|
+
* @param target - Upload target (stamper or subsidised gateway)
|
|
101
|
+
* @param encryptionKey - Optional encryption key for the update
|
|
102
|
+
* @param hints - Optional hints from previous update for calculating epoch
|
|
103
|
+
* @returns Update result with SOC address and epoch info for next update
|
|
104
|
+
*/
|
|
105
|
+
update(at: bigint, reference: Uint8Array, target: UploadTarget, encryptionKey?: Uint8Array, hints?: EpochUpdateHints): Promise<EpochUpdateResult>;
|
|
106
|
+
/**
|
|
107
|
+
* Get the owner address (derived from signer)
|
|
108
|
+
*/
|
|
109
|
+
getOwner(): EthAddress;
|
|
110
|
+
}
|
|
@@ -0,0 +1,76 @@
|
|
|
1
|
+
import { EthAddress, Topic, PrivateKey, Identifier } from "@ethersphere/bee-js";
|
|
2
|
+
import { EpochIndex } from "./epoch";
|
|
3
|
+
import { type UploadTarget } from "../../upload";
|
|
4
|
+
import type { EpochUpdater, EpochUpdateHints, EpochUpdateResult } from "./types";
|
|
5
|
+
/**
|
|
6
|
+
* Build the SOC identifier for one epoch of a topic's epoch feed:
|
|
7
|
+
* `keccak256(topic ‖ epoch.marshalBinary())`. Exported so readers can
|
|
8
|
+
* reconstruct the SOC address of a feed entry they found (e.g. the
|
|
9
|
+
* partition-state reader compensates for the slot the entry's own SOC
|
|
10
|
+
* consumed).
|
|
11
|
+
*/
|
|
12
|
+
export declare function makeEpochIdentifier(topic: Topic, epoch: EpochIndex): Promise<Identifier>;
|
|
13
|
+
/**
|
|
14
|
+
* 32-byte SOC chunk address of one epoch-feed entry:
|
|
15
|
+
* `keccak256(identifier ‖ owner)` — same formula as every SOC address.
|
|
16
|
+
*/
|
|
17
|
+
export declare function epochSocAddress(topic: Topic, epoch: EpochIndex, owner: EthAddress): Promise<Uint8Array>;
|
|
18
|
+
/**
|
|
19
|
+
* Basic updater for epoch-based feeds
|
|
20
|
+
*
|
|
21
|
+
* Implements Bee-compatible stateless epoch calculation.
|
|
22
|
+
* Each update uses hints from the previous update to calculate the next epoch,
|
|
23
|
+
* creating a proper epoch tree that Bee's finder can traverse.
|
|
24
|
+
*
|
|
25
|
+
* - First update (no hints): uses root epoch (level 32, start 0)
|
|
26
|
+
* - Subsequent updates: calculates next epoch using the standard algorithm:
|
|
27
|
+
* - If new timestamp within previous epoch's range: dive to child
|
|
28
|
+
* - Else: jump to LCA(newTimestamp, prevTimestamp) and dive to child
|
|
29
|
+
*
|
|
30
|
+
* Implements the EpochUpdater interface.
|
|
31
|
+
*/
|
|
32
|
+
export declare class BasicEpochUpdater implements EpochUpdater {
|
|
33
|
+
private readonly topic;
|
|
34
|
+
private readonly signer;
|
|
35
|
+
constructor(topic: Topic, signer: PrivateKey);
|
|
36
|
+
/**
|
|
37
|
+
* Update feed with a reference at given timestamp
|
|
38
|
+
*
|
|
39
|
+
* @param at - Unix timestamp for this update (seconds)
|
|
40
|
+
* @param reference - 32 or 64-byte Swarm reference to store
|
|
41
|
+
* @param target - Upload target (stamper or subsidised gateway)
|
|
42
|
+
* @param encryptionKey - Optional encryption key for the update
|
|
43
|
+
* @param hints - Optional hints from previous update for calculating epoch
|
|
44
|
+
* @returns Update result with SOC address and epoch info for next update
|
|
45
|
+
*/
|
|
46
|
+
update(at: bigint, reference: Uint8Array, target: UploadTarget, encryptionKey?: Uint8Array, hints?: EpochUpdateHints): Promise<EpochUpdateResult>;
|
|
47
|
+
/**
|
|
48
|
+
* Calculate the epoch for this update based on hints or auto-lookup
|
|
49
|
+
*
|
|
50
|
+
* When hints are provided, uses them for fast epoch calculation.
|
|
51
|
+
* When no hints are provided and using stamper mode, looks up the current
|
|
52
|
+
* feed state to calculate the next epoch, preventing overwrites.
|
|
53
|
+
* In subsidised mode without hints, uses root epoch (first update).
|
|
54
|
+
*
|
|
55
|
+
* @param at - Timestamp for this update
|
|
56
|
+
* @param hints - Optional hints from previous update
|
|
57
|
+
* @param encryptionKey - Optional encryption key for looking up encrypted feeds
|
|
58
|
+
* @param target - Upload target for determining if auto-lookup is possible
|
|
59
|
+
* @returns Epoch to use for this update
|
|
60
|
+
*/
|
|
61
|
+
private calculateEpoch;
|
|
62
|
+
/**
|
|
63
|
+
* Get the owner address (derived from signer)
|
|
64
|
+
*/
|
|
65
|
+
getOwner(): EthAddress;
|
|
66
|
+
/**
|
|
67
|
+
* Upload a chunk for a specific epoch
|
|
68
|
+
*
|
|
69
|
+
* @param epoch - Epoch to upload to
|
|
70
|
+
* @param at - Timestamp of this update
|
|
71
|
+
* @param reference - 32 or 64-byte reference to store
|
|
72
|
+
* @param target - Upload target (stamper or subsidised gateway)
|
|
73
|
+
* @returns SOC chunk address for utilization tracking
|
|
74
|
+
*/
|
|
75
|
+
private uploadEpochChunk;
|
|
76
|
+
}
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Shared utilities for epoch feed finders
|
|
3
|
+
*/
|
|
4
|
+
import { EpochIndex } from "./epoch";
|
|
5
|
+
/**
|
|
6
|
+
* Type for the chunk fetcher callback used by findPreviousLeaf.
|
|
7
|
+
* This allows both sync and async finders to share the same logic.
|
|
8
|
+
*/
|
|
9
|
+
export type EpochChunkFetcher = (at: bigint, epoch: EpochIndex) => Promise<Uint8Array | undefined>;
|
|
10
|
+
/**
|
|
11
|
+
* Find a previous leaf chunk by scanning backwards from the target timestamp.
|
|
12
|
+
*
|
|
13
|
+
* This is a recovery fallback for poisoned-ancestor histories where the tree
|
|
14
|
+
* traversal fails but valid leaf nodes exist.
|
|
15
|
+
*
|
|
16
|
+
* @param at - Target unix timestamp (seconds)
|
|
17
|
+
* @param after - Hint of latest known update timestamp (0 if unknown)
|
|
18
|
+
* @param getEpochChunk - Callback function to fetch epoch chunks
|
|
19
|
+
* @returns 32-byte Swarm reference, or undefined if no update found
|
|
20
|
+
*/
|
|
21
|
+
export declare function findPreviousLeaf(at: bigint, after: bigint, getEpochChunk: EpochChunkFetcher): Promise<Uint8Array | undefined>;
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Async Sequential Feed Finder
|
|
3
|
+
*
|
|
4
|
+
* Currently delegates to the sync finder to match Go behavior
|
|
5
|
+
* while keeping an async interface.
|
|
6
|
+
*/
|
|
7
|
+
import type { EthAddress, Topic, BeeRequestOptions } from "@ethersphere/bee-js";
|
|
8
|
+
import type { ChunkDownloader } from "../../download-data";
|
|
9
|
+
import type { SequentialFinder, SequentialLookupResult } from "./types";
|
|
10
|
+
export declare class AsyncSequentialFinder implements SequentialFinder {
|
|
11
|
+
private readonly syncFinder;
|
|
12
|
+
constructor(bee: ChunkDownloader, topic: Topic, owner: EthAddress);
|
|
13
|
+
findAt(at: bigint, after?: bigint, requestOptions?: BeeRequestOptions): Promise<SequentialLookupResult>;
|
|
14
|
+
}
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import type { EthAddress, Topic, BeeRequestOptions } from "@ethersphere/bee-js";
|
|
2
|
+
import type { ChunkDownloader } from "../../download-data";
|
|
3
|
+
import type { SequentialFinder, SequentialLookupResult } from "./types";
|
|
4
|
+
export declare class SyncSequentialFinder implements SequentialFinder {
|
|
5
|
+
private readonly bee;
|
|
6
|
+
private readonly topic;
|
|
7
|
+
private readonly owner;
|
|
8
|
+
constructor(bee: ChunkDownloader, topic: Topic, owner: EthAddress);
|
|
9
|
+
findAt(_at: bigint, _after?: bigint, requestOptions?: BeeRequestOptions): Promise<SequentialLookupResult>;
|
|
10
|
+
private indexExists;
|
|
11
|
+
}
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Sequential Feeds
|
|
3
|
+
*
|
|
4
|
+
* Sequential feed indexing for versioned updates.
|
|
5
|
+
*/
|
|
6
|
+
export type { SequentialFeedOptions, SequentialFeedWriterOptions, SequentialLookupResult, SequentialFinder, SequentialUpdater, } from "./types";
|
|
7
|
+
export { SyncSequentialFinder } from "./finder";
|
|
8
|
+
export { AsyncSequentialFinder } from "./async-finder";
|
|
9
|
+
export { BasicSequentialUpdater } from "./updater";
|
|
10
|
+
import type { SequentialFeedOptions, SequentialFeedWriterOptions, SequentialFinder, SequentialUpdater } from "./types";
|
|
11
|
+
/**
|
|
12
|
+
* Create a synchronous sequential feed finder
|
|
13
|
+
*/
|
|
14
|
+
export declare function createSyncSequentialFinder(options: SequentialFeedOptions): SequentialFinder;
|
|
15
|
+
/**
|
|
16
|
+
* Create an async sequential feed finder
|
|
17
|
+
*/
|
|
18
|
+
export declare function createAsyncSequentialFinder(options: SequentialFeedOptions): SequentialFinder;
|
|
19
|
+
/**
|
|
20
|
+
* Create a sequential feed updater
|
|
21
|
+
*/
|
|
22
|
+
export declare function createSequentialUpdater(options: SequentialFeedWriterOptions): SequentialUpdater;
|
|
@@ -0,0 +1,82 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Types for Sequential Feeds
|
|
3
|
+
*/
|
|
4
|
+
import type { Bee, EthAddress, Topic, PrivateKey, Stamper, BeeRequestOptions } from "@ethersphere/bee-js";
|
|
5
|
+
import type { ChunkDownloader } from "../../download-data";
|
|
6
|
+
/**
|
|
7
|
+
* Options for creating a sequential feed reader
|
|
8
|
+
*/
|
|
9
|
+
export interface SequentialFeedOptions {
|
|
10
|
+
/** Chunk reader — a `Bee`, or anything else that can `downloadChunk` */
|
|
11
|
+
bee: ChunkDownloader;
|
|
12
|
+
/** Feed topic (32 bytes) */
|
|
13
|
+
topic: Topic;
|
|
14
|
+
/** Feed owner address */
|
|
15
|
+
owner: EthAddress;
|
|
16
|
+
}
|
|
17
|
+
/**
|
|
18
|
+
* Options for creating a sequential feed writer
|
|
19
|
+
*/
|
|
20
|
+
export interface SequentialFeedWriterOptions extends SequentialFeedOptions {
|
|
21
|
+
/** The writer uploads as well as reads, so it needs the whole client */
|
|
22
|
+
bee: Bee;
|
|
23
|
+
/** Private key for signing chunks */
|
|
24
|
+
signer: PrivateKey;
|
|
25
|
+
}
|
|
26
|
+
/**
|
|
27
|
+
* Result from sequential feed lookup
|
|
28
|
+
*/
|
|
29
|
+
export interface SequentialLookupResult {
|
|
30
|
+
/** Current (latest) index if found */
|
|
31
|
+
current?: bigint;
|
|
32
|
+
/** Next index to use */
|
|
33
|
+
next: bigint;
|
|
34
|
+
}
|
|
35
|
+
/**
|
|
36
|
+
* Interface for sequential feed finders (readers)
|
|
37
|
+
*
|
|
38
|
+
* Implementations: SyncSequentialFinder, AsyncSequentialFinder
|
|
39
|
+
*/
|
|
40
|
+
export interface SequentialFinder {
|
|
41
|
+
/**
|
|
42
|
+
* Find the latest feed update index
|
|
43
|
+
*
|
|
44
|
+
* @param at - Ignored for sequential feeds (for compatibility with Go API)
|
|
45
|
+
* @param after - Hint of latest known index (0 if unknown)
|
|
46
|
+
* @returns Lookup result with current and next index
|
|
47
|
+
*/
|
|
48
|
+
findAt(at: bigint, after?: bigint, requestOptions?: BeeRequestOptions): Promise<SequentialLookupResult>;
|
|
49
|
+
}
|
|
50
|
+
/**
|
|
51
|
+
* Interface for sequential feed updaters (writers)
|
|
52
|
+
*/
|
|
53
|
+
export interface SequentialUpdater {
|
|
54
|
+
/**
|
|
55
|
+
* Update feed with payload data
|
|
56
|
+
*
|
|
57
|
+
* @param payload - Payload to store
|
|
58
|
+
* @param stamper - Stamper object for stamping
|
|
59
|
+
* @returns SOC chunk address for utilization tracking
|
|
60
|
+
*/
|
|
61
|
+
update(payload: Uint8Array, stamper: Stamper, encryptionKey?: Uint8Array): Promise<Uint8Array>;
|
|
62
|
+
/**
|
|
63
|
+
* Get the owner address (derived from signer)
|
|
64
|
+
*/
|
|
65
|
+
getOwner(): EthAddress;
|
|
66
|
+
/**
|
|
67
|
+
* Get current state (for persistence/debugging)
|
|
68
|
+
*/
|
|
69
|
+
getState(): {
|
|
70
|
+
nextIndex: bigint;
|
|
71
|
+
};
|
|
72
|
+
/**
|
|
73
|
+
* Restore state (from persistence)
|
|
74
|
+
*/
|
|
75
|
+
setState(state: {
|
|
76
|
+
nextIndex: bigint;
|
|
77
|
+
}): void;
|
|
78
|
+
/**
|
|
79
|
+
* Reset updater state (useful for testing or reinitialization)
|
|
80
|
+
*/
|
|
81
|
+
reset(): void;
|
|
82
|
+
}
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
import type { Bee, Stamper } from "@ethersphere/bee-js";
|
|
2
|
+
import { EthAddress, Topic, PrivateKey } from "@ethersphere/bee-js";
|
|
3
|
+
import type { SequentialUpdater } from "./types";
|
|
4
|
+
export declare class BasicSequentialUpdater implements SequentialUpdater {
|
|
5
|
+
private readonly bee;
|
|
6
|
+
private readonly topic;
|
|
7
|
+
private readonly signer;
|
|
8
|
+
private nextIndex;
|
|
9
|
+
constructor(bee: Bee, topic: Topic, signer: PrivateKey);
|
|
10
|
+
update(payload: Uint8Array, stamper: Stamper, encryptionKey?: Uint8Array): Promise<Uint8Array>;
|
|
11
|
+
getOwner(): EthAddress;
|
|
12
|
+
getState(): {
|
|
13
|
+
nextIndex: bigint;
|
|
14
|
+
};
|
|
15
|
+
setState(state: {
|
|
16
|
+
nextIndex: bigint;
|
|
17
|
+
}): void;
|
|
18
|
+
reset(): void;
|
|
19
|
+
private makeIdentifier;
|
|
20
|
+
}
|
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
export * from "./types";
|
|
2
|
+
export * from "./chunking";
|
|
3
|
+
export { uploadData, uploadSOC, uploadChunk, isStamperTarget, isSubsidisedTarget, type UploadTarget, type UploadDataOptions, type UploadDataResult, type UploadSOCOptions, type UploadSOCResult, type UploadChunkOptions, type UploadChunkResult, } from "./upload";
|
|
4
|
+
export * from "./feeds";
|
|
5
|
+
export * from "./act";
|