UNPKG

@biconomy-devx/modules

Version:

This package provides different validation modules/plugins for ERC4337 compatible modular account

227 lines 10.5 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.SessionKeyManagerModule = void 0; const viem_1 = require("viem"); const merkletreejs_1 = require("merkletreejs"); const Types_js_1 = require("./utils/Types.js"); const Constants_js_1 = require("./utils/Constants.js"); const Uid_js_1 = require("./utils/Uid.js"); const BaseValidationModule_js_1 = require("./BaseValidationModule.js"); const SessionLocalStorage_js_1 = require("./session-storage/SessionLocalStorage.js"); const common_1 = require("@biconomy-devx/common"); class SessionKeyManagerModule extends BaseValidationModule_js_1.BaseValidationModule { constructor(moduleConfig) { super(moduleConfig); Object.defineProperty(this, "version", { enumerable: true, configurable: true, writable: true, value: "V1_0_0" }); Object.defineProperty(this, "moduleAddress", { enumerable: true, configurable: true, writable: true, value: void 0 }); Object.defineProperty(this, "merkleTree", { enumerable: true, configurable: true, writable: true, value: void 0 }); Object.defineProperty(this, "sessionStorageClient", { enumerable: true, configurable: true, writable: true, value: void 0 }); Object.defineProperty(this, "mockEcdsaSessionKeySig", { enumerable: true, configurable: true, writable: true, value: "0x73c3ac716c487ca34bb858247b5ccf1dc354fbaabdd089af3b2ac8e78ba85a4959a2d76250325bd67c11771c31fccda87c33ceec17cc0de912690521bb95ffcb1b" }); Object.defineProperty(this, "createSessionData", { enumerable: true, configurable: true, writable: true, value: async (leavesData) => { const sessionKeyManagerModuleABI = (0, viem_1.parseAbi)(["function setMerkleRoot(bytes32 _merkleRoot)"]); const leavesToAdd = []; const sessionIDInfo = []; for (const leafData of leavesData) { const leafDataHex = (0, viem_1.concat)([ (0, viem_1.pad)((0, viem_1.toHex)(leafData.validUntil), { size: 6 }), (0, viem_1.pad)((0, viem_1.toHex)(leafData.validAfter), { size: 6 }), (0, viem_1.pad)(leafData.sessionValidationModule, { size: 20 }), leafData.sessionKeyData, ]); const generatedSessionId = leafData.preferredSessionId ?? (0, Uid_js_1.generateRandomHex)(); leavesToAdd.push((0, viem_1.keccak256)(leafDataHex)); sessionIDInfo.push(generatedSessionId); const sessionLeafNode = { ...leafData, sessionID: generatedSessionId, status: "PENDING", }; await this.sessionStorageClient.addSessionData(sessionLeafNode); } this.merkleTree.addLeaves(leavesToAdd); const leaves = this.merkleTree.getLeaves(); const newMerkleTree = new merkletreejs_1.MerkleTree(leaves, viem_1.keccak256, { sortPairs: true, hashLeaves: false, }); this.merkleTree = newMerkleTree; const setMerkleRootData = (0, viem_1.encodeFunctionData)({ abi: sessionKeyManagerModuleABI, functionName: "setMerkleRoot", args: [this.merkleTree.getHexRoot()], }); await this.sessionStorageClient.setMerkleRoot(this.merkleTree.getHexRoot()); return { data: setMerkleRootData, sessionIDInfo: sessionIDInfo, }; } }); } static async create(moduleConfig) { const instance = new SessionKeyManagerModule(moduleConfig); if (moduleConfig.moduleAddress) { instance.moduleAddress = moduleConfig.moduleAddress; } else if (moduleConfig.version) { const moduleAddr = Constants_js_1.SESSION_MANAGER_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_SESSION_KEY_MANAGER_MODULE; } if (moduleConfig.sessionStorageClient) { instance.sessionStorageClient = moduleConfig.sessionStorageClient; } else { switch (moduleConfig.storageType) { case Types_js_1.StorageType.LOCAL_STORAGE: instance.sessionStorageClient = new SessionLocalStorage_js_1.SessionLocalStorage(moduleConfig.smartAccountAddress); break; default: instance.sessionStorageClient = new SessionLocalStorage_js_1.SessionLocalStorage(moduleConfig.smartAccountAddress); } } const existingSessionData = await instance.sessionStorageClient.getAllSessionData(); const existingSessionDataLeafs = existingSessionData.map((sessionData) => { const leafDataHex = (0, viem_1.concat)([ (0, viem_1.pad)((0, viem_1.toHex)(sessionData.validUntil), { size: 6 }), (0, viem_1.pad)((0, viem_1.toHex)(sessionData.validAfter), { size: 6 }), (0, viem_1.pad)(sessionData.sessionValidationModule, { size: 20 }), sessionData.sessionKeyData, ]); return (0, viem_1.keccak256)(leafDataHex); }); instance.merkleTree = new merkletreejs_1.MerkleTree(existingSessionDataLeafs, viem_1.keccak256, { sortPairs: true, hashLeaves: false, }); return instance; } async signUserOpHash(userOpHash, params) { if (!(params && params.sessionSigner)) { throw new Error("Session signer is not provided."); } const { signer: sessionSigner } = await (0, common_1.convertSigner)(params.sessionSigner); const signature = await sessionSigner.signMessage({ raw: (0, viem_1.toBytes)(userOpHash) }); const sessionSignerData = await this.getLeafInfo(params); const leafDataHex = (0, viem_1.concat)([ (0, viem_1.pad)((0, viem_1.toHex)(sessionSignerData.validUntil), { size: 6 }), (0, viem_1.pad)((0, viem_1.toHex)(sessionSignerData.validAfter), { size: 6 }), (0, viem_1.pad)(sessionSignerData.sessionValidationModule, { size: 20 }), sessionSignerData.sessionKeyData, ]); let paddedSignature = (0, viem_1.encodeAbiParameters)((0, viem_1.parseAbiParameters)("uint48, uint48, address, bytes, bytes32[], bytes"), [ sessionSignerData.validUntil, sessionSignerData.validAfter, sessionSignerData.sessionValidationModule, sessionSignerData.sessionKeyData, this.merkleTree.getHexProof((0, viem_1.keccak256)(leafDataHex)), signature, ]); if (params?.additionalSessionData) { paddedSignature += params.additionalSessionData; } return paddedSignature; } async getLeafInfo(params) { if (!(params && params.sessionSigner)) { throw new Error("Session signer is not provided."); } const { signer: sessionSigner } = await (0, common_1.convertSigner)(params.sessionSigner); let sessionSignerData; if (params?.sessionID) { sessionSignerData = await this.sessionStorageClient.getSessionData({ sessionID: params.sessionID, }); } else if (params?.sessionValidationModule) { sessionSignerData = await this.sessionStorageClient.getSessionData({ sessionValidationModule: params.sessionValidationModule, sessionPublicKey: await sessionSigner.getAddress(), }); } else { throw new Error("sessionID or sessionValidationModule should be provided."); } return sessionSignerData; } async updateSessionStatus(param, status) { this.sessionStorageClient.updateSessionStatus(param, status); } async clearPendingSessions() { this.sessionStorageClient.clearPendingSessions(); } getAddress() { return this.moduleAddress; } async getSigner() { throw new Error("Method not implemented."); } async getDummySignature(params) { if (!params) { throw new Error("Session signer is not provided."); } const sessionSignerData = await this.getLeafInfo(params); const leafDataHex = (0, viem_1.concat)([ (0, viem_1.pad)((0, viem_1.toHex)(sessionSignerData.validUntil), { size: 6 }), (0, viem_1.pad)((0, viem_1.toHex)(sessionSignerData.validAfter), { size: 6 }), (0, viem_1.pad)(sessionSignerData.sessionValidationModule, { size: 20 }), sessionSignerData.sessionKeyData, ]); let paddedSignature = (0, viem_1.encodeAbiParameters)((0, viem_1.parseAbiParameters)("uint48, uint48, address, bytes, bytes32[], bytes"), [ sessionSignerData.validUntil, sessionSignerData.validAfter, sessionSignerData.sessionValidationModule, sessionSignerData.sessionKeyData, this.merkleTree.getHexProof((0, viem_1.keccak256)(leafDataHex)), this.mockEcdsaSessionKeySig, ]); if (params?.additionalSessionData) { paddedSignature += params.additionalSessionData; } const dummySig = (0, viem_1.encodeAbiParameters)((0, viem_1.parseAbiParameters)(["bytes, address"]), [paddedSignature, this.getAddress()]); return dummySig; } async getInitData() { throw new Error("Method not implemented."); } async signMessage(_message) { throw new Error("Method not implemented."); } } exports.SessionKeyManagerModule = SessionKeyManagerModule; //# sourceMappingURL=SessionKeyManagerModule.js.map