Desarrollar plantillas de interfaz de usuario para la inicialización de contratos
Esta guía retoma donde Construir un frontend de Dapp lo dejó, echando un vistazo más profundo al --frontend-template
utilizado allí. A partir de ahí, vamos a:
- Buscar en GitHub otras plantillas de Soroban
- Crear nuestra propia plantilla simple
Crear nuestra propia plantilla será una excelente manera de aprender cómo funcionan. ¡No son tan complicadas!
Buscar en GitHub otras plantillas de Soroban
La plantilla oficial mantenida por Stellar Development Foundation (SDF), como se usó en Construir un frontend de Dapp, está en GitHub en stellar/soroban-template-astro. Usa el marco web Astro. Aunque Astro funciona con React, Vue, Svelte y cualquier otra biblioteca de interfaz de usuario, la plantilla opta por no usarlas, prefiriendo el propio lenguaje de plantillas de Astro, que usa JavaScript puro sin biblioteca de interfaz de usuario.
(Puede que te preguntes por qué toma esta elección poco popular. ¡Una pregunta justa! El equipo quería equilibrar la utilidad real con un enfoque amplio. ¡No todos los que aprenden Stellar y Soroban están familiarizados con React, ni con ninguna otra biblioteca de interfaz de usuario. También demuestra que las bibliotecas centrales de Soroban funcionan con cualquier proyecto de JavaScript.)
Pero ten en cuenta que el comando contract init
del CLI fue diseñado para funcionar con cualquier plantilla de interfaz de usuario. ¡No necesita incluso vivir en GitHub! Simplemente pasa otra URL de git válida al comando, y clonará eso en lugar del repositorio oficial:
# the following is NOT a valid git repository, and will not work 😄
stellar contract init my-new-project --frontend-template https://whatever.cool/project/you/want
¿Entonces cómo puedes encontrar otras plantillas de interfaz de usuario válidas?
En algún momento podríamos establecer un DAO u otro sistema de votación para curar una lista de plantillas de alta calidad, pero por ahora... ¡busca en GitHub! Y en GitLab. Y en cualquier otro sitio de código fuente que conozcas.
En GitHub, en la barra de búsqueda principal, busca por "soroban-template-"
. Con las comillas. Aquí tienes un enlace directo a los resultados de búsqueda: github.com/search?q=%22soroban-template-%22
Puedes copiar este enfoque para cualquier otro sitio web de código fuente, como GitLab.
¿Cómo sabes si alguno de estos es bueno? Prueba ellos. Mira su código fuente. ¿Cuántas estrellas tienen? ¿Cuán activos son sus mantenedores? Ninguna de estas es una métrica perfecta, que es por qué un registro curado podría ser agradable en el futuro.
Si ninguno de ellos se ajusta, entonces podría ser tiempo de...
Crear tu propia plantilla
Esto será más fácil de lo que podrías imaginar. Hay algunas complicaciones, pero en general estas plantillas son proyectos de Node bastante estándar.
Pero primero, ¿cómo están organizados estos proyectos?
Cuando ejecutas stellar contract init
, siempre incluye un proyecto de Rust/Cargo, con un Cargo.toml
que define un espacio de trabajo, y miembros del espacio de trabajo ubicados en una carpeta contracts
. Como mínimo, hay un contrato, contracts/hello_world
, pero puedes obtener más usando --with-example
.
Por separado, puedes incluir un --frontend-template
. Hasta ahora, todas las plantillas de interfaz de usuario han sido proyectos de Node, que tienen un package.json
en la raíz. En el proyecto compuesto final, el proyecto de Node y el proyecto de Rust viven uno al lado del otro, y la plantilla de interfaz de usuario espera que el proyecto de Rust esté allí. Espera una carpeta contracts
con una o más subcarpetas, y espera un directorio target
con todos los artefactos de construcción de Rust.
Así que ten eso en mente. Estamos creando un proyecto de Node bastante simple, y contándole sobre nuestro material de Soroban, como la carpeta contracts
.
1. Inicializar un proyecto NPM
Así que, ¡hagamos un proyecto de Node simple! En lugar de inicializar un proyecto Astro, como la plantilla de interfaz de usuario oficial, intentemos algo nuevo. La Encuesta del Estado de JS me dice que algo llamado "Solid" es bastante nuevo y querido. ¿Qué dice que hay que hacer?
npx degit solidjs/templates/ts soroban-template-solid
cd soroban-template-solid
npm install
npm run dev
¡Ok, tenemos una plantilla de Solid en funcionamiento! ¡Ahora vamos a convertirlo en una plantilla de Soroban!
2. git init
¡Haz commit temprano, haz commit a menudo! Puedes detener el servidor de desarrollo (el que comenzaste con npm run dev
arriba; deténlo con ctrlc, incluso en un Mac) si quieres, o abre una nueva terminal y:
git init
git add .
git commit -m "init from solid ts template"
3. Copia el script initialize.js
La plantilla soroban-template-astro
mantenida por la SDF tiene un script initialize.js
en su raíz del proyecto. Cópialo en tu proyecto.
Si estás familiarizado con la scripting en Node, deberías poder averiguar lo que está haciendo. Si no, ¡es una gran manera de aprender! Consejo: comienza desde el final, donde hace el generateAccount(); buildAll(); deployAll();
.
Ese material al final debería darte una pista sobre lo que hace este script. Hace cosas que una aplicación Soroban necesita. Las aplicaciones Soroban hacen llamadas a Soroban.
Así que este script:
- genera una cuenta Soroban/Stellar
- construye todos los contratos
- despliega todos los contratos (a una red Soroban que se ejecuta localmente; recapitularé esto pronto)
- binds contracts — that is, it creates NPM projects for each deployed contract by running
stellar contract bindings typescript
- importa los contratos para un uso directo en el resto de tu proyecto
Recuerda que necesita hacer todo esto de manera independiente del contrato. Es decir, la elección de --frontend-template
es independiente de la elección de --with-example
. ¡La plantilla de interfaz de usuario no sabe qué contratos podría encontrar! Pero necesita construir, desplegar, vincular e importar lo que haya.
Así que este script hace eso.
Pero necesita algunas otras cosas.
A. devDependencies
El script utiliza un par de paquetes NPM. Instálalos:
npm install --save-dev dotenv glob
B. .env
El paquete dotenv
instalado anteriormente analiza variables de entorno desde un archivo .env
. La plantilla oficial incluye un .env.example
. Ve y cópialo en tu propio proyecto. Para prepararte para probarlo, también puedes copiarlo a un .env
local.
cp .env.example .env
C. .gitignore
Querrás ignorar el archivo .env
que creaste anteriormente, así como algunos otros artefactos de construcción creados por el script initialize.js
. Pega la parte inferior de el .gitignore
de la plantilla oficial en el .gitignore
de tu plantilla:
# environment variables
.env
.env.production
# generated contract clients
packages/*
# if you have other workspace packages, add them here
!packages/.gitkeep
# generated contract client imports
src/contracts/*
!src/contracts/util.ts
C. package.json
Asegúrate de que los usuarios de tu plantilla no olviden ejecutar el script initialize.js
. Modifica la sección scripts
de la siguiente manera:
- "start": "vite",
- "dev": "vite",
- "build": "vite build",
- "serve": "vite preview"
+ "init": "node initialize.js",
+ "start": "npm run init && vite",
+ "dev": "npm run init && vite",
+ "build": "npm run init && vite build",
+ "serve": "npm run init && vite preview"
Alternativamente, en lugar de agregar las repetitivas declaraciones npm run init
, podrías optar por añadir un script postinstall
donde ejecutes npm run init
, o simplemente node initialize.js
allí.
También necesitas decirle a NPM que trate esto como un espacio de trabajo. ¡Sí, este proyecto es un espacio de trabajo de Cargo y un espacio de trabajo de NPM! El paso bindAll
de initialize.js
coloca los paquetes de NPM generados en packages/*
. En la parte inferior de package.json
, añade:
"dependencies": {
"solid-js": "^1.8.11"
- }
+ },
+ "workspaces": [
+ "packages/*"
+ ]
}
También asegúrate de que este proyecto esté configurado para permitir las declaraciones import
en el script initialize.js
. Añade esto a nivel superior:
"description": "",
+ "type": "module",
"scripts": {
Mientras estás aquí, también puedes actualizar el name
(quizás "soroban-template-solid"
) y description
.
E. src/contracts/util.ts
En el .gitignore
anterior, es posible que hayas notado que este archivo está explícitamente incluido. Cópialo desde la plantilla oficial. Necesitarás crear la carpeta src/contracts
.
Como puedes ver, simplemente facilita import { rpcUrl, networkPassphrase } from 'util'
en los archivos generados en el paso de importAll
.
F. README
Quizás quieras comenzar copiando el README de la plantilla oficial para explicar cómo hacer cp .env.example .env
. From there, this might also be a good time to explain anything else that makes your template unique! ¿Por qué la gente querría usarla?
4. git commit
¡Haz commit de los cambios!
git add .
git commit -m "add initialize.js script and supporting changes"
5. ¡Prueba esto!
¡Eso es todo! You have an NPM project with an initialize.js
script (and its supporting cast). ¡Eso es todo lo que realmente necesitas!
Para probarlo, pronto ejecutaremos stellar contract init .
en este proyecto para añadir el material de Cargo y una carpeta contracts
. ¡Pero ten cuidado! ¡No quieres hacer commit de estos cambios! Puedes usar git restore .
al final de tus pruebas para deshacerte de los nuevos archivos.
Vamos a probarlo. Primero, asegúrate de que estás ejecutando una red Stellar local. Inicia Docker Desktop o cualquier alternativa que prefieras, entonces:
stellar network container start local
Ahora podemos ejecutar contract init
. Vamos a incluir un contrato extra. Luego ejecutaremos el script dev
(que, recuerda, ejecutará primero el script initialize.js
):
stellar contract init . --with-example increment
npm run dev
Después de hacer esto, es posible que notes muchos cambios nuevos en el proyecto. ¡Todo ese material de Rust, Cargo y Soroban!
$ git status --short
?? .soroban/
?? Cargo.lock
?? Cargo.toml
?? contracts/
?? target/
Q: Should you commit this stuff?
A: NO!
Q: Should you gitignore this stuff?
A: NO!
Las carpetas .soroban
y target
están gitignoreadas por la plantilla principal de Rust/Cargo. En los proyectos que especifiquen el tuyo como su --frontend-template
, ese .gitignore
se fusionará con el tuyo. No es necesario incluir esas líneas dos veces.
Y los proyectos que utilizan el tuyo querrán hacer commit de los archivos Cargo.*
y contracts
, pero tu plantilla no debería incluirlos. Eso puede causar problemas con la inicialización del proyecto más adelante. Nor should it gitignore them, because your .gitignore
will be part of projects started with your template! ¡Causaría problemas y confusión, si la gente no se diera cuenta de que algunos de sus archivos más importantes estaban gitignoreados!
Está bien. Ve y abre la aplicación en tu navegador. Solid ejecuta su servidor de desarrollo en http://localhost:3000
. ¿Se carga? ¡Debería! ¡En realidad no utilizamos el nuevo material src/contracts/*
en la aplicación misma!
6. Espera. ¿Debería la plantilla realmente usar los contratos?
¡Buena pregunta!
Sabes que el contrato hello_world
siempre estará allí. Así que podrías demostrar a tus usuarios cómo importarlo y usarlo en un archivo de aplicación (como src/App.tsx
, en la plantilla de Solid). Pero recuerda: ¡ningún otro contrato tiene garantizado estar allí! So don't commit any changes that import and use something like increment
!
Aquí tienes una forma de demostrar cómo importar y usar el contrato hello_world
en el App.tsx
de la plantilla de Solid:
+import greeter from "./contracts/hello_world";
const App: Component = () => {
return (
<div class={styles.App}>
<header class={styles.header}>
+ <form
+ onSubmit={async (e) => {
+ e.preventDefault();
+ const { result } = await greeter.hello({
+ to: e.currentTarget.toWhom.value,
+ });
+ alert(result);
+ }}
+ >
+ <label>
+ Who you gonna call? &nbsp;
+ <input name="toWhom" value="World" /> &nbsp;
+ </label>
+ <button type="submit">Say Hello</button>
+ </form>
7. ¡Hazlo tan complejo como quieras!
Esta es tu plantilla. Ve y añade dependencias útiles y archivos de utilidad que siempre quieras, como gestión de billeteras o lo que sea. Si quieres añadir un montón de componentes de interfaz de usuario, estilos y bibliotecas de gestión de estado, ¡adelante!
La plantilla oficial se esfuerza por la simplicidad. Incluso por superficialidad. Está destinado a ser una herramienta de enseñanza, para personas con diferentes niveles de experiencia en JS y Soroban. ¡La tuya no tiene tales restricciones! Debería ser útil para ti.
¡Y las plantillas son baratas de hacer! Si quieres tener una soroban-template-framework-x-basic
para un público más amplio, y otra soroban-template-framework-x-opinionated
para tus propios proyectos, ¡puedes hacerlo!
Conclusión
Algunas cosas que hicimos en esta sección:
- Buscamos en GitHub nuevas plantillas de interfaz de usuario
- Aprendimos que algunas plantillas podrían no estar en GitHub
- Vimos cómo funcionan las plantillas de interfaz de usuario e interactúan con la plantilla "backend" que siempre viene con
stellar contract init
- Desarrollada nuestra propia plantilla al agregar un script
initialize.js
a una plantilla básica de NPM
Después de que termines de construir tu propia plantilla de frontend, ¿qué sigue? ¡Tú eliges! Puedes:
- Ver más ejemplos de contratos complejos en la sección de Ejemplos de Contratos.
- Aprender más sobre la arquitectura y diseño internos de Soroban.
Guías en esta categoría:
📄️ Usar Docker para crear y ejecutar dapps
Entender Docker y usarlo para crear aplicaciones
📄️ Guía completa de frontend para dapps Stellar
Aprende a crear interfaces de frontend funcionales para dapps Stellar usando React, Tailwind CSS y el Stellar SDK.
📄️ Inicializa una dapp usando scripts
Configura la inicialización correctamente para asegurar un proceso fluido para tu dapp
📄️ Crear un frontend para tu dapp usando React
Conectar frontends de dapp a contratos y la billetera Freighter usando @soroban-react
📄️ Desarrollar plantillas de interfaz de usuario para la inicialización de contratos
Entender, encontrar y crear tus propias plantillas de interfaz de usuario para usarlas con el comando `stellar contract init` de Stellar CLI
📄️ Implementar archivo de estado en dapps
Aprender cómo implementar archivo de estado en tu dapp
📄️ Trabajar con especificaciones de contrato en Java, Python y PHP
Una guía para entender e interactuar con los contratos inteligentes de Soroban en diferentes lenguajes de programación