npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

@zebec-network/zebec-stream-sdk

v3.3.0

Published

This is an SDK for interacting with ZEBEC Stream Program in solana

Readme

Zebec Stream SDK

A TypeScript SDK for interacting with the Zebec Stream protocol on Solana. This SDK provides a comprehensive interface for creating, managing, and interacting with payment streams on the Zebec Network.

Features

  • Stream Management: Create, cancel, pause, resume, and withdraw from payment streams
  • Token Streaming: SPL token streaming with configurable cliff, frequency, and duration
  • Tiered Fee System: Dynamic fee calculation based on stream amount via on-chain fee tiers
  • Token Whitelisting: Admin-controlled token whitelist with full metadata resolution via Metaplex
  • Admin Operations: Initialize and update global stream configuration, fee tiers, and fee vaults
  • Flexible Permissions: Granular per-stream control — cancellation, transfer, topup, pause, and rate update permissions
  • PDA Utilities: Helpers for deriving stream config and stream vault program-derived addresses
  • Provider Abstractions: Separate read-only and read-write provider helpers
  • Type Safety: Full TypeScript support with comprehensive type definitions

Installation

npm install @zebec-network/zebec-stream-sdk
yarn add @zebec-network/zebec-stream-sdk

Quick Start

Setting Up the Service

import { Connection } from "@solana/web3.js";
import { ZebecStreamService, createAnchorProvider } from "@zebec-network/zebec-stream-sdk";

// Create a connection to devnet or mainnet-beta
const connection = new Connection("https://api.devnet.solana.com");

// Create an AnchorProvider using your wallet
const provider = createAnchorProvider(connection, wallet);

// Initialize the service with a config name and network
const streamService = ZebecStreamService.create("my-app-config", provider, "devnet");

Creating a Stream

const tx = await streamService.createStream({
  sender: "SenderPublicKeyHere",
  receiver: "ReceiverPublicKeyHere",
  streamToken: "TokenMintAddressHere",
  amount: "1000",              // Amount in human-readable token units
  duration: 86400,             // Total stream duration in seconds (1 day)
  autoWithdrawFrequency: 3600, // Auto-withdrawal interval in seconds (1 hour)
  streamName: "Monthly Salary",
  startNow: true,
  startTime: Math.floor(Date.now() / 1000),
  cliffPercentage: 0,
  automaticWithdrawal: true,
  cancelableByRecipient: true,
  cancelableBySender: true,
  isPausable: true,
  transferableByRecipient: false,
  transferableBySender: false,
  canTopup: true,
  rateUpdatable: false,
});

const signature = await tx.execute();
console.log("Stream created:", signature);

API Reference

ZebecStreamService

The main service class for interacting with Zebec streams.

ZebecStreamService.create(streamConfigName, provider, network)

Creates a new service instance. Validates that the provider connection network matches the specified network.

static create(
  streamConfigName: string,
  provider: Provider,
  network: "mainnet-beta" | "devnet"
): ZebecStreamService

| Parameter | Type | Description | | --- | --- | --- | | streamConfigName | string | Unique name identifying the stream config PDA | | provider | Provider | Anchor or readonly provider | | network | RpcNetwork | "mainnet-beta" or "devnet" |


Stream Operations

createStream(params)

Creates a new payment stream. Automatically fetches the fee quote from the Zebec backend and includes the fee transfer instruction in the transaction.

Parameters (CreateStreamParams):

