From e665416b25a843776425cc1ec07583d7549fa7fd Mon Sep 17 00:00:00 2001 From: vignesha22 <82584664+vignesha22@users.noreply.github.com> Date: Wed, 28 Aug 2024 20:00:02 +0530 Subject: [PATCH] PRO-2641-Support_Different_EntryPoints_Addr (#129) * added support for multiple ep addresses * updated version --- backend/.env.example | 2 ++ backend/config.json.default | 2 +- backend/package.json | 2 +- backend/src/plugins/config.ts | 35 ++++++++++++++++++++++---- backend/src/routes/deposit-route.ts | 10 ++++---- backend/src/routes/metadata-routes.ts | 11 +++++--- backend/src/routes/paymaster-routes.ts | 30 +++++++++++----------- backend/src/routes/whitelist-routes.ts | 10 ++++---- backend/src/utils/common.ts | 6 ++--- docker-compose.yml | 2 ++ 10 files changed, 72 insertions(+), 38 deletions(-) diff --git a/backend/.env.example b/backend/.env.example index 4ee8d46..5d6ff47 100644 --- a/backend/.env.example +++ b/backend/.env.example @@ -9,6 +9,8 @@ ADMIN_WALLET_ADDRESS="" DEFAULT_INDEXER_ENDPOINT=http://localhost:3003 FEE_MARKUP=10 HMAC_SECRET="" +EPV_06=0x5FF137D4b0FDCD49DcA30c7CF57E578a026d2789,0x48e60BBb664aEfAc9f14aDB42e5FB5b4a119EB66 +EPV_07=0x0000000071727De22E5E9d8BAf0edAc6f37da032 # postgres database connection DATABASE_URL="postgresql://arkauser:paymaster@localhost:5432/arkadev" diff --git a/backend/config.json.default b/backend/config.json.default index 5135421..e5e06a8 100644 --- a/backend/config.json.default +++ b/backend/config.json.default @@ -47,7 +47,7 @@ }, "thresholdValue": "0.00079", "MultiTokenPaymasterOracleUsed": "chainlink", - "entryPoint": "0x5FF137D4b0FDCD49DcA30c7CF57E578a026d2789" + "entryPoint": "0x48e60BBb664aEfAc9f14aDB42e5FB5b4a119EB66" }, { "chainId": 31, diff --git a/backend/package.json b/backend/package.json index 12d587d..aae7b50 100644 --- a/backend/package.json +++ b/backend/package.json @@ -1,6 +1,6 @@ { "name": "arka", - "version": "1.4.4", + "version": "1.5.0", "description": "ARKA - (Albanian for Cashier's case) is the first open source Paymaster as a service software", "type": "module", "directories": { diff --git a/backend/src/plugins/config.ts b/backend/src/plugins/config.ts index c759720..d13299b 100644 --- a/backend/src/plugins/config.ts +++ b/backend/src/plugins/config.ts @@ -26,7 +26,9 @@ const ConfigSchema = Type.Strict( HMAC_SECRET: Type.String({ minLength: 1 }), UNSAFE_MODE: Type.Boolean() || undefined, EP7_TOKEN_VGL: Type.String() || '90000', - EP7_TOKEN_PGL: Type.String() || '150000' + EP7_TOKEN_PGL: Type.String() || '150000', + EPV_06: Type.Array(Type.String()) || ['0x5FF137D4b0FDCD49DcA30c7CF57E578a026d2789'], + EPV_07: Type.Array(Type.String()) || ['0x0000000071727De22E5E9d8BAf0edAc6f37da032'] }) ); @@ -42,8 +44,27 @@ export type ArkaConfig = Static; const configPlugin: FastifyPluginAsync = async (server) => { const validate = ajv.compile(ConfigSchema); - server.log.info("Validating .env file"); - const valid = validate(process.env); + server.log.info("Validating .env file on config"); + const envVar = { + LOG_LEVEL: process.env.LOG_LEVEL, + API_PORT: process.env.API_PORT, + API_HOST: process.env.API_HOST, + SUPPORTED_NETWORKS: process.env.SUPPORTED_NETWORKS, + ADMIN_WALLET_ADDRESS: process.env.ADMIN_WALLET_ADDRESS, + FEE_MARKUP: process.env.FEE_MARKUP, + MULTI_TOKEN_MARKUP: process.env.MULTI_TOKEN_MARKUP, + DATABASE_URL: process.env.DATABASE_URL, + DATABASE_SSL_ENABLED: process.env.DATABASE_SSL_ENABLED, + DATABASE_SCHEMA_NAME: process.env.DATABASE_SCHEMA_NAME, + HMAC_SECRET: process.env.HMAC_SECRET, + UNSAFE_MODE: process.env.UNSAFE_MODE, + EP7_TOKEN_VGL: process.env.EP7_TOKEN_VGL, + EP7_TOKEN_PGL: process.env.EP7_TOKEN_PGL, + EPV_06: process.env.EPV_06?.split(','), + EPV_07: process.env.EPV_07?.split(',') + } + + const valid = validate(envVar); if (!valid) { throw new Error( ".env file validation failed - " + @@ -51,7 +72,7 @@ const configPlugin: FastifyPluginAsync = async (server) => { ); } - server.log.info("Configuring .env file"); + server.log.info("Configuring .env file with defaultValues for optional properties"); const config = { LOG_LEVEL: process.env.LOG_LEVEL ?? '', @@ -67,9 +88,13 @@ const configPlugin: FastifyPluginAsync = async (server) => { HMAC_SECRET: process.env.HMAC_SECRET ?? '', UNSAFE_MODE: process.env.UNSAFE_MODE === 'true', EP7_TOKEN_VGL: process.env.EP7_TOKEN_VGL ?? '90000', - EP7_TOKEN_PGL: process.env.EP7_TOKEN_PGL ?? '150000' + EP7_TOKEN_PGL: process.env.EP7_TOKEN_PGL ?? '150000', + EPV_06: process.env.EPV_06?.split(',') ?? ['0x5FF137D4b0FDCD49DcA30c7CF57E578a026d2789'], + EPV_07: process.env.EPV_07?.split(',') ?? ['0x0000000071727De22E5E9d8BAf0edAc6f37da032'] } + server.log.info(config, "config:"); + server.decorate("config", config); }; diff --git a/backend/src/routes/deposit-route.ts b/backend/src/routes/deposit-route.ts index 8cd698e..c8ee459 100644 --- a/backend/src/routes/deposit-route.ts +++ b/backend/src/routes/deposit-route.ts @@ -10,14 +10,14 @@ import { decode } from "../utils/crypto.js"; import { printRequest, getNetworkConfig } from "../utils/common.js"; import { APIKey } from "../models/api-key.js"; -const SUPPORTED_ENTRYPOINTS = { - 'EPV_06': "0x5FF137D4b0FDCD49DcA30c7CF57E578a026d2789", - 'EPV_07': "0x0000000071727De22E5E9d8BAf0edAc6f37da032" -} - const depositRoutes: FastifyPluginAsync = async (server) => { const paymaster = new Paymaster(server.config.FEE_MARKUP, server.config.MULTI_TOKEN_MARKUP, server.config.EP7_TOKEN_VGL, server.config.EP7_TOKEN_PGL); + const SUPPORTED_ENTRYPOINTS = { + EPV_06: server.config.EPV_06, + EPV_07: server.config.EPV_07 + } + const prefixSecretId = 'arka_'; let client: SecretsManagerClient; diff --git a/backend/src/routes/metadata-routes.ts b/backend/src/routes/metadata-routes.ts index cc79fe3..3e8bc66 100644 --- a/backend/src/routes/metadata-routes.ts +++ b/backend/src/routes/metadata-routes.ts @@ -14,6 +14,11 @@ const metadataRoutes: FastifyPluginAsync = async (server) => { const prefixSecretId = 'arka_'; + const SUPPORTED_ENTRYPOINTS = { + EPV_06: server.config.EPV_06, + EPV_07: server.config.EPV_07 + } + let client: SecretsManagerClient; const unsafeMode: boolean = process.env.UNSAFE_MODE == "true" ? true : false; @@ -90,7 +95,7 @@ const metadataRoutes: FastifyPluginAsync = async (server) => { if (server.config.SUPPORTED_NETWORKS == '' && !SupportedNetworks) { return reply.code(ReturnCode.FAILURE).send({ error: ErrorMessage.UNSUPPORTED_NETWORK }); } - const networkConfig = getNetworkConfig(chainId, supportedNetworks ?? '', "0x5FF137D4b0FDCD49DcA30c7CF57E578a026d2789"); + const networkConfig = getNetworkConfig(chainId, supportedNetworks ?? '', SUPPORTED_ENTRYPOINTS.EPV_06); if (!networkConfig) return reply.code(ReturnCode.FAILURE).send({ error: ErrorMessage.UNSUPPORTED_NETWORK }); let bundlerUrl = networkConfig.bundler; if (bundlerUrl.includes('etherspot.io')) bundlerUrl = `${networkConfig.bundler}?api-key=${bundlerApiKey}`; @@ -108,11 +113,11 @@ const metadataRoutes: FastifyPluginAsync = async (server) => { const buffer = Buffer.from(supportedNetworks, 'base64'); const SUPPORTED_NETWORKS = JSON.parse(buffer.toString()) SUPPORTED_NETWORKS.map((element: { chainId: number, entryPoint: string }) => { - chainsSupported.push({chainId: element.chainId, entryPoint: element.entryPoint ?? "0x5FF137D4b0FDCD49DcA30c7CF57E578a026d2789"}); + chainsSupported.push({chainId: element.chainId, entryPoint: element.entryPoint}); }) } else { SupportedNetworks.map(element => { - chainsSupported.push({chainId: element.chainId, entryPoint: element.entryPoint ?? "0x5FF137D4b0FDCD49DcA30c7CF57E578a026d2789"}); + chainsSupported.push({chainId: element.chainId, entryPoint: element.entryPoint}); }) } const tokenPaymasterAddresses = { diff --git a/backend/src/routes/paymaster-routes.ts b/backend/src/routes/paymaster-routes.ts index 08504c0..24eedf9 100644 --- a/backend/src/routes/paymaster-routes.ts +++ b/backend/src/routes/paymaster-routes.ts @@ -13,14 +13,14 @@ import { printRequest, getNetworkConfig } from "../utils/common.js"; import { SponsorshipPolicy } from "../models/sponsorship-policy.js"; import { DEFAULT_EP_VERSION, EPVersions, getEPVersion } from "../types/sponsorship-policy-dto.js"; -const SUPPORTED_ENTRYPOINTS = { - 'EPV_06': "0x5FF137D4b0FDCD49DcA30c7CF57E578a026d2789", - 'EPV_07': "0x0000000071727De22E5E9d8BAf0edAc6f37da032" -} - const paymasterRoutes: FastifyPluginAsync = async (server) => { const paymaster = new Paymaster(server.config.FEE_MARKUP, server.config.MULTI_TOKEN_MARKUP, server.config.EP7_TOKEN_VGL, server.config.EP7_TOKEN_PGL); + const SUPPORTED_ENTRYPOINTS = { + EPV_06: server.config.EPV_06, + EPV_07: server.config.EPV_07 + } + const prefixSecretId = 'arka_'; let client: SecretsManagerClient; @@ -72,10 +72,10 @@ const paymasterRoutes: FastifyPluginAsync = async (server) => { } if (!api_key) return reply.code(ReturnCode.FAILURE).send({ error: ErrorMessage.INVALID_API_KEY }) - if ((entryPoint != SUPPORTED_ENTRYPOINTS.EPV_06) && (entryPoint != SUPPORTED_ENTRYPOINTS.EPV_07)) + if (!SUPPORTED_ENTRYPOINTS.EPV_06?.includes(entryPoint) && !SUPPORTED_ENTRYPOINTS.EPV_07?.includes(entryPoint)) return reply.code(ReturnCode.FAILURE).send({ error: ErrorMessage.UNSUPPORTED_ENTRYPOINT }) - if (entryPoint == SUPPORTED_ENTRYPOINTS.EPV_06) epVersion = EPVersions.EPV_06; + if (SUPPORTED_ENTRYPOINTS.EPV_06?.includes(entryPoint)) epVersion = EPVersions.EPV_06; else epVersion = EPVersions.EPV_07; let customPaymasters = []; @@ -199,7 +199,7 @@ const paymasterRoutes: FastifyPluginAsync = async (server) => { !(multiTokenOracles[chainId] && multiTokenOracles[chainId][gasToken]) ) return reply.code(ReturnCode.FAILURE).send({ error: ErrorMessage.UNSUPPORTED_NETWORK_TOKEN }) - const networkConfig = getNetworkConfig(chainId, supportedNetworks ?? '', entryPoint); + const networkConfig = getNetworkConfig(chainId, supportedNetworks ?? '', [entryPoint]); if (!networkConfig) return reply.code(ReturnCode.FAILURE).send({ error: ErrorMessage.UNSUPPORTED_NETWORK }); let bundlerUrl = networkConfig.bundler; if (networkConfig.bundler.includes('etherspot.io')) bundlerUrl = `${networkConfig.bundler}?api-key=${bundlerApiKey}`; @@ -258,7 +258,7 @@ const paymasterRoutes: FastifyPluginAsync = async (server) => { const contractWhitelistResult = await checkContractWhitelist(userOp.callData, chainId.chainId, signer.address); if (!contractWhitelistResult) throw new Error('Contract Method not whitelisted'); } - if (entryPoint == SUPPORTED_ENTRYPOINTS.EPV_06) + if (epVersion === EPVersions.EPV_06) result = await paymaster.signV06(userOp, str, str1, entryPoint, networkConfig.contracts.etherspotPaymasterAddress, bundlerUrl, signer, estimate, server.log); else { const globalWhitelistRecord = await server.whitelistRepository.findOneByApiKeyAndPolicyId(api_key); @@ -271,7 +271,7 @@ const paymasterRoutes: FastifyPluginAsync = async (server) => { break; } case 'erc20': { - if (entryPoint === SUPPORTED_ENTRYPOINTS.EPV_06) { + if (epVersion === EPVersions.EPV_06) { if ( !(PAYMASTER_ADDRESS[chainId] && PAYMASTER_ADDRESS[chainId][gasToken]) && !(customPaymasters[chainId] && customPaymasters[chainId][gasToken]) @@ -280,7 +280,7 @@ const paymasterRoutes: FastifyPluginAsync = async (server) => { if (customPaymasters[chainId] && customPaymasters[chainId][gasToken]) paymasterAddress = customPaymasters[chainId][gasToken]; else paymasterAddress = PAYMASTER_ADDRESS[chainId][gasToken] result = await paymaster.pimlico(userOp, bundlerUrl, entryPoint, paymasterAddress, server.log); - } else if (entryPoint === SUPPORTED_ENTRYPOINTS.EPV_07) { + } else if (epVersion === EPVersions.EPV_07) { if ( !(customPaymastersV2[chainId] && customPaymastersV2[chainId][gasToken]) ) return reply.code(ReturnCode.FAILURE).send({ error: ErrorMessage.UNSUPPORTED_NETWORK_TOKEN }) @@ -292,8 +292,8 @@ const paymasterRoutes: FastifyPluginAsync = async (server) => { break; } case 'multitoken': { - if (entryPoint !== SUPPORTED_ENTRYPOINTS.EPV_06) - throw new Error('Currently only 0x5FF137D4b0FDCD49DcA30c7CF57E578a026d2789 entryPoint address is supported') + if (epVersion !== EPVersions.EPV_06) + throw new Error('Currently only EPV06 entryPoint address is supported') const date = new Date(); const provider = new providers.JsonRpcProvider(bundlerUrl); const signer = new Wallet(privateKey, provider) @@ -372,11 +372,11 @@ const paymasterRoutes: FastifyPluginAsync = async (server) => { decodedData[1], true ); - for (let i=0;i { const paymaster = new Paymaster(server.config.FEE_MARKUP, server.config.MULTI_TOKEN_MARKUP, server.config.EP7_TOKEN_VGL, server.config.EP7_TOKEN_PGL); + const SUPPORTED_ENTRYPOINTS = { + EPV_06: server.config.EPV_06, + EPV_07: server.config.EPV_07 + } + const prefixSecretId = 'arka_'; let client: SecretsManagerClient; diff --git a/backend/src/utils/common.ts b/backend/src/utils/common.ts index f1de5eb..5e1aeeb 100644 --- a/backend/src/utils/common.ts +++ b/backend/src/utils/common.ts @@ -9,13 +9,13 @@ export function printRequest(methodName: string, request: FastifyRequest, log: F log.info(request.body, "body passed: "); } -export function getNetworkConfig(key: any, supportedNetworks: any, entryPoint: string) { +export function getNetworkConfig(key: any, supportedNetworks: any, entryPoint: string[]) { if (supportedNetworks !== '') { const buffer = Buffer.from(supportedNetworks, 'base64'); const SUPPORTED_NETWORKS = JSON.parse(buffer.toString()) - return SUPPORTED_NETWORKS.find((chain: any) => { return chain["chainId"] == key && chain["entryPoint"] == entryPoint }); + return SUPPORTED_NETWORKS.find((chain: any) => { return chain["chainId"] == key && entryPoint.includes(chain["entryPoint"]) }); } else - return SupportedNetworks.find((chain) => chain.chainId == key && chain.entryPoint == entryPoint); + return SupportedNetworks.find((chain) => chain.chainId == key && entryPoint.includes(chain.entryPoint)); } export function getChainIdsFromDefaultSupportedNetworks() { diff --git a/docker-compose.yml b/docker-compose.yml index 3636a75..f231cee 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -33,6 +33,8 @@ services: - DATABASE_SCHEMA_NAME=${DATABASE_SCHEMA_NAME} - DATABASE_SSL_ENABLED=${DATABASE_SSL_ENABLED} - DATABASE_SSL_REJECT_UNAUTHORIZED=${DATABASE_SSL_REJECT_UNAUTHORIZED} + - EPV_06=${EPV_06} + - EPV_07=${EPV_07} build: context: ./backend dockerfile: Dockerfile