This is a mono repo forked from ink!athon for dapp development on Aleph Zero.
The frontend works out of the box, without a local node running, as the sample contract is pre-deployed on certain live testnets (i.e. alephzero-testnet
). Necessary deployment metadata and addresses are provided under contracts/deployments/
.
Pre-requisites:
- Setup Node.js v18+ (recommended via nvm with
nvm install 18
)- Install pnpm (recommended via Node.js Corepack or
npm i -g pnpm
)- Clone this repository
Special Instructions for Windows Users
[!IMPORTANT]
Windows users must either use WSL (recommended) or a custom shell like Git Bash. PowerShell is not supported.
Pre-requisites when using WSL for Linux:
- Install WSL and execute all commands in the WSL terminal
- Setup Node.js v18+ (recommended via nvm with
nvm install 18
)- Install the following npm packages globally:
npm i -g npm
npm i -g pnpm node-gyp make
- Clone this repository into the WSL file system (e.g.
/home/<user>/inkathon
).Tip: You can enter
\\wsl$\
in the top bar of the Windows Explorer to access the WSL file system visually.
# Install dependencies (once)
# NOTE: This automatically creates an `.env.local` file
pnpm install
# Start Next.js frontend
pnpm run dev
Optionally, to enable simple-git-hooks
(for automatic linting & formatting when committing), you can run the following command once: pnpm simple-git-hooks
.
The contracts/package.json
file contains shorthand scripts for building, testing, and deploying your contracts. To run these scripts, you need to set contracts/
as the active working directory in your terminal.
Pre-requisites:
- Install Rust and Ink via the Aleph Zero Docs
- Optional: Install
substrate-contracts-node
for running local substrate node
# Build contracts and move artifacts to `contracts/deployments/{contract}/` folders
pnpm run build
# Start local node with persistence (contracts stay deployed after restart)
# NOTE: When using Brave, shields have to be taken down for the UIs
pnpm run node
## IMPORTANT: Open a separate terminal window and keep the node running
# Forks Aleph Zero Testnet and runs it locally
pnpm run fork-testnet
# Deploy the contracts on the local node
pnpm run deploy
Alternatively, you can also deploy contracts manually using Contracts UI (pnpm contracts-ui
) in the browser.
Open the frontend/.env.local
file and set the NEXT_PUBLIC_DEFAULT_CHAIN
variable to development
. Then restart the frontend and you should be able to interact with the contracts deployed on your local node.
Read more about environment variables and all available chain constants in the Environment Variables section below.
Smart contract tests written with Jest are located in /contracts/test
.
# To run the tests, set contracts as the active working directory
cd contracts
# Run all test suites
pnpm test
# Run specific test suite abaxcaller
pnpm test abaxcaller
Warning
After the tests are completed, close the terminal running the fork before restarting the tests.
Spinning up a deployment via Vercel is pretty straightforward as the necessary settings are already configured in vercel.json
. If you haven't cloned the repository yet, you can also use the Deploy button below to create a new repository from this template.
One key element making this boilerplate so flexible is the usage of environment variables to configure the active network in the frontend. This is done by setting the NEXT_PUBLIC_DEFAULT_CHAIN
variable in the frontend/.env.local
file, or in the Vercel deployment settings respectively.
All Supported Chain Constants
Network Identifier | Name | Type |
---|---|---|
development |
οΈLocal Development Node | Testnet |
alephzero-testnet |
Aleph Zero Testnet | Testnet |
rococo |
Rococo | Testnet |
shibuya |
Shibuya Testnet | Testnet |
shiden |
Shiden | Mainnet |
alephzero |
Aleph Zero | Mainnet |
astar |
Astar | Mainnet |
Source: https://github.com/scio-labs/use-inkathon/blob/main/src/chains.ts
[!NOTE]
Chains can also be supplied manually by creating aSubstrateChain
object. If you think a chain is missing, please open an issue or PR.
All environment variables are imported from process.env
in frontend/src/config/environment.ts
for type safety.
Environment Variables | Default Values | Description |
---|---|---|
NEXT_PUBLIC_DEFAULT_CHAIN *οΈβ£ |
οΈalephzero-testnet |
The network (Substrate-based chain) the frontend should connect to by default and what contract deployment artifacts to import. |
NEXT_PUBLIC_PRODUCTION_MODE |
false |
Optional boolean flag to differentiate production environment (e.g. for SEO or Analytics). |
NEXT_PUBLIC_URL |
http://localhost:3000 |
Optional string that defines the base URL of the frontend (will be auto-inferred from Vercel environment variables). |
NEXT_PUBLIC_SUPPORTED_CHAINS |
β | Optional array with network identifers (e.g. ["alephzero-testnet", "alephzero"] ) that are supported by the frontend, if the dApp is supposed to be multi-chain. |
*οΈβ£ Required
In the Getting Started section above, we've already deployed the sample contracts on a local node. To target a live network, we can use the CHAIN
environment variable when running the deploy
script.
CHAIN=alephzero-testnet pnpm run deploy
Further, dynamically loaded environment files with the .env.{chain}
naming convention can be used to add additional configuration about the deployer account.
# .env.alephzero-testnet
ACCOUNT_URI=bottom drive obey lake curtain smoke basket hold race lonely fit walk//Alice
When running the same script again, this deployer account defined there will be used to sign the extrinsic.
Warning
These files are gitignored by default, but you should still be extra cautious when adding sensitive information to them.
There are multiple places where you need to insert your project's name and identifier. Most of these occurrences are highlighted with a /* TODO */
comment in the code. You can easily replace them one by one by installing the todo-tree
plugin.
Additionally, there are the following un-highlighted occurrences:
- the name of the
inkathon.code-workspace
file - the
package.json
's name & metadata in the root directory as well as in thecontracts/
andfrontend/
packages - the workspace dependency (
@inkathon/contracts
) defined infrontend/package.json
and imported infrontend/src/deployments/deployments.ts
To add a new one, you need to do the following:
- Add a new contract directory under
contracts/src/
- Add it as another workspace member to the
contracts/Cargo.toml
file - Adjust the deployment script
contracts/scripts/deploy.ts
- Adjust the
ContractIds
enum andgetDeployments
function infrontend/src/deployments/deployments.ts
Adding custom scripts is useful to interact with your contracts or test certain functionality. Therefore, just duplicate & reuse the contracts/scripts/script.template.ts
file and run it via pnpm run script <script-name>
. This command will run the TypeScript file directly via tsx
.
For general scripts, the same environment variable initialization & configuration applies as described below in the Deployment section (e.g. to change the target network).
- Monorepo Workspace with
contracts/
andfrontend/
directories as packages. - Package Manager:
pnpm
oryarn@stable
(Read more in the FAQs section below) - Smart Contract Development: Rust, ink!,
cargo-contract
,substrate-contracts-node
- Frontend: Next.js, React, TypeScript
- Contract Interactions:
polkadot-js
,useInkathon
React Hooks & Utility Library (alternatively:useInk
) - Styling:
chakra
,tailwindcss
,twin.macro
,emotion
- Linting & Formatting:
eslint
,prettier
,simple-git-hooks
,lint-staged
- Contract Interactions:
Styling, linting, and formatting libraries can be fully dropped or replaced with alternatives.
Additionally, the VSCode plugins listed below are recommended as they can be very helpful when working with this boilerplate.
All Recommended Plugins
Plugin Name | Description |
---|---|
dbaeumer.vscode-eslint |
Adds ESLint editor support. |
esbenp.prettier-vscode |
Adds Prettier editor support. |
bradlc.vscode-tailwindcss |
Adds tailwindcss editor support. |
lightyen.tailwindcss-intellisense-twin |
Adds twin.macro editor support. |
rust-lang.rust-analyzer |
Adds Rust language support. |
ink-analyzer.ink-analyzer |
Adds ink! language support. |
tamasfe.even-better-toml |
Adds .toml file support. |
gruntfuggly.todo-tree |
Lists all TODO comments in your workspace. |
wayou.vscode-todo-highlight |
Lists all TODO comments in your workspace. |
mikestead.dotenv |
Adds syntax highlighting for .env files. |
Which package managers are supported? Do I have to use pnpm?
For monorepo workspaces, pnpm is likely the fastest and most reliable choice. When using it though, it's strongly recommended everyone on the team uses it. No installs should be performed nor any other lock files should be committed.
As an alternative, yarn is also supported and can be used for installation. Caveats when using yarn:
- Only the stable version of yarn (currently v3) is supported, not yarn classic (v1).
yarn.lock
files should be committed instead of.pnpm-lock.yaml
files.- The
pnpm
CLI is still used in manypackage.json
scripts, so these would have to be adjusted manually.
[!IMPORTANT]
As npm lacks support for theworkspace
import protocol, it's not compatible with ink!athon.
How to solve `Cannot find module './greeter/development.ts'`?
Sometimes, Next.js doesn't pick up changes (i.e. file creations) in the contracts/deployments/{contract}/
folders correctly. E.g., when you just deployed on a local node for the first time and set the frontend's .env.local
to connect to the development
network.
To fix this, you can delete the build cache at frontend/.next
. This is currently the only solution and will force Next.js to rebuild the project and pick up the new files.
[!NOTE]
To prevent this behavior, thecontracts/package.json
file contains a smallpostinstall
script that creates an emptydevelopment.ts
file if none exists.
How to approach styling?
This boilerplate currently offers styling via the following options.
- Chakra UI β Component library for quick prototyping e.g. during hackathons)
- twin.macro β Tailwindcss within Styled Components via Emotion (see snippets)
- Standard (S)CSS styles via
className
and*.module.(s)css
files.
[!IMPORTANT]
To reduce the bundle size in production, it's recommended to use either option 1 or 2, but not both.
Can I just use plain TailwindCSS?
The packages mentioned above can be replaced with vanilla TailwindCSS manually without much effort.
[!NOTE]
We are currently transitioning from twin.macro to vanilla TailwindCSS as the new default. This will be reflected in the boilerplate soon.