Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Adding a build dapp step to guide #945 #1318

Open
wants to merge 4 commits into
base: main
Choose a base branch
from
Open
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
1 change: 0 additions & 1 deletion docs/build/apps/dapp-frontend.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,6 @@ sidebar_position: 70
sidebar_label: Build a Dapp Frontend
title: "Build a dapp Frontend: Connect Wallets, Handle Transactions & More"
description: "Learn how to build a dapp frontend that connects to smart contracts. Explore best practices for integrating wallets, handling transactions, and interacting with the Stellar network."
pagination_prev: build/smart-contracts/getting-started/deploy-increment-contract
---

# Build a Dapp Frontend
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,6 @@ sidebar_position: 40
title: "Deploy the Increment Smart Contract on Testnet Using the CLI: A Guide"
sidebar_label: 4. Deploy the Increment Contract
description: "Follow this step-by-step guide in the final section of Getting Started to learn how to deploy the increment smart contract on Testnet using the Stellar CLI."
pagination_next: build/apps/dapp-frontend
---

# 4. Deploy the Increment Contract
Expand Down
130 changes: 130 additions & 0 deletions docs/build/smart-contracts/getting-started/hello-world-frontend.mdx
Original file line number Diff line number Diff line change
@@ -0,0 +1,130 @@
---
sidebar_position: 50
sidebar_label: "5. Build a Hello World Frontend"
title: "Build a frontend for the Hello World contract"
description: "Build a frontend for the Hello World contract by using Stellar CLI to generate TypeScript bindings."
---

# 5. Build a Hello World Frontend

In the previous examples, we invoked the contracts using the Stellar CLI, and in this last part of the guide we'll create a web app that interacts with the Hello World contract through TypeScript bindings.

:::info

This example shows one way of creating a binding between a contract and a frontend, for a more comprehensive guide see the [Build a Dapp Frontend](../../apps/dapp-frontend.mdx) documentation.

:::

## Initialize a frontend toolchain

You can build a Soroban app with any frontend toolchain or integrate it into any existing full-stack app. For this tutorial, we're going to use [Astro](https://astro.build/). Astro works with React, Vue, Svelte, any other UI library, or no UI library at all. In this tutorial, we're not using a UI library. The Soroban-specific parts of this tutorial will be similar no matter what frontend toolchain you use.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can we say Stellar app instead of Soroban app throughout the documentation? I think we will eventually move away from using "Soroban" as much as newcomers don't necessarily know what Soroban is, they just know Stellar.


If you're new to frontend, don't worry. We won't go too deep. But it will be useful for you to see and experience the frontend development process used by Soroban apps. We'll cover the relevant bits of JavaScript and Astro, but teaching all of frontend development and Astro is beyond the scope of this tutorial.

Let's get started.

You're going to need [Node.js](https://nodejs.org/en/download/package-manager/) v18.14.1 or greater. If you haven't yet, install it now.

We want to create an Astro project with the contracts from the previous lesson. To do this, we can clone a template. You can find Soroban templates on GitHub by [searching for repositories that start with "soroban-template-"](https://github.com/search?q=%22soroban-template-%22&type=repositories). For this tutorial, we'll use [stellar/soroban-template-astro](https://github.com/stellar/soroban-template-astro). We'll also use a tool called [degit](https://github.com/Rich-Harris/degit) to clone the template without its git history. This will allow us to set it up as our own git project.

Since you have `node` and its package manager `npm` installed, you also have `npx`.

We're going to create a new project directory with this template to make things easier in this tutorial, so make sure you're no longer in your `soroban-hello-world` directory and then run:

```sh
npx degit stellar/soroban-template-astro first-soroban-app
cd first-soroban-app
git init
git add .
git commit -m "first commit: initialize from stellar/soroban-template-astro"
```

This project has the following directory structure, which we'll go over in more detail below.

```bash
├── contracts
│   ├── hello_world
│   └── increment
├── CONTRIBUTING.md
├── Cargo.toml
├── Cargo.lock
├── initialize.js
├── package-lock.json
├── package.json
├── packages
├── public
├── src
│   ├── components
│   │   └── Card.astro
│   ├── env.d.ts
│   ├── layouts
│   │   └── Layout.astro
│   └── pages
│   └── index.astro
└── tsconfig.json
```

The `contracts` are the same ones you walked through in the previous steps of the tutorial. Since we already deployed these contracts with aliases, we can reuse the generated contract ID files by copying them from the `soroban-hello-world/.stellar` directory into this project:

```sh
cp -R ../soroban-hello-world/.stellar/ .stellar
```

## Generate an NPM package for the Hello World contract

Before we open the new frontend files, let's generate an NPM package for the Hello World contract. This is our suggested way to interact with contracts from frontends. These generated libraries work with any JavaScript project (not a specific UI like React), and make it easy to work with some of the trickiest bits of Soroban, like encoding [XDR](../../../learn/encyclopedia/contract-development/types/fully-typed-contracts.mdx).

This is going to use the CLI command `stellar contract bindings typescript`:

```bash
stellar contract bindings typescript \
--network testnet \
--contract-id hello_world \
--output-dir packages/hello_world
```

:::tip

Notice that we were able to use the contract alias, `hello_world`, in place of the contract id!

:::

This project is set up as an NPM Workspace, and so the `hello_world` client library was generated in the `packages` directory at `packages/hello_world`.

We attempt to keep the code in these generated libraries readable, so go ahead and look around. Open up the new `packages/hello_world` directory in your editor. If you've built or contributed to Node projects, it will all look familiar. You'll see a `package.json` file, a `src` directory, a `tsconfig.json`, and even a README.

## Call the contract from the frontend

Now let's open up `src/pages/index.astro` and take a look at how the frontend code integrates with the NPM package we created for our contract.

Here we can see that we're importing our generated `helloWorld` client from `../contracts/hello_world`. We're then invoking the `hello` method and adding the result to the page.

```ts title="src/pages/index.astro"
---
import Layout from "../layouts/Layout.astro";
import Card from "../components/Card.astro";
import helloWorld from "../contracts/hello_world";
const { result } = await helloWorld.hello({ to: "you" });
const greeting = result.join(" ");
---

...

<h1>{greeting}</h1>
```

Let's see it in action! Start the dev server:

```bash
npm run dev
```

And open [localhost:4321](http://localhost:4321) in your browser. You should see the greeting from the contract!

You can try updating the `{ to: 'Soroban' }` argument. When you save the file, the page will automatically update.

:::info

When you start up the dev server with `npm run dev`, you will see similar output in your terminal as when you ran `npm run init`. This is because the `dev` script in package.json is set up to run `npm run init` and `astro dev`, so that you can ensure that your deployed contract and your generated NPM package are always in sync. If you want to just start the dev server without the initialize.js script, you can run `npm run astro dev`.

:::