@bropump/sdk
v0.3.8
Published
TypeScript SDK for BroPump launches, fee previews, and realtime sessions
Maintainers
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/sdkCreate 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
BPvanity 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:
timeoutMspollIntervalMssignalstopOnFailedpreferRealtime
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_snapshottoken_updatelaunch_snapshotlaunch_updateruntime_snapshotruntime_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.
