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/proxy-stream-sdk

v1.7.3

Published

TypeScript SDK for interacting with the Zebec Proxy Stream program on Solana. Enables cross-chain token streaming via proxy — minting/burning Z-tokens, managing user PDAs, and creating/managing payment streams.

Downloads

214

Readme

Zebec Proxy Stream Sdk

TypeScript SDK for interacting with the Zebec Proxy Stream program on Solana. Enables cross-chain token streaming via proxy — minting/burning Z-tokens, managing user PDAs, and creating/managing payment streams.

Table of Contents


Installation

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

Quick Setup

import { Connection } from "@solana/web3.js";
import { Wallet } from "@coral-xyz/anchor";
import {
  createAnchorProvider,
  createReadonlyProvider,
  ProxyStreamService,
} from "@zebec-network/proxy-stream-sdk";

const connection = new Connection(process.env.DEVNET_RPC_URL!, "confirmed");

// For read-only operations (no wallet required)
const readonlyProvider = createReadonlyProvider(connection);
const readService = ProxyStreamService.create(readonlyProvider, "devnet");

// For write operations (wallet required)
const wallet = new Wallet(keypair); // Anchor Wallet wrapping a Keypair
const provider = createAnchorProvider(connection, wallet);
const service = ProxyStreamService.create(provider, "devnet");

Environment Variables

Create a .env file in the project root. Required for tests and local usage.

# Mainnet RPC endpoint
RPC_URL=https://api.mainnet-beta.solana.com

# Devnet RPC endpoint
DEVNET_RPC_URL=https://api.devnet.solana.com

# JSON array of base58-encoded secret keys for mainnet
MAINNET_SECRET_KEYS=["<base58-secret-key-1>"]

# JSON array of base58-encoded secret keys for devnet
DEVNET_SECRET_KEYS=["<base58-secret-key-1>","<base58-secret-key-2>"]

API Reference

Providers

createAnchorProvider(connection, wallet, options?)

Creates an Anchor provider for signing and submitting transactions.

| Parameter | Type | Description | | ------------ | ----------------- | --------------------------------- | | connection | Connection | Solana RPC connection | | wallet | AnchorWallet | Wallet with signing capability | | options | ConfirmOptions? | Optional confirmation options |

Returns: AnchorProvider

createReadonlyProvider(connection, walletAddress?)

Creates a read-only provider for querying on-chain data without a signer.

| Parameter | Type | Description | | --------------- | ------------ | ----------------------------- | | connection | Connection | Solana RPC connection | | walletAddress | Address? | Optional wallet public key |

Returns: ReadonlyProvider


ProxyStreamService

ProxyStreamService.create(provider, network)

Factory method — the recommended way to instantiate the service.

| Parameter | Type | Description | | ---------- | ------------------------------ | --------------------------- | | provider | Provider \| ReadonlyProvider | Anchor or readonly provider | | network | "mainnet-beta" \| "devnet" | Target Solana network |

Returns: ProxyStreamService


service.initProxyConfig(params)

Initializes the on-chain proxy configuration for a chain. Called once by the admin.

| Field | Type | Description | | ----------- | --------- | ------------------------------------ | | admin | Address | Admin public key | | feeVault | Address | Fee vault public key | | chainId | string | Unique chain identifier | | fee | number | Fee percentage (e.g., 0.5 = 0.5%) | | minAmount | number | Minimum token amount |

Returns: Promise<TransactionPayload>


service.updateProxyConfig(params)

Updates fee or admin of an existing proxy config.

| Field | Type | Description | | ---------- | --------- | ------------------------ | | admin | Address | Current admin public key | | chainId | string | Chain identifier | | fee | number | New fee percentage | | newAdmin | Address | New admin public key |

Returns: Promise<TransactionPayload>


service.getProxyConfig(chainId)

Fetches the on-chain proxy configuration. Works with a readonly provider.

| Parameter | Type | Description | | --------- | -------- | ---------------- | | chainId | string | Chain identifier |

Returns: Promise<ProxyConfigInfo>


service.createToken(params)

Creates a new Z-token (SPL mint), attaches Metaplex metadata, transfers mint authority to the proxy PDA, and whitelists the token in the stream config.

| Field | Type | Description | | ------------------------ | --------- | ---------------------------------------- | | admin | Address | Admin public key | | chainId | string | Chain identifier | | streamConfigName | string | Name of the stream config PDA | | tokenInfo.tokenName | string | Full token name | | tokenInfo.symbol | string | Token symbol | | tokenInfo.metadataUri | string | URI for token metadata JSON | | tokenInfo.decimals | number | Token decimals | | tokenInfo.mintKeypair | Keypair?| Optional mint keypair (auto-generated if omitted) |

