2021-12-20 12:53:54 +00:00
|
|
|
# Node Balancer application
|
|
|
|
|
2023-05-16 10:47:41 +00:00
|
|
|
## Installation
|
2021-12-20 12:53:54 +00:00
|
|
|
|
2023-07-12 08:19:41 +00:00
|
|
|
- Prepare environment variables, according to `sample.env`.
|
2024-12-13 10:06:01 +00:00
|
|
|
- Build an application
|
2021-12-20 12:53:54 +00:00
|
|
|
|
|
|
|
```bash
|
2022-03-17 17:35:53 +00:00
|
|
|
go build -o nodebalancer .
|
2021-12-20 12:53:54 +00:00
|
|
|
```
|
|
|
|
|
2024-12-13 10:06:01 +00:00
|
|
|
## CLI
|
2022-03-16 21:33:48 +00:00
|
|
|
|
2023-05-16 11:07:24 +00:00
|
|
|
**IMPORTANT** Do not use flag `-debug` in production.
|
|
|
|
|
2024-12-13 10:06:01 +00:00
|
|
|
Node balancer access manipulation requires an administration token to create and modify resources within the Bugout moonstream application.
|
|
|
|
|
|
|
|
### add new access
|
2022-03-17 14:41:03 +00:00
|
|
|
|
|
|
|
Add new access for user:
|
|
|
|
|
|
|
|
```bash
|
2024-12-13 10:06:01 +00:00
|
|
|
./nodebalancer access add \
|
|
|
|
--access-token "<bugout_access_token>"
|
2022-03-17 14:41:03 +00:00
|
|
|
--name "Access name" \
|
2024-12-13 10:06:01 +00:00
|
|
|
--description "Description of access"
|
2022-03-17 14:41:03 +00:00
|
|
|
```
|
|
|
|
|
2024-12-13 10:06:01 +00:00
|
|
|
### delete access
|
2022-03-17 14:41:03 +00:00
|
|
|
|
|
|
|
Delete user access:
|
|
|
|
|
|
|
|
```bash
|
2024-12-13 10:06:01 +00:00
|
|
|
./nodebalancer access delete \
|
|
|
|
--access-token "<bugout_access_token>"
|
2022-03-17 14:41:03 +00:00
|
|
|
--access-id "<access_uuid>"
|
|
|
|
```
|
|
|
|
|
|
|
|
If `access-id` not specified, all user accesses will be deleted.
|
|
|
|
|
2023-05-16 10:47:41 +00:00
|
|
|
### users
|
2022-03-16 21:33:48 +00:00
|
|
|
|
|
|
|
```bash
|
2024-12-13 10:06:01 +00:00
|
|
|
./nodebalancer access list --access-token "<bugout_access_token>" | jq .
|
2022-03-16 21:33:48 +00:00
|
|
|
```
|
|
|
|
|
2024-12-13 10:06:01 +00:00
|
|
|
This command will return a list of bugout resources of registered users to access node balancer.
|
2022-03-16 21:33:48 +00:00
|
|
|
|
|
|
|
```json
|
|
|
|
[
|
|
|
|
{
|
|
|
|
"user_id": "<user_id_from_any_bugout_application>",
|
|
|
|
"access_id": "<access_uuid_which_provided_with_query>",
|
|
|
|
"name": "<short_description_of_purpose_of_this_crawler>",
|
|
|
|
"description": "<long_description>",
|
|
|
|
"blockchain_access": true,
|
|
|
|
"extended_methods": false
|
|
|
|
}
|
|
|
|
]
|
|
|
|
```
|
|
|
|
|
2023-07-12 08:19:41 +00:00
|
|
|
`access_id` - token which allows access to nodebalancer, could be specified in both ways:
|
2022-03-16 21:33:48 +00:00
|
|
|
|
|
|
|
- as a header `x-moonstream-access-id` with value `access_id`
|
|
|
|
- as query parameter `access_id=access_id`
|
|
|
|
|
2023-07-12 08:19:41 +00:00
|
|
|
`blockchain_access` - boolean which allows you or not to have access to blockchain node, otherwise you will be redirected to database
|
2022-03-16 21:33:48 +00:00
|
|
|
|
2023-07-12 08:19:41 +00:00
|
|
|
`extended_methods` - boolean which allows you to call not whitelisted method to blockchain node, by default for new user this is equal to `false`
|
2022-03-16 21:33:48 +00:00
|
|
|
|
2023-05-16 10:47:41 +00:00
|
|
|
### server
|
2022-03-16 21:33:48 +00:00
|
|
|
|
|
|
|
```bash
|
2024-12-13 10:06:01 +00:00
|
|
|
./nodebalancer server --host 0.0.0.0 --port 8544 --healthcheck
|
2022-03-16 21:33:48 +00:00
|
|
|
```
|
|
|
|
|
|
|
|
Flag `--healthcheck` will execute background process to ping-pong available nodes to keep their status and current block number.
|
|
|
|
Flag `--debug` will extend output of each request to server and healthchecks summary.
|
|
|
|
|
2023-05-16 10:47:41 +00:00
|
|
|
## Work with node
|
2022-03-16 21:33:48 +00:00
|
|
|
|
|
|
|
Common request to fetch block number
|
2021-12-20 12:53:54 +00:00
|
|
|
|
|
|
|
```bash
|
2023-05-16 10:47:41 +00:00
|
|
|
curl --request POST 'http://127.0.0.1:8544/nb/ethereum/jsonrpc?access_id=<access_id>&data_source=<blockchain/database>' \
|
2022-03-16 21:33:48 +00:00
|
|
|
--header 'Content-Type: application/json' \
|
|
|
|
--data-raw '{
|
|
|
|
"jsonrpc":"2.0",
|
|
|
|
"method":"eth_getBlockByNumber",
|
2023-05-16 10:47:41 +00:00
|
|
|
"params":["latest", false],
|
2022-03-16 21:33:48 +00:00
|
|
|
"id":1
|
|
|
|
}'
|
2021-12-20 12:53:54 +00:00
|
|
|
```
|
2022-03-17 17:35:53 +00:00
|
|
|
|
|
|
|
For Web3 providers `access_id` and `data_source` could be specified in headers
|
|
|
|
|
|
|
|
```bash
|
|
|
|
--header 'x-node-balancer-data-source: <blockchain/database>'
|
|
|
|
--header 'x-node-balancer-access-id: <access_id>'
|
|
|
|
```
|
2023-05-16 11:07:24 +00:00
|
|
|
|
|
|
|
## Tests
|
|
|
|
|
|
|
|
### Running all tests
|
|
|
|
|
|
|
|
```bash
|
|
|
|
/usr/local/go/bin/go test -run ^*$ github.com/bugout-dev/moonstream/nodes/node_balancer/cmd/nodebalancer -v -count=1
|
|
|
|
```
|
|
|
|
|
|
|
|
### Running specified test
|
|
|
|
|
|
|
|
```bash
|
|
|
|
/usr/local/go/bin/go test -run ^TestCleanInactiveClientNodes$ github.com/bugout-dev/moonstream/nodes/node_balancer/cmd/nodebalancer -v -count=1
|
|
|
|
```
|
2023-05-23 07:46:29 +00:00
|
|
|
|
|
|
|
## Migrations
|
|
|
|
|
|
|
|
To run migration:
|
|
|
|
|
|
|
|
```bash
|
|
|
|
python migrations/migrations.py run --key 20230522 \
|
|
|
|
--token-current-owner "$NB_CONTROLLER_TOKEN" \
|
|
|
|
--token-new-owner "$MOONSTREAM_ADMIN_OR_OTHER_CONTROLLER" \
|
|
|
|
--new-application-id "$MOONSTREAM_APPLICATION_ID"
|
|
|
|
```
|
2025-01-30 12:17:22 +00:00
|
|
|
|
|
|
|
## Balances Endpoint
|
|
|
|
|
|
|
|
The `/balances` endpoint allows you to retrieve token balances for a specified Ethereum address across multiple blockchains.
|
|
|
|
|
|
|
|
### Request
|
|
|
|
|
|
|
|
```
|
|
|
|
GET /balances?address=<ethereumAddress>
|
|
|
|
```
|
|
|
|
|
|
|
|
Parameters:
|
|
|
|
- `address` (required): The Ethereum address to query balances for
|
|
|
|
|
|
|
|
### Response
|
|
|
|
|
|
|
|
The endpoint returns a JSON object with the following structure:
|
|
|
|
|
|
|
|
```json
|
|
|
|
{
|
2025-02-05 16:30:44 +00:00
|
|
|
"1": {
|
|
|
|
"chain_id": "1",
|
2025-02-05 16:50:23 +00:00
|
|
|
"name": "ethereum",
|
2025-02-05 16:30:44 +00:00
|
|
|
"image_url": "https://example.com/eth.png",
|
|
|
|
"balances": {
|
|
|
|
"0x0000000000000000000000000000000000000000": "1000000000000000000",
|
|
|
|
"0xdac17f958d2ee523a2206206994597c13d831ec7": "2000000000000000000",
|
|
|
|
"0xa0b86991c6218b36c1d19d4a2e9eb0ce3606eb48": "3000000000000000"
|
|
|
|
}
|
|
|
|
},
|
|
|
|
"137": {
|
|
|
|
"chain_id": "137",
|
2025-02-05 16:50:23 +00:00
|
|
|
"name": "polygon",
|
2025-02-05 16:30:44 +00:00
|
|
|
"image_url": "https://example.com/matic.png",
|
|
|
|
"balances": {
|
|
|
|
"0x0000000000000000000000000000000000000000": "4000000000000000000",
|
|
|
|
"0x2791bca1f2de4661ed88a30c99a7a9449aa84174": "5000000000000000",
|
|
|
|
"0xc2132d05d31c914a87c6611c10748aeb04b58e8f": "6000000000000000000"
|
|
|
|
}
|
|
|
|
}
|
2025-01-30 12:17:22 +00:00
|
|
|
}
|
|
|
|
```
|
|
|
|
|
|
|
|
Where:
|
2025-02-05 16:30:44 +00:00
|
|
|
- The top-level keys are chain IDs (e.g. "1" for Ethereum, "137" for Polygon)
|
|
|
|
- Each chain object contains:
|
|
|
|
- `chain_id`: The chain identifier as a string
|
2025-02-05 16:50:23 +00:00
|
|
|
- `name`: The human-readable name of the chain
|
2025-02-05 16:30:44 +00:00
|
|
|
- `image_url`: URL to the chain's logo/image
|
|
|
|
- `balances`: Map of token addresses to their balances
|
|
|
|
- Native token (ETH, MATIC etc) is represented by the zero address: `0x0000000000000000000000000000000000000000`
|
|
|
|
- All balances are returned as strings in the token's smallest unit (e.g., wei for ETH)
|
2025-01-30 12:17:22 +00:00
|
|
|
|
|
|
|
### Features
|
|
|
|
|
|
|
|
1. **Caching**: Responses are cached for 10 seconds to minimize blockchain RPC calls
|
|
|
|
2. **Multicall**: Uses Multicall3 contract to batch balance queries for efficiency
|
2025-01-30 12:19:38 +00:00
|
|
|
3. **Error Handling**: Individual token or blockchain failures don't affect other
|
2025-01-30 12:17:22 +00:00
|
|
|
|
|
|
|
### Example
|
|
|
|
|
|
|
|
```bash
|
|
|
|
curl "http://localhost:8080/balances?address=0x742d35Cc6634C0532925a3b844Bc454e4438f44e"
|
|
|
|
```
|
2025-01-30 12:19:38 +00:00
|
|
|
|
2025-02-05 16:30:44 +00:00
|
|
|
### Contracts Config Structure
|
|
|
|
|
|
|
|
The `contracts.json` file should follow this structure:
|
|
|
|
|
2025-01-30 12:19:38 +00:00
|
|
|
```json
|
|
|
|
{
|
2025-02-05 16:30:44 +00:00
|
|
|
"ethereum": {
|
|
|
|
"multicall3": "0xcA11bde05977b3631167028862bE2a173976CA11",
|
|
|
|
"chain_id": "1",
|
|
|
|
"name": "Ethereum",
|
|
|
|
"image_url": "https://example.com/eth.png",
|
|
|
|
"native_token": "ETH",
|
|
|
|
"tokens": {
|
|
|
|
"0xdac17f958d2ee523a2206206994597c13d831ec7": "USDT",
|
|
|
|
"0xa0b86991c6218b36c1d19d4a2e9eb0ce3606eb48": "USDC"
|
|
|
|
}
|
|
|
|
},
|
|
|
|
"polygon": {
|
|
|
|
"multicall3": "0xcA11bde05977b3631167028862bE2a173976CA11",
|
|
|
|
"chain_id": "137",
|
|
|
|
"name": "Polygon",
|
|
|
|
"image_url": "https://example.com/matic.png",
|
|
|
|
"native_token": "MATIC",
|
|
|
|
"tokens": {
|
|
|
|
"0x2791bca1f2de4661ed88a30c99a7a9449aa84174": "USDC",
|
|
|
|
"0xc2132d05d31c914a87c6611c10748aeb04b58e8f": "USDT"
|
2025-01-30 12:19:38 +00:00
|
|
|
}
|
2025-02-05 16:30:44 +00:00
|
|
|
}
|
2025-01-30 12:19:38 +00:00
|
|
|
}
|
|
|
|
```
|
2025-02-05 16:30:44 +00:00
|
|
|
|
|
|
|
Where:
|
|
|
|
- Top-level keys are blockchain identifiers used internally
|
|
|
|
- Each chain configuration contains:
|
|
|
|
- `multicall3`: Address of the Multicall3 contract on that chain
|
|
|
|
- `chain_id`: The chain identifier (e.g. "1" for Ethereum)
|
|
|
|
- `name`: Human-readable name of the chain
|
|
|
|
- `image_url`: URL to the chain's logo/image
|
|
|
|
- `native_token`: Symbol for the chain's native token (ETH, MATIC etc)
|
|
|
|
- `tokens`: Map of token addresses to their symbols
|