> For the complete documentation index, see [llms.txt](https://docs.lumia.org/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://docs.lumia.org/build-on-lumia/smart-contracts/deploy-a-contract-with-hardhat.md).

# Deploy a contract with Hardhat

**Who this is for:** developers deploying a Solidity contract to Lumia with Hardhat. If you haven't set up a Hardhat project at all yet, follow [Quickstart: your first contract on Lumia](file:///5838283/Quickstart-your-first-contract-on-Lumia.md) instead. It covers this same ground end to end.

**Prerequisites:** a Hardhat project with your contract already written and compiling; a wallet funded on the network you're targeting. See [Get testnet tokens](file:///5838283/environment/Get-testnet-tokens-faucet.md) for Beam.

**Time:** a few minutes once your contract compiles.

{% stepper %}
{% step %}

#### 1. Add a network entry to `hardhat.config.js`

Pull the RPC URL and chain ID from [`/reference/networks`](file:///reference/Networks-and-endpoints.md) via an environment variable rather than a hardcoded literal:

{% code title="hardhat.config.js" %}

```js
require("@nomicfoundation/hardhat-toolbox");
require("dotenv").config();

module.exports = {
  solidity: "0.8.24",
  networks: {
    lumiaBeam: {
      url: process.env.LUMIA_BEAM_RPC_URL, // from /reference/networks
      chainId: 2030232745,
      accounts: [process.env.PRIVATE_KEY],
    },
  },
};
```

{% endcode %}
{% endstep %}

{% step %}

#### 2. Set `LUMIA_BEAM_RPC_URL` and `PRIVATE_KEY` in a `.env` file

Never commit this file. Copy the RPC value from [`/reference/networks`](file:///reference/Networks-and-endpoints.md).
{% endstep %}

{% step %}

#### 3. Write a deploy script under `scripts/`

```js
const hre = require("hardhat");

async function main() {
  const Factory = await hre.ethers.getContractFactory("YourContract");
  const contract = await Factory.deploy(/* constructor args */);
  await contract.waitForDeployment();
  console.log("Deployed to:", await contract.getAddress());
}

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

{% endstep %}

{% step %}

#### 4. Run it

```bash
npx hardhat run scripts/deploy.js --network lumiaBeam
```

{% endstep %}
{% endstepper %}

## Verify it worked

The script prints a deployed address. Search that address on the Beam explorer (see [Block explorers](file:///5838283/environment/Block-explorers.md)) and confirm a confirmed contract-creation transaction.

## Troubleshooting

<details>

<summary><code>insufficient funds for intrinsic transaction cost</code></summary>

Your deployer address has no balance on the network you targeted. Fund it: see [Get testnet tokens](file:///5838283/environment/Get-testnet-tokens-faucet.md).

</details>

<details>

<summary><code>invalid chain id</code> or chain ID mismatch</summary>

The RPC URL in your `.env` doesn't match the `chainId` in `hardhat.config.js`. Recheck both against the same row of [`/reference/networks`](file:///reference/Networks-and-endpoints.md).

</details>

<details>

<summary>Deploy hangs indefinitely</summary>

You're likely pointed at a dead RPC, commonly the retired `1952959480` network rather than Beam. See [`/reference/retired-testnet`](file:///reference/Retired-testnet-1952959480.md).

</details>

<details>

<summary><code>nonce too low</code></summary>

A previous deploy attempt is still pending from the same address; wait for it to clear or reset the nonce.

</details>