Returns: Promise<TransactionPayload>


service.updateZTokenMetadata(params)

Updates Metaplex metadata for an existing Z-token.

| Field | Type | Description | | ----------------------- | --------- | ------------------------ | | admin | Address | Admin public key | | mint | Address | Mint address | | tokenInfo.tokenName | string | New token name | | tokenInfo.symbol | string | New symbol | | tokenInfo.metadataUri | string | New metadata URI |

Returns: Promise<TransactionPayload>


service.createUserPda(params)

Creates an on-chain user PDA and vault for a given L1 wallet hash. Must be called before minting or streaming for a new user.

| Field | Type | Description | | -------------- | ---------------------------------- | ---------------------------------------- | | admin | Address | Fee payer / admin | | chainId | string | Chain identifier | | l1WalletHash | number[] \| Buffer \| Uint8Array | 32-byte SHA-256 hash of the L1 address |

Returns: Promise<TransactionPayload>


service.mintZToken(params)

Mints Z-tokens into a user vault. The signatureHash is a 32-byte SHA-256 hash of the L1 deposit signature, used for replay protection.

| Field | Type | Description | | --------------- | ---------------------------------- | ----------------------------------- | | admin | Address | Admin public key | | chainId | string | Chain identifier | | destination | Address | Destination user vault public key | | mint | Address | Z-token mint address | | amount | Numeric | Amount to mint (in human units) | | signatureHash | number[] \| Buffer \| Uint8Array | 32-byte hash for replay protection |

Returns: Promise<TransactionPayload>


service.burnZToken(params)

Burns Z-tokens from a user's vault (used when bridging back to L1).

| Field | Type | Description | | ---------------------- | ---------------------------------- | ----------------------------------------- | | proxyAdmin | Address | Admin public key | | chainId | string | Chain identifier | | mint | Address | Z-token mint address | | receiverL1WalletHash | number[] \| Buffer \| Uint8Array | 32-byte hash of receiver's L1 address | | amount | Numeric | Amount to burn (in human units) |

Returns: Promise<TransactionPayload>


service.createStream(params)

Creates a payment stream from a sender's user vault to a receiver's user vault.

See CreateStreamParams for the full parameter list.

Returns: Promise<TransactionPayload>


service.pauseResumeStream(params)

Toggles pause/resume state on an existing pausable stream (same method for both).

| Field | Type | Description | | ------------------- | ---------------------------------- | --------------------------------------- | | proxyAdmin | Address | Admin public key | | chainId | string | Chain identifier | | senderL1WalletHash| number[] \| Buffer \| Uint8Array | 32-byte hash of sender's L1 address | | streamMetadata | Address | Stream metadata account public key |

Returns: Promise<TransactionPayload>


service.cancelStream(params)

Cancels an existing stream. Remaining tokens are returned to the sender's vault.

| Field | Type | Description | | ---------------------- | ---------------------------------- | --------------------------------------- | | proxyAdmin | Address | Admin public key | | chainId | string | Chain identifier | | senderL1WalletHash | number[] \| Buffer \| Uint8Array | 32-byte hash of sender's L1 address | | receiverL1WalletHash | number[] \| Buffer \| Uint8Array | 32-byte hash of receiver's L1 address | | streamMetadata | Address | Stream metadata account public key |

Returns: Promise<TransactionPayload>


service.withdrawStream(params)

Withdraws unlocked tokens from a stream into the receiver's user vault.

| Field | Type | Description | | ---------------------- | ---------------------------------- | --------------------------------------- | | proxyAdmin | Address | Admin public key | | chainId | string | Chain identifier | | streamConfigName | string | Name of the stream config PDA | | receiverL1WalletHash | number[] \| Buffer \| Uint8Array | 32-byte hash of receiver's L1 address | | streamMetadata | Address | Stream metadata account public key |

Returns: Promise<TransactionPayload>


service.emergencyPause(params)

Triggers an emergency pause on all proxy operations.

| Field | Type | Description | | ------- | --------- | ----------------- | | admin | Address | Admin public key |

Returns: Promise<TransactionPayload>


service.createL1SilverCard(params)

Creates a new L1 Silver Card for a user. Transfers the specified L1 token amount from the user vault to the card vault and records the purchase on-chain.

