• Stars
    star
    467
  • Rank 90,830 (Top 2 %)
  • Language
    TypeScript
  • License
    Other
  • Created about 2 years ago
  • Updated about 1 month ago

Reviews

There are no reviews yet. Be the first to send feedback to the community and the maintainers!

Repository Details

Avalanche Faucet for Fuji Network and Subnets.

Avalanche Subnet Faucet

Right now there are thousands of networks and chains in the blockchain space, each with its capabilities and use-cases. And each network requires native coins to do any transaction on them, which can have a monetary value as well. These coins can be collected through centralized exchanges, token sales, etc in exchange for some monetary assets like USD.

But we cannot risk our funds on the network or on any applications hosted on that network, without testing them first. So, these networks often have test networks or testnets, where the native coins do not have any monetary value, and thus can be obtained freely through faucets.

These testnets are often the testbeds for any new native feature of the network itself, or any dApp or Subnet that is going live on the main network (mainnet). For example, Fuji network is the testnet for Avalanche's mainnet.

Besides Fuji Testnet, Avalanche Faucet can be used to get free coins on these testnets Subnets like -

You can use this repository to deploy your faucet or just make a PR with the configurations of the Subnet. This faucet comes with many features like multiple chain support, custom rate-limiting per Subnet, captcha verification, and concurrent transaction handling.

TL;DR

A Faucet powered by Avalanche for Fuji Network and other Subnets. You can -

  • Request test coins for the supported Subnets
  • Integrate your EVM Subnet with the faucet by making a PR with the chain configurations
  • Fork the repository to deploy your faucet for any EVM chain

Adding a New Subnet

You can also integrate a new Subnet on the live faucet with just a few lines of configuration parameters. All you have to do is make a PR on the Avalanche Faucet git repository with the Subnet's information. The following parameters are required.

{
    "ID": "string",
    "NAME": "string",
    "TOKEN": "string",
    "RPC": "string",
    "CHAINID": "number",
    "EXPLORER": "string",
    "IMAGE": "string",
    "MAX_PRIORITY_FEE": "string",
    "MAX_FEE": "string",
    "DRIP_AMOUNT": "number",
    "RATELIMIT": {
        "MAX_LIMIT": "number",
        "WINDOW_SIZE": "number"
    }
}
  • ID - Each subnet chain should have a unique and relatable ID.
  • NAME - Name of the Subnet chain that will appear on the website.
  • RPC - A valid RPC URL for accessing the chain.
  • CHAINID - Chain ID of the chain
  • EXPLORER - Base URL of standard explorer's website.
  • IMAGE - URL of the icon of the chain that will be shown in the dropdown.
  • MAX_PRIORITY_FEE - Maximum tip per faucet drop in wei or 10-18 unit (for EIP1559 supported chains)
  • MAX_FEE - Maximum fee that can be paid for a faucet drop in wei or 10-18 unit
  • DRIP_AMOUNT - Amount of coins to send per request in gwei or 10-9 unit
  • RECALIBRATE (optional) - Number of seconds after which the nonce and balance will recalibrate
  • RATELIMIT - Number of times (MAX_LIMIT) to allow per user within the WINDOW_SIZE (in minutes)

Add the configuration in the array of evmchains inside the config.json file and make a PR.

Building and Deploying a Faucet

You can also deploy and build your faucet by using the Avalanche Faucet repository.

Requirements

Installation

Clone this repository at your preferred location.

git clone https://github.com/ava-labs/avalanche-faucet

Client Side Configurations

We need to configure our application with the server API endpoints and Captcha site keys. All the client-side configurations are there in the client/src/config.json file. Since there are no secrets on the client-side, we do not need any environment variables. Update the config files according to your need.

{
    "banner": "/banner.png",
    "apiBaseEndpointProduction": "/api/",
    "apiBaseEndpointDevelopment": "http://localhost:8000/api/",
    "apiTimeout": 10000,
    "CAPTCHA": {
        "siteKey": "6LcNScYfAAAAAJH8fauA-okTZrmAxYqfF9gOmujf",
        "action": "faucetdrip"
    }
}

Put the Google's ReCaptcha site-key without which the faucet client can't send the necessary captcha response to the server. This key is not a secret and could be public.

In the above file, there are 2 base endpoints for the faucet server apiBaseEndpointProduction and apiBaseEndpointDevelopment.

In production mode, the client-side will be served as static content over the server's endpoint, and hence we do not have to provide the server's IP address or domain.

The URL path should be valid, where the server's APIs are hosted. If the endpoints for API have a leading /v1/api and the server is running on localhost at port 3000, then you should use http://localhost:3000/v1/api or /v1/api/ depending on whether it is production or development.

Server-Side Configurations

On the server side, we need to configure 2 files - .env for secret keys and config.json for chain and API's rate limiting configurations.

Setup Environment Variables

Setup the environment variable with your private key and ReCaptcha secret. Make a .env file in your preferred location with the following credentials, as this file will not be committed to the repository. The faucet server can handle multiple EVM chains, and therefore requires private keys for addresses with funds on each of the chains.

If you have funds on the same address on every chain, then you can specify them with the single variablePK. But if you have funds on different addresses on different chains, then you can provide each of the private keys against the ID of the chain, as shown below.

C="C chain private key"
WAGMI="Wagmi chain private key"
PK="Sender Private Key with Funds in it"
CAPTCHA_SECRET="Google ReCaptcha Secret"

PK will act as a fallback private key, in case, the key for any chain is not provided.

Setup EVM Chain Configurations

You can create a faucet server for any EVM chain by making changes in the config.json file. Add your chain configuration as shown below in the evmchains object. Configuration for Fuji's C-Chain and WAGMI chain is shown below for example.

"evmchains": [
    {
        "ID": "C",
        "NAME": "Fuji (C-Chain)",
        "TOKEN": "AVAX",
        "RPC": "https://api.avax-test.network/ext/C/rpc",
        "CHAINID": 43113,
        "EXPLORER": "https://testnet.snowtrace.io",
        "IMAGE": "/avaxred.png",
        "MAX_PRIORITY_FEE": "2000000000",
        "MAX_FEE": "100000000000",
        "DRIP_AMOUNT": 2000000000,
        "RECALIBRATE": 30,
        "RATELIMIT": {
            "MAX_LIMIT": 1,
            "WINDOW_SIZE": 1440
        }
    },
    {
        "ID": "WAGMI",
        "NAME": "WAGMI Testnet",
        "TOKEN": "WGM",
        "RPC": "https://subnets.avax.network/wagmi/wagmi-chain-testnet/rpc",
        "CHAINID": 11111,
        "EXPLORER": "https://subnets.avax.network/wagmi/wagmi-chain-testnet/explorer",
        "IMAGE": "/wagmi.png",
        "MAX_PRIORITY_FEE": "2000000000",
        "MAX_FEE": "100000000000",
        "DRIP_AMOUNT": 2000000000,
        "RATELIMIT": {
            "MAX_LIMIT": 1,
            "WINDOW_SIZE": 1440
        }
    }
]

In the above configuration drip amount is in nAVAX or gwei, whereas fees are in wei. For example, with the above configurations, the faucet will send 1 AVAX with maximum fees per gas being 100 nAVAX and priority fee as 2 nAVAX.

The rate limiter for C Chain will only accept 1 request in 60 minutes for a particular API and 2 requests in 60 minutes for the WAGMI chain. Though it will skip any failed requests so that users can request tokens again, even if there is some internal error in the application. On the other hand, the global rate limiter will allow 15 requests per minute on every API. This time failed requests will also get counted so that no one can abuse the APIs.

API Endpoints

This server will expose the following APIs

Health API

The /health API will always return a response with a 200 status code. This endpoint can be used to know the health of the server.

curl http://localhost:8000/health

Response

Server healthy

Get Faucet Address

This API will be used for fetching the faucet address.

curl http://localhost:8000/api/faucetAddress?chain=C

It will give the following response

0x3EA53fA26b41885cB9149B62f0b7c0BAf76C78D4

Get Faucet Balance

This API will be used for fetching the faucet address.

curl http://localhost:8000/api/getBalance?chain=C

It will give the following response

14282900936

Send Token

This API endpoint will handle token requests from users. It will return the transaction hash as a receipt of the faucet drip.

curl -d '{
        "address": "0x3EA53fA26b41885cB9149B62f0b7c0BAf76C78D4"
        "chain": "C"
}' -H 'Content-Type: application/json' http://localhost:8000/api/sendToken

Send token API requires a Captcha response token that is generated using the Captcha site key on the client-side. Since we can't generate and pass this token while making a curl request, we have to disable the captcha verification for testing purposes. You can find the steps to disable it in the next sections. The response is shown below

{
    "message": "Transaction successful on Avalanche C Chain!",
    "txHash": "0x3d1f1c3facf59c5cd7d6937b3b727d047a1e664f52834daf20b0555e89fc8317"
}

Rate Limiters (Important)

The rate limiters are applied on the global (all endpoints) as well as on the /api/sendToken API. These can be configured from the config.json file. Rate limiting parameters for chains are passed in the chain configuration as shown above.

"GLOBAL_RL": {
    "ID": "GLOBAL",
    "RATELIMIT": {
        "REVERSE_PROXIES": 4,
        "MAX_LIMIT": 40,
        "WINDOW_SIZE": 1,
        "PATH": "/",
        "SKIP_FAILED_REQUESTS": false
    }
}

There could be multiple proxies between the server and the client. The server will see the IP address of the adjacent proxy connected with the server, and this may not be the client's actual IP.

The IPs of all the proxies that the request has hopped through are stuffed inside the header x-forwarded-for array. But the proxies in between can easily manipulate these headers to bypass rate limiters. So, we cannot trust all the proxies and hence all the IPs inside the header.

The proxies that are set up by the owner of the server (reverse-proxies) are the trusted proxies on which we can rely and know that they have stuffed the actual IP of the requesters in between. Any proxy that is not set up by the server, should be considered an untrusted proxy. So, we can jump to the IP address added by the last proxy that we trust. The number of jumps that we want can be configured in the config.json file inside the GLOBAL_RL object.

Clients Behind Same Proxy

Consider the below diagram. The server is set up with 2 reverse proxies. If the client is behind proxies, then we cannot get the client's actual IP, and instead will consider the proxy's IP as the client's IP. And if some other client is behind the same proxy, then those clients will be considered as a single entity and might get rate-limited faster.

Therefore it is advised to the users, to avoid using any proxy for accessing applications that have critical rate limits, like this faucet.

Wrong Number of Reverse Proxies

So, if you want to deploy this faucet, and have some reverse proxies in between, then you should configure this inside the GLOBAL_RL key of the config.json file. If this is not configured properly, then the users might get rate-limited very frequently, since the server-side proxy's IP addresses are being viewed as the client's IP. You can verify this in the code here.

