Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

cleanup: clean up a bit of the mess i created #37

Merged
merged 2 commits into from
Nov 26, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
26 changes: 24 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,13 +1,35 @@
# BGD RPC ENV

When working on multichain projects it is a tedious task to setup private RPCs and managing them in your local environment or github actions.
This repository is a suite of tools to streamline the handling of RPC environment variables, by automating the creation and injection of environment variables following a common [naming scheme](./src/lib.test.ts).

## NodeJS: `@bgd-labs/rpc-env`

[![NPM Version](https://img.shields.io/npm/v/%40bgd-labs%2Frpc-env)](https://www.npmjs.com/package/@bgd-labs/rpc-env)

### Usage
### Usage as a library

```typescript
import { getRPCUrl, ChainId } from "@bgd-labs/rpc-env";

const url = getRPCUrl(ChainId.mainnet, "[YOUR_ALCHEMY_KEY]");
// will fetch the rpc based on a opinionated priorization and does not error if no rpc is found
// 1. checks if `RPC_MAINNET` is set, otherwise
// 2. checks if alchemy key was provided & if alchemy supports the network, otherwise
// 3. checks if a public rpc is configured
const url = getRPCUrl(ChainId.mainnet, { alchemyKey?: "[YOUR_ALCHEMY_KEY]" });

// alternatively you can use the explicit getters, which will throw if no rpc is found
const url = getExplicitRPC(ChainId.mainnet);
const url = getAlchemyRPC(ChainId.mainnet, alchemyKey);
const url = getPublicRpc(ChainId.mainnet);
```

### Usage as cli

The cli will emit explicit rps and a foundry.toml configuration for each network.

```
export ALCHEMY_API_KEY=<> && npx @bgd-labs/rpc-env
```

## Action: `action-rpc-env`
Expand Down
2 changes: 1 addition & 1 deletion dist/action.js
Original file line number Diff line number Diff line change
Expand Up @@ -23673,7 +23673,7 @@ var ChainId = {
linea: linea.id
};

// src/public.ts
// src/publicRPCs.ts
var publicRPCs = {
[ChainId.mainnet]: "https://eth.llamarpc.com",
[ChainId.polygon]: "https://polygon.llamarpc.com",
Expand Down
2 changes: 1 addition & 1 deletion dist/action.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -23671,7 +23671,7 @@ var ChainId = {
linea: linea.id
};

// src/public.ts
// src/publicRPCs.ts
var publicRPCs = {
[ChainId.mainnet]: "https://eth.llamarpc.com",
[ChainId.polygon]: "https://polygon.llamarpc.com",
Expand Down
2 changes: 1 addition & 1 deletion lefthook.yml
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ pre-commit:
commands:
build:
glob: "*.{ts,package-lock.json}"
run: node src/prepare.mjs > src/alchemyIds.ts && git add src/alchemyIds.ts && npm run build && git add dist/*
run: node src/prepare.mjs > src/alchemyIds.ts && git add src/alchemyIds.ts && npm run build && git add .
# yes we're actually committing the build output, because github actions works like that
stage_fixed: true
format:
Expand Down
16 changes: 16 additions & 0 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

4 changes: 3 additions & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
"publishConfig": {
"access": "public"
},
"sideEffects": false,
"scripts": {
"build": "tsup",
"test": "vitest",
Expand Down Expand Up @@ -38,7 +39,8 @@
"tsup": "^8.3.5",
"typescript": "^5.6.3",
"viem": "^2.21.48",
"vitest": "^2.1.4"
"vitest": "^2.1.4",
"dotenv": "^16.4.5"
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

why is everything devDependencies?

When using as a lib, i would expect viem to be a peerDependency.

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Because of how tsup works. DevDependencies are bundled up automatically and as we're only using the deps for some constants, IMO that is much nicer for downstream users.

Copy link
Collaborator

@boredland boredland Nov 21, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is particularly useful for actions-usage, where no dependency resolution takes place.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

i see, but currently, this means then when using as js lib it would contain the inlined viem + the viem the package uses?

It#s not a big problem as currently we only use this is node modules were pkg size does not matter, but perhaps that's sth we should look into down the line.

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Depending on if tree shake works, I'd say.. does the whole view land in there or the constants we need?

},
"tsup": {
"entry": ["src/action.ts", "src/lib.ts", "src/cli.ts"],
Expand Down
7 changes: 6 additions & 1 deletion src/cli.ts
Original file line number Diff line number Diff line change
@@ -1,12 +1,17 @@
#!/usr/bin/env node
import "dotenv/config";
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

not quite sure if it should be here ... probably not and one should export ALCHEMY_API_KEY before running the cli or put the api key as parameter on the script. Didn't want to add commander or similar for such a simple task though and working with pure args in node is pain :/

I'm conflicted.

import { ChainId, getNetworkEnv, getRPCUrl } from "./lib";

(function print() {
let env = "";
let toml = "";
Object.entries(ChainId).map(([key, chainId]) => {
const networkEnv = getNetworkEnv(chainId);
const rpc = getRPCUrl(chainId, { alchemyKey: process.env.ALCHEMY_API_KEY });
const rpc = getRPCUrl(chainId, {
alchemyKey: process.env.ALCHEMY_API_KEY,
quicknodeToken: process.env.QUICKNODE_TOKEN,
quicknodeEndpointName: process.env.QUICKNODE_ENDPOINT_NAME,
});
env += `${networkEnv}=${rpc || ""}\n`;
toml += `${key}="\${${networkEnv}}"\n`;
});
Expand Down
4 changes: 2 additions & 2 deletions src/lib.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import { networkMap } from "./alchemyIds";
import { ChainId, ChainList } from "./chainIds";
import { publicRPCs } from "./public";
import { publicRPCs } from "./publicRPCs";
import { quicknodeNetworkMap } from "./quicknodeIds";

type SupportedChainIds = (typeof ChainId)[keyof typeof ChainId];
Expand Down Expand Up @@ -141,4 +141,4 @@ export const getRPCUrl = (
} catch (e) {}
};

export { ChainId, ChainList };
export { ChainId, ChainList, type SupportedChainIds };
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

noticed it would be useful to have this type.

2 changes: 1 addition & 1 deletion src/prepare.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -444,7 +444,7 @@ const quickNodeApiResponse = {
};

const quicknodeNetworkMap = quickNodeApiResponse.data.reduce((acc, network) => {
network.networks.forEach((nw) => {
network.networks.map((nw) => {
if (nw.chain_id) {
acc[nw.chain_id] = nw.slug;
}
Expand Down
4 changes: 4 additions & 0 deletions src/public.ts → src/publicRPCs.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,9 @@
import { ChainId } from "./chainIds";

/**
* A manually maintained list of public rpcs.
* These should only be used for prs coming from forks, which should not access secrets like the alchemy api key.
*/
export const publicRPCs = {
[ChainId.mainnet]: "https://eth.llamarpc.com",
[ChainId.polygon]: "https://polygon.llamarpc.com",
Expand Down