@tunghm/relay-kit
Version:
511 lines • 30.3 kB
JavaScript
"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 __classPrivateFieldSet = (this && this.__classPrivateFieldSet) || function (receiver, state, value, kind, f) {
if (kind === "m") throw new TypeError("Private method is not writable");
if (kind === "a" && !f) throw new TypeError("Private accessor was defined without a setter");
if (typeof state === "function" ? receiver !== state || !f : !state.has(receiver)) throw new TypeError("Cannot write private member to an object whose class did not declare it");
return (kind === "a" ? f.call(receiver, value) : f ? f.value = value : state.set(receiver, value)), value;
};
var __classPrivateFieldGet = (this && this.__classPrivateFieldGet) || function (receiver, state, kind, f) {
if (kind === "a" && !f) throw new TypeError("Private accessor was defined without a getter");
if (typeof state === "function" ? receiver !== state || !f : !state.has(receiver)) throw new TypeError("Cannot read private member from an object whose class did not declare it");
return kind === "m" ? f : kind === "a" ? f.call(receiver) : f ? f.value : state.get(receiver);
};
var __importDefault = (this && this.__importDefault) || function (mod) {
return (mod && mod.__esModule) ? mod : { "default": mod };
};
var _Safe4337Pack_instances, _Safe4337Pack_BUNDLER_URL, _Safe4337Pack_ENTRYPOINT_ADDRESS, _Safe4337Pack_SAFE_4337_MODULE_ADDRESS, _Safe4337Pack_bundlerClient, _Safe4337Pack_publicClient, _Safe4337Pack_paymasterOptions, _Safe4337Pack_inheritOptions, _Safe4337Pack_getSafeUserOperationHash, _Safe4337Pack_sendUserOperation, _Safe4337Pack_signTypedData, _Safe4337Pack_getAccountNonce, _Safe4337Pack_encodeExecuteUserOpCallData, _Safe4337Pack_encodeMultiSendCallData;
Object.defineProperty(exports, "__esModule", { value: true });
exports.Safe4337Pack = void 0;
const ethers_1 = require("ethers");
const satisfies_1 = __importDefault(require("semver/functions/satisfies"));
const protocol_kit_1 = __importStar(require("@safe-global/protocol-kit"));
const RelayKitBasePack_1 = require("../../RelayKitBasePack");
const safe_core_sdk_types_1 = require("@safe-global/safe-core-sdk-types");
const safe_modules_deployments_1 = require("@safe-global/safe-modules-deployments");
// import { createPimlicoBundlerClient } from 'permissionless/clients/pimlico'
// import { http } from 'viem'
const SafeOperation_1 = __importDefault(require("./SafeOperation"));
const constants_1 = require("./constants");
const utils_1 = require("./utils");
const PimlicoFeeEstimator_1 = require("./estimators/PimlicoFeeEstimator");
const MAX_ERC20_AMOUNT_TO_APPROVE = 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffn;
/**
* Safe4337Pack class that extends RelayKitBasePack.
* This class provides an implementation of the ERC-4337 that enables Safe accounts to wrk with UserOperations.
* It allows to create, sign and execute transactions using the Safe 4337 Module.
*
* @class
* @link https://github.com/safe-global/safe-modules/blob/main/modules/4337/contracts/Safe4337Module.sol
* @link https://eips.ethereum.org/EIPS/eip-4337
*/
class Safe4337Pack extends RelayKitBasePack_1.RelayKitBasePack {
/**
* Creates an instance of the Safe4337Pack.
*
* @param {Safe4337Options} options - The initialization parameters.
*/
constructor({ protocolKit, bundlerClient, publicClient, bundlerUrl, paymasterOptions, entryPointAddress, safe4337ModuleAddress }, inheritOptions) {
super(protocolKit);
_Safe4337Pack_instances.add(this);
_Safe4337Pack_BUNDLER_URL.set(this, void 0);
_Safe4337Pack_ENTRYPOINT_ADDRESS.set(this, void 0);
_Safe4337Pack_SAFE_4337_MODULE_ADDRESS.set(this, '0x');
_Safe4337Pack_bundlerClient.set(this, void 0);
_Safe4337Pack_publicClient.set(this, void 0);
_Safe4337Pack_paymasterOptions.set(this, void 0);
_Safe4337Pack_inheritOptions.set(this, void 0);
__classPrivateFieldSet(this, _Safe4337Pack_BUNDLER_URL, bundlerUrl, "f");
__classPrivateFieldSet(this, _Safe4337Pack_bundlerClient, bundlerClient, "f");
__classPrivateFieldSet(this, _Safe4337Pack_publicClient, publicClient, "f");
__classPrivateFieldSet(this, _Safe4337Pack_paymasterOptions, paymasterOptions, "f");
__classPrivateFieldSet(this, _Safe4337Pack_inheritOptions, inheritOptions, "f");
__classPrivateFieldSet(this, _Safe4337Pack_ENTRYPOINT_ADDRESS, entryPointAddress, "f");
__classPrivateFieldSet(this, _Safe4337Pack_SAFE_4337_MODULE_ADDRESS, safe4337ModuleAddress, "f");
}
/**
* Initializes a Safe4337Pack class.
* This method creates the protocolKit instance based on the input parameters.
* When the Safe address is provided, it will use the existing Safe.
* When the Safe address is not provided, it will use the predictedSafe feature with the provided owners and threshold.
* It will use the correct contract addresses for the fallbackHandler and the module and will add the data to enable the 4337 module.
*
* @param {Safe4337InitOptions} initOptions - The initialization parameters.
* @return {Promise<Safe4337Pack>} The Promise object that will be resolved into an instance of Safe4337Pack.
*/
static async init(initOptions, inheritOptions) {
const { ethersAdapter, options, bundlerUrl, rpcUrl, customContracts, paymasterOptions } = initOptions;
let protocolKit;
const bundlerClient = (0, utils_1.getEip4337BundlerProvider)(bundlerUrl);
const publicClient = (0, utils_1.getEip1193Provider)(rpcUrl);
const chainId = await bundlerClient.send(constants_1.RPC_4337_CALLS.CHAIN_ID, []);
let addModulesLibAddress = customContracts?.addModulesLibAddress;
const network = parseInt(chainId, 16).toString();
if (!addModulesLibAddress) {
const addModulesDeployment = (0, safe_modules_deployments_1.getAddModulesLibDeployment)({
released: true,
version: initOptions.safeModulesVersion || constants_1.DEFAULT_SAFE_MODULES_VERSION,
network
});
addModulesLibAddress = addModulesDeployment?.networkAddresses[network];
}
let safe4337ModuleAddress = customContracts?.safe4337ModuleAddress;
if (!safe4337ModuleAddress) {
const safe4337ModuleDeployment = (0, safe_modules_deployments_1.getSafe4337ModuleDeployment)({
released: true,
version: initOptions.safeModulesVersion || constants_1.DEFAULT_SAFE_MODULES_VERSION,
network
});
safe4337ModuleAddress = safe4337ModuleDeployment?.networkAddresses[network];
}
if (!addModulesLibAddress || !safe4337ModuleAddress) {
throw new Error(`Safe4337Module and/or AddModulesLib not available for chain ${network} and modules version ${constants_1.DEFAULT_SAFE_MODULES_VERSION}`);
}
// Existing Safe
if ('safeAddress' in options) {
protocolKit = await protocol_kit_1.default.create({
ethAdapter: ethersAdapter,
safeAddress: options.safeAddress,
contractNetworks: inheritOptions?.contractNetworks
});
const safeVersion = inheritOptions?.version || (await protocolKit.getContractVersion());
const isSafeVersion4337Compatible = (0, satisfies_1.default)(safeVersion, '>=1.4.1');
if (!isSafeVersion4337Compatible) {
throw new Error(`Incompatibility detected: The current Safe Account version (${safeVersion}) is not supported. EIP-4337 requires the Safe to use at least v1.4.1.`);
}
const safeModules = (await protocolKit.getModules());
const is4337ModulePresent = safeModules.some((module) => module === safe4337ModuleAddress);
if (!is4337ModulePresent) {
throw new Error(`Incompatibility detected: The EIP-4337 module is not enabled in the provided Safe Account. Enable this module (address: ${safe4337ModuleAddress}) to add compatibility.`);
}
const safeFallbackhandler = await protocolKit.getFallbackHandler();
const is4337FallbackhandlerPresent = safeFallbackhandler === safe4337ModuleAddress;
if (!is4337FallbackhandlerPresent) {
throw new Error(`Incompatibility detected: The EIP-4337 fallbackhandler is not attached to the Safe Account. Attach this fallbackhandler (address: ${safe4337ModuleAddress}) to ensure compatibility.`);
}
}
else {
// New Safe will be created based on the provided configuration when bundling a new UserOperation
if (!options.owners || !options.threshold) {
throw new Error('Owners and threshold are required to deploy a new Safe');
}
let deploymentTo = addModulesLibAddress;
let deploymentData = constants_1.INTERFACES.encodeFunctionData('enableModules', [[safe4337ModuleAddress]]);
const { isSponsored, paymasterTokenAddress } = paymasterOptions || {};
const isApproveTransactionRequired = !!paymasterOptions && !isSponsored && !!paymasterTokenAddress;
if (isApproveTransactionRequired) {
const { paymasterAddress, amountToApprove = MAX_ERC20_AMOUNT_TO_APPROVE } = paymasterOptions;
const enable4337ModulesTransaction = {
to: addModulesLibAddress,
value: '0',
data: constants_1.INTERFACES.encodeFunctionData('enableModules', [[safe4337ModuleAddress]]),
operation: safe_core_sdk_types_1.OperationType.DelegateCall // DelegateCall required for enabling the 4337 module
};
const approveToPaymasterTransaction = {
to: paymasterTokenAddress,
data: constants_1.INTERFACES.encodeFunctionData('approve', [paymasterAddress, amountToApprove]),
value: '0',
operation: safe_core_sdk_types_1.OperationType.Call // Call for approve
};
const setupBatch = [enable4337ModulesTransaction, approveToPaymasterTransaction];
const batchData = constants_1.INTERFACES.encodeFunctionData('multiSend', [
(0, protocol_kit_1.encodeMultiSendData)(setupBatch)
]);
const multiSendContract = await (0, protocol_kit_1.getMultiSendContract)({
ethAdapter: ethersAdapter,
safeVersion: options.safeVersion || constants_1.DEFAULT_SAFE_VERSION
});
deploymentTo = await multiSendContract.getAddress();
deploymentData = batchData;
}
protocolKit = await protocol_kit_1.default.create({
ethAdapter: ethersAdapter,
contractNetworks: inheritOptions?.contractNetworks,
predictedSafe: {
safeDeploymentConfig: {
safeVersion: options.safeVersion || constants_1.DEFAULT_SAFE_VERSION,
saltNonce: options.saltNonce || undefined
},
safeAccountConfig: {
owners: options.owners,
threshold: options.threshold,
to: deploymentTo,
data: deploymentData,
fallbackHandler: safe4337ModuleAddress,
paymentToken: ethers_1.ethers.ZeroAddress,
payment: 0,
paymentReceiver: ethers_1.ethers.ZeroAddress
}
}
});
}
let supportedEntryPoints;
if (!customContracts?.entryPointAddress) {
supportedEntryPoints = await bundlerClient.send(constants_1.RPC_4337_CALLS.SUPPORTED_ENTRY_POINTS, []);
if (!supportedEntryPoints.length) {
throw new Error('No entrypoint provided or available through the bundler');
}
}
return new Safe4337Pack({
protocolKit,
bundlerClient,
publicClient,
paymasterOptions,
bundlerUrl,
entryPointAddress: customContracts?.entryPointAddress || supportedEntryPoints[0],
safe4337ModuleAddress
}, inheritOptions);
}
async getFeeData() {
const maxGasPriceResult = await __classPrivateFieldGet(this, _Safe4337Pack_bundlerClient, "f").send(constants_1.RPC_4337_CALLS.ESTIMATE_GAS_PRICE, []);
return maxGasPriceResult;
}
/**
* Estimates gas for the SafeOperation.
*
* @param {EstimateFeeProps} props - The parameters for the gas estimation.
* @param {SafeOperation} props.safeOperation - The SafeOperation to estimate the gas.
* @param {IFeeEstimator} props.feeEstimator - The function to estimate the gas.
* @return {Promise<SafeOperation>} The Promise object that will be resolved into the gas estimation.
*/
async getEstimateFee({ safeOperation, feeEstimator = new PimlicoFeeEstimator_1.PimlicoFeeEstimator() }) {
const userOperation = safeOperation.toUserOperation();
const setupEstimationData = await feeEstimator?.setupEstimation?.({
bundlerUrl: __classPrivateFieldGet(this, _Safe4337Pack_BUNDLER_URL, "f"),
entryPoint: __classPrivateFieldGet(this, _Safe4337Pack_ENTRYPOINT_ADDRESS, "f"),
userOperation: safeOperation.toUserOperation()
});
if (setupEstimationData) {
safeOperation.addEstimations(setupEstimationData);
}
const estimateUserOperationGas = await __classPrivateFieldGet(this, _Safe4337Pack_bundlerClient, "f").send(constants_1.RPC_4337_CALLS.ESTIMATE_USER_OPERATION_GAS, [(0, utils_1.userOperationToHexValues)(userOperation), __classPrivateFieldGet(this, _Safe4337Pack_ENTRYPOINT_ADDRESS, "f")]);
if (estimateUserOperationGas) {
safeOperation.addEstimations({
preVerificationGas: BigInt(estimateUserOperationGas.preVerificationGas),
verificationGasLimit: BigInt(estimateUserOperationGas.verificationGasLimit),
callGasLimit: BigInt(estimateUserOperationGas.callGasLimit)
});
}
const adjustEstimationData = await feeEstimator?.adjustEstimation?.({
bundlerUrl: __classPrivateFieldGet(this, _Safe4337Pack_BUNDLER_URL, "f"),
entryPoint: __classPrivateFieldGet(this, _Safe4337Pack_ENTRYPOINT_ADDRESS, "f"),
userOperation: safeOperation.toUserOperation()
});
if (adjustEstimationData) {
safeOperation.addEstimations(adjustEstimationData);
}
if (__classPrivateFieldGet(this, _Safe4337Pack_paymasterOptions, "f")?.isSponsored) {
if (!__classPrivateFieldGet(this, _Safe4337Pack_paymasterOptions, "f").paymasterUrl) {
throw new Error('No paymaster url provided for a sponsored transaction');
}
const paymasterEstimation = await feeEstimator?.getPaymasterEstimation?.({
userOperation: safeOperation.toUserOperation(),
paymasterUrl: __classPrivateFieldGet(this, _Safe4337Pack_paymasterOptions, "f").paymasterUrl,
entryPoint: __classPrivateFieldGet(this, _Safe4337Pack_ENTRYPOINT_ADDRESS, "f"),
sponsorshipPolicyId: __classPrivateFieldGet(this, _Safe4337Pack_paymasterOptions, "f").sponsorshipPolicyId
});
safeOperation.data.paymasterAndData =
paymasterEstimation?.paymasterAndData || safeOperation.data.paymasterAndData;
if (paymasterEstimation) {
safeOperation.addEstimations(paymasterEstimation);
}
}
return safeOperation;
}
/**
* Creates a relayed transaction based on the provided parameters.
*
* @param {MetaTransactionData[]} transactions - The transactions to batch in a SafeOperation.
* @param options - Optional configuration options for the transaction creation.
* @return {Promise<SafeOperation>} The Promise object will resolve a SafeOperation.
*/
async createTransaction({ transactions, options = {} }) {
const safeAddress = __classPrivateFieldGet(this, _Safe4337Pack_inheritOptions, "f")?.inheritWallet || (await this.protocolKit.getAddress());
const nonce = await __classPrivateFieldGet(this, _Safe4337Pack_instances, "m", _Safe4337Pack_getAccountNonce).call(this, safeAddress);
const { amountToApprove, validUntil, validAfter, feeEstimator } = options;
if (amountToApprove) {
if (!__classPrivateFieldGet(this, _Safe4337Pack_paymasterOptions, "f") || !__classPrivateFieldGet(this, _Safe4337Pack_paymasterOptions, "f").paymasterTokenAddress) {
throw new Error('Paymaster must be initialized');
}
const paymasterAddress = __classPrivateFieldGet(this, _Safe4337Pack_paymasterOptions, "f").paymasterAddress;
const paymasterTokenAddress = __classPrivateFieldGet(this, _Safe4337Pack_paymasterOptions, "f").paymasterTokenAddress;
const approveToPaymasterTransaction = {
to: paymasterTokenAddress,
data: constants_1.INTERFACES.encodeFunctionData('approve', [paymasterAddress, amountToApprove]),
value: '0',
operation: safe_core_sdk_types_1.OperationType.Call // Call for approve
};
transactions.push(approveToPaymasterTransaction);
}
const isBatch = transactions.length > 1;
const multiSendAddress = await this.protocolKit.getMultiSendAddress();
const callData = isBatch
? __classPrivateFieldGet(this, _Safe4337Pack_instances, "m", _Safe4337Pack_encodeExecuteUserOpCallData).call(this, {
to: multiSendAddress,
value: '0',
data: __classPrivateFieldGet(this, _Safe4337Pack_instances, "m", _Safe4337Pack_encodeMultiSendCallData).call(this, transactions),
operation: safe_core_sdk_types_1.OperationType.DelegateCall
})
: __classPrivateFieldGet(this, _Safe4337Pack_instances, "m", _Safe4337Pack_encodeExecuteUserOpCallData).call(this, transactions[0]);
const paymasterAndData = __classPrivateFieldGet(this, _Safe4337Pack_paymasterOptions, "f")?.paymasterAddress || '0x';
const userOperation = {
sender: safeAddress,
nonce: nonce,
initCode: '0x',
callData,
callGasLimit: 1n,
verificationGasLimit: 1n,
preVerificationGas: 1n,
maxFeePerGas: 1n,
maxPriorityFeePerGas: 1n,
paymasterAndData,
signature: '0x'
};
const isSafeDeployed = await this.protocolKit.getEthAdapter().isContractDeployed(safeAddress);
// const isSafeDeployed = await this.protocolKit.isSafeDeployed()
if (!isSafeDeployed) {
userOperation.initCode =
__classPrivateFieldGet(this, _Safe4337Pack_inheritOptions, "f")?.initCode || (await this.protocolKit.getInitCode());
}
const safeOperation = new SafeOperation_1.default(userOperation, {
entryPoint: __classPrivateFieldGet(this, _Safe4337Pack_ENTRYPOINT_ADDRESS, "f"),
validUntil,
validAfter
});
return await this.getEstimateFee({
safeOperation,
feeEstimator
});
}
/**
* Signs a safe operation.
*
* @param {SafeOperation} safeOperation - The SafeOperation to sign.
* @param {SigningMethod} signingMethod - The signing method to use.
* @return {Promise<SafeOperation>} The Promise object will resolve to the signed SafeOperation.
*/
async signSafeOperation(safeOperation, signingMethod = protocol_kit_1.SigningMethod.ETH_SIGN_TYPED_DATA_V4) {
const owners = __classPrivateFieldGet(this, _Safe4337Pack_inheritOptions, "f")?.owners || (await this.protocolKit.getOwners());
const signerAddress = await this.protocolKit.getEthAdapter().getSignerAddress();
if (!signerAddress) {
throw new Error('EthAdapter must be initialized with a signer to use this method');
}
const addressIsOwner = owners.some((owner) => signerAddress && owner.toLowerCase() === signerAddress.toLowerCase());
if (!addressIsOwner) {
throw new Error('UserOperations can only be signed by Safe owners');
}
let signature;
if (signingMethod === protocol_kit_1.SigningMethod.ETH_SIGN_TYPED_DATA_V4 ||
signingMethod === protocol_kit_1.SigningMethod.ETH_SIGN_TYPED_DATA_V3 ||
signingMethod === protocol_kit_1.SigningMethod.ETH_SIGN_TYPED_DATA) {
signature = await __classPrivateFieldGet(this, _Safe4337Pack_instances, "m", _Safe4337Pack_signTypedData).call(this, safeOperation.data);
}
else {
const chainId = await this.protocolKit.getEthAdapter().getChainId();
const safeOpHash = __classPrivateFieldGet(this, _Safe4337Pack_instances, "m", _Safe4337Pack_getSafeUserOperationHash).call(this, safeOperation.data, chainId);
signature = await this.protocolKit.signHash(safeOpHash);
}
const signedSafeOperation = new SafeOperation_1.default(safeOperation.toUserOperation(), {
entryPoint: __classPrivateFieldGet(this, _Safe4337Pack_ENTRYPOINT_ADDRESS, "f"),
validUntil: safeOperation.data.validUntil,
validAfter: safeOperation.data.validAfter
});
signedSafeOperation.signatures.forEach((signature) => {
signedSafeOperation.addSignature(signature);
});
signedSafeOperation.addSignature(signature);
return signedSafeOperation;
}
/**
* Executes the relay transaction.
*
* @param {SafeOperation} safeOperation - The SafeOperation to execute.
* @return {Promise<string>} The user operation hash.
*/
async executeTransaction({ executable: safeOperation }) {
const userOperation = safeOperation.toUserOperation();
return __classPrivateFieldGet(this, _Safe4337Pack_instances, "m", _Safe4337Pack_sendUserOperation).call(this, userOperation);
}
/**
* Return a UserOperation based on a hash (userOpHash) returned by eth_sendUserOperation
*
* @param {string} userOpHash - The hash of the user operation to fetch. Returned from the #sendUserOperation method
* @returns {UserOperation} - null in case the UserOperation is not yet included in a block, or a full UserOperation, with the addition of entryPoint, blockNumber, blockHash and transactionHash
*/
async getUserOperationByHash(userOpHash) {
const userOperation = await __classPrivateFieldGet(this, _Safe4337Pack_bundlerClient, "f").send(constants_1.RPC_4337_CALLS.GET_USER_OPERATION_BY_HASH, [userOpHash]);
return userOperation;
}
/**
* Return a UserOperation receipt based on a hash (userOpHash) returned by eth_sendUserOperation
*
* @param {string} userOpHash - The hash of the user operation to fetch. Returned from the #sendUserOperation method
* @returns {UserOperationReceipt} - null in case the UserOperation is not yet included in a block, or UserOperationReceipt object
*/
async getUserOperationReceipt(userOpHash) {
const userOperationReceipt = await __classPrivateFieldGet(this, _Safe4337Pack_bundlerClient, "f").send(constants_1.RPC_4337_CALLS.GET_USER_OPERATION_RECEIPT, [userOpHash]);
return userOperationReceipt;
}
/**
* Returns an array of the entryPoint addresses supported by the client.
* The first element of the array SHOULD be the entryPoint addressed preferred by the client.
*
* @returns {string[]} - The supported entry points.
*/
async getSupportedEntryPoints() {
const supportedEntryPoints = await __classPrivateFieldGet(this, _Safe4337Pack_bundlerClient, "f").send(constants_1.RPC_4337_CALLS.SUPPORTED_ENTRY_POINTS, []);
return supportedEntryPoints;
}
/**
* Returns EIP-155 Chain ID.
*
* @returns {string} - The chain id.
*/
async getChainId() {
const chainId = await __classPrivateFieldGet(this, _Safe4337Pack_bundlerClient, "f").send(constants_1.RPC_4337_CALLS.CHAIN_ID, []);
return chainId;
}
}
exports.Safe4337Pack = Safe4337Pack;
_Safe4337Pack_BUNDLER_URL = new WeakMap(), _Safe4337Pack_ENTRYPOINT_ADDRESS = new WeakMap(), _Safe4337Pack_SAFE_4337_MODULE_ADDRESS = new WeakMap(), _Safe4337Pack_bundlerClient = new WeakMap(), _Safe4337Pack_publicClient = new WeakMap(), _Safe4337Pack_paymasterOptions = new WeakMap(), _Safe4337Pack_inheritOptions = new WeakMap(), _Safe4337Pack_instances = new WeakSet(), _Safe4337Pack_getSafeUserOperationHash = function _Safe4337Pack_getSafeUserOperationHash(safeUserOperation, chainId) {
return ethers_1.ethers.TypedDataEncoder.hash({
chainId,
verifyingContract: __classPrivateFieldGet(this, _Safe4337Pack_SAFE_4337_MODULE_ADDRESS, "f")
}, constants_1.EIP712_SAFE_OPERATION_TYPE, safeUserOperation);
}, _Safe4337Pack_sendUserOperation =
/**
* Send the UserOperation to the bundler.
*
* @param {UserOperation} userOpWithSignature - The signed UserOperation to send to the bundler.
* @return {Promise<string>} The hash.
*/
async function _Safe4337Pack_sendUserOperation(userOpWithSignature) {
return await __classPrivateFieldGet(this, _Safe4337Pack_bundlerClient, "f").send(constants_1.RPC_4337_CALLS.SEND_USER_OPERATION, [
(0, utils_1.userOperationToHexValues)(userOpWithSignature),
__classPrivateFieldGet(this, _Safe4337Pack_ENTRYPOINT_ADDRESS, "f")
]);
}, _Safe4337Pack_signTypedData =
/**
* Signs typed data.
* This is currently only EthersAdapter compatible (Reflected in the init() props). If I want to make it compatible with any EthAdapter I need to either:
* - Add a SafeOp type to the protocol-kit (createSafeOperation, signSafeOperation, etc)
* - Allow to pass the data types (SafeOp, SafeMessage, SafeTx) to the signTypedData method and refactor the protocol-kit to allow any kind of data signing from outside (Currently only SafeTx and SafeMessage)
*
* @param {SafeUserOperation} safeUserOperation - Safe user operation to sign.
* @return {Promise<SafeSignature>} The SafeSignature object containing the data and the signatures.
*/
async function _Safe4337Pack_signTypedData(safeUserOperation) {
const ethAdapter = this.protocolKit.getEthAdapter();
const signer = ethAdapter.getSigner();
const chainId = await ethAdapter.getChainId();
const signerAddress = await signer.getAddress();
const signature = await signer.signTypedData({
chainId,
verifyingContract: __classPrivateFieldGet(this, _Safe4337Pack_SAFE_4337_MODULE_ADDRESS, "f")
}, constants_1.EIP712_SAFE_OPERATION_TYPE, {
...safeUserOperation,
nonce: ethers_1.ethers.toBeHex(safeUserOperation.nonce),
validAfter: ethers_1.ethers.toBeHex(safeUserOperation.validAfter),
validUntil: ethers_1.ethers.toBeHex(safeUserOperation.validUntil),
maxFeePerGas: ethers_1.ethers.toBeHex(safeUserOperation.maxFeePerGas),
maxPriorityFeePerGas: ethers_1.ethers.toBeHex(safeUserOperation.maxPriorityFeePerGas)
});
return new protocol_kit_1.EthSafeSignature(signerAddress, signature);
}, _Safe4337Pack_getAccountNonce =
/**
* Gets account nonce from the bundler.
*
* @param {string} sender - Account address for which the nonce is to be fetched.
* @returns {Promise<string>} The Promise object will resolve to the account nonce.
*/
async function _Safe4337Pack_getAccountNonce(sender) {
const abi = [
{
inputs: [
{ name: 'sender', type: 'address' },
{ name: 'key', type: 'uint192' }
],
name: 'getNonce',
outputs: [{ name: 'nonce', type: 'uint256' }],
stateMutability: 'view',
type: 'function'
}
];
const contract = new ethers_1.ethers.Contract(__classPrivateFieldGet(this, _Safe4337Pack_ENTRYPOINT_ADDRESS, "f") || '0x', abi, __classPrivateFieldGet(this, _Safe4337Pack_publicClient, "f"));
const newNonce = await contract.getNonce(sender, BigInt(0));
return newNonce.toString();
}, _Safe4337Pack_encodeExecuteUserOpCallData = function _Safe4337Pack_encodeExecuteUserOpCallData(transaction) {
return constants_1.INTERFACES.encodeFunctionData('executeUserOp', [
transaction.to,
transaction.value,
transaction.data,
transaction.operation || safe_core_sdk_types_1.OperationType.Call
]);
}, _Safe4337Pack_encodeMultiSendCallData = function _Safe4337Pack_encodeMultiSendCallData(transactions) {
return constants_1.INTERFACES.encodeFunctionData('multiSend', [
(0, protocol_kit_1.encodeMultiSendData)(transactions.map((tx) => ({ ...tx, operation: tx.operation ?? safe_core_sdk_types_1.OperationType.Call })))
]);
};
//# sourceMappingURL=Safe4337Pack.js.map