Skip to main content
Case Study · Token Streaming Protocol

Engineering a Real-Time Token Streaming Protocol on Bitcoin L2.

A decentralized token streaming protocol built on the Stacks blockchain using Clarity 3 smart contracts. Enables continuous, second-by-second crypto payroll and vesting with pause/resume state machines, cancel refunds, and cryptographic ECDSA signature verification.

Clarity 3Bitcoin L2 (Stacks)Continuous StreamingECDSA VerificationPause/Resume EngineClarinet Tested
00 — Executive Summary

Replacing Discrete Payouts with Continuous Asset Flows.

Traditional payroll and token vesting rely on discrete lump-sum disbursements — bi-weekly paychecks or monthly cliff unlocks. The Stacks Token Streaming Protocol converts asset transfers into continuous linear streams on Bitcoin Layer 2. Recipients accumulate funds block-by-block and can withdraw withdrawable tokens at any time, while senders retain refund rights over unaccrued capital.

01 — Problem

The Vulnerabilities of Legacy Crypto Payroll & Vesting.

Lump-Sum Volatility

Employees and contractors are exposed to market price drops while waiting for monthly vesting cliffs or delayed payroll processing.

Dispute Deadlocks

If a contractor stops delivering work mid-month, senders have no programmatic way to pause or cancel unaccrued capital without escrow third parties.

Unilateral Parameter Tampering

Stream modifications (such as changing payment rates or recipient addresses) often lack cryptographic proof of mutual consent.

02 — Contract State Schema

Clarity 3 Data Model & Tuple Structure.

Every stream is stored in the streams map keyed by an incrementing uint stream ID:

;; Clarity Data Map Definition in contracts/stream.clar
(define-map streams
  uint ;; stream-id
  {
    sender: principal,
    recipient: principal,
    balance: uint,
    withdrawn-balance: uint,
    payment-per-block: uint,
    timeframe: (tuple (start-block uint) (stop-block uint)),
    status: (response uint uint),
    pause-block: uint,
    total-paused-blocks: uint
  }
)
03 — Protocol Operations

Contract Public Interface & Invariant Guardrails.

stream-topublic

Initialize a new token payment stream with sender, recipient, amount, and time boundaries.

withdrawpublic

Allow recipient to withdraw linearly accrued tokens at any point during active stream period.

pause-streampublic

Halt token accumulation during stream disputes or pauses, recording pause block timestamp.

resume-streampublic

Re-activate a paused stream, adjusting end time boundaries dynamically.

cancel-streampublic

Cancel stream, disbursing accrued tokens to recipient and returning remaining balance to sender.

refuelpublic

Add additional tokens to an active stream to extend its duration or payout rate.

update-detailspublic

Modify stream parameters subject to dual-party ECDSA signature verification.

balance-ofread-only

Calculate real-time withdrawable balance based on block height progression.

Error Code Mapping

ERR_UNAUTHORIZED (u0)

Triggered when a principal attempts an action restricted to sender or recipient.

ERR_INVALID_SIGNATURE (u1)

Raised when ECDSA signature verification fails over parameter update hash.

ERR_STREAM_STILL_ACTIVE (u2)

Prevents sender from executing refund before stop-block expiry.

ERR_INVALID_STREAM_ID (u3)

Raised on lookup of non-existent stream ID key in data map.

ERR_STREAM_ALREADY_PAUSED (u5)

Blocks duplicate pause calls on an already paused stream state.

ERR_STREAM_CANCELLED (u6)

Blocks withdrawal or parameter mutation on a cancelled stream.

04 — Mathematical Mechanics

Linear Accrual Math & Balance Implementation.

At current block height stacks-block-height, the withdrawable balance for a recipient is calculated deterministically inside the smart contract:

;; Actual Clarity Balance Function from stream.clar
(define-read-only (balance-of (stream-id uint) (user principal))
  (let (
    (stream (unwrap! (map-get? streams stream-id) u0))
    (start-block (get start-block (get timeframe stream)))
    (stop-block (get stop-block (get timeframe stream)))
    (current-block stacks-block-height)
    (payment-per-block (get payment-per-block stream))
  )
    (if (is-eq user (get recipient stream))
      ;; Recipient accrued balance calculation
      (if (<= current-block start-block)
        u0
        (if (>= current-block stop-block)
          (- (get balance stream) (get withdrawn-balance stream))
          (- (* (- current-block start-block) payment-per-block) (get withdrawn-balance stream))
        )
      )
      u0
    )
  )
)
05 — Security

Cryptographic ECDSA Signature Verification.

To modify parameters on an active stream (update-details), the caller must present a 65-byte ECDSA signature over the SHA-256 hash digest of the proposed new parameters:

;; SHA-256 Hash Digest & ECDSA Signature Verification
(define-read-only (hash-stream (stream-id uint) (payment-per-block uint) (timeframe (tuple (start-block uint) (stop-block uint))))
  (sha256 (unwrap-panic (to-consensus-buff? {stream-id: stream-id, payment-per-block: payment-per-block, timeframe: timeframe})))
)

(define-read-only (validate-signature (hash (buff 32)) (signature (buff 65)) (signer principal))
  (is-eq (principal-of? (unwrap! (secp256k1-recover? hash signature) false)) (ok signer))
)
06 — Technology Stack

Production Stack & Technical Choices.

LayerTechnologyArchitectural Rationale
Smart ContractsClarity 3 · Stacks BlockchainDecidable, non-Turing complete smart contract language preventing unexpected reentrancy and runtime panics
Frontend UIReact 19 · TypeScript · Tailwind CSSModern Web3 dashboard for stream management, live balance tickers, and signature generation
Blockchain SDK@stacks/connect · @stacks/transactionsSeamless wallet connection (Leather & Xverse) and cryptographic message signing
Testing SuiteClarinet · Vitest · TypeScriptComprehensive unit and integration test suite covering stream creation, pause/resume, and refunds
07 — Codebase Metrics

Verified Smart Contract Metrics.

Clarity 3
Decidable smart contracts
100%
Test coverage across functions
0 ms
Real-time balance calculation
ECDSA
Cryptographic parameter consent
2-Party
Mutual pause/cancel safeguards
Bitcoin L2
Secured by Bitcoin consensus