Skip to content

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

Terminal window
pnpm add @snaha/swarm-id

Quick 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 manually
await client.connect()
// Option 2: Check authentication status and upload if authenticated
const 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:

ParameterTypeRequiredDescription
options.iframeOriginstringYesThe origin URL where the Swarm ID proxy iframe is hosted
options.iframePathstringNoThe path to the proxy iframe (defaults to "/proxy")
options.timeoutnumberNoRequest timeout in milliseconds (defaults to 30000)
options.initializationTimeoutnumberNoInitialization timeout in milliseconds (defaults to 30000)
options.onAuthChange(authenticated: boolean) => voidNoCallback function invoked when authentication status changes
options.popupMode"popup" | "window"NoHow to display the authentication popup (defaults to "window")
options.metadataAppMetadataYesApplication metadata shown to users during authentication
options.metadata.namestringYesApplication name (1-100 characters)
options.metadata.descriptionstringNoApplication description (max 500 characters)
options.metadata.iconstringNoApplication icon as a data URL (SVG or PNG, max 4KB)
options.buttonConfigButtonConfigNoButton configuration for the authentication UI
options.containerIdstringNoID 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:

  • Error if the client is already initialized
  • Error if the iframe fails to load
  • Error if the proxy does not respond within the initialization timeout period (configurable via initializationTimeout, defaults to 30 seconds)
  • Error if 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 unmounts
