### Install Epoch SDK Source: https://docs.epochprotocol.xyz/use-epoch-sdk/intent-automation-module/epoch-sdk Instructions for installing the Epoch Protocol SDK using either Yarn or npm package managers. This SDK is essential for interacting with Epoch Protocol functionalities like smart contract wallet management and transaction sending. ```bash yarn add @epoch-protocol/sdk ``` ```bash npm i @epoch-protocol/sdk ``` -------------------------------- ### Initialize SimpleAccountAPI with Epoch SDK Source: https://docs.epochprotocol.xyz/use-epoch-sdk/intent-automation-module/epoch-sdk Demonstrates how to initialize the SimpleAccountAPI from the `@epoch-protocol/sdk` using a provider, entry point address, owner signer, and factory address. This setup is for integrating with Eth-Infinitism's SimpleAccount.sol. ```TypeScript import { SimpleAccountAPI } from "@epoch-protocol/sdk"; const ENTRY_POINT = "0x5FF137D4b0FDCD49DcA30c7CF57E578a026d2789"; const FACTORY_ADDRESS = "0x4A4fC0bF39D191b5fcA7d4868C9F742B342a39c1"; const walletAPIInstance = new SimpleAccountAPI({ provider, entryPointAddress: ENTRY_POINT, owner: signer, factoryAddress: FACTORY_ADDRESS, }); ``` -------------------------------- ### Manage Nonce for Automated UserOperations Source: https://docs.epochprotocol.xyz/use-epoch-sdk/intent-automation-module/epoch-sdk Explains the process of managing nonces for automated transactions to prevent clashes, especially when many UserOperations are in the queue. It involves getting a valid nonce key from the bundler and then retrieving the nonce using the wallet API before assigning it to the UserOperation. ```TypeScript let userOp = {...}; const key = await bundler.getValidNonceKey(userOp); const nonce = await walletAPI.getNonce(key); userOp.nonce = nonce; ``` -------------------------------- ### Send UserOperation to Bundler and Get Receipt Source: https://docs.epochprotocol.xyz/use-epoch-sdk/intent-automation-module/epoch-sdk Details the process of sending a UserOperation to a bundler using `bundler.sendUserOpToBundler` and subsequently retrieving the transaction ID or receipt using `walletAPI.getUserOpReceipt`. This is a straightforward way to execute UserOperations. ```TypeScript const userOpHash = await bundler.sendUserOpToBundler(userOp); // In case of non advanced userops const txid = await walletAPI.getUserOpReceipt(userOpHash); ``` -------------------------------- ### Get User's Smart Contract Wallet Address with Epoch SDK Source: https://docs.epochprotocol.xyz/use-epoch-sdk/intent-automation-module/examples/how-to-get-users-sc-wallet-address This React hook, `useUserSCWallet`, provides a convenient way to obtain the user's Smart Contract wallet address. It depends on the `useBundler` hook to access the `walletAPI` instance, which is then used to call `getAccountAddress()`. The address is stored in a state variable and updated asynchronously when `walletAPI` becomes available. ```typescript import { useEffect, useState } from "react"; import { useBundler } from "./useBundler"; export const useUserSCWallet = () => { const { walletAPI } = useBundler(); const [userSCWalletAddress, setUserSCWalletAddress] = useState(""); useEffect(() => { (async () => { if (walletAPI) { setUserSCWalletAddress(await walletAPI.getAccountAddress()); } })(); }, [walletAPI]); return userSCWalletAddress; }; ``` -------------------------------- ### Set Up Epoch Bundler Instance Source: https://docs.epochprotocol.xyz/use-epoch-sdk/intent-automation-module/epoch-sdk This code snippet demonstrates how to initialize an HttpRpcClient instance for connecting to the bundler. The bundler instance is crucial for performing bundler-specific actions such as sending UserOperations (UserOps), retrieving UserOps, and generating UserOperation hashes. It requires the bundler URL, the EntryPoint contract address, and the chain ID. ```typescript import { HttpRpcClient } from '@epoch-protocol/sdk' const bundlerInstance = new HttpRpcClient(bundlerUrl, ENTRY_POINT, parseInt(network.chainId.toString())); const network = await provider.getNetwork(); ``` -------------------------------- ### Initialize Simple Account API and Bundler in React with Epoch Protocol SDK Source: https://docs.epochprotocol.xyz/use-epoch-sdk/intent-automation-module/examples/how-to-initialise-the-epoch-sdk This TypeScript React hook (`useBundler`) initializes the `SimpleAccountAPI` and `HttpRpcClient` (bundler) from the `@epoch-protocol/sdk`. It depends on `ethers` provider/signer obtained via `useEthersProvider` and `useEthersSigner`. Inputs include `ENTRY_POINT`, `FACTORY_ADDRESS`, and `BUNDLER_URL` (from environment), returning configured `walletAPI` and `bundler` instances. ```TypeScript import { useEffect, useState } from "react"; import { HttpRpcClient, SimpleAccountAPI } from "@epoch-protocol/sdk"; import { useEthersProvider, useEthersSigner } from "~~/utils/scaffold-eth/common"; export const useBundler = () => { const ENTRY_POINT = "0x5FF137D4b0FDCD49DcA30c7CF57E578a026d2789"; const FACTORY_ADDRESS = "0x4A4fC0bF39D191b5fcA7d4868C9F742B342a39c1"; const bundlerUrl: string = process.env.BUNDLER_URL ?? "http://localhost:14337/80001"; const [walletAPI, setWalletAPI] = useState(null); const [bundler, setBundler] = useState(null); const provider = useEthersProvider(); // Ethers Provider const signer = useEthersSigner(); // Ethers Signer useEffect(() => { (async () => { if (signer && provider) { const network = await provider.getNetwork(); x const walletAPIInstance = new SimpleAccountAPI({ provider, entryPointAddress: ENTRY_POINT, owner: signer, factoryAddress: FACTORY_ADDRESS, }); setWalletAPI(walletAPIInstance); const bundlerInstance = new HttpRpcClient(bundlerUrl, ENTRY_POINT, parseInt(network.chainId.toString())); setBundler(bundlerInstance); } })(); }, [signer, provider, bundlerUrl]); return { walletAPI, bundler }; }; ``` -------------------------------- ### Initialize SafeAccountAPI with Epoch SDK Source: https://docs.epochprotocol.xyz/use-epoch-sdk/intent-automation-module/epoch-sdk Illustrates how to initialize the SafeAccountAPI from the `@epoch-protocol/sdk`, leveraging a provider, entry point address, owner signer, and a `safeConfig` derived from `safeDefaultConfig` based on the network chain ID. The `salt` is crucial for deterministic address generation, and its consistency is important for application stability. ```TypeScript import { SafeAccountAPI } from "@epoch-protocol/sdk"; import { safeDefaultConfig } from "@epoch-protocol/sdk/dist/src/SafeDefaultConfig"; const walletAPIInstance = new SafeAccountAPI({ provider, entryPointAddress: ENTRY_POINT, owner: signer, safeConfig: safeDefaultConfig[network.chainId], salt: safeDefaultConfig[network.chainId].salt, }); ``` -------------------------------- ### Initialize SAFE Account API and Bundler in React with Epoch Protocol SDK Source: https://docs.epochprotocol.xyz/use-epoch-sdk/intent-automation-module/examples/how-to-initialise-the-epoch-sdk This TypeScript React hook (`useBundler`) initializes the `SafeAccountAPI` and `HttpRpcClient` (bundler) from the `@epoch-protocol/sdk`. It relies on `ethers` provider/signer and `safeDefaultConfig` for network-specific SAFE configurations. Inputs include `ENTRY_POINT` and `BUNDLER_URL` (from environment), returning configured `walletAPI` and `bundler` instances. ```TypeScript import { useEffect, useState } from "react"; import { HttpRpcClient, SafeAccountAPI } from "@epoch-protocol/sdk"; import { safeDefaultConfig } from "@epoch-protocol/sdk/dist/src/SafeDefaultConfig"; import { useEthersProvider, useEthersSigner } from "~~/utils/scaffold-eth/common"; export const useBundler = () => { const ENTRY_POINT = "0x5FF137D4b0FDCD49DcA30c7CF57E578a026d2789"; const bundlerUrl: string = process.env.BUNDLER_URL ?? "http://localhost:14337/80001"; const [walletAPI, setWalletAPI] = useState(null); const [bundler, setBundler] = useState(null); const provider = useEthersProvider(); const signer = useEthersSigner(); useEffect(() => { (async () => { if (signer && provider) { const network = await provider.getNetwork(); const walletAPIInstance = new SafeAccountAPI({ provider, entryPointAddress: ENTRY_POINT, owner: signer, safeConfig: safeDefaultConfig[network.chainId], salt: safeDefaultConfig[network.chainId].salt, }); setWalletAPI(walletAPIInstance); const bundlerInstance = new HttpRpcClient(bundlerUrl, ENTRY_POINT, parseInt(network.chainId.toString())); setBundler(bundlerInstance); } })(); }, [signer, provider, bundlerUrl]); return { walletAPI, bundler }; }; ``` -------------------------------- ### Create Signed UserOperation for Normal Transactions Source: https://docs.epochprotocol.xyz/use-epoch-sdk/intent-automation-module/epoch-sdk Shows how to create a signed UserOperation for a normal transaction using `walletAPI.createSignedUserOp`. The SDK automatically handles nonce calculation, but it can also be manually passed if needed. ```TypeScript const userOp = await walletAPI.createSignedUserOp({ target: someAddress, data: "0x", value: 100000000n, // nonce: BigInt(someNonce), }); ``` -------------------------------- ### Retrieve Queued UserOperations from Bundler Source: https://docs.epochprotocol.xyz/use-epoch-sdk/intent-automation-module/epoch-sdk Demonstrates how to fetch a list of all UserOperations currently queued with the bundler for a specific user address using `bundler.getUserOperations`. This allows monitoring of pending transactions. ```TypeScript const queuedUserOpsList = await bundler.getUserOperations(userAddress); ``` -------------------------------- ### Deploy User's Smart Contract Wallet with Epoch SDK Source: https://docs.epochprotocol.xyz/use-epoch-sdk/intent-automation-module/examples/deploy-users-sc-wallet-if-not-deployed This JavaScript snippet demonstrates how to programmatically deploy a user's smart contract (SC) wallet using the Epoch SDK. It first checks if the wallet is not yet deployed and if it holds a positive balance of native tokens for gas. If both conditions are met, it proceeds to create a signed user operation and sends it to the bundler for the wallet's deployment. ```javascript const { walletAPI, bundler } = useBundler(); const isUserWalletNotDeployed = useIsWalletDeployed(); const account = useAccount(); if(isUserWalletNotDeployed && userSCWalletBalance > 0) { const op = await walletAPI.createSignedUserOp({ target: account.address, data: "0x", value: 0n, }); const deployWalletUserOp = await bundler.sendUserOpToBundler(op); } ``` -------------------------------- ### Epoch Bundler User Operation RPC Endpoints Source: https://docs.epochprotocol.xyz/use-epoch-sdk/intent-automation-module/epoch-bundler Comprehensive documentation for the custom RPC methods provided by Epoch's bundler for managing user operations, including sending, retrieving, and deleting, with support for advanced intent automation features. ```APIDOC eth_sendUserOperation Description: Sends a user operation to the bundler, supporting advanced intent automation. Parameters: userOp: object - The standard UserOperation object. entryPoint: string - The entry point contract address. advancedUserOperation: object (optional) - An object containing trigger and evaluation statements for intent automation. triggerEvent: object - Defines the event that triggers the operation. contractAddress: string - Address of the contract emitting the event. eventSignature: string - Signature of the event (e.g., "event Sync(uint112 reserve0, uint112 reserve1);"). evaluationStatement: string - A condition to evaluate based on event data (e.g., ":reserve1: / :reserve0: >= 9"). Returns: string - The user operation hash (userOpHash). eth_getUserOperations Description: Retrieves a list of user operations currently queued in the bundler for a specific smart contract wallet. Parameters: senderAddress: string - The address of the user's smart contract wallet (e.g., "0xb28884540Dc4FA18568Bbc8564386eBd342e3a04"). Returns: array - A list of queued user operation objects. Each object includes: chainId: string userOp: object - The UserOperation object, potentially including 'advancedUserOperation'. entryPoint: string prefund: string userOpHash: string lastUpdatedTime: string Request Example: { "method": "eth_getUserOperations", "params": [ "0xb28884540Dc4FA18568Bbc8564386eBd342e3a04" ] } Response Example: { "jsonrpc": "2.0", "id": 1, "result": [ { "chainId": "0x13881", "userOp": { "sender": "0x037241C85415fcC94D830d972bBec26e079165Aa", "nonce": "0xc6168aeedaeb650000000000000000", "initCode": "0x", "callData": "0xb61d27f60000...0000000000000", "callGasLimit": "0x16e4a0", "verificationGasLimit": "0x186a0", "preVerificationGas": "0xb47c", "maxFeePerGas": "0x59682f20", "maxPriorityFeePerGas": "0x59682f00", "paymasterAndData": "0x", "signature": "0xf28148f085d947222...21bd7818ef1e94c7411b", "advancedUserOperation": { "triggerEvent": { "contractAddress": "0xBfa045514a...1E087AE82e3", "eventSignature": "event Sync(uint112 reserve0, uint112 reserve1);", "evaluationStatement": ":reserve1: / :reserve0: >= 9" } } }, "entryPoint": "0x5FF137D4b0FDCD49DcA30c7CF57E578a026d2789", "prefund": "0x0", "userOpHash": "0xc61060d21d9719...79de49ab3d3827f5", "lastUpdatedTime": "0x18c917978fb" } ] } eth_deleteUserOperation Description: Deletes a user operation from the bundler's queue based on its nonce. Parameters: nonce: string - The nonce of the user operation to be deleted. Returns: boolean - True if the user operation was successfully deleted, false otherwise. ``` -------------------------------- ### Schedule ERC-20 Token Transfer via Account Abstraction Source: https://docs.epochprotocol.xyz/use-epoch-sdk/intent-automation-module/examples/schedule-token-payment This TypeScript code snippet illustrates the process of scheduling an ERC-20 token transfer. It defines a minimal ERC-20 ABI, encodes a 'transfer' function call using viem, constructs an unsigned user operation with gas parameters, handles nonce management, signs the user operation, and finally augments it with an 'executionTimeWindow' for scheduled execution before sending it to a bundler. ```typescript import { BigNumber } from "ethers"; import { encodeFunctionData, parseUnits } from "viem"; const abi = [ // Read-Only Functions "function balanceOf(address owner) view returns (uint256)", "function decimals() view returns (uint8)", "function symbol() view returns (string)", // Authenticated Functions "function transfer(address to, uint amount) returns (bool)", // Events "event Transfer(address indexed from, address indexed to, uint amount)", ]; const data = encodeFunctionData({ abi, args: [recipientAddress, parseUnits(transferAmount.toString(), token.decimals)], functionName: "transfer", }); const unsignedUserOp = await walletAPI.createUnsignedUserOp({ target: token.address, data, maxFeePerGas: BigNumber.from("90000000000"), // average value for the token transfer maxPriorityFeePerGas: BigNumber.from("1500000000"), // average value for the token transfer gasLimit: BigNumber.from("2000320"), // average value for the token transfer value: 0n, }); const newUserOp: any = { sender: await unsignedUserOp.sender, nonce: await unsignedUserOp.nonce, initCode: await unsignedUserOp.initCode, callData: await unsignedUserOp.callData, callGasLimit: await unsignedUserOp.callGasLimit, verificationGasLimit: await unsignedUserOp.verificationGasLimit, preVerificationGas: await unsignedUserOp.preVerificationGas, maxFeePerGas: await unsignedUserOp.maxFeePerGas, maxPriorityFeePerGas: await unsignedUserOp.maxPriorityFeePerGas, paymasterAndData: await unsignedUserOp.paymasterAndData, signature: await unsignedUserOp.signature, }; const key = await bundler.getValidNonceKey(newUserOp); const nonce = await walletAPI.getNonce(key); newUserOp.nonce = nonce; const signedUserOp = await walletAPI.signUserOp(newUserOp); const advancedOp = { ...signedUserOp, advancedUserOperation: { executionTimeWindow: { executionWindowStart: epochTimeofScheduledTime, executionWindowEnd: epochTimeofScheduledTimeWindowEnd, }, }, }; const userOpHash = await bundler.sendUserOpToBundler(advancedOp); ``` -------------------------------- ### Define SafeConfig Interface for SAFE Account API Source: https://docs.epochprotocol.xyz/use-epoch-sdk/intent-automation-module/epoch-sdk Defines the TypeScript interface `SafeConfig` required for configuring the SAFE Account API. This interface specifies parameters like proxy factory, singleton, fallback module, AA module, add module library, and a salt, which are essential for calculating the SAFE Account address. ```TypeScript export interface SafeConfig { safeProxyFactory: string; singleton: string; fallbackModule: string; aaModule: string; addModuleLib: string; salt: BigNumber; } ``` -------------------------------- ### Epoch Protocol Intent Input Structure Source: https://docs.epochprotocol.xyz/litepaper Defines the structure and attributes of an intent provided to the Epoch Protocol network for resolution. This declarative paradigm allows users or dApps to express their desired state outcomes, which are then processed by Sub-Intent Orchestrators. ```APIDOC Intent Input Attributes: - Approvals: Permissions or authorizations required for the intent's execution. - Task: The specific action or desired state change the intent aims to achieve. - Optimization Factor: Criteria or preferences for optimizing the solution (e.g., lowest gas, fastest execution, specific route). - Constraints: Conditions or limitations that must be satisfied during the intent's resolution (e.g., time limits, specific protocols, asset types). - Deadline: The timestamp by which the intent must be resolved or executed. - Triggers: Conditions that, when met, initiate the intent's execution (e.g., price thresholds, external events). - Proposed Fee Rewards: Incentives offered to solvers for successfully resolving the intent. - List of Preferred Solvers: A list of specific solvers or solver types preferred by the user or dApp. ``` -------------------------------- ### API: Event-Based Trigger Configuration for Advanced User Operations Source: https://docs.epochprotocol.xyz/use-epoch-sdk/intent-automation-module/triggers Details the structure and parameters required to configure an event-based trigger within the Epoch Protocol's `advancedUserOperation` object. This allows for automated actions to be scheduled based on specific contract events and custom evaluation logic. ```APIDOC Event-Based Trigger Configuration: triggerEvent object: - contractAddress: string Description: The address of the smart contract to monitor for events. - eventSignature: string Description: The ABI signature of the event that should trigger the operation (e.g., "event Sync(uint112 reserve0, uint112 reserve1);"). - evaluationStatement: string Description: A mathematical expression or evaluation statement that uses event parameters to determine if the trigger condition is met. Supported operators include +, -, *, /, <=, >=, and ==. Example: ":reserve1: / :reserve0: <= ${somerationumber}" Usage Example (within advancedUserOperation): { ...signedUserOp, advancedUserOperation: { triggerEvent: { contractAddress: "0x123", eventSignature: "event Sync(uint112 reserve0, uint112 reserve1);", evaluationStatement: ":reserve1: / :reserve0: <= ${somerationumber}" } } } ``` -------------------------------- ### Define Time-Based Transaction Execution Window Source: https://docs.epochprotocol.xyz/use-epoch-sdk/intent-automation-module/triggers This snippet demonstrates how to specify a time-based execution window for a transaction within the Epoch Protocol. The `executionWindowStart` and `executionWindowEnd` fields define the permissible block-time range for transaction execution on a blockchain. ```JSON { ...signedUserOp, executionTimeWindow : { executionWindowStart: 12341234, executionWindowEnd: 12312123 } } ``` -------------------------------- ### Schedule ETH Transfer Triggered by Smart Contract Event Source: https://docs.epochprotocol.xyz/use-epoch-sdk/intent-automation-module/examples/schedule-eth-transfer-on-event-trigger This TypeScript code snippet illustrates how to construct and send an advanced UserOperation to schedule an ETH transfer. The transfer is configured to execute only when a 'ProposalResult' event on a specified contract emits with a 'statusCode' equal to 2. It leverages `ethers` for BigNumber operations and `viem` for function data encoding, interacting with a `walletAPI` for UserOperation management and a `bundler` for submission. ```TypeScript import { BigNumber } from "ethers"; import { encodeFunctionData, parseUnits } from "viem"; const unsignedUserOp = await walletAPI.createUnsignedUserOp({ target: recipientAddressForETH, data: "0x", maxFeePerGas: BigNumber.from("90000000000"), // average value for the token transfer maxPriorityFeePerGas: BigNumber.from("1500000000"), // average value for the token transfer gasLimit: BigNumber.from("2000320"), // average value for the token transfer value: 1000000n, // Transfering ETH to recipient }); const newUserOp: any = { sender: await unsignedUserOp.sender, nonce: await unsignedUserOp.nonce, initCode: await unsignedUserOp.initCode, callData: await unsignedUserOp.callData, callGasLimit: await unsignedUserOp.callGasLimit, verificationGasLimit: await unsignedUserOp.verificationGasLimit, preVerificationGas: await unsignedUserOp.preVerificationGas, maxFeePerGas: await unsignedUserOp.maxFeePerGas, maxPriorityFeePerGas: await unsignedUserOp.maxPriorityFeePerGas, paymasterAndData: await unsignedUserOp.paymasterAndData, signature: await unsignedUserOp.signature, }; const key = await bundler.getValidNonceKey(newUserOp); const nonce = await walletAPI.getNonce(key); newUserOp.nonce = nonce; const signedUserOp = await walletAPI.signUserOp(newUserOp); const advancedOp = { ...signedUserOp, advancedUserOperation: { triggerEvent: { contractAddress: propsalContractAddress, eventSignature: "event ProposalResult(address indexed recipient, uint statusCode);", evaluationStatement: ":statusCode: == 2", }, }, }; const userOpHash = await bundler.sendUserOpToBundler(advancedOp); ``` -------------------------------- ### Epoch Protocol Entrypoint Contract Address Source: https://docs.epochprotocol.xyz/use-epoch-sdk/contracts The main entrypoint contract address for the Epoch Protocol, serving as the primary interaction point for the protocol's functionalities. ```Blockchain 0x5FF137D4b0FDCD49DcA30c7CF57E578a026d2789 ``` -------------------------------- ### ERC-4337 UserOperation Object Structure Source: https://docs.epochprotocol.xyz/account-abstraction/erc-4337/operations Defines the structure and fields of a pseudo-transaction `UserOperation` object used in ERC-4337 for executing transactions with contract accounts. It details each field's type and purpose, crucial for dApps and wallets interacting with the EntryPoint contract. ```APIDOC UserOperation: sender: address Description: The address of the smart contract account nonce: uint256 Description: Anti-replay protection; also used as the salt for first-time account creation initCode: bytes Description: Code used to deploy the account if not yet on-chain callData: bytes Description: Data that's passed to the sender for execution callGasLimit: uint256 Description: Gas limit for execution phase verificationGasLimit: uint256 Description: Gas limit for verification phase preVerificationGas: uint256 Description: Gas to compensate the bundler maxFeePerGas: uint256 Description: Maximum fee per gas (similar to EIP-1559 max_fee_per_gas) maxPriorityFeePerGas: uint256 Description: Maximum priority fee per gas (similar to EIP-1559 max_priority_fee_per_gas) paymasterAndData: bytes Description: Paymaster Contract address and any extra data required for verification and execution (empty for self-sponsored transaction) signature: bytes Description: Used to validate a UserOperation along with the nonce during verification ``` -------------------------------- ### Check User's Smart Contract Wallet Deployment Status with React Hook Source: https://docs.epochprotocol.xyz/use-epoch-sdk/intent-automation-module/examples/check-if-users-sc-wallet-is-deployed-or-not This React hook, `useIsWalletDeployed`, checks if a user's smart contract wallet (SC Wallet) is deployed. It uses the `useBundler` hook to access the `walletAPI` and calls `walletAPI.checkAccountPhantom()` to determine the deployment status, updating a state variable accordingly. This is useful for conditional rendering or actions based on wallet deployment. ```typescript import { useEffect, useState } from "react"; import { useBundler } from "./useBundler"; export const useIsWalletDeployed = () => { const [isUserWalletNotDeployed, setIsUserWalletNotDeployed] = useState(false); const { walletAPI } = useBundler(); useEffect(() => { (async () => { if (walletAPI) { const isNotDeployed = await walletAPI.checkAccountPhantom(); if (isNotDeployed) { setIsUserWalletNotDeployed(true); } } })(); }, [walletAPI]); return isUserWalletNotDeployed; }; ``` -------------------------------- ### Delete Queued UserOperation by Sending New UserOp Source: https://docs.epochprotocol.xyz/use-epoch-sdk/intent-automation-module/epoch-sdk Explains how to delete a specific UserOperation from the automation queue. This is achieved by sending a new UserOperation with the same nonce as the UserOperation to be deleted, using `walletAPI.createSignedUserOp` and `bundler.deleteAdvancedUserOpFromBundler`. ```TypeScript const deleteOp = await walletAPI.createSignedUserOp({ target: userSCWalletAddress, data: "0x", value: 0n, nonce: BigInt(userOpToDelete.nonce).toString(), }); const deleteUserOpHash = await bundler.deleteAdvancedUserOpFromBundler(deleteOp); ``` -------------------------------- ### Epoch Paymaster Contract Address on Mumbai Testnet Source: https://docs.epochprotocol.xyz/use-epoch-sdk/contracts The Epoch Paymaster contract address deployed on the Mumbai testnet, used for testing and development of gasless transactions and account abstraction features. ```Blockchain 0x089E74F33764F6134C69389bcc4Dea8D9843ec6e ``` -------------------------------- ### Epoch Paymaster Contract Address on Polygon Source: https://docs.epochprotocol.xyz/use-epoch-sdk/contracts The Epoch Paymaster contract address deployed on the Polygon network, facilitating gasless transactions and account abstraction features. ```Blockchain 0xC6FceF87459420c710a74568B00ED47b883e6127 ``` === COMPLETE CONTENT === This response contains all available snippets from this library. No additional content exists. Do not make further requests.