| Field | Type | Description | | -------------------- | ---------------------------------- | ---------------------------------------------------- | | proxyAdmin | Address | Admin / fee payer | | chainId | string | Chain identifier | | userL1WalletHash | number[] \| Buffer \| Uint8Array | 32-byte SHA-256 hash of the user's L1 address | | currency | string | Fiat currency code (e.g., "USD") | | emailHash | number[] \| Buffer \| Uint8Array | 32-byte SHA-256 hash of the user's email | | index | bigint | Unique card index (use getNextL1CardIndex()) | | l1TokenMint | Address | Mint address of the L1 token used for payment | | l1TokenAmount | Numeric | Token amount to charge (in human units) | | l1TokenPriceInUsd | Numeric | Token price in USD micro-units at time of purchase |

Returns: Promise<TransactionPayload>


service.loadL1CarbonCard(params)

Reloads (tops up) an existing L1 Carbon Card. Transfers the specified L1 token amount from the user vault to the card vault and records the reload on-chain.

| Field | Type | Description | | -------------------- | ---------------------------------- | ---------------------------------------------------- | | proxyAdmin | Address | Admin / fee payer | | chainId | string | Chain identifier | | userL1WalletHash | number[] \| Buffer \| Uint8Array | 32-byte SHA-256 hash of the user's L1 address | | currency | string | Fiat currency code (e.g., "USD") | | emailHash | number[] \| Buffer \| Uint8Array | 32-byte SHA-256 hash of the user's email | | index | bigint | Unique card index (use getNextL1CardIndex()) | | l1TokenMint | Address | Mint address of the L1 token used for payment | | l1TokenAmount | Numeric | Token amount to charge (in human units) | | l1TokenPriceInUsd | Numeric | Token price in USD micro-units at time of reload | | reloadCardId | string | Identifier of the existing card to reload |

Returns: Promise<TransactionPayload>


service.getNextL1CardIndex()

Returns the next available card index from the on-chain cardL1Index account. Call this before createL1SilverCard or loadL1CarbonCard to obtain a valid index.

Returns: Promise<bigint>


PDA Utilities

import {
  deriveProxyConfigPda,
  deriveMintAuthorityPda,
  deriveCheckAccountPda,
  deriveUserPda,
  deriveUserVaultPda,
} from "@zebec-network/proxy-stream-sdk";

// Proxy config PDA for a chain
const [proxyConfig, bump] = deriveProxyConfigPda(chainId, programId);

// Mint authority PDA — controls Z-token minting
const [mintAuthority] = deriveMintAuthorityPda(programId);

// Check account PDA — replay protection for mint operations
const [checkAccount] = deriveCheckAccountPda(signatureHash, programId);

// User PDA for an L1 wallet hash
const [userPda] = deriveUserPda(chainId, l1WalletHash, programId);

// User vault PDA — holds user tokens
const [userVault] = deriveUserVaultPda(userPda, programId);

Types

CreateStreamParams

| Field | Type | Required | Description | | ------------------------- | ---------------------------------- | -------- | ------------------------------------------ | | proxyAdmin | Address | yes | Admin / fee payer | | chainId | string | yes | Chain identifier | | streamConfigName | string | yes | Name of the stream config PDA | | senderL1WalletHash | number[] \| Buffer \| Uint8Array | yes | 32-byte SHA-256 hash of sender's L1 address | | receiverL1WalletHash | number[] \| Buffer \| Uint8Array | yes | 32-byte SHA-256 hash of receiver's L1 address | | streamToken | Address | yes | Token mint address | | streamName | string | yes | Human-readable stream name | | amount | Numeric | yes | Token amount (in human units) | | duration | number | yes | Stream duration in seconds | | startNow | boolean | yes | Start immediately | | startTime | number | yes | Unix timestamp (used when startNow is false) | | automaticWithdrawal | boolean | yes | Enable auto-withdrawal | | autoWithdrawFrequency | number | no | Withdrawal interval in seconds | | cancelableByRecipient | boolean | yes | Allow recipient to cancel | | cancelableBySender | boolean | yes | Allow sender to cancel | | cliffPercentage | Numeric | yes | Cliff as percentage (0–100) | | isPausable | boolean | yes | Allow pausing | | rateUpdatable | boolean | yes | Allow rate updates | | transferableByRecipient | boolean | yes | Allow recipient to transfer | | transferableBySender | boolean | yes | Allow sender to transfer | | canTopup | boolean | yes | Allow topping up | | streamMetadataKeypair | Keypair | no | Keypair for metadata account (auto-generated if omitted) |

ProxyConfigInfo

type ProxyConfigInfo = {
  address: PublicKey;
  fee: string;               // e.g. "0.5" (percentage)
  minAmount: string;
  proxyAdmin: PublicKey;
  mintableTokens: PublicKey[];
  feeVault: PublicKey;
  emergencyPaused: boolean;
  chainId: string;
};

