> ## Documentation Index
> Fetch the complete documentation index at: https://docs.stablenet.network/llms.txt
> Use this file to discover all available pages before exploring further.

# Deploy a Contract with Hardhat

> Configure Hardhat for StableNet Testnet and deploy a WKRC payment contract using ethers.js.

> Deploy a Solidity contract to StableNet Testnet using Hardhat and verify it on the Explorer.

## What you'll learn

By the end of this tutorial, you'll be able to:

* Configure Hardhat and `hardhat.config.js` for StableNet Testnet
* Deploy a WKRC payment contract using a Hardhat deploy script
* Verify the deployment on the StableNet Explorer

## Prerequisites

* Node.js ≥ 18 — run `node --version` to check
* Testnet WKRC from the [Faucet](https://faucet.stablenet.network)

## Create a Hardhat project

```shell theme={null}
mkdir stablenet-hardhat && cd stablenet-hardhat
npm init -y
npm install --save-dev hardhat @nomicfoundation/hardhat-toolbox dotenv
npx hardhat init
```

When prompted, select **"Create a JavaScript project"**.

<Warning>
  Store your private key in a `.env` file and add it to `.gitignore`. Never commit it to version control.
</Warning>

```shell theme={null}
echo "PRIVATE_KEY=0xYourPrivateKey" > .env
echo ".env" >> .gitignore
```

## Configure hardhat.config.js

Replace the contents of `hardhat.config.js`:

```javascript theme={null}
require("@nomicfoundation/hardhat-toolbox");
require("dotenv").config();

module.exports = {
  solidity: {
    version: "0.8.20",
    settings: {
      // StableNet does not support blob opcodes — do not use cancun
      evmVersion: "shanghai",
    },
  },
  networks: {
    stablenet_testnet: {
      url: "https://api.test.stablenet.network",
      chainId: 8283,
      accounts: [process.env.PRIVATE_KEY],
    },
  },
};
```

<Warning>
  Do not set `evmVersion` to `cancun`. StableNet does not support blob opcodes (`BLOBHASH`, `BLOBBASEFEE`). Use `paris` or `shanghai`.
</Warning>

## Write WKRCPayment.sol

Delete the placeholder and create `contracts/WKRCPayment.sol`:

```shell theme={null}
rm contracts/Lock.sol
```

```solidity theme={null}
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.20;

interface IERC20 {
    function transferFrom(address from, address to, uint256 amount) external returns (bool);
    function allowance(address owner, address spender) external view returns (uint256);
}

/// @title WKRCPayment
/// @notice Accepts WKRC payments from an approved sender.
contract WKRCPayment {
    /// @dev NativeCoinAdapter (WKRC) — fixed system contract address on StableNet.
    IERC20 public constant WKRC =
        IERC20(0x0000000000000000000000000000000000001000);

    event Payment(address indexed from, address indexed to, uint256 amount);

    /// @notice Pull `amount` of WKRC from msg.sender and forward it to `to`.
    ///         Requires prior WKRC.approve(address(this), amount).
    function pay(address to, uint256 amount) external {
        require(WKRC.transferFrom(msg.sender, to, amount), "WKRC transfer failed");
        emit Payment(msg.sender, to, amount);
    }

    function allowanceOf(address owner) external view returns (uint256) {
        return WKRC.allowance(owner, address(this));
    }
}
```

```shell theme={null}
npx hardhat compile
```

```text theme={null}
Compiled 1 Solidity file successfully (evm target: shanghai).
```

## Write the deploy script

Create `scripts/deploy.js`:

```javascript theme={null}
const { ethers } = require("hardhat");

async function main() {
  const [deployer] = await ethers.getSigners();
  console.log("Deploying with:", deployer.address);

  const WKRCPayment = await ethers.getContractFactory("WKRCPayment");

  // StableNet requires maxPriorityFeePerGas on every transaction
  const contract = await WKRCPayment.deploy({
    maxPriorityFeePerGas: ethers.parseUnits("27600", "gwei"),
    maxFeePerGas: ethers.parseUnits("80000", "gwei"),
  });

  await contract.waitForDeployment();
  console.log("WKRCPayment deployed to:", await contract.getAddress());
}

main().catch((error) => {
  console.error(error);
  process.exitCode = 1;
});
```

<Warning>
  You must pass `maxPriorityFeePerGas` and `maxFeePerGas` on every deploy and send call. Hardhat does not pick up the network-enforced minimum automatically — omitting them causes the transaction to be rejected.
</Warning>

## Deploy to Testnet

```shell theme={null}
npx hardhat run scripts/deploy.js --network stablenet_testnet
```

```text theme={null}
Deploying with: 0xYourWalletAddress
WKRCPayment deployed to: 0xABC...
```

<Note>
  Block inclusion can take up to 1–2 minutes. If `waitForDeployment()` appears to hang, the transaction is already in the mempool. Do not cancel and retry — that may cause a nonce conflict.
</Note>

## Verify on Explorer

Open [explorer.stablenet.network](https://explorer.stablenet.network) and search for your contract address. You should see a `Contract Creation` transaction with status **Success**.

## Next steps

<CardGroup cols={2}>
  <Card title="Deploy with Foundry" href="/en/v0.3/build/tutorials/deploy-with-foundry">Deploy the same contract using Foundry's `forge` and `cast`.</Card>
  <Card title="Listen to Events" href="/en/v0.3/build/tutorials/listen-to-events">Subscribe to on-chain events with WebSocket.</Card>
  <Card title="RPC API Reference" href="/en/v0.3/reference/rpc-api">Full list of supported JSON-RPC methods.</Card>
  <Card title="Fee Delegation" href="/en/v0.3/build/tutorials/fee-delegation">Let a separate account pay gas for your users.</Card>
</CardGroup>