useEffect(() => {
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:

  • Error if the client is not initialized
  • Error if the iframe is not available

Example:

const iframe = client.getAuthIframe()
// The iframe is already displayed; this returns a reference to it

Button 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:

PropertyTypeRequiredDescriptionDefault Value
connectTextstringNoText for the connect button”🔐 Login with Swarm ID”
disconnectTextstringNoText for the disconnect button”🔓 Disconnect from Swarm ID”
loadingTextstringNoText shown during loading”⏳ Loading…”
backgroundColorstringNoBackground color for buttons#dd7200 (connect), #666 (disconnect)
colorstringNoText color for buttonswhite
borderRadiusstringNoBorder radius for buttons and iframe0

Notes:

  • Button configuration is passed directly to the constructor, not via postMessage
  • The borderRadius property 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 window
await client.connect({ popupMode: 'popup' })
// Open with agent sign-up option visible
await 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:

  1. User calls client.connect() or clicks the iframe button
  2. Authentication page opens with the app metadata
  3. User authenticates with their Swarm ID
  4. Authentication state is shared with the iframe proxy
  5. onAuthChange callback is invoked with true

checkAuthStatus()

Checks the current authentication status with the Swarm ID proxy.

Returns: Promise<AuthStatus> - The authentication status object

PropertyTypeDescription
authenticatedbooleanWhether the user is currently authenticated
originstring | undefinedThe origin that authenticated (if authenticated)

Throws:

  • Error if the client is not initialized
  • Error if 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:

ParameterTypeRequiredDescription
optionsConnectOptionsNoConfiguration options for the authentication window
options.popupMode"window" | "popup"NoWhether to open as a popup window (“popup”) or full window (“window”, default)
options.agentbooleanNoWhether 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:

  • Error if the client is not initialized
  • Error if 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 window
await client.connect({ popupMode: 'popup' })
// Open with agent sign-up option visible
await 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:

  • Error if the client is not initialized
  • Error if the disconnect operation fails
  • Error if 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

PropertyTypeDescription
canUploadbooleanWhether the user can upload data (has stamps and storage is not partitioned)
storagePartitionedboolean | undefinedtrue when browser storage partitioning prevents access to stamps/signer keys
identityobject | undefinedThe connected identity details (if authenticated)
identity.idstringUnique identifier for the identity
identity.namestringDisplay name of the identity
identity.addressstringEthereum address associated with the identity

Throws:

  • Error if the client is not initialized
  • Error if 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

PropertyTypeDescription
batchIDstringThe batch ID (64 hex characters)
utilizationnumberCurrent utilization percentage
usablebooleanWhether the batch is usable
labelstringHuman-readable label
depthnumberBatch depth
amountstringBatch amount
bucketDepthnumberBucket depth
blockNumbernumberBlock number when created
immutableFlagbooleanWhether the batch is immutable
existsbooleanWhether the batch exists
batchTTLnumber | undefinedTime-to-live in seconds

Throws:

  • Error if the client is not initialized
  • Error if 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

PropertyTypeDescription
beeModestringThe Bee node operating mode (“dev”, “light”, “full”, “ultra-light”)
chequebookEnabledbooleanWhether the chequebook is enabled
swapEnabledbooleanWhether SWAP is enabled

Throws:

  • Error if the client is not initialized
  • Error if the Bee node is not reachable
  • Error if 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:

ParameterTypeRequiredDescription
dataUint8ArrayYesThe binary data to upload
optionsUploadOptionsNoUpload configuration
options.pinbooleanNoWhether to pin the data locally (defaults to false)
options.encryptbooleanNoWhether to encrypt the data (defaults to false)
options.tagnumberNoTag ID for tracking upload progress
options.deferredbooleanNoWhether to use deferred upload (defaults to false)
options.redundancyLevel0-4NoRedundancy level for data availability
options.onProgress(progress) => voidNoCallback for tracking upload progress
requestOptionsRequestOptionsNoRequest configuration
requestOptions.timeoutnumberNoRequest timeout in milliseconds
requestOptions.headersRecord<string, string>NoCustom headers
requestOptions.endlesslyRetrybooleanNoWhether to retry endlessly

Returns: Promise<UploadResult>

PropertyTypeDescription
referencestringThe Swarm reference (hash) of the uploaded data
tagUidnumber | undefinedThe tag UID if a tag was created

Throws:

  • Error if the client is not initialized
  • Error if the user is not authenticated or cannot upload
  • Error if 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:

ParameterTypeRequiredDescription
referencestringYesThe Swarm reference (64 or 128 hex chars)
optionsDownloadOptionsNoDownload configuration
options.redundancyStrategy0-3NoStrategy for handling redundancy
options.fallbackbooleanNoWhether to use fallback retrieval
options.timeoutMsnumberNoDownload timeout in milliseconds
options.actPublisherUint8Array | stringNoACT publisher for encrypted content
options.actHistoryAddressUint8Array | stringNoACT history address for encrypted content
options.actTimestampnumber | stringNoACT timestamp for encrypted content
requestOptionsRequestOptionsNoRequest configuration
requestOptions.timeoutnumberNoRequest timeout in milliseconds
requestOptions.headersRecord<string, string>NoCustom headers
requestOptions.endlesslyRetrybooleanNoWhether to retry endlessly

Returns: Promise<Uint8Array> - The downloaded data

Throws:

  • Error if the client is not initialized
  • Error if the reference is not found
  • Error if the request times out

Example:

const data = await client.downloadData('a1b2c3...') // 64 char hex reference
const 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:

ParameterTypeRequiredDescription
fileFile | Uint8ArrayYesThe file to upload
namestringNoFilename (extracted from File object if not provided)
optionsUploadOptionsNoUpload configuration (see uploadData)
requestOptionsRequestOptionsNoRequest configuration
requestOptions.timeoutnumberNoRequest timeout in milliseconds
requestOptions.headersRecord<string, string>NoCustom headers
requestOptions.endlesslyRetrybooleanNoWhether to retry endlessly

Returns: Promise<UploadResult> - Contains reference and optional tagUid

Throws:

  • Error if the client is not initialized
  • Error if the user is not authenticated or cannot upload
  • Error if the request times out

Example:

// From file input
const fileInput = document.querySelector('input[type="file"]')
const file = fileInput.files[0]
const result = await client.uploadFile(file)
// From Uint8Array with custom name
const 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:

ParameterTypeRequiredDescription
referencestringYesThe Swarm reference of the file
pathstringNoPath within a manifest to retrieve a specific file
optionsDownloadOptionsNoDownload configuration (see downloadData)
requestOptionsRequestOptionsNoRequest configuration
requestOptions.timeoutnumberNoRequest timeout in milliseconds
requestOptions.headersRecord<string, string>NoCustom headers
requestOptions.endlesslyRetrybooleanNoWhether to retry endlessly

Returns: Promise<FileData>

PropertyTypeDescription
namestringThe filename
dataUint8ArrayThe file contents

Throws:

  • Error if the client is not initialized
  • Error if the reference is not found
  • Error if the request times out

Example:

const file = await client.downloadFile('a1b2c3...')
console.log('Filename:', file.name)
// Create download link
const 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:

ParameterTypeRequiredDescription
dataUint8ArrayYesThe chunk data (should be exactly 4KB for optimal storage)
optionsUploadOptionsNoUpload configuration (see uploadData)
requestOptionsRequestOptionsNoRequest configuration
requestOptions.timeoutnumberNoRequest timeout in milliseconds
requestOptions.headersRecord<string, string>NoCustom headers
requestOptions.endlesslyRetrybooleanNoWhether to retry endlessly

Returns: Promise<UploadResult> - Contains the reference of the uploaded chunk

Throws:

  • Error if the client is not initialized
  • Error if the user is not authenticated or cannot upload
  • Error if the request times out

Example:

const chunk = new Uint8Array(4096) // 4KB chunk
chunk.fill(0x42) // Fill with data
const 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:

ParameterTypeRequiredDescription
referencestringYesThe Swarm reference of the chunk
optionsDownloadOptionsNoDownload configuration (see downloadData)
requestOptionsRequestOptionsNoRequest configuration
requestOptions.timeoutnumberNoRequest timeout in milliseconds
requestOptions.headersRecord<string, string>NoCustom headers
requestOptions.endlesslyRetrybooleanNoWhether to retry endlessly

Returns: Promise<Uint8Array> - The chunk data

Throws:

  • Error if the client is not initialized
  • Error if the reference is not found
  • Error if 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:

ParameterTypeRequiredDescription
ownerAddressstringYesEthereum address of the SOC owner
requestOptionsRequestOptionsNoRequest configuration
requestOptions.timeoutnumberNoRequest timeout in milliseconds
requestOptions.headersRecord<string, string>NoCustom headers
requestOptions.endlesslyRetrybooleanNoWhether to retry endlessly

Returns: SOCReader

MethodDescription
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:

  • Error if the client is not initialized
  • Error if 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:

ParameterTypeRequiredDescription
signerstringNoPrivate key hex string for the SOC signer
requestOptionsRequestOptionsNoRequest configuration
requestOptions.timeoutnumberNoRequest timeout in milliseconds
requestOptions.headersRecord<string, string>NoCustom headers
requestOptions.endlesslyRetrybooleanNoWhether to retry endlessly

Returns: SOCWriter

MethodDescription
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>

PropertyTypeDescription
referencestringSOC chunk reference
ownerstringSOC owner address
encryptionKeystringEncryption key for decrypting the SOC
tagUidnumberUpload tag UID, if provided

Returns (rawUpload): Promise<SocRawUploadResult>

PropertyTypeDescription
referencestringSOC chunk reference
ownerstringSOC owner address
encryptionKeystringOptional; present only if returned by proxy
tagUidnumberUpload tag UID, if provided

Throws:

  • Error if the client is not initialized
  • Error if 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

PropertyTypeDescription
dataUint8ArrayFull SOC chunk data
identifierstringSOC identifier
signaturestringSOC signature
spannumberPayload span (bytes)
payloadUint8ArraySOC payload data
addressstringSOC address/reference
ownerstringSOC 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:

ParameterTypeRequiredDescription
options.topicstringYesFeed topic (32-byte hex string)
options.ownerstringNoFeed owner address; if omitted, resolved via proxy
requestOptionsRequestOptionsNoRequest configuration
requestOptions.timeoutnumberNoRequest timeout in milliseconds
requestOptions.headersRecord<string, string>NoCustom headers
requestOptions.endlesslyRetrybooleanNoWhether to retry endlessly

Returns: FeedReader

FeedReader

MethodDescription
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):

OptionTypeRequiredDescription
atnumber | string | bigintNoUnix timestamp (seconds); defaults to current time
afternumber | string | bigintNoHint for latest known update timestamp
encryptionKeyUint8Array | stringNoEncryption key for encrypted feed updates

Returns (downloadReference):

PropertyTypeDescription
referencestring | undefinedSwarm reference (hex) if found
encryptionKeystring | undefinedEncryption key (hex) if reference is encrypted

Returns (downloadPayload):

PropertyTypeDescription
payloadUint8Array | undefinedPayload bytes if found
referencestring | undefinedSwarm reference (hex) if found
encryptionKeystring | undefinedEncryption 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:

ParameterTypeRequiredDescription
options.topicstringYesFeed topic (32-byte hex string)
options.signerstringNoPrivate key hex string for the feed signer
requestOptionsRequestOptionsNoRequest configuration
requestOptions.timeoutnumberNoRequest timeout in milliseconds
requestOptions.headersRecord<string, string>NoCustom headers
requestOptions.endlesslyRetrybooleanNoWhether to retry endlessly

Returns: FeedWriter

FeedWriter

MethodDescription
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):

