FeatherScript

FeatherScript

chain::4663

Docs

02 / 09

Architecture

System diagrams, flows, and components

Diagrama de alto nivel

Diagram

flowchart TB
    subgraph User["Usuario"]
        W[Wallet EVM]
        B[Navegador]
    end

    subgraph Frontend["FeatherScript Frontend (Next.js)"]
        UI[Landing + dApp]
        WM[wagmi / viem]
    end

    subgraph Chain["Robinhood Chain L2"]
        SC[InscriptionRegistry]
        ST[(Contract Storage)]
    end

    subgraph Index["Opcional — futuro"]
        IDX[Event Indexer]
        DB[(Base de datos)]
    end

    B --> UI
    UI --> WM
    W --> WM
    WM -->|inscribe(bytes)| SC
    WM -->|getInscription(id)| SC
    SC --> ST
    SC -->|event Inscribed| IDX
    IDX --> DB

Flujo de inscripción

Diagram

sequenceDiagram
    participant U as Usuario
    participant F as Frontend
    participant W as Wallet
    participant C as InscriptionRegistry
    participant L2 as Robinhood Chain

    U->>F: Escribe texto o sube archivo
    F->>F: Convierte contenido a bytes (hex)
    U->>F: Clic "Inscribe On-Chain"
    F->>W: writeContract(inscribe, data)
    W->>U: Solicita firma
    U->>W: Aprueba transacción
    W->>L2: Envía tx
    L2->>C: inscribe(data)
    C->>C: inscriptionCount++
    C->>C: Guarda Inscription en storage
    C-->>L2: emit Inscribed(...)
    L2-->>F: Transaction receipt
    F->>F: Extrae inscriptionId del log
    F->>U: Muestra confirmación + detalle

Estructura del repositorio

FeatherScript/ ├── app/ # App Router de Next.js │ ├── layout.tsx # Layout raíz, fuentes, providers │ ├── page.tsx # Página principal (landing + dApp) │ └── globals.css # Estilos globales + Tailwind │ ├── components/ # Componentes React │ ├── Providers.tsx # WagmiProvider + React Query │ ├── Header.tsx # Navbar + Connect Wallet │ ├── Hero.tsx # Sección hero │ ├── InscribeForm.tsx # Formulario de inscripción │ ├── InscriptionHistory.tsx # Historial + modal de detalle │ ├── ProtocolSection.tsx # Documentación visual del protocolo │ └── Footer.tsx # Pie de página │ ├── lib/ # Lógica compartida │ ├── chains.ts # Definición Robinhood mainnet/testnet │ ├── wagmi.ts # Configuración wagmi │ ├── contract.ts # ABI + dirección del contrato │ └── utils.ts # Helpers (hex, formato, display) │ ├── contracts/ # Proyecto Foundry │ ├── src/ │ │ └── InscriptionRegistry.sol │ ├── test/ │ │ └── InscriptionRegistry.t.sol │ ├── script/ │ │ └── Deploy.s.sol │ └── foundry.toml │ ├── public/ │ └── featherscript-logo.png │ ├── docs/ # Esta documentación ├── package.json ├── .env.example └── README.md

Capas del sistema

1. Capa de presentación (Frontend)

Responsabilidades:

  • Conectar wallet del usuario
  • Convertir texto/archivos a bytes
  • Enviar transacciones al contrato
  • Leer inscripciones existentes
  • Mostrar historial y detalles

No almacena datos off-chain. Todo se lee directamente del contrato vía RPC.

2. Capa de protocolo (Smart Contract)

Responsabilidades:

  • Recibir bytes y persistirlos
  • Mantener contador global
  • Exponer lectura por ID
  • Emitir eventos para indexación

Es la única fuente de verdad on-chain.

3. Capa de red (Robinhood Chain)

  • L2 compatible con EVM (Arbitrum Orbit)
  • Gas pagado en ETH
  • Confirmaciones rápidas (~sub-segundo)
  • Chain ID mainnet: 4663

4. Capa de indexación (opcional, futuro)

No incluida en el MVP, pero recomendada para:

  • Historial completo con txHash
  • Búsqueda por creador
  • Paginación eficiente
  • APIs REST/GraphQL

Modelo de datos

Diagram

erDiagram
    INSCRIPTION_REGISTRY ||--o{ INSCRIPTION : contains

    INSCRIPTION_REGISTRY {
        uint256 inscriptionCount
    }

    INSCRIPTION {
        uint256 inscriptionId PK
        address creator
        uint256 timestamp
        uint256 blockNumber
        bytes data
    }

El inscriptionId es la clave del mapping interno _inscriptions y va de 1 a inscriptionCount.


Decisiones de diseño

¿Por qué un solo contrato sin proxy?

  • Máxima simplicidad y auditabilidad
  • Sin riesgo de upgrades maliciosos
  • Deploy una vez, permanente

¿Por qué bytes y no string?

  • bytes es más flexible (archivos binarios, hex, UTF-8)
  • No impone encoding
  • Gas ligeramente más predecible con calldata

¿Por qué IDs incrementales y no hashes?

  • Consulta directa por número (getInscription(42))
  • UX simple para usuarios ("Inscription #42")
  • Los indexadores pueden mapear ID → txHash off-chain

¿Por qué límite de 24 KB en archivos (frontend)?

  • El gas escala linealmente con el tamaño del calldata
  • 24 KB es un balance razonable para inscripciones de texto/archivos pequeños
  • Es una restricción de la UI, no del contrato

Siguiente lectura

← Back to AppInscribe On-Chain