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

@goodsdks/streaming-sdk

v1.0.0

Published

TypeScript SDK for Superfluid streaming flows on Celo and Base, with GoodDollar-aware token resolution, GDA pool helpers, live CFA reads, and subgraph-backed historical queries.

Downloads

164

Readme

@goodsdks/streaming-sdk

TypeScript SDK for Superfluid streaming flows on Celo and Base, with GoodDollar-aware token resolution, GDA pool helpers, live CFA reads, and subgraph-backed historical queries.

Features

  • Stream lifecycle helpers for create, update, delete, and createOrUpdate
  • Auto-resolved default tokens:
    • Celo -> G$
    • Base -> SUP
  • Live CFA reads through the Superfluid forwarder (getFlowRate, getFlowInfo)
  • Indexed stream, balance, balance-history, pool-membership, and reserve queries through the Superfluid subgraph
  • GDA pool connect/disconnect helpers plus member-scoped pool listing and status queries
  • Environment-aware token resolution for production, staging, and development

Installation

yarn add @goodsdks/streaming-sdk viem

Quick Start

import { StreamingSDK, calculateFlowRate } from "@goodsdks/streaming-sdk"
import { parseEther } from "viem"

const sdk = new StreamingSDK(publicClient, walletClient, {
  environment: "production",
})

const flowRate = calculateFlowRate(parseEther("100"), "month")

await sdk.createOrUpdateStream({
  receiver: "0x...",
  flowRate,
})

Address Resolution

The SDK resolves addresses from two sources:

  • Superfluid protocol forwarders come from @sfpro/sdk address maps.
    • CFA_FORWARDER_ADDRESSES
    • GDA_FORWARDER_ADDRESSES
  • GoodDollar token addresses come from this package's environment maps.
    • getG$Token(chainId, environment)
    • getSUPToken(chainId, environment)

That means developers can usually initialize once with an environment and omit token addresses from individual calls:

const sdk = new StreamingSDK(publicClient, walletClient, {
  environment: "staging",
  defaultToken: "G$",
})

You can still override the token per call with either "G$", "SUP", or a raw token address.

StreamingSDK

Write methods

createOrUpdateStream(params)

Uses the recommended CFA forwarder setFlowrate(token, receiver, flowRate) path.

await sdk.createOrUpdateStream({
  receiver: "0x...",
  flowRate: 1500n,
  token: "G$",
})

Passing 0n stops the stream.

createStream(params)

Low-level explicit createFlow wrapper. Prefer createOrUpdateStream() unless you specifically need the one-shot create call.

await sdk.createStream({
  receiver: "0x...",
  flowRate: 1000n,
  token: "G$",
  userData: "0x",
})

updateStream(params)

Low-level explicit updateFlow wrapper. Prefer createOrUpdateStream() unless you specifically need the separate update call.

await sdk.updateStream({
  receiver: "0x...",
  newFlowRate: 2000n,
  token: "G$",
  userData: "0x",
})

deleteStream(params)

await sdk.deleteStream({
  receiver: "0x...",
  token: "G$",
  userData: "0x",
})

Live reads

getFlowRate(params)

Reads the current live flow rate directly from the CFA forwarder.

const flowRate = await sdk.getFlowRate({
  sender: "0x...",
  receiver: "0x...",
  token: "G$",
})

getFlowInfo(params)

Returns live flow metadata from the CFA forwarder.

const flowInfo = await sdk.getFlowInfo({
  sender: "0x...",
  receiver: "0x...",
  token: "G$",
})

console.log(flowInfo.flowRate, flowInfo.lastUpdated)

Indexed subgraph reads

getActiveStreams(options)

Returns active streams from the Superfluid subgraph.

const streams = await sdk.getActiveStreams({
  account: "0x...",
  direction: "all",
})

Pagination is supported:

const streams = await sdk.getActiveStreams({
  account: "0x...",
  direction: "all",
  first: 20,
  skip: 20,
})

For direction: "all", pagination is applied after outgoing and incoming results are merged and sorted by createdAtTimestamp descending. Internally, the SDK batches requests to avoid unbounded scans.

getSuperTokenBalance(account, token?)

const balance = await sdk.getSuperTokenBalance("0x...", "SUP")

If token is omitted, the SDK uses its configured default token.

getBalanceHistory(options)

Returns historical balance snapshots from the subgraph.

const history = await sdk.getBalanceHistory({
  account: "0x...",
  first: 10,
  skip: 0,
})

fromTimestamp / toTimestamp accept unix seconds, and millisecond inputs are normalized automatically.

getSubgraphClient()

Use the underlying client for subgraph-only operations such as SUP reserve lookups.

SUP Reserves

SUP reserve queries use The Graph Gateway endpoint and require an API key.

import { SubgraphClient, SupportedChains } from "@goodsdks/streaming-sdk"

const client = new SubgraphClient(SupportedChains.BASE, {
  apiKey: process.env.GRAPH_API_KEY,
})

const reserves = await client.querySUPReserves("0x...")

for (const locker of reserves) {
  console.log(locker.id, locker.stakedBalance) // bigint, 18-decimal SUP
}

Each SUPReserveLocker includes the locker's id, lockerOwner, blockNumber, blockTimestamp, and a stakedBalance (bigint, sourced from stakingData.currentStakedBalance). stakedBalance is 0n when the locker has never staked.

The reserve query is intentionally account-scoped. You must pass the wallet or account whose reserves you want to inspect.

GdaSDK

connectToPool(params)

const gda = new GdaSDK(publicClient, walletClient)

await gda.connectToPool({
  poolAddress: "0x...",
  userData: "0x",
})

disconnectFromPool(params)

await gda.disconnectFromPool({
  poolAddress: "0x...",
  userData: "0x",
})

getPoolMemberships(account)

const memberships = await gda.getPoolMemberships("0x..." as Address)

getDistributionPools(account)

Lists only distribution pools where account is a member, including per-pool isConnected status for that account.

const pools = await gda.getDistributionPools("0x..." as Address)

getPoolDetails(poolId, account)

Looks up a specific pool within the queried account's distribution pools.

const pool = await gda.getPoolDetails("0xPool..." as Address, "0xAccount..." as Address)

Supported Chains

| Token | Chain | Chain ID | Environment | | --- | --- | --- | --- | | G$ | Celo | 42220 | production, staging, development | | SUP | Base | 8453 | production |

SUP is a production-only token on Base. Resolving SUP for staging or development returns undefined by design, and any SDK call that would require such an address throws a clear "Token address not available" error.

License

MIT