| Field | Type | Description | | --- | --- | --- | | sender | Address | Sender's public key | | receiver | Address | Recipient's public key | | streamToken | Address | SPL token mint address | | amount | Numeric | Amount to stream in human-readable token units | | duration | number | Stream duration in seconds | | autoWithdrawFrequency | number | Auto-withdrawal interval in seconds (must be in config's allowed frequencies when automaticWithdrawal is true) | | streamName | string | Human-readable stream name (max 128 bytes) | | startNow | boolean | Whether to start immediately | | startTime | number | Unix timestamp for scheduled start | | cliffPercentage | Numeric | Percentage of amount locked until cliff expires | | automaticWithdrawal | boolean | Enable automatic withdrawals | | cancelableByRecipient | boolean | Allow recipient to cancel | | cancelableBySender | boolean | Allow sender to cancel | | isPausable | boolean | Allow stream to be paused | | transferableByRecipient | boolean | Allow recipient to transfer | | transferableBySender | boolean | Allow sender to transfer | | canTopup | boolean | Allow adding funds to stream | | rateUpdatable | boolean | Allow rate modifications | | feePayer? | Address | Optional custom fee payer (defaults to sender) | | streamMetadataKeypair? | Keypair | Optional custom metadata keypair |

Returns: Promise<TransactionPayload>


cancelStream(params)

Cancels an existing stream. Either sender or receiver can cancel (if allowed by stream permissions).

Parameters (CancelStreamParams):

| Field | Type | Description | | --- | --- | --- | | streamMetadata | Address | Stream metadata account address | | user | Address | User canceling the stream (must be sender or receiver) | | feePayer? | Address | Optional custom fee payer |

Returns: Promise<TransactionPayload>


pauseResumeStream(params)

Toggles a stream between paused and active states. Only the sender can call this.

Parameters:

| Field | Type | Description | | --- | --- | --- | | streamMetadata | Address | Stream metadata account address |

Returns: Promise<TransactionPayload>


withdrawStream(params)

Withdraws vested tokens from a stream to the receiver.

Parameters (WithdrawStreamParams):

| Field | Type | Description | | --- | --- | --- | | streamMetadata | Address | Stream metadata account address | | receiver | Address | Recipient's public key | | withdrawer? | Address | Optional custom withdrawer (defaults to receiver) | | feePayer? | Address | Optional custom fee payer |

Returns: Promise<TransactionPayload>


changeStreamReceiver(params)

Transfers stream ownership to a new recipient.

Parameters (ChangeStreamReceiverParams):

| Field | Type | Description | | --- | --- | --- | | streamMetadata | Address | Stream metadata account address | | newRecipient | Address | New recipient's public key | | signer | Address | Currently authorized signer |

Returns: Promise<TransactionPayload>


Information Retrieval

getStreamMetadataInfo(streamMetadata, commitment?)

Retrieves detailed information about a stream.

Returns: Promise<StreamMetadataInfo>

const info = await streamService.getStreamMetadataInfo("StreamMetadataAddressHere");
console.log(info.parties.sender.toBase58());
console.log(info.financials.depositedAmount); // human-readable
console.log(info.schedule.startTime);
console.log(info.permissions.isPausable);

getStreamConfigInfo(configName, commitment?)

Retrieves the global stream configuration for a given config name.

Returns: Promise<StreamConfigInfo>

const config = await streamService.getStreamConfigInfo("my-app-config");
console.log(config.frequencies);   // allowed auto-withdraw intervals
console.log(config.feeTiers);      // tiered fee schedule
console.log(config.feeVault.toBase58());

getWhitelistedTokens(configName, commitment?)

Fetches the list of whitelisted tokens with full on-chain mint info and Metaplex metadata.

Returns: Promise<TokenMetadata[]>

const tokens = await streamService.getWhitelistedTokens("my-app-config");
tokens.forEach(t => {
  console.log(t.metadata?.symbol, t.mint.toBase58());
});

Admin Operations

initializeStreamConfig(params)

Initializes the global stream configuration (admin only, one-time setup).

Parameters (InitializeStreamConfigParams):

await streamService.initializeStreamConfig({
  admin: adminAddress, // optional, defaults to provider wallet
  config: {
    baseFeePercent: "0.1",
    platformFeePercent: "0.05",
    frequencies: [3600, 86400, 604800], // hourly, daily, weekly
    withdrawAccount: "WithdrawAccountAddressHere",
    feeVault: "FeeVaultAddressHere",
    feeTiers: [
      { minThreshold: "0",     maxThreshold: "1000",  feeRateInPercent: "1.0" },
      { minThreshold: "1000",  maxThreshold: "10000", feeRateInPercent: "0.75" },
      { minThreshold: "10000", maxThreshold: "99999999", feeRateInPercent: "0.5" },
    ],
  },
});

updateStreamConfig(params)

Updates an existing stream configuration (admin only).

Parameters (UpdateStreamConfigParams): Same shape as InitializeStreamConfigParams.

Returns: Promise<TransactionPayload>


whiteListTokens(params)

Adds token mint addresses to the whitelist (admin only).

Parameters (WhiteListTokensParams):

| Field | Type | Description | | --- | --- | --- | | admin | Address | Admin public key | | tokens | Address[] | Array of token mint addresses to whitelist |

Returns: Promise<TransactionPayload>


Low-Level Instruction Builders

Each high-level method has a corresponding instruction builder for composing custom transactions:

| Method | Returns | | --- | --- | | getCreateStreamInstruction(...) | Promise<TransactionInstruction> | | getCancelStreamInstruction(...) | Promise<TransactionInstruction> | | getPauseResumeStreamInstruction(...) | Promise<TransactionInstruction> | | getWithdrawStreamInstruction(...) | Promise<TransactionInstruction> | | getChangeStreamReceiverInstruction(...) | Promise<TransactionInstruction> | | getWhitelistTokensInstruction(...) | Promise<TransactionInstruction> | | getInitializeStreamConfigInstruction(...) | Promise<TransactionInstruction> | | getUpdateStreamConfigInstruction(...) | Promise<TransactionInstruction> |


Provider Setup

AnchorProvider (Read/Write)

Use for operations that sign transactions:

import { createAnchorProvider } from "@zebec-network/zebec-stream-sdk";

const provider = createAnchorProvider(connection, wallet, {
  commitment: "confirmed",
  preflightCommitment: "confirmed",
});

ReadonlyProvider (Read-Only)

Use for read-only queries without a wallet:

import { createReadonlyProvider } from "@zebec-network/zebec-stream-sdk";

const provider = createReadonlyProvider(connection, optionalWalletAddress);

PDA Utilities

import { deriveStreamConfigPda, deriveStreamVaultPda } from "@zebec-network/zebec-stream-sdk";

// Derive the stream config PDA
const [configPda] = deriveStreamConfigPda("my-app-config", programId);

// Derive the stream vault PDA for a given stream metadata address
const [vaultPda] = deriveStreamVaultPda(streamMetadataAddress, programId);

Types

StreamMetadataInfo

type StreamMetadataInfo = {
  address: PublicKey;
  parties: {
    sender: PublicKey;
    receiver: PublicKey;
  };
  financials: {
    streamToken: PublicKey;
    cliffPercentage: number;
    depositedAmount: string; // human-readable
    withdrawnAmount: string; // human-readable
  };
  schedule: {
    startTime: number;
    endTime: number;
    lastWithdrawTime: number;
    frequency: number;
    duration: number;
    pausedTimestamp: number;
    pausedInterval: number;
    canceledTimestamp: number;
  };
  permissions: {
    cancelableBySender: boolean;
    cancelableByRecipient: boolean;
    automaticWithdrawal: boolean;
    transferableBySender: boolean;
    transferableByRecipient: boolean;
    canTopup: boolean;
    isPausable: boolean;
    rateUpdatable: boolean;
  };
  streamName: string;
};

StreamConfigInfo

type StreamConfigInfo = {
  address: PublicKey;
  admin: PublicKey;
  withdrawerAccount: PublicKey;
  whitelistedTokens: PublicKey[];
  platformFee: number;
  baseFee: number;
  frequencies: number[];
  feeTiers: FeeTier[];
  feeVault: PublicKey;
};

FeeTier

type FeeTier = {
  minThreshold: Numeric; // minimum USD amount for this tier
  maxThreshold: Numeric; // maximum USD amount for this tier
  feeRateInPercent: Numeric;
};

StreamFeeInfo

Returned by the Zebec backend fee quote API and used internally during stream creation:

type StreamFeeInfo = {
  tokenSymbol: string;
  mintAddress: string;
  chain: string;
  streamAmount: string;
  streamAmountUi: string;
  tokenPriceUsd: number;
  streamAmountUsd: number;
  feeTier: { tier: number; range: string; feeRatePercent: number };
  feeRatePercent: number;
  feeAmountUsd: number;
  feeToken: { symbol: string; decimals: number; priceUsd: number; mintAddress: string };
  feeAmount: number;
  feeAmountRaw: string;
};

TokenMetadata

type TokenMetadata = {
  mint: PublicKey;
  decimals: number;
  freezeAuthority: PublicKey | null;
  supply: string;
  isInitialized: boolean;
  mintAuthority: PublicKey | null;
  metadata: {
    address: PublicKey;
    updateAuthority: PublicKey;
    name: string;
    symbol: string;
    uri: string;
  } | null;
};

Usage Examples

Complete Stream Lifecycle

import { Connection } from "@solana/web3.js";
import { ZebecStreamService, createAnchorProvider } from "@zebec-network/zebec-stream-sdk";

const connection = new Connection("https://api.devnet.solana.com");
const provider = createAnchorProvider(connection, wallet);
const streamService = ZebecStreamService.create("my-app-config", provider, "devnet");

// 1. Create a stream
const createTx = await streamService.createStream({
  sender: senderAddress,
  receiver: receiverAddress,
  streamToken: tokenMintAddress,
  amount: "1000",
  duration: 86400,
  autoWithdrawFrequency: 3600,
  streamName: "Test Stream",
  startNow: true,
  startTime: Math.floor(Date.now() / 1000),
  cliffPercentage: 0,
  automaticWithdrawal: true,
  cancelableByRecipient: false,
  cancelableBySender: true,
  isPausable: true,
  transferableByRecipient: false,
  transferableBySender: false,
  canTopup: false,
  rateUpdatable: false,
});
const streamSignature = await createTx.execute();
console.log("Stream created:", streamSignature);

// 2. Fetch stream info
const streamInfo = await streamService.getStreamMetadataInfo(streamMetadataAddress);
console.log("Deposited:", streamInfo.financials.depositedAmount);

// 3. Withdraw vested tokens
const withdrawTx = await streamService.withdrawStream({
  streamMetadata: streamMetadataAddress,
  receiver: receiverAddress,
});
await withdrawTx.execute();

// 4. Cancel the stream
const cancelTx = await streamService.cancelStream({
  streamMetadata: streamMetadataAddress,
  user: senderAddress,
});
await cancelTx.execute();

Pause and Resume a Stream

const pauseTx = await streamService.pauseResumeStream({
  streamMetadata: streamMetadataAddress,
});
await pauseTx.execute(); // toggles between paused and active

Change Stream Receiver

const changeTx = await streamService.changeStreamReceiver({
  streamMetadata: streamMetadataAddress,
  newRecipient: newRecipientAddress,
  signer: currentRecipientAddress,
});
await changeTx.execute();

Fetch Whitelisted Tokens

const tokens = await streamService.getWhitelistedTokens("my-app-config");
tokens.forEach((token) => {
  console.log(token.metadata?.name, token.metadata?.symbol);
  console.log("Mint:", token.mint.toBase58());
  console.log("Decimals:", token.decimals);
});

Error Handling

try {
  const tx = await streamService.createStream(params);
  const signature = await tx.execute();
  console.log("Success:", signature);
} catch (error) {
  if (error.message.includes("Invalid stream frequency")) {
    console.error("autoWithdrawFrequency must be one of the config's allowed frequencies");
  } else {
    console.error("Stream creation failed:", error);
  }
}

Constants

| Constant | Description | | --- | --- | | STREAM_PROGRAM_ID | Program ID per network (zSTRMmYcFF8SPdHmsAmAUjBnx4zDHvnqqGz2mPcc5QC) | | STREAM_PROGRAM_LOOKUP_TABLE_ADDRESS | Address lookup table per network | | SUPERAPP_BACKEND_URL | Zebec backend URL per network (used for fee quotes) | | STREAM_NAME_BUFFER_SIZE | Fixed buffer size for stream names (128 bytes) |


Network Support

| Network | Status | | --- | --- | | Mainnet Beta | Supported | | Devnet | Supported | | Testnet | Not supported |


Dependencies

| Package | Purpose | | --- | --- | | @coral-xyz/anchor | Anchor framework for Solana program interaction | | @solana/web3.js | Solana Web3 JavaScript API | | @solana/spl-token | SPL token utilities | | @metaplex-foundation/mpl-token-metadata | On-chain token metadata resolution | | @metaplex-foundation/umi | Metaplex UMI framework | | @metaplex-foundation/umi-bundle-defaults | UMI default bundle | | @metaplex-foundation/umi-web3js-adapters | UMI ↔ web3.js adapters | | @zebec-network/core-utils | Zebec core utility functions (BPS conversions, etc.) | | @zebec-network/solana-common | Common Solana helpers (ATAs, transaction payload, etc.) | | bignumber.js | Arbitrary-precision arithmetic for token amounts |


Development

Install Dependencies

npm install

Build

npm run build

Clean Build Artifacts

npm run clean

Run Tests

npm test

Run a Single Test File

npm run test:single -- test/e2e/stream/createStream.test.ts

Format Code

npm run format

Publishing

  1. Bump the version in package.json.

  2. Build the package:

    npm run build
  3. Publish to npm:

    npm publish --access public

Only the dist/ directory is included in the published package (as specified by the files field in package.json).


License

This project is licensed under the MIT License.

Support

For issues and questions: