# Faucet

The Armchain faucet distributes free devnet ARM tokens for development and testing purposes.

## Devnet Faucet

The official devnet faucet is available at:

**<https://www.armchain.org/faucet>** *(coming soon)*

### How to Use

1. Connect to the Armchain devnet (Chain ID: 55)
2. Copy your wallet address
3. Visit the faucet URL
4. Paste your address
5. Click "Request Tokens"
6. Tokens arrive within seconds (instant finality)

### Limits

> **Note**: Drop amount and cooldown period for the devnet faucet are yet to be finalized.

| Parameter          | Value |
| ------------------ | ----- |
| Tokens per request | TBD   |
| Cooldown period    | TBD   |

## Local Development (Fakenet)

For local development, fakenet validators are pre-funded. No faucet needed.

### Pre-funded Accounts

When running a fakenet with a single validator, `--fakenet 1/1`, the validator account is funded with a large ARM balance. Use it as a "faucet" for your tests:

```javascript
import { ethers } from "@armchain-ethersv6/ethers";

const provider = new ethers.JsonRpcProvider("http://localhost:18545");

// The validator account private key (from fakenet genesis)
// Replace with the actual key from your fakenet setup
const faucet = new ethers.Wallet(VALIDATOR_PRIVATE_KEY, provider);

// Send ARM to a test address
async function fund(address) {
  const tx = await faucet.sendTransaction({
    to: address,
    value: ethers.parseEther("100"),
    type: 3,
  });
  await tx.wait();
  console.log(`Funded ${address} with 100 ARM`);
}
```

### Hardhat Local Faucet

> **⚠ Compatibility Warning**: Self-funding via `hre.ethers` or Hardhat's default signers does not work on Armchain. The `deployer.sendTransaction()` pattern uses ECDSA and will be rejected. Use the Armchain Ethers SDK example above instead.

## Programmatic Faucet (Self-Hosted)

For CI/CD pipelines or automated testing, set up a simple faucet script:

```javascript
import { ethers } from "@armchain-ethersv6/ethers";
import express from "express";

const app = express();
app.use(express.json());

const provider = new ethers.JsonRpcProvider("http://localhost:18545");
const faucet = new ethers.Wallet(process.env.FAUCET_KEY, provider);

const cooldowns = new Map();
const AMOUNT = ethers.parseEther("10");
const COOLDOWN_MS = 60 * 60 * 1000; // 1 hour

app.post("/fund", async (req, res) => {
  const { address } = req.body;

  if (!ethers.isAddress(address)) {
    return res.status(400).json({ error: "Invalid address" });
  }

  const lastRequest = cooldowns.get(address);
  if (lastRequest && Date.now() - lastRequest < COOLDOWN_MS) {
    return res.status(429).json({ error: "Rate limited" });
  }

  try {
    const tx = await faucet.sendTransaction({
      to: address,
      value: AMOUNT,
      type: 3,
    });
    await tx.wait();
    cooldowns.set(address, Date.now());
    res.json({ txHash: tx.hash });
  } catch (err) {
    res.status(500).json({ error: err.message });
  }
});

app.listen(3000, () => console.log("Faucet running on :3000"));
```

## Further Reading

* [Fakenet Setup](/node-operators/fakenet.md) to run a local development network
* [Network Configuration](/get-started/network-configuration.md) to connect to devnet
* [Quickstart](/get-started/quickstart.md) to deploy your first contract


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://docs.armchain.org/tools/faucet.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