"GLOBAL_RL": {
    "ID": "GLOBAL",
    "RATELIMIT": {
        "REVERSE_PROXIES": 4,
        ...

It is also quite common to have Cloudflare as the last reverse proxy or the exposed server. Cloudflare provides a header cf-connecting-ip which is the IP of the client that requested the faucet and hence Cloudflare. We are using this as default.

Captcha Verification

Captcha is required to prove the user is a human and not a bot. For this purpose, we will use Google's Recaptcha. The server side will require CAPTCHA_SECRET that should not be exposed. You can set the threshold score to pass the captcha test by the users here.

You can disable these Captcha verifications and rate limiters for testing the purpose, by tweaking in the server.ts file.

Disabling Rate Limiters

Comment or remove these 2 lines from the server.ts file

new RateLimiter(app, [GLOBAL_RL]);
new RateLimiter(app, evmchains);

Disabling Captcha Verification

Remove the captcha.middleware from sendToken API.

Starting the Faucet

Follow the below commands to start your local faucet.

Installing Dependencies

This will concurrently install dependencies for both client and server.

npm install

If ports have a default configuration, then the client will start at port 3000 and the server will start at port 8000 while in development mode.

Starting in Development Mode

This will concurrently start the server and client in development mode.

npm run dev

Building for Production

The following command will build server and client at build/ and build/client directories.

npm run build

Starting in Production Mode

This command should only be run after successfully building the client and server-side code.

npm start

Setting up with Docker

Follow the steps to run this application in a Docker container.

Build Docker Image

Docker images can be served as the built versions of our application, that can be used to deploy on Docker container.

docker build . -t faucet-image

Starting Application inside Docker Container

Now we can create any number of containers using the above faucet image. We also have to supply the .env file or the environment variables with the secret keys to create the container. Once the container is created, these variables and configurations will be persisted and can be easily started or stopped with a single command.

docker run -p 3000:8000 --name faucet-container --env-file ../.env faucet-image

The server will run on port 8000, and our Docker will also expose this port for the outer world to interact. We have exposed this port in the Dockerfile. But we cannot directly interact with the container port, so we had to bind this container port to our host port. For the host port, we have chosen 3000. This flag -p 3000:8000 achieves the same.

This will start our faucet application in a Docker container at port 3000 (port 8000 on the container). You can interact with the application by visiting http://localhost:3000 in your browser.

Stopping the Container

You can easily stop the container using the following command

docker stop faucet-container

Restarting the Container

To restart the container, use the following command

docker start faucet-container

Using the Faucet

Using the faucet is quite straightforward, but for the sake of completeness, let's go through the steps, to collect your first test coins.

Visit Avalanche Faucet Website

Go to https://faucet.avax.network. You will see various network parameters like network name, faucet balance, drop amount, drop limit, faucet address, etc.

Select Network

You can use the dropdown to select the network of your choice and get some free coins (each network may have a different drop amount).

Put Address and Request Coins

Put your wallet address where you want to get a drop, and click the Request button. Within a second, you will get a transaction hash for the processed transaction. The hash would be a hyperlink to Subnet's explorer. You can see the transaction status, by clicking on that hyperlink.

More Interactions

This is not just it. Using the buttons shown below, you can go to the Subnet explorer or add the Subnet to your browser wallet extensions like Metamask with a single click.

Probable Errors and Troubleshooting

Errors are not expected, but if you are facing some of the errors shown, then you could try troubleshooting as shown below. If none of the troubleshooting works, reach us through Discord.

  • Too many requests. Please try again after X minutes This is a rate-limiting message. Every Subnet can set its drop limits. The above message suggests that you have reached your drop limit i.e. the number of times you could request coins within the window of X minutes. You should try requesting after X minutes. If you are facing this problem, even when you are requesting for the first time in the window, you may be behind some proxy, WiFi, or VPN service that is also being used by some other user.

  • Captcha verification failed! Try refreshing We are using v3 of Google's ReCaptcha. This version uses scores between 0 and 1 to rate the interaction of humans with the website, with 0 being the most suspicious one. You do not have to solve any puzzle or mark the I am not a Robot checkbox. The score will be automatically calculated. We want our users to score at least 0.3 to use the faucet. This is configurable, and we will update the threshold after having broader data. But if you are facing this issue, then you can try refreshing your page, disabling ad-blockers, or switching off any VPN. You can follow this guide to get rid of this issue.

  • Internal RPC error! Please try after sometime This is an internal error in the Subnet's node, on which we are making an RPC for sending transactions. A regular check will update the RPC's health status every 30 seconds (default) or whatever is set in the configuration. This may happen only in rare scenarios and you cannot do much about it, rather than waiting.

  • Timeout of 10000ms exceeded There could be many reasons for this message. It could be an internal server error, or the request didn't receive by the server, slow internet, etc. You could try again after some time, and if the problem persists, then you should raise this issue on our Discord server.

  • Couldn't see any transaction status on explorer The transaction hash that you get for each drop is pre-computed using the expected nonce, amount, and receiver's address. Though transactions on Avalanche are near-instant, the explorer may take time to index those transactions. You should wait for a few more seconds, before raising any issue or reaching out to us.

More Repositories

1

avalanchego

Go implementation of an Avalanche node.
Go
2,038
star
2

avalanchejs

The Avalanche Platform JavaScript Library
TypeScript
298
star
3

avalanche-smart-contract-quickstart

The easiest way to build smart contracts on Avalanche.
Solidity
248
star
4

avalanche-wallet

The Avalanche web wallet
Vue
229
star
5

subnet-evm

Launch your own EVM as an Avalanche Subnet
Go
227
star
6

mastering-avalanche

Mastering Avalanche 1st Edition - The Internet of Finance
176
star
7

coreth

Code and wrapper to extract Ethereum blockchain functionalities without network/consensus, for building custom blockchain services.
Go
166
star
8

hypersdk

Opinionated Framework for Building Hyper-Scalable Blockchains on Avalanche
Go
163
star
9

avalanche-docs

JavaScript
155
star
10

firewood

Compaction-Less Database Optimized for Efficiently Storing Recent Merkleized Blockchain State
Rust
93
star
11

spacesvm

Go
86
star
12

avalanche-cli

Go
84
star
13

avalanche-explorer

The Vue frontend for the Avalanche blockchain.
Vue
82
star
14

avalanche-network-runner

Tool to run and interact with an Avalanche network locally
Go
81
star
15

avash

Avash - The Avalanche Shell Client
Go
72
star
16

ortelius

State archival and indexer for the Avalanche network. Used in the Avalanche Explorer.
Go
59
star
17

subnet-cli

Go
58
star
18

avalanche-rs

Avalanche APIs/VM SDK in Rust
Rust
45
star
19

avalanche-wallet-sdk

A Typescript library to create and manage wallets on the Avalanche network.
TypeScript
39
star
20

wrapped-assets

Smart Contract for Wrapped AVAX
Solidity
38
star
21

avalanche-ops

operation toolkit for Avalanche nodes
Rust
36
star
22

ecosystem-projects

JavaScript
33
star
23

avalanche-types-rs

Avalanche primitive types in Rust (experimental)
Rust
32
star
24

avalanche-faucet-legacy

A frontend Vue application for the Avalanche Faucet
TypeScript
30
star
25

ava-sim

Go
28
star
26

avalanche-rosetta

Rosetta server for Avalanche (C-Chain and P-Chain)
Go
28
star
27

xsvm

Example Virtual Machine supporting Subnet Messaging on the Avalanche Network
Go
27
star
28

avalanche-bridge-resources

Token List for the Avalanche Bridge
Solidity
26
star
29

teleporter

EVM cross-chain messaging protocol built on top of Avalanche Warp Messaging
Solidity
23
star
30

timestampvm

timestampvm implementation as rpc-plugin
Go
23
star
31

bridge-tokens

Python
23
star
32

blobvm

Go
18
star
33

timestampvm-rs

Timestamp VM in Rust
Rust
18
star
34

avax-js-cli-tools

A collection of helpful scripts for the Avalanche network.
JavaScript
17
star
35

spacesvm-js

TypeScript
17
star
36

precompile-evm

A new repository for Subnet-EVM Stateful Precompiles
Shell
14
star
37

indexvm

The Context Layer of the Decentralized Web
Go
11
star
38

avalanche-monitoring

Monitoring tooling for Avalanche nodes
Shell
10
star
39

avalanche-quicksign

A very simple webpage that signs a string with a private key and prompts the user to email it. Used to verify users on the test net.
Vue
10
star
40

mnemonic-shamir-secret-sharing-cli

C++
10
star
41

ledger-avalanche

Rust
9
star
42

audits

Security audits for the Avalanche platform
9
star
43

awm-relayer

Service for relaying Avalanche Warp Messages between Subnets
Go
9
star
44

avalanche-dapp-sdks

Working example of a dapp working with core extension
TypeScript
8
star
45

avalanche-network-runner-sdk-rs

avalanche-network-runner-sdk-rs
Rust
8
star
46

avalanchetipbot

Avalanche Tip Bot for telegram, twitter and discord.
JavaScript
7
star
47

apm

Plugin manager for Avalanche
Go
7
star
48

chainsafe-scripts

Scripts for chainsafe analysis
Python
6
star
49

public-facing-docs

Repo of public docs
6
star
50

spacesvm-rs

Spaces VM in Rust
Rust
6
star
51

teleporter-token-bridge

Token bridging cross-chain built on top of Teleporter
Solidity
5
star
52

avalanche-evm-gasless-transaction

Rust
5
star
53

avalanchego-kurtosis

Run AvalancheGo tests in the Kurtosis framework
Go
4
star
54

avalanche-network-runner-postman-collection

A postman colllection to interact with the Avalanche Network Runner
4
star
55

avalanche-network-runner-sdk

Go
4
star
56

vue-components

A collection of Vue based components used across our application frontends.
Vue
4
star
57

firewood-mit

Rust
4
star
58

avalanche-ledger-go

Shell
3
star
59

open-defi-hackathon

3
star
60

gnosis-subnet

Helper repo for deploying gnosis safe contracts on Avalanche subnets
Shell
3
star
61

avalanche-plugins-core

Core plugins for Avalanche
3
star
62

spacesvm-postman-collection

Postman collection for the SpacesVM
2
star
63

avalanchejs-docs

Documentation for AvalancheJS
2
star
64

subnet-assets

JavaScript
2
star
65

cargo-workspace-version

Cargo plugin to check and/or update all local package versions in a workspace
Rust
2
star
66

ip-manager

IP manager
Rust
2
star
67

avalanche-telemetry

Avalanche node telemetry agent (supports CloudWatch, DataDog)
Rust
2
star
68

qevm

Rust
2
star
69

public-avalanche-sdks

Public SDKs for interfacing with Avalanche
TypeScript
2
star
70

avalanche-installer

Avalanche installer
Rust
1
star
71

avalanchego-operator

Go
1
star
72

btcb-por-workshop

Demo contracts for interacting with the BTC.b Proof-of-Reserves on Fuji Testnet
Shell
1
star
73

avalanche-hackathon

Solidity
1
star
74

homebrew-avalanchego

Homebrew formula for distribution of public avalanche binaries to MacOS
Ruby
1
star