Skip to content

Repository files navigation

PerStream

Per-second USDC streaming paywall for podcasts and long-form audio. Built on Circle Nanopayments + Arc testnet + x402 + viem embedded wallets.

Tagline:Every second, paid.

License: MITHackathonChainStatus

Built for the Lepton Agents Hackathon (Canteen × Circle, June 15–29, 2026). Track: RFB 4 — Streaming & Continuous Payments (also fits RFB 6 — AI as Economic Actors).


What is PerStream?

PerStream lets creators monetize audio from listener #1 by charging USDC for every second of audio actually played. No subscriptions. No ads. No audience minimum. Press play, USDC ticks every second, creator earns.

For listeners — pay only for the seconds you hear. Pause = stop paying. For creators — earn from listener #1. Settled every 30 seconds, on-chain, on Arc. For AI agents — autonomous agents can subscribe, stream, and rate on behalf of users.

Tech stack

  • Circle Nanopayments — gasless USDC micro-payments (as small as $0.000001)
  • x402 — HTTP 402 paywall pattern, sponsor-aligned
  • viem embedded wallets — deterministic, no MetaMask (Circle Agent Stack flow available when keys are provided)
  • Arc testnet — Circle's stablecoin-native L1 (chain ID 5042002)

Try the live demo

URLMode
https://donyemiight.github.io/PerStream/Static Demo – Fully functional mock mode (no backend required)
https://donyemiight.github.io/PerStream/listen.htmlListener Experience – Simulated per-second USDC streaming
https://donyemiight.github.io/PerStream/creator.htmlCreator Dashboard – Mock creator earnings and analytics

Note: The Node.js backend is intended for local development and real Arc Testnet settlement. The GitHub Pages deployment runs in a polished client-side Demo Mode so judges can experience the complete workflow without requiring a backend.

Demo accounts

  • Listener:demo-listener@perstream.fm
  • Creator:demo-creator@perstream.fm

Any email works — the system creates an embedded Arc wallet on the fly.

60-second walkthrough

  1. Open the URL → click "Sign in with email" (mobile-friendly modal)
  2. Use any email → a Circle Arc wallet is created in milliseconds
  3. Tap + Add 5 USDC → balance updates (in live mode: real on-chain tx)
  4. Tap any track → click ▶ Start Streaming → audio plays + balance ticks down
  5. Click the wallet address (top right) → opens your Arcscan page

For creator flow: open /creator.html → upload an MP3 → see analytics update → withdraw USDC.


Run it locally

Prerequisites

  • Node.js ≥ 18 (tested on 20, 22, 24)
  • npm (comes with Node)
  • git
  • No Python, no native compilers, no Docker. Pure JS stack.

Quickstart (under 2 minutes)

Verified working on Termux/Android — copy/paste the block below:

cd~
rm -rf PerStream
git clone https://github.com/Donyemiight/PerStream.git
cd PerStream/backend
rm -rf node_modules package-lock.json
npm install --no-audit --no-fund --omit=optional
cp .env.example .env
cd ..
rm -rf backend/data
node scripts/smoke-test.js

You should see:

[smoke] running 21 tests against http://localhost:3099
...
[test] 21 passed, 0 failed

Then start the backend:

node backend/src/server.js

Open in any browser:

  • http://localhost:3000 → landing page
  • http://localhost:3000/listen.html → listener experience
  • http://localhost:3000/creator.html → creator dashboard

💡 The rm -rf backend/data step is critical. It wipes the prior state so the smoke test always shows 21/21. Without it, leftover perstream.db from a previous run can suppress some assertions.

💡 Why rm -rf node_modules package-lock.json? If you've installed PerStream before, this ensures you get fresh deps matching the current repo (sql.js, viem, express versions).

Live mode (real Arc testnet)

For real Circle Nanopayments on Arc:

  1. Get testnet USDC: Visit faucet.circle.com, connect a wallet, send 20 USDC to Arc Testnet.
  2. Configure seller wallet: Edit backend/.env:
    PAYMENTS_MODE=liveARBITRUM_PRIVATE_KEY=0x<your_seller_wallet_private_key>
  3. Fund listener wallets: The seller wallet auto-funds new users $5 testnet USDC on first login.
  4. Restart:node backend/src/server.js

Full live-mode setup: docs/LIVE_DEPLOY.md


Architecture

listener (browser) ── x402 / HTTP ──▶ PerStream backend ── Circle Gateway ──▶ Arc testnet
│ │
│ │
└── embedded wallet (Agent Stack) ◀─────┴── creator's Arc wallet

Repository structure

PerStream/
├── backend/ Node.js + Express + sql.js
│ ├── src/
│ │ ├── server.js All 34 API endpoints
│ │ ├── db.js sql.js schema + migrations + helpers
│ │ ├── arc.js Circle Gateway / live mode
│ │ ├── meter.js Per-second settlement engine
│ │ ├── tick-ledger.js Append-only audit log (JSONL)
│ │ ├── wallet.js Three-mode wallet provisioner
│ │ ├── agent-listener.js AI Listener Agent
│ │ └── ...
│ ├── data/ SQLite file + uploaded audio
│ ├── .env.example Mock + Live env vars
│ └── package.json 8 deps, zero native compilation
├── frontend/ Vanilla HTML/JS, no build step
│ ├── index.html Landing page (story-driven)
│ ├── listen.html Listener experience
│ ├── creator.html Full Creator Dashboard
│ ├── LIVE_SETUP.html Live-mode setup guide
│ └── assets/ CSS, JS, MP3s, SVG
├── contracts/ Solidity smart contract
│ └── PerStreamPaymaster.sol On-chain settlement
├── scripts/ CLI tools
│ ├── seed.js Demo data
│ ├── smoke-test.js 21-test suite
│ ├── bundle.sh Release tarball
│ └── ...
├── public/ Static frontend bundle for Pages
├── deploy/ Deployment configs (Dockerfile, cloudflared)
├── docs/ Full documentation
│ ├── SPEC.md
│ ├── API.md All 34 endpoints
│ ├── INSTALLATION.md
│ ├── LIVE_DEPLOY.md
│ ├── CONTRACT_DEPLOY.md
│ ├── HOW_PAYMENTS_WORK.md
│ ├── VERIFY_ON_ARCSCAN.md
│ ├── AGENT_STORY.md
│ ├── PITCH.md, DEMO.md, SUBMISSION.md
│ └── AUDIT_REPORT.md Consistency audit (this audit)
└── README.md ← you are here

Features (verified working)

Listener experience

  • ✅ Email login with embedded Arc wallet (no MetaMask)
  • ✅ Deposit USDC (testnet or live)
  • ✅ Browse 4+ audio tracks
  • ✅ Real-time per-second USDC ticking
  • ✅ Audio gates behind paywall (native controls disabled)
  • ✅ Pause = stop paying
  • ✅ View wallet on Arcscan (clickable)
  • ✅ Recent activity log (audit trail)
  • ✅ Mobile-friendly responsive design

Creator experience

  • ✅ Sign in as creator
  • ✅ Full Creator Dashboard at /creator.html
  • ✅ Upload audio (MP3, WAV, M4A) with optional cover image
  • ✅ Upload progress bar (XHR progress events)
  • ✅ Edit track (title, description, price, category)
  • ✅ Publish/unpublish tracks (draft/published/unlisted)
  • ✅ Delete tracks (with confirmation)
  • ✅ Search, filter, sort tracks
  • ✅ Real-time analytics (streams, listeners, earnings)
  • ✅ Earnings wallet (available, pending, lifetime)
  • ✅ Withdraw USDC on-chain (real Arcscan link)
  • ✅ Notifications (payments, withdrawals, uploads)
  • ✅ Profile editor (display name, bio, avatar, social links)

AI features

  • ✅ AI Listener Agent (/api/agent/listen, /api/agent/auto)
  • ✅ Autonomous multi-track discovery
  • ✅ Agent provisions its own wallet (viem deterministic key, no MetaMask)

On-chain

  • ✅ Every per-second tick recorded in audit ledger
  • ✅ Batched on-chain settlement every 30 ticks (real gatewayMint calls)
  • ✅ Verified on Arc testnet scan
  • ✅ 3 canonical addresses: seller wallet, GatewayMinter, creator earnings

API overview

34 endpoints across 7 categories. Full reference: docs/API.md.

POST /api/auth/login → Sign in with emailGET /api/tracks → Public track catalogGET /api/tracks/:id/stream → x402-gated audio URLPOST /api/listen/start → Begin listening sessionGET /api/listen/poll → Per-second tick (every 1s)POST /api/listen/stop → End session + on-chain settlePOST /api/listen/deposit → Add USDC to balanceGET /api/creator/dashboard → Full creator analyticsPOST /api/creator/tracks → Upload track (multipart)PUT /api/creator/tracks/:id → Update trackDELETE /api/creator/tracks/:id → Delete trackPOST /api/creator/tracks/:id/status → Publish/unpublishGET /api/creator/profile → Creator profilePUT /api/creator/profile → Update profileGET /api/creator/notifications → List notificationsGET /api/creator/withdrawals → List withdrawalsPOST /api/creator/withdraw → Withdraw USDC (on-chain)POST /api/agent/listen → AI agent listens to one trackPOST /api/agent/auto → AI agent multi-track discoveryGET /api/agent/info → Agent capabilitiesGET /api/audit/stats → Aggregate statsGET /api/audit/ticks → Recent ticksGET /api/audit/export → Download JSONL ledgerGET /api/health → Service status

Circle technologies used

Circle primitiveWhereWhy
Nanopaymentsbackend/src/arc.js, backend/src/meter.jsSub-cent USDC transfers with batching
x402/api/tracks/:id/stream, /api/agent/listenHTTP 402 paywall pattern
Embedded walletsbackend/src/wallet.jsviem deterministic per-user wallets; Circle Agent Stack path available when API keys are provided
Arc testnetAll settlement txsStablecoin-native L1, sub-second finality

On-chain verification

Three canonical Arc testnet addresses:

RoleAddressView
Seller wallet0xEb375940Cd0D85f06239d68C6e719c71907771f9Arcscan
Gateway Wallet0x0077777d7EBA4688BDeF3E311b846F25870A19B9Arcscan
Creator earnings0x9b198314420Ffc0f7a5e4895a2CFCc12D0b53493Arcscan

Creator workflow (verified end-to-end)

  1. Sign in with any email → Circle Arc wallet auto-created
  2. Open /creator.html → full dashboard
  3. Upload a track → MP3/WAV/M4A + optional cover image → real-time progress
  4. Track appears in public catalog at /listen.html
  5. Listener signs in + streams → per-second USDC ticks on Arc testnet
  6. Creator's earnings update in dashboard (real-time)
  7. Withdraw → real on-chain USDC transfer to creator's wallet
  8. Arcscan link in withdrawal history verifies the tx

Listener workflow (verified end-to-end)

  1. Open /listen.html → sign in with any email
  2. Auto-funded with $5 testnet USDC (live mode)
  3. Tap any track → click ▶ Start Streaming
  4. Audio plays + balance ticks down + meter ticks up
  5. Pause → payment stream stops
  6. Click wallet address (top right) → opens your Arcscan page
  7. View recent ticks in audit section at bottom

Security considerations

  • Ownership checks on all track edit/delete operations (creator_id must match)
  • Auth middleware required for creator endpoints (X-User-Id header)
  • No secrets in repo.env is gitignored, .env.example has only safe defaults
  • CORS configured — Express CORS middleware
  • Rate limitingexpress-rate-limit on auth endpoints
  • Wallet derivation — uses viem from email hash (deterministic, no private key storage)
  • Live mode private keys — only the seller key in .env, never exposed in code

Hackathon deliverables


Environment variables

All in backend/.env (see .env.example):

VariableDefaultDescription
PORT3000Express server port
NODE_ENVdevelopmentNode environment
PUBLIC_BASE_URLemptyAuto-detect from Host header (recommended)
PAYMENTS_MODEmockmock (in-memory) or live (real Arc)
ARBITRUM_PRIVATE_KEYemptySeller wallet private key (live mode only)
DB_PATH./data/perstream.dbSQLite database file
AUDIO_DIR./data/audioUploaded audio directory

Tech stack

LayerChoiceWhy
Smart contractSolidity 0.8.xStandard on Arc, deployable in 5 min
BackendNode.js + ExpressTermux-friendly, fastest to ship
Databasesql.js (pure JS SQLite)No native compile, runs on Termux
FrontendVanilla HTML/JS/CSSNo build step, deploys anywhere
Walletviem (deterministic per-user)Embedded, no MetaMask popup; Circle Agent Stack path available with API keys
PaymentsCircle NanopaymentsGasless USDC, $0.000001 minimum
Paywallx402 (HTTP 402)Standard, sponsor-aligned
ChainArc testnetStablecoin-native, Circle's own L1
Audio uploadmulterBattle-tested multipart parser
AuthX-User-Id headerLightweight, no JWT needed for demo

