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
Jump to file
Failed to load files.
Loading
Diff view
Diff view
82 changes: 82 additions & 0 deletions AGENTS.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,82 @@
# AGENTS.md - Relaycode

## Project Overview

Relaycode is a modern extrinsic builder for the Polkadot ecosystem, funded by a Web3 Foundation (W3F) grant. It provides a dual-pane interface for building, encoding/decoding, and submitting Substrate extrinsics with human-readable inputs on one side and encoded data on the other.

## Tech Stack

- **Framework**: Next.js 14 (App Router, SSR)
- **Language**: TypeScript (strict mode)
- **Styling**: Tailwind CSS + shadcn/ui
- **Polkadot Client**: [Dedot](https://github.com/dedotdev/dedot) (NOT @polkadot/api, which is deprecated)
- **Wallet**: LunoKit (planned M2 — NOT custom wallet provider)
- **State Management**: React Context API + hooks
- **Testing**: Jest + React Testing Library
- **Package Manager**: Yarn 1.x

## Directory Structure

```
app/ # Next.js App Router pages
(marketing)/ # Landing/marketing pages
builder/ # Extrinsic builder tool
components/
builder/ # Extrinsic builder components
params/ # Parameter type components
inputs/ # Substrate type input components (account, balance, enum, etc.)
ui/ # shadcn/ui base components
config/ # App configuration
context/ # React context providers
hooks/ # Custom React hooks
lib/ # Utility libraries
types/ # TypeScript type definitions
utils/ # Helper utilities
styles/ # Global styles
__tests__/ # Jest test files
docs/ # Documentation (public)
```

## Commands

```bash
yarn dev # Start dev 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
```

## Architecture Notes

**Three-layer architecture** (planned M2):
1. **Infrastructure** — providers, clients, wallet connection (LunoKit)
2. **Components** — reusable UI (params/inputs, builder panes)
3. **App** — pages, routing, layouts

**Key patterns:**
- Path aliases via `@/*` mapping to project root
- shadcn/ui components in `components/ui/` — don't modify directly
- Input components in `components/params/inputs/` map to Substrate types
- Dedot client provides type-safe chain interactions via `DedotClient<PolkadotApi>`

## Code Conventions

- TypeScript strict mode enabled
- Kebab-case for filenames (e.g., `key-value.tsx`, `vote-threshold.tsx`)
- Barrel exports from directories via `index.ts`
- React components use named exports
- `"use client"` directive for client components

## Important Gotchas

1. **Dedot, not polkadot-js** — This project uses Dedot as the Polkadot client. Do not import from `@polkadot/api`.
2. **LunoKit for wallet** — M2 will use LunoKit for wallet connection. Do not build custom wallet/keyring providers.
3. **shadcn/ui components** — Generated into `components/ui/`. Add new ones via `npx shadcn-ui add <component>`.
4. **Next.js 14** — Uses App Router (not Pages Router). Layouts in `layout.tsx`, pages in `page.tsx`.
5. **No `lib/polkadot/`** — Legacy directory removed. Dedot is the only Polkadot integration.

## M2 Implementation Reference

See local `docs/m2-plan/` directory for detailed implementation plans (gitignored, not in repo).
71 changes: 41 additions & 30 deletions app/studio/layout.tsx
Original file line number Diff line number Diff line change
@@ -1,37 +1,48 @@
"use client";
import type { Metadata } from "next";
import type { ReactNode } from "react";

import React from "react";
import { NavBar } from "@/components/layout/site-header";
import { ClientProvider } from "@/context/client";
import { ContractProvider } from "@/context/contract-provider";
import { StudioProvider } from "@/context/studio-provider";
import { StudioNavCenter } from "@/components/studio/studio-nav-center";
import { siteConfig } from "@/config/site";
import { StudioClientLayout } from "@/components/studio/studio-client-layout";

const title = "Contract Studio — Smart Contract IDE for Polkadot Hub";
const description =
"Write Solidity, compile to EVM or PVM, and deploy smart contracts on Polkadot Hub. No CLI or MetaMask required.";
const canonicalUrl = `${siteConfig.url}/studio`;
const imageUrl = `${siteConfig.url}/api/og/studio`;

export const metadata: Metadata = {
title,
description,
alternates: {
canonical: canonicalUrl,
},
openGraph: {
type: "website",
url: canonicalUrl,
title,
description,
siteName: siteConfig.name,
images: [
{
url: imageUrl,
width: 1200,
height: 630,
alt: title,
},
],
},
twitter: {
card: "summary_large_image",
title,
description,
images: [imageUrl],
},
};

interface StudioLayoutProps {
children: React.ReactNode;
children: ReactNode;
}

export default function StudioLayout({ children }: StudioLayoutProps) {
return (
<ClientProvider>
<ContractProvider>
<StudioProvider>
<div className="flex h-screen flex-col overflow-hidden">
<title>Contract Studio — Smart Contract IDE for Polkadot Hub | Relaycode</title>
<meta name="description" content="Write Solidity, compile to EVM or PVM, and deploy smart contracts on Polkadot Hub. No CLI or MetaMask required." />
<meta property="og:title" content="Contract Studio — Smart Contract IDE for Polkadot Hub" />
<meta property="og:description" content="Write Solidity, compile to EVM or PVM, and deploy smart contracts on Polkadot Hub. No CLI or MetaMask required." />
<meta property="og:image" content="/api/og/studio" />
<meta property="og:image:width" content="1200" />
<meta property="og:image:height" content="630" />
<meta name="twitter:card" content="summary_large_image" />
<meta name="twitter:image" content="/api/og/studio" />
<link rel="canonical" href="https://relaycode.org/studio" />
<NavBar centerElement={<StudioNavCenter />} />
<main className="flex flex-col flex-1 min-h-0">{children}</main>
</div>
</StudioProvider>
</ContractProvider>
</ClientProvider>
);
return <StudioClientLayout>{children}</StudioClientLayout>;
}
28 changes: 28 additions & 0 deletions components/studio/studio-client-layout.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
"use client";

import type { ReactNode } from "react";

import { NavBar } from "@/components/layout/site-header";
import { ClientProvider } from "@/context/client";
import { ContractProvider } from "@/context/contract-provider";
import { StudioProvider } from "@/context/studio-provider";
import { StudioNavCenter } from "@/components/studio/studio-nav-center";

interface StudioClientLayoutProps {
children: ReactNode;
}

export function StudioClientLayout({ children }: StudioClientLayoutProps) {
return (
<ClientProvider>
<ContractProvider>
<StudioProvider>
<div className="flex h-screen flex-col overflow-hidden">
<NavBar centerElement={<StudioNavCenter />} />
<main className="flex min-h-0 flex-1 flex-col">{children}</main>
</div>
</StudioProvider>
</ContractProvider>
</ClientProvider>
);
}
Binary file added public/relaycode-studio-logo.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
18 changes: 18 additions & 0 deletions public/relaycode-studio-logo.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading