This web application shows several informations about Cartesi Proof of Stake:
- node public address
- node balance
- current node owner
- action to claim a node through metamask
- action to release a node from the current owner
This project pins its toolchain, and CI uses the same versions:
- Node.js 24.21.0 (Active LTS)
- pnpm 11.27.1, declared in
packageManager
pnpm is activated through Corepack, which ships with Node.js 24:
$ corepack enable
$ pnpm --version # 11.27.1
Corepack is still flagged Experimental in Node.js 24 and is not distributed with Node.js 25 or newer. When this project moves past Node.js 24, install pnpm directly instead (e.g.
npm install -g pnpm@11.27.1).
Dependency installs are governed by pnpm-workspace.yaml. Install with:
$ pnpm install --frozen-lockfile
The following supply-chain protections are enabled:
allowBuilds— dependency install scripts are denied unless explicitly listed. When a new dependency needs to run a build script, pnpm reports it and the package has to be added here deliberately.strictDepBuilds: true— the install fails rather than silently skipping a dependency whose build script has not been reviewed.blockExoticSubdeps: true— transitive dependencies may not be pulled from git repositories or tarball URLs, only from the registry.minimumReleaseAge: 10080— a newly published version must be at least 7 days old before it can be resolved, which blunts hijacked-release attacks.trustPolicy: no-downgrade— a package whose trust level drops relative to its previous releases fails the install.
overrides is used to pin transitive dependencies away from vulnerable or
non-registry sources.
The wallet layer lives in src/components/wallet/ and is the only place that
imports RainbowKit and wagmi; the
rest of the application consumes the connection through useWallet(), which
exposes the account, the chain id and the viem publicClient/walletClient.
Swapping the wallet library again means changing that folder only.
config.tsholds the supported chains, the RPC transports and the wallet list shown by the RainbowKit modal: MetaMask, WalletConnect (also the way to reach Ledger Live), Safe and Base (Coinbase Wallet), plus any browser wallet it detects through EIP-6963. RainbowKit renders its own wallet list on mobile, so breadth comes from that list.- Safe only appears when the explorer is loaded as a Safe App (see
public/manifest.json) and connects automatically on load. NEXT_PUBLIC_WALLETCONNECT_PROJECT_ID(WalletConnect Cloud / Reown dashboard) andNEXT_PUBLIC_DAPP_URLare required; the RPC endpoints come fromNEXT_PUBLIC_RPC_URL_<chainId>.- RainbowKit 2 pins wagmi to the 2.x line, which froze when wagmi 3 shipped. The bundled WalletConnect and MetaMask SDK versions move only when RainbowKit adds wagmi 3 support; this is a known, accepted trade-off.
Contracts are called through viem using ABIs and deployment
addresses generated into src/services/contracts/generated.ts (gitignored) by
pnpm gen:abi, part of pnpm codegen together with the Chakra UI type
generation. pnpm dev, pnpm build and CI run codegen first; run it once
after pnpm install before pnpm test or pnpm storybook. wagmi.config.ts
lists every contract and the @cartesi package it comes from. Those packages
and ethers are devDependencies used only by the generator: an ESLint rule
rejects importing them from src/.
Addresses coming from the subgraph are lowercase, while contract reads return
checksummed addresses. Keep comparing account (already lowercase) with
subgraph values as the code does today, and compare contract results with
viem's isAddressEqual rather than ===.
This is a Next.js application which uses smart contracts deployed by the pos-dlib and staking-pool projects. In order to run the application locally you need to:
- Run a localhost hardhat node with all contracts deployed
- Run a local graph node reading from the local hardhat node and deploy the subgraph
- Run the application
- Open application in browser and switch to a local network in MetaMask
This can be done from the staking-pool project by running:
$ cd staking-pool
$ yarn start --export ../explorer/src/services/contracts/localhost.json
This will run a local hardhat node running at http://127.0.0.1:8545/ and deploy all smart contracts. Among the contracts are:
- CartesiToken: the CTSI token contract. Minter is the first account, and holds 1B tokens initially.
- StakingImpl: the staking contract.
- WorkerManagerAuthManagerImpl: used to hire worker nodes.
- PoS: proof of stake smart contract, holds the chains. Starts with no chain created.
- StakingPoolFactoryImpl: factory of new staking pools.
The application uses a subgraph powered by thegraph to consolidate blockchain information and serve using a GraphQL endpoint.
- Clone the graph node from GitHub.
- Copy the file
docker/docker-compose.ymltodocker/docker-compose-localhost.yml - Modify line 20 to
ethereum: 'localhost:http://host.docker.internal:8545/' - Modify line 27 to
./data_localhost/ipfs:/data/ipfs - Modify line 38 to
./data_localhost/postgres:/var/lib/postgresql/data
Then run:
$ cd docker
$ docker-compose -f docker-compose-localhost.yml up
Every time you reset your local hardhat node you will need to delete the data_localhost folder that is created by the docker-compose command before running it again.
The next step is the deploy the subgraph to the local graph node.
Checkout the subgraph project from GitHub.
Then yarn link the project to the local staking-pool project by running yarn link at the staking-pool project and than yarn link @cartesi/staking-pool at the subgraph project.
Then run the following commands:
$ yarn prepare:localhost
$ yarn create:localhost
$ yarn deploy:localhost
There are two files in the explorer project the.env.development and .env.production as reference. You can create a file called .env.development.local that is gitignored so you can add your secrets there.
The next step is to create an account on Infura or any other node-rpc. Create a project so you can have access to a node-rpc endpoint.
On your .env.development.local set the following var:
- NEXT_PUBLIC_RPC_URL_1=your_mainnet_node_rpc_endpoint_goes_here
We support ethereum Mainnet(1), Sepolia(11155111) and Devnet (31337),
Check the .env to see the available variables. additional.d.ts also includes process.env declarations for improved IDE autocomplete.
You can read more about nextJS env vars here
Simply run:
$ pnpm dev
This runs the database migration and pnpm codegen (Chakra UI types and the
contract ABIs) before starting Next.js.
Open the application in your browser at http://localhost:3000 Open MetaMask and switch to a network configured to the url http://localhost:8545 and Chain ID 31337.
We are using Coveralls as a reporting tool for our tests' coverage. We generate coverage report by running the tests using the test:ci npm script. At each build we send the report to Coveralls.
The project use tags that represent releases, including a branch to signal cloud providers to update the production code (e.g. Staking).
That is as follows:
- Combined tag name
v+ SemVer format tag (e.g. v3.4.0) to pinpoint repository state on a given production release.