From 14e95b45e99723b40521b0dfd136ba929230f7c1 Mon Sep 17 00:00:00 2001 From: Vignesh Date: Fri, 26 Jul 2024 16:13:28 +0530 Subject: [PATCH 1/2] added migration script and also support for ep07 for erc20 --- .../20240725000001-update-apiKey-table.cjs | 11 + backend/src/abi/ERC20PaymasterV07Abi.ts | 681 ++++++++++++++++++ backend/src/models/api-key.ts | 6 + backend/src/paymaster/index.ts | 75 +- backend/src/routes/paymaster-routes.ts | 42 +- 5 files changed, 800 insertions(+), 15 deletions(-) create mode 100644 backend/migrations/20240725000001-update-apiKey-table.cjs create mode 100644 backend/src/abi/ERC20PaymasterV07Abi.ts diff --git a/backend/migrations/20240725000001-update-apiKey-table.cjs b/backend/migrations/20240725000001-update-apiKey-table.cjs new file mode 100644 index 0000000..1173517 --- /dev/null +++ b/backend/migrations/20240725000001-update-apiKey-table.cjs @@ -0,0 +1,11 @@ +require('dotenv').config(); + +async function up({ context: queryInterface }) { + await queryInterface.sequelize.query(`ALTER TABLE IF EXISTS arka.api_keys ADD COLUMN "ERC20_PAYMASTERS_V2" text default null`); +} + +async function down({ context: queryInterface }) { + await queryInterface.sequelize.query(`ALTER TABLE "${process.env.DATABASE_SCHEMA_NAME}".api_keys DROP COLUMN ERC20_PAYMASTERS_V2;`); +} + +module.exports = { up, down } \ No newline at end of file diff --git a/backend/src/abi/ERC20PaymasterV07Abi.ts b/backend/src/abi/ERC20PaymasterV07Abi.ts new file mode 100644 index 0000000..854ebc9 --- /dev/null +++ b/backend/src/abi/ERC20PaymasterV07Abi.ts @@ -0,0 +1,681 @@ +export default [ + { + "inputs": [ + { + "internalType": "contract IERC20Metadata", + "name": "_token", + "type": "address" + }, + { + "internalType": "address", + "name": "_entryPoint", + "type": "address" + }, + { + "internalType": "contract IOracle", + "name": "_tokenOracle", + "type": "address" + }, + { + "internalType": "contract IOracle", + "name": "_nativeAssetOracle", + "type": "address" + }, + { + "internalType": "uint32", + "name": "_stalenessThreshold", + "type": "uint32" + }, + { + "internalType": "address", + "name": "_owner", + "type": "address" + }, + { + "internalType": "uint32", + "name": "_priceMarkupLimit", + "type": "uint32" + }, + { + "internalType": "uint32", + "name": "_priceMarkup", + "type": "uint32" + }, + { + "internalType": "uint256", + "name": "_refundPostOpCost", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "_refundPostOpCostWithGuarantor", + "type": "uint256" + } + ], + "stateMutability": "nonpayable", + "type": "constructor" + }, + { + "inputs": [], + "name": "OracleDecimalsInvalid", + "type": "error" + }, + { + "inputs": [], + "name": "OraclePriceNotPositive", + "type": "error" + }, + { + "inputs": [], + "name": "OraclePriceStale", + "type": "error" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "owner", + "type": "address" + } + ], + "name": "OwnableInvalidOwner", + "type": "error" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "account", + "type": "address" + } + ], + "name": "OwnableUnauthorizedAccount", + "type": "error" + }, + { + "inputs": [], + "name": "PaymasterDataLengthInvalid", + "type": "error" + }, + { + "inputs": [], + "name": "PaymasterDataModeInvalid", + "type": "error" + }, + { + "inputs": [], + "name": "PriceMarkupTooHigh", + "type": "error" + }, + { + "inputs": [], + "name": "PriceMarkupTooLow", + "type": "error" + }, + { + "inputs": [], + "name": "TokenAmountTooHigh", + "type": "error" + }, + { + "inputs": [], + "name": "TokenLimitZero", + "type": "error" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "uint32", + "name": "priceMarkup", + "type": "uint32" + } + ], + "name": "MarkupUpdated", + "type": "event" + }, + { + "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": true, + "internalType": "bytes32", + "name": "userOpHash", + "type": "bytes32" + }, + { + "indexed": true, + "internalType": "address", + "name": "user", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "guarantor", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "tokenAmountPaid", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "tokenPrice", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "bool", + "name": "paidByGuarantor", + "type": "bool" + } + ], + "name": "UserOperationSponsored", + "type": "event" + }, + { + "inputs": [], + "name": "PRICE_DENOMINATOR", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "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" + }, + { + "internalType": "uint256", + "name": "tokenLimit", + "type": "uint256" + } + ], + "name": "getHash", + "outputs": [ + { + "internalType": "bytes32", + "name": "", + "type": "bytes32" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "getPrice", + "outputs": [ + { + "internalType": "uint192", + "name": "", + "type": "uint192" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "nativeAssetOracle", + "outputs": [ + { + "internalType": "contract IOracle", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "owner", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "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": "priceMarkup", + "outputs": [ + { + "internalType": "uint32", + "name": "", + "type": "uint32" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "priceMarkupLimit", + "outputs": [ + { + "internalType": "uint32", + "name": "", + "type": "uint32" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "refundPostOpCost", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "refundPostOpCostWithGuarantor", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "renounceOwnership", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "stalenessThreshold", + "outputs": [ + { + "internalType": "uint32", + "name": "", + "type": "uint32" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "token", + "outputs": [ + { + "internalType": "contract IERC20", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "tokenDecimals", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "tokenOracle", + "outputs": [ + { + "internalType": "contract IOracle", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "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": "uint32", + "name": "_priceMarkup", + "type": "uint32" + } + ], + "name": "updateMarkup", + "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": [ + { + "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" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "to", + "type": "address" + }, + { + "internalType": "uint256", + "name": "amount", + "type": "uint256" + } + ], + "name": "withdrawToken", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + } +] \ No newline at end of file diff --git a/backend/src/models/api-key.ts b/backend/src/models/api-key.ts index 3072d5c..e098534 100644 --- a/backend/src/models/api-key.ts +++ b/backend/src/models/api-key.ts @@ -6,6 +6,7 @@ export class APIKey extends Model { public privateKey!: string; public supportedNetworks?: string | null; public erc20Paymasters?: string | null; + public erc20PaymastersV2?: string | null; public multiTokenPaymasters?: string | null; public multiTokenOracles?: string | null; public sponsorName?: string | null; @@ -46,6 +47,11 @@ export function initializeAPIKeyModel(sequelize: Sequelize, schema: string) { allowNull: true, field: 'ERC20_PAYMASTERS' }, + erc20PaymastersV2: { + type: DataTypes.TEXT, + allowNull: true, + field: 'ERC20_PAYMASTERS_V2' + }, multiTokenPaymasters: { type: DataTypes.TEXT, allowNull: true, diff --git a/backend/src/paymaster/index.ts b/backend/src/paymaster/index.ts index 5d5a15c..4d12009 100644 --- a/backend/src/paymaster/index.ts +++ b/backend/src/paymaster/index.ts @@ -11,6 +11,7 @@ import { getEtherscanFee } from '../utils/common.js'; import MultiTokenPaymasterAbi from '../abi/MultiTokenPaymasterAbi.js'; import OrochiOracleAbi from '../abi/OrochiOracleAbi.js'; import ChainlinkOracleAbi from '../abi/ChainlinkOracleAbi.js'; +import ERC20PaymasterV07Abi from '../abi/ERC20PaymasterV07Abi.js'; export class Paymaster { feeMarkUp: BigNumber; @@ -89,9 +90,9 @@ export class Paymaster { returnValue = { paymaster: paymasterAddress, paymasterData: paymasterData, - preVerificationGas: packedUserOp.preVerificationGas.toString(), - verificationGasLimit: userOp.verificationGasLimit, - callGasLimit: userOp.callGasLimit, + preVerificationGas: BigNumber.from(packedUserOp.preVerificationGas).toHexString(), + verificationGasLimit: BigNumber.from(userOp.verificationGasLimit).toHexString(), + callGasLimit: BigNumber.from(userOp.callGasLimit).toHexString(), paymasterVerificationGasLimit: BigNumber.from(30000).toString(), paymasterPostOpGasLimit: "0x1" } @@ -288,6 +289,74 @@ export class Paymaster { } } + async ERC20PaymasterV07(userOp: any, bundlerRpc: string, entryPoint: string, paymasterAddress: string, estimate: boolean, log?: FastifyBaseLogger) { + try { + const provider = new providers.JsonRpcProvider(bundlerRpc); + if (!userOp.signature) userOp.signature = '0x'; + if (userOp.factory && userOp.factoryData) userOp.initCode = hexConcat([userOp.factory, userOp.factoryData ?? '']) + if (!userOp.initCode) userOp.initCode = "0x"; + const erc20Paymaster = new Contract(paymasterAddress, ERC20PaymasterV07Abi, provider) + const tokenAddress = await erc20Paymaster.token(); + const tokenPrice = await erc20Paymaster.getPrice(); + const priceMarkup = await erc20Paymaster.priceMarkup(); + // The minimum ABI to get the ERC20 Token balance + const minABI = [ + // balanceOf + { + constant: true, + + inputs: [{ name: '_owner', type: 'address' }], + + name: 'balanceOf', + + outputs: [{ name: 'balance', type: 'uint256' }], + + type: 'function', + }, + ] + const maxCost = BigNumber.from(userOp.preVerificationGas ?? 0).add(userOp.callGasLimit ?? 0).add(userOp.verificationGasLimit ?? 0); + if (!userOp.maxFeePerGas) userOp.maxFeePerGas = "0x1"; + let tokenAmountRequired = maxCost.add('30000').mul(userOp.maxFeePerGas) + tokenAmountRequired = tokenAmountRequired.mul(priceMarkup).div(1e6).mul(tokenPrice).div(ethers.utils.parseEther('1')) + const tokenContract = new Contract(tokenAddress, minABI, provider) + const tokenBalance = await tokenContract.balanceOf(userOp.sender); + + if (tokenAmountRequired.gte(tokenBalance)) + throw new Error(`The required token amount ${tokenAmountRequired.toString()} is more than what the sender has ${tokenBalance}`) + if (estimate) { + userOp.paymaster = paymasterAddress; + userOp.paymasterVerificationGasLimit = BigNumber.from('60000').toHexString(); + userOp.paymasterPostOpGasLimit = BigNumber.from('100000').toHexString(); + const response = await provider.send('eth_estimateUserOperationGas', [userOp, entryPoint]); + userOp.verificationGasLimit = response.verificationGasLimit; + userOp.callGasLimit = response.callGasLimit; + userOp.preVerificationGas = response.preVerificationGas; + } + let returnValue; + if (estimate) { + returnValue = { + paymaster: paymasterAddress, + paymasterData: "0x", // since the default mode is 0 + preVerificationGas: BigNumber.from(userOp.preVerificationGas).toHexString(), + verificationGasLimit: BigNumber.from(userOp.verificationGasLimit).toHexString(), + callGasLimit: BigNumber.from(userOp.callGasLimit).toHexString(), + paymasterVerificationGasLimit: BigNumber.from('60000').toHexString(), + paymasterPostOpGasLimit: BigNumber.from('100000').toHexString() + } + } else { + returnValue = { + paymaster: paymasterAddress, + paymasterData: "0x", + } + } + + return returnValue; + } catch (err: any) { + if (log) log.error(err, 'ERC20Paymaster'); + throw new Error('Failed to process request to bundler. Please contact support team RawErrorMsg:' + err.message) + } + } + async pimlicoAddress(gasToken: string, chainId: number, log?: FastifyBaseLogger) { try { return { diff --git a/backend/src/routes/paymaster-routes.ts b/backend/src/routes/paymaster-routes.ts index 564ea15..a7278e2 100644 --- a/backend/src/routes/paymaster-routes.ts +++ b/backend/src/routes/paymaster-routes.ts @@ -79,6 +79,7 @@ const paymasterRoutes: FastifyPluginAsync = async (server) => { else epVersion = EPVersions.EPV_07; let customPaymasters = []; + let customPaymastersV2 = []; let multiTokenPaymasters = []; let multiTokenOracles = []; let privateKey = ''; @@ -102,6 +103,10 @@ const paymasterRoutes: FastifyPluginAsync = async (server) => { const buffer = Buffer.from(secrets['ERC20_PAYMASTERS'], 'base64'); customPaymasters = JSON.parse(buffer.toString()); } + if (secrets['ERC20_PAYMASTERS_V2']) { + const buffer = Buffer.from(secrets['ERC20_PAYMASTERS_V2'], 'base64'); + customPaymastersV2 = JSON.parse(buffer.toString()); + } if (secrets['MULTI_TOKEN_PAYMASTERS']) { const buffer = Buffer.from(secrets['MULTI_TOKEN_PAYMASTERS'], 'base64'); multiTokenPaymasters = JSON.parse(buffer.toString()); @@ -137,10 +142,16 @@ const paymasterRoutes: FastifyPluginAsync = async (server) => { customPaymasters = JSON.parse(buffer.toString()); } + if (apiKeyEntity.erc20PaymastersV2) { + const buffer = Buffer.from(apiKeyEntity.erc20PaymastersV2, 'base64'); + customPaymastersV2 = JSON.parse(buffer.toString()); + } + if (apiKeyEntity.multiTokenPaymasters) { const buffer = Buffer.from(apiKeyEntity.multiTokenPaymasters, 'base64'); multiTokenPaymasters = JSON.parse(buffer.toString()); } + if (apiKeyEntity.multiTokenOracles) { const buffer = Buffer.from(apiKeyEntity.multiTokenOracles, 'base64'); multiTokenOracles = JSON.parse(buffer.toString()); @@ -169,12 +180,6 @@ const paymasterRoutes: FastifyPluginAsync = async (server) => { return reply.code(ReturnCode.FAILURE).send({ error: ErrorMessage.UNSUPPORTED_NETWORK }); } - if ( - mode.toLowerCase() == 'erc20' && - !(PAYMASTER_ADDRESS[chainId] && PAYMASTER_ADDRESS[chainId][gasToken]) && - !(customPaymasters[chainId] && customPaymasters[chainId][gasToken]) - ) return reply.code(ReturnCode.FAILURE).send({ error: ErrorMessage.UNSUPPORTED_NETWORK_TOKEN }) - if (gasToken && ethers.utils.isAddress(gasToken)) gasToken = ethers.utils.getAddress(gasToken) if (mode.toLowerCase() == 'multitoken' && @@ -247,12 +252,25 @@ const paymasterRoutes: FastifyPluginAsync = async (server) => { 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] - result = await paymaster.pimlico(userOp, networkConfig.bundler, entryPoint, paymasterAddress, server.log); + if (entryPoint === SUPPORTED_ENTRYPOINTS.EPV_06) { + if ( + !(PAYMASTER_ADDRESS[chainId] && PAYMASTER_ADDRESS[chainId][gasToken]) && + !(customPaymasters[chainId] && customPaymasters[chainId][gasToken]) + ) return reply.code(ReturnCode.FAILURE).send({ error: ErrorMessage.UNSUPPORTED_NETWORK_TOKEN }) + let paymasterAddress: string; + if (customPaymasters[chainId] && customPaymasters[chainId][gasToken]) paymasterAddress = customPaymasters[chainId][gasToken]; + else paymasterAddress = PAYMASTER_ADDRESS[chainId][gasToken] + result = await paymaster.pimlico(userOp, networkConfig.bundler, entryPoint, paymasterAddress, server.log); + } else if (entryPoint === SUPPORTED_ENTRYPOINTS.EPV_07) { + if ( + !(customPaymastersV2[chainId] && customPaymastersV2[chainId][gasToken]) && + entryPoint !== SUPPORTED_ENTRYPOINTS.EPV_07 + ) return reply.code(ReturnCode.FAILURE).send({ error: ErrorMessage.UNSUPPORTED_NETWORK_TOKEN }) + const paymasterAddress = customPaymastersV2[chainId][gasToken]; + result = await paymaster.ERC20PaymasterV07(userOp, networkConfig.bundler, entryPoint, paymasterAddress, estimate, server.log); + } else { + throw new Error(`Currently only ${SUPPORTED_ENTRYPOINTS.EPV_06} & ${SUPPORTED_ENTRYPOINTS.EPV_07} entryPoint addresses are supported`) + } break; } case 'multitoken': { From 198521eff9d79eced8ee30c232e2db6214355323 Mon Sep 17 00:00:00 2001 From: Vignesh Date: Fri, 26 Jul 2024 18:06:37 +0530 Subject: [PATCH 2/2] updated package version --- 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 9e3e514..ef7e15c 100644 --- a/admin_frontend/package-lock.json +++ b/admin_frontend/package-lock.json @@ -1,12 +1,12 @@ { "name": "admin_frontend", - "version": "1.2.9", + "version": "1.3.1", "lockfileVersion": 3, "requires": true, "packages": { "": { "name": "admin_frontend", - "version": "1.2.9", + "version": "1.3.1", "dependencies": { "@emotion/react": "11.11.3", "@emotion/styled": "11.11.0", diff --git a/admin_frontend/package.json b/admin_frontend/package.json index 90184df..30eb497 100644 --- a/admin_frontend/package.json +++ b/admin_frontend/package.json @@ -1,6 +1,6 @@ { "name": "admin_frontend", - "version": "1.3.0", + "version": "1.3.1", "private": true, "dependencies": { "@emotion/react": "11.11.3", diff --git a/backend/package.json b/backend/package.json index a56129e..9c182af 100644 --- a/backend/package.json +++ b/backend/package.json @@ -1,6 +1,6 @@ { "name": "arka", - "version": "1.3.0", + "version": "1.3.1", "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 4397593..93ea6c9 100644 --- a/frontend/package-lock.json +++ b/frontend/package-lock.json @@ -1,12 +1,12 @@ { "name": "arka_frontend", - "version": "1.2.9", + "version": "1.3.1", "lockfileVersion": 3, "requires": true, "packages": { "": { "name": "arka_frontend", - "version": "1.2.9", + "version": "1.3.1", "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 f1eaa32..9cbe057 100644 --- a/frontend/package.json +++ b/frontend/package.json @@ -1,6 +1,6 @@ { "name": "arka_frontend", - "version": "1.3.0", + "version": "1.3.1", "private": true, "dependencies": { "@babel/plugin-proposal-private-property-in-object": "7.21.11",