Skip to content

Commit

Permalink
Improvement/foundry-setup (#72)
Browse files Browse the repository at this point in the history
* updated contracts prettier, foundry toml, and solhint
added javascript files to generate accounts
added env example

* updates to remapping
added openzeppelin node module
added pinata keys to env example

* some copilot updates for spacing and uneeded strings
  • Loading branch information
Oba-One authored Aug 18, 2024
1 parent dcfbc46 commit ccd83ae
Show file tree
Hide file tree
Showing 16 changed files with 400 additions and 61 deletions.
9 changes: 9 additions & 0 deletions .vscode/settings.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
{
"[solidity]": {
"editor.defaultFormatter": "NomicFoundation.hardhat-solidity"
},
"[toml]": {
"editor.defaultFormatter": "tamasfe.even-better-toml"
},
"solidity.formatter": "forge"
}
8 changes: 4 additions & 4 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -28,12 +28,12 @@
"dependencies": {
"dotenv": "16.4.5",
"ethers": "^6.13.2",
"viem": "^2.19.2"
"viem": "^2.19.6"
},
"devDependencies": {
"concurrently": "8.2.1",
"prettier": "^3.0.3",
"typescript": "^5.2.2",
"concurrently": "8.2.2",
"prettier": "^3.3.3",
"typescript": "^5.5.4",
"wait-port": "1.1.0"
},
"engines": {
Expand Down
5 changes: 3 additions & 2 deletions packages/app/.env.example
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
VITE_ALCHEMY_API_KEY=
VITE_PRIVY_API_KEY=
VITE_PIMLICO_API_KEY=
VITE_PINATA_API_KEY=



PINATA_API_SECRET=
PINATA_API_JWT=
19 changes: 19 additions & 0 deletions packages/contracts/.editorconfig
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
# EditorConfig http://EditorConfig.org

# top-most EditorConfig file
root = true

# All files
[*]
charset = utf-8
end_of_line = lf
indent_size = 2
indent_style = space
insert_final_newline = true
trim_trailing_whitespace = true

[*.sol]
indent_size = 4

[*.tree]
indent_size = 1
5 changes: 5 additions & 0 deletions packages/contracts/.env.example
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
export API_KEY_ALCHEMY="YOUR_API_KEY_ALCHEMY"
export API_KEY_ARBISCAN="YOUR_API_KEY_ARBISCAN"
export API_KEY_INFURA="YOUR_API_KEY_INFURA"
export PRIVATE_KEY="YOUR_MNEMONIC"
export FOUNDRY_PROFILE="default"
45 changes: 17 additions & 28 deletions packages/contracts/.gitignore
Original file line number Diff line number Diff line change
@@ -1,35 +1,24 @@
# See https://help.github.com/articles/ignoring-files/ for more about ignoring files.

# dependencies

# directories
cache
coverage
node_modules
dist
dev-dist
.DS_Store
DS_Store

node_modules
/.pnp
.pnp.js

out

# production

build

# local env files

.env\*.local
.env
# files
*.env
*.log
.DS_Store
.pnp.*
lcov.info
package-lock.json
pnpm-lock.yaml
yarn.lock

# forge
out/
cache/
cache_hardhat/
node_modules/
bindings/
artifacts/
# broadcasts
!broadcast
broadcast/*
broadcast/*/31337/

# Ignore MUD deploy artifacts
deploys/**/*.json

20 changes: 16 additions & 4 deletions packages/contracts/.prettierignore
Original file line number Diff line number Diff line change
@@ -1,5 +1,17 @@
dist
node_modules
contracts/out
contracts/cache
# directories
broadcast
cache
coverage
node_modules
out

# files
*.env
*.log
.DS_Store
.pnp.*
bun.lockb
lcov.info
package-lock.json
pnpm-lock.yaml
yarn.lock
8 changes: 6 additions & 2 deletions packages/contracts/.prettierrc.json
Original file line number Diff line number Diff line change
@@ -1,5 +1,9 @@
{
"bracketSpacing": true,
"printWidth": 120,
"proseWrap": "always",
"singleQuote": false,
"tabWidth": 2,
"useTabs": false,
"trailingComma": "all"
"trailingComma": "all",
"useTabs": false
}
11 changes: 9 additions & 2 deletions packages/contracts/.solhint.json
Original file line number Diff line number Diff line change
Expand Up @@ -2,10 +2,17 @@
"extends": ["solhint:recommended"],
"plugins": [],
"rules": {
"compiler-version": ["error", ">=0.8.0"],
"code-complexity": ["error", 8],
"compiler-version": ["error", ">=0.8.25"],
"func-name-mixedcase": "off",
"func-visibility": ["error", { "ignoreConstructors": true }],
"max-line-length": ["error", 120],
"named-parameters-mapping": "warn",
"no-console": "off",
"not-rely-on-time": "off",
"one-contract-per-file": true,
"avoid-low-level-calls": "off",
"no-inline-assembly": "off",
"func-visibility": ["warn", { "ignoreConstructors": true }],
"no-empty-blocks": "off",
"no-complex-fallback": "off"
}
Expand Down
38 changes: 29 additions & 9 deletions packages/contracts/foundry.toml
Original file line number Diff line number Diff line change
@@ -1,18 +1,38 @@
[profile.default]
solc = '0.8.21'
solc = "0.8.25"
ffi = false
fuzz_runs = 256
auto_detect_solc = false
block_timestamp = 1_680_220_800 # March 31, 2023 at 00:00 GMT
bytecode_hash = "none"
evm_version = "shanghai"
fuzz = { runs = 1_000 }
gas_reports = ["*"]
optimizer = true
optimizer_runs = 3000
optimizer_runs = 10_000
verbosity = 2
libs = ['lib']
out = 'out'
script = "script"
src = 'src'
test = 'test'
out = 'out'
libs = ['lib']
allow_paths = [
# pnpm symlinks to the project root's node_modules
"../../node_modules",
]

[profile.ci]
fuzz = { runs = 10_000 }
verbosity = 4

[etherscan]
arbitrum = { key = "${API_KEY_ARBISCAN}" }

[fmt]
bracket_spacing = true
int_types = "long"
line_length = 120
multiline_func_header = "all"
number_underscore = "thousands"
quote_style = "double"
tab_width = 2
wrap_comments = true

extra_output_files = [
"abi",
"evm.bytecode"
Expand Down
19 changes: 14 additions & 5 deletions packages/contracts/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,9 @@
"private": true,
"description": "Contracts for Protocol",
"scripts": {
"account": "node script/ListAccount.js",
"chain": "anvil --config-out localhost.json",
"compile": "forge compile",
"dev": "forge build",
"prettier": "prettier --write 'src/**/*.sol'",
"solhint": "solhint --config ./.solhint.json 'src/**/*.sol' --fix",
Expand All @@ -15,14 +18,20 @@
"deploy:arbitrum-sepolia": "source .env && FOUNDRY_PROFILE=arbitrum-sepolia forge script script/ArbitrumSepolia.s.sol:ArbitrumScript --private-key $FORGE_PRIVATE_KEY --etherscan-api-key $ETHERSCAN_API_KEY --broadcast"
},
"dependencies": {
"@ethereum-attestation-service/eas-contracts": "1.7.1"
"@ethereum-attestation-service/eas-contracts": "1.7.1",
"@openzeppelin/contracts": "4.8.3",
"@openzeppelin/contracts-upgradeable": "4.8.3"
},
"devDependencies": {
"@types/prettier": "2",
"@types/qrcode": "1",
"envfile": "~6.18.0",
"qrcode": "~1.5.3",
"toml": "~3.0.0",
"solidity-coverage": "^0.8.12",
"solhint": "^5.0.1",
"ds-test": "https://github.com/dapphub/ds-test.git#e282159d5170298eb2455a6c05280ab5a73a4ef0",
"forge-std": "https://github.com/foundry-rs/forge-std.git#74cfb77e308dd188d2f58864aaf44963ae6b88b1",
"solhint": "^5.0.3",
"forge-std": "github:foundry-rs/forge-std#v1.8.1",
"prettier": "^3.3.3",
"prettier-plugin-solidity": "^1.3.1"
"prettier-plugin-solidity": "^1.4.0"
}
}
8 changes: 4 additions & 4 deletions packages/contracts/remappings.txt
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
ds-test=./node_modules/ds-test/src/
forge-std=./node_modules/forge-std/src/
@openzeppelin/contracts=./node_modules/@openzeppelin/contracts/
@openzeppelin/contracts-upgradeable=./node_modules/@openzeppelin/contracts-upgradeable/
eas-contracts=./node_modules/@ethereum-attestation-service/eas-contracts/contracts/
forge-std=./node_modules/forge-std/src/
ds-test=./node_modules/ds-test/src/
tokenbound=./lib/tokenbound/src/
@eas=./node_modules/@ethereum-attestation-service/eas-contracts/contracts/
@tokenbound=./lib/tokenbound/src/
68 changes: 68 additions & 0 deletions packages/contracts/script/ListAccount.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,68 @@
const dotenv = require("dotenv");
dotenv.config();
const path = require("path");
const { ethers, Wallet } = require("ethers");
const QRCode = require("qrcode");
const fs = require("fs");
const toml = require("toml");

const ALCHEMY_API_KEY = process.env.ALCHEMY_API_KEY || "oKxs-03sij-U_N0iOlrSsZFr29-IqbuF";

async function getBalanceForEachNetwork(address) {
try {
// Read the foundry.toml file
const foundryTomlPath = path.join(__dirname, "..", "foundry.toml");
const tomlString = fs.readFileSync(foundryTomlPath, "utf-8");

// Parse the tomlString to get the JS object representation
const parsedToml = toml.parse(tomlString);

// Extract rpc_endpoints from parsedToml
const rpcEndpoints = parsedToml.rpc_endpoints;

// Replace placeholders in the rpc_endpoints section
function replaceENVAlchemyKey(input) {
return input.replace("${ALCHEMY_API_KEY}", ALCHEMY_API_KEY);
}

for (const networkName in rpcEndpoints) {
if (networkName === "localhost" || networkName === "default_network") continue;

const networkUrl = replaceENVAlchemyKey(rpcEndpoints[networkName]);

try {
const provider = new ethers.providers.JsonRpcProvider(networkUrl);
const balance = await provider.getBalance(address);
console.log("--", networkName, "-- 📡");
console.log(" balance:", +ethers.utils.formatEther(balance));
console.log(" nonce:", +(await provider.getTransactionCount(address)));
} catch (e) {
console.log("Can't connect to network", networkName);
console.log();
}
}
} catch (error) {
console.error("Error reading foundry.toml:", error);
}
}
async function main() {
const privateKey = process.env.DEPLOYER_PRIVATE_KEY;

if (!privateKey) {
console.log("🚫️ You don't have a deployer account. Run `yarn generate` first");
return;
}

// Get account from private key.
const wallet = new Wallet(privateKey);
const address = wallet.address;
console.log(await QRCode.toString(address, { type: "terminal", small: true }));
console.log("Public address:", address, "\n");

await getBalanceForEachNetwork(address);
}

main().catch((error) => {
console.error(error);
process.exitCode = 1;
});
49 changes: 49 additions & 0 deletions packages/contracts/script/generateAccount.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
const ethers = require("ethers");
const { parse, stringify } = require("envfile");
const fs = require("fs");

const envFilePath = "./.env";

/**
* Generate a new random private key and write it to the .env file
* @param existingEnvConfig
*/
const setNewEnvConfig = (existingEnvConfig = {}) => {
console.log("👛 Generating new Wallet");
const randomWallet = ethers.Wallet.createRandom();

const newEnvConfig = {
...existingEnvConfig,
DEPLOYER_PRIVATE_KEY: randomWallet.privateKey,
};

// Store in .env
fs.writeFileSync(envFilePath, stringify(newEnvConfig));
console.log("📄 Private Key saved to packages/foundry/.env file");
console.log("🪄 Generated wallet address:", randomWallet.address);
};

async function main() {
if (!fs.existsSync(envFilePath)) {
console.log("entered here");
// No .env file yet.
setNewEnvConfig();
return;
}

// .env file exists
const existingEnvConfig = parse(fs.readFileSync(envFilePath).toString());
if (existingEnvConfig.DEPLOYER_PRIVATE_KEY) {
console.log(
"⚠️ You already have a deployer account. Check the packages/foundry/.env file"
);
return;
}

setNewEnvConfig(existingEnvConfig);
}

main().catch((error) => {
console.error(error);
process.exitCode = 1;
});
Loading

0 comments on commit ccd83ae

Please sign in to comment.