@beam-network/sdk
v0.4.1
Published
TypeScript SDK for BEAM transfer creation and management.
Readme
BEAM SDK for TypeScript
Install:
npm install @beam-network/sdkExample:
import { BeamClient, R2ProviderConfig, S3ProviderConfig } from "@beam-network/sdk";
const beam = new BeamClient({
apiKey: "bk_your_key"
});
const transfer = await beam.createTransfer({
sources: [
R2ProviderConfig.create({
bucket: "source-bucket",
key: "exports/report.parquet",
account_id: "cloudflare-account-id",
access_key_id: "r2-access-key",
secret_access_key: "r2-secret-key"
})
],
destinations: [
S3ProviderConfig.create({
bucket: "destination-bucket",
key: "imports/report.parquet",
region: "us-east-1",
access_key_id: "aws-access-key",
secret_access_key: "aws-secret-key"
})
],
name: "r2-to-s3-report",
testMode: true
});
const status = await beam.waitForTransfer(transfer.transfer_id);
console.log(status.status);
await beam.close();The main createTransfer API is provider-aware and strictly typed for S3, R2, S3-compatible, and Hippius configs.
Use testMode: true to create a BeamCore test-mode transfer.
S3-Compatible Providers
Use S3CompatibleProviderConfig for S3-compatible providers with custom
endpoints, such as Wasabi, MinIO, Backblaze B2 S3 API, DigitalOcean Spaces,
Scaleway Object Storage, and self-hosted S3-compatible systems.
import {
BeamClient,
S3CompatibleProviderConfig
} from "@beam-network/sdk";
const beam = new BeamClient({ apiKey: process.env.BEAM_API_KEY! });
await beam.prepareProviderTransfer({
sources: [
S3CompatibleProviderConfig.create({
provider: "wasabi",
bucket: "my-bucket",
key: "input/file.bin",
region: "us-east-1",
endpoint_url: "https://s3.us-east-1.wasabisys.com",
access_key_id: process.env.WASABI_ACCESS_KEY_ID!,
secret_access_key: process.env.WASABI_SECRET_ACCESS_KEY!
})
],
destinations: [
S3CompatibleProviderConfig.create({
provider: "minio",
bucket: "archive",
key: "file.bin",
endpoint_url: "https://minio.example.com",
force_path_style: true,
access_key_id: process.env.MINIO_ACCESS_KEY_ID!,
secret_access_key: process.env.MINIO_SECRET_ACCESS_KEY!
})
],
name: "S3-compatible transfer"
});Use S3ProviderConfig for ordinary AWS S3 if preferred, and keep using
R2ProviderConfig for existing Cloudflare R2 code. Use
S3CompatibleProviderConfig when a provider needs a custom S3-compatible
endpoint.
For low-level raw transfer configs, use createRawTransfer; lifecycle transport still goes through NATS.
Route Streaming And Payload Size
Provider transfers use signed_url_v2 and transfer-client-control/v3. Before route streaming, S3, R2, and S3-compatible destinations create one metadata-bearing multipart upload per source/destination object. Its deduplicated manifest contains complete/abort and final HEAD controls, expected object size/count, required Beam object metadata, and exactly ceil(max_part_number / 1000) unique URLs in each of list_page_urls and staging_list_urls. Staging pages fix MaxKeys=1000; keys are ordered by unsigned UTF-8 bytes, page zero omits StartAfter, and later pages start after the preceding page's last key. Per-route batches carry only the stable group ID and route-attempt metadata. Part number is source_chunk_index + 1, and retries overwrite that same part.
The client signs up to 64 routes concurrently by default and emits a 32-route bootstrap batch followed by 256-route steady batches. Out-of-order signing completions are buffered until the next deterministic delivery index, keeping batch contents reproducible. The stream ID derives from the transfer and immutable plan identity, and each ordered batch ID includes its route-coordinate checksum. Manual multi-destination attachment requires delivery_index on every route. Encoded MessagePack requests still split under maxPayloadBytes (24 MiB by default), and lifecycle mutations retry transient failures up to three times with the same request identity. waitForTransfer subscribes to the API-key-owned, at-most-once terminal signal before its first status read and reconciles every signal through authoritative status; subscription failure degrades to the same jittered 15-to-30-second status fallback. Call close() when the client is no longer needed; it also closes outstanding terminal waiters.
Hippius uses genuine non-multipart v2 routes, so its manifest is empty and group-level final HEAD verification is not available from that provider flow.
NATS requires this guard because the broker rejects messages above its configured max_payload. This limit applies only to lifecycle/control metadata; transfer file bytes do not flow through NATS.