OptionTypeRequiredDescription
atnumber | string | bigintNoUnix timestamp (seconds); defaults to current time
encryptbooleanNoWhether payload uploads are encrypted (default true)
uploadOptionsUploadOptionsNoUpload configuration (tag, pin, deferred, etc.)
encryptionKeyUint8Array | stringNoEncryption key for encrypted feed updates

Returns (uploadPayload / uploadReference / uploadRawPayload / uploadRawReference):

PropertyTypeDescription
socAddressstringSOC address for the feed update
referencestringSwarm reference stored in the feed
encryptionKeystring | undefinedEncryption key (hex) if reference is encrypted
epoch{ start: string; level: number }The epoch where the update was stored
timestampstringThe 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:

ParameterTypeRequiredDescription
options.topicstringYesFeed topic (32-byte hex string)
options.ownerstringNoFeed owner address; if omitted, resolved via proxy
requestOptionsRequestOptionsNoRequest configuration

Returns: SequentialFeedReader

FeedReader

MethodDescription
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):

OptionTypeRequiredDescription
indexnumber | string | bigintNoFeed index to read (0..2^64-1)
atnumber | string | bigintNoUnix timestamp (seconds); resolves nearest update at or before at
hasTimestampbooleanNoWhether payloads include a timestamp prefix (default true)
lookupTimeoutMsnumberNoTimeout (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:

ParameterTypeRequiredDescription
options.topicstringYesFeed topic (32-byte hex string)
options.signerstringNoPrivate key hex string for the feed signer
requestOptionsRequestOptionsNoRequest configuration

Returns: SequentialFeedWriter

FeedWriter

MethodDescription
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):

