Skip to content
Draft
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
The table of contents is too big for display.
Diff view
Diff view
  •  
  •  
  •  
9 changes: 0 additions & 9 deletions .dockerignore

This file was deleted.

49 changes: 21 additions & 28 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -1,45 +1,38 @@
# See https://help.github.com/articles/ignoring-files/ for more about ignoring files.

# dependencies
# Dependencies
node_modules
.pnp
.pnp.js
.pnpm-store

# testing
coverage

# next.js
.next/
out/
build
dist/

# misc
.DS_Store
*.pem

# debug
npm-debug.log*
yarn-debug.log*
yarn-error.log*

# local env files
# Local env files
.env
!packages/chain/src/environments/*/.env
.env.local
.env.development.local
.env.test.local
.env.production.local

# turbo
# Testing
coverage

# Turbo
.turbo

# vercel
# Vercel
.vercel

# intellij
.idea
starter-kit.iml
# Build Outputs
.next/
out/
build
dist


docker/data
# Debug
npm-debug.log*
yarn-debug.log*
yarn-error.log*

# Misc
.DS_Store
*.pem
1 change: 0 additions & 1 deletion .npmrc
Original file line number Diff line number Diff line change
@@ -1 +0,0 @@
enable-pre-post-scripts=true
2 changes: 1 addition & 1 deletion .nvmrc
Original file line number Diff line number Diff line change
@@ -1 +1 @@
v18
v22.9.0
15 changes: 15 additions & 0 deletions .vscode/launch.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
{
// Use IntelliSense to learn about possible attributes.
// Hover to view descriptions of existing attributes.
// For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387
"version": "0.2.0",
"configurations": [
{
"type": "chrome",
"request": "launch",
"name": "Launch Chrome against localhost",
"url": "http://localhost:8080",
"webRoot": "${workspaceFolder}"
}
]
}
245 changes: 50 additions & 195 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,240 +1,95 @@
# Protokit starter-kit

This repository is a monorepo aimed at kickstarting application chain development using the Protokit framework.
You can learn more about the Protokit framework at the [official documentation](protokit.dev), or at the official [Mina discord](https://discord.gg/minaprotocol).
This is a starter-kit for building a Protokit application chains.

## Quick start

**Prerequisites:**
### Create a new application chain

- Node.js `v18.18` (we recommend using NVM)
- pnpm `v9.8.0`
- nvm
- (optional) For running with persistance / deploying on a server
- docker `>= 24.0`
- docker-compose `>= 2.22.0`
```sh
git clone https://github.com/proto-kit/starter-kit your-application-chain
cd your-application-chain
```

**Run the following commands to get started:**
```zsh
# clone the repository
git clone https://github.com/proto-kit/starter-kit my-chain
cd my-chain
### Install dependencies

# ensures you have the right node.js version
nvm use
# install dependencies
```sh
pnpm install
# starts both the UI and the sequencer (file watcher / live reload enabled)
pnpm env:inmemory dev
```
Visit http://localhost:3000 to view the example UI, or http://localhost:8080/graphql to explore the sequencer's GraphQL APIs.

### Structural overview

The starter kit contains the following files and folders:
```
├── apps
│ └── web // example UI that connects to the app-chain's sequencer
│ ├── components // display components
│ ├── containers // smart components ("containers")
│ └── lib
│ └── stores // data stores for interacting with the app-chain's sequencer
├── docker
│ └── data // mounted as a volume for the docker containers
└── packages
└── chain
├── src // source files for various app-chain modules
│ ├── app-chain // app-chain modules (signers, queries, ...)
│ ├── environments // app-chain environments (inmemory, development, ...)
│ ├── indexer // indexer configuration (graphql server, storage services, ...)
├── processor // processor configuration (handlers, graphql resolvers, graphql server, ...)
│ ├── protocol // protocol modules (transaction fees, ...)
│ ├── runtime // runtime modules (your app-chain's business logic, such as balances)
│ │ └── modules
│ │ └── balances.ts // built-in example runtime module for Balances, with a faucet
│ ├── sequencer // sequencer modules (graphql server, mempool, block production, ...)
└── test // tests for various app-chain components
└── runtime
└── modules
└── balances.test.ts
### Run the Sequencer and UI

```sh
pnpm dev
```

## Environments

The starter-kit offers different environments to run you appchain.
You can use those environments to configure the mode of operation for your appchain depending on which stage of development you are in.
## What's inside?

The starter kit comes with a set of pre-configured environments:
- `inmemory`: Runs everything in-memory without persisting the data. Useful for early stages of runtime development.
- `development`: Runs the sequencer locally and persists all state in databases running in docker.
- `sovereign`: Runs your appchain fully in docker (including the UI) for testnet deployments without settlement or bridging.
This starter-kit is a [Turborepo](https://turbo.build) that includes the following packages/apps:

Every command you execute should follow this pattern:

```
pnpm env:<environment> <command>
```
### Apps and Packages

> This makes sure that everything is set correctly and our tooling knows which environment you want to use.
- `docs`: a [Next.js](https://nextjs.org/) app
- `web`: another [Next.js](https://nextjs.org/) app
- [`@repo/runtime`](./packages/runtime/README.md): Business logic of your application chain
- `@repo/eslint-config`: `eslint` configurations (includes `eslint-config-next` and `eslint-config-prettier`)
- `@repo/typescript-config`: `tsconfig.json`s used throughout the monorepo

### Environment files
### Utilities

Each environment comes with a set of environment variables specified in `.env`. This allows for configuration for the Protokit app-chain stack.
This Turborepo has some additional tools already setup for you:

To learn more about what configuration options are available, check out any of the available env files at `packages/chain/src/environments/<environment>/.env`
- [TypeScript](https://www.typescriptlang.org/) for static type checking
- [ESLint](https://eslint.org/) for code linting
- [Prettier](https://prettier.io) for code formatting

## Development workflow
### Build

### Running tests
To build all apps and packages, run the following command:

```zsh
# run and watch tests for the `chain` package
pnpm env:inmemory run test --filter=chain -- --watchAll
```

### (Optional) Running the containerized dependencies

> This step isn't required if you're using the `inmemory` environment.

```
# run dockerized dependencies in the background
pnpm env:development docker:up -d

# generate prisma clients
pnpm env:development prisma:generate

# migrate database schemas
pnpm env:development prisma:migrate
cd my-turborepo
pnpm build
```

#### Pruning data
### Develop

Persisted data is stored under `docker/data`, you can delete this folder in case you're experiencing issues with persistence and need to reset your environment setup entirely.
To develop all apps and packages, run the following command:

However to prune data during development, you should use the `--pruneOnStartup` CLI option [documented here](#cli-options)

### Running the sequencer

Ensure you've successfully started the dockerized dependencies, generated and migrated all prisma schemas before running the sequencer (or indexer) in the development environment. In case of using the inmemory environment, you don't need to start the dockerized dependencies.

#### With live reload

> ⚠️ Be aware, the dev command will automatically restart your application when your sources change.
> Please keep in mind that running the components below in `dev` mode (with live reload / watchersr) is advisable only when you're working on that specific component. In case you're experiencing issues with watches cross-triggering reload of different components, you can use the `start` command instead.

```zsh
pnpm env:development sequencer:dev --filter=chain
```

#### Without live reload

```zsh
pnpm env:development build --filter=chain
pnpm env:development sequencer:start --filter=chain
cd my-turborepo
pnpm dev
```

### Running the UI

```zsh
pnpm env:development dev --filter=web
```

> You can also build/start the UI as well, instead of using `dev` command with live-reload.


### Running the indexer

⚠️ Indexer only runs with docker-enabled environments, therefore it is not available with the `inmemory` environment
### Remote Caching

```zsh
pnpm env:development indexer:dev --filter=chain
```

Indexer's graphql is available at `http://localhost:8081/graphql`, unless your environment configuraton specifies otherwise.
> [!TIP]
> Vercel Remote Cache is free for all plans. Get started today at [vercel.com](https://vercel.com/signup?/signup?utm_source=remote-cache-sdk&utm_campaign=free_remote_cache).

### Running the processor
Turborepo can use a technique known as [Remote Caching](https://turbo.build/repo/docs/core-concepts/remote-caching) to share cache artifacts across machines, enabling you to share build caches with your team and CI/CD pipelines.

⚠️ Processor only runs with docker-enabled environments, therefore it is not available with the `inmemory` environment
By default, Turborepo will cache locally. To enable Remote Caching you will need an account with Vercel. If you don't have an account you can [create one](https://vercel.com/signup?utm_source=turborepo-examples), then enter the following commands:

```zsh
pnpm env:development processor:dev --filter=chain
```

Processor's graphql is available at `http://localhost:8082/graphql`, unless your environment configuraton specifies otherwise.

### CLI Options

- `logLevel`: Overrides the loglevel used. Also configurable via the `PROTOKIT_LOG_LEVEL` environment variable.
- `pruneOnStartup`: If set, prunes the database before startup, so that your chain is starting from a clean, genesis state. Alias for environment variable `PROTOKIT_PRUNE_ON_STARTUP`

In order to pass in those CLI option, add it at the end of your command like this

`pnpm env:inmemory dev --filter chain -- --logLevel DEBUG --pruneOnStartup`

## Historical data processing (processor)

Starter-kit ships with a preconfigured historical data processor using `@proto-kit/processor`. Example block & transactions handlers are available in `chain/src/processor/handlers/*`. Once the sequencer produces a block, it flows to the indexer for historical storage, and it's picked up by the processor via the indexer graphql API. The processor then runs the specified handlers in order to process the available block & transaction data into the user specified schema. Additionally the processor serves the processed data via a set of auto-generated graphql resolvers.

### Handling transactions

1. Define your database schema at `chain/src/processor/prisma/schema.prisma`
2. Generate the prisma client using `pnpm env:<your_environment_name> run processor:prisma:generate`
3. Generate your database migrations using `pnpm env:<your_environment_name> run processor:prisma:migrate:dev`
4. Write your handlers as shows in `chain/src/processor/handlers/**`
5. Run the processor using `pnpm env:<your_environment_name> run processor:dev` (sequencer & indexer should be running beforehand)

> Processor relies on the sequencer to produce blocks, and the indexer to access them

Once the processor starts, you can observe it query the indexer for blocks from the last processed block (starting at #0) and running the defined onBlock handler for each block.

Finally, you can query the processed data at the indexer's graphql API available at `http://localhost:8082/graphql` (depending on your environment configuration).

### GraphQL API

You can define which resolvers are available in `chain/src/processor/api/resolvers.ts`. By default all available resolvers generated based on your database schema file are used. You must configure additional middlewares, validations etc. yourself. The example configures a simple validation for the `take` argument for resolvers returning multiple entities at once.

## Deployments (sovereign environment)

When deploying to a server, you should push your code along with your forked starter-kit to some repository,
then clone it on your remote server and execute it.

> Don't forget to run `pnpm env:sovereign docker:build` to build the required images.

```zsh
# start every component with docker
pnpm env:sovereign docker:up -d
cd my-turborepo
npx turbo login
```

UI will be accessible at `https://localhost` and GQL inspector will be available at `https://localhost/graphql` (sequencer), `https://localhost/indexer/graphql` (indexer) and `https://localhost/processor/graphql` (processor)
This will authenticate the Turborepo CLI with your [Vercel account](https://vercel.com/docs/concepts/personal-accounts/overview).

### Configuration
Next, you can link your Turborepo to your Remote Cache by running the following command from the root of your Turborepo:

Go to `docker/proxy/Caddyfile` and replace the `*` matcher with your domain.
```
yourdomain.com {
...
}
npx turbo link
```

> HTTPS is handled automatically by Caddy, you can (learn more about automatic https here.)[https://caddyserver.com/docs/automatic-https]

In most cases, you will need to change the `NEXT_PUBLIC_PROTOKIT_GRAPHQL_URL` property in the `.env` file to the domain your graphql endpoint is running in.
By default, the graphql endpoint is running on the same domain as your UI with the `/graphql` suffix.

### Running sovereign chain locally

The caddy reverse-proxy automatically uses https for all connections, use this guide to remove certificate errors when accessing localhost sites

<https://caddyserver.com/docs/running#local-https-with-docker>


## Building the framework from source
## Useful Links

1. Make sure the framework is located under ../framework from the starter-kit's location
2. Adapt your starter-kit's package.json to use the file:// references to framework
3. Go into the framework folder, and build a docker image containing the sources with `docker build -f ./packages/deployment/docker/development-base/Dockerfile -t protokit-base .`
Learn more about the power of Turborepo:

4. Comment out the first line of docker/base/Dockerfile to use protokit-base
- [Tasks](https://turbo.build/repo/docs/core-concepts/monorepos/running-tasks)
- [Caching](https://turbo.build/repo/docs/core-concepts/caching)
- [Remote Caching](https://turbo.build/repo/docs/core-concepts/remote-caching)
- [Filtering](https://turbo.build/repo/docs/core-concepts/monorepos/filtering)
- [Configuration Options](https://turbo.build/repo/docs/reference/configuration)
- [CLI Usage](https://turbo.build/repo/docs/reference/command-line-reference)
Loading