@biconomy-devx/modules
Version:
This package provides different validation modules/plugins for ERC4337 compatible modular account
136 lines • 6.58 kB
JavaScript
;
Object.defineProperty(exports, "__esModule", { value: true });
exports.MultiChainValidationModule = void 0;
const viem_1 = require("viem");
const merkletreejs_1 = require("merkletreejs");
const Constants_js_1 = require("./utils/Constants.js");
const BaseValidationModule_js_1 = require("./BaseValidationModule.js");
const Helper_js_1 = require("./utils/Helper.js");
const common_1 = require("@biconomy-devx/common");
class MultiChainValidationModule extends BaseValidationModule_js_1.BaseValidationModule {
constructor(moduleConfig) {
super(moduleConfig);
Object.defineProperty(this, "signer", {
enumerable: true,
configurable: true,
writable: true,
value: void 0
});
Object.defineProperty(this, "moduleAddress", {
enumerable: true,
configurable: true,
writable: true,
value: void 0
});
Object.defineProperty(this, "version", {
enumerable: true,
configurable: true,
writable: true,
value: "V1_0_0"
});
this.signer = moduleConfig.signer;
}
static async create(moduleConfig) {
const { signer } = await (0, common_1.convertSigner)(moduleConfig.signer, true);
const configForConstructor = { ...moduleConfig, signer };
const instance = new MultiChainValidationModule(configForConstructor);
if (moduleConfig.moduleAddress) {
instance.moduleAddress = moduleConfig.moduleAddress;
}
else if (moduleConfig.version) {
const moduleAddr = Constants_js_1.MULTICHAIN_VALIDATION_MODULE_ADDRESSES_BY_VERSION[moduleConfig.version];
if (!moduleAddr) {
throw new Error(`Invalid version ${moduleConfig.version}`);
}
instance.moduleAddress = moduleAddr;
instance.version = moduleConfig.version;
}
else {
instance.moduleAddress = Constants_js_1.DEFAULT_MULTICHAIN_MODULE;
}
return instance;
}
getAddress() {
return this.moduleAddress;
}
async getSigner() {
return Promise.resolve(this.signer);
}
async getDummySignature() {
const moduleAddress = (0, viem_1.getAddress)(this.getAddress());
const dynamicPart = moduleAddress.substring(2).padEnd(40, "0");
return `0x0000000000000000000000000000000000000000000000000000000000000040000000000000000000000000${dynamicPart}000000000000000000000000000000000000000000000000000000000000004181d4b4981670cb18f99f0b4a66446df1bf5b204d24cfcb659bf38ba27a4359b5711649ec2423c5e1247245eba2964679b6a1dbb85c992ae40b9b00c6935b02ff1b00000000000000000000000000000000000000000000000000000000000000`;
}
async getInitData() {
const ecdsaOwnerAddress = await this.signer.getAddress();
const moduleRegistryParsedAbi = (0, viem_1.parseAbi)(["function initForSmartAccount(address owner)"]);
const ecdsaOwnershipInitData = (0, viem_1.encodeFunctionData)({
abi: moduleRegistryParsedAbi,
functionName: "initForSmartAccount",
args: [ecdsaOwnerAddress],
});
return ecdsaOwnershipInitData;
}
async signUserOpHash(userOpHash) {
const sig = await this.signer.signMessage({ raw: (0, viem_1.toBytes)(userOpHash) });
return sig;
}
async signMessage(_message) {
const message = typeof _message === "string" ? _message : { raw: _message };
let signature = await this.signer.signMessage(message);
const potentiallyIncorrectV = parseInt(signature.slice(-2), 16);
if (![27, 28].includes(potentiallyIncorrectV)) {
const correctV = potentiallyIncorrectV + 27;
signature = signature.slice(0, -2) + correctV.toString(16);
}
return signature;
}
async signUserOps(multiChainUserOps) {
try {
const leaves = [];
for (const multiChainOp of multiChainUserOps) {
const validUntil = multiChainOp.validUntil ?? 0;
const validAfter = multiChainOp.validAfter ?? 0;
const leaf = (0, viem_1.concat)([
(0, viem_1.pad)((0, viem_1.toHex)(validUntil), { size: 6 }),
(0, viem_1.pad)((0, viem_1.toHex)(validAfter), { size: 6 }),
(0, viem_1.pad)((0, Helper_js_1.getUserOpHash)(multiChainOp.userOp, this.entryPointAddress, multiChainOp.chainId), { size: 32 }),
]);
leaves.push((0, viem_1.keccak256)(leaf));
}
const merkleTree = new merkletreejs_1.MerkleTree(leaves, viem_1.keccak256, { sortPairs: true });
let multichainSignature = await this.signer.signMessage({ raw: (0, viem_1.toBytes)(merkleTree.getHexRoot()) });
const potentiallyIncorrectV = parseInt(multichainSignature.slice(-2), 16);
if (![27, 28].includes(potentiallyIncorrectV)) {
const correctV = potentiallyIncorrectV + 27;
multichainSignature = multichainSignature.slice(0, -2) + correctV.toString(16);
}
const updatedUserOps = [];
for (let i = 0; i < leaves.length; i++) {
const merkleProof = merkleTree.getHexProof(leaves[i]);
const validUntil = multiChainUserOps[i].validUntil ?? 0;
const validAfter = multiChainUserOps[i].validAfter ?? 0;
const moduleSignature = (0, viem_1.encodeAbiParameters)((0, viem_1.parseAbiParameters)(["uint48, uint48, bytes32, bytes32[], bytes"]), [
validUntil,
validAfter,
merkleTree.getHexRoot(),
merkleProof,
multichainSignature,
]);
const signatureWithModuleAddress = (0, viem_1.encodeAbiParameters)((0, viem_1.parseAbiParameters)(["bytes, address"]), [moduleSignature, this.getAddress()]);
const updatedUserOp = {
...multiChainUserOps[i].userOp,
signature: signatureWithModuleAddress,
};
updatedUserOps.push(updatedUserOp);
}
return updatedUserOps;
}
catch (error) {
common_1.Logger.error("Error in signing multi chain userops");
throw new Error(JSON.stringify(error));
}
}
}
exports.MultiChainValidationModule = MultiChainValidationModule;
//# sourceMappingURL=MultichainValidationModule.js.map