SwarmIdClient API Reference
The SwarmIdClient is the main class for integrating Swarm ID authentication and storage capabilities into web applications. It enables parent windows to interact with a Swarm ID iframe proxy, providing secure authentication, identity management, and data upload/download functionality to the Swarm decentralized storage network.
Installation
pnpm add @snaha/swarm-idQuick Start
import { SwarmIdClient } from '@snaha/swarm-id'
const client = new SwarmIdClient({ iframeOrigin: 'https://swarm-id.example.com', metadata: { name: 'My App', description: 'A decentralized application', }, onAuthChange: (authenticated) => { console.log('Auth status changed:', authenticated) },})
await client.initialize()
// Option 1: Open authentication page manuallyawait client.connect()
// Option 2: Check authentication status and upload if authenticatedconst status = await client.checkAuthStatus()if (status.authenticated) { const result = await client.uploadData(new Uint8Array([1, 2, 3])) console.log('Uploaded with reference:', result.reference)}Constructor
new SwarmIdClient(options)
Creates a new SwarmIdClient instance.
Parameters:
| Parameter | Type | Required | Description |
|---|---|---|---|
options.iframeOrigin | string | Yes | The origin URL where the Swarm ID proxy iframe is hosted |
options.iframePath | string | No | The path to the proxy iframe (defaults to "/proxy") |
options.timeout | number | No | Request timeout in milliseconds (defaults to 30000) |
options.initializationTimeout | number | No | Initialization timeout in milliseconds (defaults to 30000) |
options.onAuthChange | (authenticated: boolean) => void | No | Callback function invoked when authentication status changes |
options.popupMode | "popup" | "window" | No | How to display the authentication popup (defaults to "window") |
options.metadata | AppMetadata | Yes | Application metadata shown to users during authentication |
options.metadata.name | string | Yes | Application name (1-100 characters) |
options.metadata.description | string | No | Application description (max 500 characters) |
options.metadata.icon | string | No | Application icon as a data URL (SVG or PNG, max 4KB) |
options.buttonConfig | ButtonConfig | No | Button configuration for the authentication UI |
options.containerId | string | No | ID of container element to place iframe in (optional) |
Throws: Error if the provided app metadata is invalid
Example:
const client = new SwarmIdClient({ iframeOrigin: 'https://id.swarm.example.com', timeout: 60000, metadata: { name: 'My dApp', description: 'A decentralized application built on Swarm', icon: 'data:image/svg+xml;base64,...', }, onAuthChange: (authenticated) => { updateUI(authenticated) },})Lifecycle Methods
initialize()
Initializes the client by creating and embedding the proxy iframe.
This method must be called before using any other client methods. It creates a hidden iframe, waits for the proxy to initialize, identifies the parent application to the proxy, and waits for the proxy to signal readiness.
Returns: Promise<void> - Resolves when the client is fully initialized
Throws:
Errorif the client is already initializedErrorif the iframe fails to loadErrorif the proxy does not respond within the initialization timeout period (configurable viainitializationTimeout, defaults to 30 seconds)Errorif origin validation fails on the proxy side
Example:
const client = new SwarmIdClient({ ... })try { await client.initialize() console.log('Client ready')} catch (error) { console.error('Failed to initialize:', error)}destroy()
Destroys the client and releases all resources.
This method should be called when the client is no longer needed. It performs the following cleanup:
- Cancels all pending requests with an error
- Removes the message event listener
- Removes the iframe from the DOM
- Resets the client to an uninitialized state
After calling destroy(), the client instance cannot be reused. Create a new instance if you need to reconnect.
Returns: void
Example:
// Clean up when component unmountsuseEffect(() => { const client = new SwarmIdClient({ ... }) client.initialize()
return () => { client.destroy() }}, [])Authentication Methods
getAuthIframe()
Returns the authentication iframe element.
The iframe displays authentication UI based on the current auth status:
- If not authenticated: shows a “Connect” button
- If authenticated: shows identity info and a “Disconnect” button
The iframe is positioned fixed in the bottom-right corner of the viewport.
Returns: HTMLIFrameElement - The iframe element displaying the authentication UI
Throws:
Errorif the client is not initializedErrorif the iframe is not available
Example:
const iframe = client.getAuthIframe()// The iframe is already displayed; this returns a reference to itButton Configuration
The authentication button in the iframe can be customized using the buttonConfig option in the constructor. This configuration allows you to customize the button text, colors, and styling.
ButtonConfig Interface:
interface ButtonConfig { connectText?: string disconnectText?: string loadingText?: string backgroundColor?: string color?: string borderRadius?: string}Example: Customizing Button Configuration
const client = new SwarmIdClient({ iframeOrigin: 'https://swarm-id.example.com', metadata: { name: 'My App', description: 'A decentralized application', }, buttonConfig: { connectText: 'Connect with Swarm', disconnectText: 'Disconnect', loadingText: 'Loading...', backgroundColor: '#4CAF50', color: 'white', borderRadius: '8px', }, onAuthChange: (authenticated) => { console.log('Auth status changed:', authenticated) },})
await client.initialize()ButtonConfig Properties:
| Property | Type | Required | Description | Default Value |
|---|---|---|---|---|
connectText | string | No | Text for the connect button | ”🔐 Login with Swarm ID” |
disconnectText | string | No | Text for the disconnect button | ”🔓 Disconnect from Swarm ID” |
loadingText | string | No | Text shown during loading | ”⏳ Loading…” |
backgroundColor | string | No | Background color for buttons | #dd7200 (connect), #666 (disconnect) |
color | string | No | Text color for buttons | white |
borderRadius | string | No | Border radius for buttons and iframe | 0 |
Notes:
- Button configuration is passed directly to the constructor, not via postMessage
- The
borderRadiusproperty affects both the buttons and the iframe container - Colors should be valid CSS color strings (e.g.,
'#FF0000','rgb(255, 0, 0)','red') - Text properties support plain text or emoji combinations
- The configuration applies to both authentication states (connect/disconnect)
Manual Authentication
In addition to the iframe-based authentication (via getAuthIframe()), you can manually trigger the authentication flow by calling connect(). This opens the same authentication URL in a new window:
// Open authentication page (default: new window)await client.connect()
// Open as popup windowawait client.connect({ popupMode: 'popup' })
// Open with agent sign-up option visibleawait client.connect({ agent: true })When to use connect():
- When you want to trigger authentication from a custom UI element
- When you prefer the authentication to open in a new window instead of an iframe
Authentication Flow:
- User calls
client.connect()or clicks the iframe button - Authentication page opens with the app metadata
- User authenticates with their Swarm ID
- Authentication state is shared with the iframe proxy
onAuthChangecallback is invoked withtrue
checkAuthStatus()
Checks the current authentication status with the Swarm ID proxy.
Returns: Promise<AuthStatus> - The authentication status object
| Property | Type | Description |
|---|---|---|
authenticated | boolean | Whether the user is currently authenticated |
origin | string | undefined | The origin that authenticated (if authenticated) |
Throws:
Errorif the client is not initializedErrorif the request times out
Example:
const status = await client.checkAuthStatus()if (status.authenticated) { console.log('Authenticated from:', status.origin)}connect(options?)
Opens Swarm ID authentication page in a new window.
This method creates the same authentication URL as used by the iframe proxy and opens it in a new browser window. The user can authenticate with their Swarm ID, and the resulting authentication will be available to the client when they return.
Parameters:
| Parameter | Type | Required | Description |
|---|---|---|---|
options | ConnectOptions | No | Configuration options for the authentication window |
options.popupMode | "window" | "popup" | No | Whether to open as a popup window (“popup”) or full window (“window”, default) |
options.agent | boolean | No | Whether to show the agent sign-up option on the authentication page |
ConnectOptions Interface:
interface ConnectOptions { popupMode?: 'popup' | 'window' // Default: "window" agent?: boolean // Shows agent sign-up option}Returns: Promise<void> - Resolves when the authentication popup has been opened
Throws:
Errorif the client is not initializedErrorif the popup fails to open
Example:
const client = new SwarmIdClient({ ... })await client.initialize()
// Open authentication page (default: new window)await client.connect()
// Open as popup windowawait client.connect({ popupMode: 'popup' })
// Open with agent sign-up option visibleawait client.connect({ agent: true })disconnect()
Disconnects the current session and clears authentication data.
After disconnection, the user will need to re-authenticate to perform uploads or access identity-related features. The onAuthChange callback will be invoked with false.
Returns: Promise<void> - Resolves when disconnection is complete
Throws:
Errorif the client is not initializedErrorif the disconnect operation failsErrorif the request times out
Example:
await client.disconnect()console.log('User logged out')getConnectionInfo()
Retrieves connection information including upload capability and identity details.
Use this method to check if the user can upload data and to get information about the currently connected identity.
Returns: Promise<ConnectionInfo> - The connection info object
| Property | Type | Description |
|---|---|---|
canUpload | boolean | Whether the user can upload data (has stamps and storage is not partitioned) |
storagePartitioned | boolean | undefined | true when browser storage partitioning prevents access to stamps/signer keys |
identity | object | undefined | The connected identity details (if authenticated) |
identity.id | string | Unique identifier for the identity |
identity.name | string | Display name of the identity |
identity.address | string | Ethereum address associated with the identity |
Throws:
Errorif the client is not initializedErrorif the request times out
Example:
const info = await client.getConnectionInfo()if (info.canUpload) { console.log('Ready to upload as:', info.identity?.name)} else if (info.storagePartitioned) { console.log('Storage partitioned — downloads only')} else { console.log('No postage stamp available')}getPostageBatch()
Gets the current postage batch for the authenticated identity.
Returns information about the postage stamp associated with the connected identity, including batch ID, utilization, depth, and TTL.
Returns: Promise<PostageBatch | undefined> - The postage batch info, or undefined if none is configured
| Property | Type | Description |
|---|---|---|
batchID | string | The batch ID (64 hex characters) |
utilization | number | Current utilization percentage |
usable | boolean | Whether the batch is usable |
label | string | Human-readable label |
depth | number | Batch depth |
amount | string | Batch amount |
bucketDepth | number | Bucket depth |
blockNumber | number | Block number when created |
immutableFlag | boolean | Whether the batch is immutable |
exists | boolean | Whether the batch exists |
batchTTL | number | undefined | Time-to-live in seconds |
Throws:
Errorif the client is not initializedErrorif the request times out
Example:
const batch = await client.getPostageBatch()if (batch) { console.log('Batch ID:', batch.batchID) console.log('Utilization:', batch.utilization) console.log('Depth:', batch.depth) console.log('TTL:', batch.batchTTL)} else { console.log('No postage batch configured')}Bee Connectivity Methods
isBeeConnected()
Checks whether the Bee node is reachable.
This method never throws an exception. If the client is not initialized, the request times out, or any other error occurs, it returns false.
Returns: Promise<boolean> - true if the Bee node is reachable, false otherwise
Example:
const connected = await client.isBeeConnected()if (connected) { console.log('Bee node is online')} else { console.log('Bee node is offline')}getNodeInfo()
Gets information about the Bee node configuration.
This method retrieves the current Bee node’s operating mode and feature flags. Use this to determine if deferred uploads are required (dev mode) or if direct uploads are available (production modes).
Returns: Promise<NodeInfo> - The node info object
| Property | Type | Description |
|---|---|---|
beeMode | string | The Bee node operating mode (“dev”, “light”, “full”, “ultra-light”) |
chequebookEnabled | boolean | Whether the chequebook is enabled |
swapEnabled | boolean | Whether SWAP is enabled |
Throws:
Errorif the client is not initializedErrorif the Bee node is not reachableErrorif the request times out
Example:
const nodeInfo = await client.getNodeInfo()if (nodeInfo.beeMode === 'dev') { // Dev mode requires deferred uploads await client.uploadData(data, { deferred: true })} else { // Production modes can use direct uploads await client.uploadData(data, { deferred: false })}Data Methods
uploadData(data, options?, requestOptions?)
Uploads raw binary data to the Swarm network.
The data is uploaded using the authenticated user’s postage stamp. Progress can be tracked via the options.onProgress callback.
Parameters:
| Parameter | Type | Required | Description |
|---|---|---|---|
data | Uint8Array | Yes | The binary data to upload |
options | UploadOptions | No | Upload configuration |
options.pin | boolean | No | Whether to pin the data locally (defaults to false) |
options.encrypt | boolean | No | Whether to encrypt the data (defaults to false) |
options.tag | number | No | Tag ID for tracking upload progress |
options.deferred | boolean | No | Whether to use deferred upload (defaults to false) |
options.redundancyLevel | 0-4 | No | Redundancy level for data availability |
options.onProgress | (progress) => void | No | Callback for tracking upload progress |
requestOptions | RequestOptions | No | Request configuration |
requestOptions.timeout | number | No | Request timeout in milliseconds |
requestOptions.headers | Record<string, string> | No | Custom headers |
requestOptions.endlesslyRetry | boolean | No | Whether to retry endlessly |
Returns: Promise<UploadResult>
| Property | Type | Description |
|---|---|---|
reference | string | The Swarm reference (hash) of the uploaded data |
tagUid | number | undefined | The tag UID if a tag was created |
Throws:
Errorif the client is not initializedErrorif the user is not authenticated or cannot uploadErrorif the request times out
Example:
const data = new TextEncoder().encode('Hello, Swarm!')const result = await client.uploadData(data, { encrypt: true, onProgress: (progress) => { console.log(`Progress: ${progress.processed}/${progress.total}`) },})console.log('Reference:', result.reference)downloadData(reference, options?, requestOptions?)
Downloads raw binary data from the Swarm network.
Parameters:
| Parameter | Type | Required | Description |
|---|---|---|---|
reference | string | Yes | The Swarm reference (64 or 128 hex chars) |
options | DownloadOptions | No | Download configuration |
options.redundancyStrategy | 0-3 | No | Strategy for handling redundancy |
options.fallback | boolean | No | Whether to use fallback retrieval |
options.timeoutMs | number | No | Download timeout in milliseconds |
options.actPublisher | Uint8Array | string | No | ACT publisher for encrypted content |
options.actHistoryAddress | Uint8Array | string | No | ACT history address for encrypted content |
options.actTimestamp | number | string | No | ACT timestamp for encrypted content |
requestOptions | RequestOptions | No | Request configuration |
requestOptions.timeout | number | No | Request timeout in milliseconds |
requestOptions.headers | Record<string, string> | No | Custom headers |
requestOptions.endlesslyRetry | boolean | No | Whether to retry endlessly |
Returns: Promise<Uint8Array> - The downloaded data
Throws:
Errorif the client is not initializedErrorif the reference is not foundErrorif the request times out
Example:
const data = await client.downloadData('a1b2c3...') // 64 char hex referenceconst text = new TextDecoder().decode(data)console.log('Downloaded:', text)File Methods
uploadFile(file, name?, options?, requestOptions?)
Uploads a file to the Swarm network.
Accepts either a File object (from file input) or raw Uint8Array data. When using a File object, the filename is automatically extracted unless explicitly overridden.
Parameters:
| Parameter | Type | Required | Description |
|---|---|---|---|
file | File | Uint8Array | Yes | The file to upload |
name | string | No | Filename (extracted from File object if not provided) |
options | UploadOptions | No | Upload configuration (see uploadData) |
requestOptions | RequestOptions | No | Request configuration |
requestOptions.timeout | number | No | Request timeout in milliseconds |
requestOptions.headers | Record<string, string> | No | Custom headers |
requestOptions.endlesslyRetry | boolean | No | Whether to retry endlessly |
Returns: Promise<UploadResult> - Contains reference and optional tagUid
Throws:
Errorif the client is not initializedErrorif the user is not authenticated or cannot uploadErrorif the request times out
Example:
// From file inputconst fileInput = document.querySelector('input[type="file"]')const file = fileInput.files[0]const result = await client.uploadFile(file)
// From Uint8Array with custom nameconst data = new Uint8Array([...])const result = await client.uploadFile(data, 'document.pdf')downloadFile(reference, path?, options?, requestOptions?)
Downloads a file from the Swarm network.
Returns both the file data and its original filename (if available). For manifest references, an optional path can be specified to retrieve a specific file from the manifest.
Parameters:
| Parameter | Type | Required | Description |
|---|---|---|---|
reference | string | Yes | The Swarm reference of the file |
path | string | No | Path within a manifest to retrieve a specific file |
options | DownloadOptions | No | Download configuration (see downloadData) |
requestOptions | RequestOptions | No | Request configuration |
requestOptions.timeout | number | No | Request timeout in milliseconds |
requestOptions.headers | Record<string, string> | No | Custom headers |
requestOptions.endlesslyRetry | boolean | No | Whether to retry endlessly |
Returns: Promise<FileData>
| Property | Type | Description |
|---|---|---|
name | string | The filename |
data | Uint8Array | The file contents |
Throws:
Errorif the client is not initializedErrorif the reference is not foundErrorif the request times out
Example:
const file = await client.downloadFile('a1b2c3...')console.log('Filename:', file.name)
// Create download linkconst blob = new Blob([file.data])const url = URL.createObjectURL(blob)Chunk Methods
uploadChunk(data, options?, requestOptions?)
Uploads a single chunk to the Swarm network.
Chunks are the fundamental unit of storage in Swarm (4KB each). This method is useful for low-level operations or when implementing custom chunking strategies.
Parameters:
| Parameter | Type | Required | Description |
|---|---|---|---|
data | Uint8Array | Yes | The chunk data (should be exactly 4KB for optimal storage) |
options | UploadOptions | No | Upload configuration (see uploadData) |
requestOptions | RequestOptions | No | Request configuration |
requestOptions.timeout | number | No | Request timeout in milliseconds |
requestOptions.headers | Record<string, string> | No | Custom headers |
requestOptions.endlesslyRetry | boolean | No | Whether to retry endlessly |
Returns: Promise<UploadResult> - Contains the reference of the uploaded chunk
Throws:
Errorif the client is not initializedErrorif the user is not authenticated or cannot uploadErrorif the request times out
Example:
const chunk = new Uint8Array(4096) // 4KB chunkchunk.fill(0x42) // Fill with dataconst result = await client.uploadChunk(chunk)console.log('Chunk reference:', result.reference)downloadChunk(reference, options?, requestOptions?)
Downloads a single chunk from the Swarm network.
Retrieves a chunk by its reference hash. This method is useful for low-level operations or when implementing custom retrieval strategies.
Parameters:
| Parameter | Type | Required | Description |
|---|---|---|---|
reference | string | Yes | The Swarm reference of the chunk |
options | DownloadOptions | No | Download configuration (see downloadData) |
requestOptions | RequestOptions | No | Request configuration |
requestOptions.timeout | number | No | Request timeout in milliseconds |
requestOptions.headers | Record<string, string> | No | Custom headers |
requestOptions.endlesslyRetry | boolean | No | Whether to retry endlessly |
Returns: Promise<Uint8Array> - The chunk data
Throws:
Errorif the client is not initializedErrorif the reference is not foundErrorif the request times out
Example:
const chunk = await client.downloadChunk('a1b2c3...')console.log('Chunk size:', chunk.length)SOC Methods
SOC (Single Owner Chunk) methods provide read/write helpers for SOCs, which are signed chunks owned by an Ethereum address. Uploads via SOCWriter.upload are encrypted by default and return an encryptionKey for later decryption.
makeSOCReader(ownerAddress, requestOptions?)
Creates an SOC reader bound to the given owner address.
Parameters:
| Parameter | Type | Required | Description |
|---|---|---|---|
ownerAddress | string | Yes | Ethereum address of the SOC owner |
requestOptions | RequestOptions | No | Request configuration |
requestOptions.timeout | number | No | Request timeout in milliseconds |
requestOptions.headers | Record<string, string> | No | Custom headers |
requestOptions.endlesslyRetry | boolean | No | Whether to retry endlessly |
Returns: SOCReader
| Method | Description |
|---|---|
getOwner() | Resolves the SOC owner address |
download(identifier, encryptionKey) | Downloads and decrypts an encrypted SOC |
rawDownload(identifier, encryptionKey?) | Downloads an unencrypted SOC, or decrypts if encryptionKey is provided |
Throws:
Errorif the client is not initializedErrorif the request times out
Example:
const owner = '0x1234...'const reader = client.makeSOCReader(owner)const resolvedOwner = await reader.getOwner()const soc = await reader.download(identifier, encryptionKey)console.log('Payload:', new TextDecoder().decode(soc.payload))makeSOCWriter(signer?, requestOptions?)
Creates an SOC writer for uploading and downloading SOCs. If signer is omitted, the proxy uses the app signer.
Parameters:
| Parameter | Type | Required | Description |
|---|---|---|---|
signer | string | No | Private key hex string for the SOC signer |
requestOptions | RequestOptions | No | Request configuration |
requestOptions.timeout | number | No | Request timeout in milliseconds |
requestOptions.headers | Record<string, string> | No | Custom headers |
requestOptions.endlesslyRetry | boolean | No | Whether to retry endlessly |
Returns: SOCWriter
| Method | Description |
|---|---|
getOwner() | Resolves the SOC owner address |
upload(identifier, data, options?) | Uploads an encrypted SOC |
rawUpload(identifier, data, options?) | Uploads an unencrypted SOC |
download(identifier, encryptionKey) | Downloads and decrypts an encrypted SOC |
rawDownload(identifier, encryptionKey?) | Downloads an unencrypted SOC, or decrypts if encryptionKey is provided |
Returns (upload): Promise<SocUploadResult>
| Property | Type | Description |
|---|---|---|
reference | string | SOC chunk reference |
owner | string | SOC owner address |
encryptionKey | string | Encryption key for decrypting the SOC |
tagUid | number | Upload tag UID, if provided |
Returns (rawUpload): Promise<SocRawUploadResult>
| Property | Type | Description |
|---|---|---|
reference | string | SOC chunk reference |
owner | string | SOC owner address |
encryptionKey | string | Optional; present only if returned by proxy |
tagUid | number | Upload tag UID, if provided |
Throws:
Errorif the client is not initializedErrorif the request times out
Example:
const writer = client.makeSOCWriter()const payload = new TextEncoder().encode('Hello SOC')const upload = await writer.upload(identifier, payload)
const owner = await writer.getOwner()const soc = await writer.download(identifier, upload.encryptionKey)console.log('Owner:', soc.owner)SOC Payload Structure (download methods): SingleOwnerChunk
| Property | Type | Description |
|---|---|---|
data | Uint8Array | Full SOC chunk data |
identifier | string | SOC identifier |
signature | string | SOC signature |
span | number | Payload span (bytes) |
payload | Uint8Array | SOC payload data |
address | string | SOC address/reference |
owner | string | SOC owner address |
Epoch Feed Methods
Epoch feed methods provide time-indexed updates backed by Single Owner Chunks (SOCs). Feed updates are addressed by (topic, owner) and can be looked up by timestamp. The interface mirrors sequential feeds with upload and download helpers.
makeEpochFeedReader(options, requestOptions?)
Creates a feed reader bound to a topic and optional owner.
Parameters:
| Parameter | Type | Required | Description |
|---|---|---|---|
options.topic | string | Yes | Feed topic (32-byte hex string) |
options.owner | string | No | Feed owner address; if omitted, resolved via proxy |
requestOptions | RequestOptions | No | Request configuration |
requestOptions.timeout | number | No | Request timeout in milliseconds |
requestOptions.headers | Record<string, string> | No | Custom headers |
requestOptions.endlesslyRetry | boolean | No | Whether to retry endlessly |
Returns: FeedReader
FeedReader
| Method | Description |
|---|---|
getOwner() | Resolves the feed owner address |
downloadReference(options?) | Returns the reference for timestamp options.at (requires encryption key) |
downloadPayload(options?) | Downloads payload data for timestamp options.at (requires encryption key) |
downloadRawReference(options?) | Returns unencrypted reference for timestamp options.at (for /bzz access) |
downloadRawPayload(options?) | Downloads unencrypted payload for timestamp options.at (for /bzz access) |
Epoch download options (options):
| Option | Type | Required | Description |
|---|---|---|---|
at | number | string | bigint | No | Unix timestamp (seconds); defaults to current time |
after | number | string | bigint | No | Hint for latest known update timestamp |
encryptionKey | Uint8Array | string | No | Encryption key for encrypted feed updates |
Returns (downloadReference):
| Property | Type | Description |
|---|---|---|
reference | string | undefined | Swarm reference (hex) if found |
encryptionKey | string | undefined | Encryption key (hex) if reference is encrypted |
Returns (downloadPayload):
| Property | Type | Description |
|---|---|---|
payload | Uint8Array | undefined | Payload bytes if found |
reference | string | undefined | Swarm reference (hex) if found |
encryptionKey | string | undefined | Encryption key (hex) if reference is encrypted |
Example:
const reader = client.makeEpochFeedReader({ topic })const owner = await reader.getOwner()const reference = await reader.downloadReference({ at: BigInt(Math.floor(Date.now() / 1000)) })const payload = await reader.downloadPayload({ at: BigInt(Math.floor(Date.now() / 1000)) })makeEpochFeedWriter(options, requestOptions?)
Creates a feed writer for updating and reading a topic. If signer is omitted, the proxy uses the app signer.
Parameters:
| Parameter | Type | Required | Description |
|---|---|---|---|
options.topic | string | Yes | Feed topic (32-byte hex string) |
options.signer | string | No | Private key hex string for the feed signer |
requestOptions | RequestOptions | No | Request configuration |
requestOptions.timeout | number | No | Request timeout in milliseconds |
requestOptions.headers | Record<string, string> | No | Custom headers |
requestOptions.endlesslyRetry | boolean | No | Whether to retry endlessly |
Returns: FeedWriter
FeedWriter
| Method | Description |
|---|---|
getOwner() | Resolves the feed owner address |
downloadReference(options?) | Returns the reference for timestamp options.at (requires encryption key) |
downloadPayload(options?) | Downloads payload data for timestamp options.at (requires encryption key) |
downloadRawReference(options?) | Returns unencrypted reference for timestamp options.at (for /bzz access) |
downloadRawPayload(options?) | Downloads unencrypted payload for timestamp options.at (for /bzz access) |
uploadPayload(data, options?) | Uploads encrypted payload data and updates the feed |
uploadReference(reference, options?) | Updates the feed with an encrypted reference |
uploadRawPayload(data, options?) | Uploads unencrypted payload (for /bzz access) |
uploadRawReference(reference, options?) | Updates the feed with an unencrypted reference (for /bzz access) |
Epoch upload options (options):
| Option | Type | Required | Description |
|---|---|---|---|
at | number | string | bigint | No | Unix timestamp (seconds); defaults to current time |
encrypt | boolean | No | Whether payload uploads are encrypted (default true) |
uploadOptions | UploadOptions | No | Upload configuration (tag, pin, deferred, etc.) |
encryptionKey | Uint8Array | string | No | Encryption key for encrypted feed updates |
Returns (uploadPayload / uploadReference / uploadRawPayload / uploadRawReference):
| Property | Type | Description |
|---|---|---|
socAddress | string | SOC address for the feed update |
reference | string | Swarm reference stored in the feed |
encryptionKey | string | undefined | Encryption key (hex) if reference is encrypted |
epoch | { start: string; level: number } | The epoch where the update was stored |
timestamp | string | The timestamp used (stringified bigint) |
Example:
const writer = client.makeEpochFeedWriter({ topic })const upload = await writer.uploadPayload('Hello feed', { at: BigInt(Math.floor(Date.now() / 1000)),})const latest = await writer.downloadReference({ at: BigInt(Math.floor(Date.now() / 1000)) })Sequential Feed Methods
Sequential feed methods provide index-based updates backed by Single Owner Chunks (SOCs) and use the chunk API only. Payload uploads are encrypted by default; raw uploads allow supplying or omitting an encryption key.
makeSequentialFeedReader(options, requestOptions?)
Creates a sequential feed reader bound to a topic and optional owner.
Parameters:
| Parameter | Type | Required | Description |
|---|---|---|---|
options.topic | string | Yes | Feed topic (32-byte hex string) |
options.owner | string | No | Feed owner address; if omitted, resolved via proxy |
requestOptions | RequestOptions | No | Request configuration |
Returns: SequentialFeedReader
FeedReader
| Method | Description |
|---|---|
getOwner() | Resolves the feed owner address |
downloadPayload(encryptionKey, options?) | Downloads payload data for the given index or timestamp (requires encryption key) |
downloadRawPayload(options?, encryptionKey?) | Downloads raw payload data (encryption key optional) |
downloadReference(encryptionKey, options?) | Downloads reference for the given index or timestamp (requires encryption key) |
Sequential download options (options):
| Option | Type | Required | Description |
|---|---|---|---|
index | number | string | bigint | No | Feed index to read (0..2^64-1) |
at | number | string | bigint | No | Unix timestamp (seconds); resolves nearest update at or before at |
hasTimestamp | boolean | No | Whether payloads include a timestamp prefix (default true) |
lookupTimeoutMs | number | No | Timeout (ms) for sequential index lookups (default 2000) |
Example:
const reader = client.makeSequentialFeedReader({ topic })const owner = await reader.getOwner()const payload = await reader.downloadPayload(encryptionKey, { index: 0 })makeSequentialFeedWriter(options, requestOptions?)
Creates a sequential feed writer for updating and reading a topic. If signer is omitted, the proxy uses the app signer.
Parameters:
| Parameter | Type | Required | Description |
|---|---|---|---|
options.topic | string | Yes | Feed topic (32-byte hex string) |
options.signer | string | No | Private key hex string for the feed signer |
requestOptions | RequestOptions | No | Request configuration |
Returns: SequentialFeedWriter
FeedWriter
| Method | Description |
|---|---|
getOwner() | Resolves the feed owner address |
downloadPayload(encryptionKey, options?) | Downloads payload data for the given index or timestamp (requires encryption key) |
downloadRawPayload(options?, encryptionKey?) | Downloads raw payload data (encryption key optional) |
downloadReference(encryptionKey, options?) | Downloads reference for the given index or timestamp (requires encryption key) |
uploadPayload(data, options?) | Uploads payload data (encrypted) and updates the feed |
uploadRawPayload(data, options?, encryptionKey?) | Uploads raw payload data (encryption optional) and updates the feed |
uploadReference(reference, options?) | Uploads a reference (encrypted) and updates the feed |
Sequential upload options (options):
| Option | Type | Required | Description |
|---|---|---|---|
index | number | string | bigint | No | Feed index to write (0..2^64-1); defaults to next index |
at | number | string | bigint | No | Unix timestamp (seconds); used when hasTimestamp is true |
hasTimestamp | boolean | No | Whether payloads include a timestamp prefix (default true) |
lookupTimeoutMs | number | No | Timeout (ms) for sequential index lookups (default 2000) |
pin | boolean | No | Whether to pin the data locally |
encrypt | boolean | No | Whether to encrypt the data |
tag | number | No | Tag ID for tracking upload progress |
deferred | boolean | No | Whether to use deferred upload |
redundancyLevel | 0-4 | No | Redundancy level for data availability |
Example:
const writer = client.makeSequentialFeedWriter({ topic })const upload = await writer.uploadPayload('Hello feed!', { index: 0 })const payload = await writer.downloadPayload(upload.encryptionKey, { index: 0 })Feed Manifest Methods
createFeedManifest(topic, options?, requestOptions?)
Creates a feed manifest for accessing feed content via URL.
A feed manifest enables accessing the latest feed content via a URL path (e.g., /bzz/{manifest-reference}/). The manifest stores metadata about the feed including owner, topic, and feed type.
Parameters:
| Parameter | Type | Required | Description |
|---|---|---|---|
topic | string | Yes | Feed topic (32-byte hex string) |
options | object | No | Configuration options |
options.owner | string | No | Feed owner address; if omitted, uses app signer |
options.feedType | "Sequence" | "Epoch" | No | Feed type (defaults to "Sequence") |
options.uploadOptions | UploadOptions | No | Upload configuration (pin, deferred, etc.) |
requestOptions | RequestOptions | No | Request configuration |
requestOptions.timeout | number | No | Request timeout in milliseconds |
requestOptions.headers | Record<string, string> | No | Custom headers |
Returns: Promise<string> - The feed manifest reference (64 hex characters)
Throws:
Errorif the client is not initializedErrorif no owner is provided and no app signer is availableErrorif the request times out
Example:
// Create manifest for a feed (uses app signer as owner)const manifestRef = await client.createFeedManifest(topic)console.log('Feed accessible at /bzz/' + manifestRef)
// Create manifest with explicit ownerconst manifestRef = await client.createFeedManifest(topic, { owner: '0x1234...',})
// Use with feed writerconst writer = client.makeSequentialFeedWriter({ topic })const result = await writer.uploadPayload('Hello feed!')
const manifestRef = await client.createFeedManifest(topic)// Now feed content accessible via /bzz/{manifestRef}/GSOC Methods
GSOC (Global Single Owner Chunk) methods enable proximity-based message routing on the Swarm network. These methods allow you to mine a private key that produces a SOC address proximate to a target overlay, then send messages using that key.
gsocMine(targetOverlay, identifier, proximity?)
Mines a private key whose SOC (Single Owner Chunk) address is proximate to a target overlay address.
This is useful for sending messages to specific nodes in the Swarm network based on their overlay address.
Parameters:
| Parameter | Type | Required | Description |
|---|---|---|---|
targetOverlay | string | Yes | The target overlay address to be proximate to |
identifier | string | Yes | The identifier for the SOC |
proximity | number | No | The required proximity (number of matching prefix bits) |
Returns: Promise<string> - The mined signer as a hex string (private key)
Throws:
Errorif the client is not initializedErrorif mining failsErrorif the request times out
Example:
const targetOverlay = 'a1b2c3d4e5f6...'const identifier = 'my-channel'const signer = await client.gsocMine(targetOverlay, identifier, 8)console.log('Mined signer:', signer)gsocSend(signer, identifier, data, options?, requestOptions?)
Sends a GSOC (Global Single Owner Chunk) message using a mined signer.
Use the signer obtained from gsocMine() to send messages that will be routed to nodes with the target overlay address.
Parameters:
| Parameter | Type | Required | Description |
|---|---|---|---|
signer | string | Yes | The mined signer (private key) from gsocMine() |
identifier | string | Yes | The identifier for the SOC (must match the one used in mining) |
data | Uint8Array | Yes | The message data to send |
options | UploadOptions | No | Upload configuration (see uploadData) |
requestOptions | RequestOptions | No | Request configuration |
requestOptions.timeout | number | No | Request timeout in milliseconds |
requestOptions.headers | Record<string, string> | No | Custom headers |
requestOptions.endlesslyRetry | boolean | No | Whether to retry endlessly |
Returns: Promise<UploadResult> - Contains the reference of the uploaded chunk
Throws:
Errorif the client is not initializedErrorif the user is not authenticated or cannot uploadErrorif the request times out
Example:
// First, mine a signer for the target overlayconst targetOverlay = 'a1b2c3d4e5f6...'const identifier = 'my-channel'const signer = await client.gsocMine(targetOverlay, identifier, 8)
// Then send a message using the mined signerconst message = new TextEncoder().encode('Hello, Swarm!')const result = await client.gsocSend(signer, identifier, message)console.log('Message sent with reference:', result.reference)ACT Methods
ACT (Access Control Tries) methods enable encrypted data sharing with specific grantees. Data is encrypted and only users with the appropriate public key can decrypt it.
actUploadData(data, grantees, options?, requestOptions?)
Uploads encrypted data to the Swarm network with access control for specific grantees.
The data is encrypted using ACT (Access Control Tries) and can only be downloaded by users who have one of the grantee public keys.
Parameters:
| Parameter | Type | Required | Description |
|---|---|---|---|
data | Uint8Array | Yes | The binary data to upload |
grantees | string[] | Yes | Array of compressed public keys (66 hex chars each) |
options | ActUploadOptions | No | Upload configuration |
options.pin | boolean | No | Whether to pin the data locally (defaults to false) |
options.tag | number | No | Tag ID for tracking upload progress |
options.deferred | boolean | No | Whether to use deferred upload (defaults to false) |
options.redundancyLevel | 0-4 | No | Redundancy level for data availability |
options.onProgress | (progress) => void | No | Callback for tracking upload progress |
requestOptions | RequestOptions | No | Request configuration |
requestOptions.timeout | number | No | Request timeout in milliseconds |
requestOptions.headers | Record<string, string> | No | Custom headers |
requestOptions.endlesslyRetry | boolean | No | Whether to retry endlessly |
Returns: Promise<ActUploadResult>
| Property | Type | Description |
|---|---|---|
encryptedReference | string | The encrypted Swarm reference (pass to actDownloadData) |
historyReference | string | The history reference (pass to add/revoke grantees) |
granteeListReference | string | Reference to the grantee list |
publisherPubKey | string | Publisher’s compressed public key (pass to actDownloadData) |
actReference | string | The ACT reference |
tagUid | number | undefined | The tag UID if a tag was created |
Throws:
Errorif the client is not initializedErrorif the user is not authenticated or cannot uploadErrorif the request times out
Example:
const data = new TextEncoder().encode('Secret message')
// Grantees are compressed public keys (33 bytes = 66 hex chars)const grantees = [ '02abc123...', // Alice's public key '03def456...', // Bob's public key]
const result = await client.actUploadData(data, grantees, { onProgress: (progress) => { console.log(`Progress: ${progress.processed}/${progress.total}`) },})
console.log('History Reference:', result.historyReference)console.log('Encrypted Reference:', result.encryptedReference)console.log('Publisher Public Key:', result.publisherPubKey)
// Save these for later download:// - encryptedReference, historyReference, publisherPubKeyactDownloadData(encryptedReference, historyReference, publisherPubKey, timestamp?, requestOptions?)
Downloads and decrypts ACT-protected data from the Swarm network.
The user must have access (their public key must be in the grantee list) to decrypt the data.
Parameters:
| Parameter | Type | Required | Description |
|---|---|---|---|
encryptedReference | string | Yes | The encrypted reference from actUploadData |
historyReference | string | Yes | The history reference from actUploadData |
publisherPubKey | string | Yes | Publisher’s compressed public key from actUploadData |
timestamp | number | No | Unix timestamp for historical access (optional) |
requestOptions | RequestOptions | No | Request configuration |
requestOptions.timeout | number | No | Request timeout in milliseconds |
requestOptions.headers | Record<string, string> | No | Custom headers |
requestOptions.endlesslyRetry | boolean | No | Whether to retry endlessly |
Returns: Promise<Uint8Array> - The decrypted data
Throws:
Errorif the client is not initializedErrorif the user does not have access (not in grantee list)Errorif the reference is not foundErrorif the request times out
Example:
// Using the references from actUploadDataconst data = await client.actDownloadData(encryptedReference, historyReference, publisherPubKey)const text = new TextDecoder().decode(data)console.log('Decrypted:', text)actAddGrantees(historyReference, grantees, requestOptions?)
Adds new grantees to an existing ACT.
This method adds new public keys to the ACT’s access list. The encrypted reference remains the same, but a new history reference is returned that should be used for future operations.
Parameters:
| Parameter | Type | Required | Description |
|---|---|---|---|
historyReference | string | Yes | The history reference from actUploadData or previous actAddGrantees |
grantees | string[] | Yes | Array of compressed public keys to add (66 hex chars each) |
requestOptions | RequestOptions | No | Request configuration |
requestOptions.timeout | number | No | Request timeout in milliseconds |
requestOptions.headers | Record<string, string> | No | Custom headers |
requestOptions.endlesslyRetry | boolean | No | Whether to retry endlessly |
Returns: Promise<ActAddGranteesResult>
| Property | Type | Description |
|---|---|---|
historyReference | string | New history reference (use for future ops) |
granteeListReference | string | Reference to the updated grantee list |
actReference | string | The ACT reference |
Throws:
Errorif the client is not initializedErrorif the user is not authenticatedErrorif the request times out
Example:
const newGrantees = [ '02xyz789...', // Charlie's public key]
const result = await client.actAddGrantees(historyReference, newGrantees)console.log('New History Reference:', result.historyReference)// The encrypted reference remains the same// Use the new historyReference for future operationsactRevokeGrantees(historyReference, encryptedReference, revokeGrantees, requestOptions?)
Revokes access from grantees by removing them from the ACT.
Parameters:
| Parameter | Type | Required | Description |
|---|---|---|---|
historyReference | string | Yes | The current history reference |
encryptedReference | string | Yes | The current encrypted reference |
revokeGrantees | string[] | Yes | Array of compressed public keys to revoke (66 hex chars) |
requestOptions | RequestOptions | No | Request configuration |
requestOptions.timeout | number | No | Request timeout in milliseconds |
requestOptions.headers | Record<string, string> | No | Custom headers |
requestOptions.endlesslyRetry | boolean | No | Whether to retry endlessly |
Returns: Promise<ActRevokeGranteesResult>
| Property | Type | Description |
|---|---|---|
encryptedReference | string | New encrypted reference (due to rotation) |
historyReference | string | New history reference |
granteeListReference | string | Reference to the updated grantee list |
actReference | string | The ACT reference |
Throws:
Errorif the client is not initializedErrorif the user is not authenticatedErrorif the request times out
Example:
const revokeKeys = [ '02abc123...', // Alice's public key (revoke access)]
const result = await client.actRevokeGrantees(historyReference, encryptedReference, revokeKeys)console.log('New History Reference:', result.historyReference)console.log('New Encrypted Reference:', result.encryptedReference)// All references are new due to key rotation// Update your stored references!actGetGrantees(historyReference, requestOptions?)
Retrieves the list of current grantees for an ACT.
Parameters:
| Parameter | Type | Required | Description |
|---|---|---|---|
historyReference | string | Yes | The history reference of the ACT |
requestOptions | RequestOptions | No | Request configuration |
requestOptions.timeout | number | No | Request timeout in milliseconds |
requestOptions.headers | Record<string, string> | No | Custom headers |
requestOptions.endlesslyRetry | boolean | No | Whether to retry endlessly |
Returns: Promise<string[]> - Array of compressed public keys (66 hex chars each)
Throws:
Errorif the client is not initializedErrorif the history reference is not foundErrorif the request times out
Example:
const grantees = await client.actGetGrantees(historyReference)console.log('Current grantees:', grantees.length)grantees.forEach((pubKey) => console.log(' -', pubKey))Types
import type { // Client configuration ClientOptions, AuthStatus, ConnectionInfo, PostageBatch, NodeInfo, AppMetadata, ButtonConfig, RequestOptions,
// Upload/Download UploadOptions, DownloadOptions, UploadResult, FileData, Reference,
// SOC SingleOwnerChunk,
// Feed types FeedReader, FeedWriter, SequentialFeedReader, SequentialFeedWriter, EpochFeedUploadResult, EpochFeedDownloadReferenceResult, EpochFeedDownloadPayloadResult,
// ACT types ActUploadOptions,
// Backup & Recovery types EncryptedSwarmIdExport, ParseHeaderResult, AccountStateSnapshot, RestoreAccountResult,} from '@snaha/swarm-id'Backup Encryption
Functions for creating and reading encrypted .swarmid backup files. Exported from @snaha/swarm-id.
createEncryptedExport(account, identities, connectedApps, postageStamps, swarmEncryptionKeyHex)
Create a fully encrypted .swarmid export object. Serializes account data, derives an AES-GCM-256 key from the swarmEncryptionKey (which is itself derived from the account’s stored derivationKey), encrypts the payload, and builds a header with account metadata.
Parameters:
| Parameter | Type | Description |
|---|---|---|
account | Account | The account to export |
identities | Identity[] | Account identities |
connectedApps | ConnectedApp[] | Connected applications (appSecret is stripped) |
postageStamps | PostageStamp[] | Postage stamps |
swarmEncryptionKeyHex | string | Hex-encoded swarm encryption key (derived from account.derivationKey via deriveSwarmEncryptionKey) |
Returns: Promise<EncryptedSwarmIdExport>
const swarmEncryptionKey = await deriveSwarmEncryptionKey(account.derivationKey)const exported = await createEncryptedExport( account, identities, connectedApps, postageStamps, swarmEncryptionKey,)// Save as .swarmid fileconst blob = new Blob([JSON.stringify(exported)], { type: 'application/json' })decryptEncryptedExport(encryptedData, swarmEncryptionKeyHex)
Decrypt an encrypted .swarmid export and return the parsed account state snapshot.
Parameters:
| Parameter | Type | Description |
|---|---|---|
encryptedData | unknown | The parsed JSON from a .swarmid file |
swarmEncryptionKeyHex | string | Hex-encoded swarm encryption key (derived from derivationKey) |
Returns: Promise<AccountStateSnapshotResult> — { success: true, data: AccountStateSnapshot } or { success: false, error: ZodError }
const swarmEncryptionKey = await deriveSwarmEncryptionKey(account.derivationKey)const result = await decryptEncryptedExport(fileData, swarmEncryptionKey)if (result.success) { const { identities, connectedApps, postageStamps } = result.data}parseEncryptedExportHeader(data)
Parse and validate just the encrypted export header without decrypting. Useful for reading account metadata (name, type, export date) before attempting decryption.
Parameters:
| Parameter | Type | Description |
|---|---|---|
data | unknown | The parsed JSON from a .swarmid file |
Returns: ParseHeaderResult — { success: true, header: EncryptedSwarmIdExport } or { success: false, error: string }
deriveBackupEncryptionKey(swarmEncryptionKeyHex)
Derive an AES-GCM-256 CryptoKey for backup encryption from the swarmEncryptionKey (which is itself derived from the stored derivationKey). Uses HMAC-SHA256 with context "swarm-id-backup-encryption-v1".
Parameters:
| Parameter | Type | Description |
|---|---|---|
swarmEncryptionKeyHex | string | Hex-encoded swarm encryption key (derived from derivationKey) |
Returns: Promise<CryptoKey>
Types
// Discriminated union of backup headers (passkey | ethereum | agent)type EncryptedSwarmIdExport = PasskeyBackupHeader | EthereumBackupHeader | AgentBackupHeader
// Common fields in all headersinterface BackupHeaderBase { version: 1 accountName: string exportedAt: number // Unix timestamp ciphertext: string // Base64-encoded encrypted payload}
// Result of parseEncryptedExportHeader()type ParseHeaderResult = | { success: true; header: EncryptedSwarmIdExport } | { success: false; error: string }Account State Snapshots
Shared serialization for account state used by both file export and Swarm sync.
serializeAccountStateSnapshot(input)
Serialize account data into a plain object suitable for JSON encoding. Strips appSecret from connected apps.
Parameters:
| Parameter | Type | Description |
|---|---|---|
input.accountId | string | Account ID (hex) |
input.metadata | AccountMetadata | Account metadata |
input.identities | Identity[] | Account identities |
input.connectedApps | ConnectedApp[] | Connected apps (appSecret stripped) |
input.postageStamps | PostageStamp[] | Postage stamps |
input.timestamp | number | Snapshot timestamp |
Returns: Record<string, unknown>
deserializeAccountStateSnapshot(data)
Deserialize and validate an account state snapshot. Any appSecret injected in the raw data is stripped by the Zod schema.
Parameters:
| Parameter | Type | Description |
|---|---|---|
data | unknown | Raw data to parse |
Returns: AccountStateSnapshotResult — { success: true, data: AccountStateSnapshot } or { success: false, error: ZodError }
Types
interface AccountStateSnapshot { version: 1 timestamp: number accountId: string metadata: AccountMetadata identities: SerializedIdentity[] connectedApps: ExportedConnectedApp[] // no appSecret postageStamps: SerializedPostageStamp[]}Account Restoration
restoreAccountFromSwarm(bee, masterKey, ethereumAddress, credentialId)
Restore account state from Swarm using passkey authentication result. Derives keys, looks up the epoch feed, downloads and decrypts the latest snapshot.
Parameters:
| Parameter | Type | Description |
|---|---|---|
bee | Bee | Bee client instance |
masterKey | Bytes | Master key from passkey authentication |
ethereumAddress | EthAddress | Account ID from passkey authentication |
credentialId | string | Credential ID from passkey authentication |
Returns: Promise<RestoreAccountResult | undefined> — undefined if no backup found in Swarm
Types
interface RestoreAccountResult { snapshot: AccountStateSnapshot derivationKey: string credentialId: string}Key Derivation
derivePostageSignerKey(derivationKey, identityId?)
Derive a deterministic postage batch signer key from the account’s derivation key. When identityId is provided, derives a unique signer key for that identity; otherwise derives an account-level signer key.
Parameters:
| Parameter | Type | Description |
|---|---|---|
derivationKey | string | Account derivation key (64-char hex) |
identityId | string | undefined | Optional identity ID for per-identity signer keys |
Returns: Promise<string> — 32-byte signer key as hex string
import { derivePostageSignerKey } from '@snaha/swarm-id'import { PrivateKey } from '@ethersphere/bee-js'
// Account-level signer keyconst signerKeyHex = await derivePostageSignerKey(account.derivationKey)const signerKey = new PrivateKey(signerKeyHex)
// Identity-specific signer keyconst identitySignerKeyHex = await derivePostageSignerKey(account.derivationKey, identity.id)