OptionTypeRequiredDescription
indexnumber | string | bigintNoFeed index to write (0..2^64-1); defaults to next index
atnumber | string | bigintNoUnix timestamp (seconds); used when hasTimestamp is true
hasTimestampbooleanNoWhether payloads include a timestamp prefix (default true)
lookupTimeoutMsnumberNoTimeout (ms) for sequential index lookups (default 2000)
pinbooleanNoWhether to pin the data locally
encryptbooleanNoWhether to encrypt the data
tagnumberNoTag ID for tracking upload progress
deferredbooleanNoWhether to use deferred upload
redundancyLevel0-4NoRedundancy 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:

ParameterTypeRequiredDescription
topicstringYesFeed topic (32-byte hex string)
optionsobjectNoConfiguration options
options.ownerstringNoFeed owner address; if omitted, uses app signer
options.feedType"Sequence" | "Epoch"NoFeed type (defaults to "Sequence")
options.uploadOptionsUploadOptionsNoUpload configuration (pin, deferred, etc.)
requestOptionsRequestOptionsNoRequest configuration
requestOptions.timeoutnumberNoRequest timeout in milliseconds
requestOptions.headersRecord<string, string>NoCustom headers

Returns: Promise<string> - The feed manifest reference (64 hex characters)

Throws:

  • Error if the client is not initialized
  • Error if no owner is provided and no app signer is available
  • Error if 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 owner
