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

@bropump/sdk

v0.3.8

Published

TypeScript SDK for BroPump launches, fee previews, and realtime sessions

Readme

@bropump/sdk

TypeScript SDK for BroPump launches, fee previews, feeds, and realtime launch sessions.

The SDK is designed to give you one fast default:

  • use client.tokens.startLaunchSession(...)
  • let the SDK handle image upload, image preparation, and launch prewarm for you
  • only reach for lower-level helpers when you are intentionally building custom infrastructure

Install

npm install @bropump/sdk

Create a Client

Use mainnet by default:

import { BroPumpClient } from '@bropump/sdk'

const client = new BroPumpClient({ network: 'mainnet' })

Use devnet only when you are explicitly testing against https://dev.bropump.run.

Pick a Launch Mode

Fetch the current launch modes from the API and show users the human displayName:

const launchConfig = await client.launchConfig.get()
const selectedLaunchMode =
  launchConfig.launchModeOptions.find((option) => option.displayName === 'ELASTIC LP') ??
  launchConfig.launchModeOptions.find(
    (option) => option.launchMode === launchConfig.defaultLaunchMode
  ) ??
  launchConfig.launchModeOptions[0]

Treat launchMode as an opaque value returned by the API. Do not hardcode internal ids like MAINNET_CONFIG_35 or MAINNET_ELASTIC_LP_MODE into your UI.

Launch a Token

This is the primary launch flow for both browser forms and backend integrations:

import {
  BroPumpClient,
  BroPumpTokenFailedError,
  hasSubmitAction,
  isTokenLive,
} from '@bropump/sdk'

const client = new BroPumpClient({ network: 'mainnet' })
const launchConfig = await client.launchConfig.get()
const selectedLaunchMode =
  launchConfig.launchModeOptions.find((option) => option.displayName === 'ELASTIC LP') ??
  launchConfig.launchModeOptions.find(
    (option) => option.launchMode === launchConfig.defaultLaunchMode
  ) ??
  launchConfig.launchModeOptions[0]

const imageFile = fileInput.files?.[0]
if (!imageFile) throw new Error('Select an image before launching')

const launch = await client.tokens.startLaunchSession({
  deployer: 'YOUR_WALLET',
  image: imageFile,
  name: 'Bro Pump',
  symbol: 'BRO',
  description: 'Fast launch flow',
  launchMode: selectedLaunchMode.launchMode,
  firstBuyAmount: 0.25,
  x: 'https://x.com/yourproject',
  website: 'https://yourproject.example',
  telegram: 'https://t.me/yourproject',
})

let token = await launch.createAndWaitForReadyToSign()

try {
  while (!isTokenLive(token)) {
    token = await client.tokens.submitSignedAndWaitForLive(token.id, {
      submitId: token.submit.id,
      signedTransactions: [
        /* signed base64 transactions */
      ],
    })

    if (!isTokenLive(token) && !hasSubmitAction(token)) {
      throw new Error('Launch is waiting on a state the client cannot sign yet')
    }
  }

  console.log(token.pool, token.mint)
} catch (error) {
  if (error instanceof BroPumpTokenFailedError) {
    console.error(error.token.error)
  }
  throw error
}

This is the fast path:

  • image upload starts before the launch click
  • image preparation happens before the launch click
  • draft prewarm happens before the launch click
  • when you do not provide your own mint keypair, BroPump automatically prepares a BP vanity mint when available
  • the final create stays fast without exposing internal claims to your app

If your form is interactive, call launch.update(...) while the user edits fields so the draft stays warm. If your bot or backend already knows the final fields, pass them up front and call createAndWaitForReadyToSign() immediately.

The older one-shot helpers still exist:

  • client.tokens.create(...)
  • client.tokens.createAndWaitForReadyToSign(...)

They now run through this same launch-session engine under the hood, so there is one fast path instead of two separate implementations.

Optional Custom Mint Keypair

If you want to force a specific mint keypair, pass mintSecretKeyBase58. When it is omitted, BroPump uses its default fast mint path and will attempt a BP vanity mint automatically.

const ready = await client.tokens.createAndWaitForReadyToSign({
  name: 'Bro Pump',
  symbol: 'BRO',
  description: 'Simple token flow',
  deployer: 'YOUR_WALLET',
  launchMode: selectedLaunchMode.launchMode,
  image: imageFile,
  mintSecretKeyBase58: 'BASE58_64_BYTE_SECRET_KEY',
})

This is an advanced override. Most clients should not set it.

Preview Fees and Curve Data

