Skip to content
Draft
1 change: 1 addition & 0 deletions src/lib/og-sections.ts
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@ export const ogSectionMap: Record<string, string> = {

/** Second path segment → subsection label (only applied to 3+ segment routes). */
export const ogSubsectionMap: Record<string, string> = {
accounts: 'ACCOUNTS',
blockspace: 'BLOCKSPACE',
exchange: 'DEX',
fees: 'FEES',
Expand Down
2 changes: 1 addition & 1 deletion src/marketing/app/_components/CodePanel.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -248,7 +248,7 @@ export default function CodePanel({
if (inline) {
return (
<div
className={`code-scroll min-h-0 flex-1 overflow-auto bg-surface-block p-4 ${
className={`code-scroll min-h-0 w-full min-w-0 flex-1 overflow-auto bg-surface-block p-4 ${
bare ? '' : 'border border-line'
}`}
>
Expand Down
6 changes: 3 additions & 3 deletions src/marketing/app/_components/CodeWindow.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,7 @@ export default function CodeWindow({

return (
<div
className={`flex min-h-0 ${heightClassName} flex-col overflow-hidden rounded-lg border border-line bg-surface-block shadow-2xl`}
className={`flex min-h-0 w-full min-w-0 ${heightClassName} flex-col overflow-hidden rounded-lg border border-line bg-surface-block shadow-2xl`}
>
<div className="relative flex items-center gap-2 border-line border-b bg-surface-panel px-4 py-3">
<span aria-hidden className="size-3 shrink-0 rounded-full bg-[#FF5F57]" />
Expand Down Expand Up @@ -71,13 +71,13 @@ export default function CodeWindow({
))}
</div>
) : null}
<div className="grid min-h-0 flex-1">
<div className="grid min-h-0 min-w-0 flex-1">
{panels.map((panel, index) => (
<div
key={panel.lang}
inert={active !== panel}
aria-hidden={active !== panel}
className={`flex min-h-0 bg-surface-block [grid-area:1/1] ${
className={`flex min-h-0 min-w-0 bg-surface-block [grid-area:1/1] ${
index === activePanelIndex ? '' : 'invisible'
}`}
>
Expand Down
1 change: 1 addition & 0 deletions src/marketing/app/_components/Footer.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,7 @@ const columns: FooterColumn[] = [
{
header: 'Protocol',
links: [
{ label: 'Accounts', href: featurePath('accounts') },
{ label: 'Transactions', href: featurePath('transactions') },
{ label: 'TIP-20 tokens', href: featurePath('tokens') },
],
Expand Down
9 changes: 8 additions & 1 deletion src/marketing/app/_components/Header.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ import {
ExplorerIcon,
FaucetIcon,
McpIcon,
PoliciesIcon,
TerminalIcon,
TokensIcon,
TransactionsIcon,
Expand All @@ -32,8 +33,14 @@ const protocolMenu: MegaMenuData = {
variant: 'vertical',
columns: [
{
title: 'Transactions',
title: 'Protocol',
items: [
{
label: 'Tempo Accounts',
desc: 'Account model for keys, permissions, and policies',
href: featurePath('accounts'),
icon: <PoliciesIcon />,
},
{
label: 'Tempo Transactions',
desc: 'Flexible transactions for batching, fee sponsorship, scheduling, and more',
Expand Down
98 changes: 96 additions & 2 deletions src/marketing/app/_components/features.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -30,11 +30,105 @@ export type Feature = {
}

const featurePrecedence: Record<string, number> = {
tokens: 0,
transactions: 1,
accounts: 0,
tokens: 1,
transactions: 2,
}

export const features: Feature[] = [
{
slug: 'accounts',
title: 'Tempo Accounts',
description: (
<>
Account infrastructure for <span className="text-foreground">passkeys</span>,{' '}
<span className="text-foreground">scoped keys</span>,{' '}
<span className="text-foreground">receive controls</span>, and{' '}
<span className="text-foreground">deposit attribution</span>.
</>
),
items: [
{
label: 'Root keys and passkeys',
desc: 'Use modern account signing without wrapping every account in a contract.',
code: [
'import { Account } from "viem/tempo";',
'',
'// A Tempo account can be controlled by root keys',
'// including passkey-backed signing schemes.',
'const account = Account.fromWebAuthnCredential({',
' id: credential.id,',
' publicKey: credential.publicKey,',
'});',
],
highlight: ['Account.fromWebAuthnCredential'],
},
{
label: 'Scoped access keys',
desc: 'Delegate limited signing to apps, agents, sessions, or devices.',
code: [
'import { Account, Actions, Expiry } from "viem/tempo";',
'',
'const accessKey = Account.fromP256(sessionKey, {',
' access: rootAccount,',
'});',
'',
'await Actions.accessKey.signAuthorization(client, {',
' accessKey,',
' expiry: Expiry.days(7),',
' spendingLimit: { token: usdc, amount: 100_000_000n },',
'});',
],
highlight: ['accessKey', 'Expiry.days(7)', 'spendingLimit'],
},
{
label: 'Virtual addresses',
desc: 'Attribute deposits per customer without creating new state accounts.',
code: [
'import { getVirtualAddress } from "viem/tempo";',
'',
'const depositAddress = getVirtualAddress({',
' master: treasuryAccount,',
' salt: customerId,',
'});',
'',
'// Incoming TIP-20 funds resolve to treasuryAccount',
'// while preserving customer-level attribution.',
],
highlight: ['getVirtualAddress', 'treasuryAccount', 'customerId'],
},
{
label: 'Receive policies',
desc: 'Control which tokens and senders can deliver funds to an account.',
code: [
'await client.receivePolicy.setPolicy({',
' account: merchant,',
' acceptedTokens: [usdc, usdt],',
' allowedSenders: [processor],',
' recovery: complianceOps,',
'});',
],
highlight: ['acceptedTokens', 'allowedSenders', 'recovery'],
},
],
readLabel: 'Read account docs',
readHref: '/docs/guide/accounts',
heroActions: [
{
label: 'Create and manage accounts',
href: '/docs/guide/accounts',
primary: true,
},
{
label: 'Use access keys',
href: '/docs/guide/accounts/use-access-keys',
},
{
label: 'Configure receive policies',
href: '/docs/guide/payments/configure-receive-policies',
},
],
},
{
slug: 'transactions',
title: 'Tempo Transactions',
Expand Down
47 changes: 25 additions & 22 deletions src/marketing/app/_components/transactionCodeVariants.ts
Original file line number Diff line number Diff line change
Expand Up @@ -352,33 +352,36 @@ export const accessKeyCodeVariants: CodeVariant[] = [
{
lang: 'Rust',
code: [
'use alloy::primitives::{Address, U256};',
'use tempo_alloy::contracts::precompiles::{',
' IAccountKeychain, TokenLimit, ACCOUNT_KEYCHAIN,',
'use alloy::primitives::U256;',
'use tempo_alloy::{',
' primitives::{SignatureType, transaction::TokenLimit},',
' provider::{',
' KeyRestrictions,',
' keychain::authorize_key,',
' },',
'};',
'',
'let keychain = IAccountKeychain::new(ACCOUNT_KEYCHAIN, provider.clone());',
'let expiry = now + 7 * 24 * 60 * 60;',
'',
'keychain',
' .authorizeKey(',
' access_key,',
' 1u8,',
' expiry,',
' true,',
' vec![TokenLimit {',
' token: alpha_usd,',
' amount: U256::from(500_000_000),',
' }],',
' )',
' .send()',
' .await?;',
'let restrictions = KeyRestrictions::default()',
' .with_expiry(now + 7 * 24 * 60 * 60)',
' .with_limits(vec![TokenLimit {',
' token: alpha_usd,',
' limit: U256::from(500_000_000),',
' period: 0,',
' }]);',
'',
'let authorize = authorize_key(',
' access_key,',
' SignatureType::P256,',
' restrictions,',
');',
'',
'// Include `authorize` in a root-key-signed Tempo Transaction.',
],
highlight: [
'IAccountKeychain::new(ACCOUNT_KEYCHAIN, provider.clone())',
'.authorizeKey(',
'let restrictions = KeyRestrictions::default()',
'TokenLimit {',
'amount: U256::from(500_000_000)',
'let authorize = authorize_key(',
'SignatureType::P256',
],
},
{
Expand Down
4 changes: 1 addition & 3 deletions src/marketing/app/_lib/developersPaths.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -21,8 +21,6 @@ describe('developersPath', () => {

expect(developersPath('/')).toBe('/developers')
expect(developersPath('/docs')).toBe('/developers/docs')
expect(developersPath('/build/tempo-transactions')).toBe(
'/developers/build/tempo-transactions',
)
expect(developersPath('/build/tempo-transactions')).toBe('/developers/build/tempo-transactions')
})
})
1 change: 1 addition & 0 deletions src/marketing/app/_lib/featurePaths.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import { developersPath } from './developersPaths'

const featurePaths: Record<string, string> = {
accounts: developersPath('/build/tempo-accounts'),
transactions: developersPath('/build/tempo-transactions'),
tokens: developersPath('/build/tip20-tokens'),
}
Expand Down
13 changes: 11 additions & 2 deletions src/marketing/app/features/[slug]/page.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ import { features } from '../../_components/features'
import Header from '../../_components/Header'
import HeroDots from '../../_components/HeroDots'
import Reveal from '../../_components/Reveal'
import AccountsSections from '../_components/AccountsSections'
import TokensSections from '../_components/TokensSections'
import TransactionsSections from '../_components/TransactionsSections'

Expand Down Expand Up @@ -42,7 +43,13 @@ export default function FeaturePage({ params }: { params: FeatureParams }) {
<Header />

<section className="relative isolate px-5 py-28 lg:py-36">
<HeroDots plus={feature.slug === 'transactions' || feature.slug === 'tokens'} />
<HeroDots
plus={
feature.slug === 'accounts' ||
feature.slug === 'transactions' ||
feature.slug === 'tokens'
}
/>
<Reveal className="flex flex-col items-center text-center">
<h1 className="text-balance font-sans text-[clamp(2.5rem,7vw,3.5rem)] text-foreground leading-[1.05] tracking-[-0.03em] antialiased">
{feature.title}
Expand Down Expand Up @@ -80,7 +87,9 @@ export default function FeaturePage({ params }: { params: FeatureParams }) {
{/* Every snippet expanded — no select-to-reveal on the dedicated page.
Rows run full-bleed so their borders meet the shell's side borders;
the content is inset to match the section intros. */}
{feature.slug === 'transactions' ? (
{feature.slug === 'accounts' ? (
<AccountsSections />
) : feature.slug === 'transactions' ? (
<TransactionsSections />
) : feature.slug === 'tokens' ? (
<TokensSections />
Expand Down
Loading
Loading