const manifestRef = await client.createFeedManifest(topic, {
owner: '0x1234...',
})
// Use with feed writer
const 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:

ParameterTypeRequiredDescription
targetOverlaystringYesThe target overlay address to be proximate to
identifierstringYesThe identifier for the SOC
proximitynumberNoThe required proximity (number of matching prefix bits)

Returns: Promise<string> - The mined signer as a hex string (private key)

Throws:

  • Error if the client is not initialized
  • Error if mining fails
  • Error if 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:

ParameterTypeRequiredDescription
signerstringYesThe mined signer (private key) from gsocMine()
identifierstringYesThe identifier for the SOC (must match the one used in mining)
dataUint8ArrayYesThe message data to send
optionsUploadOptionsNoUpload configuration (see uploadData)
requestOptionsRequestOptionsNoRequest configuration
requestOptions.timeoutnumberNoRequest timeout in milliseconds
requestOptions.headersRecord<string, string>NoCustom headers
requestOptions.endlesslyRetrybooleanNoWhether to retry endlessly

Returns: Promise<UploadResult> - Contains the reference of the uploaded chunk

Throws:

  • Error if the client is not initialized
  • Error if the user is not authenticated or cannot upload
  • Error if the request times out

Example:

// First, mine a signer for the target overlay
const targetOverlay = 'a1b2c3d4e5f6...'
const identifier = 'my-channel'
const signer = await client.gsocMine(targetOverlay, identifier, 8)
// Then send a message using the mined signer
const 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:

ParameterTypeRequiredDescription
dataUint8ArrayYesThe binary data to upload
granteesstring[]YesArray of compressed public keys (66 hex chars each)
optionsActUploadOptionsNoUpload configuration
options.pinbooleanNoWhether to pin the data locally (defaults to false)
options.tagnumberNoTag ID for tracking upload progress
options.deferredbooleanNoWhether to use deferred upload (defaults to false)
options.redundancyLevel0-4NoRedundancy level for data availability
options.onProgress(progress) => voidNoCallback for tracking upload progress
requestOptionsRequestOptionsNoRequest configuration
requestOptions.timeoutnumberNoRequest timeout in milliseconds
requestOptions.headersRecord<string, string>NoCustom headers
requestOptions.endlesslyRetrybooleanNoWhether to retry endlessly

Returns: Promise<ActUploadResult>

PropertyTypeDescription
encryptedReferencestringThe encrypted Swarm reference (pass to actDownloadData)
historyReferencestringThe history reference (pass to add/revoke grantees)
granteeListReferencestringReference to the grantee list
publisherPubKeystringPublisher’s compressed public key (pass to actDownloadData)
actReferencestringThe ACT reference
tagUidnumber | undefinedThe tag UID if a tag was created

Throws:

  • Error if the client is not initialized
  • Error if the user is not authenticated or cannot upload
  • Error if 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, publisherPubKey

