mirror of
https://github.com/semaphore-protocol/semaphore.git
synced 2026-01-08 22:28:08 -05:00
refactor(utils): re-organize 'networks' module structure and add tests
re #715
This commit is contained in:
@@ -13,8 +13,8 @@ const projects: any = fs
|
||||
displayName: name,
|
||||
setupFiles: ["dotenv/config"],
|
||||
moduleNameMapper: {
|
||||
"@semaphore-protocol/(.*)/(.*)": "<rootDir>/../$1/src/$2.ts",
|
||||
"@semaphore-protocol/(.*)": "<rootDir>/../$1/src/index.ts"
|
||||
"@semaphore-protocol/(.*)/(.*)": "<rootDir>/../$1/src/$2",
|
||||
"@semaphore-protocol/(.*)": "<rootDir>/../$1/src"
|
||||
}
|
||||
}))
|
||||
|
||||
|
||||
@@ -24,7 +24,7 @@ export default {
|
||||
"fs",
|
||||
"path",
|
||||
"child_process",
|
||||
"@semaphore-protocol/utils/supported-networks"
|
||||
"@semaphore-protocol/utils/networks"
|
||||
],
|
||||
plugins: [
|
||||
typescript({
|
||||
|
||||
@@ -12,7 +12,7 @@ export type DeployedContracts = {
|
||||
contracts: NetworkDeployedContracts
|
||||
}[]
|
||||
|
||||
const deployedContractsPath = "../utils/src/deployed-contracts.json"
|
||||
const deployedContractsPath = "../utils/src/networks/deployed-contracts.json"
|
||||
|
||||
export function getDeployedContracts(): DeployedContracts {
|
||||
return JSON.parse(readFileSync(deployedContractsPath, "utf8"))
|
||||
|
||||
@@ -19,6 +19,12 @@ export default {
|
||||
{ file: pkg.exports.require, format: "cjs", banner, exports: "auto" },
|
||||
{ file: pkg.exports.default, format: "es", banner }
|
||||
],
|
||||
external: [...Object.keys(pkg.dependencies), "ethers/contract", "ethers/constants", "ethers/providers"],
|
||||
external: [
|
||||
...Object.keys(pkg.dependencies),
|
||||
"ethers/contract",
|
||||
"ethers/constants",
|
||||
"ethers/providers",
|
||||
"@semaphore-protocol/utils/networks"
|
||||
],
|
||||
plugins: [json(), typescript({ tsconfig: "./build.tsconfig.json" }), cleanup({ comments: "jsdoc" })]
|
||||
}
|
||||
|
||||
@@ -1,5 +1,9 @@
|
||||
import { SupportedNetwork, getDeployedContract, isSupportedNetwork } from "@semaphore-protocol/utils"
|
||||
import { defaultNetwork } from "@semaphore-protocol/utils/networks"
|
||||
import {
|
||||
SupportedNetwork,
|
||||
defaultNetwork,
|
||||
getDeployedContract,
|
||||
isSupportedNetwork
|
||||
} from "@semaphore-protocol/utils/networks"
|
||||
import { ZeroAddress } from "ethers/constants"
|
||||
import { Contract } from "ethers/contract"
|
||||
import {
|
||||
|
||||
@@ -1,5 +1,4 @@
|
||||
import type { SupportedNetwork } from "@semaphore-protocol/utils"
|
||||
import { defaultNetwork } from "@semaphore-protocol/utils/networks"
|
||||
import { defaultNetwork, SupportedNetwork } from "@semaphore-protocol/utils/networks"
|
||||
import { AxiosRequestConfig } from "axios"
|
||||
import checkParameter from "./checkParameter"
|
||||
import getURL from "./getURL"
|
||||
|
||||
@@ -35,7 +35,8 @@ export default {
|
||||
"ethers/utils",
|
||||
"ethers/abi",
|
||||
"@zk-kit/utils/error-handlers",
|
||||
"@zk-kit/utils/proof-packing"
|
||||
"@zk-kit/utils/proof-packing",
|
||||
"@semaphore-protocol/utils/constants"
|
||||
],
|
||||
plugins: [
|
||||
alias({
|
||||
|
||||
@@ -40,7 +40,8 @@ export default {
|
||||
"ethers/utils",
|
||||
"ethers/abi",
|
||||
"@zk-kit/utils/error-handlers",
|
||||
"@zk-kit/utils/proof-packing"
|
||||
"@zk-kit/utils/proof-packing",
|
||||
"@semaphore-protocol/utils/constants"
|
||||
],
|
||||
plugins: [
|
||||
typescript({
|
||||
|
||||
@@ -13,9 +13,9 @@
|
||||
"default": "./dist/index.js"
|
||||
},
|
||||
"./networks": {
|
||||
"types": "./dist/types/networks.d.ts",
|
||||
"require": "./dist/lib.commonjs/networks.cjs",
|
||||
"default": "./dist/lib.esm/networks.js"
|
||||
"types": "./dist/types/networks/index.d.ts",
|
||||
"require": "./dist/lib.commonjs/networks/index.cjs",
|
||||
"default": "./dist/lib.esm/networks/index.js"
|
||||
},
|
||||
"./constants": {
|
||||
"types": "./dist/types/constants.d.ts",
|
||||
|
||||
@@ -20,6 +20,7 @@ export default [
|
||||
{ file: pkg.exports["."].require, format: "cjs", banner, exports: "auto" },
|
||||
{ file: pkg.exports["."].default, format: "es", banner }
|
||||
],
|
||||
external: [...Object.keys(pkg.dependencies), "ethers/abi", "ethers/utils"],
|
||||
plugins: [
|
||||
typescript({
|
||||
tsconfig: "./build.tsconfig.json"
|
||||
@@ -40,6 +41,7 @@ export default [
|
||||
},
|
||||
{ dir: "./dist/lib.esm", format: "es", banner, preserveModules: true }
|
||||
],
|
||||
external: [...Object.keys(pkg.dependencies), "ethers/abi", "ethers/utils"],
|
||||
plugins: [
|
||||
typescript({
|
||||
tsconfig: "./build.tsconfig.json",
|
||||
|
||||
@@ -1,71 +0,0 @@
|
||||
import deployedContracts from "./deployed-contracts.json"
|
||||
|
||||
// List of Semaphore supported networks.
|
||||
export const supportedNetworks = {
|
||||
sepolia: {
|
||||
name: "Sepolia",
|
||||
url: "https://rpc2.sepolia.org",
|
||||
chainId: 11155111,
|
||||
explorer: "https://sepolia.etherscan.io"
|
||||
},
|
||||
"arbitrum-sepolia": {
|
||||
name: "Arbitrum Sepolia",
|
||||
url: "https://sepolia-rollup.arbitrum.io/rpc",
|
||||
chainId: 421614,
|
||||
explorer: "https://sepolia.arbiscan.io"
|
||||
},
|
||||
"optimism-sepolia": {
|
||||
name: "Optimism Sepolia",
|
||||
url: "https://sepolia.optimism.io",
|
||||
chainId: 11155420,
|
||||
explorer: "https://sepolia-optimism.etherscan.io"
|
||||
},
|
||||
"matic-mumbai": {
|
||||
name: "Matic Mumbai",
|
||||
url: "https://rpc-mumbai.polygon.technology",
|
||||
chainId: 80001,
|
||||
explorer: "https://mumbai.polygonscan.com"
|
||||
}
|
||||
// "arbitrum"
|
||||
}
|
||||
|
||||
export type SupportedNetwork = keyof typeof supportedNetworks
|
||||
|
||||
// Default Semaphore network.
|
||||
export const defaultNetwork: SupportedNetwork = "sepolia"
|
||||
|
||||
export function isSupportedNetwork(supportedNetwork: string): boolean {
|
||||
return Object.keys(supportedNetworks).includes(supportedNetwork)
|
||||
}
|
||||
|
||||
export function getHardhatNetworks(account?: string) {
|
||||
if (!account) {
|
||||
return {}
|
||||
}
|
||||
|
||||
const supportedNetworks2 = JSON.parse(JSON.stringify(supportedNetworks))
|
||||
|
||||
for (const key in supportedNetworks2) {
|
||||
if (Object.prototype.hasOwnProperty.call(supportedNetworks2, key)) {
|
||||
supportedNetworks2[key].accounts = [`0x${account}`]
|
||||
}
|
||||
}
|
||||
|
||||
return supportedNetworks2
|
||||
}
|
||||
|
||||
export function getDeployedContract(supportedNetwork: SupportedNetwork) {
|
||||
if (!isSupportedNetwork(supportedNetwork)) {
|
||||
throw new Error(`Semaphore has not been deployed on '${supportedNetwork}' yet`)
|
||||
}
|
||||
|
||||
const deployedContract = deployedContracts.find(({ network }) => network === supportedNetwork)
|
||||
|
||||
return deployedContract!.contracts.find(({ name }) => name === "Semaphore") as {
|
||||
name: string
|
||||
address: string
|
||||
startBlock: number
|
||||
}
|
||||
}
|
||||
|
||||
export { deployedContracts }
|
||||
66
packages/utils/src/networks/index.ts
Normal file
66
packages/utils/src/networks/index.ts
Normal file
@@ -0,0 +1,66 @@
|
||||
/**
|
||||
* @module Networks
|
||||
* This module provides a collection of utility functions to provide the other internal
|
||||
* packages and developers with information on deployed contracts and networks supported
|
||||
* by Semaphore.
|
||||
*/
|
||||
|
||||
import deployedContracts from "./deployed-contracts.json"
|
||||
import supportedNetworks from "./supported-networks"
|
||||
|
||||
export type SupportedNetwork = keyof typeof supportedNetworks
|
||||
|
||||
// Default Semaphore network.
|
||||
export const defaultNetwork: SupportedNetwork = "sepolia"
|
||||
|
||||
/**
|
||||
* Returns true if a network is supported by Semaphore, false otherwise.
|
||||
* @param supportedNetwork The network to be checked.
|
||||
*/
|
||||
export function isSupportedNetwork(supportedNetwork: string): boolean {
|
||||
return Object.keys(supportedNetworks).includes(supportedNetwork)
|
||||
}
|
||||
|
||||
/**
|
||||
* Utility function to get an object compatible with the Hardhat 'networks' option.
|
||||
* If the private key is not defined it returns an empty object.
|
||||
* @param privateKey Private key to be used with networks.
|
||||
* @returns An object compatible with the Hardhat 'networks' option.
|
||||
*/
|
||||
export function getHardhatNetworks(privateKey?: string) {
|
||||
if (!privateKey) {
|
||||
return {}
|
||||
}
|
||||
|
||||
const supportedNetworksCopy = JSON.parse(JSON.stringify(supportedNetworks))
|
||||
|
||||
for (const key in supportedNetworksCopy) {
|
||||
if (Object.prototype.hasOwnProperty.call(supportedNetworksCopy, key)) {
|
||||
supportedNetworksCopy[key].accounts = [`0x${privateKey}`]
|
||||
}
|
||||
}
|
||||
|
||||
return supportedNetworksCopy
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns name, address and start block of a Semaphore contract deployed
|
||||
* on a specific supported network.
|
||||
* @param The network supported by Semaphore.
|
||||
* @returns An object with name, address and start block of the deployed contract.
|
||||
*/
|
||||
export function getDeployedContract(supportedNetwork: SupportedNetwork) {
|
||||
if (!isSupportedNetwork(supportedNetwork)) {
|
||||
throw new Error(`Semaphore has not been deployed on '${supportedNetwork}' yet`)
|
||||
}
|
||||
|
||||
const deployedContract = deployedContracts.find(({ network }) => network === supportedNetwork)
|
||||
|
||||
return deployedContract!.contracts.find(({ name }) => name === "Semaphore") as {
|
||||
name: string
|
||||
address: string
|
||||
startBlock: number
|
||||
}
|
||||
}
|
||||
|
||||
export { deployedContracts, supportedNetworks }
|
||||
26
packages/utils/src/networks/supported-networks.ts
Normal file
26
packages/utils/src/networks/supported-networks.ts
Normal file
@@ -0,0 +1,26 @@
|
||||
export default {
|
||||
sepolia: {
|
||||
name: "Sepolia",
|
||||
url: "https://rpc2.sepolia.org",
|
||||
chainId: 11155111,
|
||||
explorer: "https://sepolia.etherscan.io"
|
||||
},
|
||||
"arbitrum-sepolia": {
|
||||
name: "Arbitrum Sepolia",
|
||||
url: "https://sepolia-rollup.arbitrum.io/rpc",
|
||||
chainId: 421614,
|
||||
explorer: "https://sepolia.arbiscan.io"
|
||||
},
|
||||
"optimism-sepolia": {
|
||||
name: "Optimism Sepolia",
|
||||
url: "https://sepolia.optimism.io",
|
||||
chainId: 11155420,
|
||||
explorer: "https://sepolia-optimism.etherscan.io"
|
||||
},
|
||||
"matic-mumbai": {
|
||||
name: "Matic Mumbai",
|
||||
url: "https://rpc-mumbai.polygon.technology",
|
||||
chainId: 80001,
|
||||
explorer: "https://mumbai.polygonscan.com"
|
||||
}
|
||||
}
|
||||
@@ -1,25 +1,49 @@
|
||||
import { encodeBytes32String } from "ethers/abi"
|
||||
import { toBigInt } from "ethers/utils"
|
||||
import decodeMessage from "../src/decode-message"
|
||||
import { getDeployedContract, isSupportedNetwork } from "../src/networks"
|
||||
import { getDeployedContract, getHardhatNetworks, isSupportedNetwork, supportedNetworks } from "../src/networks"
|
||||
|
||||
describe("Utils", () => {
|
||||
describe("# isSupportedNetwork", () => {
|
||||
it("Should return true if the network is supported", () => {
|
||||
expect(isSupportedNetwork("sepolia")).toBeTruthy()
|
||||
describe("# networks", () => {
|
||||
describe("# isSupportedNetwork", () => {
|
||||
it("Should return true if the network is supported", () => {
|
||||
expect(isSupportedNetwork("sepolia")).toBeTruthy()
|
||||
})
|
||||
|
||||
it("Should return false if the network is not supported", () => {
|
||||
expect(isSupportedNetwork("hello")).toBeFalsy()
|
||||
})
|
||||
})
|
||||
|
||||
it("Should return false if the network is not supported", () => {
|
||||
expect(isSupportedNetwork("hello")).toBeFalsy()
|
||||
describe("# getDeployedContract", () => {
|
||||
it("Should return Semaphore deployment data for Sepolia", () => {
|
||||
const { address, startBlock } = getDeployedContract("sepolia")
|
||||
|
||||
expect(address).toHaveLength(42)
|
||||
expect(typeof startBlock).toBe("number")
|
||||
})
|
||||
|
||||
it("Should throw an error if the network is not supported", () => {
|
||||
const fun = () => getDeployedContract("hello" as any)
|
||||
|
||||
expect(fun).toThrow("Semaphore has not been deployed on 'hello' yet")
|
||||
})
|
||||
})
|
||||
})
|
||||
|
||||
describe("# getDeployedContract", () => {
|
||||
it("Should return Semaphore deployment data for Sepolia", () => {
|
||||
const { address, startBlock } = getDeployedContract("sepolia")
|
||||
describe("# getHardhatNetworks", () => {
|
||||
it("Should return an empty object if the private key is not defined", () => {
|
||||
const networks = getHardhatNetworks()
|
||||
|
||||
expect(address).toHaveLength(42)
|
||||
expect(typeof startBlock).toBe("number")
|
||||
expect(networks).toEqual({})
|
||||
})
|
||||
|
||||
it("Should return a list of networks compatible with the Hardhat 'networks' object", () => {
|
||||
const networks = getHardhatNetworks("ec12f72ab17a2f14cf538a1a2455d6cd94ec99a90e8d8be591f987744b7b440f")
|
||||
|
||||
expect(Object.keys(networks)).toEqual(Object.keys(supportedNetworks))
|
||||
expect(Object.keys(networks)).toHaveLength(Object.keys(supportedNetworks).length)
|
||||
expect(networks.sepolia.accounts).toHaveLength(1)
|
||||
})
|
||||
})
|
||||
})
|
||||
|
||||
|
||||
Reference in New Issue
Block a user