rivus-sdk
v0.1.0
Published
TypeScript SDK for interacting with Rivus payment streaming contracts on the Stacks blockchain
Downloads
1,475
Maintainers
Readme
rivus-sdk
TypeScript SDK for interacting with Rivus — a payment streaming protocol on the Stacks blockchain. Rivus lets senders open real-time STX streams to recipients: funds flow block-by-block and can be paused, topped-up, or cancelled at any time.
This SDK handles all read queries against the deployed contracts and produces ready-to-sign transaction payloads for every write operation. It works in the browser (via @stacks/connect) and on the server (via makeContractCall).
Install
npm install rivus-sdkPeer dependency:
@stacks/transactions ^7
Quick start
import {
createRivusConfig,
fetchStream,
fetchProtocolStats,
buildOpenStreamTx,
buildCancelStreamTx,
getStreamStatus,
formatStx,
} from 'rivus-sdk';
// 1. Create a config once and reuse it
const config = createRivusConfig({
network: 'mainnet',
contractAddress: 'SP...', // address that deployed the Rivus contracts
});
// 2. Read a stream
const stream = await fetchStream(42, config);
if (stream) {
console.log(formatStx(stream.totalAmount)); // "1 STX"
console.log(getStreamStatus(stream, currentBlock)); // "active"
}
// 3. Check protocol stats
const stats = await fetchProtocolStats(config);
console.log(stats.totalOpened, stats.totalVolume);
// 4. Build a transaction payload and send it with @stacks/connect
import { openContractCall } from '@stacks/connect';
const payload = buildOpenStreamTx(
'SP_RECIPIENT',
1_000_000, // 1 STX in micro-STX
startBlock,
endBlock,
config,
);
openContractCall({
...payload,
onFinish: (data) => console.log('txid:', data.txId),
});API
createRivusConfig(options)
Creates a resolved config object to pass into every SDK function.
const config = createRivusConfig({
network: 'mainnet', // 'mainnet' | 'testnet' | 'devnet'
contractAddress: 'SP...', // principal that deployed Rivus
stacksApiUrl: '...', // optional — overrides the default Hiro API URL
});Stream Registry
The core contract. Manages the full lifecycle of a payment stream.
Reads
| Function | Returns | Description |
|---|---|---|
| fetchStream(id, config) | Stream \| null | Fetch a stream by ID |
| fetchWithdrawableAmount(id, config) | number | Claimable micro-STX available to the recipient right now |
| fetchSenderStreamCount(address, config) | number | How many streams an address has opened |
| fetchRecipientStreamCount(address, config) | number | How many streams target an address |
| fetchProtocolStats(config) | ProtocolStats | Global totals: opened, cancelled, volume, next ID |
| fetchNextStreamId(config) | number | The ID that will be assigned to the next stream |
| fetchIsStreamActive(id, config) | boolean | true if the stream is live (not paused, cancelled, or completed) |
| fetchStreamRate(id, config) | number | Emission rate in micro-STX per block |
| fetchStreamRemaining(id, config) | number | Unspent micro-STX still locked in the stream |
| fetchStreamElapsed(id, config) | number | Blocks elapsed since the last withdrawal |
Transaction builders
These return a ContractCallPayload you can spread into openContractCall (browser) or makeContractCall (server). No signing happens inside the SDK.
// Open a new payment stream
buildOpenStreamTx(recipient, totalAmount, startBlock, endBlock, config)
// Recipient claims earned funds
buildWithdrawFromStreamTx(streamId, config)
// Sender cancels — recipient gets earned amount, sender gets the rest back
buildCancelStreamTx(streamId, config)
// Sender pauses / resumes flow
buildPauseStreamTx(streamId, config)
buildResumeStreamTx(streamId, config)
// Sender adds more funds to an active stream
buildTopUpStreamTx(streamId, amount, config)Stream Factory
Batch helpers for common payroll and vesting patterns.
Reads
| Function | Description |
|---|---|
| estimatePayrollTotal(monthlyAmount, months, config) | Total micro-STX needed for a payroll stream |
| estimateRatePerBlock(totalAmount, durationBlocks, config) | Emission rate for a given amount and duration |
| fetchBlocksPerMonth(config) | Blocks per ~30-day period (constant: 4 320) |
| fetchTotalFactoryStreams(config) | Streams created via the factory |
| fetchMinStreamAmount(config) | Minimum deposit to open a stream |
Transaction builders
// Monthly payroll: streams `monthlyAmount` per month for `months` months
buildCreatePayrollStreamTx(recipient, monthlyAmount, months, startBlock, config)
// Token vesting: cliff then linear release over vestingBlocks
buildCreateVestingStreamTx(beneficiary, totalAmount, cliffBlocks, vestingBlocks, config)Stream Vault
Read-only views into the custodial vault that holds locked STX.
| Function | Description |
|---|---|
| fetchStreamBalance(streamId, config) | Locked micro-STX for one stream |
| fetchTotalLocked(config) | Total micro-STX currently held across all streams |
| fetchVaultUtilization(config) | Alias for fetchTotalLocked |
RVUS Token
The Rivus protocol token (SIP-010).
| Function | Description |
|---|---|
| fetchRvusBalance(account, config) | RVUS balance for an address |
| fetchRvusTotalSupply(config) | Circulating RVUS supply |
| fetchRvusName(config) | "Rivus" |
| fetchRvusSymbol(config) | "RVUS" |
| fetchRvusDecimals(config) | 6 |
| buildTransferRvusTx(amount, sender, recipient, memo, config) | Build a transfer payload |
Utilities
// STX conversions
microToStx(amount: number): number // 1_000_000 → 1
stxToMicro(amount: number): bigint // 1 → 1_000_000n
formatStx(microStx: number, decimals?: number): string // "1.5 STX"
// Address helpers
truncateAddress(address: string): string // "SP1PQH...PGZGM"
validateAddress(address: string): boolean // regex check for SP/ST/SM/SN
// Block helpers
blocksToMs(blocks: number): number // blocks × 600 000 ms
formatDuration(blocks: number): string // "3 months", "1 day", etc.
// Stream helpers
getStreamStatus(stream, currentBlock): StreamStatus
calculateStreamProgress(stream, currentBlock): number // 0–100
blocksRemaining(stream, currentBlock): number
estimatedRatePerBlock(totalAmount, durationBlocks): numberTypes
interface Stream {
streamId: number;
sender: string;
recipient: string;
totalAmount: number; // micro-STX
withdrawn: number;
ratePerBlock: number;
startBlock: number;
endBlock: number;
lastWithdrawBlock: number;
pauseBlock: number;
pausedDuration: number;
isPaused: boolean;
isCancelled: boolean;
isCompleted: boolean;
}
type StreamStatus = 'pending' | 'active' | 'paused' | 'cancelled' | 'completed';
interface ProtocolStats {
totalOpened: number;
totalCancelled: number;
totalVolume: number; // lifetime micro-STX streamed
nextId: number;
}Constants
MIN_STREAM_AMOUNT // 10_000 — minimum deposit in micro-STX
MIN_STREAM_DURATION // 10 — minimum duration in blocks
BLOCKS_PER_DAY // 144
BLOCKS_PER_MONTH // 4_320
BLOCKS_PER_YEAR // 52_560
MS_PER_BLOCK // 600_000 — ~10 minutes per block
STX_DECIMALS // 6
RVUS_DECIMALS // 6Usage with @stacks/connect (browser)
import { openContractCall } from '@stacks/connect';
import { buildWithdrawFromStreamTx, createRivusConfig } from 'rivus-sdk';
const config = createRivusConfig({ network: 'mainnet', contractAddress: 'SP...' });
openContractCall({
...buildWithdrawFromStreamTx(streamId, config),
onFinish: ({ txId }) => console.log('withdrew, txid:', txId),
onCancel: () => console.log('cancelled'),
});Usage with makeContractCall (server / scripts)
import { makeContractCall, broadcastTransaction } from '@stacks/transactions';
import { buildCancelStreamTx, createRivusConfig } from 'rivus-sdk';
const config = createRivusConfig({ network: 'mainnet', contractAddress: 'SP...' });
const payload = buildCancelStreamTx(streamId, config);
const tx = await makeContractCall({ ...payload, senderKey: privateKey });
const result = await broadcastTransaction({ transaction: tx, network: 'mainnet' });
console.log(result.txid);Development
npm install # install deps
npm run build # compile to dist/ (CJS + ESM + .d.ts)
npm test # run vitest suite
npm run dev # watch modePublishing
Releases are published automatically via GitHub Actions when a new GitHub release is created. The workflow runs tests, builds, and publishes to npm using the NPM_TOKEN repository secret.
To publish manually:
npm run build
npm publishLicense
MIT
