Files
zeekay cb6db9e659 design: every page and component outside the landing and beta paths is at zero lint
Inline style objects became gui props (Box for a div, View or Text rendering the
element for the rest, since Box styles only a div), raw colours and sizes became
the design's tokens, the brand swatches read @hanzo/design's own values, and the
project and creation hues moved to palette.json, which is data. The newsletter's
subscribe button is the standard filled Action. connect-steps.tsx, which nothing
imports, is deleted with the brand constants nobody read.

Pages compared before and after at 1440x900 and 390x844: blockchain, brand,
directory, projects, settings, unsubscribe identical; founder 0.03% of pixels;
buying specialist's title snaps from 28 to the ramp's 26px and the newsletter's
button is now filled.

Claude-Session: https://claude.ai/code/session_017vrVus6PPBgP5YRzKV1iqW
2026-10-26 03:49:42 -07:00

601 lines
27 KiB
TypeScript

'use client'
/**
* /blockchain — one key, every chain, and the tools an agent calls with it.
*
* The six section frames are `components/marketing/band`'s `Band` and `Head`;
* the type and the controls are `@hanzo/ui/marketing`; the inks, the
* tile, the mark disc and a card's two lines are `components/blockchain/surface`,
* where the pages under this route agree on them; the rest is gui props.
*
* A product card offers its "Get started" line only on approach (and on
* keyboard focus); nothing else about the card changes, because its two
* grounds were one colour in both themes. A capability head is a disclosure
* whose ground answers a pointer and adds no geometry.
*/
import React, { useState, type ReactNode } from "react";
import Link from "next/link";
import { motion } from "@/components/motion";
import {
Blocks,
Wallet,
CreditCard,
FileCode,
HardDrive,
Radio,
Search,
ArrowLeftRight,
Shield,
ArrowRight,
Check,
Database,
Globe,
Zap,
Lock,
Server,
Code,
ChevronDown,
ChevronUp
} from "lucide-react";
import { phrase } from "@hanzo/i18n";
import { useI18n } from "@hanzo/i18n/react";
import { Box, Pulse, Text, XStack, YStack } from '@hanzo/ui'
import { Grid } from '@hanzo/ui/grid'
import { Band, Head } from '@/components/marketing/band'
import { Card, CardBody, CardTitle, DIM, GROUND, INK, SOFT, Tile, ink, white } from '@/components/blockchain/surface'
import { Action, Chip, Display, Lede, Title } from '@hanzo/ui/marketing'
// Web3 capability categories
const CAPABILITIES = [
{
id: "nodes",
icon: Server,
title: phrase("Blockchain Nodes & Data"),
description: phrase("Read a chain without running a node for it"),
features: [
phrase("Multi-chain RPC endpoints (EVM, Solana, Cosmos, etc.)"),
phrase("Archive nodes for historical data access"),
phrase("WebSocket subscriptions for real-time events"),
phrase("Rate limiting and load balancing built-in"),
phrase("High availability with global distribution"),
],
},
{
id: "wallet",
icon: Wallet,
title: phrase("Wallet & Key Management"),
description: phrase("Where the keys live, and what has to happen before one signs"),
features: [
phrase("MPC (Multi-Party Computation) wallets"),
phrase("Hardware Security Module (HSM) integration"),
phrase("Policy-based transaction signing"),
phrase("Multi-sig support across chains"),
phrase("Custodial and non-custodial options"),
],
},
{
id: "payments",
icon: CreditCard,
title: phrase("On-Chain Payments"),
description: phrase("Take a stablecoin the way you would take a card"),
features: [
phrase("Stablecoin payment processing (USDC, USDT, DAI)"),
phrase("Native token support across chains"),
phrase("Payment links and checkout widgets"),
phrase("Automatic conversion and settlement"),
phrase("Invoice generation and tracking"),
],
},
{
id: "contracts",
icon: FileCode,
title: phrase("Smart Contract Management"),
description: phrase("Ship a contract to several chains and keep track of what you shipped"),
features: [
phrase("Contract deployment across multiple chains"),
phrase("ABI management and verification"),
phrase("Gas estimation and optimization"),
phrase("Event indexing and webhooks"),
phrase("Upgradeable proxy pattern support"),
],
},
{
id: "storage",
icon: HardDrive,
title: phrase("Decentralized Storage"),
description: phrase("Persistent, censorship-resistant data storage"),
features: [
phrase("IPFS pinning with global CDN"),
phrase("Arweave permanent storage integration"),
phrase("Filecoin deal management"),
phrase("NFT metadata hosting"),
phrase("Content-addressed file retrieval"),
],
},
{
id: "oracles",
icon: Radio,
title: phrase("Oracle Services"),
description: phrase("Bring off-chain data on-chain"),
features: [
phrase("Price feeds for DeFi applications"),
phrase("Custom data feeds and attestations"),
phrase("VRF (Verifiable Random Function)"),
phrase("Cross-chain message passing"),
phrase("Chainlink and custom oracle integration"),
],
},
{
id: "indexing",
icon: Search,
title: phrase("Blockchain Indexing"),
description: phrase("Ask a question a chain cannot answer in one call"),
features: [
phrase("Custom subgraph deployment"),
phrase("Real-time indexing and caching"),
phrase("Historical data aggregation"),
phrase("Cross-chain data unification"),
phrase("SQL and GraphQL query interfaces"),
],
},
{
id: "crosschain",
icon: ArrowLeftRight,
title: phrase("Cross-Chain Infrastructure"),
description: phrase("Bridge assets and data between chains"),
features: [
phrase("Token bridging with Wormhole, LayerZero"),
phrase("Cross-chain messaging protocols"),
phrase("Unified liquidity across chains"),
phrase("Chain abstraction for users"),
phrase("Multi-chain transaction batching"),
],
},
{
id: "compliance",
icon: Shield,
title: phrase("Compliance & Fiat"),
description: phrase("Enterprise compliance and fiat rails"),
features: [
phrase("KYC/AML integration"),
phrase("Transaction monitoring and screening"),
phrase("Fiat on/off ramp connections"),
phrase("Tax reporting and documentation"),
phrase("Regulatory-compliant custody"),
],
},
];
// Product pages - Core APIs
const PRODUCTS = [
// Core Infrastructure
{ id: "chains", name: phrase("Hanzo Chains"), description: phrase("Multi-chain RPC endpoints & infrastructure"), icon: Server, href: "/blockchain/chains" },
{ id: "directory", name: phrase("Chain Directory"), description: phrase("RPC endpoints, chain IDs and explorers for every network"), icon: Search, href: "/blockchain/directory" },
{ id: "indexer", name: phrase("Indexer"), description: phrase("Query blockchain data with GraphQL"), icon: Search, href: "/blockchain/indexer" },
{ id: "wallets", name: phrase("Smart Wallets"), description: phrase("ERC-4337 account abstraction wallets"), icon: Wallet, href: "/blockchain/wallets" },
{ id: "rollups", name: phrase("Rollups"), description: phrase("L2 scaling & rollup infrastructure"), icon: Blocks, href: "/blockchain/rollups" },
// Data APIs
{ id: "tokens", name: phrase("Token API"), description: phrase("ERC-20 balances, prices & metadata"), icon: Database, href: "/blockchain/tokens" },
{ id: "nft", name: phrase("NFT API"), description: phrase("NFT metadata, ownership & transfers"), icon: Blocks, href: "/blockchain/nft" },
{ id: "transfers", name: phrase("Transfers API"), description: phrase("Track token & NFT transfers"), icon: ArrowLeftRight, href: "/blockchain/transfers" },
// Trading & DeFi APIs
{ id: "prices", name: phrase("Prices API"), description: phrase("Real-time & historical price feeds"), icon: Database, href: "/blockchain/tokens" },
{ id: "dex", name: phrase("DEX API"), description: phrase("Swap routing & liquidity aggregation"), icon: ArrowLeftRight, href: "/blockchain/exchange" },
{ id: "oracle", name: phrase("Oracle API"), description: phrase("On-chain price oracles & data feeds"), icon: Radio, href: "/blockchain/oracle" },
// Realtime & Events
{ id: "webhooks", name: phrase("Webhooks"), description: phrase("Real-time blockchain event notifications"), icon: Radio, href: "/blockchain/webhooks" },
{ id: "websockets", name: phrase("Websockets"), description: phrase("Live blockchain data streaming"), icon: Radio, href: "/blockchain/websockets" },
// Account Abstraction
{ id: "bundler", name: phrase("Bundler API"), description: phrase("ERC-4337 UserOp bundling service"), icon: Blocks, href: "/blockchain/bundler" },
{ id: "gas", name: phrase("Gas Manager"), description: phrase("Sponsor gas for your users"), icon: Zap, href: "/blockchain/gas" },
{ id: "simulation", name: phrase("Simulation API"), description: phrase("UserOp & transaction simulation"), icon: Code, href: "/blockchain/bundler" },
// Debug & Development
{ id: "debug", name: phrase("Debug API"), description: phrase("Transaction tracing & debugging"), icon: Code, href: "/blockchain/explorer" },
{ id: "trace", name: phrase("Trace API"), description: phrase("Internal transaction traces"), icon: Search, href: "/blockchain/explorer" },
// Payments
{ id: "pay", name: phrase("Payments"), description: phrase("Crypto payments gateway"), icon: CreditCard, href: "/blockchain/pay" },
];
/** The two calls to action every block of this page closes on. */
function Actions() {
const { t } = useI18n();
return (
<>
<Action render="button" type="button" onClick={() => window.location.assign('/login')} fill>
{t('Try Hanzo')}
<ArrowRight width={16} height={16} data-i18n-mirror />
</Action>
<Action render="button" type="button" onClick={() => (window.location.href = '/pricing?tab=blockchain')}>{t('View Pricing')}</Action>
</>
)
}
/** A word in an outline on a tinted ground: the badges over the hero and the agent section. */
function Badge({ edge, ground, children }: { edge: string; ground: string; children: ReactNode }) {
return (
<Chip px={16} py={8} borderColor={edge} bg={ground}>
{children}
</Chip>
)
}
/** The diagonal white wash a framed block sits on. */
const WASH = { background: `linear-gradient(to bottom right in oklab, ${white(20)}, transparent)` } as const
const Blockchain = ({ agent }: { agent: ReactNode }) => {
const [expandedCapability, setExpandedCapability] = useState<string | null>(null);
const { t } = useI18n();
return (
<Box minH="100vh" $platform-web={{ color: 'var(--foreground)' }}>
{/* Hero Section */}
<Box render="section" position="relative" overflow="hidden" pt={96} pb={64} px={16} $md={{ px: 32 }}>
<Box position="relative" z="var(--z-raised)" width="100%" maxW={1152} mx="auto">
<motion.div initial={{ opacity: 0, y: 20 }} animate={{ opacity: 1, y: 0 }} transition={{ duration: 0.5 }}>
<Box mb={64} $platform-web={{ textAlign: 'center' }}>
{/* Live Badge */}
<Box mb={24}>
<Badge edge="var(--border)" ground={white(5)}>
<Pulse render="span" width={8} height={8} rounded={9999} $platform-web={{ backgroundColor: white(10) }} />
<Text fontSize="$2" lineHeight="1.1607rem" fontWeight="500" $platform-web={{ color: ink(70) }}>
{t('Now Available')}
</Text>
</Badge>
</Box>
<Display mb={24}>
{t('One API key, every chain.')}
<br />
{t('And an agent that can use it.')}
</Display>
<Lede mb={32} width="100%" maxW={672} mx="auto">
{t('RPC endpoints, token and NFT data, smart wallets, and webhooks — reached the same way whichever chain you are on. Reading a balance on Ethereum and reading one on Solana are the same call with a different argument, so the chain becomes a parameter instead of a rewrite. The same calls are exposed as tools, so an agent can make them too.')}
</Lede>
{/* CTA Buttons */}
<motion.div initial={{ opacity: 0, y: 20 }} animate={{ opacity: 1, y: 0 }} transition={{ duration: 0.5, delay: 0.1 }}>
<XStack flexWrap="wrap" gap={16} justify="center">
<Actions />
</XStack>
</motion.div>
<Text render="p" display="block" mt={16} fontSize="$1" lineHeight="0.9167rem" color={DIM}>
{t('Start on the free tier. No credit card required.')}
</Text>
</Box>
</motion.div>
{/* Visual Hero Element */}
<motion.div initial={{ opacity: 0, y: 40 }} animate={{ opacity: 1, y: 0 }} transition={{ duration: 0.6, delay: 0.2 }}>
<Box rounded="var(--radius-2xl)" borderWidth={1} borderColor="var(--border)" p={32} $md={{ p: 48 }} $platform-web={WASH}>
<Grid columns={{ min: 96, max: 6 }} gap={24}>
{[
{ icon: Server, label: phrase("Nodes") },
{ icon: Wallet, label: phrase("Wallets") },
{ icon: CreditCard, label: phrase("Payments") },
{ icon: FileCode, label: phrase("Contracts") },
{ icon: Database, label: phrase("Storage") },
{ icon: ArrowLeftRight, label: phrase("Bridges") },
].map((item, idx) => {
const Icon = item.icon;
return (
<motion.div
key={item.label}
initial={{ opacity: 0, scale: 0.8 }}
animate={{ opacity: 1, scale: 1 }}
transition={{ duration: 0.4, delay: 0.3 + idx * 0.05 }}
>
<YStack items="center" gap={8}>
{/* Half the tile at both sizes — 24 of 48, 32 of 64 —
so the mark steps with its box. */}
<Tile size={48} $md={{ width: 64, height: 64 }} rounded="var(--radius-xl)" borderWidth={1} $platform-web={{ borderColor: white(30) }}>
<Icon color={INK} width="50%" height="50%" />
</Tile>
<Text fontSize="$1" lineHeight="0.9167rem" color={DIM}>
{t(item.label)}
</Text>
</YStack>
</motion.div>
);
})}
</Grid>
</Box>
</motion.div>
</Box>
</Box>
{/* Performance Metrics */}
<Band pad="$10" measure={1152}>
<motion.div initial={{ opacity: 0, y: 20 }} whileInView={{ opacity: 1, y: 0 }} viewport={{ once: true }}>
<Grid columns={{ min: 150, max: 4 }} gap={32}>
{[
{ value: phrase("One key"), label: phrase("Every chain"), detail: phrase("The chain is an argument") },
{ value: phrase("Archive"), label: phrase("Full history"), detail: phrase("Not just recent state") },
{ value: phrase("Push"), label: phrase("Webhooks and sockets"), detail: phrase("Instead of polling") },
{ value: phrase("Tools"), label: phrase("Agent-callable"), detail: phrase("The same calls you make") },
].map((stat, idx) => (
<motion.div
key={stat.label}
initial={{ opacity: 0, y: 20 }}
whileInView={{ opacity: 1, y: 0 }}
viewport={{ once: true }}
transition={{ duration: 0.4, delay: idx * 0.1 }}
>
<Box $platform-web={{ textAlign: 'center' }}>
<Text display="block" mb={4} fontSize="$8" lineHeight="1.95rem" fontWeight="700" color={INK}>
{t(stat.value)}
</Text>
<Text display="block" fontSize="$2" lineHeight="1.1607rem" fontWeight="500" color={INK}>
{t(stat.label)}
</Text>
<Text display="block" mt={4} fontSize="$1" lineHeight="0.9167rem" color={DIM}>
{t(stat.detail)}
</Text>
</Box>
</motion.div>
))}
</Grid>
</motion.div>
</Band>
{/* Products Section */}
<Band rule={false} pad="$12" measure={1152} ground="var(--background)">
<Head
title={t('The pieces')}
lede={t('Each one answers a question you would otherwise run a node to answer. They share a key, an address scheme, and a chain argument, so reaching for a second one costs you a line.')}
/>
<Grid columns={{ min: 260, max: 4 }} gap={16}>
{PRODUCTS.map((product, index) => {
const Icon = product.icon;
return (
<motion.div
key={product.id}
initial={{ opacity: 0, y: 20 }}
whileInView={{ opacity: 1, y: 0 }}
viewport={{ once: true }}
transition={{ duration: 0.4, delay: index * 0.03 }}
>
{/* A product card: the line under it is only OFFERED, on
approach — nothing else about the card changes. */}
<Card render={<Link href={product.href || "#"} />} group display="block" height="100%" p={20} rounded={16}>
<Tile size={40} mb={12}>
<Icon width={20} height={20} color={white(70)} />
</Tile>
<CardTitle>{t(product.name)}</CardTitle>
<CardBody>{t(product.description)}</CardBody>
<XStack
mt={12}
items="center"
gap={4}
opacity={0}
$group-hover={{ opacity: 1 }}
$group-focusVisible={{ opacity: 1 }}
$platform-web={{ transition: 'opacity var(--duration-fast) var(--ease-in-out)' }}
>
<Text fontSize="$1" lineHeight="0.9167rem" color={INK}>
{t('Get started')}
</Text>
<ArrowRight width={12} height={12} color={INK} data-i18n-mirror />
</XStack>
</Card>
</motion.div>
);
})}
</Grid>
</Band>
{/* Capabilities Section */}
<Band rule={false} pad="$12" measure={1152}>
<Head
title={t('What sits behind the key')}
lede={t('An app that touches a chain ends up needing most of this — a node to read from, somewhere to keep keys, a way to hear about a transaction that already happened. Open a group to see what it covers.')}
/>
<Grid columns={{ min: 300, max: 3 }} gap={16}>
{CAPABILITIES.map((capability, index) => {
const Icon = capability.icon;
const isExpanded = expandedCapability === capability.id;
return (
<motion.div
key={capability.id}
initial={{ opacity: 0, y: 20 }}
whileInView={{ opacity: 1, y: 0 }}
viewport={{ once: true }}
transition={{ duration: 0.4, delay: index * 0.05 }}
>
<Card overflow="hidden">
{/* A disclosure head whose ground answers a pointer, with no
geometry of its own. */}
<XStack
render={<button type="button" onClick={() => setExpandedCapability(isExpanded ? null : capability.id)} />}
items="flex-start"
gap={16}
width="100%"
p={20}
borderWidth={0}
bg="transparent"
cursor="pointer"
hoverStyle={{ bg: 'var(--white-06)' }}
$platform-web={{ textAlign: 'start', color: 'inherit', font: 'inherit' }}
>
<Tile size={40}>
<Icon width={20} height={20} color={INK} />
</Tile>
<Box grow={1} shrink={1} flexBasis="0%" minW={0}>
<XStack items="center" justify="space-between" gap={8}>
<CardTitle mb={0}>{t(capability.title)}</CardTitle>
{isExpanded ? <ChevronUp width={16} height={16} color={DIM} /> : <ChevronDown width={16} height={16} color={DIM} />}
</XStack>
<CardBody mt={4}>{t(capability.description)}</CardBody>
</Box>
</XStack>
{isExpanded && (
<motion.div initial={{ opacity: 0, height: 0 }} animate={{ opacity: 1, height: "auto" }} exit={{ opacity: 0, height: 0 }}>
<Box px={20} pb={20} borderTopWidth={1} borderColor="var(--border)">
<YStack render="ul" gap={8} mt={16}>
{capability.features.map((feature, idx) => (
<XStack key={idx} render="li" items="flex-start" gap={8}>
<XStack shrink={0} mt={2}>
<Check width={16} height={16} color={INK} />
</XStack>
<Text fontSize="$2" lineHeight="1.1607rem" $platform-web={{ color: SOFT }}>
{t(feature)}
</Text>
</XStack>
))}
</YStack>
</Box>
</motion.div>
)}
</Card>
</motion.div>
);
})}
</Grid>
</Band>
{/* Integration Section */}
<Band rule={false} pad="$12" measure={1152}>
<YStack gap={48} $lg={{ flexDirection: 'row', items: 'center' }}>
<Box grow={1} shrink={1} flexBasis="0%">
<motion.div initial={{ opacity: 0, x: -20 }} whileInView={{ opacity: 1, x: 0 }} viewport={{ once: true }}>
<Box mb={24}>
<Badge edge={white(30)} ground={white(10)}>
<Zap width={16} height={16} color={INK} />
<Text fontSize="$2" lineHeight="1.1607rem" fontWeight="500" color={INK}>
{t('Unified Platform')}
</Text>
</Badge>
</Box>
<Title quiet mb={16}>
{t('An agent with{br}{address}', { br: <br />, address: <Text color={DIM}>{t('an address.')}</Text> })}
</Title>
<Lede mb={24}>
{t('These calls are exposed as tools, so an agent can make them the way you would. It reads a balance, builds a transaction, and signs under whatever policy you put on the key — the same policy that governs a person. What an agent may spend is a rule on the wallet, not a promise in a prompt.')}
</Lede>
<YStack render="ul" gap={12} mt={14} mb={32} pl={40}>
{[
phrase("AI agents that can send on-chain transactions"),
phrase("Natural language smart contract interaction"),
phrase("Automated DeFi strategies with AI optimization"),
phrase("Cross-chain portfolio management"),
].map((item, idx) => (
<XStack key={idx} render="li" items="center" gap={12}>
<Tile size={24} rounded="var(--radius)">
<Check width={14} height={14} color={INK} />
</Tile>
<Text fontSize="$3" lineHeight="1.25rem" $platform-web={{ color: SOFT }}>
{t(item)}
</Text>
</XStack>
))}
</YStack>
</motion.div>
</Box>
<Box grow={1} shrink={1} flexBasis="0%">
<motion.div initial={{ opacity: 0, x: 20 }} whileInView={{ opacity: 1, x: 0 }} viewport={{ once: true }}>
<Card overflow="hidden" $platform-web={{ backgroundColor: 'color-mix(in oklab, var(--secondary) 80%, transparent)' }}>
<XStack items="center" gap={8} px={16} py={12} borderBottomWidth={1} borderColor="var(--border)" bg="var(--background)">
<XStack gap={6}>
{[0, 1, 2].map((k) => (
<Box key={k} width={12} height={12} rounded={9999} $platform-web={{ backgroundColor: white(10) }} />
))}
</XStack>
<Text ml={8} fontFamily="$mono" fontSize="$1" lineHeight="0.9167rem" color={DIM}>
hanzo-agent.ts
</Text>
</XStack>
{agent}
</Card>
</motion.div>
</Box>
</YStack>
</Band>
{/* Supported Chains */}
<Band rule={false} pad="$12" measure={1152}>
<Head
title={t('The chains')}
lede={t('Adding one is our work, not yours — the call you already wrote takes a different argument.')}
/>
<motion.div initial={{ opacity: 0, y: 20 }} whileInView={{ opacity: 1, y: 0 }} viewport={{ once: true }}>
<XStack flexWrap="wrap" justify="center" gap={16}>
{[
// L1s
"Ethereum", "Solana", "Bitcoin", "Avalanche", "BNB Chain", "Cosmos",
// L2s & Rollups
"Arbitrum", "Optimism", "Base", "Polygon", "zkSync", "Scroll", "Linea", "Blast", "Starknet",
// Lux Ecosystem - All Chains
"Lux P-Chain", "Lux C-Chain", "Lux A-Chain", "Lux B-Chain", "Lux Z-Chain",
"Lux T-Chain", "Lux K-Chain", "Lux Q-Chain", "Lux D-Chain",
"Hanzo Network", "Zoo Network", "Pars Network",
// Other Networks
"Aptos", "Sui", "Sei", "Near", "Tron",
].map((chain) => (
<Chip
key={chain}
px={16}
py={8} borderColor="var(--border)" bg={GROUND} color={SOFT}
>
{chain}
</Chip>
))}
</XStack>
</motion.div>
</Band>
{/* CTA Section */}
<Band pad="$12" measure={896}>
<motion.div initial={{ opacity: 0, y: 20 }} whileInView={{ opacity: 1, y: 0 }} viewport={{ once: true }}>
<Box
rounded="var(--radius-2xl)"
borderWidth={1}
p={32}
$md={{ p: 48 }}
$platform-web={{ ...WASH, borderColor: white(30), textAlign: 'center' }}
>
<Tile size={64} mb={24} mx="auto" rounded="var(--radius-2xl)">
<Blocks width={32} height={32} color={INK} />
</Tile>
<Title quiet mb={16}>
{t('Make the first call')}
</Title>
<Lede mb={32} width="100%" maxW={576} mx="auto">
{t('A key from the console reaches the RPC endpoints, the token and NFT data, the wallets and the webhooks. Pick a chain and read something. No credit card required.')}
</Lede>
<XStack mb={32} flexWrap="wrap" gap={16} justify="center">
<Actions />
</XStack>
<XStack flexWrap="wrap" justify="center" gap={24}>
{[
{ icon: Lock, text: phrase('Enterprise-grade security') },
{ icon: Globe, text: phrase('One key, every chain') },
{ icon: Zap, text: phrase('AI-native integration') },
].map(({ icon: Icon, text }) => (
<XStack key={text} items="center" gap={8}>
<Icon width={16} height={16} color={DIM} />
<Text fontSize="$2" lineHeight="1.1607rem" color={DIM}>
{t(text)}
</Text>
</XStack>
))}
</XStack>
</Box>
</motion.div>
</Band>
</Box>
);
};
export default Blockchain;