From fc3e8009ef56c8430fee782a67869c01fe0f9351 Mon Sep 17 00:00:00 2001 From: vignesha22 <82584664+vignesha22@users.noreply.github.com> Date: Thu, 22 Aug 2024 22:30:56 +0530 Subject: [PATCH] Change NetworkConfig (#127) --- admin_frontend/package-lock.json | 4 +- admin_frontend/package.json | 2 +- backend/config.json.default | 50 +++++++++---------- .../2024082200001-update-api-keys.cjs | 11 ++++ backend/package.json | 2 +- backend/src/models/api-key.ts | 7 +++ backend/src/repository/api-key-repository.ts | 3 +- backend/src/routes/admin-routes.ts | 6 ++- backend/src/routes/deposit-route.ts | 18 ++++++- backend/src/routes/metadata-routes.ts | 11 +++- backend/src/routes/paymaster-routes.ts | 12 ++++- backend/src/routes/pimlico-routes.ts | 8 +++ backend/src/routes/whitelist-routes.ts | 48 +++++++++++++++++- backend/src/types/apikey-dto.ts | 1 + frontend/package-lock.json | 4 +- frontend/package.json | 2 +- 16 files changed, 150 insertions(+), 39 deletions(-) create mode 100644 backend/migrations/2024082200001-update-api-keys.cjs diff --git a/admin_frontend/package-lock.json b/admin_frontend/package-lock.json index 333a723..1f69dca 100644 --- a/admin_frontend/package-lock.json +++ b/admin_frontend/package-lock.json @@ -1,12 +1,12 @@ { "name": "admin_frontend", - "version": "1.4.0", + "version": "1.4.3", "lockfileVersion": 3, "requires": true, "packages": { "": { "name": "admin_frontend", - "version": "1.4.0", + "version": "1.4.3", "dependencies": { "@emotion/react": "11.11.3", "@emotion/styled": "11.11.0", diff --git a/admin_frontend/package.json b/admin_frontend/package.json index a2485ea..508ad2f 100644 --- a/admin_frontend/package.json +++ b/admin_frontend/package.json @@ -1,6 +1,6 @@ { "name": "admin_frontend", - "version": "1.4.0", + "version": "1.4.3", "private": true, "dependencies": { "@emotion/react": "11.11.3", diff --git a/backend/config.json.default b/backend/config.json.default index a65a276..5135421 100644 --- a/backend/config.json.default +++ b/backend/config.json.default @@ -1,7 +1,7 @@ [ { "chainId": 1, - "bundler": "https://ethereum-bundler.etherspot.io/", + "bundler": "https://rpc.etherspot.io/ethereum", "contracts": { "etherspotPaymasterAddress": "0x7F690e93CecFca5A31E6e1dF50A33F6d3059048c" }, @@ -11,7 +11,7 @@ }, { "chainId": 10, - "bundler": "https://optimism-bundler.etherspot.io", + "bundler": "https://rpc.etherspot.io/optimism", "contracts": { "etherspotPaymasterAddress": "0x805650ce74561C85baA44a8Bd13E19633Fd0F79d" }, @@ -21,7 +21,7 @@ }, { "chainId": 14, - "bundler": "https://flare-bundler.etherspot.io", + "bundler": "https://rpc.etherspot.io/flare", "contracts": { "etherspotPaymasterAddress": "0x8A41594e5c6Fe492e437414c24eA6f401186b8d2" }, @@ -31,7 +31,7 @@ }, { "chainId": 30, - "bundler": "https://rootstock-bundler.etherspot.io", + "bundler": "https://rpc.etherspot.io/rootstock", "contracts": { "etherspotPaymasterAddress": "0xe893A26dD53b325bFFaACdFA224692EFF4C448C4" }, @@ -59,6 +59,16 @@ "MultiTokenPaymasterOracleUsed": "chainlink", "entryPoint": "0x0000000071727De22E5E9d8BAf0edAc6f37da032" }, + { + "chainId": 50, + "bundler": "https://rpc.etherspot.io/v2/50", + "contracts": { + "etherspotPaymasterAddress": "0xABA00E929d66119A4A7F4B2E27150fC387ee801c" + }, + "thresholdValue": "0.01", + "MultiTokenPaymasterOracleUsed": "chainlink", + "entryPoint": "0x0000000071727De22E5E9d8BAf0edAc6f37da032" + }, { "chainId": 51, "bundler": "https://testnet-rpc.etherspot.io/v2/51", @@ -71,7 +81,7 @@ }, { "chainId": 56, - "bundler": "https://bnb-bundler.etherspot.io/", + "bundler": "https://rpc.etherspot.io/bnb", "contracts": { "etherspotPaymasterAddress": "0xEA5ecE95D3A28f9faB161779d20128b449F9EC9C" }, @@ -101,7 +111,7 @@ }, { "chainId": 100, - "bundler": "https://gnosis-bundler.etherspot.io/", + "bundler": "https://rpc.etherspot.io/gnosis", "contracts": { "etherspotPaymasterAddress": "0x373aBcF1EA9e5802778E32870e7f72C8A6a90349" }, @@ -131,7 +141,7 @@ }, { "chainId": 122, - "bundler": "https://fuse-bundler.etherspot.io", + "bundler": "https://rpc.etherspot.io/fuse", "contracts": { "etherspotPaymasterAddress": "0xEC2EE24E79C73DB13Dd9bC782856a5296626b7eb" }, @@ -161,7 +171,7 @@ }, { "chainId": 137, - "bundler": "https://polygon-bundler.etherspot.io", + "bundler": "https://rpc.etherspot.io/polygon", "contracts": { "etherspotPaymasterAddress": "0x26FeC24b0D467C9de105217B483931e8f944ff50" }, @@ -181,7 +191,7 @@ }, { "chainId": 5000, - "bundler": "https://mantle-bundler.etherspot.io/", + "bundler": "https://rpc.etherspot.io/mantle", "contracts": { "etherspotPaymasterAddress": "0x8A41594e5c6Fe492e437414c24eA6f401186b8d2" }, @@ -209,19 +219,9 @@ "MultiTokenPaymasterOracleUsed": "chainlink", "entryPoint": "0x0000000071727De22E5E9d8BAf0edAc6f37da032" }, - { - "chainId": 8217, - "bundler": "https://klaytn-bundler.etherspot.io/", - "contracts": { - "etherspotPaymasterAddress": "0x4ebd86AAF89151b5303DB072e0205C668e31E5E7" - }, - "thresholdValue": "275.2", - "MultiTokenPaymasterOracleUsed": "chainlink", - "entryPoint": "0x5FF137D4b0FDCD49DcA30c7CF57E578a026d2789" - }, { "chainId": 8453, - "bundler": "https://base-bundler.etherspot.io/", + "bundler": "https://rpc.etherspot.io/base", "contracts": { "etherspotPaymasterAddress": "0x810FA4C915015b703db0878CF2B9344bEB254a40" }, @@ -241,7 +241,7 @@ }, { "chainId": 42161, - "bundler": "https://arbitrum-bundler.etherspot.io", + "bundler": "https://rpc.etherspot.io/arbitrum", "contracts": { "etherspotPaymasterAddress": "0xEC2EE24E79C73DB13Dd9bC782856a5296626b7eb" }, @@ -261,7 +261,7 @@ }, { "chainId": 43114, - "bundler": "https://avalanche-bundler.etherspot.io/", + "bundler": "https://rpc.etherspot.io/avalanche", "contracts": { "etherspotPaymasterAddress": "0x527569794781671319f20374A050BDbef4181aB3" }, @@ -271,7 +271,7 @@ }, { "chainId": 59144, - "bundler": "https://linea-bundler.etherspot.io/", + "bundler": "https://rpc.etherspot.io/linea", "contracts": { "etherspotPaymasterAddress": "0xB3AD9B9B06c6016f81404ee8FcCD0526F018Cf0C" }, @@ -361,7 +361,7 @@ }, { "chainId": 534352, - "bundler": "https://scroll-bundler.etherspot.io", + "bundler": "https://rpc.etherspot.io/scroll", "contracts": { "etherspotPaymasterAddress": "0xB3AD9B9B06c6016f81404ee8FcCD0526F018Cf0C" }, @@ -431,7 +431,7 @@ }, { "chainId": 888888888, - "bundler": "https://ancient8-bundler.etherspot.io", + "bundler": "https://rpc.etherspot.io/ancient8", "contracts": { "etherspotPaymasterAddress": "0x810FA4C915015b703db0878CF2B9344bEB254a40" }, diff --git a/backend/migrations/2024082200001-update-api-keys.cjs b/backend/migrations/2024082200001-update-api-keys.cjs new file mode 100644 index 0000000..70eb504 --- /dev/null +++ b/backend/migrations/2024082200001-update-api-keys.cjs @@ -0,0 +1,11 @@ +require('dotenv').config(); + +async function up({ context: queryInterface }) { + await queryInterface.sequelize.query(`ALTER TABLE IF EXISTS "${process.env.DATABASE_SCHEMA_NAME}".api_keys ADD COLUMN "BUNDLER_API_KEY" text default null`); +} + +async function down({ context: queryInterface }) { + await queryInterface.sequelize.query(`ALTER TABLE "${process.env.DATABASE_SCHEMA_NAME}".api_keys DROP COLUMN BUNDLER_API_KEY;`); +} + +module.exports = { up, down } \ No newline at end of file diff --git a/backend/package.json b/backend/package.json index e370afc..e14bb6f 100644 --- a/backend/package.json +++ b/backend/package.json @@ -1,6 +1,6 @@ { "name": "arka", - "version": "1.4.2", + "version": "1.4.3", "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/models/api-key.ts b/backend/src/models/api-key.ts index 6da8801..78c74ec 100644 --- a/backend/src/models/api-key.ts +++ b/backend/src/models/api-key.ts @@ -11,6 +11,7 @@ export class APIKey extends Model { public multiTokenOracles?: string | null; public sponsorName?: string | null; public logoUrl?: string | null; + public bundlerApiKey?: string | null; public transactionLimit!: number; public noOfTransactionsInAMonth?: number | null; public indexerEndpoint?: string | null; @@ -53,6 +54,12 @@ export function initializeAPIKeyModel(sequelize: Sequelize, schema: string) { allowNull: true, field: 'ERC20_PAYMASTERS_V2' }, + bundlerApiKey: { + type: DataTypes.TEXT, + allowNull: true, + field: 'BUNDLER_API_KEY', + defaultValue: null + }, multiTokenPaymasters: { type: DataTypes.TEXT, allowNull: true, diff --git a/backend/src/repository/api-key-repository.ts b/backend/src/repository/api-key-repository.ts index 08d3bf2..027e192 100644 --- a/backend/src/repository/api-key-repository.ts +++ b/backend/src/repository/api-key-repository.ts @@ -23,7 +23,8 @@ export class APIKeyRepository { logoUrl: apiKey.logoUrl, transactionLimit: apiKey.transactionLimit, noOfTransactionsInAMonth: apiKey.noOfTransactionsInAMonth, - indexerEndpoint: apiKey.indexerEndpoint + indexerEndpoint: apiKey.indexerEndpoint, + bundlerApiKey: apiKey.bundlerApiKey, }) as APIKey; diff --git a/backend/src/routes/admin-routes.ts b/backend/src/routes/admin-routes.ts index 9a742ea..f7ed789 100644 --- a/backend/src/routes/admin-routes.ts +++ b/backend/src/routes/admin-routes.ts @@ -110,7 +110,8 @@ const adminRoutes: FastifyPluginAsync = async (server) => { logoUrl: body.logoUrl ?? null, transactionLimit: body.transactionLimit ?? 0, noOfTransactionsInAMonth: body.noOfTransactionsInAMonth ?? 10, - indexerEndpoint: body.indexerEndpoint ?? process.env.DEFAULT_INDEXER_ENDPOINT + indexerEndpoint: body.indexerEndpoint ?? process.env.DEFAULT_INDEXER_ENDPOINT, + bundlerApiKey: body.bundlerApiKey ?? null, }); return reply.code(ReturnCode.SUCCESS).send({ error: null, message: 'Successfully saved' }); @@ -141,7 +142,8 @@ const adminRoutes: FastifyPluginAsync = async (server) => { erc20Paymasters: body.erc20Paymasters, transactionLimit: body.transactionLimit ?? 0, noOfTransactionsInAMonth: body.noOfTransactionsInAMonth ?? 10, - indexerEndpoint: body.indexerEndpoint ?? process.env.DEFAULT_INDEXER_ENDPOINT + indexerEndpoint: body.indexerEndpoint ?? process.env.DEFAULT_INDEXER_ENDPOINT, + bundlerApiKey: body.bundlerApiKey ?? null, }); return reply.code(ReturnCode.SUCCESS).send({ error: null, message: 'Successfully updated' }); diff --git a/backend/src/routes/deposit-route.ts b/backend/src/routes/deposit-route.ts index 1acbcec..e7c88c3 100644 --- a/backend/src/routes/deposit-route.ts +++ b/backend/src/routes/deposit-route.ts @@ -16,7 +16,7 @@ const SUPPORTED_ENTRYPOINTS = { } const depositRoutes: FastifyPluginAsync = async (server) => { - const paymaster = new Paymaster(server.config.FEE_MARKUP, server.config.MULTI_TOKEN_MARKUP); + const paymaster = new Paymaster(server.config.FEE_MARKUP, server.config.MULTI_TOKEN_MARKUP, server.config.EP7_TOKEN_VGL, server.config.EP7_TOKEN_PGL); const prefixSecretId = 'arka_'; @@ -55,6 +55,7 @@ const depositRoutes: FastifyPluginAsync = async (server) => { return reply.code(ReturnCode.FAILURE).send({ error: ErrorMessage.INVALID_API_KEY }) let privateKey = ''; let supportedNetworks; + let bundlerApiKey = api_key; if (!unsafeMode) { const AWSresponse = await client.send( new GetSecretValueCommand({ @@ -63,6 +64,9 @@ const depositRoutes: FastifyPluginAsync = async (server) => { ); const secrets = JSON.parse(AWSresponse.SecretString ?? '{}'); if (!secrets['PRIVATE_KEY']) return reply.code(ReturnCode.FAILURE).send({ error: ErrorMessage.INVALID_API_KEY }) + if (secrets['BUNDLER_API_KEY']) { + bundlerApiKey = secrets['BUNDLER_API_KEY']; + } privateKey = secrets['PRIVATE_KEY']; supportedNetworks = secrets['SUPPORTED_NETWORKS']; } else { @@ -70,6 +74,9 @@ const depositRoutes: FastifyPluginAsync = async (server) => { if (!apiKeyEntity) return reply.code(ReturnCode.FAILURE).send({ error: ErrorMessage.INVALID_API_KEY }) privateKey = decode(apiKeyEntity.privateKey, server.config.HMAC_SECRET); supportedNetworks = apiKeyEntity.supportedNetworks; + if (apiKeyEntity.bundlerApiKey) { + bundlerApiKey = apiKeyEntity.bundlerApiKey; + } } if ( isNaN(amount) || @@ -83,6 +90,7 @@ const depositRoutes: FastifyPluginAsync = async (server) => { } const networkConfig = getNetworkConfig(chainId, supportedNetworks ?? '', SUPPORTED_ENTRYPOINTS.EPV_06); if (!networkConfig) return reply.code(ReturnCode.FAILURE).send({ error: ErrorMessage.UNSUPPORTED_NETWORK }); + if (networkConfig.bundler.includes('etherspot.io')) networkConfig.bundler = `${networkConfig.bundler}?api-key=${bundlerApiKey}`; return await paymaster.deposit(amount, networkConfig.contracts.etherspotPaymasterAddress, networkConfig.bundler, privateKey, chainId, true, server.log); } catch (err: any) { request.log.error(err); @@ -107,6 +115,7 @@ const depositRoutes: FastifyPluginAsync = async (server) => { return reply.code(ReturnCode.FAILURE).send({ error: ErrorMessage.INVALID_API_KEY }) let privateKey = ''; let supportedNetworks; + let bundlerApiKey = api_key; if (!unsafeMode) { const AWSresponse = await client.send( new GetSecretValueCommand({ @@ -115,6 +124,9 @@ const depositRoutes: FastifyPluginAsync = async (server) => { ); const secrets = JSON.parse(AWSresponse.SecretString ?? '{}'); if (!secrets['PRIVATE_KEY']) return reply.code(ReturnCode.FAILURE).send({ error: ErrorMessage.INVALID_API_KEY }) + if (secrets['BUNDLER_API_KEY']) { + bundlerApiKey = secrets['BUNDLER_API_KEY']; + } privateKey = secrets['PRIVATE_KEY']; supportedNetworks = secrets['SUPPORTED_NETWORKS']; } else { @@ -122,6 +134,9 @@ const depositRoutes: FastifyPluginAsync = async (server) => { if (!apiKeyEntity) return reply.code(ReturnCode.FAILURE).send({ error: ErrorMessage.INVALID_API_KEY }) privateKey = decode(apiKeyEntity.privateKey, server.config.HMAC_SECRET); supportedNetworks = apiKeyEntity.supportedNetworks; + if (apiKeyEntity.bundlerApiKey) { + bundlerApiKey = apiKeyEntity.bundlerApiKey; + } } if ( isNaN(amount) || @@ -135,6 +150,7 @@ const depositRoutes: FastifyPluginAsync = async (server) => { } const networkConfig = getNetworkConfig(chainId, supportedNetworks ?? '', SUPPORTED_ENTRYPOINTS.EPV_07); if (!networkConfig) return reply.code(ReturnCode.FAILURE).send({ error: ErrorMessage.UNSUPPORTED_NETWORK }); + if (networkConfig.bundler.includes('etherspot.io')) networkConfig.bundler = `${networkConfig.bundler}?api-key=${bundlerApiKey}`; return await paymaster.deposit(amount, networkConfig.contracts.etherspotPaymasterAddress, networkConfig.bundler, privateKey, chainId, false, server.log); } catch (err: any) { request.log.error(err); diff --git a/backend/src/routes/metadata-routes.ts b/backend/src/routes/metadata-routes.ts index cefa106..cc79fe3 100644 --- a/backend/src/routes/metadata-routes.ts +++ b/backend/src/routes/metadata-routes.ts @@ -38,6 +38,7 @@ const metadataRoutes: FastifyPluginAsync = async (server) => { let privateKey = ''; let supportedNetworks; let sponsorName = '', sponsorImage = ''; + let bundlerApiKey = api_key; if (!unsafeMode) { const AWSresponse = await client.send( new GetSecretValueCommand({ @@ -57,6 +58,9 @@ const metadataRoutes: FastifyPluginAsync = async (server) => { const buffer = Buffer.from(secrets['MULTI_TOKEN_PAYMASTERS'], 'base64'); multiTokenPaymasters = JSON.parse(buffer.toString()); } + if (secrets['BUNDLER_API_KEY']) { + bundlerApiKey = secrets['BUNDLER_API_KEY']; + } sponsorName = secrets['SPONSOR_NAME']; sponsorImage = secrets['LOGO_URL']; privateKey = secrets['PRIVATE_KEY']; @@ -75,6 +79,9 @@ const metadataRoutes: FastifyPluginAsync = async (server) => { const buffer = Buffer.from(apiKeyEntity.multiTokenPaymasters, 'base64'); multiTokenPaymasters = JSON.parse(buffer.toString()); } + if (apiKeyEntity.bundlerApiKey) { + bundlerApiKey = apiKeyEntity.bundlerApiKey; + } sponsorName = apiKeyEntity.sponsorName ? apiKeyEntity.sponsorName : ""; sponsorImage = apiKeyEntity.logoUrl ? apiKeyEntity.logoUrl : ""; privateKey = decode(apiKeyEntity.privateKey, server.config.HMAC_SECRET); @@ -85,7 +92,9 @@ const metadataRoutes: FastifyPluginAsync = async (server) => { } const networkConfig = getNetworkConfig(chainId, supportedNetworks ?? '', "0x5FF137D4b0FDCD49DcA30c7CF57E578a026d2789"); if (!networkConfig) return reply.code(ReturnCode.FAILURE).send({ error: ErrorMessage.UNSUPPORTED_NETWORK }); - const provider = new providers.JsonRpcProvider(networkConfig.bundler); + let bundlerUrl = networkConfig.bundler; + if (bundlerUrl.includes('etherspot.io')) bundlerUrl = `${networkConfig.bundler}?api-key=${bundlerApiKey}`; + const provider = new providers.JsonRpcProvider(bundlerUrl); const signer = new Wallet(privateKey, provider) const sponsorWalletBalance = await signer.getBalance(); const sponsorAddress = await signer.getAddress(); diff --git a/backend/src/routes/paymaster-routes.ts b/backend/src/routes/paymaster-routes.ts index 9c291e4..d495d17 100644 --- a/backend/src/routes/paymaster-routes.ts +++ b/backend/src/routes/paymaster-routes.ts @@ -89,6 +89,7 @@ const paymasterRoutes: FastifyPluginAsync = async (server) => { let indexerEndpoint; let sponsorName = '', sponsorImage = ''; let contractWhitelistMode = false; + let bundlerApiKey = api_key; if (!unsafeMode) { const AWSresponse = await client.send( new GetSecretValueCommand({ @@ -116,6 +117,9 @@ const paymasterRoutes: FastifyPluginAsync = async (server) => { const buffer = Buffer.from(secrets['MULTI_TOKEN_ORACLES'], 'base64'); multiTokenOracles = JSON.parse(buffer.toString()); } + if (secrets['BUNDLER_API_KEY']) { + bundlerApiKey = secrets['BUNDLER_API_KEY']; + } sponsorName = secrets['SPONSOR_NAME']; sponsorImage = secrets['LOGO_URL']; privateKey = secrets['PRIVATE_KEY']; @@ -158,6 +162,11 @@ const paymasterRoutes: FastifyPluginAsync = async (server) => { const buffer = Buffer.from(apiKeyEntity.multiTokenOracles, 'base64'); multiTokenOracles = JSON.parse(buffer.toString()); } + + if (apiKeyEntity.bundlerApiKey) { + bundlerApiKey = apiKeyEntity.bundlerApiKey; + } + sponsorName = apiKeyEntity.sponsorName ? apiKeyEntity.sponsorName : ''; sponsorImage = apiKeyEntity.logoUrl ? apiKeyEntity.logoUrl : ''; privateKey = decode(apiKeyEntity.privateKey, server.config.HMAC_SECRET); @@ -191,8 +200,9 @@ const paymasterRoutes: FastifyPluginAsync = async (server) => { ) return reply.code(ReturnCode.FAILURE).send({ error: ErrorMessage.UNSUPPORTED_NETWORK_TOKEN }) const networkConfig = getNetworkConfig(chainId, supportedNetworks ?? '', entryPoint); - server.log.warn(networkConfig, `Network Config fetched for ${api_key}: `); if (!networkConfig) return reply.code(ReturnCode.FAILURE).send({ error: ErrorMessage.UNSUPPORTED_NETWORK }); + if (networkConfig.bundler.includes('etherspot.io')) networkConfig.bundler = `${networkConfig.bundler}?api-key=${bundlerApiKey}`; + server.log.warn(networkConfig, `Network Config fetched for ${api_key}: `); let result: any; switch (mode.toLowerCase()) { diff --git a/backend/src/routes/pimlico-routes.ts b/backend/src/routes/pimlico-routes.ts index 35f9654..6a61f2a 100644 --- a/backend/src/routes/pimlico-routes.ts +++ b/backend/src/routes/pimlico-routes.ts @@ -52,6 +52,7 @@ const pimlicoRoutes: FastifyPluginAsync = async (server) => { let customPaymasters = []; let privateKey = ''; let supportedNetworks; + let bundlerApiKey = api_key; if (!unsafeMode) { const AWSresponse = await client.send( new GetSecretValueCommand({ @@ -64,6 +65,9 @@ const pimlicoRoutes: FastifyPluginAsync = async (server) => { const buffer = Buffer.from(secrets['ERC20_PAYMASTERS'], 'base64'); customPaymasters = JSON.parse(buffer.toString()); } + if (secrets['BUNDLER_API_KEY']) { + bundlerApiKey = secrets['BUNDLER_API_KEY']; + } privateKey = secrets['PRIVATE_KEY']; supportedNetworks = secrets['SUPPORTED_NETWORKS']; } else { @@ -78,6 +82,9 @@ const pimlicoRoutes: FastifyPluginAsync = async (server) => { privateKey = decode(apiKeyEntity.privateKey, server.config.HMAC_SECRET); supportedNetworks = apiKeyEntity.supportedNetworks; + if (apiKeyEntity.bundlerApiKey) { + bundlerApiKey = apiKeyEntity.bundlerApiKey; + } } if (!privateKey) return reply.code(ReturnCode.FAILURE).send({ error: ErrorMessage.INVALID_API_KEY }) if ( @@ -93,6 +100,7 @@ const pimlicoRoutes: FastifyPluginAsync = async (server) => { } const networkConfig = getNetworkConfig(chainId, supportedNetworks ?? '', entryPoint); if (!networkConfig) return reply.code(ReturnCode.FAILURE).send({ error: ErrorMessage.UNSUPPORTED_NETWORK }); + if (networkConfig.bundler.includes('etherspot.io')) networkConfig.bundler = `${networkConfig.bundler}?api-key=${bundlerApiKey}`; let result; if (customPaymasters[chainId] && customPaymasters[chainId][gasToken]) result = { message: customPaymasters[chainId][gasToken] } else { diff --git a/backend/src/routes/whitelist-routes.ts b/backend/src/routes/whitelist-routes.ts index 3b7ab8e..217b678 100644 --- a/backend/src/routes/whitelist-routes.ts +++ b/backend/src/routes/whitelist-routes.ts @@ -42,6 +42,7 @@ const whitelistRoutes: FastifyPluginAsync = async (server) => { return reply.code(ReturnCode.FAILURE).send({ error: ErrorMessage.INVALID_API_KEY }) let privateKey = ''; let supportedNetworks; + let bundlerApiKey = api_key; if (!unsafeMode) { const AWSresponse = await client.send( new GetSecretValueCommand({ @@ -50,11 +51,17 @@ const whitelistRoutes: FastifyPluginAsync = async (server) => { ); const secrets = JSON.parse(AWSresponse.SecretString ?? '{}'); if (!secrets['PRIVATE_KEY']) return reply.code(ReturnCode.FAILURE).send({ error: ErrorMessage.INVALID_API_KEY }) + if (secrets['BUNDLER_API_KEY']) { + bundlerApiKey = secrets['BUNDLER_API_KEY']; + } privateKey = secrets['PRIVATE_KEY']; supportedNetworks = secrets['SUPPORTED_NETWORKS']; } else { const apiKeyEntity: APIKey | null = await server.apiKeyRepository.findOneByApiKey(api_key); if (!apiKeyEntity) return reply.code(ReturnCode.FAILURE).send({ error: ErrorMessage.INVALID_API_KEY }) + if (apiKeyEntity.bundlerApiKey) { + bundlerApiKey = apiKeyEntity.bundlerApiKey; + } privateKey = decode(apiKeyEntity.privateKey, server.config.HMAC_SECRET); supportedNetworks = apiKeyEntity.supportedNetworks; } @@ -72,6 +79,7 @@ const whitelistRoutes: FastifyPluginAsync = async (server) => { } const networkConfig = getNetworkConfig(chainId, supportedNetworks ?? '', SUPPORTED_ENTRYPOINTS.EPV_06); if (!networkConfig) return reply.code(ReturnCode.FAILURE).send({ error: ErrorMessage.UNSUPPORTED_NETWORK }); + if (networkConfig.bundler.includes('etherspot.io')) networkConfig.bundler = `${networkConfig.bundler}?api-key=${bundlerApiKey}`; const validAddresses = address.every(ethers.utils.isAddress); if (!validAddresses) return reply.code(ReturnCode.FAILURE).send({ error: ErrorMessage.INVALID_ADDRESS_PASSSED }); const result = await paymaster.whitelistAddresses(address, networkConfig.contracts.etherspotPaymasterAddress, networkConfig.bundler, privateKey, chainId, server.log); @@ -100,6 +108,7 @@ const whitelistRoutes: FastifyPluginAsync = async (server) => { return reply.code(ReturnCode.FAILURE).send({ error: ErrorMessage.INVALID_API_KEY }) let privateKey = ''; let supportedNetworks; + let bundlerApiKey = api_key; if (!unsafeMode) { const AWSresponse = await client.send( new GetSecretValueCommand({ @@ -108,11 +117,15 @@ const whitelistRoutes: FastifyPluginAsync = async (server) => { ); const secrets = JSON.parse(AWSresponse.SecretString ?? '{}'); if (!secrets['PRIVATE_KEY']) return reply.code(ReturnCode.FAILURE).send({ error: ErrorMessage.INVALID_API_KEY }) + if (secrets['BUNDLER_API_KEY']) bundlerApiKey = secrets['BUNDLER_API_KEY']; privateKey = secrets['PRIVATE_KEY']; supportedNetworks = secrets['SUPPORTED_NETWORKS']; } else { const apiKeyEntity: APIKey | null = await server.apiKeyRepository.findOneByApiKey(api_key); if (!apiKeyEntity) return reply.code(ReturnCode.FAILURE).send({ error: ErrorMessage.INVALID_API_KEY }) + if (apiKeyEntity.bundlerApiKey) { + bundlerApiKey = apiKeyEntity.bundlerApiKey; + } privateKey = decode(apiKeyEntity.privateKey, server.config.HMAC_SECRET); supportedNetworks = apiKeyEntity.supportedNetworks; } @@ -130,6 +143,7 @@ const whitelistRoutes: FastifyPluginAsync = async (server) => { } const networkConfig = getNetworkConfig(chainId, supportedNetworks ?? '', SUPPORTED_ENTRYPOINTS.EPV_06); if (!networkConfig) return reply.code(ReturnCode.FAILURE).send({ error: ErrorMessage.UNSUPPORTED_NETWORK }); + if (networkConfig.bundler.includes('etherspot.io')) networkConfig.bundler = `${networkConfig.bundler}?api-key=${bundlerApiKey}`; const validAddresses = address.every(ethers.utils.isAddress); if (!validAddresses) return reply.code(ReturnCode.FAILURE).send({ error: ErrorMessage.INVALID_ADDRESS_PASSSED }); const result = await paymaster.removeWhitelistAddress(address, networkConfig.contracts.etherspotPaymasterAddress, networkConfig.bundler, privateKey, chainId, server.log); @@ -157,6 +171,7 @@ const whitelistRoutes: FastifyPluginAsync = async (server) => { return reply.code(ReturnCode.FAILURE).send({ error: ErrorMessage.INVALID_API_KEY }) let privateKey = ''; let supportedNetworks; + let bundlerApiKey = api_key; if (!unsafeMode) { const AWSresponse = await client.send( new GetSecretValueCommand({ @@ -165,11 +180,13 @@ const whitelistRoutes: FastifyPluginAsync = async (server) => { ); const secrets = JSON.parse(AWSresponse.SecretString ?? '{}'); if (!secrets['PRIVATE_KEY']) return reply.code(ReturnCode.FAILURE).send({ error: ErrorMessage.INVALID_API_KEY }) + if (secrets['BUNDLER_API_KEY']) bundlerApiKey = secrets['BUNDLER_API_KEY']; privateKey = secrets['PRIVATE_KEY']; supportedNetworks = secrets['SUPPORTED_NETWORKS']; } else { const apiKeyEntity: APIKey | null = await server.apiKeyRepository.findOneByApiKey(api_key); if (!apiKeyEntity) return reply.code(ReturnCode.FAILURE).send({ error: ErrorMessage.INVALID_API_KEY }) + if (apiKeyEntity.bundlerApiKey) bundlerApiKey = apiKeyEntity.bundlerApiKey; privateKey = decode(apiKeyEntity.privateKey, server.config.HMAC_SECRET); supportedNetworks = apiKeyEntity.supportedNetworks; } @@ -187,6 +204,7 @@ const whitelistRoutes: FastifyPluginAsync = async (server) => { } const networkConfig = getNetworkConfig(chainId, supportedNetworks ?? '', SUPPORTED_ENTRYPOINTS.EPV_06); if (!networkConfig) return reply.code(ReturnCode.FAILURE).send({ error: ErrorMessage.UNSUPPORTED_NETWORK }); + if (networkConfig.bundler.includes('etherspot.io')) networkConfig.bundler = `${networkConfig.bundler}?api-key=${bundlerApiKey}`; const response = await paymaster.checkWhitelistAddress(accountAddress, networkConfig.contracts.etherspotPaymasterAddress, networkConfig.bundler, privateKey, server.log); server.log.info(response, 'Response sent: '); if (body.jsonrpc) @@ -215,6 +233,7 @@ const whitelistRoutes: FastifyPluginAsync = async (server) => { return reply.code(ReturnCode.FAILURE).send({ error: ErrorMessage.INVALID_API_KEY }) let privateKey = ''; let supportedNetworks; + let bundlerApiKey = api_key; if (!unsafeMode) { const AWSresponse = await client.send( new GetSecretValueCommand({ @@ -223,11 +242,13 @@ const whitelistRoutes: FastifyPluginAsync = async (server) => { ); const secrets = JSON.parse(AWSresponse.SecretString ?? '{}'); if (!secrets['PRIVATE_KEY']) return reply.code(ReturnCode.FAILURE).send({ error: ErrorMessage.INVALID_API_KEY }) + if (secrets['BUNDLER_API_KEY']) bundlerApiKey = secrets['BUNDLER_API_KEY']; privateKey = secrets['PRIVATE_KEY']; supportedNetworks = secrets['SUPPORTED_NETWORKS']; } else { const apiKeyEntity: APIKey | null = await server.apiKeyRepository.findOneByApiKey(api_key); if (!apiKeyEntity) return reply.code(ReturnCode.FAILURE).send({ error: ErrorMessage.INVALID_API_KEY }) + if (apiKeyEntity.bundlerApiKey) bundlerApiKey = apiKeyEntity.bundlerApiKey; privateKey = decode(apiKeyEntity.privateKey, server.config.HMAC_SECRET); supportedNetworks = apiKeyEntity.supportedNetworks; } @@ -245,6 +266,7 @@ const whitelistRoutes: FastifyPluginAsync = async (server) => { } const networkConfig = getNetworkConfig(chainId, supportedNetworks ?? '', SUPPORTED_ENTRYPOINTS.EPV_07); if (!networkConfig) return reply.code(ReturnCode.FAILURE).send({ error: ErrorMessage.UNSUPPORTED_NETWORK }); + if (networkConfig.bundler.includes('etherspot.io')) networkConfig.bundler = `${networkConfig.bundler}?api-key=${bundlerApiKey}`; const validAddresses = address.every(ethers.utils.isAddress); if (!validAddresses) return reply.code(ReturnCode.FAILURE).send({ error: ErrorMessage.INVALID_ADDRESS_PASSSED }); const existingWhitelistRecord = await server.whitelistRepository.findOneByApiKeyAndPolicyId(api_key, policyId); @@ -293,6 +315,7 @@ const whitelistRoutes: FastifyPluginAsync = async (server) => { return reply.code(ReturnCode.FAILURE).send({ error: ErrorMessage.INVALID_API_KEY }) let privateKey = ''; let supportedNetworks; + let bundlerApiKey = api_key; if (!unsafeMode) { const AWSresponse = await client.send( new GetSecretValueCommand({ @@ -301,11 +324,13 @@ const whitelistRoutes: FastifyPluginAsync = async (server) => { ); const secrets = JSON.parse(AWSresponse.SecretString ?? '{}'); if (!secrets['PRIVATE_KEY']) return reply.code(ReturnCode.FAILURE).send({ error: ErrorMessage.INVALID_API_KEY }) + if (secrets['BUNDLER_API_KEY']) bundlerApiKey = secrets['BUNDLER_API_KEY']; privateKey = secrets['PRIVATE_KEY']; supportedNetworks = secrets['SUPPORTED_NETWORKS']; } else { const apiKeyEntity: APIKey | null = await server.apiKeyRepository.findOneByApiKey(api_key); if (!apiKeyEntity) return reply.code(ReturnCode.FAILURE).send({ error: ErrorMessage.INVALID_API_KEY }) + if (apiKeyEntity.bundlerApiKey) bundlerApiKey = apiKeyEntity.bundlerApiKey; privateKey = decode(apiKeyEntity.privateKey, server.config.HMAC_SECRET); supportedNetworks = apiKeyEntity.supportedNetworks; } @@ -323,6 +348,7 @@ const whitelistRoutes: FastifyPluginAsync = async (server) => { } const networkConfig = getNetworkConfig(chainId, supportedNetworks ?? '', SUPPORTED_ENTRYPOINTS.EPV_07); if (!networkConfig) return reply.code(ReturnCode.FAILURE).send({ error: ErrorMessage.UNSUPPORTED_NETWORK }); + if (networkConfig.bundler.includes('etherspot.io')) networkConfig.bundler = `${networkConfig.bundler}?api-key=${bundlerApiKey}`; const existingWhitelistRecord = await server.whitelistRepository.findOneByApiKeyAndPolicyId(api_key, policyId); if (!existingWhitelistRecord) { @@ -432,6 +458,7 @@ const whitelistRoutes: FastifyPluginAsync = async (server) => { return reply.code(ReturnCode.FAILURE).send({ error: ErrorMessage.INVALID_API_KEY }) let privateKey = ''; let supportedNetworks; + let bundlerApiKey = api_key; if (!unsafeMode) { const AWSresponse = await client.send( new GetSecretValueCommand({ @@ -440,12 +467,14 @@ const whitelistRoutes: FastifyPluginAsync = async (server) => { ); const secrets = JSON.parse(AWSresponse.SecretString ?? '{}'); if (!secrets['PRIVATE_KEY']) return reply.code(ReturnCode.FAILURE).send({ error: ErrorMessage.INVALID_API_KEY }) + if (secrets['BUNDLER_API_KEY']) bundlerApiKey = secrets['BUNDLER_API_KEY']; privateKey = secrets['PRIVATE_KEY']; supportedNetworks = secrets['SUPPORTED_NETWORKS']; } else { const apiKeyEntity: APIKey | null = await server.apiKeyRepository.findOneByApiKey(api_key); if (!apiKeyEntity) return reply.code(ReturnCode.FAILURE).send({ error: ErrorMessage.INVALID_API_KEY }) privateKey = decode(apiKeyEntity.privateKey, server.config.HMAC_SECRET); + if (apiKeyEntity.bundlerApiKey) bundlerApiKey = apiKeyEntity.bundlerApiKey; supportedNetworks = apiKeyEntity.supportedNetworks; } if (!privateKey) return reply.code(ReturnCode.FAILURE).send({ error: ErrorMessage.INVALID_API_KEY }) @@ -460,6 +489,7 @@ const whitelistRoutes: FastifyPluginAsync = async (server) => { } const networkConfig = getNetworkConfig(chainId, supportedNetworks ?? '', SUPPORTED_ENTRYPOINTS.EPV_07); if (!networkConfig) return reply.code(ReturnCode.FAILURE).send({ error: ErrorMessage.UNSUPPORTED_NETWORK }); + if (networkConfig.bundler.includes('etherspot.io')) networkConfig.bundler = `${networkConfig.bundler}?api-key=${bundlerApiKey}`; const existingWhitelistRecord = await server.whitelistRepository.findOneByApiKeyAndPolicyId(api_key, policyId); if (!existingWhitelistRecord) { @@ -492,6 +522,7 @@ const whitelistRoutes: FastifyPluginAsync = async (server) => { return reply.code(ReturnCode.FAILURE).send({ error: ErrorMessage.INVALID_API_KEY }) let privateKey = ''; let supportedNetworks; + let bundlerApiKey = api_key; if (!unsafeMode) { const AWSresponse = await client.send( new GetSecretValueCommand({ @@ -500,11 +531,13 @@ const whitelistRoutes: FastifyPluginAsync = async (server) => { ); const secrets = JSON.parse(AWSresponse.SecretString ?? '{}'); if (!secrets['PRIVATE_KEY']) return reply.code(ReturnCode.FAILURE).send({ error: ErrorMessage.INVALID_API_KEY }) + if (secrets['BUNDLER_API_KEY']) bundlerApiKey = secrets['BUNDLER_API_KEY']; privateKey = secrets['PRIVATE_KEY']; supportedNetworks = secrets['SUPPORTED_NETWORKS']; } else { const apiKeyEntity: APIKey | null = await server.apiKeyRepository.findOneByApiKey(api_key); if (!apiKeyEntity) return reply.code(ReturnCode.FAILURE).send({ error: ErrorMessage.INVALID_API_KEY }) + if (apiKeyEntity.bundlerApiKey) bundlerApiKey = apiKeyEntity.bundlerApiKey; privateKey = decode(apiKeyEntity.privateKey, server.config.HMAC_SECRET); supportedNetworks = apiKeyEntity.supportedNetworks; } @@ -520,6 +553,7 @@ const whitelistRoutes: FastifyPluginAsync = async (server) => { } const networkConfig = getNetworkConfig(chainId, supportedNetworks ?? '', SUPPORTED_ENTRYPOINTS.EPV_07); if (!networkConfig) return reply.code(ReturnCode.FAILURE).send({ error: ErrorMessage.UNSUPPORTED_NETWORK }); + if (networkConfig.bundler.includes('etherspot.io')) networkConfig.bundler = `${networkConfig.bundler}?api-key=${bundlerApiKey}`; const provider = new providers.JsonRpcProvider(networkConfig.bundler); const signer = new Wallet(privateKey, provider) @@ -556,6 +590,7 @@ const whitelistRoutes: FastifyPluginAsync = async (server) => { return reply.code(ReturnCode.FAILURE).send({ error: ErrorMessage.INVALID_API_KEY }) let privateKey = ''; let supportedNetworks; + let bundlerApiKey = api_key; if (!unsafeMode) { const AWSresponse = await client.send( new GetSecretValueCommand({ @@ -564,11 +599,13 @@ const whitelistRoutes: FastifyPluginAsync = async (server) => { ); const secrets = JSON.parse(AWSresponse.SecretString ?? '{}'); if (!secrets['PRIVATE_KEY']) return reply.code(ReturnCode.FAILURE).send({ error: ErrorMessage.INVALID_API_KEY }) + if (secrets['BUNDLER_API_KEY']) bundlerApiKey = secrets['BUNDLER_API_KEY']; privateKey = secrets['PRIVATE_KEY']; supportedNetworks = secrets['SUPPORTED_NETWORKS']; } else { const apiKeyEntity: APIKey | null = await server.apiKeyRepository.findOneByApiKey(api_key); if (!apiKeyEntity) return reply.code(ReturnCode.FAILURE).send({ error: ErrorMessage.INVALID_API_KEY }) + if (apiKeyEntity.bundlerApiKey) bundlerApiKey = apiKeyEntity.bundlerApiKey; privateKey = decode(apiKeyEntity.privateKey, server.config.HMAC_SECRET); supportedNetworks = apiKeyEntity.supportedNetworks; } @@ -584,12 +621,13 @@ const whitelistRoutes: FastifyPluginAsync = async (server) => { } const networkConfig = getNetworkConfig(chainId, supportedNetworks ?? '', SUPPORTED_ENTRYPOINTS.EPV_07); if (!networkConfig) return reply.code(ReturnCode.FAILURE).send({ error: ErrorMessage.UNSUPPORTED_NETWORK }); + if (networkConfig.bundler.includes('etherspot.io')) networkConfig.bundler = `${networkConfig.bundler}?api-key=${bundlerApiKey}`; const provider = new providers.JsonRpcProvider(networkConfig.bundler); const signer = new Wallet(privateKey, provider) const existingRecord = await server.contractWhitelistRepository.findOneByChainIdContractAddressAndWalletAddress(chainId, signer.address, contractWhitelistDto.contractAddress); if (!existingRecord) return reply.code(ReturnCode.FAILURE).send({ error: ErrorMessage.NO_CONTRACT_WHITELIST_FOUND }) - + existingRecord.contractAddress = contractWhitelistDto.contractAddress; existingRecord.functionSelectors = contractWhitelistDto.functionSelectors; existingRecord.abi = contractWhitelistDto.abi; @@ -622,6 +660,7 @@ const whitelistRoutes: FastifyPluginAsync = async (server) => { return reply.code(ReturnCode.FAILURE).send({ error: ErrorMessage.INVALID_API_KEY }) let privateKey = ''; let supportedNetworks; + let bundlerApiKey = api_key; if (!unsafeMode) { const AWSresponse = await client.send( new GetSecretValueCommand({ @@ -630,11 +669,17 @@ const whitelistRoutes: FastifyPluginAsync = async (server) => { ); const secrets = JSON.parse(AWSresponse.SecretString ?? '{}'); if (!secrets['PRIVATE_KEY']) return reply.code(ReturnCode.FAILURE).send({ error: ErrorMessage.INVALID_API_KEY }) + if (secrets['BUNDLER_API_KEY']) { + bundlerApiKey = secrets['BUNDLER_API_KEY']; + } privateKey = secrets['PRIVATE_KEY']; supportedNetworks = secrets['SUPPORTED_NETWORKS']; } else { const apiKeyEntity: APIKey | null = await server.apiKeyRepository.findOneByApiKey(api_key); if (!apiKeyEntity) return reply.code(ReturnCode.FAILURE).send({ error: ErrorMessage.INVALID_API_KEY }) + if (apiKeyEntity.bundlerApiKey) { + bundlerApiKey = apiKeyEntity.bundlerApiKey; + } privateKey = decode(apiKeyEntity.privateKey, server.config.HMAC_SECRET); supportedNetworks = apiKeyEntity.supportedNetworks; } @@ -650,6 +695,7 @@ const whitelistRoutes: FastifyPluginAsync = async (server) => { } const networkConfig = getNetworkConfig(chainId, supportedNetworks ?? '', SUPPORTED_ENTRYPOINTS.EPV_07); if (!networkConfig) return reply.code(ReturnCode.FAILURE).send({ error: ErrorMessage.UNSUPPORTED_NETWORK }); + if (networkConfig.bundler.includes('etherspot.io')) networkConfig.bundler = `${networkConfig.bundler}?api-key=${bundlerApiKey}`; const provider = new providers.JsonRpcProvider(networkConfig.bundler); const signer = new Wallet(privateKey, provider) diff --git a/backend/src/types/apikey-dto.ts b/backend/src/types/apikey-dto.ts index e6babac..9d32b7f 100644 --- a/backend/src/types/apikey-dto.ts +++ b/backend/src/types/apikey-dto.ts @@ -4,6 +4,7 @@ export interface ApiKeyDto { walletAddress: string | null; privateKey: string | null; supportedNetworks: string | null; + bundlerApiKey: string | null; erc20Paymasters: string | null; multiTokenPaymasters: string | null; multiTokenOracles: string | null; diff --git a/frontend/package-lock.json b/frontend/package-lock.json index 6830a46..59ec568 100644 --- a/frontend/package-lock.json +++ b/frontend/package-lock.json @@ -1,12 +1,12 @@ { "name": "arka_frontend", - "version": "1.4.0", + "version": "1.4.3", "lockfileVersion": 3, "requires": true, "packages": { "": { "name": "arka_frontend", - "version": "1.4.0", + "version": "1.4.3", "dependencies": { "@babel/plugin-proposal-private-property-in-object": "7.21.11", "@emotion/react": "^11.11.1", diff --git a/frontend/package.json b/frontend/package.json index 9332314..df9b08f 100644 --- a/frontend/package.json +++ b/frontend/package.json @@ -1,6 +1,6 @@ { "name": "arka_frontend", - "version": "1.4.0", + "version": "1.4.3", "private": true, "dependencies": { "@babel/plugin-proposal-private-property-in-object": "7.21.11",