Skip to Content

Hardhat

This page sets up a Hardhat 3  project for SupraEVM on Devnet, deploys a contract with a script and calls it. Hardhat 3 needs Node.js  22.13 or later. The deploying address must hold SUPRA; see Funding an account.

Create a project

mkdir supra-storage cd supra-storage npx hardhat@3 --init --template mocha-ethers

The mocha-ethers template uses ethers.js and installs its dependencies. Run npx hardhat --init without --template to choose a template interactively.

Configure the project

In hardhat.config.ts, add evmVersion: "osaka" to the settings of each Solidity build profile, and add a supraDevnet entry to the template’s networks object. The listing shows the profiles and the supraDevnet entry; the template’s other networks stay in place:

import hardhatToolboxMochaEthersPlugin from '@nomicfoundation/hardhat-toolbox-mocha-ethers' import { configVariable, defineConfig } from 'hardhat/config' export default defineConfig({ plugins: [hardhatToolboxMochaEthersPlugin], solidity: { profiles: { default: { version: '0.8.34', settings: { evmVersion: 'osaka', }, }, production: { version: '0.8.34', settings: { evmVersion: 'osaka', optimizer: { enabled: true, runs: 200, }, }, }, }, }, networks: { // ...the template's existing networks, unchanged supraDevnet: { type: 'http', chainType: 'l1', url: 'https://rpc-devnet.supra.com/rpc/v1/eth/wallet_integration', chainId: 535600, accounts: [configVariable('SUPRA_DEVNET_PRIVATE_KEY')], }, }, })
  • evmVersion: "osaka" compiles for Osaka, the EVM version SupraEVM targets. Governance sets it; 0x1::evm_config::current_spec returns the version in force (2 is Osaka). Hardhat’s default EVM version depends on the Hardhat and compiler releases, so set it explicitly. EVM version lists the versions that execute here.
  • url is the wallet-integration endpoint, which answers requests that name a block other than the head; see Which endpoint to use.
  • chainId makes Hardhat check that the endpoint serves chain 535600 before it signs anything.
  • configVariable reads the deploying key from Hardhat’s encrypted keystore, so it is never written into the project.

Keep the template’s hardhatMainnet and hardhatOp networks for local tests, or remove them and the scripts that use them.

Store the deploying key

npx hardhat keystore set SUPRA_DEVNET_PRIVATE_KEY

The command prompts for a keystore password, and on the first use asks for it a second time to confirm it; the password must have at least 8 characters. It then prompts for the private key. Hardhat prompts for the password again when a command uses the supraDevnet network. To use a StarKey account, export its EVM private key as described in Exporting a private key.

Write a contract

Create contracts/SimpleStorage.sol:

// SPDX-License-Identifier: MIT pragma solidity ^0.8.0; contract SimpleStorage { uint256 public storedData; function set(uint256 x) public { storedData = x; } function get() public view returns (uint256) { return storedData; } }
npx hardhat build

The build reports evm target: osaka.

Deploy the contract

Create scripts/deploy.ts:

import { network } from 'hardhat' const { ethers } = await network.create() const storage = await ethers.deployContract('SimpleStorage') await storage.waitForDeployment() console.log('SimpleStorage deployed to:', await storage.getAddress())
npx hardhat run scripts/deploy.ts --network supraDevnet

network.create() connects to the network named by --network. The ethers plugin takes the fee from the endpoint’s fee data, which is at or above the gas price floor. A script that sets maxFeePerGas or gasPrice itself must stay at or above the floor.

Call the contract

Create scripts/interact.ts, with the address the deployment printed:

import { network } from 'hardhat' const { ethers } = await network.create() const storage = await ethers.getContractAt('SimpleStorage', '<CONTRACT_ADDRESS>') const tx = await storage.set(42) await tx.wait() console.log('Stored value:', await storage.get())
npx hardhat run scripts/interact.ts --network supraDevnet

set sends a transaction; get is a view function, read through eth_call without a transaction. Both transactions appear on the Devnet explorer  under the contract’s address.

Last updated on