actDownloadData(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:

ParameterTypeRequiredDescription
encryptedReferencestringYesThe encrypted reference from actUploadData
historyReferencestringYesThe history reference from actUploadData
publisherPubKeystringYesPublisher’s compressed public key from actUploadData
timestampnumberNoUnix timestamp for historical access (optional)
requestOptionsRequestOptionsNoRequest configuration
requestOptions.timeoutnumberNoRequest timeout in milliseconds
requestOptions.headersRecord<string, string>NoCustom headers
requestOptions.endlesslyRetrybooleanNoWhether to retry endlessly

Returns: Promise<Uint8Array> - The decrypted data

Throws:

  • Error if the client is not initialized
  • Error if the user does not have access (not in grantee list)
  • Error if the reference is not found
  • Error if the request times out

Example:

// Using the references from actUploadData
const 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:

ParameterTypeRequiredDescription
historyReferencestringYesThe history reference from actUploadData or previous actAddGrantees
granteesstring[]YesArray of compressed public keys to add (66 hex chars each)
requestOptionsRequestOptionsNoRequest configuration
requestOptions.timeoutnumberNoRequest timeout in milliseconds
requestOptions.headersRecord<string, string>NoCustom headers
requestOptions.endlesslyRetrybooleanNoWhether to retry endlessly

Returns: Promise<ActAddGranteesResult>

PropertyTypeDescription
historyReferencestringNew history reference (use for future ops)
granteeListReferencestringReference to the updated grantee list
actReferencestringThe ACT reference

Throws:

  • Error if the client is not initialized
  • Error if the user is not authenticated
  • Error if 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 operations

actRevokeGrantees(historyReference, encryptedReference, revokeGrantees, requestOptions?)

Revokes access from grantees by removing them from the ACT.

Parameters:

ParameterTypeRequiredDescription
historyReferencestringYesThe current history reference
encryptedReferencestringYesThe current encrypted reference
revokeGranteesstring[]YesArray of compressed public keys to revoke (66 hex chars)
requestOptionsRequestOptionsNoRequest configuration
requestOptions.timeoutnumberNoRequest timeout in milliseconds
requestOptions.headersRecord<string, string>NoCustom headers
requestOptions.endlesslyRetrybooleanNoWhether to retry endlessly

Returns: Promise<ActRevokeGranteesResult>

PropertyTypeDescription
encryptedReferencestringNew encrypted reference (due to rotation)
historyReferencestringNew history reference
granteeListReferencestringReference to the updated grantee list
actReferencestringThe ACT reference

Throws:

  • Error if the client is not initialized
  • Error if the user is not authenticated
  • Error if 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:

ParameterTypeRequiredDescription
historyReferencestringYesThe history reference of the ACT
requestOptionsRequestOptionsNoRequest configuration
requestOptions.timeoutnumberNoRequest timeout in milliseconds
requestOptions.headersRecord<string, string>NoCustom headers
requestOptions.endlesslyRetrybooleanNoWhether to retry endlessly

Returns: Promise<string[]> - Array of compressed public keys (66 hex chars each)

Throws:

  • Error if the client is not initialized
  • Error if the history reference is not found
  • Error if 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:

ParameterTypeDescription
accountAccountThe account to export
identitiesIdentity[]Account identities
connectedAppsConnectedApp[]Connected applications (appSecret is stripped)
postageStampsPostageStamp[]Postage stamps
swarmEncryptionKeyHexstringHex-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 file
const 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:

ParameterTypeDescription
encryptedDataunknownThe parsed JSON from a .swarmid file
swarmEncryptionKeyHexstringHex-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:

ParameterTypeDescription
dataunknownThe 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:

ParameterTypeDescription
swarmEncryptionKeyHexstringHex-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 headers
interface 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:

ParameterTypeDescription
input.accountIdstringAccount ID (hex)
input.metadataAccountMetadataAccount metadata
input.identitiesIdentity[]Account identities
input.connectedAppsConnectedApp[]Connected apps (appSecret stripped)
input.postageStampsPostageStamp[]Postage stamps
input.timestampnumberSnapshot 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:

ParameterTypeDescription
dataunknownRaw 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:

ParameterTypeDescription
beeBeeBee client instance
masterKeyBytesMaster key from passkey authentication
ethereumAddressEthAddressAccount ID from passkey authentication
credentialIdstringCredential 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:

ParameterTypeDescription
derivationKeystringAccount derivation key (64-char hex)
identityIdstring | undefinedOptional 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 key
const signerKeyHex = await derivePostageSignerKey(account.derivationKey)
const signerKey = new PrivateKey(signerKeyHex)
// Identity-specific signer key
const identitySignerKeyHex = await derivePostageSignerKey(account.derivationKey, identity.id)