From 149c97aaf996d2814912dbb269f80b1ae55a983e Mon Sep 17 00:00:00 2001 From: Haardik H Date: Tue, 1 Sep 2026 10:56:12 -0400 Subject: [PATCH 1/5] feat(vibenet): group validity demos; updates llms.txt Co-authored-by: OpenCode --- app/components/AppShell.tsx | 9 +- app/navigation.test.ts | 5 + app/navigation.ts | 3 + app/sitemap.test.ts | 12 ++ app/sitemap.ts | 1 + app/vibenet/demos/catalogue.test.ts | 51 +++++- app/vibenet/demos/catalogue.ts | 68 +++++++- app/vibenet/demos/validity/ValidityDemo.tsx | 4 +- app/vibenet/demos/validity/layout.tsx | 6 +- .../demos/validity/limit-orders/layout.tsx | 12 ++ .../demos/validity/limit-orders/page.tsx | 5 + app/vibenet/demos/validity/metadata.test.ts | 11 ++ app/vibenet/demos/validity/page.tsx | 157 +++++++++++++++++- 13 files changed, 317 insertions(+), 27 deletions(-) create mode 100644 app/sitemap.test.ts create mode 100644 app/vibenet/demos/validity/limit-orders/layout.tsx create mode 100644 app/vibenet/demos/validity/limit-orders/page.tsx create mode 100644 app/vibenet/demos/validity/metadata.test.ts diff --git a/app/components/AppShell.tsx b/app/components/AppShell.tsx index 7da2cce..d7781b5 100644 --- a/app/components/AppShell.tsx +++ b/app/components/AppShell.tsx @@ -10,7 +10,7 @@ import { Toaster } from 'sonner'; import { getActiveParent, isChildActive, isTopNavActive, navActiveParent, navHighlightPath, NAV_ITEMS, NavIcon, titleForPath } from '../navigation'; import { BLUE, BORDER, DISABLED, INK, MUTED, SELECTED } from '../theme'; import { getChangeBySlug } from '../upgrades/data/changes'; -import { demoLabel } from '../vibenet/demos/catalogue'; +import { demoBreadcrumb } from '../vibenet/demos/catalogue'; import { getUpgradeById } from '../upgrades/data/upgrades'; import { trackNavClick } from '../analytics/events'; @@ -869,15 +869,16 @@ export function AppShell({ children }: PropsWithChildren) { let childLabel = title; let middle: { label: string; href: string } | undefined; const explorerDetailMatch = pathname.match(/^\/vibenet\/explorer\/(tx|block|address)\/(.+)$/); - const demoMatch = pathname.match(/^\/vibenet\/demos\/(.+)$/); + const demo = demoBreadcrumb(pathname); if (explorerDetailMatch) { middle = { label: 'Explorer', href: '/vibenet/explorer' }; const raw = explorerDetailMatch[2]; childLabel = raw.startsWith('0x') && raw.length > 12 ? `${raw.slice(0, 6)}…${raw.slice(-4)}` : raw; - } else if (demoMatch) { - childLabel = demoLabel(demoMatch[1].split('/')[0]); + } else if (demo) { + childLabel = demo.childLabel; + middle = demo.middle; } return ( { expect(titleForPath('/vibenet/faucet')).toBe('Faucet'); expect(titleForPath('/vibenet')).toBe('Overview'); }); + + it('uses catalogue labels for grouped and nested demos', () => { + expect(titleForPath('/vibenet/demos/validity')).toBe('Validity Transactions'); + expect(titleForPath('/vibenet/demos/validity/limit-orders')).toBe('Limit Orders'); + }); }); diff --git a/app/navigation.ts b/app/navigation.ts index 9730402..d294733 100644 --- a/app/navigation.ts +++ b/app/navigation.ts @@ -1,5 +1,6 @@ import { BENCHMARK_ENABLED } from './benchmark/flag'; import { EXPLORER_ENABLED, EXPLORER_LABEL } from './internal-explorer/flag'; +import { demoBreadcrumb } from './vibenet/demos/catalogue'; export type NavIcon = 'home' | 'snapshots' | 'upgrades' | 'changelog' | 'vibenet' | 'overview' | 'demos' | 'faucet' | 'explorer' | 'internal-explorer' | 'benchmark' | 'runs' | 'loadtest'; @@ -66,6 +67,8 @@ export function pathMatches(href: string, pathname: string, exact = false): bool export function titleForPath(pathname: string): string { if (pathname === '/') return 'Home'; + const demo = demoBreadcrumb(pathname); + if (demo) return demo.childLabel; for (const item of NAV_ITEMS) { if (item.children) { for (const child of item.children) { diff --git a/app/sitemap.test.ts b/app/sitemap.test.ts new file mode 100644 index 0000000..18a49f7 --- /dev/null +++ b/app/sitemap.test.ts @@ -0,0 +1,12 @@ +import { describe, expect, it } from 'vitest'; + +import sitemap from './sitemap'; + +describe('sitemap', () => { + it('indexes the Validity Transactions group and its Limit Orders demo', () => { + const urls = sitemap().map((entry) => entry.url); + + expect(urls).toContain('https://chain.base.org/vibenet/demos/validity'); + expect(urls).toContain('https://chain.base.org/vibenet/demos/validity/limit-orders'); + }); +}); diff --git a/app/sitemap.ts b/app/sitemap.ts index a87908a..00078de 100644 --- a/app/sitemap.ts +++ b/app/sitemap.ts @@ -26,6 +26,7 @@ export default function sitemap(): MetadataRoute.Sitemap { { path: '/vibenet/demos/account', priority: 0.5, changeFrequency: 'weekly' }, { path: '/vibenet/demos/b20', priority: 0.5, changeFrequency: 'weekly' }, { path: '/vibenet/demos/validity', priority: 0.5, changeFrequency: 'weekly' }, + { path: '/vibenet/demos/validity/limit-orders', priority: 0.5, changeFrequency: 'weekly' }, ]; return routes.map(({ path, priority, changeFrequency }) => ({ diff --git a/app/vibenet/demos/catalogue.test.ts b/app/vibenet/demos/catalogue.test.ts index 34ed354..fa26555 100644 --- a/app/vibenet/demos/catalogue.test.ts +++ b/app/vibenet/demos/catalogue.test.ts @@ -1,10 +1,10 @@ import { describe, expect, it } from 'vitest'; -import { DEMOS, demoLabel, listedDemos } from './catalogue'; +import { DEMOS, demoBreadcrumb, demoForPath, demoLabel, listedDemos } from './catalogue'; describe('demoLabel', () => { - it('prefers shortTitle for the validity demo', () => { - expect(demoLabel('validity')).toBe('Validity'); + it('uses the group title for the validity demo', () => { + expect(demoLabel('validity')).toBe('Validity Transactions'); }); it('prefers shortTitle over title when both are set', () => { @@ -31,19 +31,54 @@ describe('demoLabel', () => { }); describe('DEMOS', () => { + const allDemos = DEMOS.flatMap((demo) => [demo, ...(demo.children ?? [])]); + it('gives every entry a /vibenet/demos/ href, so demoLabel can resolve it', () => { - for (const demo of DEMOS) { + for (const demo of allDemos) { expect(demo.href.startsWith('/vibenet/demos/')).toBe(true); } }); it('has no duplicate hrefs', () => { - const hrefs = DEMOS.map((d) => d.href); + const hrefs = allDemos.map((demo) => demo.href); expect(new Set(hrefs).size).toBe(hrefs.length); }); - it('keeps Validity off the Vibenet demos grid while the route still resolves', () => { - expect(listedDemos().some((demo) => demo.href === '/vibenet/demos/validity')).toBe(false); - expect(demoLabel('validity')).toBe('Validity'); + it('lists Validity Transactions as a top-level group', () => { + const validity = listedDemos().find((demo) => demo.href === '/vibenet/demos/validity'); + expect(validity?.title).toBe('Validity Transactions'); + expect(validity?.children?.map((demo) => demo.title)).toEqual(['Limit Orders']); + }); +}); + +describe('demoForPath', () => { + it('finds nested demos without flattening them onto the Vibenet grid', () => { + expect(demoForPath('/vibenet/demos/validity/limit-orders')?.title).toBe('Limit Orders'); + expect(listedDemos().some((demo) => demo.title === 'Limit Orders')).toBe(false); + }); +}); + +describe('demoBreadcrumb', () => { + it('resolves a top-level group breadcrumb', () => { + expect(demoBreadcrumb('/vibenet/demos/validity')).toEqual({ + childLabel: 'Validity Transactions', + }); + }); + + it('resolves a nested demo breadcrumb through its group', () => { + expect(demoBreadcrumb('/vibenet/demos/validity/limit-orders')).toEqual({ + middle: { + label: 'Validity Transactions', + href: '/vibenet/demos/validity', + }, + childLabel: 'Limit Orders', + }); + }); + + it('falls back to readable labels for unregistered nested routes', () => { + expect(demoBreadcrumb('/vibenet/demos/trading/stop-loss')).toEqual({ + middle: { label: 'Trading', href: '/vibenet/demos/trading' }, + childLabel: 'Stop Loss', + }); }); }); diff --git a/app/vibenet/demos/catalogue.ts b/app/vibenet/demos/catalogue.ts index 83e0052..0248efe 100644 --- a/app/vibenet/demos/catalogue.ts +++ b/app/vibenet/demos/catalogue.ts @@ -19,6 +19,8 @@ export type DemoEntry = { available: boolean; /** When false, the route stays live but is omitted from the Vibenet demos grid. */ listed?: boolean; + /** Nested demos shown from a group landing page. */ + children?: DemoEntry[]; }; /** Demos shown on the Vibenet index. Unlisted entries stay reachable by URL. */ @@ -55,17 +57,30 @@ export const DEMOS: DemoEntry[] = [ }, { href: '/vibenet/demos/validity', - title: 'Validity', - shortTitle: 'Validity', + title: 'Validity Transactions', + shortTitle: 'Validity Transactions', summary: - 'Attach conditions to a transaction so the sequencer includes it only while they hold. A simulated pool shows a swap waiting on price, then landing or expiring.', + 'Explore transactions that remain pending until their onchain conditions are satisfied, then execute without a keeper or a custom settlement contract.', points: [ - 'Add storage and block-number conditions to an ordinary swap', - 'A simulated AMM makes those conditions visible on a moving mid', - 'Stack several 8130 conditions at once, or replace the resting one', + 'Attach storage and block-number conditions to signed transactions', + 'Let the sequencer evaluate validity before inclusion', + 'Build intent-like flows from ordinary account transactions', ], available: true, - listed: false, + children: [ + { + href: '/vibenet/demos/validity/limit-orders', + title: 'Limit Orders', + summary: + 'Place a swap that waits for a target price, then lands or expires as a shared simulated market moves through its validity window.', + points: [ + 'Set a buy or sell price against a live VIBE/USDV pool', + 'Inspect the EIP-8130 predicates attached to the swap', + 'Watch pending orders fill, expire, or get replaced', + ], + available: true, + }, + ], }, ]; @@ -87,3 +102,42 @@ export function demoLabel(slug: string): string { const demo = DEMOS.find((entry) => entry.href === `/vibenet/demos/${slug}`); return demo?.shortTitle ?? demo?.title ?? prettifySlug(slug); } + +function entryLabel(entry: DemoEntry | undefined, fallbackSlug: string): string { + return entry?.shortTitle ?? entry?.title ?? prettifySlug(fallbackSlug); +} + +/** Finds a registered top-level or nested demo by its full route. */ +export function demoForPath(pathname: string): DemoEntry | undefined { + for (const demo of DEMOS) { + if (demo.href === pathname) return demo; + const child = demo.children?.find((entry) => entry.href === pathname); + if (child) return child; + } + return undefined; +} + +export type DemoBreadcrumb = { + childLabel: string; + middle?: { label: string; href: string }; +}; + +/** Resolves catalogue-backed labels for any route below `/vibenet/demos`. */ +export function demoBreadcrumb(pathname: string): DemoBreadcrumb | null { + const prefix = '/vibenet/demos/'; + if (!pathname.startsWith(prefix)) return null; + + const segments = pathname.slice(prefix.length).split('/').filter(Boolean); + if (segments.length === 0) return null; + + const parentHref = `${prefix}${segments[0]}`; + const parent = DEMOS.find((entry) => entry.href === parentHref); + const parentLabel = entryLabel(parent, segments[0]); + if (segments.length === 1) return { childLabel: parentLabel }; + + const child = parent?.children?.find((entry) => entry.href === pathname); + return { + middle: { label: parentLabel, href: parentHref }, + childLabel: entryLabel(child, segments.at(-1) ?? ''), + }; +} diff --git a/app/vibenet/demos/validity/ValidityDemo.tsx b/app/vibenet/demos/validity/ValidityDemo.tsx index 1769ded..9acbb5b 100644 --- a/app/vibenet/demos/validity/ValidityDemo.tsx +++ b/app/vibenet/demos/validity/ValidityDemo.tsx @@ -879,8 +879,8 @@ function ValidityDemoInner() {
diff --git a/app/vibenet/demos/validity/layout.tsx b/app/vibenet/demos/validity/layout.tsx index 3ad36c7..a09c99f 100644 --- a/app/vibenet/demos/validity/layout.tsx +++ b/app/vibenet/demos/validity/layout.tsx @@ -2,11 +2,11 @@ import type { Metadata } from 'next'; import type { ReactNode } from 'react'; export const metadata: Metadata = { - title: 'Validity · Vibenet', + title: 'Validity Transactions · Vibenet', description: - 'Attach conditions to a transaction. A simulated pool shows how a swap waits, lands, or expires.', + 'Explore Vibenet demos built with transactions that execute only while their onchain validity conditions hold.', }; -export default function ValidityDemoLayout({ children }: { children: ReactNode }) { +export default function ValidityTransactionsLayout({ children }: { children: ReactNode }) { return <>{children}; } diff --git a/app/vibenet/demos/validity/limit-orders/layout.tsx b/app/vibenet/demos/validity/limit-orders/layout.tsx new file mode 100644 index 0000000..5419de1 --- /dev/null +++ b/app/vibenet/demos/validity/limit-orders/layout.tsx @@ -0,0 +1,12 @@ +import type { Metadata } from 'next'; +import type { ReactNode } from 'react'; + +export const metadata: Metadata = { + title: 'Limit Orders · Validity Transactions', + description: + 'Place a validity-backed swap on Vibenet that waits for a target price, then fills or expires as the market moves.', +}; + +export default function LimitOrdersLayout({ children }: { children: ReactNode }) { + return <>{children}; +} diff --git a/app/vibenet/demos/validity/limit-orders/page.tsx b/app/vibenet/demos/validity/limit-orders/page.tsx new file mode 100644 index 0000000..df968cf --- /dev/null +++ b/app/vibenet/demos/validity/limit-orders/page.tsx @@ -0,0 +1,5 @@ +import { ValidityDemo } from '../ValidityDemo'; + +export default function LimitOrdersPage() { + return ; +} diff --git a/app/vibenet/demos/validity/metadata.test.ts b/app/vibenet/demos/validity/metadata.test.ts new file mode 100644 index 0000000..d32cf77 --- /dev/null +++ b/app/vibenet/demos/validity/metadata.test.ts @@ -0,0 +1,11 @@ +import { describe, expect, it } from 'vitest'; + +import { metadata as groupMetadata } from './layout'; +import { metadata as limitOrdersMetadata } from './limit-orders/layout'; + +describe('validity route metadata', () => { + it('names the group and nested demo independently', () => { + expect(groupMetadata.title).toBe('Validity Transactions · Vibenet'); + expect(limitOrdersMetadata.title).toBe('Limit Orders · Validity Transactions'); + }); +}); diff --git a/app/vibenet/demos/validity/page.tsx b/app/vibenet/demos/validity/page.tsx index 42a8089..7bdb45e 100644 --- a/app/vibenet/demos/validity/page.tsx +++ b/app/vibenet/demos/validity/page.tsx @@ -1,5 +1,156 @@ -import { ValidityDemo } from './ValidityDemo'; +import { Button } from '../../../components/ui/Button'; +import { Card, LinkCard } from '../../../components/ui/Card'; +import { AnimatedArrowIcon } from '../../../components/ui/icons'; +import { Text } from '../../../components/ui/Text'; +import { DemoHeader } from '../_components/DemoHeader'; +import { demoForPath } from '../catalogue'; -export default function ValidityDemoPage() { - return ; +const LIMIT_ORDERS_PATH = '/vibenet/demos/validity/limit-orders'; + +export default function ValidityTransactionsPage() { + const limitOrders = demoForPath(LIMIT_ORDERS_PATH); + if (!limitOrders) return null; + + return ( +
+ + +
+
+
+ Interactive demo + Start with a limit order +
+ 1 demo +
+ + +
+
+
+ {limitOrders.title} + + {limitOrders.summary} + +
    + {limitOrders.points.map((point) => ( +
  • +
  • + ))} +
+
+ Open Limit Orders + +
+
+ +
+
+ +
+ + + +
+ + +
+ See validity in motion + + Fund an account, place an order away from the market, and watch the transaction move from pending to filled or expired. + +
+ +
+
+ ); +} + +function TimelinePoint({ label, detail, active = false }: { label: string; detail: string; active?: boolean }) { + return ( +
+
+ ); +} + +function PrincipleCard({ index, title, description }: { index: string; title: string; description: string }) { + return ( + + {index} + {title} + {description} + + ); } From afa2581492b39d7d92ad3c9c2bb127e235977427 Mon Sep 17 00:00:00 2001 From: Haardik H Date: Tue, 1 Sep 2026 10:56:46 -0400 Subject: [PATCH 2/5] chore: regenerate validity agent docs Co-authored-by: OpenCode --- public/AGENTS.md | 5 +++-- public/llms-full.txt | 3 ++- public/llms.txt | 3 ++- 3 files changed, 7 insertions(+), 4 deletions(-) diff --git a/public/AGENTS.md b/public/AGENTS.md index f007d1b..3309577 100644 --- a/public/AGENTS.md +++ b/public/AGENTS.md @@ -27,7 +27,7 @@ Machine-readable entry point for agents working with Base Chain network state. | /upgrades/changelog | per release | re-fetch before stating an activation status | | /vibenet/faucet | monthly | stable within a session | | /api/snapshots | daily | re-fetch every session; never cache across sessions | -| /, /vibenet, /vibenet/demos/account, /vibenet/demos/b20, /vibenet/demos/validity | infrequent | stable within a session | +| /, /vibenet, /vibenet/demos/account, /vibenet/demos/b20, /vibenet/demos/validity, /vibenet/demos/validity/limit-orders | infrequent | stable within a session | ## Machine-readable endpoints @@ -88,7 +88,8 @@ Discovered from the Next.js app directory. - [/vibenet](https://chain.base.org/vibenet) — Explore Vibenet, the Base devnet for testing in-flight protocol features. - [/vibenet/demos/account](https://chain.base.org/vibenet/demos/account) — Create native account abstraction accounts from in-browser keys, fund them from the faucet, and inspect balances on Vibenet. - [/vibenet/demos/b20](https://chain.base.org/vibenet/demos/b20) — Explore, configure, and issue Base-native B20 tokens on Vibenet. -- [/vibenet/demos/validity](https://chain.base.org/vibenet/demos/validity) — Attach conditions to a transaction. A simulated pool shows how a swap waits, lands, or expires. +- [/vibenet/demos/validity](https://chain.base.org/vibenet/demos/validity) — Explore Vibenet demos built with transactions that execute only while their onchain validity conditions hold. +- [/vibenet/demos/validity/limit-orders](https://chain.base.org/vibenet/demos/validity/limit-orders) — Place a validity-backed swap on Vibenet that waits for a target price, then fills or expires as the market moves. - [/vibenet/explorer](https://chain.base.org/vibenet/explorer) — Browse blocks, transactions, and addresses on the Vibenet devnet. - [/vibenet/faucet](https://chain.base.org/vibenet/faucet) — Request testnet tokens on Vibenet to fund accounts and try in-flight Base features. diff --git a/public/llms-full.txt b/public/llms-full.txt index 2567977..268a45d 100644 --- a/public/llms-full.txt +++ b/public/llms-full.txt @@ -21,7 +21,8 @@ - [Vibenet · Base Chain](https://chain.base.org/vibenet): Explore Vibenet, the Base devnet for testing in-flight protocol features. - [Accounts · Vibenet](https://chain.base.org/vibenet/demos/account): Create native account abstraction accounts from in-browser keys, fund them from the faucet, and inspect balances on Vibenet. - [Tokens · Vibenet](https://chain.base.org/vibenet/demos/b20): Explore, configure, and issue Base-native B20 tokens on Vibenet. -- [Validity · Vibenet](https://chain.base.org/vibenet/demos/validity): Attach conditions to a transaction. A simulated pool shows how a swap waits, lands, or expires. +- [Validity Transactions · Vibenet](https://chain.base.org/vibenet/demos/validity): Explore Vibenet demos built with transactions that execute only while their onchain validity conditions hold. +- [Limit Orders · Validity Transactions](https://chain.base.org/vibenet/demos/validity/limit-orders): Place a validity-backed swap on Vibenet that waits for a target price, then fills or expires as the market moves. - [Explorer · Vibenet](https://chain.base.org/vibenet/explorer): Browse blocks, transactions, and addresses on the Vibenet devnet. (changes daily; re-fetch before relying on it) - [Faucet · Vibenet](https://chain.base.org/vibenet/faucet): Request testnet tokens on Vibenet to fund accounts and try in-flight Base features. (changes monthly; re-fetch before relying on it) diff --git a/public/llms.txt b/public/llms.txt index 80acc38..bbe65b7 100644 --- a/public/llms.txt +++ b/public/llms.txt @@ -19,7 +19,8 @@ Freshness: /snapshots and /vibenet/explorer change daily. /vibenet/faucet change - [Vibenet · Base Chain](https://chain.base.org/vibenet): Explore Vibenet, the Base devnet for testing in-flight protocol features. - [Accounts · Vibenet](https://chain.base.org/vibenet/demos/account): Create native account abstraction accounts from in-browser keys, fund them from the faucet, and inspect balances on Vibenet. - [Tokens · Vibenet](https://chain.base.org/vibenet/demos/b20): Explore, configure, and issue Base-native B20 tokens on Vibenet. -- [Validity · Vibenet](https://chain.base.org/vibenet/demos/validity): Attach conditions to a transaction. A simulated pool shows how a swap waits, lands, or expires. +- [Validity Transactions · Vibenet](https://chain.base.org/vibenet/demos/validity): Explore Vibenet demos built with transactions that execute only while their onchain validity conditions hold. +- [Limit Orders · Validity Transactions](https://chain.base.org/vibenet/demos/validity/limit-orders): Place a validity-backed swap on Vibenet that waits for a target price, then fills or expires as the market moves. - [Explorer · Vibenet](https://chain.base.org/vibenet/explorer): Browse blocks, transactions, and addresses on the Vibenet devnet. - [Faucet · Vibenet](https://chain.base.org/vibenet/faucet): Request testnet tokens on Vibenet to fund accounts and try in-flight Base features. From 412f96c85cf2a39694d1816a83416865b196c1c4 Mon Sep 17 00:00:00 2001 From: Haardik H Date: Tue, 1 Sep 2026 11:32:03 -0400 Subject: [PATCH 3/5] fix(vibenet): align validity landing with demo patterns Co-authored-by: OpenCode --- app/vibenet/demos/validity/page.tsx | 212 +++++++++------------------- 1 file changed, 69 insertions(+), 143 deletions(-) diff --git a/app/vibenet/demos/validity/page.tsx b/app/vibenet/demos/validity/page.tsx index 7bdb45e..35d50d4 100644 --- a/app/vibenet/demos/validity/page.tsx +++ b/app/vibenet/demos/validity/page.tsx @@ -1,156 +1,82 @@ import { Button } from '../../../components/ui/Button'; -import { Card, LinkCard } from '../../../components/ui/Card'; -import { AnimatedArrowIcon } from '../../../components/ui/icons'; import { Text } from '../../../components/ui/Text'; -import { DemoHeader } from '../_components/DemoHeader'; +import { FeatureCard } from '../../components/FeatureCard'; +import type { VibenetFeature } from '../../library/types'; +import { FeatureGridCard } from '../_shared/FeatureGridCard'; import { demoForPath } from '../catalogue'; -const LIMIT_ORDERS_PATH = '/vibenet/demos/validity/limit-orders'; +const VALIDITY_PATH = '/vibenet/demos/validity'; + +const VALIDITY_FEATURE: VibenetFeature = { + id: 'validity-transactions', + tag: 'EIP-8130', + title: 'Validity Transactions', + summary: + 'Submit transactions with onchain conditions, then let the sequencer include them only while those conditions are valid.', + status: 'live', + availability: 'Coming soon in ', + availabilityLabel: 'Base Cobalt', + availabilityHref: '/upgrades/upgrade/cobalt', + highlights: [ + { + title: 'State-Aware Inclusion', + detail: 'The sequencer evaluates current onchain state immediately before including a transaction.', + }, + { + title: 'Submit Before It Is Valid', + detail: 'Sign and submit intent now, then let it wait until its execution conditions are satisfied.', + }, + { + title: 'Storage Conditions', + detail: 'Require contract storage values to match ranges or expected values at inclusion time.', + }, + { + title: 'Block Bounds & Expiry', + detail: 'Constrain execution to explicit block windows so stale transactions expire safely.', + }, + { + title: 'Concurrent Intents', + detail: 'Nonce-isolated transactions can wait independently without blocking other account activity.', + }, + { + title: 'No Keeper Required', + detail: 'Build intent-like flows from ordinary account transactions without a separate settlement contract.', + }, + ], +}; export default function ValidityTransactionsPage() { - const limitOrders = demoForPath(LIMIT_ORDERS_PATH); - if (!limitOrders) return null; + const validity = demoForPath(VALIDITY_PATH); + if (!validity) return null; return ( -
- - -
-
-
- Interactive demo - Start with a limit order -
- 1 demo -
- - -
-
-
- {limitOrders.title} - - {limitOrders.summary} - -
    - {limitOrders.points.map((point) => ( -
  • -
  • - ))} -
-
- Open Limit Orders - -
-
- -
-
- -
- - - -
- - -
- See validity in motion - - Fund an account, place an order away from the market, and watch the transaction move from pending to filled or expired. - -
- -
+
+ {validity.children?.map((demo) => ( + + + + + + } + title={demo.title} + description={demo.summary} + > + + + ))} +
); } - -function TimelinePoint({ label, detail, active = false }: { label: string; detail: string; active?: boolean }) { - return ( -
-
- ); -} - -function PrincipleCard({ index, title, description }: { index: string; title: string; description: string }) { - return ( - - {index} - {title} - {description} - - ); -} From befbfc25bbddef612d00cc654e44b23b5d170b01 Mon Sep 17 00:00:00 2001 From: Haardik H Date: Wed, 2 Sep 2026 13:39:46 -0400 Subject: [PATCH 4/5] refactor(vibenet): rename demo to conditional swaps; updates llms.txt Co-authored-by: OpenCode --- app/navigation.test.ts | 2 +- app/sitemap.test.ts | 4 ++-- app/sitemap.ts | 2 +- app/vibenet/demos/catalogue.test.ts | 10 +++++----- app/vibenet/demos/catalogue.ts | 4 ++-- .../{limit-orders => conditional-swaps}/layout.tsx | 4 ++-- .../{limit-orders => conditional-swaps}/page.tsx | 2 +- app/vibenet/demos/validity/metadata.test.ts | 4 ++-- 8 files changed, 16 insertions(+), 16 deletions(-) rename app/vibenet/demos/validity/{limit-orders => conditional-swaps}/layout.tsx (66%) rename app/vibenet/demos/validity/{limit-orders => conditional-swaps}/page.tsx (61%) diff --git a/app/navigation.test.ts b/app/navigation.test.ts index 40de8f8..5419743 100644 --- a/app/navigation.test.ts +++ b/app/navigation.test.ts @@ -95,6 +95,6 @@ describe('titleForPath', () => { it('uses catalogue labels for grouped and nested demos', () => { expect(titleForPath('/vibenet/demos/validity')).toBe('Validity Transactions'); - expect(titleForPath('/vibenet/demos/validity/limit-orders')).toBe('Limit Orders'); + expect(titleForPath('/vibenet/demos/validity/conditional-swaps')).toBe('Conditional Swaps'); }); }); diff --git a/app/sitemap.test.ts b/app/sitemap.test.ts index 18a49f7..c500afc 100644 --- a/app/sitemap.test.ts +++ b/app/sitemap.test.ts @@ -3,10 +3,10 @@ import { describe, expect, it } from 'vitest'; import sitemap from './sitemap'; describe('sitemap', () => { - it('indexes the Validity Transactions group and its Limit Orders demo', () => { + it('indexes the Validity Transactions group and its Conditional Swaps demo', () => { const urls = sitemap().map((entry) => entry.url); expect(urls).toContain('https://chain.base.org/vibenet/demos/validity'); - expect(urls).toContain('https://chain.base.org/vibenet/demos/validity/limit-orders'); + expect(urls).toContain('https://chain.base.org/vibenet/demos/validity/conditional-swaps'); }); }); diff --git a/app/sitemap.ts b/app/sitemap.ts index 00078de..d70a940 100644 --- a/app/sitemap.ts +++ b/app/sitemap.ts @@ -26,7 +26,7 @@ export default function sitemap(): MetadataRoute.Sitemap { { path: '/vibenet/demos/account', priority: 0.5, changeFrequency: 'weekly' }, { path: '/vibenet/demos/b20', priority: 0.5, changeFrequency: 'weekly' }, { path: '/vibenet/demos/validity', priority: 0.5, changeFrequency: 'weekly' }, - { path: '/vibenet/demos/validity/limit-orders', priority: 0.5, changeFrequency: 'weekly' }, + { path: '/vibenet/demos/validity/conditional-swaps', priority: 0.5, changeFrequency: 'weekly' }, ]; return routes.map(({ path, priority, changeFrequency }) => ({ diff --git a/app/vibenet/demos/catalogue.test.ts b/app/vibenet/demos/catalogue.test.ts index fa26555..dd72425 100644 --- a/app/vibenet/demos/catalogue.test.ts +++ b/app/vibenet/demos/catalogue.test.ts @@ -47,14 +47,14 @@ describe('DEMOS', () => { it('lists Validity Transactions as a top-level group', () => { const validity = listedDemos().find((demo) => demo.href === '/vibenet/demos/validity'); expect(validity?.title).toBe('Validity Transactions'); - expect(validity?.children?.map((demo) => demo.title)).toEqual(['Limit Orders']); + expect(validity?.children?.map((demo) => demo.title)).toEqual(['Conditional Swaps']); }); }); describe('demoForPath', () => { it('finds nested demos without flattening them onto the Vibenet grid', () => { - expect(demoForPath('/vibenet/demos/validity/limit-orders')?.title).toBe('Limit Orders'); - expect(listedDemos().some((demo) => demo.title === 'Limit Orders')).toBe(false); + expect(demoForPath('/vibenet/demos/validity/conditional-swaps')?.title).toBe('Conditional Swaps'); + expect(listedDemos().some((demo) => demo.title === 'Conditional Swaps')).toBe(false); }); }); @@ -66,12 +66,12 @@ describe('demoBreadcrumb', () => { }); it('resolves a nested demo breadcrumb through its group', () => { - expect(demoBreadcrumb('/vibenet/demos/validity/limit-orders')).toEqual({ + expect(demoBreadcrumb('/vibenet/demos/validity/conditional-swaps')).toEqual({ middle: { label: 'Validity Transactions', href: '/vibenet/demos/validity', }, - childLabel: 'Limit Orders', + childLabel: 'Conditional Swaps', }); }); diff --git a/app/vibenet/demos/catalogue.ts b/app/vibenet/demos/catalogue.ts index 0248efe..f854d87 100644 --- a/app/vibenet/demos/catalogue.ts +++ b/app/vibenet/demos/catalogue.ts @@ -69,8 +69,8 @@ export const DEMOS: DemoEntry[] = [ available: true, children: [ { - href: '/vibenet/demos/validity/limit-orders', - title: 'Limit Orders', + href: '/vibenet/demos/validity/conditional-swaps', + title: 'Conditional Swaps', summary: 'Place a swap that waits for a target price, then lands or expires as a shared simulated market moves through its validity window.', points: [ diff --git a/app/vibenet/demos/validity/limit-orders/layout.tsx b/app/vibenet/demos/validity/conditional-swaps/layout.tsx similarity index 66% rename from app/vibenet/demos/validity/limit-orders/layout.tsx rename to app/vibenet/demos/validity/conditional-swaps/layout.tsx index 5419de1..98306f2 100644 --- a/app/vibenet/demos/validity/limit-orders/layout.tsx +++ b/app/vibenet/demos/validity/conditional-swaps/layout.tsx @@ -2,11 +2,11 @@ import type { Metadata } from 'next'; import type { ReactNode } from 'react'; export const metadata: Metadata = { - title: 'Limit Orders · Validity Transactions', + title: 'Conditional Swaps · Validity Transactions', description: 'Place a validity-backed swap on Vibenet that waits for a target price, then fills or expires as the market moves.', }; -export default function LimitOrdersLayout({ children }: { children: ReactNode }) { +export default function ConditionalSwapsLayout({ children }: { children: ReactNode }) { return <>{children}; } diff --git a/app/vibenet/demos/validity/limit-orders/page.tsx b/app/vibenet/demos/validity/conditional-swaps/page.tsx similarity index 61% rename from app/vibenet/demos/validity/limit-orders/page.tsx rename to app/vibenet/demos/validity/conditional-swaps/page.tsx index df968cf..8a98f18 100644 --- a/app/vibenet/demos/validity/limit-orders/page.tsx +++ b/app/vibenet/demos/validity/conditional-swaps/page.tsx @@ -1,5 +1,5 @@ import { ValidityDemo } from '../ValidityDemo'; -export default function LimitOrdersPage() { +export default function ConditionalSwapsPage() { return ; } diff --git a/app/vibenet/demos/validity/metadata.test.ts b/app/vibenet/demos/validity/metadata.test.ts index d32cf77..bbebcc2 100644 --- a/app/vibenet/demos/validity/metadata.test.ts +++ b/app/vibenet/demos/validity/metadata.test.ts @@ -1,11 +1,11 @@ import { describe, expect, it } from 'vitest'; import { metadata as groupMetadata } from './layout'; -import { metadata as limitOrdersMetadata } from './limit-orders/layout'; +import { metadata as conditionalSwapsMetadata } from './conditional-swaps/layout'; describe('validity route metadata', () => { it('names the group and nested demo independently', () => { expect(groupMetadata.title).toBe('Validity Transactions · Vibenet'); - expect(limitOrdersMetadata.title).toBe('Limit Orders · Validity Transactions'); + expect(conditionalSwapsMetadata.title).toBe('Conditional Swaps · Validity Transactions'); }); }); From da305c1420636e387c9dd554452c829c7fdcc1b7 Mon Sep 17 00:00:00 2001 From: Haardik H Date: Wed, 2 Sep 2026 13:40:12 -0400 Subject: [PATCH 5/5] chore: regenerate conditional swaps agent docs Co-authored-by: OpenCode --- public/AGENTS.md | 4 ++-- public/llms-full.txt | 2 +- public/llms.txt | 2 +- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/public/AGENTS.md b/public/AGENTS.md index 3309577..b86c490 100644 --- a/public/AGENTS.md +++ b/public/AGENTS.md @@ -27,7 +27,7 @@ Machine-readable entry point for agents working with Base Chain network state. | /upgrades/changelog | per release | re-fetch before stating an activation status | | /vibenet/faucet | monthly | stable within a session | | /api/snapshots | daily | re-fetch every session; never cache across sessions | -| /, /vibenet, /vibenet/demos/account, /vibenet/demos/b20, /vibenet/demos/validity, /vibenet/demos/validity/limit-orders | infrequent | stable within a session | +| /, /vibenet, /vibenet/demos/account, /vibenet/demos/b20, /vibenet/demos/validity, /vibenet/demos/validity/conditional-swaps | infrequent | stable within a session | ## Machine-readable endpoints @@ -89,7 +89,7 @@ Discovered from the Next.js app directory. - [/vibenet/demos/account](https://chain.base.org/vibenet/demos/account) — Create native account abstraction accounts from in-browser keys, fund them from the faucet, and inspect balances on Vibenet. - [/vibenet/demos/b20](https://chain.base.org/vibenet/demos/b20) — Explore, configure, and issue Base-native B20 tokens on Vibenet. - [/vibenet/demos/validity](https://chain.base.org/vibenet/demos/validity) — Explore Vibenet demos built with transactions that execute only while their onchain validity conditions hold. -- [/vibenet/demos/validity/limit-orders](https://chain.base.org/vibenet/demos/validity/limit-orders) — Place a validity-backed swap on Vibenet that waits for a target price, then fills or expires as the market moves. +- [/vibenet/demos/validity/conditional-swaps](https://chain.base.org/vibenet/demos/validity/conditional-swaps) — Place a validity-backed swap on Vibenet that waits for a target price, then fills or expires as the market moves. - [/vibenet/explorer](https://chain.base.org/vibenet/explorer) — Browse blocks, transactions, and addresses on the Vibenet devnet. - [/vibenet/faucet](https://chain.base.org/vibenet/faucet) — Request testnet tokens on Vibenet to fund accounts and try in-flight Base features. diff --git a/public/llms-full.txt b/public/llms-full.txt index 268a45d..84e1cda 100644 --- a/public/llms-full.txt +++ b/public/llms-full.txt @@ -22,7 +22,7 @@ - [Accounts · Vibenet](https://chain.base.org/vibenet/demos/account): Create native account abstraction accounts from in-browser keys, fund them from the faucet, and inspect balances on Vibenet. - [Tokens · Vibenet](https://chain.base.org/vibenet/demos/b20): Explore, configure, and issue Base-native B20 tokens on Vibenet. - [Validity Transactions · Vibenet](https://chain.base.org/vibenet/demos/validity): Explore Vibenet demos built with transactions that execute only while their onchain validity conditions hold. -- [Limit Orders · Validity Transactions](https://chain.base.org/vibenet/demos/validity/limit-orders): Place a validity-backed swap on Vibenet that waits for a target price, then fills or expires as the market moves. +- [Conditional Swaps · Validity Transactions](https://chain.base.org/vibenet/demos/validity/conditional-swaps): Place a validity-backed swap on Vibenet that waits for a target price, then fills or expires as the market moves. - [Explorer · Vibenet](https://chain.base.org/vibenet/explorer): Browse blocks, transactions, and addresses on the Vibenet devnet. (changes daily; re-fetch before relying on it) - [Faucet · Vibenet](https://chain.base.org/vibenet/faucet): Request testnet tokens on Vibenet to fund accounts and try in-flight Base features. (changes monthly; re-fetch before relying on it) diff --git a/public/llms.txt b/public/llms.txt index bbe65b7..1d93dc4 100644 --- a/public/llms.txt +++ b/public/llms.txt @@ -20,7 +20,7 @@ Freshness: /snapshots and /vibenet/explorer change daily. /vibenet/faucet change - [Accounts · Vibenet](https://chain.base.org/vibenet/demos/account): Create native account abstraction accounts from in-browser keys, fund them from the faucet, and inspect balances on Vibenet. - [Tokens · Vibenet](https://chain.base.org/vibenet/demos/b20): Explore, configure, and issue Base-native B20 tokens on Vibenet. - [Validity Transactions · Vibenet](https://chain.base.org/vibenet/demos/validity): Explore Vibenet demos built with transactions that execute only while their onchain validity conditions hold. -- [Limit Orders · Validity Transactions](https://chain.base.org/vibenet/demos/validity/limit-orders): Place a validity-backed swap on Vibenet that waits for a target price, then fills or expires as the market moves. +- [Conditional Swaps · Validity Transactions](https://chain.base.org/vibenet/demos/validity/conditional-swaps): Place a validity-backed swap on Vibenet that waits for a target price, then fills or expires as the market moves. - [Explorer · Vibenet](https://chain.base.org/vibenet/explorer): Browse blocks, transactions, and addresses on the Vibenet devnet. - [Faucet · Vibenet](https://chain.base.org/vibenet/faucet): Request testnet tokens on Vibenet to fund accounts and try in-flight Base features.