UNPKG

@biconomy/abstractjs

Version:

SDK for Biconomy integration with support for account abstraction, smart accounts, ERC-4337.

105 lines 3.92 kB
import { encodePacked, keccak256 } from "viem"; // Storage contract export const NAMESPACE_STORAGE_CONTRACT_ADDRESS = "0x0000000671eb337E12fe5dB0e788F32e1D71B183"; export const NAMESPACE_STORAGE_ABI = [ { inputs: [ { internalType: "bytes32", name: "slot", type: "bytes32" }, { internalType: "bytes32", name: "value", type: "bytes32" }, { internalType: "address", name: "account", type: "address" } ], name: "writeStorage", outputs: [], stateMutability: "nonpayable", type: "function" }, { inputs: [ { internalType: "bytes32", name: "namespace", type: "bytes32" }, { internalType: "bytes32", name: "slot", type: "bytes32" } ], name: "readStorage", outputs: [ { internalType: "bytes32", name: "", type: "bytes32" } ], stateMutability: "view", type: "function" } ]; class NamespaceStorageManager { constructor() { Object.defineProperty(this, "isNameSpaceStorageSlotKeyBeingCalculated", { enumerable: true, configurable: true, writable: true, value: new Map() }); } static getInstance() { if (!NamespaceStorageManager.instance) { NamespaceStorageManager.instance = new NamespaceStorageManager(); } return NamespaceStorageManager.instance; } buildNameSpaceStorageKey(accountAddress, callerAddress, chainId) { return `${accountAddress.toLowerCase()}::${callerAddress.toLowerCase()}::${chainId}`; } // This function always make sure to provide a unique storage slot. // This is helpful to reduce storage slot collusion async getDefaultStorageSlotKey(accountAddress, callerAddress, chainId) { const storeKey = this.buildNameSpaceStorageKey(accountAddress, callerAddress, chainId); while (this.isNameSpaceStorageSlotKeyBeingCalculated.get(storeKey)) { await new Promise((resolve) => setTimeout(resolve, 1)); // wait for 1 ms if another key is being calculated } this.isNameSpaceStorageSlotKeyBeingCalculated.set(storeKey, true); const key = BigInt(Date.now()); await new Promise((resolve) => setTimeout(resolve, 1)); // ensure next call is in the next millisecond this.isNameSpaceStorageSlotKeyBeingCalculated.set(storeKey, false); return key; } getStorageNameSpace(accountAddress, callerAddress) { return keccak256(encodePacked(["address", "address"], [accountAddress, callerAddress])); } async getStorageNameSpaceSlot(accountAddress, callerAddress, chainId) { const defaultKey = await this.getDefaultStorageSlotKey(accountAddress, callerAddress, chainId); return keccak256(encodePacked(["address", "address", "uint256"], [ accountAddress, accountAddress, // Unique timestamp for each slot so that slots are unique for every new request / flow defaultKey ])); } } export const getStorageNameSpace = (accountAddress, callerAddress) => { const manager = NamespaceStorageManager.getInstance(); return manager.getStorageNameSpace(accountAddress, callerAddress); }; export const getStorageNameSpaceSlot = async (accountAddress, callerAddress, chainId) => { const manager = NamespaceStorageManager.getInstance(); return manager.getStorageNameSpaceSlot(accountAddress, callerAddress, chainId); }; //# sourceMappingURL=getNamespaceStorage.js.map