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

Use config file for network and other configuration #231

Closed
wants to merge 28 commits into from

Conversation

technophile-04
Copy link
Collaborator

Fixes #230

@technophile-04 technophile-04 marked this pull request as draft March 9, 2023 19:39
pollingInterval: number;
};

const ScaffoldConfig: TScaffoldConfig = {
Copy link
Collaborator

@sverps sverps Mar 10, 2023

Choose a reason for hiding this comment

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

I think we should settle on a styleguide and apply it on the whole project (I like google's styleguide as a good starting point).

That means here we'd follow default naming convention and make the const lowerCamelCase.

As for the type, I think the convention should be to not prefix or suffix it and use regular UpperCamelCase, since typescript itself already contains the info about what kind of type it is (https://google.github.io/styleguide/tsguide.html#naming-style).
Prefixes should, in my opinion, be reserved for generic types, to mark a clear distinction between defined types and generics.

@rin-st @carletex any thoughts?

Copy link
Member

Choose a reason for hiding this comment

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

I agree 👍

Copy link
Member

Choose a reason for hiding this comment

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

I'm up for a having a styleguide.

Besides applying it here, we should create an issue an for it, discuss what guidelines we want to follow..... and make a PR refactoring all the names / types / etc.

Copy link
Collaborator

Choose a reason for hiding this comment

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

Opened an issue about it 👍

Comment on lines 62 to 68
const chainNames = Object.keys(chains);

const targetChainArr = chainNames.filter(chainName => {
const wagmiChain = chains[chainName as keyof typeof chains];
return wagmiChain.id === chainId;
});

Copy link
Member

Choose a reason for hiding this comment

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

An idea (without testing it 👼 ).

What if we make the argument network to be wagmi's Chain? So we don't need to do this conversion.

In the transactor, we could get the connected network with wagmi's useNetwork() (and maybe throw an error / return if the signer is on a different network)

// useTransactor
const { chain } = useNetwork();
// check that network.chainId === chain.id => if not, error / return
getBlockExplorerTxLink(chain, ...)

Since we are using wagmi's Chains as source of truth, maybe we should rely on them whenever we can? Instead of using internal ethers/providers.

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

Yup makes sense, lol even I was a bit uncomfortable while writing the conversion,

What if we make the argument network to be wagmi's Chain? So we don't need to do this conversion.

This is a great idea but the problem is useTransactor accepts custom signer too and the reason we are relying on the signers network is that :
NITPICK: There might a case where people pass in the custom signer without connecting their wallet and in that case useNetwork and signer network will be different and might cause some inconsistency, we are using similar pattern in Faucet.jsx.

Again the above NITPICK is a very rare case.

Will try exploring some more alternatives 🙌

Copy link
Member

Choose a reason for hiding this comment

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

Hey Shiv, good point!!

After pulling the threads on this, some notes:

  • The only instance where we are passing a custom signer, is for the hardhat faucet (where we want to send funds from a hardhat account with funds). Can we think about other use case? Since we are in the front-end, 99.99% of the times we'll want to use the connected signer (besides the faucet, and maybe a exotic build where we do deterministic private key derivation or something)
  • getBlockExplorerTxLink doesn't return anything for the local chain (the only instance where we are using a custom signer for the transactor 🤔 )
  • getLocalProvider is only used in the Faucet stuff. Could be an unneeded early abstraction.
  • Maybe an util like getChainFromChainId that returns a wagmi Chain for a given Id?

In any case, no need to make any updates rn!! just thinking out loud and pointing out some possible inconsistencies. Maybe we made some past decisions that could use some refactors for the sake of consistency / simplicity / better DX.

Thanks!

Copy link
Collaborator Author

@technophile-04 technophile-04 Mar 13, 2023

Choose a reason for hiding this comment

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

Tysm everything makes sense !!

Maybe we made some past decisions that could use some refactors for the sake of consistency / simplicity / better DX

+++

@rin-st rin-st mentioned this pull request Mar 12, 2023
@technophile-04
Copy link
Collaborator Author

technophile-04 commented Mar 13, 2023

Small update

Moved scaffold.config to root and same is being utilised by both next and hardhat

btw I came across some patterns where people have created config directory similar to nextjs and harhdat where all the base configurations live like .eslintrc, .tsconfig etc, just wanted to put here since we are in "refactoring phase" :) and also we can put scaffold.config inside it. I like the way currently it is now but would love to know others thought

Will mark this PR as ready once proper testing and try to make things more consistent

@sverps
Copy link
Collaborator

sverps commented Mar 13, 2023

btw I came across some patterns where people have created config directory similar to nextjs and harhdat where all the base configurations live like .eslintrc, .tsconfig etc, just wanted to put here since we are in "refactoring phase" :) and also we can put scaffold.config inside it. I like the way currently it is now but would love to know others thought

I'm used to those types of config files being at the root of their package, that's where I would generally look for them, so it doesn't bother me personally.

Do you know if all config files will play nice if they're not at the root of a package (e.g. tailwind.config.js, postcss.config.js, next.config.js)? I'd only consider it if all configs can be grouped, otherwise there will be 2 locations for config files, which would be a bit confusing.

Comment on lines 4 to 5
targetNetwork: chain.Chain;
pollingInterval: number;
Copy link
Member

Choose a reason for hiding this comment

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

I think this are tabs

@@ -15,7 +15,8 @@
"jsx": "preserve",
"incremental": true,
"paths": {
"~~/*": ["./*"]
"~~/*": ["./*"],
"@root/*": ["../../*"]
Copy link
Member

Choose a reason for hiding this comment

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

I still get this on my nextjs console:

image

I ran yarn install and restarted nextjs. Am I missing something?

Copy link
Collaborator Author

@technophile-04 technophile-04 Mar 14, 2023

Choose a reason for hiding this comment

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

Yes !! encountered the same problem, don't know for some reason it was working but I am sure i am missing some configuration, working on it

@carletex
Copy link
Member

Moved scaffold.config to root and same is being utilised by both next and hardhat

This is great! I think having an unique config file it's more dx friendly. A few thoughts/questions:

  • Could/Should we add a single source of truth here about networks? We have the networks.ts file on next, and we use the networks also in hardhat.config.ts. I'm just wondering if we could define a network object with all the data we need in scaffold.config, for hardhat & next (wagmi) to use. "Networks" feel like a key & transversal piece for SE-2 (or any dApp)
  • Should we also support env vars in the config file? Specifically for secrets, since people are going to commit the config file. Things like "DEPLOYER_PRIVATE_KEY" or even alchemy/infura keys that could live in config.
const scaffoldConfig: ScaffoldConfig = {
	targetNetwork: chain.hardhat,
	pollingInterval: 30000,
        deployerdPrivateKey: process.env.DEPLOYER_PRIVATE_KEY
} as const;

I think we'll just need the dotenv package on the root. Handling all the config & env vars in the root seems more friendly. I think it will work on Vercel when manually defining the env vars in their UI.

This is just me thinking out loud, would love to hear your view on it.

btw I came across some patterns where people have created config directory similar to nextjs and harhdat where all the base configurations live like .eslintrc, .tsconfig etc, just wanted to put here since we are in "refactoring phase" :) and also we can put scaffold.config inside it. I like the way currently it is now but would love to know others thought
I'm used to those types of config files being at the root of their package, that's where I would generally look for them, so it doesn't bother me personally.

Since this is a monorepo with two packages, it also doesn't bother me having separate config files. But I've also seen monorepos with a shared (or config) directory.. I guess it's an alternative to having everything shared in the root (when is too bloated). It's definitely something that we should explore, but maybe in the future / another PR? This PR is already a big refactor.

@technophile-04
Copy link
Collaborator Author

technophile-04 commented Mar 15, 2023

Edit

Found a way to solve vercel deployments, updating it ...

Update

Now scaffold.config.ts at root should work but there are some catches :

The way the front end was deployed previously is changed.

Since we are utilizing scaffold.config.ts which is at root, outside the nextjs dir when you deploy to vercel it gives the below error :
Screenshot 2023-03-15 at 9 15 08 PM

Previously we were uploading the whole source code to vercel and then running build there.

Now, the flow is: first you need to build locally and then publish only build dir to vercel similar to surge.sh in SE

I have create script alias which will do it :
yarn vercel:prod - will build and deploy to vercel on production
yarn vercel:dev - will build and deploy as preview
yarn vercel:yolo - ignore errors and deploy to production

Approaches explored :

Although using a .ts file at monorepo root seems like very simple / famous case but was not able to find good examples/references to deal with it having nextjs.

  1. Using externalDir which is experimental feature by nextjs, it seems to do the work but it prints the warning when you start the app :

Screenshot 2023-03-15 at 9 44 32 PM

checkout this disccusion / comment => vercel/next.js#32192 (comment)

And this issue: vercel/next.js#20374 why there are problems.

  1. Currently using nextjs built in module-transpilation which was built in nextjs by author of next-transpile-modules, I saw people using next-transpile-modules as a workaround for the problem which we faced and now its inbuild so utilzing it.

I tried comparing build size of both approaches and they came to be same :

using module-transpilation using experimental
Screenshot 2023-03-15 at 10 16 50 PM Screenshot 2023-03-15 at 10 17 19 PM
  1. Others, there some approaches where people used reconfigured webpack in next.config.js but found them really hacky and not future proof

  2. Maybe we can just put back scaffold.config.ts inside nextjs

Some thoughts :

  1. Yes I think new deployment flow is a bit off but I think if we want scaffold.config.ts to stay out of nextjs dir then we need to go with current approach, btw the current approach build time is really fast. Also would love to know others thoughts / approaches to conquer this
  2. This was just a draft to see how it will look if we put scaffold.config.ts in root, happy to revamp this whole thing 🙌

Regarding putting .envs in scaffold.config.ts love the idea even tried exploring it but again there seems problem with nextjs using external env's

People seem to use dotenv inside next.config.js to read from external .env and pass in env's inside nextConfig the problem with this approach is that the env's you pass in are inlined in javascript while bundling i.e only allowed to pass in NEXT_PUBLIC and this will lead to exposing unnecessary keys if you are not mindful + found this approach a bit hacky

cehkcout -> https://stackoverflow.com/questions/69259896/set-environment-variables-outside-of-pages-dir-in-nextjs
and https://stackoverflow.com/questions/59462614/how-to-use-different-env-files-with-nextjs/69619744#69619744

PS : the above stackoverflow links were picked from differnt next js issues

I think maybe we can keep our api key's as hardcoded in scaffold.config.ts so that it can be used in both hardhat.config.ts and wagmiClient and let nextjs handle env's since nextjs aslo has env.production and etc we would manually need to handle its a bit messy chekcout -> https://stackoverflow.com/a/74154252/16480510

Also I saw one pattern where env's were managed in .yml file checkout -> https://stackoverflow.com/a/69619744/16480510


cc @carletex @rin-st @sverps please feel free to suggest other approaches/suggestions happy to give it another try, I am sure I might have missed something 🙌

@carletex
Copy link
Member

Hey @technophile-04 Thank you for this and your detailed explanation. Super helpful!

I feel that this got out of hand: my fault for suggesting the root config file haha. But we had to explore it and see what the issues were. I still feel that we want to aim for it, but let's do it in a more iterative / incremental way.

Proposal

Since the most important reason for this was to enable #202, I think we should go with the simple approach for now, and keep exploring the root / shared stuff for the monorepo.

Let's create a config file only for Next (replacing the .env.* files). This way we won't have any issues with Vercel are the changes will be minimal.

What do you think?

Thank you Shiv!

@technophile-04
Copy link
Collaborator Author

technophile-04 commented Mar 16, 2023

In the latest commit 4c4e4a6 now deployments are back to normal and no need to prebuilt stuff as mentioned here #231 (comment) but just a very small catch 🙃 :

Although this is one time config, you need to mention the path to nexjts dir :
Screenshot 2023-03-16 at 2 40 32 PM

Reason :

Since we using monorepo, vercel offically suggests to invoke vercel cli from root of monorepo and then pass in source code location to solve the problem mentioned here 4c4e4a6

Screenshot 2023-03-16 at 2 43 35 PM

Screenshot 2023-03-16 at 2 44 15 PM

Checkout Vercel docs monorepo FAQ -> https://vercel.com/docs/concepts/monorepos

Now the flow for the target network is :

scaffold.config.ts is a single source of truth for both nextjs and hardhat.

Just doing yarn deploy will deploy to network configured in scaffold.config.ts and yarn start will use it as target network in frontend.

Flow for configuring env's :

How env's works remain the same as the main branch.

What's changed?
I have hardcoded our API keys inside scaffoldConfig so that they can be used by both hardhat and `nextjs, for example Alchemy providerKey.

Also removed .env.* from frontend since all handled by scaffold.config now.

reason: It's now saying that Scaffold-eth is "configured" with some handy api keys which you can access through scaffold.config.


TODO :

Happy to handle them both in different PRs, since this is already big and don't want us blocking on #202 🙌

@carletex carletex marked this pull request as ready for review March 16, 2023 10:16
},
"packageManager": "yarn@3.2.3",
"devDependencies": {
"@types/node": "^18.15.3",
Copy link
Member

Choose a reason for hiding this comment

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

Are we really need it? It seems everything works without it

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

Tysm !! yes yes we can remove it, it was added here 8f19b21 and since now we are not using .env at root we can completely remove it

// If not set, it uses the hardhat account 0 private key.
const deployerPrivateKey =
process.env.DEPLOYER_PRIVATE_KEY ?? "0xac0974bec39a17e36ba4a6b4d238ff944bacb478cbed5efcae784d7bf4f2ff80";
const deployerPrivateKey = process.env.DEPLOYER_PRIVATE_KEY ?? scaffoldConfig.deployerPrivateKey;
Copy link
Member

Choose a reason for hiding this comment

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

minor nitpick: above and below we use ||, so probably it's better to use it here too

@@ -9,6 +9,7 @@ const nextConfig = {
eslint: {
ignoreDuringBuilds: process.env.NEXT_PUBLIC_IGNORE_BUILD_ERROR === "true",
},
transpilePackages: ["se-2"],
Copy link
Member

Choose a reason for hiding this comment

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

could you explain please, why we need it?

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

if you look at #231 (comment) in the section

Approaches explored :
2.

TLDR;
Since we have scaffold.config.ts outside the nextjs directory if you don't pass in this it gives this error -> #231 (comment)

The reason I have put se-2 there is because we had scaffold.config.ts at se-2 workspace and needed to transpile it during next build :

Screenshot 2023-03-16 at 9 16 32 PM

Although would highly recommend giving a quick read of the section Approaches explored especially the links mentioned in that section 🙌

Also would love to hear if there are any alternatives / suggestions 🙌

Copy link
Member

Choose a reason for hiding this comment

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

Thank you! ❤️ You've done such a big research, it's hard even to understand everything at first sight :D

@rin-st
Copy link
Member

rin-st commented Mar 16, 2023

Great job, @technophile-04 !

Sorry for the delays in comments, sometimes I suddenly need to go 🤷‍♂️

@carletex
Copy link
Member

Great job @technophile-04

I think we are not far, but still doesn't feel 100% right to me.

1. Vercel root directory

Screenshot 2023-03-16 at 2 40 32 PM

It might be like a little thing, but for me, it decreases the deploy experience by a bunch. I tried to search for options for the CLI / vercel.json config file, but it doesn't seem that you can provide a default root directory option. The --cwd option doesn't work either.

Not sure what we could try.

2. .env vars

If we plan to have global env's then implement them, checkout out the last section for resistance faced #231 (comment)

I think we need .env vars for secrets.

Answer 1
Right now on scaffold.config.ts:

const scaffoldConfig: ScaffoldConfig = {
  // ....
  deployerPrivateKey:
    "0xac0974bec39a17e36ba4a6b4d238ff944bacb478cbed5efcae784d7bf4f2ff80",
 // ..
} as const;

and then const deployerPrivateKey = process.env.DEPLOYER_PRIVATE_KEY ?? scaffoldConfig.deployerPrivateKey; on hardhat.config.ts. It's confusing, since we have the deployerPrivateKey on the config file and it's not clear that people need to create a .env file inside the hardhat folder

I think it should be:

const scaffoldConfig: ScaffoldConfig = {
  // ....
  deployerPrivateKey: process.env.deployerPrivateKey || 
    "0xac0974bec39a17e36ba4a6b4d238ff944bacb478cbed5efcae784d7bf4f2ff80",
 // ..
} as const;

So people can create a .env file in the root folder (we might have a .env.example) that it's meant for secrets. And secrets consumers just read scaffoldConfig.deployerPrivateKey. Same for alchemyApiKey and etherscanApiKey.

And make sure people understand that they should never use scaffoldConfig to store secrets directly (even if we are doing so 😅)

Maybe we could pass the secrets/env vars like this to Vercel:

image

If people create/update an env var from the Vercel UI, they will take effect if they rebuild (they are being used on the scaffold.config.file)?

Answer 2

Use scaffold.config.ts only for public variables (targetNetwork && pollingInterval), and handle the secrets env vars in its own package:

  • Hardhat.. Same as in main (.env file)
  • NextJS. We'd replace .env.* with the config file, but people could still use .env / .env.local / Vercel UI to set up secrets and use them in their API routes or whatever.

This way we don't mix config & secret env vars... and things might be simpler.

Handle this properly #231 (comment)

This is not a big deal for now. We could create an issue for that refactor.


Definitely having a root config file makes things a bit more complicated. I'll be up for it if we find a nice balance. But #231 (comment) is still on my mind.

Thoughts?

@technophile-04
Copy link
Collaborator Author

technophile-04 commented Mar 16, 2023

Tysm all for the review !! 🙌

I think we are not far, but still doesn't feel 100% right to me.

Lol yes !, even I have this feeling it doesn't feel 100% right

I have made #246 which has config in frontend only as suggested in #231 (comment)

I plan to explore more on putting .config at the root, Planning to also open some issues/ discussions on vercel github to find/suggest better solutions. Example: configuring project root as Carlos mention for verceli-cli even I tried finding hard and there were no options to configure it

Marking this as a draft, Thanks 🙌

@technophile-04
Copy link
Collaborator Author

I have created a discussion on Vercel for Pt.1 of #231 (comment) -> https://github.com/orgs/vercel/discussions/2145

Closing this for now, since not under active development and until SE-2 cli is up

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Migrate from env's to config fiile
4 participants