UNPKG

@tunghm/relay-kit

Version:
542 lines 29.8 kB
"use strict"; var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) { if (k2 === undefined) k2 = k; var desc = Object.getOwnPropertyDescriptor(m, k); if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) { desc = { enumerable: true, get: function() { return m[k]; } }; } Object.defineProperty(o, k2, desc); }) : (function(o, m, k, k2) { if (k2 === undefined) k2 = k; o[k2] = m[k]; })); var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) { Object.defineProperty(o, "default", { enumerable: true, value: v }); }) : function(o, v) { o["default"] = v; }); var __importStar = (this && this.__importStar) || function (mod) { if (mod && mod.__esModule) return mod; var result = {}; if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k); __setModuleDefault(result, mod); return result; }; var __importDefault = (this && this.__importDefault) || function (mod) { return (mod && mod.__esModule) ? mod : { "default": mod }; }; Object.defineProperty(exports, "__esModule", { value: true }); const ethers_1 = require("ethers"); const protocol_kit_1 = __importStar(require("@safe-global/protocol-kit")), protocolKit = protocol_kit_1; const safe_modules_deployments_1 = require("@safe-global/safe-modules-deployments"); const safe_core_sdk_types_1 = require("@safe-global/safe-core-sdk-types"); const Safe4337Pack_1 = require("./Safe4337Pack"); const SafeOperation_1 = __importDefault(require("./SafeOperation")); const constants = __importStar(require("./constants")); const fixtures = __importStar(require("./testing-utils/fixtures")); const helpers_1 = require("./testing-utils/helpers"); const dotenv_1 = __importDefault(require("dotenv")); const utils = __importStar(require("./utils")); dotenv_1.default.config(); const sendMock = jest.fn(async (method) => { switch (method) { case constants.RPC_4337_CALLS.SUPPORTED_ENTRY_POINTS: return fixtures.ENTRYPOINTS; case constants.RPC_4337_CALLS.CHAIN_ID: return fixtures.CHAIN_ID; case constants.RPC_4337_CALLS.SEND_USER_OPERATION: return fixtures.USER_OPERATION_HASH; case constants.RPC_4337_CALLS.ESTIMATE_USER_OPERATION_GAS: return fixtures.GAS_ESTIMATION; case constants.RPC_4337_CALLS.GET_USER_OPERATION_BY_HASH: return fixtures.USER_OPERATION_BY_HASH; case constants.RPC_4337_CALLS.GET_USER_OPERATION_RECEIPT: return fixtures.USER_OPERATION_RECEIPT; case 'pimlico_getUserOperationGasPrice': return fixtures.USER_OPERATION_GAS_PRICE; default: return undefined; } }); jest.mock('./utils', () => ({ ...jest.requireActual('./utils'), getEip4337BundlerProvider: () => ({ send: sendMock }) })); let safe4337ModuleAddress; let addModulesLibAddress; describe('Safe4337Pack', () => { beforeAll(async () => { const network = parseInt(fixtures.CHAIN_ID).toString(); safe4337ModuleAddress = (0, safe_modules_deployments_1.getSafe4337ModuleDeployment)({ released: true, version: '0.2.0', network })?.networkAddresses[network]; addModulesLibAddress = (0, safe_modules_deployments_1.getAddModulesLibDeployment)({ released: true, version: '0.2.0', network })?.networkAddresses[network]; }); afterEach(() => { jest.clearAllMocks(); }); describe('4337 Safe validation', () => { it('should throw an error if the Safe version is not greater than 1.4.1', async () => { await expect((0, helpers_1.createSafe4337Pack)({ options: { safeAddress: fixtures.SAFE_ADDRESS_v1_3_0 } })).rejects.toThrow('Incompatibility detected: The current Safe Account version (1.3.0) is not supported. EIP-4337 requires the Safe to use at least v1.4.1.'); }); it('should throw an error if the 4337 Module is not enabled in the Safe account', async () => { await expect((0, helpers_1.createSafe4337Pack)({ options: { safeAddress: fixtures.SAFE_ADDRESS_4337_MODULE_NOT_ENABLED } })).rejects.toThrow('Incompatibility detected: The EIP-4337 module is not enabled in the provided Safe Account. Enable this module (address: 0xa581c4A4DB7175302464fF3C06380BC3270b4037) to add compatibility.'); }); it('should throw an error if the 4337 fallbackhandler is not attached to the Safe account', async () => { await expect((0, helpers_1.createSafe4337Pack)({ options: { safeAddress: fixtures.SAFE_ADDRESS_4337_FALLBACKHANDLER_NOT_ENABLED } })).rejects.toThrow('Incompatibility detected: The EIP-4337 fallbackhandler is not attached to the Safe Account. Attach this fallbackhandler (address: 0xa581c4A4DB7175302464fF3C06380BC3270b4037) to ensure compatibility.'); }); }); describe('When using existing Safe Accounts with version 1.4.1 or greater', () => { it('should be able to instantiate the pack using a existing Safe', async () => { const safe4337Pack = await (0, helpers_1.createSafe4337Pack)({ options: { safeAddress: fixtures.SAFE_ADDRESS_v1_4_1 } }); expect(safe4337Pack).toBeInstanceOf(Safe4337Pack_1.Safe4337Pack); expect(safe4337Pack.protocolKit).toBeInstanceOf(protocol_kit_1.default); expect(await safe4337Pack.protocolKit.getAddress()).toBe(fixtures.SAFE_ADDRESS_v1_4_1); expect(await safe4337Pack.getChainId()).toBe(fixtures.CHAIN_ID); }); it('should have the 4337 module enabled', async () => { const safe4337Pack = await (0, helpers_1.createSafe4337Pack)({ options: { safeAddress: fixtures.SAFE_ADDRESS_v1_4_1 } }); expect(await safe4337Pack.protocolKit.getModules()).toEqual([safe4337ModuleAddress]); }); it('should detect if a custom 4337 module is not enabled in the Safe', async () => { await expect((0, helpers_1.createSafe4337Pack)({ customContracts: { safe4337ModuleAddress: '0xCustomModule' }, options: { safeAddress: fixtures.SAFE_ADDRESS_v1_4_1 } })).rejects.toThrow('Incompatibility detected: The EIP-4337 module is not enabled in the provided Safe Account. Enable this module (address: 0xCustomModule) to add compatibility.'); }); it('should use the 4337 module as the fallback handler', async () => { const safe4337Pack = await (0, helpers_1.createSafe4337Pack)({ options: { safeAddress: fixtures.SAFE_ADDRESS_v1_4_1 } }); expect(await safe4337Pack.protocolKit.getFallbackHandler()).toEqual(safe4337ModuleAddress); }); }); describe('When the Safe Account does not exists', () => { it('should be able to instantiate the pack using a predicted Safe', async () => { const safe4337Pack = await (0, helpers_1.createSafe4337Pack)({ options: { owners: [fixtures.OWNER_1], threshold: 1 } }); expect(await safe4337Pack.protocolKit.getAddress()).toBe(fixtures.PREDICTED_SAFE_ADDRESS); }); it('should throw an error if the owners or threshold are not specified', async () => { await expect((0, helpers_1.createSafe4337Pack)({ // @ts-expect-error - An error will be thrown options: { threshold: 1 } })).rejects.toThrow('Owners and threshold are required to deploy a new Safe'); await expect((0, helpers_1.createSafe4337Pack)({ // @ts-expect-error - An error will be thrown options: { owners: [fixtures.OWNER_1] } })).rejects.toThrow('Owners and threshold are required to deploy a new Safe'); }); it('should encode the enableModules transaction as deployment data', async () => { const encodeFunctionDataSpy = jest.spyOn(constants.INTERFACES, 'encodeFunctionData'); const safeCreateSpy = jest.spyOn(protocol_kit_1.default, 'create'); const safe4337Pack = await (0, helpers_1.createSafe4337Pack)({ options: { owners: [fixtures.OWNER_1], threshold: 1 } }); expect(encodeFunctionDataSpy).toHaveBeenCalledWith('enableModules', [[safe4337ModuleAddress]]); expect(safeCreateSpy).toHaveBeenCalledWith({ ethAdapter: safe4337Pack.protocolKit.getEthAdapter(), predictedSafe: { safeDeploymentConfig: { safeVersion: constants.DEFAULT_SAFE_VERSION, saltNonce: undefined }, safeAccountConfig: { owners: [fixtures.OWNER_1], threshold: 1, to: addModulesLibAddress, data: constants.INTERFACES.encodeFunctionData('enableModules', [ [safe4337ModuleAddress] ]), fallbackHandler: safe4337ModuleAddress, paymentToken: ethers_1.ethers.ZeroAddress, payment: 0, paymentReceiver: ethers_1.ethers.ZeroAddress } } }); }); it('should encode the enablesModule transaction together with a specific token approval in a multiSend call when trying to use a paymaster', async () => { const encodeFunctionDataSpy = jest.spyOn(constants.INTERFACES, 'encodeFunctionData'); const safeCreateSpy = jest.spyOn(protocol_kit_1.default, 'create'); const safe4337Pack = await (0, helpers_1.createSafe4337Pack)({ options: { owners: [fixtures.OWNER_1], threshold: 1 }, paymasterOptions: { paymasterAddress: fixtures.PAYMASTER_ADDRESS, paymasterTokenAddress: fixtures.PAYMASTER_TOKEN_ADDRESS } }); const enableModulesData = constants.INTERFACES.encodeFunctionData('enableModules', [ [safe4337ModuleAddress] ]); const approveData = constants.INTERFACES.encodeFunctionData('approve', [ fixtures.PAYMASTER_ADDRESS, 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffn ]); const enable4337ModuleTransaction = { to: addModulesLibAddress, value: '0', data: enableModulesData, operation: safe_core_sdk_types_1.OperationType.DelegateCall }; const approveToPaymasterTransaction = { to: fixtures.PAYMASTER_TOKEN_ADDRESS, value: '0', data: approveData, operation: safe_core_sdk_types_1.OperationType.Call }; const multiSendData = protocolKit.encodeMultiSendData([ enable4337ModuleTransaction, approveToPaymasterTransaction ]); expect(encodeFunctionDataSpy).toHaveBeenNthCalledWith(4, 'multiSend', [multiSendData]); expect(safeCreateSpy).toHaveBeenCalledWith({ ethAdapter: safe4337Pack.protocolKit.getEthAdapter(), predictedSafe: { safeDeploymentConfig: { safeVersion: constants.DEFAULT_SAFE_VERSION, saltNonce: undefined }, safeAccountConfig: { owners: [fixtures.OWNER_1], threshold: 1, to: await safe4337Pack.protocolKit.getMultiSendAddress(), data: constants.INTERFACES.encodeFunctionData('multiSend', [multiSendData]), fallbackHandler: safe4337ModuleAddress, paymentToken: ethers_1.ethers.ZeroAddress, payment: 0, paymentReceiver: ethers_1.ethers.ZeroAddress } } }); }); }); describe('When creating a new SafeOperation', () => { let safe4337Pack; let transferUSDC; beforeAll(async () => { safe4337Pack = await (0, helpers_1.createSafe4337Pack)({ options: { safeAddress: fixtures.SAFE_ADDRESS_v1_4_1 } }); transferUSDC = { to: fixtures.PAYMASTER_TOKEN_ADDRESS, data: (0, helpers_1.generateTransferCallData)(fixtures.SAFE_ADDRESS_v1_4_1, 100000n), value: '0', operation: 0 }; }); it('should allow to use a transaction batch', async () => { const transactions = [transferUSDC, transferUSDC]; const safeOperation = await safe4337Pack.createTransaction({ transactions }); expect(safeOperation).toBeInstanceOf(SafeOperation_1.default); expect(safeOperation.data).toMatchObject({ safe: fixtures.SAFE_ADDRESS_v1_4_1, entryPoint: '0x5FF137D4b0FDCD49DcA30c7CF57E578a026d2789', initCode: '0x', paymasterAndData: '0x', callData: constants.INTERFACES.encodeFunctionData('executeUserOp', [ await safe4337Pack.protocolKit.getMultiSendAddress(), '0', constants.INTERFACES.encodeFunctionData('multiSend', [ protocolKit.encodeMultiSendData(transactions) ]), safe_core_sdk_types_1.OperationType.DelegateCall ]), nonce: 1n, callGasLimit: 150000n, validAfter: 0, validUntil: 0, maxFeePerGas: 100000n, maxPriorityFeePerGas: 200000n, verificationGasLimit: 150000n, preVerificationGas: 100000n }); }); it('should allow to use a single transaction', async () => { const safeOperation = await safe4337Pack.createTransaction({ transactions: [transferUSDC] }); expect(safeOperation).toBeInstanceOf(SafeOperation_1.default); expect(safeOperation.data).toMatchObject({ safe: fixtures.SAFE_ADDRESS_v1_4_1, entryPoint: '0x5FF137D4b0FDCD49DcA30c7CF57E578a026d2789', initCode: '0x', paymasterAndData: '0x', callData: constants.INTERFACES.encodeFunctionData('executeUserOp', [ transferUSDC.to, transferUSDC.value, transferUSDC.data, safe_core_sdk_types_1.OperationType.Call ]), nonce: 1n, callGasLimit: 150000n, validAfter: 0, validUntil: 0, maxFeePerGas: 100000n, maxPriorityFeePerGas: 200000n, verificationGasLimit: 150000n, preVerificationGas: 100000n }); }); it('should fill the initCode property when the Safe does not exist', async () => { const safe4337Pack = await (0, helpers_1.createSafe4337Pack)({ options: { owners: [fixtures.OWNER_1], threshold: 1 } }); const getInitCodeSpy = jest.spyOn(safe4337Pack.protocolKit, 'getInitCode'); const safeOperation = await safe4337Pack.createTransaction({ transactions: [transferUSDC] }); expect(getInitCodeSpy).toHaveBeenCalled(); expect(safeOperation.data.initCode).toBe('0x4e1DCf7AD4e460CfD30791CCC4F9c8a4f820ec671688f0b900000000000000000000000029fcb43b46531bca003ddc8fcb67ffe91900c7620000000000000000000000000000000000000000000000000000000000000060ad27de2a410652abce96ea0fdfc30c2f0fd35952b78f554667111999a28ff33800000000000000000000000000000000000000000000000000000000000001e4b63e800d000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000000010000000000000000000000008ecd4ec46d4d2a6b64fe960b3d64e8b94b2234eb0000000000000000000000000000000000000000000000000000000000000140000000000000000000000000a581c4a4db7175302464ff3c06380bc3270b40370000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001000000000000000000000000ffac5578be8ac1b2b9d13b34caf4a074b96b8a1b00000000000000000000000000000000000000000000000000000000000000648d0dc49f00000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000001000000000000000000000000a581c4a4db7175302464ff3c06380bc3270b40370000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000'); }); it('should allow to create a sponsored transaction', async () => { const safe4337Pack = await (0, helpers_1.createSafe4337Pack)({ options: { safeAddress: fixtures.SAFE_ADDRESS_v1_4_1 }, paymasterOptions: { isSponsored: true, paymasterUrl: fixtures.PAYMASTER_URL, paymasterAddress: fixtures.PAYMASTER_ADDRESS } }); const sponsoredSafeOperation = await safe4337Pack.createTransaction({ transactions: [transferUSDC] }); expect(sponsoredSafeOperation).toBeInstanceOf(SafeOperation_1.default); expect(sponsoredSafeOperation.data).toMatchObject({ safe: fixtures.SAFE_ADDRESS_v1_4_1, entryPoint: '0x5FF137D4b0FDCD49DcA30c7CF57E578a026d2789', initCode: '0x', paymasterAndData: '0x0000000000325602a77416A16136FDafd04b299f', callData: constants.INTERFACES.encodeFunctionData('executeUserOp', [ transferUSDC.to, transferUSDC.value, transferUSDC.data, safe_core_sdk_types_1.OperationType.Call ]), nonce: 1n, callGasLimit: 150000n, validAfter: 0, validUntil: 0, maxFeePerGas: 100000n, maxPriorityFeePerGas: 200000n, verificationGasLimit: 150000n, preVerificationGas: 100000n }); }); it('createTransaction should throw an error if paymasterUrl is not present in sponsored transactions', async () => { const safe4337Pack = await (0, helpers_1.createSafe4337Pack)({ options: { safeAddress: fixtures.SAFE_ADDRESS_v1_4_1 }, paymasterOptions: { isSponsored: true, paymasterAddress: fixtures.PAYMASTER_ADDRESS } }); await expect(safe4337Pack.createTransaction({ transactions: [transferUSDC] })).rejects.toThrow('No paymaster url provided for a sponsored transaction'); }); it('should add the approve transaction to the batch when amountToApprove is provided', async () => { const safe4337Pack = await (0, helpers_1.createSafe4337Pack)({ options: { safeAddress: fixtures.SAFE_ADDRESS_v1_4_1 }, paymasterOptions: { paymasterTokenAddress: fixtures.PAYMASTER_TOKEN_ADDRESS, paymasterAddress: fixtures.PAYMASTER_ADDRESS } }); const amountToApprove = 80000n; const sponsoredSafeOperation = await safe4337Pack.createTransaction({ transactions: [transferUSDC], options: { amountToApprove } }); const approveTransaction = { to: fixtures.PAYMASTER_TOKEN_ADDRESS, data: constants.INTERFACES.encodeFunctionData('approve', [ fixtures.PAYMASTER_ADDRESS, amountToApprove ]), value: '0', operation: safe_core_sdk_types_1.OperationType.Call // Call for approve }; const batch = [transferUSDC, approveTransaction]; expect(sponsoredSafeOperation).toBeInstanceOf(SafeOperation_1.default); expect(sponsoredSafeOperation.data).toMatchObject({ safe: fixtures.SAFE_ADDRESS_v1_4_1, entryPoint: '0x5FF137D4b0FDCD49DcA30c7CF57E578a026d2789', initCode: '0x', paymasterAndData: '0x0000000000325602a77416A16136FDafd04b299f', callData: constants.INTERFACES.encodeFunctionData('executeUserOp', [ await safe4337Pack.protocolKit.getMultiSendAddress(), '0', constants.INTERFACES.encodeFunctionData('multiSend', [ protocolKit.encodeMultiSendData(batch) ]), safe_core_sdk_types_1.OperationType.DelegateCall ]), nonce: 1n, callGasLimit: 150000n, validAfter: 0, validUntil: 0, maxFeePerGas: 100000n, maxPriorityFeePerGas: 200000n, verificationGasLimit: 150000n, preVerificationGas: 100000n }); }); }); it('should all to sign a SafeOperation', async () => { const transferUSDC = { to: fixtures.PAYMASTER_TOKEN_ADDRESS, data: (0, helpers_1.generateTransferCallData)(fixtures.SAFE_ADDRESS_v1_4_1, 100000n), value: '0', operation: 0 }; const safe4337Pack = await (0, helpers_1.createSafe4337Pack)({ options: { safeAddress: fixtures.SAFE_ADDRESS_v1_4_1 } }); const safeOperation = await safe4337Pack.createTransaction({ transactions: [transferUSDC] }); expect(await safe4337Pack.signSafeOperation(safeOperation)).toMatchObject({ signatures: new Map().set(fixtures.OWNER_1.toLowerCase(), new protocolKit.EthSafeSignature(fixtures.OWNER_1, '0x63de7fdf99bcf20a1981ae74c3960604139d8bf025da894abc11604b30f438e82ceb0d37e73bf16b0b8b896f8be82a49750433733c0414fe4a3b8182a3875e1f1c', false)) }); }); it('should allow to send an UserOperation to a bundler', async () => { const transferUSDC = { to: fixtures.PAYMASTER_TOKEN_ADDRESS, data: (0, helpers_1.generateTransferCallData)(fixtures.SAFE_ADDRESS_v1_4_1, 100000n), value: '0', operation: 0 }; const safe4337Pack = await (0, helpers_1.createSafe4337Pack)({ options: { safeAddress: fixtures.SAFE_ADDRESS_v1_4_1 } }); let safeOperation = await safe4337Pack.createTransaction({ transactions: [transferUSDC] }); safeOperation = await safe4337Pack.signSafeOperation(safeOperation); await safe4337Pack.executeTransaction({ executable: safeOperation }); expect(sendMock).toHaveBeenCalledWith(constants.RPC_4337_CALLS.SEND_USER_OPERATION, [ utils.userOperationToHexValues(safeOperation.toUserOperation()), fixtures.ENTRYPOINTS[0] ]); }); it('should return a UserOperation based on a userOpHash', async () => { const safe4337Pack = await (0, helpers_1.createSafe4337Pack)({ options: { safeAddress: fixtures.SAFE_ADDRESS_v1_4_1 } }); const { userOperation, entryPoint, transactionHash, blockHash, blockNumber } = await safe4337Pack.getUserOperationByHash('0xee8e07f229d0ebf11c84a3e40f87e1d1b4c7b18eaeaebf3babb4b479424823e6'); expect(userOperation).toMatchObject({ sender: '0x1405B3659a11a16459fc27Fa1925b60388C38Ce1', nonce: '0x1', initCode: '0x', callData: '0x7bb3742800000000000000000000000038869bf66a61cf6bdb996a6ae40d5853fd43b52600000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000080000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000001848d80ff0a00000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000132001c7d4b196cb0c7b01d743fbc6116a902379c723800000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000044a9059cbb000000000000000000000000d725e11588f040d86c4c49d8236e32a5868549f000000000000000000000000000000000000000000000000000000000000186a0001c7d4b196cb0c7b01d743fbc6116a902379c723800000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000044a9059cbb000000000000000000000000d725e11588f040d86c4c49d8236e32a5868549f000000000000000000000000000000000000000000000000000000000000186a0000000000000000000000000000000000000000000000000000000000000000000000000000000000000', callGasLimit: '0x1d7d0', verificationGasLimit: '0x14470', preVerificationGas: '0xbdb8', maxFeePerGas: '0x2d128cfa8c', maxPriorityFeePerGas: '0x52412100', paymasterAndData: '0x', signature: '0x000000000000000000000000a397ca32ee7fb5282256ee3465da0843485930b803d747516aac76e152f834051ac18fd2b3c0565590f9d65085538993c85c9bb189c940d15c15402c7c2885821b' }); expect(blockHash).toBe('0x65f8249337ffede2067a006a96da47d3d3445ca72492a6a82afa02899f05d2e5'); expect(blockNumber).toBe('0x5378b9'); expect(entryPoint).toBe('0x5FF137D4b0FDCD49DcA30c7CF57E578a026d2789'); expect(transactionHash).toBe('0xef262d20f68e4900aa6380b8ac0f66f9c00a7d988179fa177ad9c9758f0e380e'); }); it('should return a UserOperation receipt based on a userOpHash', async () => { const safe4337Pack = await (0, helpers_1.createSafe4337Pack)({ options: { safeAddress: fixtures.SAFE_ADDRESS_v1_4_1 } }); const userOperationReceipt = await safe4337Pack.getUserOperationReceipt('0xee8e07f229d0ebf11c84a3e40f87e1d1b4c7b18eaeaebf3babb4b479424823e6'); expect(userOperationReceipt?.userOpHash).toBe('0x3cb881d1969036174f38d636d22108d1d032145518b53104fc0b1e1296d2cc9c'); expect(userOperationReceipt?.sender).toBe('0x1405B3659a11a16459fc27Fa1925b60388C38Ce1'); expect(userOperationReceipt?.actualGasUsed).toBe('0x27067'); expect(userOperationReceipt?.actualGasCost).toBe('0x42f29418377167'); expect(userOperationReceipt?.success).toBe(true); expect(userOperationReceipt?.logs).toStrictEqual([]); expect(userOperationReceipt?.receipt).toMatchObject({ transactionHash: '0xef262d20f68e4900aa6380b8ac0f66f9c00a7d988179fa177ad9c9758f0e380e', transactionIndex: '0x63', blockHash: '0x65f8249337ffede2067a006a96da47d3d3445ca72492a6a82afa02899f05d2e5', blockNumber: '0x5378b9', from: '0x4337001Fff419768e088Ce247456c1B892888084', to: '0x5FF137D4b0FDCD49DcA30c7CF57E578a026d2789', cumulativeGasUsed: '0xc1a846', gasUsed: '0x25e6c', contractAddress: null, logs: [], logsBloom: '0x000000000000900000000000000000000000000000000000080000000002000000080000000000000402000100000000001000000000000080000200000100000000000000000000000000080000000000000000000000000000002000002000000000000a0000000000000000000800000000000000000000000010000200000000000060100000000000000040000000800000000000000008800000000000000000000000000000400000000000000200000000000000000002000000008000000002000100000001000000000000000000000020000000000000000020010040000000000020000010000008000200000000000000000000000000000000', status: '0x1', effectiveGasPrice: '0x1b67f3c201' }); }); it('should return an array of the entryPoint addresses supported by the client', async () => { const safe4337Pack = await (0, helpers_1.createSafe4337Pack)({ options: { safeAddress: fixtures.SAFE_ADDRESS_v1_4_1 } }); const supportedEntryPoints = await safe4337Pack.getSupportedEntryPoints(); expect(supportedEntryPoints).toContain('0x5FF137D4b0FDCD49DcA30c7CF57E578a026d2789'); }); }); //# sourceMappingURL=Safe4337Pack.test.js.map