From 765dd3e3898779a213a52a23c9a6e5c77f4f18ec Mon Sep 17 00:00:00 2001 From: Yogesh Kumar Date: Sun, 22 Mar 2026 08:28:37 +0530 Subject: [PATCH 1/2] Improve SEO metadata and rewrite README for toolkit rebrand MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit SEO fixes: - Add sitemap.ts and robots.ts for search engine indexing - Add JSON-LD structured data (SoftwareApplication schema) - Add viewport export with theme-color for light/dark modes - Add canonical URLs to all pages - Fix homepage title (9 chars → 50 chars) and description (169 → 120 chars) - Add title.template ("%s | Relaycode") for consistent sub-page titles - Update keywords to include Studio, Solidity, PolkaVM, Dedot - Fix siteName in openGraph (was using page title instead of "Relaycode") README: - Rewrite to reflect toolkit rebrand (not just extrinsic builder) - Add OG banner images for each tool section - Document Contract Studio, Extrinsic Builder, Component Docs - Update tech stack table, getting started, and project structure --- README.md | 218 ++++++++++++++++++++++++++++------------- app/builder/layout.tsx | 7 +- app/docs/layout.tsx | 7 +- app/layout.tsx | 44 ++++++++- app/robots.ts | 15 +++ app/sitemap.ts | 32 ++++++ app/studio/layout.tsx | 7 +- config/site.ts | 4 +- lib/utils.ts | 28 ++++-- public/og/builder.png | Bin 0 -> 47595 bytes public/og/docs.png | Bin 0 -> 42910 bytes public/og/home.png | Bin 0 -> 40649 bytes public/og/studio.png | Bin 0 -> 50313 bytes 13 files changed, 274 insertions(+), 88 deletions(-) create mode 100644 app/robots.ts create mode 100644 app/sitemap.ts create mode 100644 public/og/builder.png create mode 100644 public/og/docs.png create mode 100644 public/og/home.png create mode 100644 public/og/studio.png diff --git a/README.md b/README.md index 7d431e9..d6e1901 100644 --- a/README.md +++ b/README.md @@ -1,4 +1,4 @@ -# Relaycode: Rethinking Extrinsics in Polkadot +# Relaycode [![CI](https://github.com/itsyogesh/relaycode/actions/workflows/ci.yml/badge.svg)](https://github.com/itsyogesh/relaycode/actions/workflows/ci.yml) [![codecov](https://codecov.io/gh/itsyogesh/relaycode/branch/master/graph/badge.svg)](https://codecov.io/gh/itsyogesh/relaycode) @@ -6,80 +6,160 @@ [![TypeScript](https://img.shields.io/badge/TypeScript-strict-blue.svg)](https://www.typescriptlang.org/) [![W3F Grant](https://img.shields.io/badge/Web3_Foundation-Grant-green.svg)](https://grants.web3.foundation/) -## Project Overview -Relaycode is an intuitive extrinsics builder designed to transform the way developers and users interact with extrinsics in the Polkadot ecosystem. By bridging the gap between complex pallet operations and user-friendly interfaces, Relaycode gives both regular users and developers the ability to harness the full potential of extrinsics the Polkadot ecosystem. +The developer toolkit for Polkadot. Build extrinsics, write smart contracts, and interact with Substrate chains — all from your browser. -### Key Features: +

+ Relaycode — The Developer Toolkit for Polkadot +