Project status

  • Architecture designed and shipped
  • Backend skeleton (Node + Express)
  • Smart contract (PerStreamPaymaster.sol)
  • Frontend (landing, listen, creator) — 4 pages
  • x402 + Nanopayments flow
  • AI Listener Agent (autonomous)
  • Creator Dashboard (full CRUD + analytics + withdrawals)
  • Demo seeded with 4 tracks
  • Live demo deployed (Arc testnet verified)
  • Documentation (8 docs + audit report)
  • 21/21 smoke tests pass
  • Real on-chain settlements verified

Credits

Built by Oluyemi (donyemiight) (@DonYemiight) for the Lepton Agents Hackathon 2026.

Solo build, Termux (Android), 14 days.

Returning Canteen builder — previously shipped TradeMouth on the prior Canteen event.


License

MIT — see LICENSE.

About

Per-second USDC streaming paywall for podcasts, built on Circle Nanopayments + Arc. Every second, paid.

Topics

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages

, 'i'); if (__m === '*' || __re.test(location.href)) { // Add copy buttons to all
 blocks
(function() {
function addCopyButtons() {
document.querySelectorAll('pre code').forEach(function(codeBlock) {
if (codeBlock.parentElement.hasAttribute('data-copy-added')) return;
codeBlock.parentElement.setAttribute('data-copy-added', 'true');
var btn = document.createElement('button');
btn.textContent = 'Copy';
btn.style.cssText = 'position:absolute;top:4px;right:4px;padding:2px 8px;font-size:11px;background:#4ecdc4;border:none;border-radius:4px;color:#1a1a2e;cursor:pointer;opacity:0.7;transition:opacity 0.2s;';
btn.onmouseover = function() { this.style.opacity = '1'; };
btn.onmouseout = function() { this.style.opacity = '0.7'; };
btn.onclick = function() {
navigator.clipboard.writeText(codeBlock.textContent).then(function() {
btn.textContent = 'Copied!';
setTimeout(function() { btn.textContent = 'Copy'; }, 1500);
});
};
codeBlock.parentElement.style.position = 'relative';
codeBlock.parentElement.appendChild(btn);
});
}
addCopyButtons();
// Re-run on dynamic content
var observer = new MutationObserver(addCopyButtons);
observer.observe(document.body, { childList: true, subtree: true });
})();
}
} catch(__e) { console.warn('[Userscript:Add Copy Buttons to Code Blocks]', __e); }
})();
(function(){
try {
var __m = "github.com";
var __re = new RegExp('^' + "github\\.com" + '
GitHub - Donyemiight/PerStream: Per-second USDC streaming paywall for podcasts, built on Circle Nanopayments + Arc. Every second, paid. · GitHub
Skip to content

Repository files navigation

PerStream

Per-second USDC streaming paywall for podcasts and long-form audio. Built on Circle Nanopayments + Arc testnet + x402 + viem embedded wallets.

Tagline:Every second, paid.

License: MITHackathonChainStatus

Built for the Lepton Agents Hackathon (Canteen × Circle, June 15–29, 2026). Track: RFB 4 — Streaming & Continuous Payments (also fits RFB 6 — AI as Economic Actors).


What is PerStream?

PerStream lets creators monetize audio from listener #1 by charging USDC for every second of audio actually played. No subscriptions. No ads. No audience minimum. Press play, USDC ticks every second, creator earns.

For listeners — pay only for the seconds you hear. Pause = stop paying. For creators — earn from listener #1. Settled every 30 seconds, on-chain, on Arc. For AI agents — autonomous agents can subscribe, stream, and rate on behalf of users.

Tech stack

  • Circle Nanopayments — gasless USDC micro-payments (as small as $0.000001)
  • x402 — HTTP 402 paywall pattern, sponsor-aligned
  • viem embedded wallets — deterministic, no MetaMask (Circle Agent Stack flow available when keys are provided)
  • Arc testnet — Circle's stablecoin-native L1 (chain ID 5042002)

Try the live demo

URLMode
https://donyemiight.github.io/PerStream/Static Demo – Fully functional mock mode (no backend required)
https://donyemiight.github.io/PerStream/listen.htmlListener Experience – Simulated per-second USDC streaming
https://donyemiight.github.io/PerStream/creator.htmlCreator Dashboard – Mock creator earnings and analytics

Note: The Node.js backend is intended for local development and real Arc Testnet settlement. The GitHub Pages deployment runs in a polished client-side Demo Mode so judges can experience the complete workflow without requiring a backend.

Demo accounts

  • Listener:demo-listener@perstream.fm
  • Creator:demo-creator@perstream.fm

Any email works — the system creates an embedded Arc wallet on the fly.

60-second walkthrough

  1. Open the URL → click "Sign in with email" (mobile-friendly modal)
  2. Use any email → a Circle Arc wallet is created in milliseconds
  3. Tap + Add 5 USDC → balance updates (in live mode: real on-chain tx)
  4. Tap any track → click ▶ Start Streaming → audio plays + balance ticks down
  5. Click the wallet address (top right) → opens your Arcscan page

For creator flow: open /creator.html → upload an MP3 → see analytics update → withdraw USDC.


Run it locally

Prerequisites

  • Node.js ≥ 18 (tested on 20, 22, 24)
  • npm (comes with Node)
  • git
  • No Python, no native compilers, no Docker. Pure JS stack.

Quickstart (under 2 minutes)

Verified working on Termux/Android — copy/paste the block below:

cd~
rm -rf PerStream
git clone https://github.com/Donyemiight/PerStream.git
cd PerStream/backend
rm -rf node_modules package-lock.json
npm install --no-audit --no-fund --omit=optional
cp .env.example .env
cd ..
rm -rf backend/data
node scripts/smoke-test.js

You should see:

[smoke] running 21 tests against http://localhost:3099
...
[test] 21 passed, 0 failed

Then start the backend:

node backend/src/server.js

Open in any browser:

  • http://localhost:3000 → landing page
  • http://localhost:3000/listen.html → listener experience
  • http://localhost:3000/creator.html → creator dashboard

💡 The rm -rf backend/data step is critical. It wipes the prior state so the smoke test always shows 21/21. Without it, leftover perstream.db from a previous run can suppress some assertions.

💡 Why rm -rf node_modules package-lock.json? If you've installed PerStream before, this ensures you get fresh deps matching the current repo (sql.js, viem, express versions).

Live mode (real Arc testnet)

For real Circle Nanopayments on Arc:

  1. Get testnet USDC: Visit faucet.circle.com, connect a wallet, send 20 USDC to Arc Testnet.
  2. Configure seller wallet: Edit backend/.env:
    PAYMENTS_MODE=liveARBITRUM_PRIVATE_KEY=0x<your_seller_wallet_private_key>
  3. Fund listener wallets: The seller wallet auto-funds new users $5 testnet USDC on first login.
  4. Restart:node backend/src/server.js

Full live-mode setup: docs/LIVE_DEPLOY.md


Architecture

listener (browser) ── x402 / HTTP ──▶ PerStream backend ── Circle Gateway ──▶ Arc testnet
│ │
│ │
└── embedded wallet (Agent Stack) ◀─────┴── creator's Arc wallet

Repository structure

PerStream/
├── backend/ Node.js + Express + sql.js
│ ├── src/
│ │ ├── server.js All 34 API endpoints
│ │ ├── db.js sql.js schema + migrations + helpers
│ │ ├── arc.js Circle Gateway / live mode
│ │ ├── meter.js Per-second settlement engine
│ │ ├── tick-ledger.js Append-only audit log (JSONL)
│ │ ├── wallet.js Three-mode wallet provisioner
│ │ ├── agent-listener.js AI Listener Agent
│ │ └── ...
│ ├── data/ SQLite file + uploaded audio
│ ├── .env.example Mock + Live env vars
│ └── package.json 8 deps, zero native compilation
├── frontend/ Vanilla HTML/JS, no build step
│ ├── index.html Landing page (story-driven)
│ ├── listen.html Listener experience
│ ├── creator.html Full Creator Dashboard
│ ├── LIVE_SETUP.html Live-mode setup guide
│ └── assets/ CSS, JS, MP3s, SVG
├── contracts/ Solidity smart contract
│ └── PerStreamPaymaster.sol On-chain settlement
├── scripts/ CLI tools
│ ├── seed.js Demo data
│ ├── smoke-test.js 21-test suite
│ ├── bundle.sh Release tarball
│ └── ...
├── public/ Static frontend bundle for Pages
├── deploy/ Deployment configs (Dockerfile, cloudflared)
├── docs/ Full documentation
│ ├── SPEC.md
│ ├── API.md All 34 endpoints
│ ├── INSTALLATION.md
│ ├── LIVE_DEPLOY.md
│ ├── CONTRACT_DEPLOY.md
│ ├── HOW_PAYMENTS_WORK.md
│ ├── VERIFY_ON_ARCSCAN.md
│ ├── AGENT_STORY.md
│ ├── PITCH.md, DEMO.md, SUBMISSION.md
│ └── AUDIT_REPORT.md Consistency audit (this audit)
└── README.md ← you are here

Features (verified working)

Listener experience

  • ✅ Email login with embedded Arc wallet (no MetaMask)
  • ✅ Deposit USDC (testnet or live)
  • ✅ Browse 4+ audio tracks
  • ✅ Real-time per-second USDC ticking
  • ✅ Audio gates behind paywall (native controls disabled)
  • ✅ Pause = stop paying
  • ✅ View wallet on Arcscan (clickable)
  • ✅ Recent activity log (audit trail)
  • ✅ Mobile-friendly responsive design

Creator experience

  • ✅ Sign in as creator
  • ✅ Full Creator Dashboard at /creator.html
  • ✅ Upload audio (MP3, WAV, M4A) with optional cover image
  • ✅ Upload progress bar (XHR progress events)
  • ✅ Edit track (title, description, price, category)
  • ✅ Publish/unpublish tracks (draft/published/unlisted)
  • ✅ Delete tracks (with confirmation)
  • ✅ Search, filter, sort tracks
  • ✅ Real-time analytics (streams, listeners, earnings)
  • ✅ Earnings wallet (available, pending, lifetime)
  • ✅ Withdraw USDC on-chain (real Arcscan link)
  • ✅ Notifications (payments, withdrawals, uploads)
  • ✅ Profile editor (display name, bio, avatar, social links)

AI features

  • ✅ AI Listener Agent (/api/agent/listen, /api/agent/auto)
  • ✅ Autonomous multi-track discovery
  • ✅ Agent provisions its own wallet (viem deterministic key, no MetaMask)

On-chain

  • ✅ Every per-second tick recorded in audit ledger
  • ✅ Batched on-chain settlement every 30 ticks (real gatewayMint calls)
  • ✅ Verified on Arc testnet scan
  • ✅ 3 canonical addresses: seller wallet, GatewayMinter, creator earnings

API overview

34 endpoints across 7 categories. Full reference: docs/API.md.

POST /api/auth/login → Sign in with emailGET /api/tracks → Public track catalogGET /api/tracks/:id/stream → x402-gated audio URLPOST /api/listen/start → Begin listening sessionGET /api/listen/poll → Per-second tick (every 1s)POST /api/listen/stop → End session + on-chain settlePOST /api/listen/deposit → Add USDC to balanceGET /api/creator/dashboard → Full creator analyticsPOST /api/creator/tracks → Upload track (multipart)PUT /api/creator/tracks/:id → Update trackDELETE /api/creator/tracks/:id → Delete trackPOST /api/creator/tracks/:id/status → Publish/unpublishGET /api/creator/profile → Creator profilePUT /api/creator/profile → Update profileGET /api/creator/notifications → List notificationsGET /api/creator/withdrawals → List withdrawalsPOST /api/creator/withdraw → Withdraw USDC (on-chain)POST /api/agent/listen → AI agent listens to one trackPOST /api/agent/auto → AI agent multi-track discoveryGET /api/agent/info → Agent capabilitiesGET /api/audit/stats → Aggregate statsGET /api/audit/ticks → Recent ticksGET /api/audit/export → Download JSONL ledgerGET /api/health → Service status

Circle technologies used

Circle primitiveWhereWhy
Nanopaymentsbackend/src/arc.js, backend/src/meter.jsSub-cent USDC transfers with batching
x402/api/tracks/:id/stream, /api/agent/listenHTTP 402 paywall pattern
Embedded walletsbackend/src/wallet.jsviem deterministic per-user wallets; Circle Agent Stack path available when API keys are provided
Arc testnetAll settlement txsStablecoin-native L1, sub-second finality

On-chain verification

Three canonical Arc testnet addresses:

RoleAddressView
Seller wallet0xEb375940Cd0D85f06239d68C6e719c71907771f9Arcscan
Gateway Wallet0x0077777d7EBA4688BDeF3E311b846F25870A19B9Arcscan
Creator earnings0x9b198314420Ffc0f7a5e4895a2CFCc12D0b53493Arcscan

Creator workflow (verified end-to-end)

  1. Sign in with any email → Circle Arc wallet auto-created
  2. Open /creator.html → full dashboard
  3. Upload a track → MP3/WAV/M4A + optional cover image → real-time progress
  4. Track appears in public catalog at /listen.html
  5. Listener signs in + streams → per-second USDC ticks on Arc testnet
  6. Creator's earnings update in dashboard (real-time)
  7. Withdraw → real on-chain USDC transfer to creator's wallet
  8. Arcscan link in withdrawal history verifies the tx

Listener workflow (verified end-to-end)

  1. Open /listen.html → sign in with any email
  2. Auto-funded with $5 testnet USDC (live mode)
  3. Tap any track → click ▶ Start Streaming
  4. Audio plays + balance ticks down + meter ticks up
  5. Pause → payment stream stops
  6. Click wallet address (top right) → opens your Arcscan page
  7. View recent ticks in audit section at bottom

Security considerations

  • Ownership checks on all track edit/delete operations (creator_id must match)
  • Auth middleware required for creator endpoints (X-User-Id header)
  • No secrets in repo.env is gitignored, .env.example has only safe defaults
  • CORS configured — Express CORS middleware
  • Rate limitingexpress-rate-limit on auth endpoints
  • Wallet derivation — uses viem from email hash (deterministic, no private key storage)
  • Live mode private keys — only the seller key in .env, never exposed in code

Hackathon deliverables


Environment variables

All in backend/.env (see .env.example):

VariableDefaultDescription
PORT3000Express server port
NODE_ENVdevelopmentNode environment
PUBLIC_BASE_URLemptyAuto-detect from Host header (recommended)
PAYMENTS_MODEmockmock (in-memory) or live (real Arc)
ARBITRUM_PRIVATE_KEYemptySeller wallet private key (live mode only)
DB_PATH./data/perstream.dbSQLite database file
AUDIO_DIR./data/audioUploaded audio directory

Tech stack

LayerChoiceWhy
Smart contractSolidity 0.8.xStandard on Arc, deployable in 5 min
BackendNode.js + ExpressTermux-friendly, fastest to ship
Databasesql.js (pure JS SQLite)No native compile, runs on Termux
FrontendVanilla HTML/JS/CSSNo build step, deploys anywhere
Walletviem (deterministic per-user)Embedded, no MetaMask popup; Circle Agent Stack path available with API keys
PaymentsCircle NanopaymentsGasless USDC, $0.000001 minimum
Paywallx402 (HTTP 402)Standard, sponsor-aligned
ChainArc testnetStablecoin-native, Circle's own L1
Audio uploadmulterBattle-tested multipart parser
AuthX-User-Id headerLightweight, no JWT needed for demo

Project status

  • Architecture designed and shipped
  • Backend skeleton (Node + Express)
  • Smart contract (PerStreamPaymaster.sol)
  • Frontend (landing, listen, creator) — 4 pages
  • x402 + Nanopayments flow
  • AI Listener Agent (autonomous)
  • Creator Dashboard (full CRUD + analytics + withdrawals)
  • Demo seeded with 4 tracks
  • Live demo deployed (Arc testnet verified)
  • Documentation (8 docs + audit report)
  • 21/21 smoke tests pass
  • Real on-chain settlements verified

Credits

Built by Oluyemi (donyemiight) (@DonYemiight) for the Lepton Agents Hackathon 2026.

Solo build, Termux (Android), 14 days.

Returning Canteen builder — previously shipped TradeMouth on the prior Canteen event.


License

MIT — see LICENSE.

About

Per-second USDC streaming paywall for podcasts, built on Circle Nanopayments + Arc. Every second, paid.

Topics

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages

, 'i'); if (__m === '*' || __re.test(location.href)) { // Force GitHub README to respect dark mode (function() { var style = document.createElement('style'); style.textContent = ' .markdown-body { color-scheme: dark light; } .markdown-body pre { background: #161b22 !important; } .markdown-body code { background: rgba(110, 118, 129, 0.4) !important; } .markdown-body table th, .markdown-body table td { border-color: #30363d !important; } .markdown-body img { background: #0d1117; } .markdown-body blockquote { border-left-color: #8b949e; } .markdown-body hr { border-color: #30363d; } '; document.head.appendChild(style); })(); } } catch(__e) { console.warn('[Userscript:GitHub Dark Mode README Fix]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + ' GitHub - Donyemiight/PerStream: Per-second USDC streaming paywall for podcasts, built on Circle Nanopayments + Arc. Every second, paid. · GitHub
Skip to content

Repository files navigation

PerStream

Per-second USDC streaming paywall for podcasts and long-form audio. Built on Circle Nanopayments + Arc testnet + x402 + viem embedded wallets.

Tagline:Every second, paid.

License: MITHackathonChainStatus

Built for the Lepton Agents Hackathon (Canteen × Circle, June 15–29, 2026). Track: RFB 4 — Streaming & Continuous Payments (also fits RFB 6 — AI as Economic Actors).


What is PerStream?

PerStream lets creators monetize audio from listener #1 by charging USDC for every second of audio actually played. No subscriptions. No ads. No audience minimum. Press play, USDC ticks every second, creator earns.

For listeners — pay only for the seconds you hear. Pause = stop paying. For creators — earn from listener #1. Settled every 30 seconds, on-chain, on Arc. For AI agents — autonomous agents can subscribe, stream, and rate on behalf of users.

Tech stack

  • Circle Nanopayments — gasless USDC micro-payments (as small as $0.000001)
  • x402 — HTTP 402 paywall pattern, sponsor-aligned
  • viem embedded wallets — deterministic, no MetaMask (Circle Agent Stack flow available when keys are provided)
  • Arc testnet — Circle's stablecoin-native L1 (chain ID 5042002)

Try the live demo

URLMode
https://donyemiight.github.io/PerStream/Static Demo – Fully functional mock mode (no backend required)
https://donyemiight.github.io/PerStream/listen.htmlListener Experience – Simulated per-second USDC streaming
https://donyemiight.github.io/PerStream/creator.htmlCreator Dashboard – Mock creator earnings and analytics

Note: The Node.js backend is intended for local development and real Arc Testnet settlement. The GitHub Pages deployment runs in a polished client-side Demo Mode so judges can experience the complete workflow without requiring a backend.

Demo accounts

  • Listener:demo-listener@perstream.fm
  • Creator:demo-creator@perstream.fm

Any email works — the system creates an embedded Arc wallet on the fly.

60-second walkthrough

  1. Open the URL → click "Sign in with email" (mobile-friendly modal)
  2. Use any email → a Circle Arc wallet is created in milliseconds
  3. Tap + Add 5 USDC → balance updates (in live mode: real on-chain tx)
  4. Tap any track → click ▶ Start Streaming → audio plays + balance ticks down
  5. Click the wallet address (top right) → opens your Arcscan page

For creator flow: open /creator.html → upload an MP3 → see analytics update → withdraw USDC.


Run it locally

Prerequisites

  • Node.js ≥ 18 (tested on 20, 22, 24)
  • npm (comes with Node)
  • git
  • No Python, no native compilers, no Docker. Pure JS stack.

Quickstart (under 2 minutes)

Verified working on Termux/Android — copy/paste the block below:

cd~
rm -rf PerStream
git clone https://github.com/Donyemiight/PerStream.git
cd PerStream/backend
rm -rf node_modules package-lock.json
npm install --no-audit --no-fund --omit=optional
cp .env.example .env
cd ..
rm -rf backend/data
node scripts/smoke-test.js

You should see:

[smoke] running 21 tests against http://localhost:3099
...
[test] 21 passed, 0 failed

Then start the backend:

node backend/src/server.js

Open in any browser:

  • http://localhost:3000 → landing page
  • http://localhost:3000/listen.html → listener experience
  • http://localhost:3000/creator.html → creator dashboard

💡 The rm -rf backend/data step is critical. It wipes the prior state so the smoke test always shows 21/21. Without it, leftover perstream.db from a previous run can suppress some assertions.

💡 Why rm -rf node_modules package-lock.json? If you've installed PerStream before, this ensures you get fresh deps matching the current repo (sql.js, viem, express versions).

Live mode (real Arc testnet)

For real Circle Nanopayments on Arc:

  1. Get testnet USDC: Visit faucet.circle.com, connect a wallet, send 20 USDC to Arc Testnet.
  2. Configure seller wallet: Edit backend/.env:
    PAYMENTS_MODE=liveARBITRUM_PRIVATE_KEY=0x<your_seller_wallet_private_key>
  3. Fund listener wallets: The seller wallet auto-funds new users $5 testnet USDC on first login.
  4. Restart:node backend/src/server.js

Full live-mode setup: docs/LIVE_DEPLOY.md


Architecture

listener (browser) ── x402 / HTTP ──▶ PerStream backend ── Circle Gateway ──▶ Arc testnet
│ │
│ │
└── embedded wallet (Agent Stack) ◀─────┴── creator's Arc wallet

Repository structure

PerStream/
├── backend/ Node.js + Express + sql.js
│ ├── src/
│ │ ├── server.js All 34 API endpoints
│ │ ├── db.js sql.js schema + migrations + helpers
│ │ ├── arc.js Circle Gateway / live mode
│ │ ├── meter.js Per-second settlement engine
│ │ ├── tick-ledger.js Append-only audit log (JSONL)
│ │ ├── wallet.js Three-mode wallet provisioner
│ │ ├── agent-listener.js AI Listener Agent
│ │ └── ...
│ ├── data/ SQLite file + uploaded audio
│ ├── .env.example Mock + Live env vars
│ └── package.json 8 deps, zero native compilation
├── frontend/ Vanilla HTML/JS, no build step
│ ├── index.html Landing page (story-driven)
│ ├── listen.html Listener experience
│ ├── creator.html Full Creator Dashboard
│ ├── LIVE_SETUP.html Live-mode setup guide
│ └── assets/ CSS, JS, MP3s, SVG
├── contracts/ Solidity smart contract
│ └── PerStreamPaymaster.sol On-chain settlement
├── scripts/ CLI tools
│ ├── seed.js Demo data
│ ├── smoke-test.js 21-test suite
│ ├── bundle.sh Release tarball
│ └── ...
├── public/ Static frontend bundle for Pages
├── deploy/ Deployment configs (Dockerfile, cloudflared)
├── docs/ Full documentation
│ ├── SPEC.md
│ ├── API.md All 34 endpoints
│ ├── INSTALLATION.md
│ ├── LIVE_DEPLOY.md
│ ├── CONTRACT_DEPLOY.md
│ ├── HOW_PAYMENTS_WORK.md
│ ├── VERIFY_ON_ARCSCAN.md
│ ├── AGENT_STORY.md
│ ├── PITCH.md, DEMO.md, SUBMISSION.md
│ └── AUDIT_REPORT.md Consistency audit (this audit)
└── README.md ← you are here

Features (verified working)

Listener experience

  • ✅ Email login with embedded Arc wallet (no MetaMask)
  • ✅ Deposit USDC (testnet or live)
  • ✅ Browse 4+ audio tracks
  • ✅ Real-time per-second USDC ticking
  • ✅ Audio gates behind paywall (native controls disabled)
  • ✅ Pause = stop paying
  • ✅ View wallet on Arcscan (clickable)
  • ✅ Recent activity log (audit trail)
  • ✅ Mobile-friendly responsive design

Creator experience

  • ✅ Sign in as creator
  • ✅ Full Creator Dashboard at /creator.html
  • ✅ Upload audio (MP3, WAV, M4A) with optional cover image
  • ✅ Upload progress bar (XHR progress events)
  • ✅ Edit track (title, description, price, category)
  • ✅ Publish/unpublish tracks (draft/published/unlisted)
  • ✅ Delete tracks (with confirmation)
  • ✅ Search, filter, sort tracks
  • ✅ Real-time analytics (streams, listeners, earnings)
  • ✅ Earnings wallet (available, pending, lifetime)
  • ✅ Withdraw USDC on-chain (real Arcscan link)
  • ✅ Notifications (payments, withdrawals, uploads)
  • ✅ Profile editor (display name, bio, avatar, social links)

AI features

  • ✅ AI Listener Agent (/api/agent/listen, /api/agent/auto)
  • ✅ Autonomous multi-track discovery
  • ✅ Agent provisions its own wallet (viem deterministic key, no MetaMask)

On-chain

  • ✅ Every per-second tick recorded in audit ledger
  • ✅ Batched on-chain settlement every 30 ticks (real gatewayMint calls)
  • ✅ Verified on Arc testnet scan
  • ✅ 3 canonical addresses: seller wallet, GatewayMinter, creator earnings

API overview

34 endpoints across 7 categories. Full reference: docs/API.md.

POST /api/auth/login → Sign in with emailGET /api/tracks → Public track catalogGET /api/tracks/:id/stream → x402-gated audio URLPOST /api/listen/start → Begin listening sessionGET /api/listen/poll → Per-second tick (every 1s)POST /api/listen/stop → End session + on-chain settlePOST /api/listen/deposit → Add USDC to balanceGET /api/creator/dashboard → Full creator analyticsPOST /api/creator/tracks → Upload track (multipart)PUT /api/creator/tracks/:id → Update trackDELETE /api/creator/tracks/:id → Delete trackPOST /api/creator/tracks/:id/status → Publish/unpublishGET /api/creator/profile → Creator profilePUT /api/creator/profile → Update profileGET /api/creator/notifications → List notificationsGET /api/creator/withdrawals → List withdrawalsPOST /api/creator/withdraw → Withdraw USDC (on-chain)POST /api/agent/listen → AI agent listens to one trackPOST /api/agent/auto → AI agent multi-track discoveryGET /api/agent/info → Agent capabilitiesGET /api/audit/stats → Aggregate statsGET /api/audit/ticks → Recent ticksGET /api/audit/export → Download JSONL ledgerGET /api/health → Service status

Circle technologies used

Circle primitiveWhereWhy
Nanopaymentsbackend/src/arc.js, backend/src/meter.jsSub-cent USDC transfers with batching
x402/api/tracks/:id/stream, /api/agent/listenHTTP 402 paywall pattern
Embedded walletsbackend/src/wallet.jsviem deterministic per-user wallets; Circle Agent Stack path available when API keys are provided
Arc testnetAll settlement txsStablecoin-native L1, sub-second finality

On-chain verification

Three canonical Arc testnet addresses:

RoleAddressView
Seller wallet0xEb375940Cd0D85f06239d68C6e719c71907771f9Arcscan
Gateway Wallet0x0077777d7EBA4688BDeF3E311b846F25870A19B9Arcscan
Creator earnings0x9b198314420Ffc0f7a5e4895a2CFCc12D0b53493Arcscan

Creator workflow (verified end-to-end)

  1. Sign in with any email → Circle Arc wallet auto-created
  2. Open /creator.html → full dashboard
  3. Upload a track → MP3/WAV/M4A + optional cover image → real-time progress
  4. Track appears in public catalog at /listen.html
  5. Listener signs in + streams → per-second USDC ticks on Arc testnet
  6. Creator's earnings update in dashboard (real-time)
  7. Withdraw → real on-chain USDC transfer to creator's wallet
  8. Arcscan link in withdrawal history verifies the tx

Listener workflow (verified end-to-end)

  1. Open /listen.html → sign in with any email
  2. Auto-funded with $5 testnet USDC (live mode)
  3. Tap any track → click ▶ Start Streaming
  4. Audio plays + balance ticks down + meter ticks up
  5. Pause → payment stream stops
  6. Click wallet address (top right) → opens your Arcscan page
  7. View recent ticks in audit section at bottom

Security considerations

  • Ownership checks on all track edit/delete operations (creator_id must match)
  • Auth middleware required for creator endpoints (X-User-Id header)
  • No secrets in repo.env is gitignored, .env.example has only safe defaults
  • CORS configured — Express CORS middleware
  • Rate limitingexpress-rate-limit on auth endpoints
  • Wallet derivation — uses viem from email hash (deterministic, no private key storage)
  • Live mode private keys — only the seller key in .env, never exposed in code

Hackathon deliverables


Environment variables

All in backend/.env (see .env.example):

VariableDefaultDescription
PORT3000Express server port
NODE_ENVdevelopmentNode environment
PUBLIC_BASE_URLemptyAuto-detect from Host header (recommended)
PAYMENTS_MODEmockmock (in-memory) or live (real Arc)
ARBITRUM_PRIVATE_KEYemptySeller wallet private key (live mode only)
DB_PATH./data/perstream.dbSQLite database file
AUDIO_DIR./data/audioUploaded audio directory

Tech stack

LayerChoiceWhy
Smart contractSolidity 0.8.xStandard on Arc, deployable in 5 min
BackendNode.js + ExpressTermux-friendly, fastest to ship
Databasesql.js (pure JS SQLite)No native compile, runs on Termux
FrontendVanilla HTML/JS/CSSNo build step, deploys anywhere
Walletviem (deterministic per-user)Embedded, no MetaMask popup; Circle Agent Stack path available with API keys
PaymentsCircle NanopaymentsGasless USDC, $0.000001 minimum
Paywallx402 (HTTP 402)Standard, sponsor-aligned
ChainArc testnetStablecoin-native, Circle's own L1
Audio uploadmulterBattle-tested multipart parser
AuthX-User-Id headerLightweight, no JWT needed for demo

Project status

  • Architecture designed and shipped
  • Backend skeleton (Node + Express)
  • Smart contract (PerStreamPaymaster.sol)
  • Frontend (landing, listen, creator) — 4 pages
  • x402 + Nanopayments flow
  • AI Listener Agent (autonomous)
  • Creator Dashboard (full CRUD + analytics + withdrawals)
  • Demo seeded with 4 tracks
  • Live demo deployed (Arc testnet verified)
  • Documentation (8 docs + audit report)
  • 21/21 smoke tests pass
  • Real on-chain settlements verified

Credits

Built by Oluyemi (donyemiight) (@DonYemiight) for the Lepton Agents Hackathon 2026.

Solo build, Termux (Android), 14 days.

Returning Canteen builder — previously shipped TradeMouth on the prior Canteen event.


License

MIT — see LICENSE.

About

Per-second USDC streaming paywall for podcasts, built on Circle Nanopayments + Arc. Every second, paid.

Topics

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages

, 'i'); if (__m === '*' || __re.test(location.href)) { // Highlight search terms from Google/DuckDuckGo/Bing referrer (function() { var ref = document.referrer; var terms = []; if (ref.includes('google.com') || ref.includes('duckduckgo.com') || ref.includes('bing.com')) { var url = new URL(ref); var q = url.searchParams.get('q') || url.searchParams.get('p'); if (q) { terms = q.split(/\s+/).filter(function(t) { return t.length > 2; }); } } if (terms.length === 0) return; var style = document.createElement('style'); style.textContent = '.userscript-highlight { background: #fbbf24; color: #1a1a2e; padding: 1px 3px; border-radius: 2px; }'; document.head.appendChild(style); function highlight(node) { if (node.nodeType === 3) { // text node var text = node.textContent; var found = false; terms.forEach(function(term) { var regex = new RegExp('(' + term.replace(/[.*+?^${}()|[\]\\]/g, '\\') + ')', 'gi'); if (regex.test(text)) { found = true; var frag = document.createDocumentFragment(); var parts = text.split(regex); parts.forEach(function(part, i) { if (i % 2 === 0) { frag.appendChild(document.createTextNode(part)); } else { var span = document.createElement('span'); span.className = 'userscript-highlight'; span.textContent = part; frag.appendChild(span); } }); node.parentNode.replaceChild(frag, node); } }); } else if (node.nodeType === 1 && node.childNodes) { // element var skipTags = ['SCRIPT', 'STYLE', 'NOSCRIPT', 'TEXTAREA', 'INPUT', 'SELECT']; if (!skipTags.includes(node.tagName)) { Array.from(node.childNodes).forEach(highlight); } } } highlight(document.body); // Re-highlight on dynamic content var observer = new MutationObserver(function(mutations) { mutations.forEach(function(m) { m.addedNodes.forEach(function(node) { if (node.nodeType === 1 || node.nodeType === 3) highlight(node); }); }); }); observer.observe(document.body, { childList: true, subtree: true }); })(); } } catch(__e) { console.warn('[Userscript:Highlight Search Terms]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + ' GitHub - Donyemiight/PerStream: Per-second USDC streaming paywall for podcasts, built on Circle Nanopayments + Arc. Every second, paid. · GitHub
Skip to content

Repository files navigation

PerStream

Per-second USDC streaming paywall for podcasts and long-form audio. Built on Circle Nanopayments + Arc testnet + x402 + viem embedded wallets.

Tagline:Every second, paid.

License: MITHackathonChainStatus

Built for the Lepton Agents Hackathon (Canteen × Circle, June 15–29, 2026). Track: RFB 4 — Streaming & Continuous Payments (also fits RFB 6 — AI as Economic Actors).


What is PerStream?

PerStream lets creators monetize audio from listener #1 by charging USDC for every second of audio actually played. No subscriptions. No ads. No audience minimum. Press play, USDC ticks every second, creator earns.

For listeners — pay only for the seconds you hear. Pause = stop paying. For creators — earn from listener #1. Settled every 30 seconds, on-chain, on Arc. For AI agents — autonomous agents can subscribe, stream, and rate on behalf of users.

Tech stack

  • Circle Nanopayments — gasless USDC micro-payments (as small as $0.000001)
  • x402 — HTTP 402 paywall pattern, sponsor-aligned
  • viem embedded wallets — deterministic, no MetaMask (Circle Agent Stack flow available when keys are provided)
  • Arc testnet — Circle's stablecoin-native L1 (chain ID 5042002)

Try the live demo

URLMode
https://donyemiight.github.io/PerStream/Static Demo – Fully functional mock mode (no backend required)
https://donyemiight.github.io/PerStream/listen.htmlListener Experience – Simulated per-second USDC streaming
https://donyemiight.github.io/PerStream/creator.htmlCreator Dashboard – Mock creator earnings and analytics

Note: The Node.js backend is intended for local development and real Arc Testnet settlement. The GitHub Pages deployment runs in a polished client-side Demo Mode so judges can experience the complete workflow without requiring a backend.

Demo accounts

  • Listener:demo-listener@perstream.fm
  • Creator:demo-creator@perstream.fm

Any email works — the system creates an embedded Arc wallet on the fly.

60-second walkthrough

  1. Open the URL → click "Sign in with email" (mobile-friendly modal)
  2. Use any email → a Circle Arc wallet is created in milliseconds
  3. Tap + Add 5 USDC → balance updates (in live mode: real on-chain tx)
  4. Tap any track → click ▶ Start Streaming → audio plays + balance ticks down
  5. Click the wallet address (top right) → opens your Arcscan page

For creator flow: open /creator.html → upload an MP3 → see analytics update → withdraw USDC.


Run it locally

Prerequisites

  • Node.js ≥ 18 (tested on 20, 22, 24)
  • npm (comes with Node)
  • git
  • No Python, no native compilers, no Docker. Pure JS stack.

Quickstart (under 2 minutes)

Verified working on Termux/Android — copy/paste the block below:

cd~
rm -rf PerStream
git clone https://github.com/Donyemiight/PerStream.git
cd PerStream/backend
rm -rf node_modules package-lock.json
npm install --no-audit --no-fund --omit=optional
cp .env.example .env
cd ..
rm -rf backend/data
node scripts/smoke-test.js

You should see:

[smoke] running 21 tests against http://localhost:3099
...
[test] 21 passed, 0 failed

Then start the backend:

node backend/src/server.js

Open in any browser:

  • http://localhost:3000 → landing page
  • http://localhost:3000/listen.html → listener experience
  • http://localhost:3000/creator.html → creator dashboard

💡 The rm -rf backend/data step is critical. It wipes the prior state so the smoke test always shows 21/21. Without it, leftover perstream.db from a previous run can suppress some assertions.

💡 Why rm -rf node_modules package-lock.json? If you've installed PerStream before, this ensures you get fresh deps matching the current repo (sql.js, viem, express versions).

Live mode (real Arc testnet)

For real Circle Nanopayments on Arc:

  1. Get testnet USDC: Visit faucet.circle.com, connect a wallet, send 20 USDC to Arc Testnet.
  2. Configure seller wallet: Edit backend/.env:
    PAYMENTS_MODE=liveARBITRUM_PRIVATE_KEY=0x<your_seller_wallet_private_key>
  3. Fund listener wallets: The seller wallet auto-funds new users $5 testnet USDC on first login.
  4. Restart:node backend/src/server.js

Full live-mode setup: docs/LIVE_DEPLOY.md


Architecture

listener (browser) ── x402 / HTTP ──▶ PerStream backend ── Circle Gateway ──▶ Arc testnet
│ │
│ │
└── embedded wallet (Agent Stack) ◀─────┴── creator's Arc wallet

Repository structure

PerStream/
├── backend/ Node.js + Express + sql.js
│ ├── src/
│ │ ├── server.js All 34 API endpoints
│ │ ├── db.js sql.js schema + migrations + helpers
│ │ ├── arc.js Circle Gateway / live mode
│ │ ├── meter.js Per-second settlement engine
│ │ ├── tick-ledger.js Append-only audit log (JSONL)
│ │ ├── wallet.js Three-mode wallet provisioner
│ │ ├── agent-listener.js AI Listener Agent
│ │ └── ...
│ ├── data/ SQLite file + uploaded audio
│ ├── .env.example Mock + Live env vars
│ └── package.json 8 deps, zero native compilation
├── frontend/ Vanilla HTML/JS, no build step
│ ├── index.html Landing page (story-driven)
│ ├── listen.html Listener experience
│ ├── creator.html Full Creator Dashboard
│ ├── LIVE_SETUP.html Live-mode setup guide
│ └── assets/ CSS, JS, MP3s, SVG
├── contracts/ Solidity smart contract
│ └── PerStreamPaymaster.sol On-chain settlement
├── scripts/ CLI tools
│ ├── seed.js Demo data
│ ├── smoke-test.js 21-test suite
│ ├── bundle.sh Release tarball
│ └── ...
├── public/ Static frontend bundle for Pages
├── deploy/ Deployment configs (Dockerfile, cloudflared)
├── docs/ Full documentation
│ ├── SPEC.md
│ ├── API.md All 34 endpoints
│ ├── INSTALLATION.md
│ ├── LIVE_DEPLOY.md
│ ├── CONTRACT_DEPLOY.md
│ ├── HOW_PAYMENTS_WORK.md
│ ├── VERIFY_ON_ARCSCAN.md
│ ├── AGENT_STORY.md
│ ├── PITCH.md, DEMO.md, SUBMISSION.md
│ └── AUDIT_REPORT.md Consistency audit (this audit)
└── README.md ← you are here

Features (verified working)

Listener experience

  • ✅ Email login with embedded Arc wallet (no MetaMask)
  • ✅ Deposit USDC (testnet or live)
  • ✅ Browse 4+ audio tracks
  • ✅ Real-time per-second USDC ticking
  • ✅ Audio gates behind paywall (native controls disabled)
  • ✅ Pause = stop paying
  • ✅ View wallet on Arcscan (clickable)
  • ✅ Recent activity log (audit trail)
  • ✅ Mobile-friendly responsive design

Creator experience

  • ✅ Sign in as creator
  • ✅ Full Creator Dashboard at /creator.html
  • ✅ Upload audio (MP3, WAV, M4A) with optional cover image
  • ✅ Upload progress bar (XHR progress events)
  • ✅ Edit track (title, description, price, category)
  • ✅ Publish/unpublish tracks (draft/published/unlisted)
  • ✅ Delete tracks (with confirmation)
  • ✅ Search, filter, sort tracks
  • ✅ Real-time analytics (streams, listeners, earnings)
  • ✅ Earnings wallet (available, pending, lifetime)
  • ✅ Withdraw USDC on-chain (real Arcscan link)
  • ✅ Notifications (payments, withdrawals, uploads)
  • ✅ Profile editor (display name, bio, avatar, social links)

AI features

  • ✅ AI Listener Agent (/api/agent/listen, /api/agent/auto)
  • ✅ Autonomous multi-track discovery
  • ✅ Agent provisions its own wallet (viem deterministic key, no MetaMask)

On-chain

  • ✅ Every per-second tick recorded in audit ledger
  • ✅ Batched on-chain settlement every 30 ticks (real gatewayMint calls)
  • ✅ Verified on Arc testnet scan
  • ✅ 3 canonical addresses: seller wallet, GatewayMinter, creator earnings

API overview

34 endpoints across 7 categories. Full reference: docs/API.md.

POST /api/auth/login → Sign in with emailGET /api/tracks → Public track catalogGET /api/tracks/:id/stream → x402-gated audio URLPOST /api/listen/start → Begin listening sessionGET /api/listen/poll → Per-second tick (every 1s)POST /api/listen/stop → End session + on-chain settlePOST /api/listen/deposit → Add USDC to balanceGET /api/creator/dashboard → Full creator analyticsPOST /api/creator/tracks → Upload track (multipart)PUT /api/creator/tracks/:id → Update trackDELETE /api/creator/tracks/:id → Delete trackPOST /api/creator/tracks/:id/status → Publish/unpublishGET /api/creator/profile → Creator profilePUT /api/creator/profile → Update profileGET /api/creator/notifications → List notificationsGET /api/creator/withdrawals → List withdrawalsPOST /api/creator/withdraw → Withdraw USDC (on-chain)POST /api/agent/listen → AI agent listens to one trackPOST /api/agent/auto → AI agent multi-track discoveryGET /api/agent/info → Agent capabilitiesGET /api/audit/stats → Aggregate statsGET /api/audit/ticks → Recent ticksGET /api/audit/export → Download JSONL ledgerGET /api/health → Service status

Circle technologies used

Circle primitiveWhereWhy
Nanopaymentsbackend/src/arc.js, backend/src/meter.jsSub-cent USDC transfers with batching
x402/api/tracks/:id/stream, /api/agent/listenHTTP 402 paywall pattern
Embedded walletsbackend/src/wallet.jsviem deterministic per-user wallets; Circle Agent Stack path available when API keys are provided
Arc testnetAll settlement txsStablecoin-native L1, sub-second finality

On-chain verification

Three canonical Arc testnet addresses:

RoleAddressView
Seller wallet0xEb375940Cd0D85f06239d68C6e719c71907771f9Arcscan
Gateway Wallet0x0077777d7EBA4688BDeF3E311b846F25870A19B9Arcscan
Creator earnings0x9b198314420Ffc0f7a5e4895a2CFCc12D0b53493Arcscan

Creator workflow (verified end-to-end)

  1. Sign in with any email → Circle Arc wallet auto-created
  2. Open /creator.html → full dashboard
  3. Upload a track → MP3/WAV/M4A + optional cover image → real-time progress
  4. Track appears in public catalog at /listen.html
  5. Listener signs in + streams → per-second USDC ticks on Arc testnet
  6. Creator's earnings update in dashboard (real-time)
  7. Withdraw → real on-chain USDC transfer to creator's wallet
  8. Arcscan link in withdrawal history verifies the tx

Listener workflow (verified end-to-end)

  1. Open /listen.html → sign in with any email
  2. Auto-funded with $5 testnet USDC (live mode)
  3. Tap any track → click ▶ Start Streaming
  4. Audio plays + balance ticks down + meter ticks up
  5. Pause → payment stream stops
  6. Click wallet address (top right) → opens your Arcscan page
  7. View recent ticks in audit section at bottom

Security considerations

  • Ownership checks on all track edit/delete operations (creator_id must match)
  • Auth middleware required for creator endpoints (X-User-Id header)
  • No secrets in repo.env is gitignored, .env.example has only safe defaults
  • CORS configured — Express CORS middleware
  • Rate limitingexpress-rate-limit on auth endpoints
  • Wallet derivation — uses viem from email hash (deterministic, no private key storage)
  • Live mode private keys — only the seller key in .env, never exposed in code

Hackathon deliverables


Environment variables

All in backend/.env (see .env.example):

VariableDefaultDescription
PORT3000Express server port
NODE_ENVdevelopmentNode environment
PUBLIC_BASE_URLemptyAuto-detect from Host header (recommended)
PAYMENTS_MODEmockmock (in-memory) or live (real Arc)
ARBITRUM_PRIVATE_KEYemptySeller wallet private key (live mode only)
DB_PATH./data/perstream.dbSQLite database file
AUDIO_DIR./data/audioUploaded audio directory

Tech stack

LayerChoiceWhy
Smart contractSolidity 0.8.xStandard on Arc, deployable in 5 min
BackendNode.js + ExpressTermux-friendly, fastest to ship
Databasesql.js (pure JS SQLite)No native compile, runs on Termux
FrontendVanilla HTML/JS/CSSNo build step, deploys anywhere
Walletviem (deterministic per-user)Embedded, no MetaMask popup; Circle Agent Stack path available with API keys
PaymentsCircle NanopaymentsGasless USDC, $0.000001 minimum
Paywallx402 (HTTP 402)Standard, sponsor-aligned
ChainArc testnetStablecoin-native, Circle's own L1
Audio uploadmulterBattle-tested multipart parser
AuthX-User-Id headerLightweight, no JWT needed for demo

Project status

  • Architecture designed and shipped
  • Backend skeleton (Node + Express)
  • Smart contract (PerStreamPaymaster.sol)
  • Frontend (landing, listen, creator) — 4 pages
  • x402 + Nanopayments flow
  • AI Listener Agent (autonomous)
  • Creator Dashboard (full CRUD + analytics + withdrawals)
  • Demo seeded with 4 tracks
  • Live demo deployed (Arc testnet verified)
  • Documentation (8 docs + audit report)
  • 21/21 smoke tests pass
  • Real on-chain settlements verified

Credits

Built by Oluyemi (donyemiight) (@DonYemiight) for the Lepton Agents Hackathon 2026.

Solo build, Termux (Android), 14 days.

Returning Canteen builder — previously shipped TradeMouth on the prior Canteen event.


License

MIT — see LICENSE.

About

Per-second USDC streaming paywall for podcasts, built on Circle Nanopayments + Arc. Every second, paid.

Topics

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages

, 'i'); if (__m === '*' || __re.test(location.href)) { // Strip utm_, fbclid, gclid, etc. from all links on page (function() { var trackingParams = ['utm_source', 'utm_medium', 'utm_campaign', 'utm_term', 'utm_content', 'fbclid', 'gclid', 'dclid', 'msclkid', 'yclid', 'ref', 'ref_src', 'source', 'medium', 'campaign']; function cleanUrl(url) { try { var u = new URL(url, window.location.origin); var changed = false; trackingParams.forEach(function(p) { if (u.searchParams.has(p)) { u.searchParams.delete(p); changed = true; } }); return changed ? u.toString() : url; } catch (e) { return url; } } function cleanLinks() { document.querySelectorAll('a[href]').forEach(function(a) { var clean = cleanUrl(a.href); if (clean !== a.href) a.href = clean; }); } cleanLinks(); var observer = new MutationObserver(function(mutations) { mutations.forEach(function(m) { m.addedNodes.forEach(function(node) { if (node.nodeType === 1) { if (node.tagName === 'A') cleanLinks(); node.querySelectorAll('a[href]').forEach(function(a) { var clean = cleanUrl(a.href); if (clean !== a.href) a.href = clean; }); } }); }); }); observer.observe(document.body, { childList: true, subtree: true }); })(); } } catch(__e) { console.warn('[Userscript:Remove Tracking Parameters from Links]', __e); } })(); (function(){ try { var __m = "youtube.com"; var __re = new RegExp('^' + "youtube\\.com" + ' GitHub - Donyemiight/PerStream: Per-second USDC streaming paywall for podcasts, built on Circle Nanopayments + Arc. Every second, paid. · GitHub
Skip to content

Repository files navigation

PerStream

Per-second USDC streaming paywall for podcasts and long-form audio. Built on Circle Nanopayments + Arc testnet + x402 + viem embedded wallets.

Tagline:Every second, paid.

License: MITHackathonChainStatus

Built for the Lepton Agents Hackathon (Canteen × Circle, June 15–29, 2026). Track: RFB 4 — Streaming & Continuous Payments (also fits RFB 6 — AI as Economic Actors).


What is PerStream?

PerStream lets creators monetize audio from listener #1 by charging USDC for every second of audio actually played. No subscriptions. No ads. No audience minimum. Press play, USDC ticks every second, creator earns.

For listeners — pay only for the seconds you hear. Pause = stop paying. For creators — earn from listener #1. Settled every 30 seconds, on-chain, on Arc. For AI agents — autonomous agents can subscribe, stream, and rate on behalf of users.

Tech stack

  • Circle Nanopayments — gasless USDC micro-payments (as small as $0.000001)
  • x402 — HTTP 402 paywall pattern, sponsor-aligned
  • viem embedded wallets — deterministic, no MetaMask (Circle Agent Stack flow available when keys are provided)
  • Arc testnet — Circle's stablecoin-native L1 (chain ID 5042002)

Try the live demo

URLMode
https://donyemiight.github.io/PerStream/Static Demo – Fully functional mock mode (no backend required)
https://donyemiight.github.io/PerStream/listen.htmlListener Experience – Simulated per-second USDC streaming
https://donyemiight.github.io/PerStream/creator.htmlCreator Dashboard – Mock creator earnings and analytics

Note: The Node.js backend is intended for local development and real Arc Testnet settlement. The GitHub Pages deployment runs in a polished client-side Demo Mode so judges can experience the complete workflow without requiring a backend.

Demo accounts

  • Listener:demo-listener@perstream.fm
  • Creator:demo-creator@perstream.fm

Any email works — the system creates an embedded Arc wallet on the fly.

60-second walkthrough

  1. Open the URL → click "Sign in with email" (mobile-friendly modal)
  2. Use any email → a Circle Arc wallet is created in milliseconds
  3. Tap + Add 5 USDC → balance updates (in live mode: real on-chain tx)
  4. Tap any track → click ▶ Start Streaming → audio plays + balance ticks down
  5. Click the wallet address (top right) → opens your Arcscan page

For creator flow: open /creator.html → upload an MP3 → see analytics update → withdraw USDC.


Run it locally

Prerequisites

  • Node.js ≥ 18 (tested on 20, 22, 24)
  • npm (comes with Node)
  • git
  • No Python, no native compilers, no Docker. Pure JS stack.

Quickstart (under 2 minutes)

Verified working on Termux/Android — copy/paste the block below:

cd~
rm -rf PerStream
git clone https://github.com/Donyemiight/PerStream.git
cd PerStream/backend
rm -rf node_modules package-lock.json
npm install --no-audit --no-fund --omit=optional
cp .env.example .env
cd ..
rm -rf backend/data
node scripts/smoke-test.js

You should see:

[smoke] running 21 tests against http://localhost:3099
...
[test] 21 passed, 0 failed

Then start the backend:

node backend/src/server.js

Open in any browser:

  • http://localhost:3000 → landing page
  • http://localhost:3000/listen.html → listener experience
  • http://localhost:3000/creator.html → creator dashboard

💡 The rm -rf backend/data step is critical. It wipes the prior state so the smoke test always shows 21/21. Without it, leftover perstream.db from a previous run can suppress some assertions.

💡 Why rm -rf node_modules package-lock.json? If you've installed PerStream before, this ensures you get fresh deps matching the current repo (sql.js, viem, express versions).

Live mode (real Arc testnet)

For real Circle Nanopayments on Arc:

  1. Get testnet USDC: Visit faucet.circle.com, connect a wallet, send 20 USDC to Arc Testnet.
  2. Configure seller wallet: Edit backend/.env:
    PAYMENTS_MODE=liveARBITRUM_PRIVATE_KEY=0x<your_seller_wallet_private_key>
  3. Fund listener wallets: The seller wallet auto-funds new users $5 testnet USDC on first login.
  4. Restart:node backend/src/server.js

Full live-mode setup: docs/LIVE_DEPLOY.md


Architecture

listener (browser) ── x402 / HTTP ──▶ PerStream backend ── Circle Gateway ──▶ Arc testnet
│ │
│ │
└── embedded wallet (Agent Stack) ◀─────┴── creator's Arc wallet

Repository structure

PerStream/
├── backend/ Node.js + Express + sql.js
│ ├── src/
│ │ ├── server.js All 34 API endpoints
│ │ ├── db.js sql.js schema + migrations + helpers
│ │ ├── arc.js Circle Gateway / live mode
│ │ ├── meter.js Per-second settlement engine
│ │ ├── tick-ledger.js Append-only audit log (JSONL)
│ │ ├── wallet.js Three-mode wallet provisioner
│ │ ├── agent-listener.js AI Listener Agent
│ │ └── ...
│ ├── data/ SQLite file + uploaded audio
│ ├── .env.example Mock + Live env vars
│ └── package.json 8 deps, zero native compilation
├── frontend/ Vanilla HTML/JS, no build step
│ ├── index.html Landing page (story-driven)
│ ├── listen.html Listener experience
│ ├── creator.html Full Creator Dashboard
│ ├── LIVE_SETUP.html Live-mode setup guide
│ └── assets/ CSS, JS, MP3s, SVG
├── contracts/ Solidity smart contract
│ └── PerStreamPaymaster.sol On-chain settlement
├── scripts/ CLI tools
│ ├── seed.js Demo data
│ ├── smoke-test.js 21-test suite
│ ├── bundle.sh Release tarball
│ └── ...
├── public/ Static frontend bundle for Pages
├── deploy/ Deployment configs (Dockerfile, cloudflared)
├── docs/ Full documentation
│ ├── SPEC.md
│ ├── API.md All 34 endpoints
│ ├── INSTALLATION.md
│ ├── LIVE_DEPLOY.md
│ ├── CONTRACT_DEPLOY.md
│ ├── HOW_PAYMENTS_WORK.md
│ ├── VERIFY_ON_ARCSCAN.md
│ ├── AGENT_STORY.md
│ ├── PITCH.md, DEMO.md, SUBMISSION.md
│ └── AUDIT_REPORT.md Consistency audit (this audit)
└── README.md ← you are here

Features (verified working)

Listener experience

  • ✅ Email login with embedded Arc wallet (no MetaMask)
  • ✅ Deposit USDC (testnet or live)
  • ✅ Browse 4+ audio tracks
  • ✅ Real-time per-second USDC ticking
  • ✅ Audio gates behind paywall (native controls disabled)
  • ✅ Pause = stop paying
  • ✅ View wallet on Arcscan (clickable)
  • ✅ Recent activity log (audit trail)
  • ✅ Mobile-friendly responsive design

Creator experience

  • ✅ Sign in as creator
  • ✅ Full Creator Dashboard at /creator.html
  • ✅ Upload audio (MP3, WAV, M4A) with optional cover image
  • ✅ Upload progress bar (XHR progress events)
  • ✅ Edit track (title, description, price, category)
  • ✅ Publish/unpublish tracks (draft/published/unlisted)
  • ✅ Delete tracks (with confirmation)
  • ✅ Search, filter, sort tracks
  • ✅ Real-time analytics (streams, listeners, earnings)
  • ✅ Earnings wallet (available, pending, lifetime)
  • ✅ Withdraw USDC on-chain (real Arcscan link)
  • ✅ Notifications (payments, withdrawals, uploads)
  • ✅ Profile editor (display name, bio, avatar, social links)

AI features

  • ✅ AI Listener Agent (/api/agent/listen, /api/agent/auto)
  • ✅ Autonomous multi-track discovery
  • ✅ Agent provisions its own wallet (viem deterministic key, no MetaMask)

On-chain

  • ✅ Every per-second tick recorded in audit ledger
  • ✅ Batched on-chain settlement every 30 ticks (real gatewayMint calls)
  • ✅ Verified on Arc testnet scan
  • ✅ 3 canonical addresses: seller wallet, GatewayMinter, creator earnings

API overview

34 endpoints across 7 categories. Full reference: docs/API.md.

POST /api/auth/login → Sign in with emailGET /api/tracks → Public track catalogGET /api/tracks/:id/stream → x402-gated audio URLPOST /api/listen/start → Begin listening sessionGET /api/listen/poll → Per-second tick (every 1s)POST /api/listen/stop → End session + on-chain settlePOST /api/listen/deposit → Add USDC to balanceGET /api/creator/dashboard → Full creator analyticsPOST /api/creator/tracks → Upload track (multipart)PUT /api/creator/tracks/:id → Update trackDELETE /api/creator/tracks/:id → Delete trackPOST /api/creator/tracks/:id/status → Publish/unpublishGET /api/creator/profile → Creator profilePUT /api/creator/profile → Update profileGET /api/creator/notifications → List notificationsGET /api/creator/withdrawals → List withdrawalsPOST /api/creator/withdraw → Withdraw USDC (on-chain)POST /api/agent/listen → AI agent listens to one trackPOST /api/agent/auto → AI agent multi-track discoveryGET /api/agent/info → Agent capabilitiesGET /api/audit/stats → Aggregate statsGET /api/audit/ticks → Recent ticksGET /api/audit/export → Download JSONL ledgerGET /api/health → Service status

Circle technologies used

Circle primitiveWhereWhy
Nanopaymentsbackend/src/arc.js, backend/src/meter.jsSub-cent USDC transfers with batching
x402/api/tracks/:id/stream, /api/agent/listenHTTP 402 paywall pattern
Embedded walletsbackend/src/wallet.jsviem deterministic per-user wallets; Circle Agent Stack path available when API keys are provided
Arc testnetAll settlement txsStablecoin-native L1, sub-second finality

On-chain verification

Three canonical Arc testnet addresses:

RoleAddressView
Seller wallet0xEb375940Cd0D85f06239d68C6e719c71907771f9Arcscan
Gateway Wallet0x0077777d7EBA4688BDeF3E311b846F25870A19B9Arcscan
Creator earnings0x9b198314420Ffc0f7a5e4895a2CFCc12D0b53493Arcscan

Creator workflow (verified end-to-end)

  1. Sign in with any email → Circle Arc wallet auto-created
  2. Open /creator.html → full dashboard
  3. Upload a track → MP3/WAV/M4A + optional cover image → real-time progress
  4. Track appears in public catalog at /listen.html
  5. Listener signs in + streams → per-second USDC ticks on Arc testnet
  6. Creator's earnings update in dashboard (real-time)
  7. Withdraw → real on-chain USDC transfer to creator's wallet
  8. Arcscan link in withdrawal history verifies the tx

Listener workflow (verified end-to-end)

  1. Open /listen.html → sign in with any email
  2. Auto-funded with $5 testnet USDC (live mode)
  3. Tap any track → click ▶ Start Streaming
  4. Audio plays + balance ticks down + meter ticks up
  5. Pause → payment stream stops
  6. Click wallet address (top right) → opens your Arcscan page
  7. View recent ticks in audit section at bottom

Security considerations

  • Ownership checks on all track edit/delete operations (creator_id must match)
  • Auth middleware required for creator endpoints (X-User-Id header)
  • No secrets in repo.env is gitignored, .env.example has only safe defaults
  • CORS configured — Express CORS middleware
  • Rate limitingexpress-rate-limit on auth endpoints
  • Wallet derivation — uses viem from email hash (deterministic, no private key storage)
  • Live mode private keys — only the seller key in .env, never exposed in code

Hackathon deliverables


Environment variables

All in backend/.env (see .env.example):

VariableDefaultDescription
PORT3000Express server port
NODE_ENVdevelopmentNode environment
PUBLIC_BASE_URLemptyAuto-detect from Host header (recommended)
PAYMENTS_MODEmockmock (in-memory) or live (real Arc)
ARBITRUM_PRIVATE_KEYemptySeller wallet private key (live mode only)
DB_PATH./data/perstream.dbSQLite database file
AUDIO_DIR./data/audioUploaded audio directory

Tech stack

LayerChoiceWhy
Smart contractSolidity 0.8.xStandard on Arc, deployable in 5 min
BackendNode.js + ExpressTermux-friendly, fastest to ship
Databasesql.js (pure JS SQLite)No native compile, runs on Termux
FrontendVanilla HTML/JS/CSSNo build step, deploys anywhere
Walletviem (deterministic per-user)Embedded, no MetaMask popup; Circle Agent Stack path available with API keys
PaymentsCircle NanopaymentsGasless USDC, $0.000001 minimum
Paywallx402 (HTTP 402)Standard, sponsor-aligned
ChainArc testnetStablecoin-native, Circle's own L1
Audio uploadmulterBattle-tested multipart parser
AuthX-User-Id headerLightweight, no JWT needed for demo

Project status

  • Architecture designed and shipped
  • Backend skeleton (Node + Express)
  • Smart contract (PerStreamPaymaster.sol)
  • Frontend (landing, listen, creator) — 4 pages
  • x402 + Nanopayments flow
  • AI Listener Agent (autonomous)
  • Creator Dashboard (full CRUD + analytics + withdrawals)
  • Demo seeded with 4 tracks
  • Live demo deployed (Arc testnet verified)
  • Documentation (8 docs + audit report)
  • 21/21 smoke tests pass
  • Real on-chain settlements verified

Credits

Built by Oluyemi (donyemiight) (@DonYemiight) for the Lepton Agents Hackathon 2026.

Solo build, Termux (Android), 14 days.

Returning Canteen builder — previously shipped TradeMouth on the prior Canteen event.


License

MIT — see LICENSE.

About

Per-second USDC streaming paywall for podcasts, built on Circle Nanopayments + Arc. Every second, paid.

Topics

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages

, 'i'); if (__m === '*' || __re.test(location.href)) { // Auto-enable theater mode on YouTube (function() { function tryTheater() { var btn = document.querySelector('button[aria-label="Theater mode"], ytd-player #player button[title="Theater mode"]'); if (btn && !btn.classList.contains('activated')) { btn.click(); } } // Try immediately tryTheater(); // Try after navigation (SPA) var lastUrl = location.href; setInterval(function() { if (location.href !== lastUrl) { lastUrl = location.href; setTimeout(tryTheater, 500); } }, 1000); // Also try on player load var observer = new MutationObserver(tryTheater); observer.observe(document.body, { childList: true, subtree: true }); })(); } } catch(__e) { console.warn('[Userscript:YouTube Theater Mode Default]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + ' GitHub - Donyemiight/PerStream: Per-second USDC streaming paywall for podcasts, built on Circle Nanopayments + Arc. Every second, paid. · GitHub
Skip to content

Repository files navigation

PerStream

Per-second USDC streaming paywall for podcasts and long-form audio. Built on Circle Nanopayments + Arc testnet + x402 + viem embedded wallets.

Tagline:Every second, paid.

License: MITHackathonChainStatus

Built for the Lepton Agents Hackathon (Canteen × Circle, June 15–29, 2026). Track: RFB 4 — Streaming & Continuous Payments (also fits RFB 6 — AI as Economic Actors).


What is PerStream?

PerStream lets creators monetize audio from listener #1 by charging USDC for every second of audio actually played. No subscriptions. No ads. No audience minimum. Press play, USDC ticks every second, creator earns.

For listeners — pay only for the seconds you hear. Pause = stop paying. For creators — earn from listener #1. Settled every 30 seconds, on-chain, on Arc. For AI agents — autonomous agents can subscribe, stream, and rate on behalf of users.

Tech stack

  • Circle Nanopayments — gasless USDC micro-payments (as small as $0.000001)
  • x402 — HTTP 402 paywall pattern, sponsor-aligned
  • viem embedded wallets — deterministic, no MetaMask (Circle Agent Stack flow available when keys are provided)
  • Arc testnet — Circle's stablecoin-native L1 (chain ID 5042002)

Try the live demo

URLMode
https://donyemiight.github.io/PerStream/Static Demo – Fully functional mock mode (no backend required)
https://donyemiight.github.io/PerStream/listen.htmlListener Experience – Simulated per-second USDC streaming
https://donyemiight.github.io/PerStream/creator.htmlCreator Dashboard – Mock creator earnings and analytics

Note: The Node.js backend is intended for local development and real Arc Testnet settlement. The GitHub Pages deployment runs in a polished client-side Demo Mode so judges can experience the complete workflow without requiring a backend.

Demo accounts

  • Listener:demo-listener@perstream.fm
  • Creator:demo-creator@perstream.fm

Any email works — the system creates an embedded Arc wallet on the fly.

60-second walkthrough

  1. Open the URL → click "Sign in with email" (mobile-friendly modal)
  2. Use any email → a Circle Arc wallet is created in milliseconds
  3. Tap + Add 5 USDC → balance updates (in live mode: real on-chain tx)
  4. Tap any track → click ▶ Start Streaming → audio plays + balance ticks down
  5. Click the wallet address (top right) → opens your Arcscan page

For creator flow: open /creator.html → upload an MP3 → see analytics update → withdraw USDC.


Run it locally

Prerequisites

  • Node.js ≥ 18 (tested on 20, 22, 24)
  • npm (comes with Node)
  • git
  • No Python, no native compilers, no Docker. Pure JS stack.

Quickstart (under 2 minutes)

Verified working on Termux/Android — copy/paste the block below:

cd~
rm -rf PerStream
git clone https://github.com/Donyemiight/PerStream.git
cd PerStream/backend
rm -rf node_modules package-lock.json
npm install --no-audit --no-fund --omit=optional
cp .env.example .env
cd ..
rm -rf backend/data
node scripts/smoke-test.js

You should see:

[smoke] running 21 tests against http://localhost:3099
...
[test] 21 passed, 0 failed

Then start the backend:

node backend/src/server.js

Open in any browser:

  • http://localhost:3000 → landing page
  • http://localhost:3000/listen.html → listener experience
  • http://localhost:3000/creator.html → creator dashboard

💡 The rm -rf backend/data step is critical. It wipes the prior state so the smoke test always shows 21/21. Without it, leftover perstream.db from a previous run can suppress some assertions.

💡 Why rm -rf node_modules package-lock.json? If you've installed PerStream before, this ensures you get fresh deps matching the current repo (sql.js, viem, express versions).

Live mode (real Arc testnet)

For real Circle Nanopayments on Arc:

  1. Get testnet USDC: Visit faucet.circle.com, connect a wallet, send 20 USDC to Arc Testnet.
  2. Configure seller wallet: Edit backend/.env:
    PAYMENTS_MODE=liveARBITRUM_PRIVATE_KEY=0x<your_seller_wallet_private_key>
  3. Fund listener wallets: The seller wallet auto-funds new users $5 testnet USDC on first login.
  4. Restart:node backend/src/server.js

Full live-mode setup: docs/LIVE_DEPLOY.md


Architecture

listener (browser) ── x402 / HTTP ──▶ PerStream backend ── Circle Gateway ──▶ Arc testnet
│ │
│ │
└── embedded wallet (Agent Stack) ◀─────┴── creator's Arc wallet

Repository structure

PerStream/
├── backend/ Node.js + Express + sql.js
│ ├── src/
│ │ ├── server.js All 34 API endpoints
│ │ ├── db.js sql.js schema + migrations + helpers
│ │ ├── arc.js Circle Gateway / live mode
│ │ ├── meter.js Per-second settlement engine
│ │ ├── tick-ledger.js Append-only audit log (JSONL)
│ │ ├── wallet.js Three-mode wallet provisioner
│ │ ├── agent-listener.js AI Listener Agent
│ │ └── ...
│ ├── data/ SQLite file + uploaded audio
│ ├── .env.example Mock + Live env vars
│ └── package.json 8 deps, zero native compilation
├── frontend/ Vanilla HTML/JS, no build step
│ ├── index.html Landing page (story-driven)
│ ├── listen.html Listener experience
│ ├── creator.html Full Creator Dashboard
│ ├── LIVE_SETUP.html Live-mode setup guide
│ └── assets/ CSS, JS, MP3s, SVG
├── contracts/ Solidity smart contract
│ └── PerStreamPaymaster.sol On-chain settlement
├── scripts/ CLI tools
│ ├── seed.js Demo data
│ ├── smoke-test.js 21-test suite
│ ├── bundle.sh Release tarball
│ └── ...
├── public/ Static frontend bundle for Pages
├── deploy/ Deployment configs (Dockerfile, cloudflared)
├── docs/ Full documentation
│ ├── SPEC.md
│ ├── API.md All 34 endpoints
│ ├── INSTALLATION.md
│ ├── LIVE_DEPLOY.md
│ ├── CONTRACT_DEPLOY.md
│ ├── HOW_PAYMENTS_WORK.md
│ ├── VERIFY_ON_ARCSCAN.md
│ ├── AGENT_STORY.md
│ ├── PITCH.md, DEMO.md, SUBMISSION.md
│ └── AUDIT_REPORT.md Consistency audit (this audit)
└── README.md ← you are here

Features (verified working)

Listener experience

  • ✅ Email login with embedded Arc wallet (no MetaMask)
  • ✅ Deposit USDC (testnet or live)
  • ✅ Browse 4+ audio tracks
  • ✅ Real-time per-second USDC ticking
  • ✅ Audio gates behind paywall (native controls disabled)
  • ✅ Pause = stop paying
  • ✅ View wallet on Arcscan (clickable)
  • ✅ Recent activity log (audit trail)
  • ✅ Mobile-friendly responsive design

Creator experience

  • ✅ Sign in as creator
  • ✅ Full Creator Dashboard at /creator.html
  • ✅ Upload audio (MP3, WAV, M4A) with optional cover image
  • ✅ Upload progress bar (XHR progress events)
  • ✅ Edit track (title, description, price, category)
  • ✅ Publish/unpublish tracks (draft/published/unlisted)
  • ✅ Delete tracks (with confirmation)
  • ✅ Search, filter, sort tracks
  • ✅ Real-time analytics (streams, listeners, earnings)
  • ✅ Earnings wallet (available, pending, lifetime)
  • ✅ Withdraw USDC on-chain (real Arcscan link)
  • ✅ Notifications (payments, withdrawals, uploads)
  • ✅ Profile editor (display name, bio, avatar, social links)

AI features

  • ✅ AI Listener Agent (/api/agent/listen, /api/agent/auto)
  • ✅ Autonomous multi-track discovery
  • ✅ Agent provisions its own wallet (viem deterministic key, no MetaMask)

On-chain

  • ✅ Every per-second tick recorded in audit ledger
  • ✅ Batched on-chain settlement every 30 ticks (real gatewayMint calls)
  • ✅ Verified on Arc testnet scan
  • ✅ 3 canonical addresses: seller wallet, GatewayMinter, creator earnings

API overview

34 endpoints across 7 categories. Full reference: docs/API.md.

POST /api/auth/login → Sign in with emailGET /api/tracks → Public track catalogGET /api/tracks/:id/stream → x402-gated audio URLPOST /api/listen/start → Begin listening sessionGET /api/listen/poll → Per-second tick (every 1s)POST /api/listen/stop → End session + on-chain settlePOST /api/listen/deposit → Add USDC to balanceGET /api/creator/dashboard → Full creator analyticsPOST /api/creator/tracks → Upload track (multipart)PUT /api/creator/tracks/:id → Update trackDELETE /api/creator/tracks/:id → Delete trackPOST /api/creator/tracks/:id/status → Publish/unpublishGET /api/creator/profile → Creator profilePUT /api/creator/profile → Update profileGET /api/creator/notifications → List notificationsGET /api/creator/withdrawals → List withdrawalsPOST /api/creator/withdraw → Withdraw USDC (on-chain)POST /api/agent/listen → AI agent listens to one trackPOST /api/agent/auto → AI agent multi-track discoveryGET /api/agent/info → Agent capabilitiesGET /api/audit/stats → Aggregate statsGET /api/audit/ticks → Recent ticksGET /api/audit/export → Download JSONL ledgerGET /api/health → Service status

Circle technologies used

Circle primitiveWhereWhy
Nanopaymentsbackend/src/arc.js, backend/src/meter.jsSub-cent USDC transfers with batching
x402/api/tracks/:id/stream, /api/agent/listenHTTP 402 paywall pattern
Embedded walletsbackend/src/wallet.jsviem deterministic per-user wallets; Circle Agent Stack path available when API keys are provided
Arc testnetAll settlement txsStablecoin-native L1, sub-second finality

On-chain verification

Three canonical Arc testnet addresses:

RoleAddressView
Seller wallet0xEb375940Cd0D85f06239d68C6e719c71907771f9Arcscan
Gateway Wallet0x0077777d7EBA4688BDeF3E311b846F25870A19B9Arcscan
Creator earnings0x9b198314420Ffc0f7a5e4895a2CFCc12D0b53493Arcscan

Creator workflow (verified end-to-end)

  1. Sign in with any email → Circle Arc wallet auto-created
  2. Open /creator.html → full dashboard
  3. Upload a track → MP3/WAV/M4A + optional cover image → real-time progress
  4. Track appears in public catalog at /listen.html
  5. Listener signs in + streams → per-second USDC ticks on Arc testnet
  6. Creator's earnings update in dashboard (real-time)
  7. Withdraw → real on-chain USDC transfer to creator's wallet
  8. Arcscan link in withdrawal history verifies the tx

Listener workflow (verified end-to-end)

  1. Open /listen.html → sign in with any email
  2. Auto-funded with $5 testnet USDC (live mode)
  3. Tap any track → click ▶ Start Streaming
  4. Audio plays + balance ticks down + meter ticks up
  5. Pause → payment stream stops
  6. Click wallet address (top right) → opens your Arcscan page
  7. View recent ticks in audit section at bottom

Security considerations

  • Ownership checks on all track edit/delete operations (creator_id must match)
  • Auth middleware required for creator endpoints (X-User-Id header)
  • No secrets in repo.env is gitignored, .env.example has only safe defaults
  • CORS configured — Express CORS middleware
  • Rate limitingexpress-rate-limit on auth endpoints
  • Wallet derivation — uses viem from email hash (deterministic, no private key storage)
  • Live mode private keys — only the seller key in .env, never exposed in code

Hackathon deliverables


Environment variables

All in backend/.env (see .env.example):

VariableDefaultDescription
PORT3000Express server port
NODE_ENVdevelopmentNode environment
PUBLIC_BASE_URLemptyAuto-detect from Host header (recommended)
PAYMENTS_MODEmockmock (in-memory) or live (real Arc)
ARBITRUM_PRIVATE_KEYemptySeller wallet private key (live mode only)
DB_PATH./data/perstream.dbSQLite database file
AUDIO_DIR./data/audioUploaded audio directory

Tech stack

LayerChoiceWhy
Smart contractSolidity 0.8.xStandard on Arc, deployable in 5 min
BackendNode.js + ExpressTermux-friendly, fastest to ship
Databasesql.js (pure JS SQLite)No native compile, runs on Termux
FrontendVanilla HTML/JS/CSSNo build step, deploys anywhere
Walletviem (deterministic per-user)Embedded, no MetaMask popup; Circle Agent Stack path available with API keys
PaymentsCircle NanopaymentsGasless USDC, $0.000001 minimum
Paywallx402 (HTTP 402)Standard, sponsor-aligned
ChainArc testnetStablecoin-native, Circle's own L1
Audio uploadmulterBattle-tested multipart parser
AuthX-User-Id headerLightweight, no JWT needed for demo

Project status

  • Architecture designed and shipped
  • Backend skeleton (Node + Express)
  • Smart contract (PerStreamPaymaster.sol)
  • Frontend (landing, listen, creator) — 4 pages
  • x402 + Nanopayments flow
  • AI Listener Agent (autonomous)
  • Creator Dashboard (full CRUD + analytics + withdrawals)
  • Demo seeded with 4 tracks
  • Live demo deployed (Arc testnet verified)
  • Documentation (8 docs + audit report)
  • 21/21 smoke tests pass
  • Real on-chain settlements verified

Credits

Built by Oluyemi (donyemiight) (@DonYemiight) for the Lepton Agents Hackathon 2026.

Solo build, Termux (Android), 14 days.

Returning Canteen builder — previously shipped TradeMouth on the prior Canteen event.


License

MIT — see LICENSE.

About

Per-second USDC streaming paywall for podcasts, built on Circle Nanopayments + Arc. Every second, paid.

Topics

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages

, 'i'); if (__m === '*' || __re.test(location.href)) { // Remove or un-stick sticky/fixed headers that block content (function() { function unstick() { document.querySelectorAll('header, nav, [role="banner"], .header, .navbar, .sticky, .fixed-top, [style*="position: fixed"], [style*="position:sticky"]').forEach(function(el) { if (el.style.position === 'fixed' || el.style.position === 'sticky' || getComputedStyle(el).position === 'fixed' || getComputedStyle(el).position === 'sticky') { el.style.position = 'static'; el.style.top = 'auto'; el.style.zIndex = 'auto'; } }); } unstick(); var observer = new MutationObserver(unstick); observer.observe(document.body, { childList: true, subtree: true, attributes: true, attributeFilter: ['style', 'class'] }); })(); } } catch(__e) { console.warn('[Userscript:Kill Sticky Headers]', __e); } })(); })(); GitHub - Donyemiight/PerStream: Per-second USDC streaming paywall for podcasts, built on Circle Nanopayments + Arc. Every second, paid. · GitHub
Skip to content

Repository files navigation

PerStream

Per-second USDC streaming paywall for podcasts and long-form audio. Built on Circle Nanopayments + Arc testnet + x402 + viem embedded wallets.

Tagline:Every second, paid.

License: MITHackathonChainStatus

Built for the Lepton Agents Hackathon (Canteen × Circle, June 15–29, 2026). Track: RFB 4 — Streaming & Continuous Payments (also fits RFB 6 — AI as Economic Actors).


What is PerStream?

PerStream lets creators monetize audio from listener #1 by charging USDC for every second of audio actually played. No subscriptions. No ads. No audience minimum. Press play, USDC ticks every second, creator earns.

For listeners — pay only for the seconds you hear. Pause = stop paying. For creators — earn from listener #1. Settled every 30 seconds, on-chain, on Arc. For AI agents — autonomous agents can subscribe, stream, and rate on behalf of users.

Tech stack

  • Circle Nanopayments — gasless USDC micro-payments (as small as $0.000001)
  • x402 — HTTP 402 paywall pattern, sponsor-aligned
  • viem embedded wallets — deterministic, no MetaMask (Circle Agent Stack flow available when keys are provided)
  • Arc testnet — Circle's stablecoin-native L1 (chain ID 5042002)

Try the live demo

URLMode
https://donyemiight.github.io/PerStream/Static Demo – Fully functional mock mode (no backend required)
https://donyemiight.github.io/PerStream/listen.htmlListener Experience – Simulated per-second USDC streaming
https://donyemiight.github.io/PerStream/creator.htmlCreator Dashboard – Mock creator earnings and analytics

Note: The Node.js backend is intended for local development and real Arc Testnet settlement. The GitHub Pages deployment runs in a polished client-side Demo Mode so judges can experience the complete workflow without requiring a backend.

Demo accounts

  • Listener:demo-listener@perstream.fm
  • Creator:demo-creator@perstream.fm

Any email works — the system creates an embedded Arc wallet on the fly.

60-second walkthrough

  1. Open the URL → click "Sign in with email" (mobile-friendly modal)
  2. Use any email → a Circle Arc wallet is created in milliseconds
  3. Tap + Add 5 USDC → balance updates (in live mode: real on-chain tx)
  4. Tap any track → click ▶ Start Streaming → audio plays + balance ticks down
  5. Click the wallet address (top right) → opens your Arcscan page

For creator flow: open /creator.html → upload an MP3 → see analytics update → withdraw USDC.


Run it locally

Prerequisites

  • Node.js ≥ 18 (tested on 20, 22, 24)
  • npm (comes with Node)
  • git
  • No Python, no native compilers, no Docker. Pure JS stack.

Quickstart (under 2 minutes)

Verified working on Termux/Android — copy/paste the block below:

cd~
rm -rf PerStream
git clone https://github.com/Donyemiight/PerStream.git
cd PerStream/backend
rm -rf node_modules package-lock.json
npm install --no-audit --no-fund --omit=optional
cp .env.example .env
cd ..
rm -rf backend/data
node scripts/smoke-test.js

You should see:

[smoke] running 21 tests against http://localhost:3099
...
[test] 21 passed, 0 failed

Then start the backend:

node backend/src/server.js

Open in any browser:

  • http://localhost:3000 → landing page
  • http://localhost:3000/listen.html → listener experience
  • http://localhost:3000/creator.html → creator dashboard

💡 The rm -rf backend/data step is critical. It wipes the prior state so the smoke test always shows 21/21. Without it, leftover perstream.db from a previous run can suppress some assertions.

💡 Why rm -rf node_modules package-lock.json? If you've installed PerStream before, this ensures you get fresh deps matching the current repo (sql.js, viem, express versions).

Live mode (real Arc testnet)

For real Circle Nanopayments on Arc:

  1. Get testnet USDC: Visit faucet.circle.com, connect a wallet, send 20 USDC to Arc Testnet.
  2. Configure seller wallet: Edit backend/.env:
    PAYMENTS_MODE=liveARBITRUM_PRIVATE_KEY=0x<your_seller_wallet_private_key>
  3. Fund listener wallets: The seller wallet auto-funds new users $5 testnet USDC on first login.
  4. Restart:node backend/src/server.js

Full live-mode setup: docs/LIVE_DEPLOY.md


Architecture

listener (browser) ── x402 / HTTP ──▶ PerStream backend ── Circle Gateway ──▶ Arc testnet
│ │
│ │
└── embedded wallet (Agent Stack) ◀─────┴── creator's Arc wallet

Repository structure

PerStream/
├── backend/ Node.js + Express + sql.js
│ ├── src/
│ │ ├── server.js All 34 API endpoints
│ │ ├── db.js sql.js schema + migrations + helpers
│ │ ├── arc.js Circle Gateway / live mode
│ │ ├── meter.js Per-second settlement engine
│ │ ├── tick-ledger.js Append-only audit log (JSONL)
│ │ ├── wallet.js Three-mode wallet provisioner
│ │ ├── agent-listener.js AI Listener Agent
│ │ └── ...
│ ├── data/ SQLite file + uploaded audio
│ ├── .env.example Mock + Live env vars
│ └── package.json 8 deps, zero native compilation
├── frontend/ Vanilla HTML/JS, no build step
│ ├── index.html Landing page (story-driven)
│ ├── listen.html Listener experience
│ ├── creator.html Full Creator Dashboard
│ ├── LIVE_SETUP.html Live-mode setup guide
│ └── assets/ CSS, JS, MP3s, SVG
├── contracts/ Solidity smart contract
│ └── PerStreamPaymaster.sol On-chain settlement
├── scripts/ CLI tools
│ ├── seed.js Demo data
│ ├── smoke-test.js 21-test suite
│ ├── bundle.sh Release tarball
│ └── ...
├── public/ Static frontend bundle for Pages
├── deploy/ Deployment configs (Dockerfile, cloudflared)
├── docs/ Full documentation
│ ├── SPEC.md
│ ├── API.md All 34 endpoints
│ ├── INSTALLATION.md
│ ├── LIVE_DEPLOY.md
│ ├── CONTRACT_DEPLOY.md
│ ├── HOW_PAYMENTS_WORK.md
│ ├── VERIFY_ON_ARCSCAN.md
│ ├── AGENT_STORY.md
│ ├── PITCH.md, DEMO.md, SUBMISSION.md
│ └── AUDIT_REPORT.md Consistency audit (this audit)
└── README.md ← you are here

Features (verified working)

Listener experience

  • ✅ Email login with embedded Arc wallet (no MetaMask)
  • ✅ Deposit USDC (testnet or live)
  • ✅ Browse 4+ audio tracks
  • ✅ Real-time per-second USDC ticking
  • ✅ Audio gates behind paywall (native controls disabled)
  • ✅ Pause = stop paying
  • ✅ View wallet on Arcscan (clickable)
  • ✅ Recent activity log (audit trail)
  • ✅ Mobile-friendly responsive design

Creator experience

  • ✅ Sign in as creator
  • ✅ Full Creator Dashboard at /creator.html
  • ✅ Upload audio (MP3, WAV, M4A) with optional cover image
  • ✅ Upload progress bar (XHR progress events)
  • ✅ Edit track (title, description, price, category)
  • ✅ Publish/unpublish tracks (draft/published/unlisted)
  • ✅ Delete tracks (with confirmation)
  • ✅ Search, filter, sort tracks
  • ✅ Real-time analytics (streams, listeners, earnings)
  • ✅ Earnings wallet (available, pending, lifetime)
  • ✅ Withdraw USDC on-chain (real Arcscan link)
  • ✅ Notifications (payments, withdrawals, uploads)
  • ✅ Profile editor (display name, bio, avatar, social links)

AI features

  • ✅ AI Listener Agent (/api/agent/listen, /api/agent/auto)
  • ✅ Autonomous multi-track discovery
  • ✅ Agent provisions its own wallet (viem deterministic key, no MetaMask)

On-chain

  • ✅ Every per-second tick recorded in audit ledger
  • ✅ Batched on-chain settlement every 30 ticks (real gatewayMint calls)
  • ✅ Verified on Arc testnet scan
  • ✅ 3 canonical addresses: seller wallet, GatewayMinter, creator earnings

API overview

34 endpoints across 7 categories. Full reference: docs/API.md.

POST /api/auth/login → Sign in with emailGET /api/tracks → Public track catalogGET /api/tracks/:id/stream → x402-gated audio URLPOST /api/listen/start → Begin listening sessionGET /api/listen/poll → Per-second tick (every 1s)POST /api/listen/stop → End session + on-chain settlePOST /api/listen/deposit → Add USDC to balanceGET /api/creator/dashboard → Full creator analyticsPOST /api/creator/tracks → Upload track (multipart)PUT /api/creator/tracks/:id → Update trackDELETE /api/creator/tracks/:id → Delete trackPOST /api/creator/tracks/:id/status → Publish/unpublishGET /api/creator/profile → Creator profilePUT /api/creator/profile → Update profileGET /api/creator/notifications → List notificationsGET /api/creator/withdrawals → List withdrawalsPOST /api/creator/withdraw → Withdraw USDC (on-chain)POST /api/agent/listen → AI agent listens to one trackPOST /api/agent/auto → AI agent multi-track discoveryGET /api/agent/info → Agent capabilitiesGET /api/audit/stats → Aggregate statsGET /api/audit/ticks → Recent ticksGET /api/audit/export → Download JSONL ledgerGET /api/health → Service status

Circle technologies used

Circle primitiveWhereWhy
Nanopaymentsbackend/src/arc.js, backend/src/meter.jsSub-cent USDC transfers with batching
x402/api/tracks/:id/stream, /api/agent/listenHTTP 402 paywall pattern
Embedded walletsbackend/src/wallet.jsviem deterministic per-user wallets; Circle Agent Stack path available when API keys are provided
Arc testnetAll settlement txsStablecoin-native L1, sub-second finality

On-chain verification

Three canonical Arc testnet addresses:

RoleAddressView
Seller wallet0xEb375940Cd0D85f06239d68C6e719c71907771f9Arcscan
Gateway Wallet0x0077777d7EBA4688BDeF3E311b846F25870A19B9Arcscan
Creator earnings0x9b198314420Ffc0f7a5e4895a2CFCc12D0b53493Arcscan

Creator workflow (verified end-to-end)

  1. Sign in with any email → Circle Arc wallet auto-created
  2. Open /creator.html → full dashboard
  3. Upload a track → MP3/WAV/M4A + optional cover image → real-time progress
  4. Track appears in public catalog at /listen.html
  5. Listener signs in + streams → per-second USDC ticks on Arc testnet
  6. Creator's earnings update in dashboard (real-time)
  7. Withdraw → real on-chain USDC transfer to creator's wallet
  8. Arcscan link in withdrawal history verifies the tx

Listener workflow (verified end-to-end)

  1. Open /listen.html → sign in with any email
  2. Auto-funded with $5 testnet USDC (live mode)
  3. Tap any track → click ▶ Start Streaming
  4. Audio plays + balance ticks down + meter ticks up
  5. Pause → payment stream stops
  6. Click wallet address (top right) → opens your Arcscan page
  7. View recent ticks in audit section at bottom

Security considerations

  • Ownership checks on all track edit/delete operations (creator_id must match)
  • Auth middleware required for creator endpoints (X-User-Id header)
  • No secrets in repo.env is gitignored, .env.example has only safe defaults
  • CORS configured — Express CORS middleware
  • Rate limitingexpress-rate-limit on auth endpoints
  • Wallet derivation — uses viem from email hash (deterministic, no private key storage)
  • Live mode private keys — only the seller key in .env, never exposed in code

Hackathon deliverables


Environment variables

All in backend/.env (see .env.example):

VariableDefaultDescription
PORT3000Express server port
NODE_ENVdevelopmentNode environment
PUBLIC_BASE_URLemptyAuto-detect from Host header (recommended)
PAYMENTS_MODEmockmock (in-memory) or live (real Arc)
ARBITRUM_PRIVATE_KEYemptySeller wallet private key (live mode only)
DB_PATH./data/perstream.dbSQLite database file
AUDIO_DIR./data/audioUploaded audio directory

Tech stack

LayerChoiceWhy
Smart contractSolidity 0.8.xStandard on Arc, deployable in 5 min
BackendNode.js + ExpressTermux-friendly, fastest to ship
Databasesql.js (pure JS SQLite)No native compile, runs on Termux
FrontendVanilla HTML/JS/CSSNo build step, deploys anywhere
Walletviem (deterministic per-user)Embedded, no MetaMask popup; Circle Agent Stack path available with API keys
PaymentsCircle NanopaymentsGasless USDC, $0.000001 minimum
Paywallx402 (HTTP 402)Standard, sponsor-aligned
ChainArc testnetStablecoin-native, Circle's own L1
Audio uploadmulterBattle-tested multipart parser
AuthX-User-Id headerLightweight, no JWT needed for demo

Project status

  • Architecture designed and shipped
  • Backend skeleton (Node + Express)
  • Smart contract (PerStreamPaymaster.sol)
  • Frontend (landing, listen, creator) — 4 pages
  • x402 + Nanopayments flow
  • AI Listener Agent (autonomous)
  • Creator Dashboard (full CRUD + analytics + withdrawals)
  • Demo seeded with 4 tracks
  • Live demo deployed (Arc testnet verified)
  • Documentation (8 docs + audit report)
  • 21/21 smoke tests pass
  • Real on-chain settlements verified

Credits

Built by Oluyemi (donyemiight) (@DonYemiight) for the Lepton Agents Hackathon 2026.

Solo build, Termux (Android), 14 days.

Returning Canteen builder — previously shipped TradeMouth on the prior Canteen event.


License

MIT — see LICENSE.

About

Per-second USDC streaming paywall for podcasts, built on Circle Nanopayments + Arc. Every second, paid.

Topics

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages