UNPKG

@biconomy/abstractjs

Version:

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

79 lines 3.27 kB
import { concat, getContract, toHex } from "viem"; import { ENTRY_POINT_ADDRESS } from "../../constants/index.js"; import { EntrypointAbi } from "../../constants/abi/index.js"; import { sanitizeUrl } from "../utils/index.js"; class NonceManager { constructor() { Object.defineProperty(this, "isNonceKeyBeingCalculated", { enumerable: true, configurable: true, writable: true, value: new Map() }); } static getInstance() { if (!NonceManager.instance) { NonceManager.instance = new NonceManager(); } return NonceManager.instance; } buildNonceStoreKey(accountAddress, chainId) { return `${accountAddress.toLowerCase()}::${chainId}`; } // This function always make sure to provide a unique nonce key with respect to timestamps. // This is helpful to reduce nonce collusion async getDefaultNonceKey(accountAddress, chainId) { const storeKey = this.buildNonceStoreKey(accountAddress, chainId); while (this.isNonceKeyBeingCalculated.get(storeKey)) { await new Promise((resolve) => setTimeout(resolve, 1)); // wait for 1 ms if another key is being calculated } this.isNonceKeyBeingCalculated.set(storeKey, true); const key = BigInt(Date.now()); await new Promise((resolve) => setTimeout(resolve, 1)); // ensure next call is in the next millisecond this.isNonceKeyBeingCalculated.set(storeKey, false); return key; } async getNonceWithKey(client, accountAddress, parameters) { const TIMESTAMP_ADJUSTMENT = 16777215n; const { key: key_, validationMode, moduleAddress } = parameters; try { const adjustedKey = BigInt(key_) % TIMESTAMP_ADJUSTMENT; const key = concat([ toHex(adjustedKey, { size: 3 }), validationMode, moduleAddress ]); const entryPointContract = getContract({ address: ENTRY_POINT_ADDRESS, abi: EntrypointAbi, client }); const nonce = await entryPointContract.read.getNonce([ accountAddress, BigInt(key) ]); return { nonceKey: BigInt(key), nonce }; } catch (error) { const errorMessage = error.message ?? "RPC issue"; throw new Error(`Failed to fetch nonce due to the error: ${sanitizeUrl(errorMessage)}`); } } } export const getDefaultNonceKey = async (accountAddress, chainId) => { const manager = NonceManager.getInstance(); return manager.getDefaultNonceKey(accountAddress, chainId); }; /** * @description Gets the nonce for the account along with modified key * @param client Viem public client * @param accountAddress EVM wallet account address * @param chainId evm chainId * @param parameters Optional parameters for getting the nonce * @returns The nonce and the key */ export const getNonceWithKeyUtil = async (client, accountAddress, parameters) => { const manager = NonceManager.getInstance(); return manager.getNonceWithKey(client, accountAddress, parameters); }; //# sourceMappingURL=getNonceWithKey.js.map