Usage Examples

Initialize proxy config

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

const provider = createAnchorProvider(connection, wallet);
const service = ProxyStreamService.create(provider, "devnet");

const txPayload = await service.initProxyConfig({
  admin: wallet.publicKey,
  feeVault: "A8TFmgg65YmA4LG7aFKLA1Fqg1Rb3kxSLYgio5YmNUgJ",
  chainId: "DASH",
  fee: 0.5,       // 0.5%
  minAmount: 1000,
});

const signature = await txPayload.execute({ commitment: "confirmed" });
console.log("Tx:", signature);

Get proxy config

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

const provider = createReadonlyProvider(connection);
const service = ProxyStreamService.create(provider, "devnet");

const config = await service.getProxyConfig("DASH");
console.log(config);

Create Z token

import { Keypair } from "@solana/web3.js";

const mintKeypair = Keypair.generate();
console.log("New mint:", mintKeypair.publicKey.toString());

const txPayload = await service.createToken({
  admin: wallet.publicKey,
  chainId: "DASH",
  streamConfigName: "Config-001",
  tokenInfo: {
    tokenName: "Z Dash USDC",
    symbol: "ZDUSDC",
    metadataUri: "https://example.com/zdusdc.json",
    decimals: 9,
    mintKeypair,
  },
});

const signature = await txPayload.execute({ commitment: "confirmed" });

Mint Z token

import { hashSHA256ToBuffer } from "@zebec-network/core-utils";
import { deriveUserPda, deriveUserVaultPda } from "@zebec-network/proxy-stream-sdk";

const chainId = "DASH";
const l1WalletHash = await hashSHA256ToBuffer("0xc0ffee254729296a45a3885639AC7E10F9d54979");

// Ensure user PDA exists first
const [userPda] = deriveUserPda(chainId, l1WalletHash, service.proxyStreamProgramId);
if (!(await connection.getAccountInfo(userPda))) {
  const tx = await service.createUserPda({ admin: wallet.publicKey, chainId, l1WalletHash });
  await tx.execute({ commitment: "confirmed" });
}

const [destination] = deriveUserVaultPda(userPda, service.proxyStreamProgramId);
const signatureHash = await hashSHA256ToBuffer(`deposit-${Date.now()}`);

const txPayload = await service.mintZToken({
  admin: wallet.publicKey,
  chainId,
  destination,
  mint: "De31sBPcDejCVpZZh1fq8SNs7AcuWcBKuU3k2jqnkmKc",
  amount: 5000,
  signatureHash,
});

const signature = await txPayload.execute({ commitment: "confirmed" });

Burn Z token

const txPayload = await service.burnZToken({
  mint: "De31sBPcDejCVpZZh1fq8SNs7AcuWcBKuU3k2jqnkmKc",
  chainId: "DASH",
  proxyAdmin: wallet.publicKey,
  receiverL1WalletHash: l1WalletHash,
  amount: 2000,
});

const signature = await txPayload.execute({ commitment: "confirmed" });

Create stream

import { Keypair } from "@solana/web3.js";
import { hashSHA256ToBuffer } from "@zebec-network/core-utils";

const senderL1WalletHash = await hashSHA256ToBuffer("0xSenderEthAddress");
const receiverL1WalletHash = await hashSHA256ToBuffer("0xReceiverEthAddress");
const streamMetadataKeypair = Keypair.generate();

const txPayload = await service.createStream({
  proxyAdmin: wallet.publicKey,
  chainId: "DASH",
  streamConfigName: "Config-001",
  senderL1WalletHash,
  receiverL1WalletHash,
  streamToken: "De31sBPcDejCVpZZh1fq8SNs7AcuWcBKuU3k2jqnkmKc",
  streamName: "My Payment Stream",
  amount: 200,
  duration: 200,
  startNow: true,
  startTime: 0,
  automaticWithdrawal: false,
  autoWithdrawFrequency: 0,
  cancelableByRecipient: false,
  cancelableBySender: true,
  cliffPercentage: 0,
  isPausable: true,
  rateUpdatable: false,
  transferableByRecipient: false,
  transferableBySender: false,
  canTopup: false,
  streamMetadataKeypair,
});

const signature = await txPayload.execute({ commitment: "confirmed" });
console.log("Stream metadata:", streamMetadataKeypair.publicKey.toBase58());

Pause / Resume stream

// Same method toggles between paused and active
const txPayload = await service.pauseResumeStream({
  proxyAdmin: wallet.publicKey,
  chainId: "DASH",
  senderL1WalletHash,
  streamMetadata: streamMetadataKeypair.publicKey,
});

