From 03f1a15f3c06499ea7cbcaeb5634443fd40a962e Mon Sep 17 00:00:00 2001 From: Vignesh Date: Fri, 31 May 2024 04:49:07 +0530 Subject: [PATCH 1/2] added support for epv07 and ERC7677 standards --- backend/config.json.default | 95 ++-- .../src/abi/EtherspotVerifyingSignerAbi.ts | 456 ++++++++++++++++++ backend/src/constants/ErrorMessage.ts | 2 + backend/src/migrations/002.apiKeys.sql | 2 + backend/src/paymaster/index.ts | 139 +++++- backend/src/routes/admin.ts | 6 +- backend/src/routes/index.ts | 124 ++++- backend/src/routes/metadata.ts | 16 +- backend/src/utils/common.ts | 6 +- 9 files changed, 773 insertions(+), 73 deletions(-) create mode 100644 backend/src/abi/EtherspotVerifyingSignerAbi.ts diff --git a/backend/config.json.default b/backend/config.json.default index 970e584..d8ae092 100644 --- a/backend/config.json.default +++ b/backend/config.json.default @@ -6,7 +6,8 @@ "etherspotPaymasterAddress": "0x7F690e93CecFca5A31E6e1dF50A33F6d3059048c" }, "thresholdValue": "0.016", - "MultiTokenPaymasterOracleUsed": "chainlink" + "MultiTokenPaymasterOracleUsed": "chainlink", + "entryPoint": "0x5FF137D4b0FDCD49DcA30c7CF57E578a026d2789" }, { "chainId": 10, @@ -15,7 +16,8 @@ "etherspotPaymasterAddress": "0x805650ce74561C85baA44a8Bd13E19633Fd0F79d" }, "thresholdValue": "21.8", - "MultiTokenPaymasterOracleUsed": "chainlink" + "MultiTokenPaymasterOracleUsed": "chainlink", + "entryPoint": "0x5FF137D4b0FDCD49DcA30c7CF57E578a026d2789" }, { "chainId": 14, @@ -24,7 +26,8 @@ "etherspotPaymasterAddress": "0x8A41594e5c6Fe492e437414c24eA6f401186b8d2" }, "thresholdValue": "1556", - "MultiTokenPaymasterOracleUsed": "chainlink" + "MultiTokenPaymasterOracleUsed": "chainlink", + "entryPoint": "0x5FF137D4b0FDCD49DcA30c7CF57E578a026d2789" }, { "chainId": 30, @@ -33,7 +36,8 @@ "etherspotPaymasterAddress": "0xe893A26dD53b325bFFaACdFA224692EFF4C448C4" }, "thresholdValue": "0.00079", - "MultiTokenPaymasterOracleUsed": "chainlink" + "MultiTokenPaymasterOracleUsed": "chainlink", + "entryPoint": "0x5FF137D4b0FDCD49DcA30c7CF57E578a026d2789" }, { "chainId": 31, @@ -42,7 +46,8 @@ "etherspotPaymasterAddress": "0xD302BE6e9D3fE0fBf8122a0C34611E31c0D0E792" }, "thresholdValue": "0.00079", - "MultiTokenPaymasterOracleUsed": "chainlink" + "MultiTokenPaymasterOracleUsed": "chainlink", + "entryPoint": "0x5FF137D4b0FDCD49DcA30c7CF57E578a026d2789" }, { "chainId": 56, @@ -51,7 +56,8 @@ "etherspotPaymasterAddress": "0xEA5ecE95D3A28f9faB161779d20128b449F9EC9C" }, "thresholdValue": "0.09", - "MultiTokenPaymasterOracleUsed": "chainlink" + "MultiTokenPaymasterOracleUsed": "chainlink", + "entryPoint": "0x5FF137D4b0FDCD49DcA30c7CF57E578a026d2789" }, { "chainId": 97, @@ -60,7 +66,8 @@ "etherspotPaymasterAddress": "0x153e26707DF3787183945B88121E4Eb188FDCAAA" }, "thresholdValue": "0.09", - "MultiTokenPaymasterOracleUsed": "chainlink" + "MultiTokenPaymasterOracleUsed": "chainlink", + "entryPoint": "0x5FF137D4b0FDCD49DcA30c7CF57E578a026d2789" }, { "chainId": 100, @@ -69,7 +76,8 @@ "etherspotPaymasterAddress": "0x373aBcF1EA9e5802778E32870e7f72C8A6a90349" }, "thresholdValue": "50", - "MultiTokenPaymasterOracleUsed": "chainlink" + "MultiTokenPaymasterOracleUsed": "chainlink", + "entryPoint": "0x5FF137D4b0FDCD49DcA30c7CF57E578a026d2789" }, { "chainId": 114, @@ -78,7 +86,8 @@ "etherspotPaymasterAddress": "0x2a18C360b525824B3e5656B5a705554f2a5036Be" }, "thresholdValue": "1556", - "MultiTokenPaymasterOracleUsed": "chainlink" + "MultiTokenPaymasterOracleUsed": "chainlink", + "entryPoint": "0x5FF137D4b0FDCD49DcA30c7CF57E578a026d2789" }, { "chainId": 122, @@ -86,7 +95,9 @@ "contracts": { "etherspotPaymasterAddress": "0xEC2EE24E79C73DB13Dd9bC782856a5296626b7eb" }, - "thresholdValue": "669" + "thresholdValue": "669", + "MultiTokenPaymasterOracleUsed": "chainlink", + "entryPoint": "0x5FF137D4b0FDCD49DcA30c7CF57E578a026d2789" }, { "chainId": 123, @@ -95,7 +106,8 @@ "etherspotPaymasterAddress": "0xAF628C207513c5E51d894b3733056B8080634923" }, "thresholdValue": "669", - "MultiTokenPaymasterOracleUsed": "chainlink" + "MultiTokenPaymasterOracleUsed": "chainlink", + "entryPoint": "0x5FF137D4b0FDCD49DcA30c7CF57E578a026d2789" }, { "chainId": 137, @@ -104,7 +116,8 @@ "etherspotPaymasterAddress": "0x26FeC24b0D467C9de105217B483931e8f944ff50" }, "thresholdValue": "69.85", - "MultiTokenPaymasterOracleUsed": "chainlink" + "MultiTokenPaymasterOracleUsed": "chainlink", + "entryPoint": "0x5FF137D4b0FDCD49DcA30c7CF57E578a026d2789" }, { "chainId": 5000, @@ -113,7 +126,8 @@ "etherspotPaymasterAddress": "0x8A41594e5c6Fe492e437414c24eA6f401186b8d2" }, "thresholdValue": "44.24", - "MultiTokenPaymasterOracleUsed": "chainlink" + "MultiTokenPaymasterOracleUsed": "chainlink", + "entryPoint": "0x5FF137D4b0FDCD49DcA30c7CF57E578a026d2789" }, { "chainId": 5003, @@ -122,7 +136,8 @@ "etherspotPaymasterAddress": "0x8350355c08aDAC387b443782124A30A8942BeC2e" }, "thresholdValue": "44.24", - "MultiTokenPaymasterOracleUsed": "chainlink" + "MultiTokenPaymasterOracleUsed": "chainlink", + "entryPoint": "0x5FF137D4b0FDCD49DcA30c7CF57E578a026d2789" }, { "chainId": 8217, @@ -131,7 +146,8 @@ "etherspotPaymasterAddress": "0x4ebd86AAF89151b5303DB072e0205C668e31E5E7" }, "thresholdValue": "275.2", - "MultiTokenPaymasterOracleUsed": "chainlink" + "MultiTokenPaymasterOracleUsed": "chainlink", + "entryPoint": "0x5FF137D4b0FDCD49DcA30c7CF57E578a026d2789" }, { "chainId": 8453, @@ -140,7 +156,8 @@ "etherspotPaymasterAddress": "0x810FA4C915015b703db0878CF2B9344bEB254a40" }, "thresholdValue": "15.19", - "MultiTokenPaymasterOracleUsed": "chainlink" + "MultiTokenPaymasterOracleUsed": "chainlink", + "entryPoint": "0x5FF137D4b0FDCD49DcA30c7CF57E578a026d2789" }, { "chainId": 42161, @@ -149,7 +166,8 @@ "etherspotPaymasterAddress": "0xEC2EE24E79C73DB13Dd9bC782856a5296626b7eb" }, "thresholdValue": "43.10", - "MultiTokenPaymasterOracleUsed": "chainlink" + "MultiTokenPaymasterOracleUsed": "chainlink", + "entryPoint": "0x5FF137D4b0FDCD49DcA30c7CF57E578a026d2789" }, { "chainId": 43114, @@ -158,7 +176,8 @@ "etherspotPaymasterAddress": "0x527569794781671319f20374A050BDbef4181aB3" }, "thresholdValue": "1.4", - "MultiTokenPaymasterOracleUsed": "chainlink" + "MultiTokenPaymasterOracleUsed": "chainlink", + "entryPoint": "0x5FF137D4b0FDCD49DcA30c7CF57E578a026d2789" }, { "chainId": 59144, @@ -167,7 +186,8 @@ "etherspotPaymasterAddress": "0xB3AD9B9B06c6016f81404ee8FcCD0526F018Cf0C" }, "thresholdValue": "0.016", - "MultiTokenPaymasterOracleUsed": "chainlink" + "MultiTokenPaymasterOracleUsed": "chainlink", + "entryPoint": "0x5FF137D4b0FDCD49DcA30c7CF57E578a026d2789" }, { "chainId": 84532, @@ -176,7 +196,8 @@ "etherspotPaymasterAddress": "0xe893A26DD53b325BffAacDfA224692EfF4C448c4" }, "thresholdValue": "15.19", - "MultiTokenPaymasterOracleUsed": "chainlink" + "MultiTokenPaymasterOracleUsed": "chainlink", + "entryPoint": "0x5FF137D4b0FDCD49DcA30c7CF57E578a026d2789" }, { "chainId": 421614, @@ -185,7 +206,8 @@ "etherspotPaymasterAddress": "0xe893A26DD53b325BffAacDfA224692EfF4C448c4" }, "thresholdValue": "43.10", - "MultiTokenPaymasterOracleUsed": "chainlink" + "MultiTokenPaymasterOracleUsed": "chainlink", + "entryPoint": "0x5FF137D4b0FDCD49DcA30c7CF57E578a026d2789" }, { "chainId": 534351, @@ -194,7 +216,8 @@ "etherspotPaymasterAddress": "0xe893A26DD53b325BffAacDfA224692EfF4C448c4" }, "thresholdValue": "0.016", - "MultiTokenPaymasterOracleUsed": "chainlink" + "MultiTokenPaymasterOracleUsed": "chainlink", + "entryPoint": "0x5FF137D4b0FDCD49DcA30c7CF57E578a026d2789" }, { "chainId": 534352, @@ -203,7 +226,8 @@ "etherspotPaymasterAddress": "0xB3AD9B9B06c6016f81404ee8FcCD0526F018Cf0C" }, "thresholdValue": "0.016", - "MultiTokenPaymasterOracleUsed": "chainlink" + "MultiTokenPaymasterOracleUsed": "chainlink", + "entryPoint": "0x5FF137D4b0FDCD49DcA30c7CF57E578a026d2789" }, { "chainId": 11155111, @@ -212,7 +236,8 @@ "etherspotPaymasterAddress": "0xcaDBADcFeD5530A49762DFc9d1d712CcD6b09b25" }, "thresholdValue": "0.016", - "MultiTokenPaymasterOracleUsed": "chainlink" + "MultiTokenPaymasterOracleUsed": "chainlink", + "entryPoint": "0x5FF137D4b0FDCD49DcA30c7CF57E578a026d2789" }, { "chainId": 28122024, @@ -221,7 +246,8 @@ "etherspotPaymasterAddress": "0xe893A26DD53b325BffAacDfA224692EfF4C448c4" }, "thresholdValue": "0.016", - "MultiTokenPaymasterOracleUsed": "orochi" + "MultiTokenPaymasterOracleUsed": "orochi", + "entryPoint": "0x5FF137D4b0FDCD49DcA30c7CF57E578a026d2789" }, { "chainId": 11155420, @@ -230,7 +256,8 @@ "etherspotPaymasterAddress": "0xB3AD9B9B06c6016f81404ee8FcCD0526F018Cf0C" }, "thresholdValue": "21.8", - "MultiTokenPaymasterOracleUsed": "chainlink" + "MultiTokenPaymasterOracleUsed": "chainlink", + "entryPoint": "0x5FF137D4b0FDCD49DcA30c7CF57E578a026d2789" }, { "chainId": 888888888, @@ -239,7 +266,8 @@ "etherspotPaymasterAddress": "0x810FA4C915015b703db0878CF2B9344bEB254a40" }, "thresholdValue": "0.016", - "MultiTokenPaymasterOracleUsed": "orochi" + "MultiTokenPaymasterOracleUsed": "orochi", + "entryPoint": "0x5FF137D4b0FDCD49DcA30c7CF57E578a026d2789" }, { "chainId": 80002, @@ -248,6 +276,17 @@ "etherspotPaymasterAddress": "0xe893a26dd53b325bffaacdfa224692eff4c448c4" }, "thresholdValue": "0.01", - "MultiTokenPaymasterOracleUsed": "chainlink" + "MultiTokenPaymasterOracleUsed": "chainlink", + "entryPoint": "0x5FF137D4b0FDCD49DcA30c7CF57E578a026d2789" + }, + { + "chainId": 80002, + "bundler": "https://testnet-rpc.etherspot.io/v2/80002", + "contracts": { + "etherspotPaymasterAddress": "0x810FA4C915015b703db0878CF2B9344bEB254a40" + }, + "thresholdValue": "0.01", + "MultiTokenPaymasterOracleUsed": "chainlink", + "entryPoint": "0x0000000071727De22E5E9d8BAf0edAc6f37da032" } ] diff --git a/backend/src/abi/EtherspotVerifyingSignerAbi.ts b/backend/src/abi/EtherspotVerifyingSignerAbi.ts new file mode 100644 index 0000000..268d0f8 --- /dev/null +++ b/backend/src/abi/EtherspotVerifyingSignerAbi.ts @@ -0,0 +1,456 @@ +export default [ + { + "inputs": [ + { + "internalType": "contract IEntryPoint", + "name": "_entryPoint", + "type": "address" + }, + { + "internalType": "address", + "name": "_verifyingSigner", + "type": "address" + } + ], + "stateMutability": "nonpayable", + "type": "constructor" + }, + { + "inputs": [], + "name": "ECDSAInvalidSignature", + "type": "error" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "length", + "type": "uint256" + } + ], + "name": "ECDSAInvalidSignatureLength", + "type": "error" + }, + { + "inputs": [ + { + "internalType": "bytes32", + "name": "s", + "type": "bytes32" + } + ], + "name": "ECDSAInvalidSignatureS", + "type": "error" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "owner", + "type": "address" + } + ], + "name": "OwnableInvalidOwner", + "type": "error" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "account", + "type": "address" + } + ], + "name": "OwnableUnauthorizedAccount", + "type": "error" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "previousOwner", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "newOwner", + "type": "address" + } + ], + "name": "OwnershipTransferred", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "address", + "name": "newVerifyingSigner", + "type": "address" + } + ], + "name": "VerifyingSignerUpdated", + "type": "event" + }, + { + "inputs": [ + { + "internalType": "uint32", + "name": "unstakeDelaySec", + "type": "uint32" + } + ], + "name": "addStake", + "outputs": [], + "stateMutability": "payable", + "type": "function" + }, + { + "inputs": [], + "name": "deposit", + "outputs": [], + "stateMutability": "payable", + "type": "function" + }, + { + "inputs": [], + "name": "entryPoint", + "outputs": [ + { + "internalType": "contract IEntryPoint", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "getDeposit", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "components": [ + { + "internalType": "address", + "name": "sender", + "type": "address" + }, + { + "internalType": "uint256", + "name": "nonce", + "type": "uint256" + }, + { + "internalType": "bytes", + "name": "initCode", + "type": "bytes" + }, + { + "internalType": "bytes", + "name": "callData", + "type": "bytes" + }, + { + "internalType": "bytes32", + "name": "accountGasLimits", + "type": "bytes32" + }, + { + "internalType": "uint256", + "name": "preVerificationGas", + "type": "uint256" + }, + { + "internalType": "bytes32", + "name": "gasFees", + "type": "bytes32" + }, + { + "internalType": "bytes", + "name": "paymasterAndData", + "type": "bytes" + }, + { + "internalType": "bytes", + "name": "signature", + "type": "bytes" + } + ], + "internalType": "struct PackedUserOperation", + "name": "userOp", + "type": "tuple" + }, + { + "internalType": "uint48", + "name": "validUntil", + "type": "uint48" + }, + { + "internalType": "uint48", + "name": "validAfter", + "type": "uint48" + } + ], + "name": "getHash", + "outputs": [ + { + "internalType": "bytes32", + "name": "", + "type": "bytes32" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "owner", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "bytes", + "name": "paymasterAndData", + "type": "bytes" + } + ], + "name": "parsePaymasterAndData", + "outputs": [ + { + "internalType": "uint48", + "name": "validUntil", + "type": "uint48" + }, + { + "internalType": "uint48", + "name": "validAfter", + "type": "uint48" + }, + { + "internalType": "bytes", + "name": "signature", + "type": "bytes" + } + ], + "stateMutability": "pure", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "enum IPaymaster.PostOpMode", + "name": "mode", + "type": "uint8" + }, + { + "internalType": "bytes", + "name": "context", + "type": "bytes" + }, + { + "internalType": "uint256", + "name": "actualGasCost", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "actualUserOpFeePerGas", + "type": "uint256" + } + ], + "name": "postOp", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "renounceOwnership", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "newOwner", + "type": "address" + } + ], + "name": "transferOwnership", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "unlockStake", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_newVerifyingSigner", + "type": "address" + } + ], + "name": "updateVerifyingSigner", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "components": [ + { + "internalType": "address", + "name": "sender", + "type": "address" + }, + { + "internalType": "uint256", + "name": "nonce", + "type": "uint256" + }, + { + "internalType": "bytes", + "name": "initCode", + "type": "bytes" + }, + { + "internalType": "bytes", + "name": "callData", + "type": "bytes" + }, + { + "internalType": "bytes32", + "name": "accountGasLimits", + "type": "bytes32" + }, + { + "internalType": "uint256", + "name": "preVerificationGas", + "type": "uint256" + }, + { + "internalType": "bytes32", + "name": "gasFees", + "type": "bytes32" + }, + { + "internalType": "bytes", + "name": "paymasterAndData", + "type": "bytes" + }, + { + "internalType": "bytes", + "name": "signature", + "type": "bytes" + } + ], + "internalType": "struct PackedUserOperation", + "name": "userOp", + "type": "tuple" + }, + { + "internalType": "bytes32", + "name": "userOpHash", + "type": "bytes32" + }, + { + "internalType": "uint256", + "name": "maxCost", + "type": "uint256" + } + ], + "name": "validatePaymasterUserOp", + "outputs": [ + { + "internalType": "bytes", + "name": "context", + "type": "bytes" + }, + { + "internalType": "uint256", + "name": "validationData", + "type": "uint256" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "verifyingSigner", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address payable", + "name": "withdrawAddress", + "type": "address" + } + ], + "name": "withdrawStake", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address payable", + "name": "withdrawAddress", + "type": "address" + }, + { + "internalType": "uint256", + "name": "amount", + "type": "uint256" + } + ], + "name": "withdrawTo", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + } +] as const; diff --git a/backend/src/constants/ErrorMessage.ts b/backend/src/constants/ErrorMessage.ts index 1bf8bee..74a04b2 100644 --- a/backend/src/constants/ErrorMessage.ts +++ b/backend/src/constants/ErrorMessage.ts @@ -13,4 +13,6 @@ export default { INVALID_USER: 'Unauthorised User', RECORD_NOT_FOUND: 'Api Key provided not found', API_KEY_VALIDATION_FAILED: 'Api Key is not in the right format as described in readme file', + UNSUPPORTED_METHOD: 'Unsupported method name received', + UNSUPPORTED_ENTRYPOINT: 'Unsupported EntryPoint Address', } diff --git a/backend/src/migrations/002.apiKeys.sql b/backend/src/migrations/002.apiKeys.sql index 881f5a7..fd83ae8 100644 --- a/backend/src/migrations/002.apiKeys.sql +++ b/backend/src/migrations/002.apiKeys.sql @@ -10,6 +10,8 @@ CREATE TABLE IF NOT EXISTS api_keys ( ERC20_PAYMASTERS varchar DEFAULT NULL, MULTI_TOKEN_PAYMASTERS varchar DEFAULT NULL, MULTI_TOKEN_ORACLES varchar DEFAULT NULL, + SPONSOR_NAME varchar DEFAULT NULL, + LOGO_URL varchar DEFAULT NULL, TRANSACTION_LIMIT INT NOT NULL, NO_OF_TRANSACTIONS_IN_A_MONTH int, INDEXER_ENDPOINT varchar diff --git a/backend/src/paymaster/index.ts b/backend/src/paymaster/index.ts index 6531873..b81933d 100644 --- a/backend/src/paymaster/index.ts +++ b/backend/src/paymaster/index.ts @@ -1,8 +1,9 @@ /* eslint-disable @typescript-eslint/no-explicit-any */ -import { providers, Wallet, ethers, Contract, BigNumber } from 'ethers'; -import { arrayify, defaultAbiCoder, hexConcat } from 'ethers/lib/utils.js'; +import { providers, Wallet, ethers, Contract, BigNumber, BigNumberish, utils } from 'ethers'; +import { arrayify, BytesLike, defaultAbiCoder, hexConcat, hexZeroPad } from 'ethers/lib/utils.js'; import { FastifyBaseLogger } from 'fastify'; -import abi from "../abi/EtherspotAbi.js"; +import EtherspotAbiV06 from '../abi/EtherspotAbi.js'; +import EtherspotAbiV07 from "../abi/EtherspotVerifyingSignerAbi.js"; import { PimlicoPaymaster } from './pimlico.js'; import ErrorMessage from '../constants/ErrorMessage.js'; import { PAYMASTER_ADDRESS } from '../constants/Pimlico.js'; @@ -21,6 +22,93 @@ export class Paymaster { else this.multiTokenMarkUp = Number(multiTokenMarkUp); } + packUint (high128: BigNumberish, low128: BigNumberish): string { + return hexZeroPad(BigNumber.from(high128).shl(128).add(low128).toHexString(), 32) + } + + packPaymasterData (paymaster: string, paymasterVerificationGasLimit: BigNumberish, postOpGasLimit: BigNumberish, paymasterData?: BytesLike): BytesLike { + return ethers.utils.hexConcat([ + paymaster, + this.packUint(paymasterVerificationGasLimit, postOpGasLimit), + paymasterData ?? '0x' + ]) + } + + async getPaymasterData(userOp: any, validUntil: string, validAfter: string, paymasterContract: Contract, signer: Wallet) { + // actual signing... + const hash = await paymasterContract.getHash( + userOp, + validUntil, + validAfter + ); + + const sig = await signer.signMessage(arrayify(hash)); + + const paymasterData = hexConcat([ + defaultAbiCoder.encode( + ['uint48', 'uint48'], + [validUntil, validAfter] + ), + sig, + ]); + + return paymasterData; + } + + async signV07(userOp: any, validUntil: string, validAfter: string, entryPoint: string, paymasterAddress: string, + bundlerRpc: string, signer: Wallet, estimate: boolean, log?: FastifyBaseLogger) { + try { + const provider = new providers.JsonRpcProvider(bundlerRpc); + const paymasterContract = new ethers.Contract(paymasterAddress, EtherspotAbiV07, provider); + if (!userOp.signature) userOp.signature = '0x'; + if (userOp.factory && userOp.factoryData) userOp.initCode = hexConcat([userOp.factory, userOp.factoryData ?? '']) + if (!userOp.initCode) userOp.initCode = "0x"; + if (estimate) { + const response = await provider.send('eth_estimateUserOperationGas', [userOp, entryPoint]); + userOp.verificationGasLimit = response.verificationGasLimit; + userOp.callGasLimit = response.callGasLimit; + userOp.preVerificationGas = response.preVerificationGas; + } + const accountGasLimits = this.packUint(userOp.verificationGasLimit, userOp.callGasLimit) + const gasFees = this.packUint(userOp.maxPriorityFeePerGas, userOp.maxFeePerGas); + let packedUserOp = { + sender: userOp.sender, + nonce: userOp.nonce, + initCode: userOp.initCode, + callData: userOp.callData, + accountGasLimits: accountGasLimits, + preVerificationGas: userOp.preVerificationGas, + gasFees: gasFees, + paymasterAndData: this.packPaymasterData(paymasterAddress, BigNumber.from(30000), "0x1"), + signature: userOp.signature + } + + let paymasterData = await this.getPaymasterData(packedUserOp, validUntil, validAfter, paymasterContract, signer); + let returnValue; + if (estimate) { + returnValue = { + paymaster: paymasterAddress, + paymasterData: paymasterData, + preVerificationGas: packedUserOp.preVerificationGas.toString(), + verificationGasLimit: userOp.verificationGasLimit, + callGasLimit: userOp.callGasLimit, + paymasterVerificationGasLimit: BigNumber.from(30000).toString(), + paymasterPostOpGasLimit: "0x1" + } + } else { + returnValue = { + paymaster: paymasterAddress, + paymasterData: paymasterData, + } + } + + return returnValue; + } catch (err: any) { + if (log) log.error(err, 'signv07'); + throw new Error('Failed to process request to bundler. Please contact support team RawErrorMsg:' + err.message) + } + } + async getPaymasterAndData(userOp: any, validUntil: string, validAfter: string, paymasterContract: Contract, signer: Wallet) { // actual signing... const hash = await paymasterContract.getHash( @@ -43,33 +131,40 @@ export class Paymaster { return paymasterAndData; } - async sign(userOp: any, validUntil: string, validAfter: string, entryPoint: string, paymasterAddress: string, - bundlerRpc: string, signer: Wallet, log?: FastifyBaseLogger) { + async signV06(userOp: any, validUntil: string, validAfter: string, entryPoint: string, paymasterAddress: string, + bundlerRpc: string, signer: Wallet, estimate: boolean, log?: FastifyBaseLogger) { try { const provider = new providers.JsonRpcProvider(bundlerRpc); - const paymasterContract = new ethers.Contract(paymasterAddress, abi, provider); + const paymasterContract = new ethers.Contract(paymasterAddress, EtherspotAbiV06, provider); userOp.paymasterAndData = await this.getPaymasterAndData(userOp, validUntil, validAfter, paymasterContract, signer); if (!userOp.signature) userOp.signature = '0x'; + if (estimate) { const response = await provider.send('eth_estimateUserOperationGas', [userOp, entryPoint]); - userOp.verificationGasLimit = response.verificationGasLimit; - userOp.preVerificationGas = response.preVerificationGas; - userOp.callGasLimit = response.callGasLimit; - + userOp.verificationGasLimit = response.verificationGasLimit; + userOp.preVerificationGas = response.preVerificationGas; + userOp.callGasLimit = response.callGasLimit; + } const paymasterAndData = await this.getPaymasterAndData(userOp, validUntil, validAfter, paymasterContract, signer); - - const returnValue = { - paymasterAndData, - verificationGasLimit: response.verificationGasLimit, - preVerificationGas: response.preVerificationGas, - callGasLimit: response.callGasLimit, + let returnValue; + if (estimate) { + returnValue = { + paymasterAndData, + verificationGasLimit: userOp.verificationGasLimit, + preVerificationGas: userOp.preVerificationGas, + callGasLimit: userOp.callGasLimit, + } + } else { + returnValue = { + paymasterAndData + } } return returnValue; } catch (err: any) { - if (log) log.error(err, 'sign'); + if (log) log.error(err, 'signV06'); throw new Error('Failed to process request to bundler. Please contact support team RawErrorMsg:' + err.message) } - } + } async getPaymasterAndDataForMultiTokenPaymaster(userOp: any, validUntil: string, validAfter: string, feeToken: string, ethPrice: string, paymasterContract: Contract, signer: Wallet) { @@ -207,7 +302,7 @@ export class Paymaster { async whitelistAddresses(address: string[], paymasterAddress: string, bundlerRpc: string, relayerKey: string, chainId: number, log?: FastifyBaseLogger) { try { const provider = new providers.JsonRpcProvider(bundlerRpc); - const paymasterContract = new ethers.Contract(paymasterAddress, abi, provider); + const paymasterContract = new ethers.Contract(paymasterAddress, EtherspotAbiV06, provider); const signer = new Wallet(relayerKey, provider) for (let i = 0; i < address.length; i++) { const isAdded = await paymasterContract.check(signer.address, address[i]); @@ -260,7 +355,7 @@ export class Paymaster { async removeWhitelistAddress(address: string[], paymasterAddress: string, bundlerRpc: string, relayerKey: string, chainId: number, log?: FastifyBaseLogger) { try { const provider = new providers.JsonRpcProvider(bundlerRpc); - const paymasterContract = new ethers.Contract(paymasterAddress, abi, provider); + const paymasterContract = new ethers.Contract(paymasterAddress, EtherspotAbiV06, provider); const signer = new Wallet(relayerKey, provider) for (let i = 0; i < address.length; i++) { const isAdded = await paymasterContract.check(signer.address, address[i]); @@ -314,7 +409,7 @@ export class Paymaster { try { const provider = new providers.JsonRpcProvider(bundlerRpc); const signer = new Wallet(relayerKey, provider) - const paymasterContract = new ethers.Contract(paymasterAddress, abi, provider); + const paymasterContract = new ethers.Contract(paymasterAddress, EtherspotAbiV06, provider); return paymasterContract.check(signer.address, accountAddress); } catch (err) { if (log) log.error(err, 'checkWhitelistAddress'); @@ -325,7 +420,7 @@ export class Paymaster { async deposit(amount: string, paymasterAddress: string, bundlerRpc: string, relayerKey: string, chainId: number, log?: FastifyBaseLogger) { try { const provider = new providers.JsonRpcProvider(bundlerRpc); - const paymasterContract = new ethers.Contract(paymasterAddress, abi, provider); + const paymasterContract = new ethers.Contract(paymasterAddress, EtherspotAbiV06, provider); const signer = new Wallet(relayerKey, provider) const balance = await signer.getBalance(); const amountInWei = ethers.utils.parseEther(amount.toString()); diff --git a/backend/src/routes/admin.ts b/backend/src/routes/admin.ts index e37c038..5c851b9 100644 --- a/backend/src/routes/admin.ts +++ b/backend/src/routes/admin.ts @@ -99,9 +99,11 @@ const adminRoutes: FastifyPluginAsync = async (server) => { ERC20_PAYMASTERS, \ MULTI_TOKEN_PAYMASTERS, \ MULTI_TOKEN_ORACLES, \ + SPONSOR_NAME, \ + LOGO_URL, \ TRANSACTION_LIMIT, \ NO_OF_TRANSACTIONS_IN_A_MONTH, \ - INDEXER_ENDPOINT) VALUES (?, ?, ?, ?, ?, ?, ?, ?)", [ + INDEXER_ENDPOINT) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)", [ body.API_KEY, publicAddress, hmac, @@ -109,6 +111,8 @@ const adminRoutes: FastifyPluginAsync = async (server) => { body.ERC20_PAYMASTERS, body.MULTI_TOKEN_PAYMASTERS ?? null, body.MULTI_TOKEN_ORACLES ?? null, + body.SPONSOR_NAME ?? null, + body.LOGO_URL ?? null, body.TRANSACTION_LIMIT ?? 0, body.NO_OF_TRANSACTIONS_IN_A_MONTH ?? 10, body.INDEXER_ENDPOINT ?? process.env.DEFAULT_INDEXER_ENDPOINT diff --git a/backend/src/routes/index.ts b/backend/src/routes/index.ts index 10896c6..824358f 100644 --- a/backend/src/routes/index.ts +++ b/backend/src/routes/index.ts @@ -1,7 +1,7 @@ /* eslint-disable @typescript-eslint/no-explicit-any */ import { Type } from "@sinclair/typebox"; import { FastifyPluginAsync } from "fastify"; -import { Wallet, ethers, providers } from "ethers"; +import { BigNumber, Wallet, ethers, providers } from "ethers"; import { gql, request as GLRequest } from "graphql-request"; import { GetSecretValueCommand, SecretsManagerClient } from "@aws-sdk/client-secrets-manager"; import { Paymaster } from "../paymaster/index.js"; @@ -12,6 +12,11 @@ import ReturnCode from "../constants/ReturnCode.js"; import { decode } from "../utils/crypto.js"; import { printRequest, getNetworkConfig, getSQLdata } from "../utils/common.js"; +const SUPPORTED_ENTRYPOINTS = { + 'EPV_06' : "0x5FF137D4b0FDCD49DcA30c7CF57E578a026d2789", + 'EPV_07' : "0x0000000071727De22E5E9d8BAf0edAc6f37da032" +} + const routes: FastifyPluginAsync = async (server) => { const paymaster = new Paymaster(server.config.FEE_MARKUP, server.config.MULTI_TOKEN_MARKUP); @@ -48,13 +53,39 @@ const routes: FastifyPluginAsync = async (server) => { if (!body) return reply.code(ReturnCode.FAILURE).send({ error: ErrorMessage.EMPTY_BODY }); const userOp = body.params[0]; const entryPoint = body.params[1]; - const context = body.params[2]; + let context = body.params[2]; let gasToken = context?.token ? context.token : null; - const mode = context?.mode ? String(context.mode) : null; - const chainId = query['chainId'] ?? body.params[3]; + let mode = context?.mode ? String(context.mode) : "sponsor"; + let chainId = query['chainId'] ?? body.params[3]; const api_key = query['apiKey'] ?? body.params[4]; + let sponsorDetails = false, estimate = true; + if (body.method) { + switch(body.method) { + case 'pm_getPaymasterData': { + estimate = false; + sponsorDetails = true; + } + case 'pm_getPaymasterStubData': { + chainId = BigNumber.from(body.params[2]).toNumber(); + context = body.params[3]; + gasToken = context?.token ? context.token : null; + mode = context?.mode ? String(context.mode) : "sponsor"; + break; + }; + case 'pm_sponsorUserOperation': { + break; + }; + default: { + return reply.code(ReturnCode.FAILURE).send({ error: ErrorMessage.UNSUPPORTED_METHOD }); + break; + } + } + } if (!api_key) return reply.code(ReturnCode.FAILURE).send({ error: ErrorMessage.INVALID_API_KEY }) + console.log('entryPoint: ', entryPoint); + if ((entryPoint != SUPPORTED_ENTRYPOINTS.EPV_06) && (entryPoint != SUPPORTED_ENTRYPOINTS.EPV_07)) + return reply.code(ReturnCode.FAILURE).send({ error: ErrorMessage.UNSUPPORTED_ENTRYPOINT }) let customPaymasters = []; let multiTokenPaymasters = []; let multiTokenOracles = []; @@ -63,6 +94,7 @@ const routes: FastifyPluginAsync = async (server) => { let noOfTxns; let txnMode; let indexerEndpoint; + let sponsorName = '', sponsorImage = ''; if (!unsafeMode) { const AWSresponse = await client.send( new GetSecretValueCommand({ @@ -86,6 +118,8 @@ const routes: FastifyPluginAsync = async (server) => { const buffer = Buffer.from(secrets['MULTI_TOKEN_ORACLES'], 'base64'); multiTokenOracles = JSON.parse(buffer.toString()); } + sponsorName = secrets['SPONSOR_NAME']; + sponsorImage = secrets['LOGO_URL']; privateKey = secrets['PRIVATE_KEY']; supportedNetworks = secrets['SUPPORTED_NETWORKS']; noOfTxns = secrets['NO_OF_TRANSACTIONS_IN_A_MONTH'] ?? 10; @@ -109,6 +143,8 @@ const routes: FastifyPluginAsync = async (server) => { const buffer = Buffer.from(record['MULTI_TOKEN_ORACLES'], 'base64'); multiTokenOracles = JSON.parse(buffer.toString()); } + sponsorName = record['SPONSOR_NAME']; + sponsorImage = record['LOGO_URL']; privateKey = decode(record['PRIVATE_KEY']); supportedNetworks = record['SUPPORTED_NETWORKS']; noOfTxns = record['NO_OF_TRANSACTIONS_IN_A_MONTH']; @@ -144,10 +180,10 @@ const routes: FastifyPluginAsync = async (server) => { !(multiTokenOracles[chainId] && multiTokenOracles[chainId][gasToken]) ) return reply.code(ReturnCode.FAILURE).send({ error: ErrorMessage.UNSUPPORTED_NETWORK_TOKEN }) - const networkConfig = getNetworkConfig(chainId, supportedNetworks ?? ''); + const networkConfig = getNetworkConfig(chainId, supportedNetworks ?? '', entryPoint); if (!networkConfig) return reply.code(ReturnCode.FAILURE).send({ error: ErrorMessage.UNSUPPORTED_NETWORK }); - let result; + let result: any; switch (mode.toLowerCase()) { case 'sponsor': { const date = new Date(); @@ -158,8 +194,8 @@ const routes: FastifyPluginAsync = async (server) => { const IndexerData = await getIndexerData(signerAddress, userOp.sender, date.getMonth(), date.getFullYear(), noOfTxns, indexerEndpoint); if (IndexerData.length >= noOfTxns) return reply.code(ReturnCode.FAILURE).send({ error: ErrorMessage.QUOTA_EXCEEDED }) } - const validUntil = context.validUntil ? new Date(context.validUntil) : date; - const validAfter = context.validAfter ? new Date(context.validAfter) : date; + const validUntil = context?.validUntil ? new Date(context.validUntil) : date; + const validAfter = context?.validAfter ? new Date(context.validAfter) : date; const hex = (Number((validUntil.valueOf() / 1000).toFixed(0)) + 600).toString(16); const hex1 = (Number((validAfter.valueOf() / 1000).toFixed(0)) - 60).toString(16); let str = '0x' @@ -172,10 +208,14 @@ const routes: FastifyPluginAsync = async (server) => { } str += hex; str1 += hex1; - result = await paymaster.sign(userOp, str, str1, entryPoint, networkConfig.contracts.etherspotPaymasterAddress, networkConfig.bundler, signer, server.log); + if (entryPoint == SUPPORTED_ENTRYPOINTS.EPV_06) + result = await paymaster.signV06(userOp, str, str1, entryPoint, networkConfig.contracts.etherspotPaymasterAddress, networkConfig.bundler, signer, estimate, server.log); + else result = await paymaster.signV07(userOp, str, str1, entryPoint, networkConfig.contracts.etherspotPaymasterAddress, networkConfig.bundler, signer, estimate, server.log); break; } case 'erc20': { + if (entryPoint !== SUPPORTED_ENTRYPOINTS.EPV_06) + throw new Error('Currently only 0x5FF137D4b0FDCD49DcA30c7CF57E578a026d2789 entryPoint address is supported') let paymasterAddress: string; if (customPaymasters[chainId] && customPaymasters[chainId][gasToken]) paymasterAddress = customPaymasters[chainId][gasToken]; else paymasterAddress = PAYMASTER_ADDRESS[chainId][gasToken] @@ -183,6 +223,8 @@ const routes: FastifyPluginAsync = async (server) => { break; } case 'multitoken': { + if (entryPoint !== SUPPORTED_ENTRYPOINTS.EPV_06) + throw new Error('Currently only 0x5FF137D4b0FDCD49DcA30c7CF57E578a026d2789 entryPoint address is supported') const date = new Date(); const provider = new providers.JsonRpcProvider(networkConfig.bundler); const signer = new Wallet(privateKey, provider) @@ -211,6 +253,7 @@ const routes: FastifyPluginAsync = async (server) => { } } server.log.info(result, 'Response sent: '); + if (sponsorDetails) result.sponsor = { name: sponsorName, icon: sponsorImage }; if (body.jsonrpc) return reply.code(ReturnCode.SUCCESS).send({ jsonrpc: body.jsonrpc, id: body.id, result, error: null }) return reply.code(ReturnCode.SUCCESS).send(result); @@ -277,7 +320,7 @@ const routes: FastifyPluginAsync = async (server) => { if (server.config.SUPPORTED_NETWORKS == '' && !SupportedNetworks) { return reply.code(ReturnCode.FAILURE).send({ error: ErrorMessage.UNSUPPORTED_NETWORK }); } - const networkConfig = getNetworkConfig(chainId, supportedNetworks ?? ''); + const networkConfig = getNetworkConfig(chainId, supportedNetworks ?? '', entryPoint); if (!networkConfig) return reply.code(ReturnCode.FAILURE).send({ error: ErrorMessage.UNSUPPORTED_NETWORK }); let result; if (customPaymasters[chainId] && customPaymasters[chainId][gasToken]) result = { message: customPaymasters[chainId][gasToken] } @@ -340,7 +383,7 @@ const routes: FastifyPluginAsync = async (server) => { if (server.config.SUPPORTED_NETWORKS == '' && !SupportedNetworks) { return reply.code(ReturnCode.FAILURE).send({ error: ErrorMessage.UNSUPPORTED_NETWORK }); } - const networkConfig = getNetworkConfig(chainId, supportedNetworks ?? ''); + const networkConfig = getNetworkConfig(chainId, supportedNetworks ?? '', SUPPORTED_ENTRYPOINTS.EPV_06); if (!networkConfig) return reply.code(ReturnCode.FAILURE).send({ error: ErrorMessage.UNSUPPORTED_NETWORK }); const validAddresses = address.every(ethers.utils.isAddress); if (!validAddresses) return reply.code(ReturnCode.FAILURE).send({ error: "Invalid Address passed" }); @@ -398,7 +441,7 @@ const routes: FastifyPluginAsync = async (server) => { if (server.config.SUPPORTED_NETWORKS == '' && !SupportedNetworks) { return reply.code(ReturnCode.FAILURE).send({ error: ErrorMessage.UNSUPPORTED_NETWORK }); } - const networkConfig = getNetworkConfig(chainId, supportedNetworks ?? ''); + const networkConfig = getNetworkConfig(chainId, supportedNetworks ?? '', SUPPORTED_ENTRYPOINTS.EPV_06); if (!networkConfig) return reply.code(ReturnCode.FAILURE).send({ error: ErrorMessage.UNSUPPORTED_NETWORK }); const validAddresses = address.every(ethers.utils.isAddress); if (!validAddresses) return reply.code(ReturnCode.FAILURE).send({ error: "Invalid Address passed" }); @@ -456,7 +499,7 @@ const routes: FastifyPluginAsync = async (server) => { if (server.config.SUPPORTED_NETWORKS == '' && !SupportedNetworks) { return reply.code(ReturnCode.FAILURE).send({ error: ErrorMessage.UNSUPPORTED_NETWORK }); } - const networkConfig = getNetworkConfig(chainId, supportedNetworks ?? ''); + const networkConfig = getNetworkConfig(chainId, supportedNetworks ?? '', SUPPORTED_ENTRYPOINTS.EPV_06); if (!networkConfig) return reply.code(ReturnCode.FAILURE).send({ error: ErrorMessage.UNSUPPORTED_NETWORK }); const response = await paymaster.checkWhitelistAddress(accountAddress, networkConfig.contracts.etherspotPaymasterAddress, networkConfig.bundler, privateKey, server.log); server.log.info(response, 'Response sent: '); @@ -513,7 +556,60 @@ const routes: FastifyPluginAsync = async (server) => { if (server.config.SUPPORTED_NETWORKS == '' && !SupportedNetworks) { return reply.code(ReturnCode.FAILURE).send({ error: ErrorMessage.UNSUPPORTED_NETWORK }); } - const networkConfig = getNetworkConfig(chainId, supportedNetworks ?? ''); + const networkConfig = getNetworkConfig(chainId, supportedNetworks ?? '', SUPPORTED_ENTRYPOINTS.EPV_06); + if (!networkConfig) return reply.code(ReturnCode.FAILURE).send({ error: ErrorMessage.UNSUPPORTED_NETWORK }); + return await paymaster.deposit(amount, networkConfig.contracts.etherspotPaymasterAddress, networkConfig.bundler, privateKey, chainId, server.log); + } catch (err: any) { + request.log.error(err); + if (err.name == "ResourceNotFoundException") + return reply.code(ReturnCode.FAILURE).send({ error: ErrorMessage.INVALID_API_KEY }); + return reply.code(ReturnCode.FAILURE).send({ error: err.message ?? ErrorMessage.FAILED_TO_PROCESS }) + } + } + ) + + server.post( + "/deposit/v2", + whitelistResponseSchema, + async function (request, reply) { + try { + printRequest("/deposit/v2", request, server.log); + const body: any = request.body; + const query: any = request.query; + const amount = body.params[0]; + const chainId = query['chainId'] ?? body.params[1]; + const api_key = query['apiKey'] ?? body.params[2]; + if (!api_key) + return reply.code(ReturnCode.FAILURE).send({ error: ErrorMessage.INVALID_API_KEY }) + let privateKey = ''; + let supportedNetworks; + if (!unsafeMode) { + const AWSresponse = await client.send( + new GetSecretValueCommand({ + SecretId: prefixSecretId + api_key, + }) + ); + const secrets = JSON.parse(AWSresponse.SecretString ?? '{}'); + if (!secrets['PRIVATE_KEY']) return reply.code(ReturnCode.FAILURE).send({ error: ErrorMessage.INVALID_API_KEY }) + privateKey = secrets['PRIVATE_KEY']; + supportedNetworks = secrets['SUPPORTED_NETWORKS']; + } else { + const record: any = await getSQLdata(api_key, server.sqlite.db, server.log); + if (!record) return reply.code(ReturnCode.FAILURE).send({ error: ErrorMessage.INVALID_API_KEY }) + privateKey = decode(record['PRIVATE_KEY']); + supportedNetworks = record['SUPPORTED_NETWORKS']; + } + if ( + isNaN(amount) || + !chainId || + isNaN(chainId) + ) { + return reply.code(ReturnCode.FAILURE).send({ error: ErrorMessage.INVALID_DATA }); + } + if (server.config.SUPPORTED_NETWORKS == '' && !SupportedNetworks) { + return reply.code(ReturnCode.FAILURE).send({ error: ErrorMessage.UNSUPPORTED_NETWORK }); + } + const networkConfig = getNetworkConfig(chainId, supportedNetworks ?? '', SUPPORTED_ENTRYPOINTS.EPV_07); if (!networkConfig) return reply.code(ReturnCode.FAILURE).send({ error: ErrorMessage.UNSUPPORTED_NETWORK }); return await paymaster.deposit(amount, networkConfig.contracts.etherspotPaymasterAddress, networkConfig.bundler, privateKey, chainId, server.log); } catch (err: any) { diff --git a/backend/src/routes/metadata.ts b/backend/src/routes/metadata.ts index b8171e0..4007af3 100644 --- a/backend/src/routes/metadata.ts +++ b/backend/src/routes/metadata.ts @@ -37,6 +37,7 @@ const metadataRoutes: FastifyPluginAsync = async (server) => { let multiTokenOracles = []; let privateKey = ''; let supportedNetworks; + let sponsorName = '', sponsorImage = ''; if (!unsafeMode) { const AWSresponse = await client.send( new GetSecretValueCommand({ @@ -56,6 +57,8 @@ const metadataRoutes: FastifyPluginAsync = async (server) => { const buffer = Buffer.from(secrets['MULTI_TOKEN_PAYMASTERS'], 'base64'); multiTokenPaymasters = JSON.parse(buffer.toString()); } + sponsorName = secrets['SPONSOR_NAME']; + sponsorImage = secrets['LOGO_URL']; privateKey = secrets['PRIVATE_KEY']; supportedNetworks = secrets['SUPPORTED_NETWORKS']; } else { @@ -72,28 +75,30 @@ const metadataRoutes: FastifyPluginAsync = async (server) => { const buffer = Buffer.from(record['MULTI_TOKEN_PAYMASTERS'], 'base64'); multiTokenPaymasters = JSON.parse(buffer.toString()); } + sponsorName = record['SPONSOR_NAME']; + sponsorImage = record['LOGO_URL']; privateKey = decode(record['PRIVATE_KEY']); supportedNetworks = record['SUPPORTED_NETWORKS']; } if (server.config.SUPPORTED_NETWORKS == '' && !SupportedNetworks) { return reply.code(ReturnCode.FAILURE).send({ error: ErrorMessage.UNSUPPORTED_NETWORK }); } - const networkConfig = getNetworkConfig(chainId, supportedNetworks ?? ''); + 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); const signer = new Wallet(privateKey, provider) const balance = await signer.getBalance(); const address = await signer.getAddress(); - const chainsSupported: number[] = []; + const chainsSupported: {chainId: number, entryPoint: string}[] = []; if (supportedNetworks) { const buffer = Buffer.from(supportedNetworks, 'base64'); const SUPPORTED_NETWORKS = JSON.parse(buffer.toString()) - SUPPORTED_NETWORKS.map((element: { chainId: number; }) => { - chainsSupported.push(element.chainId); + SUPPORTED_NETWORKS.map((element: { chainId: number, entryPoint: string }) => { + chainsSupported.push({chainId: element.chainId, entryPoint: element.entryPoint ?? "0x5FF137D4b0FDCD49DcA30c7CF57E578a026d2789"}); }) } else { SupportedNetworks.map(element => { - chainsSupported.push(element.chainId); + chainsSupported.push({chainId: element.chainId, entryPoint: element.entryPoint ?? "0x5FF137D4b0FDCD49DcA30c7CF57E578a026d2789"}); }) } const tokenPaymasterAddresses = { @@ -106,6 +111,7 @@ const metadataRoutes: FastifyPluginAsync = async (server) => { chainsSupported: chainsSupported, tokenPaymasters: tokenPaymasterAddresses, multiTokenPaymasters, + sponsorDetails: { name: sponsorName, icon: sponsorImage } }) } catch (err: any) { request.log.error(err); diff --git a/backend/src/utils/common.ts b/backend/src/utils/common.ts index 86ad8b2..bfc2624 100644 --- a/backend/src/utils/common.ts +++ b/backend/src/utils/common.ts @@ -10,13 +10,13 @@ export function printRequest(methodName: string, request: FastifyRequest, log: F log.info(request.body, "body passed: "); } -export function getNetworkConfig(key: any, supportedNetworks: any) { +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 }); + return SUPPORTED_NETWORKS.find((chain: any) => { return chain["chainId"] == key && chain["entryPoint"] == entryPoint }); } else - return SupportedNetworks.find((chain) => chain.chainId == key); + return SupportedNetworks.find((chain) => chain.chainId == key && chain.entryPoint == entryPoint); } export async function getSQLdata(apiKey: string, db: Database, log: FastifyBaseLogger) { From 5944f0453824aaac9289ba5efdb176dcc2fd17e6 Mon Sep 17 00:00:00 2001 From: Vignesh Date: Fri, 31 May 2024 04:51:45 +0530 Subject: [PATCH 2/2] bumped up package versions --- admin_frontend/package-lock.json | 4 ++-- admin_frontend/package.json | 2 +- backend/package.json | 2 +- frontend/package-lock.json | 4 ++-- frontend/package.json | 2 +- 5 files changed, 7 insertions(+), 7 deletions(-) diff --git a/admin_frontend/package-lock.json b/admin_frontend/package-lock.json index 46cb049..8a4bf82 100644 --- a/admin_frontend/package-lock.json +++ b/admin_frontend/package-lock.json @@ -1,12 +1,12 @@ { "name": "admin_frontend", - "version": "1.2.3", + "version": "1.2.4", "lockfileVersion": 3, "requires": true, "packages": { "": { "name": "admin_frontend", - "version": "1.2.3", + "version": "1.2.4", "dependencies": { "@emotion/react": "11.11.3", "@emotion/styled": "11.11.0", diff --git a/admin_frontend/package.json b/admin_frontend/package.json index dff0365..4cbb426 100644 --- a/admin_frontend/package.json +++ b/admin_frontend/package.json @@ -1,6 +1,6 @@ { "name": "admin_frontend", - "version": "1.2.3", + "version": "1.2.4", "private": true, "dependencies": { "@emotion/react": "11.11.3", diff --git a/backend/package.json b/backend/package.json index 45ae781..11d1509 100644 --- a/backend/package.json +++ b/backend/package.json @@ -1,6 +1,6 @@ { "name": "arka", - "version": "1.2.3", + "version": "1.2.4", "description": "ARKA - (Albanian for Cashier's case) is the first open source Paymaster as a service software", "type": "module", "directories": { diff --git a/frontend/package-lock.json b/frontend/package-lock.json index 27b0e76..7460a20 100644 --- a/frontend/package-lock.json +++ b/frontend/package-lock.json @@ -1,12 +1,12 @@ { "name": "arka_frontend", - "version": "1.2.3", + "version": "1.2.4", "lockfileVersion": 3, "requires": true, "packages": { "": { "name": "arka_frontend", - "version": "1.2.3", + "version": "1.2.4", "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 6b1e142..630bf15 100644 --- a/frontend/package.json +++ b/frontend/package.json @@ -1,6 +1,6 @@ { "name": "arka_frontend", - "version": "1.2.3", + "version": "1.2.4", "private": true, "dependencies": { "@babel/plugin-proposal-private-property-in-object": "7.21.11",