-1. **A New Extrinsic Builder**: Our state-of-the-art builder allows users to construct extrinsics with ease, providing real-time encoding and decoding for immediate visual feedback. +## Tools -2. **Dual-Pane Interface**: Relaycode lets you see the best of both worlds with our split-view design. Build extrinsics using human-readable inputs on one side, while simultaneously viewing the corresponding encoded data on the other. +### Contract Studio -3. **Bi-Directional Editing**: Seamlessly switch between editing human-readable values and raw encoded data. Changes in one pane are instantly reflected in the other, offering unparalleled flexibility. +Relaycode Studio -4. **Wallet Integration**: Connect your Polkadot wallet directly within Relaycode to sign and submit extrinsics, eliminating the need for external tools or interfaces. +Browser-based smart contract IDE for Polkadot Hub. Write Solidity, compile to EVM or PVM (PolkaVM), and deploy with native Polkadot wallets. No CLI, no MetaMask, no fragmented toolchain. -5. **Customizable Snippets**: Create, save, and share reusable extrinsic templates. Streamline complex processes by chaining multiple calls into a single, user-friendly form. +**[relaycode.org/studio](https://relaycode.org/studio)** -6. **Educational Tools**: Built-in guides and tooltips help users understand the intricacies of extrinsics, making Relaycode an excellent learning platform for Polkadot users. +### Extrinsic Builder -

- Relaycode Demo -