const signature = await txPayload.execute({ commitment: "confirmed" });

Cancel stream

const txPayload = await service.cancelStream({
  proxyAdmin: wallet.publicKey,
  chainId: "DASH",
  senderL1WalletHash,
  receiverL1WalletHash,
  streamMetadata: streamMetadataKeypair.publicKey,
});

const signature = await txPayload.execute({ commitment: "confirmed" });

Withdraw stream

const txPayload = await service.withdrawStream({
  proxyAdmin: wallet.publicKey,
  chainId: "DASH",
  streamConfigName: "Config-001",
  receiverL1WalletHash,
  streamMetadata: streamMetadataKeypair.publicKey,
});

const signature = await txPayload.execute({ commitment: "confirmed" });

L1 Card Features

Create L1 Silver Card

Creates a new Silver Card for a user, charging the specified L1 token amount.

import { hashSHA256ToBuffer } from "@zebec-network/core-utils";

const userL1WalletHash = await hashSHA256ToBuffer("0xUserEthAddress");
const emailHash = await hashSHA256ToBuffer("[email protected]");

// Fetch the next available card index before creating
const index = await service.getNextL1CardIndex();

const txPayload = await service.createL1SilverCard({
  proxyAdmin: wallet.publicKey,
  chainId: "DASH",
  userL1WalletHash,
  currency: "USD",
  emailHash,
  index,
  l1TokenMint: "De31sBPcDejCVpZZh1fq8SNs7AcuWcBKuU3k2jqnkmKc",
  l1TokenAmount: 100,
  l1TokenPriceInUsd: 1_000_000, // price in USD micro-units (1 USD = 1_000_000)
});

const signature = await txPayload.execute({ commitment: "confirmed" });
console.log("Silver card created:", signature);

Load (Reload) L1 Carbon Card

Tops up an existing Carbon Card by transferring additional L1 tokens.

import { hashSHA256ToBuffer } from "@zebec-network/core-utils";

const userL1WalletHash = await hashSHA256ToBuffer("0xUserEthAddress");
const emailHash = await hashSHA256ToBuffer("[email protected]");

const index = await service.getNextL1CardIndex();

const txPayload = await service.loadL1CarbonCard({
  proxyAdmin: wallet.publicKey,
  chainId: "DASH",
  userL1WalletHash,
  currency: "USD",
  emailHash,
  index,
  l1TokenMint: "De31sBPcDejCVpZZh1fq8SNs7AcuWcBKuU3k2jqnkmKc",
  l1TokenAmount: 50,
  l1TokenPriceInUsd: 1_000_000,
  reloadCardId: "existing-card-id",
});

const signature = await txPayload.execute({ commitment: "confirmed" });
console.log("Carbon card reloaded:", signature);

Get Next L1 Card Index

Reads the current global card index from the on-chain cardL1Index account. Always call this immediately before creating or reloading a card to avoid index collisions.

const index = await service.getNextL1CardIndex();
console.log("Next card index:", index.toString());

Development

Prerequisites

  • Node.js >= 18
  • npm / yarn / pnpm

Install dependencies

npm install

Build

Compiles TypeScript to dist/.

npm run build

Clean

Removes the dist/ directory.

npm run clean

Format

Formats source files using Biome.

npm run format

Run all tests

Runs the full e2e test suite. Requires .env to be configured with devnet credentials.

npm test

Run a single test file

npm run test:single test/e2e/getProxyConfig.test.ts
npm run test:single test/e2e/initProxyconfig.test.ts
npm run test:single test/e2e/updateProxyConfig.test.ts
npm run test:single test/e2e/createToken.test.ts
npm run test:single test/e2e/updateZTokenMetadata.test.ts
npm run test:single test/e2e/createUserPda.test.ts
npm run test:single test/e2e/mintZtoken.test.ts
npm run test:single test/e2e/burnZtoken.test.ts
npm run test:single test/e2e/stream/createStream.test.ts
npm run test:single test/e2e/stream/pauseResumeStream.test.ts
npm run test:single test/e2e/stream/cancelStream.test.ts
npm run test:single test/e2e/stream/withdrawStream.test.ts

Program IDs

| Network | Program ID | | ------------ | ----------------------------------------------- | | Devnet | 5SaauzPGka7m7pTis7BXGwTh1zFYpGnU3wSQrehZDgJH | | Mainnet-Beta | TBD |


License

MIT — see LICENSE for details.

Author

Zebec Network | Ashish Sapkota