const launchConfig = await client.launchConfig.get()
const selectedLaunchMode = launchConfig.launchModeOptions.find(
  (option) => option.displayName === 'ELASTIC LP'
)

const preview = await client.fees.preview({
  launchMode: selectedLaunchMode?.launchMode ?? launchConfig.defaultLaunchMode,
  firstBuyAmount: 0.5,
  deployerWallet: 'YOUR_WALLET',
})

console.log(preview.selectedLaunchMode)
console.log(preview.curve.migrationThreshold)
console.log(preview.costQuote.recommendedMinBalanceSol)

Wait Helpers

The SDK includes built-in wait helpers for the common launch lifecycle checkpoints. These helpers use the token websocket first and fall back to HTTP polling automatically if realtime is unavailable or times out.

  • client.tokens.waitForReadyToSign(id, options)
  • client.tokens.waitForLive(id, options)
  • client.tokens.waitFor(id, predicate, options)
  • client.tokens.createAndWaitForReadyToSign(input, options)
  • client.tokens.submitSignedAndWaitForLive(id, input, options)

Typical launch loop:

const launchConfig = await client.launchConfig.get()
const memeMode =
  launchConfig.launchModeOptions.find((option) => option.displayName === 'MEME') ??
  launchConfig.launchModeOptions[0]

const imageFile = fileInput.files?.[0]
if (!imageFile) throw new Error('Select an image before launching')

const ready = await client.tokens.createAndWaitForReadyToSign({
  name: 'Bro Pump',
  symbol: 'BRO',
  description: 'Simple token flow',
  deployer: 'YOUR_WALLET',
  launchMode: memeMode.launchMode,
  image: imageFile,
})

const live = await client.tokens.submitSignedAndWaitForLive(ready.id, {
  submitId: ready.submit.id,
  signedTransactions: [
    /* signed base64 transactions */
  ],
})

Treat that one-shot helper as a convenience wrapper. For the cleanest integration and the fastest launch button, prefer startLaunchSession(...).

All wait helpers accept:

  • timeoutMs
  • pollIntervalMs
  • signal
  • stopOnFailed
  • preferRealtime

Token Feeds

The launcher terminal can stay SDK-first too. Use the token feed helpers for live lists of new pools and migrated pools:

  • client.tokens.list(input, options)
  • client.tokens.watchList(input, options)
const newPools = await client.tokens.list({
  feed: 'new',
  limit: 18,
})

const migrated = await client.tokens.list({
  feed: 'migrated',
  limit: 18,
  recentHours: 24,
})

Live feed over WSS:

const stream = await client.tokens.watchList({
  feed: 'migrated',
  limit: 18,
  recentHours: 24,
})

for await (const message of stream) {
  console.log(message.type, message.data?.length)
}

Realtime / WSS

You do not need to manage a separate websocket host manually. The SDK derives ws:// or wss:// from the API base URL automatically for both mainnet and devnet.

The built-in wait helpers already use websocket-first behavior internally, so most clients only need the raw stream APIs when they want custom live UX.

Watch a Token Session

const stream = await client.tokens.watch(token.id)

for await (const message of stream) {
  console.log(message.type, message.data)

  if (message.type === 'token_update' && message.data?.status === 'live') {
    break
  }
}

stream.close()

Wait for a Specific Realtime Event

const stream = await client.tokens.watch(token.id)

const readyMessage = await stream.waitFor(
  (message) =>
    message.type === 'token_update' &&
    Boolean(message.data?.submit?.id),
  30_000
)

console.log(readyMessage.data?.submit?.id)
stream.close()

Watch a Pool Directly

const poolStream = await client.tokens.watchPool('POOL_ADDRESS')

for await (const message of poolStream) {
  console.log(message.type, message.data?.runtime?.phase)
}

Common message types:

  • token_snapshot
  • token_update
  • launch_snapshot
  • launch_update
  • runtime_snapshot
  • runtime_update

Use client.tokens.watch(tokenId) for a launch session and client.tokens.watchPool(poolAddress) for a live pool stream.

Manual WSS URL Access

If you need the derived websocket URL for your own socket layer, use buildWebSocketUrl:

import { buildWebSocketUrl } from '@bropump/sdk'

const wsUrl = buildWebSocketUrl('https://dev.bropump.run', '/tokens/123/ws')

Errors

Request failures throw BroPumpApiError:

import { BroPumpApiError } from '@bropump/sdk'

try {
  await client.health()
} catch (error) {
  if (error instanceof BroPumpApiError) {
    console.error(error.status, error.code, error.body)
  }
}

Lifecycle polling helpers throw BroPumpTokenFailedError when a token reaches failed while you are waiting on it.