+Relaycode Builder + +Visual extrinsic builder for the Polkadot ecosystem. Build, encode, decode, and submit any Substrate extrinsic with a dual-pane interface. Supports all pallets across all chains. + +**[relaycode.org/builder](https://relaycode.org/builder)** + +### Component Docs + +Documentation for input components, encoding/decoding APIs, and usage guides. Built with Fumadocs. + +**[relaycode.org/docs](https://relaycode.org/docs)** + +### Substrate Utilities *(planned)* + +SS58, EVM, and hex address converter plus other Substrate utilities. + +## Tech Stack + +| Layer | Technology | +|-------|-----------| +| **Framework** | Next.js 15 (App Router) | +| **Language** | TypeScript (strict mode) | +| **Styling** | Tailwind CSS + shadcn/ui | +| **Polkadot Client** | [Dedot](https://github.com/dedotdev/dedot) | +| **Wallet** | [LunoKit](https://github.com/nickytonline/luno-kit) (Polkadot.js, Talisman, SubWallet) | +| **Smart Contracts** | Solidity → EVM / PVM via PolkaVM | +| **Docs** | [Fumadocs](https://fumadocs.vercel.app/) | +| **Testing** | Jest + React Testing Library | +| **Deployment** | Vercel (Edge + Serverless) | +| **Package Manager** | Yarn 1.x | + +### Supported Chains + +Polkadot, Kusama, Westend, Paseo, Asset Hubs, People chains, Coretime chains. + +## Getting Started + +### Prerequisites + +- Node.js 18+ +- Yarn 1.x (`npm install -g yarn`) + +### Setup + +```bash +# Clone the repository +git clone https://github.com/itsyogesh/relaycode.git +cd relaycode + +# Install dependencies +yarn install + +# Start the development server +yarn dev +``` + +Open [http://localhost:3000](http://localhost:3000) in your browser. + +### Environment Variables + +Copy the example and configure: + +```bash +cp .env.example .env +``` + +| Variable | Description | Default | +|----------|------------|---------| +| `NEXT_PUBLIC_APP_URL` | Application URL | `http://localhost:3000` | +| `NEXT_PUBLIC_DEFAULT_CHAIN` | Default chain identifier | `pop-network-testnet` | +| `NEXT_PUBLIC_SUPPORTED_CHAINS` | JSON array of supported chains | See `.env` | + +### Available Commands + +| Command | Description | +|---------|------------| +| `yarn dev` | Start development server | +| `yarn build` | Production build | +| `yarn start` | Start production server | +| `yarn lint` | Run ESLint | +| `yarn test` | Run Jest tests | +| `yarn test:watch` | Run tests in watch mode | + +## Project Structure + +``` +app/ + (marketing)/ # Landing pages + builder/ # Extrinsic builder + studio/ # Contract Studio IDE + docs/ # Documentation (Fumadocs) + api/ + og/ # Dynamic OG image generation + compile/ # Solidity compilation endpoint +components/ + builder/ # Extrinsic builder components + studio/ # Contract Studio components + params/inputs/ # Substrate type input components + ui/ # shadcn/ui base components +context/ # React context providers +hooks/ # Custom React hooks +lib/ # Utility libraries +types/ # TypeScript type definitions +``` + +### Input Components + +The extrinsic builder includes type-aware input components for every Substrate type: + +Account, Amount, Balance, Bool, BTreeMap, BTreeSet, Bytes, Call, Enum, Hash (H160/H256/H512), KeyValue, Moment, Option, Struct, Text, Tuple, Vector, VectorFixed, Vote, VoteThreshold. + +Each component maps directly to SCALE-encoded Substrate types and supports validation, encoding, and real-time feedback. + +## Deployment + +Relaycode is deployed on Vercel. Pushes to `master` trigger automatic production deployments. + +OG images are generated dynamically at the edge via `next/og` ImageResponse routes: + +- `/api/og/home` — Homepage +- `/api/og/studio` — Contract Studio +- `/api/og/builder` — Extrinsic Builder +- `/api/og/docs` — Documentation + +## Contributing + +1. Fork the repository +2. Create a feature branch (`git checkout -b feat/my-feature`) +3. Commit your changes +4. Push to the branch (`git push origin feat/my-feature`) +5. Open a Pull Request + +## License + +[Apache 2.0](LICENSE) + +## Acknowledgments -## Technical Architecture -- Frontend: Next.js 15 with App Router, React, TypeScript -- Styling: Tailwind CSS, shadcn/ui components -- State Management: React Hooks, Context API -- Polkadot Integration: [Dedot](https://github.com/dedotdev/dedot) -- Wallet: [LunoKit](https://github.com/nickytonline/luno-kit) (Polkadot.js, Talisman, SubWallet) -- Chains: Polkadot, Kusama, Westend (testnet) -- Theming: next-themes for dark/light mode support - -## Documentation - -- [API Reference](docs/api/README.md) - Core encoding, decoding, and validation APIs -- [Component Reference](docs/components/README.md) - Input component documentation -- [Getting Started Tutorial](docs/tutorial/getting-started.md) - Build your first extrinsic -- [Advanced Usage](docs/tutorial/advanced.md) - Bi-directional editing, batch calls, complex types -- [Testing Guide](docs/testing-guide.md) - How to run and write tests - -## Milestones - -For detailed project milestones and deliverables, see our [Milestones](docs/relaycode.md) documentation. - -### Implemented Input Components - -The following input components have been implemented for the extrinsic builder: - -- [x] **Account** - Handles `AccountId`, `Address`, `LookupSource`, `MultiAddress` -- [x] **Amount** - Handles `i8`, `i16`, `i32`, `i64`, `i128`, `u8`, `u16`, `u32`, `u64`, `u128`, `Compact` -- [x] **Balance** - Handles `Balance`, `BalanceOf`, `Compact`, `Compact` -- [x] **Bool** - Handles `bool` -- [x] **BTreeMap** - Handles `BTreeMap` with typed key-value pair inputs -- [x] **BTreeSet** - Handles `BTreeSet` with duplicate detection -- [x] **Bytes** - Handles `Bytes`, `Vec` -- [x] **Call** - Handles `Call`, `RuntimeCall` -- [x] **Enum** - Handles enum types from metadata -- [x] **Hash160** - Handles `H160` (20-byte hash) -- [x] **Hash256** - Handles `Hash`, `H256` (32-byte hash) -- [x] **Hash512** - Handles `H512` (64-byte hash) -- [x] **KeyValue** - Handles `KeyValue` -- [x] **Moment** - Handles `Moment`, `MomentOf` -- [x] **Option** - Handles `Option` -- [x] **Text** - Handles `String`, `Text` (and fallback for unknown types) -- [x] **Struct** - Handles composite/struct types -- [x] **Tuple** - Handles tuple types `(T1, T2, ...)` -- [x] **Vector** - Handles `Vec`, `BoundedVec` -- [x] **VectorFixed** - Handles fixed-length arrays `[T; N]` -- [x] **Vote** - Handles `Vote` -- [x] **VoteThreshold** - Handles `VoteThreshold` - -### M2 Features - -- [x] **Chain Selector** - Switch between Polkadot, Kusama, and Westend (testnet) from the navbar -- [x] **Type Badges** - Builder displays Substrate type names alongside field labels -- [x] **Wallet Integration** - LunoKit-based wallet connect (Polkadot.js, Talisman, SubWallet) -- [x] **Bi-Directional Editing** - Edit via form or raw hex, with real-time sync -- [x] **Transaction Submission** - Sign and submit extrinsics directly from the builder -- [x] **Input Validation** - Pre-submission validation with descriptive error messages +Funded by a [Web3 Foundation](https://web3.foundation/) grant. Built with [Dedot](https://github.com/dedotdev/dedot) and [LunoKit](https://github.com/nickytonline/luno-kit). diff --git a/app/builder/layout.tsx b/app/builder/layout.tsx index 44a6033..b7aacd1 100644 --- a/app/builder/layout.tsx +++ b/app/builder/layout.tsx @@ -4,9 +4,9 @@ import { SiteFooter } from "@/components/layout/site-footer"; import { Blocks } from "lucide-react"; export const metadata: Metadata = { - title: "Relaycode Builder — Polkadot Extrinsic Builder", + title: "Extrinsic Builder — Build and Submit Substrate Extrinsics", description: - "Build, encode, decode, and submit any Substrate extrinsic visually. Supports all pallets across the Polkadot ecosystem.", + "Visual extrinsic builder for Polkadot. Build, encode, decode, and submit any pallet call across all Substrate chains.", openGraph: { images: [{ url: "/api/og/builder", width: 1200, height: 630 }], }, @@ -14,6 +14,9 @@ export const metadata: Metadata = { card: "summary_large_image", images: ["/api/og/builder"], }, + alternates: { + canonical: "/builder", + }, }; interface BuilderLayoutProps { diff --git a/app/docs/layout.tsx b/app/docs/layout.tsx index 91eff0d..d450733 100644 --- a/app/docs/layout.tsx +++ b/app/docs/layout.tsx @@ -4,9 +4,9 @@ import { DocsLayout } from "fumadocs-ui/layouts/docs"; import { source } from "@/lib/source"; export const metadata: Metadata = { - title: "Relaycode Docs — Developer Documentation", + title: "Docs — Guides, References, and Examples", description: - "Developer documentation for the Relaycode toolkit. Guides, references, and examples for building on Polkadot.", + "Developer documentation for Relaycode. Guides, API references, and examples for building on Polkadot with Substrate.", openGraph: { images: [{ url: "/api/og/docs", width: 1200, height: 630 }], }, @@ -14,6 +14,9 @@ export const metadata: Metadata = { card: "summary_large_image", images: ["/api/og/docs"], }, + alternates: { + canonical: "/docs", + }, }; export default function Layout({ children }: { children: ReactNode }) { diff --git a/app/layout.tsx b/app/layout.tsx index 8237711..a3feac3 100644 --- a/app/layout.tsx +++ b/app/layout.tsx @@ -1,5 +1,6 @@ import "@/styles/globals.css"; +import type { Viewport } from "next"; import { Nunito } from "next/font/google"; import { GeistMono } from "geist/font/mono"; import { GeistSans } from "geist/font/sans"; @@ -23,12 +24,53 @@ const nunito = Nunito({ variable: "--font-nunito", }); +export const viewport: Viewport = { + width: "device-width", + initialScale: 1, + maximumScale: 5, + themeColor: [ + { media: "(prefers-color-scheme: light)", color: "#ffffff" }, + { media: "(prefers-color-scheme: dark)", color: "#0a0a0a" }, + ], +}; + export const metadata = constructMetadata(); export default function RootLayout({ children }: RootLayoutProps) { return ( - + +