Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
The table of contents is too big for display.
Diff view
Diff view
  •  
  •  
  •  
42 changes: 42 additions & 0 deletions .github/workflows/test-200ms-demo.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
name: 200ms demo

on:
pull_request:
paths:
- "200ms-demo/**"
- ".github/workflows/test-200ms-demo.yml"
push:
branches: [master]
paths:
- "200ms-demo/**"
- ".github/workflows/test-200ms-demo.yml"
workflow_dispatch:

permissions:
contents: read

jobs:
build:
runs-on: ubuntu-latest
defaults:
run:
working-directory: 200ms-demo
steps:
- name: Checkout
uses: actions/checkout@v6

- name: Set up Node
uses: actions/setup-node@v6
with:
node-version: 22
cache: npm
cache-dependency-path: 200ms-demo/package-lock.json

- name: Install dependencies
run: npm ci

- name: Test exact rate math
run: npm run test:math

- name: Build the hosted path
run: npm run build:pages
5 changes: 5 additions & 0 deletions 200ms-demo/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
node_modules
dist
.DS_Store
*.local
npm-debug.log*
68 changes: 68 additions & 0 deletions 200ms-demo/PHASE1.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,68 @@
# Phase 1 live-chain report

Verified against Base Vibenet on September 10, 2026.

## Final passing configuration

- Chain ID: `84538453`
- Sender implementation: `CanonicalHighRatePayerAccount`
(`0x813002ffdd25c81cef79781702176d453af0fa57` at test time)
- Bootstrap transaction: ordered nonce key `0`
- Streaming transactions: nonce-free `nonceKeyMax`, 15-second validity
- Cadence: self-correcting 200ms schedule
- Gas limit: sequenced estimate + nonce-free surcharge + 30% headroom
- Receipt reconciliation: independent watcher with exact signed-byte rebroadcast

## 50-transfer gate

| Metric | Result |
| --- | ---: |
| Transfers | 50 |
| Recipient delta | 0.833300 USDV |
| Broadcast duration | 9.922s |
| Accepted throughput | 5.04 tx/s |
| Confirmation duration | 10.824s |
| Confirmed throughput | 4.62 tx/s |
| Mean gas per transfer | 50,017 |
| Sampled base fee | 1 gwei |
| Cost per transfer | 0.000050017 ETH |
| 0.1 ETH runway | 1,999 transfers |
| Runway at 5 tx/s | 6.66 minutes |

## Five-minute streamer/funding soak

The corrected hot loop then ran for five minutes with `npm run soak`:

| Metric | Result |
| --- | ---: |
| Transfers | 1,500 |
| Recipient delta | 24.999000 USDV |
| Broadcast duration | 299.915s |
| Accepted throughput | 5.00 tx/s |
| Confirmation duration | 303.017s |
| Confirmed throughput | 4.95 tx/s |
| Mean gas per transfer | 50,040 |
| Automatic ETH top-ups | 1 |

Two absent transactions were recovered by exact signed-byte rebroadcast during
the soak. There were no unrecovered nonce failures, and every transfer was
included in the final authoritative recipient balance delta.

## Rejected designs discovered by the gate

1. **Unchecked ordered-nonce bursts:** a lower sequence could disappear after
the RPC returned its hash. Later sequences then filled the sender signature
pool and produced `sender EIP-8130 signature limit reached`.
2. **Receipt work inside the queue:** throughput fell to 2.65 tx/s.
3. **Visibility acknowledgement through the account RPC proxy:** consistent but
effectively receipt-paced at 1.39 tx/s.
4. **Account configuration lock:** the current execution client rejected the
lock change as `unknown account-change op in the enshrined apply path`.
5. **60-second nonce-free validity:** the live admission window is 20 seconds;
the working path uses 15 seconds.

Run the gate again with:

```bash
npm run spike
```
57 changes: 57 additions & 0 deletions 200ms-demo/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
# 200ms demo

A single-page React app that streams Vibenet USDV through real EIP-8130 native
account-abstraction transactions at approximately five transfers per second.
It uses a locally generated devnet key: no wallet connection, extension, or
signing prompt.

Live preview: <https://youssefea.github.io/demos/200ms/>

The workflow committed to `base/demos` validates this directory but does not
deploy to the Base organization GitHub Pages site.

## Run

```bash
npm install
npm run dev
```

Open the printed local Vite URL. A fresh browser profile takes roughly 12–20
seconds to receive both faucet drips because Vibenet enforces a shared ten-second
IP cooldown.

## Verify the live transaction path

```bash
npm run spike
```

The spike creates a disposable high-rate account, funds it, deploys it, and
sends 50 real USDV transfers. See [PHASE1.md](./PHASE1.md) for the passing
September 10, 2026 measurements and the designs rejected during testing.

The five-minute funding/throughput soak is available as `npm run soak`.

## Architecture

- `src/chain/bootstrap.ts` — health, live contracts, persisted account,
cooldown-aware funding, deployment proof, and one-time gas calibration.
- `src/chain/streamer.ts` — exact rational accumulator, 200ms scheduler,
nonce-free signing, pending backpressure, receipt watcher, rebroadcast,
funding daemon, and reset detection.
- `src/hooks/useStream.ts` — requestAnimationFrame sampling over the mutable
streamer snapshot.
- `src/ui/` — counter, real balance cards, rate selector, and explorer-linked
transaction ticker.

## Important limitations

- **Devnet only.** The private signing key is stored in localStorage. Do not
point this storage model at production assets.
- **USDV, not USDC.** USDV is Vibenet's faucet-backed six-decimal test USD token.
- The high-rate account implementation restricts outbound ETH execution. The
app only calls the USDV token and uses ETH for transaction fees.
- There is no mock fallback. If Vibenet is down, the app says so.
- Browsers call Vibenet directly. Visitors behind the same NAT or corporate
egress can still contend for the faucet's IP cooldown.
14 changes: 14 additions & 0 deletions 200ms-demo/index.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
<!doctype html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<meta name="theme-color" content="#ffffff" />
<meta name="description" content="The 200ms demo streams USDV through real EIP-8130 transfers at block cadence." />
<title>200ms demo</title>
</head>
<body>
<div id="root"></div>
<script type="module" src="/src/main.tsx"></script>
</body>
</html>
Loading
Loading