diff --git a/CHANGELOG.md b/CHANGELOG.md index 8810cab6..6b599ce7 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,4 +1,14 @@ # Changelog +## [1.1.0] - 2023-07-14 +### New +- Added Mantle Mainnet config as supported networks +### Breaking Changes +- Changed the wallet factory address so the smart wallet address will generate a new address. Whoever wishes to access the old wallet should use version 1.0.3 to connect to the old smart wallet +- Renamed sign method to estimate and get the return object as UserOps without signature +- Now signing the UserOps is moved into send method so provider would be requested to sign only while calling send method +- getUserOpsReceipt returns the whole object with UserOpsReceipt with transaction Receipt as compared to previously returned transaction hash +- getUserOpsReceipt only returns if the transaction is included into the block on-chain and would give results only for 15k blocks from the latest block number + ## [1.0.3] - 2023-07-10 ### Fixed - Fuse and ArbitrumGoerli bundler url and native transfer funds example diff --git a/examples/02-transfer-funds.ts b/examples/02-transfer-funds.ts index b424e95d..0a8dbbcd 100644 --- a/examples/02-transfer-funds.ts +++ b/examples/02-transfer-funds.ts @@ -2,6 +2,7 @@ import { ethers } from 'ethers'; import { PrimeSdk } from '../src'; import { printOp } from '../src/sdk/common/OperationUtils'; import * as dotenv from 'dotenv'; +import { sleep } from '../src/sdk/common'; dotenv.config(); @@ -30,18 +31,23 @@ async function main() { console.log('balances: ', balance); - // sign transactions added to the batch - const op = await primeSdk.sign(); - console.log(`Signed UserOp: ${await printOp(op)}`); + // estimate transactions added to the batch and get the fee data for the UserOp + const op = await primeSdk.estimate(); + console.log(`Estimate UserOp: ${await printOp(op)}`); - // sending to the bundler... + // sign the UserOp and sending to the bundler... const uoHash = await primeSdk.send(op); console.log(`UserOpHash: ${uoHash}`); // get transaction hash... console.log('Waiting for transaction...'); - const txHash = await primeSdk.getUserOpReceipt(uoHash); - console.log('\x1b[33m%s\x1b[0m', `Transaction hash: ${txHash}`); + let userOpsReceipt = null; + const timeout = Date.now() + 60000; // 1 minute timeout + while((userOpsReceipt == null) && (Date.now() < timeout)) { + await sleep(2); + userOpsReceipt = await primeSdk.getUserOpReceipt(uoHash); + } + console.log('\x1b[33m%s\x1b[0m', `Transaction Receipt: `, userOpsReceipt); } main() diff --git a/examples/03-transfer-erc20.ts b/examples/03-transfer-erc20.ts index 4e2e4104..69ef947d 100644 --- a/examples/03-transfer-erc20.ts +++ b/examples/03-transfer-erc20.ts @@ -3,11 +3,12 @@ import { PrimeSdk } from '../src'; import { printOp } from '../src/sdk/common/OperationUtils'; import { ERC20_ABI } from '../src/sdk/helpers/abi/ERC20_ABI'; import * as dotenv from 'dotenv'; +import { sleep } from '../src/sdk/common'; dotenv.config(); // add/change these values -const recipient: string = '0xD129dB5e418e389c3F7D3ae0B8771B3f76799A52'; // recipient wallet address +const recipient: string = '0x80a1874E1046B1cc5deFdf4D3153838B72fF94Ac'; // recipient wallet address const value: string = '0.1'; // transfer value const tokenAddress: string = '0x326C977E6efc84E512bB9C30f76E30c160eD06FB'; @@ -38,18 +39,23 @@ async function main() { let userOpsBatch = await primeSdk.addUserOpsToBatch({to: tokenAddress, data: transactionData}); console.log('transactions: ', userOpsBatch); - // sign transactions added to the batch - const op = await primeSdk.sign(); - console.log(`Signed UserOp: ${await printOp(op)}`); + // estimate transactions added to the batch and get the fee data for the UserOp + const op = await primeSdk.estimate(); + console.log(`Estimate UserOp: ${await printOp(op)}`); - // sending to the bundler... + // sign the UserOp and sending to the bundler... const uoHash = await primeSdk.send(op); console.log(`UserOpHash: ${uoHash}`); // get transaction hash... console.log('Waiting for transaction...'); - const txHash = await primeSdk.getUserOpReceipt(uoHash); - console.log('\x1b[33m%s\x1b[0m', `Transaction hash: ${txHash}`); + let userOpsReceipt = null; + const timeout = Date.now() + 60000; // 1 minute timeout + while((userOpsReceipt == null) && (Date.now() < timeout)) { + await sleep(2); + userOpsReceipt = await primeSdk.getUserOpReceipt(uoHash); + } + console.log('\x1b[33m%s\x1b[0m', `Transaction Receipt: `, userOpsReceipt); } main() diff --git a/examples/04-transfer-nft.ts b/examples/04-transfer-nft.ts index 1e5a85e7..2de3664d 100644 --- a/examples/04-transfer-nft.ts +++ b/examples/04-transfer-nft.ts @@ -2,6 +2,7 @@ import { ethers } from 'ethers'; import { PrimeSdk } from '../src'; import { printOp } from '../src/sdk/common/OperationUtils'; import * as dotenv from 'dotenv'; +import { sleep } from '../src/sdk/common'; dotenv.config(); @@ -34,17 +35,22 @@ async function main() { console.log('transactions: ', userOpsBatch); // sign transactions added to the batch - const op = await primeSdk.sign(); - console.log(`Signed UserOp: ${await printOp(op)}`); + const op = await primeSdk.estimate(); + console.log(`Estimated UserOp: ${await printOp(op)}`); - // sending to the bundler... + // sign the userOps and sending to the bundler... const uoHash = await primeSdk.send(op); console.log(`UserOpHash: ${uoHash}`); // get transaction hash... console.log('Waiting for transaction...'); - const txHash = await primeSdk.getUserOpReceipt(uoHash); - console.log('\x1b[33m%s\x1b[0m', `Transaction hash: ${txHash}`); + let userOpsReceipt = null; + const timeout = Date.now() + 60000; // 1 minute timeout + while((userOpsReceipt == null) && (Date.now() < timeout)) { + await sleep(2); + userOpsReceipt = await primeSdk.getUserOpReceipt(uoHash); + } + console.log('\x1b[33m%s\x1b[0m', `Transaction Receipt: `, userOpsReceipt); } main() diff --git a/examples/scripts/commands/NFTTransfer.ts b/examples/scripts/commands/NFTTransfer.ts index ee25abd4..750aac25 100644 --- a/examples/scripts/commands/NFTTransfer.ts +++ b/examples/scripts/commands/NFTTransfer.ts @@ -3,6 +3,7 @@ import { ethers } from "ethers"; import config from "../../config.json"; import { PrimeSdk } from "../../../src"; import { printOp } from "../../../src/sdk/common/OperationUtils"; +import { sleep } from "../../../src/sdk/common"; export default async function main( tknid: number, @@ -31,15 +32,20 @@ export default async function main( await primeSdk.addUserOpsToBatch({to: tokenAddress, data: erc721Data}); console.log(`Added transaction to batch`); - const op = await primeSdk.sign(); - console.log(`Signed UserOp: ${await printOp(op)}`); + const op = await primeSdk.estimate(); + console.log(`Estimated UserOp: ${await printOp(op)}`); - // sending to the bundler... + // sign the userOp and sending to the bundler... const uoHash = await primeSdk.send(op); console.log(`UserOpHash: ${uoHash}`); // get transaction hash... console.log('Waiting for transaction...'); - const txHash = await primeSdk.getUserOpReceipt(uoHash); - console.log('\x1b[33m%s\x1b[0m', `Transaction hash: ${txHash}`); + let userOpsReceipt = null; + const timeout = Date.now() + 60000; // 1 minute timeout + while((userOpsReceipt == null) && (Date.now() < timeout)) { + await sleep(2); + userOpsReceipt = await primeSdk.getUserOpReceipt(uoHash); + } + console.log('\x1b[33m%s\x1b[0m', `Transaction Receipt: `, userOpsReceipt); } diff --git a/examples/scripts/commands/batchErc20Transfer.ts b/examples/scripts/commands/batchErc20Transfer.ts index 99268e28..7acc8f7e 100644 --- a/examples/scripts/commands/batchErc20Transfer.ts +++ b/examples/scripts/commands/batchErc20Transfer.ts @@ -4,6 +4,7 @@ import { ERC20_ABI } from '../../../src/sdk/helpers/abi/ERC20_ABI'; import config from "../../config.json"; import { PrimeSdk } from '../../../src'; import { printOp } from "../../../src/sdk/common/OperationUtils"; +import { sleep } from "../../../src/sdk/common"; // This example requires several layers of calls: // EntryPoint @@ -52,15 +53,20 @@ export default async function main( await primeSdk.addUserOpsToBatch({to: dest[i], data: data[i]}) } - const op = await primeSdk.sign(); - console.log(`Signed UserOp: ${await printOp(op)}`); + const op = await primeSdk.estimate(); + console.log(`Estimated UserOp: ${await printOp(op)}`); - // sending to the bundler... + // sign the userop and sending to the bundler... const uoHash = await primeSdk.send(op); console.log(`UserOpHash: ${uoHash}`); // get transaction hash... console.log('Waiting for transaction...'); - const txHash = await primeSdk.getUserOpReceipt(uoHash); - console.log('\x1b[33m%s\x1b[0m', `Transaction hash: ${txHash}`); + let userOpsReceipt = null; + const timeout = Date.now() + 60000; // 1 minute timeout + while((userOpsReceipt == null) && (Date.now() < timeout)) { + await sleep(2); + userOpsReceipt = await primeSdk.getUserOpReceipt(uoHash); + } + console.log('\x1b[33m%s\x1b[0m', `Transaction Receipt: `, userOpsReceipt); } diff --git a/examples/scripts/commands/erc20Approve.ts b/examples/scripts/commands/erc20Approve.ts index a3465407..e51b27af 100644 --- a/examples/scripts/commands/erc20Approve.ts +++ b/examples/scripts/commands/erc20Approve.ts @@ -4,6 +4,7 @@ import { ERC20_ABI } from '../../../src/sdk/helpers/abi/ERC20_ABI'; import config from "../../config.json"; import { PrimeSdk } from "../../../src"; import { printOp } from "../../../src/sdk/common/OperationUtils"; +import { sleep } from "../../../src/sdk/common"; export default async function main( tkn: string, @@ -30,15 +31,20 @@ export default async function main( await primeSdk.addUserOpsToBatch({to: erc20.address, data: approveData}); console.log(`Added transaction to batch`); - const op = await primeSdk.sign(); - console.log(`Signed UserOp: ${await printOp(op)}`); + const op = await primeSdk.estimate(); + console.log(`Estimated UserOp: ${await printOp(op)}`); - // sending to the bundler... + // sign the userOp and sending to the bundler... const uoHash = await primeSdk.send(op); console.log(`UserOpHash: ${uoHash}`); // get transaction hash... console.log('Waiting for transaction...'); - const txHash = await primeSdk.getUserOpReceipt(uoHash); - console.log('\x1b[33m%s\x1b[0m', `Transaction hash: ${txHash}`); + let userOpsReceipt = null; + const timeout = Date.now() + 60000; // 1 minute timeout + while((userOpsReceipt == null) && (Date.now() < timeout)) { + await sleep(2); + userOpsReceipt = await primeSdk.getUserOpReceipt(uoHash); + } + console.log('\x1b[33m%s\x1b[0m', `Transaction Receipt: `, userOpsReceipt); } diff --git a/examples/scripts/commands/erc20Transfer.ts b/examples/scripts/commands/erc20Transfer.ts index 946ff033..909308a9 100644 --- a/examples/scripts/commands/erc20Transfer.ts +++ b/examples/scripts/commands/erc20Transfer.ts @@ -4,6 +4,7 @@ import { ERC20_ABI } from '../../../src/sdk/helpers/abi/ERC20_ABI'; import config from "../../config.json"; import { PrimeSdk } from "../../../src"; import { printOp } from "../../../src/sdk/common/OperationUtils"; +import { sleep } from "../../../src/sdk/common"; export default async function main( tkn: string, @@ -32,15 +33,20 @@ export default async function main( await primeSdk.addUserOpsToBatch({to: erc20.address, data: transferData}); console.log(`Added transaction to batch`); - const op = await primeSdk.sign(); - console.log(`Signed UserOp: ${await printOp(op)}`); + const op = await primeSdk.estimate(); + console.log(`Estimated UserOp: ${await printOp(op)}`); - // sending to the bundler... + // sign the UserOp and sending to the bundler... const uoHash = await primeSdk.send(op); console.log(`UserOpHash: ${uoHash}`); // get transaction hash... console.log('Waiting for transaction...'); - const txHash = await primeSdk.getUserOpReceipt(uoHash); - console.log('\x1b[33m%s\x1b[0m', `Transaction hash: ${txHash}`); + let userOpsReceipt = null; + const timeout = Date.now() + 60000; // 1 minute timeout + while((userOpsReceipt == null) && (Date.now() < timeout)) { + await sleep(2); + userOpsReceipt = await primeSdk.getUserOpReceipt(uoHash); + } + console.log('\x1b[33m%s\x1b[0m', `Transaction Receipt: `, userOpsReceipt); } diff --git a/examples/scripts/commands/transfer.ts b/examples/scripts/commands/transfer.ts index d86ad3c1..77da0269 100644 --- a/examples/scripts/commands/transfer.ts +++ b/examples/scripts/commands/transfer.ts @@ -3,6 +3,7 @@ import { ethers } from "ethers"; import config from "../../config.json"; import { PrimeSdk } from "../../../src"; import { printOp } from "../../../src/sdk/common/OperationUtils"; +import { sleep } from "../../../src/sdk/common"; export default async function main(t: string, amt: string) { @@ -18,15 +19,20 @@ export default async function main(t: string, amt: string) { await primeSdk.addUserOpsToBatch({to: target, value}); console.log(`Added transaction to batch`); - const op = await primeSdk.sign(); - console.log(`Signed UserOp: ${await printOp(op)}`); + const op = await primeSdk.estimate(); + console.log(`Estimated UserOp: ${await printOp(op)}`); - // sending to the bundler... + // sign the userOp and sending to the bundler... const uoHash = await primeSdk.send(op); console.log(`UserOpHash: ${uoHash}`); // get transaction hash... console.log('Waiting for transaction...'); - const txHash = await primeSdk.getUserOpReceipt(uoHash); - console.log('\x1b[33m%s\x1b[0m', `Transaction hash: ${txHash}`); + let userOpsReceipt = null; + const timeout = Date.now() + 60000; // 1 minute timeout + while((userOpsReceipt == null) && (Date.now() < timeout)) { + await sleep(2); + userOpsReceipt = await primeSdk.getUserOpReceipt(uoHash); + } + console.log('\x1b[33m%s\x1b[0m', `Transaction Receipt: `, userOpsReceipt); } diff --git a/package-lock.json b/package-lock.json index c3bd5493..9176ee1c 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,12 +1,12 @@ { "name": "@etherspot/prime-sdk", - "version": "1.0.3", + "version": "1.1.0", "lockfileVersion": 3, "requires": true, "packages": { "": { "name": "@etherspot/prime-sdk", - "version": "1.0.3", + "version": "1.1.0", "license": "MIT", "dependencies": { "@thehubbleproject/bls": "0.5.1", diff --git a/package.json b/package.json index af5f7115..1de9583c 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "@etherspot/prime-sdk", - "version": "1.0.3", + "version": "1.1.0", "description": "Etherspot Prime (Account Abstraction) SDK", "keywords": [ "ether", diff --git a/src/sdk/base/BaseAccountAPI.ts b/src/sdk/base/BaseAccountAPI.ts index 4b57d95e..4c113916 100644 --- a/src/sdk/base/BaseAccountAPI.ts +++ b/src/sdk/base/BaseAccountAPI.ts @@ -384,12 +384,7 @@ export abstract class BaseAccountAPI { } const provider = this.services.walletService.getWalletProvider(); const callGasLimit = - parseNumber(detailsForUserOp.gasLimit) ?? - (await provider.estimateGas({ - from: this.entryPointAddress, - to: this.getAccountAddress(), - data: callData, - })); + parseNumber(detailsForUserOp.gasLimit) ?? BigNumber.from(35000) return { callData, @@ -448,7 +443,17 @@ export abstract class BaseAccountAPI { let { maxFeePerGas, maxPriorityFeePerGas } = info; if (maxFeePerGas == null || maxPriorityFeePerGas == null) { const provider = this.services.walletService.getWalletProvider(); - const feeData = await provider.getFeeData(); + let feeData: any = {}; + try { + feeData = await provider.getFeeData(); + } catch (err) { + console.warn( + "getGas: eth_maxPriorityFeePerGas failed, falling back to legacy gas price." + ); + const gas = await provider.getGasPrice(); + + feeData = { maxFeePerGas: gas, maxPriorityFeePerGas: gas }; + } if (maxFeePerGas == null) { maxFeePerGas = feeData.maxFeePerGas ?? undefined; } @@ -466,7 +471,6 @@ export abstract class BaseAccountAPI { verificationGasLimit, maxFeePerGas, maxPriorityFeePerGas, - chainId: 80001, }; diff --git a/src/sdk/base/HttpRpcClient.ts b/src/sdk/base/HttpRpcClient.ts index d099da57..39dd0b88 100644 --- a/src/sdk/base/HttpRpcClient.ts +++ b/src/sdk/base/HttpRpcClient.ts @@ -58,6 +58,11 @@ export class HttpRpcClient { ]); } + async getUserOpsReceipt(uoHash: string): Promise { + const response = await this.userOpJsonRpcProvider.send('eth_getUserOperationReceipt', [uoHash]); + return response; + } + private async printUserOperation( method: string, [userOp1, entryPointAddress]: [UserOperationStruct, string], diff --git a/src/sdk/common/constants.ts b/src/sdk/common/constants.ts index c335b241..04c9c8f2 100644 --- a/src/sdk/common/constants.ts +++ b/src/sdk/common/constants.ts @@ -7,3 +7,5 @@ export enum HeaderNames { ProjectKey = 'x-project-key', ProjectMetadata = 'x-project-metadata', } + +export const bufferPercent:number = 13; // Buffer in percent diff --git a/src/sdk/common/getGasFee.ts b/src/sdk/common/getGasFee.ts index c4077885..e1bd0840 100644 --- a/src/sdk/common/getGasFee.ts +++ b/src/sdk/common/getGasFee.ts @@ -1,4 +1,5 @@ -import { BigNumberish, ethers } from 'ethers'; +import { BigNumber, BigNumberish, ethers } from 'ethers'; +import { bufferPercent } from './constants'; export interface Gas { maxFeePerGas: BigNumberish; @@ -6,12 +7,21 @@ export interface Gas { } export async function getGasFee(provider: ethers.providers.JsonRpcProvider): Promise { - const [fee, block] = await Promise.all([provider.send('eth_maxPriorityFeePerGas', []), provider.getBlock('latest')]); - const tip = ethers.BigNumber.from(fee); - const buffer = tip.div(100).mul(13); - const maxPriorityFeePerGas = tip.add(buffer); - const maxFeePerGas = - block.baseFeePerGas != null ? block.baseFeePerGas.mul(2).add(maxPriorityFeePerGas) : maxPriorityFeePerGas; + try { + const [fee, block] = await provider.send('eth_maxPriorityFeePerGas', []); + if (BigNumber.from(0).eq(fee)) return { maxFeePerGas: BigNumber.from(1), maxPriorityFeePerGas: BigNumber.from(1) }; + const tip = ethers.BigNumber.from(fee); + const buffer = tip.div(100).mul(bufferPercent); + const maxPriorityFeePerGas = tip.add(buffer); + const maxFeePerGas = + block.baseFeePerGas != null ? block.baseFeePerGas.mul(2).add(maxPriorityFeePerGas) : maxPriorityFeePerGas; - return { maxFeePerGas, maxPriorityFeePerGas }; + return { maxFeePerGas, maxPriorityFeePerGas }; + } catch (err) { + console.warn( + "getGas: eth_maxPriorityFeePerGas failed, falling back to legacy gas price." + ); + const gas = await provider.getGasPrice(); + return { maxFeePerGas: gas, maxPriorityFeePerGas: gas }; + } } diff --git a/src/sdk/network/constants.ts b/src/sdk/network/constants.ts index 75201035..17fa61c3 100644 --- a/src/sdk/network/constants.ts +++ b/src/sdk/network/constants.ts @@ -18,9 +18,10 @@ export enum NetworkNames { OptimismGoerli = 'optimismGoerli', RSKTestnet = 'RSKTestnet', VerseTestnet = 'verseTestnet', + Mantle = 'Mantle', } -export const SupportedNetworks = [5, 80001, 84531, 11155111, 10, 137, 42161, 421613, 10200, 122, 123, 100, 2357, 1, 420, 31, 20197 ] +export const SupportedNetworks = [1, 5, 10, 31, 100, 122, 123, 137, 420, 2357, 5000, 10200, 20197, 42161, 80001, 84531, 421613, 11155111] export const NETWORK_NAME_TO_CHAIN_ID: { [key: string]: number; @@ -42,6 +43,7 @@ export const NETWORK_NAME_TO_CHAIN_ID: { [NetworkNames.OptimismGoerli]: 420, [NetworkNames.RSKTestnet]: 31, [NetworkNames.VerseTestnet]: 20197, + [NetworkNames.Mantle]: 5000, }; export const Networks: { @@ -52,7 +54,7 @@ export const Networks: { bundler: 'https://goerli-bundler.etherspot.io', contracts: { entryPoint: '0x5FF137D4b0FDCD49DcA30c7CF57E578a026d2789', - walletFactory: '0x2f771DCa6Ffa3879e48355E8A4aF5b81d82A6164', + walletFactory: '0x27f11918740060bd9Be146086F6836e18eedBB8C', }, paymaster: { use: false, @@ -64,7 +66,7 @@ export const Networks: { bundler: 'https://mumbai-bundler.etherspot.io', contracts: { entryPoint: '0x5FF137D4b0FDCD49DcA30c7CF57E578a026d2789', - walletFactory: '0x2f771DCa6Ffa3879e48355E8A4aF5b81d82A6164', + walletFactory: '0x27f11918740060bd9Be146086F6836e18eedBB8C', }, paymaster: { use: false, @@ -76,7 +78,7 @@ export const Networks: { bundler: 'https://basegoerli-bundler.etherspot.io', contracts: { entryPoint: '0x5FF137D4b0FDCD49DcA30c7CF57E578a026d2789', - walletFactory: '0x2f771DCa6Ffa3879e48355E8A4aF5b81d82A6164', + walletFactory: '0x27f11918740060bd9Be146086F6836e18eedBB8C', }, paymaster: { use: false, @@ -88,7 +90,7 @@ export const Networks: { bundler: 'https://sepolia-bundler.etherspot.io', contracts: { entryPoint: '0x5FF137D4b0FDCD49DcA30c7CF57E578a026d2789', - walletFactory: '0x2f771DCa6Ffa3879e48355E8A4aF5b81d82A6164', + walletFactory: '0x27f11918740060bd9Be146086F6836e18eedBB8C', }, paymaster: { use: false, @@ -100,7 +102,7 @@ export const Networks: { bundler: 'https://optimism-bundler.etherspot.io', contracts: { entryPoint: '0x5FF137D4b0FDCD49DcA30c7CF57E578a026d2789', - walletFactory: '0x2f771DCa6Ffa3879e48355E8A4aF5b81d82A6164', + walletFactory: '0x27f11918740060bd9Be146086F6836e18eedBB8C', }, paymaster: { use: false, @@ -112,7 +114,7 @@ export const Networks: { bundler: 'https://polygon-bundler.etherspot.io', contracts: { entryPoint: '0x5FF137D4b0FDCD49DcA30c7CF57E578a026d2789', - walletFactory: '0x2f771DCa6Ffa3879e48355E8A4aF5b81d82A6164', + walletFactory: '0x27f11918740060bd9Be146086F6836e18eedBB8C', }, paymaster: { use: false, @@ -124,7 +126,7 @@ export const Networks: { bundler: 'https://arbitrum-bundler.etherspot.io', contracts: { entryPoint: '0x5FF137D4b0FDCD49DcA30c7CF57E578a026d2789', - walletFactory: '0x2f771DCa6Ffa3879e48355E8A4aF5b81d82A6164', + walletFactory: '0x27f11918740060bd9Be146086F6836e18eedBB8C', }, paymaster: { use: false, @@ -136,7 +138,7 @@ export const Networks: { bundler: 'https://ethereum-bundler.etherspot.io/', contracts: { entryPoint: '0x5FF137D4b0FDCD49DcA30c7CF57E578a026d2789', - walletFactory: '0x2f771DCa6Ffa3879e48355E8A4aF5b81d82A6164', + walletFactory: '0x27f11918740060bd9Be146086F6836e18eedBB8C', }, paymaster: { use: false, @@ -148,7 +150,7 @@ export const Networks: { bundler: 'https://arbitrumgoerli-bundler.etherspot.io', contracts: { entryPoint: '0x5FF137D4b0FDCD49DcA30c7CF57E578a026d2789', - walletFactory: '0x2f771DCa6Ffa3879e48355E8A4aF5b81d82A6164', + walletFactory: '0x27f11918740060bd9Be146086F6836e18eedBB8C', }, paymaster: { use: false, @@ -160,7 +162,7 @@ export const Networks: { bundler: '', contracts: { entryPoint: '0x5FF137D4b0FDCD49DcA30c7CF57E578a026d2789', - walletFactory: '0x2f771DCa6Ffa3879e48355E8A4aF5b81d82A6164', + walletFactory: '0x27f11918740060bd9Be146086F6836e18eedBB8C', }, paymaster: { use: false, @@ -172,7 +174,7 @@ export const Networks: { bundler: 'https://fuse-bundler.etherspot.io', contracts: { entryPoint: '0x5FF137D4b0FDCD49DcA30c7CF57E578a026d2789', - walletFactory: '0x2f771DCa6Ffa3879e48355E8A4aF5b81d82A6164', + walletFactory: '0x27f11918740060bd9Be146086F6836e18eedBB8C', }, paymaster: { use: false, @@ -184,7 +186,7 @@ export const Networks: { bundler: '', contracts: { entryPoint: '0x5FF137D4b0FDCD49DcA30c7CF57E578a026d2789', - walletFactory: '0x2f771DCa6Ffa3879e48355E8A4aF5b81d82A6164', + walletFactory: '0x27f11918740060bd9Be146086F6836e18eedBB8C', }, paymaster: { use: false, @@ -196,7 +198,7 @@ export const Networks: { bundler: '', contracts: { entryPoint: '0x5FF137D4b0FDCD49DcA30c7CF57E578a026d2789', - walletFactory: '0x2f771DCa6Ffa3879e48355E8A4aF5b81d82A6164', + walletFactory: '0x27f11918740060bd9Be146086F6836e18eedBB8C', }, paymaster: { use: false, @@ -208,7 +210,7 @@ export const Networks: { bundler: '', contracts: { entryPoint: '0x5FF137D4b0FDCD49DcA30c7CF57E578a026d2789', - walletFactory: '0x2f771DCa6Ffa3879e48355E8A4aF5b81d82A6164', + walletFactory: '0x27f11918740060bd9Be146086F6836e18eedBB8C', }, paymaster: { use: false, @@ -220,7 +222,7 @@ export const Networks: { bundler: '', contracts: { entryPoint: '0x5FF137D4b0FDCD49DcA30c7CF57E578a026d2789', - walletFactory: '0x2f771DCa6Ffa3879e48355E8A4aF5b81d82A6164', + walletFactory: '0x27f11918740060bd9Be146086F6836e18eedBB8C', }, paymaster: { use: false, @@ -232,7 +234,7 @@ export const Networks: { bundler: '', contracts: { entryPoint: '0x5FF137D4b0FDCD49DcA30c7CF57E578a026d2789', - walletFactory: '0x2f771DCa6Ffa3879e48355E8A4aF5b81d82A6164', + walletFactory: '0x27f11918740060bd9Be146086F6836e18eedBB8C', }, paymaster: { use: false, @@ -244,7 +246,19 @@ export const Networks: { bundler: '', contracts: { entryPoint: '0x5FF137D4b0FDCD49DcA30c7CF57E578a026d2789', - walletFactory: '0x2f771DCa6Ffa3879e48355E8A4aF5b81d82A6164', + walletFactory: '0x27f11918740060bd9Be146086F6836e18eedBB8C', + }, + paymaster: { + use: false, + url: '', + }, + }, + [5000]: { + chainId: 5000, + bundler: 'https://mantle-bundler.etherspot.io/', + contracts: { + entryPoint: '0x5FF137D4b0FDCD49DcA30c7CF57E578a026d2789', + walletFactory: '0x27f11918740060bd9Be146086F6836e18eedBB8C', }, paymaster: { use: false, diff --git a/src/sdk/sdk.ts b/src/sdk/sdk.ts index cebc254e..3515268a 100644 --- a/src/sdk/sdk.ts +++ b/src/sdk/sdk.ts @@ -119,7 +119,7 @@ export class PrimeSdk { return this.etherspotWallet.getCounterFactualAddress(); } - async sign(gasDetails?: TransactionGasInfoForUserOp) { + async estimate(gasDetails?: TransactionGasInfoForUserOp) { const gas = await this.getGasFee(); if (this.userOpsBatch.to.length < 1){ @@ -133,7 +133,7 @@ export class PrimeSdk { ...gasDetails, } - let partialtx = await this.etherspotWallet.createSignedUserOp({ + let partialtx = await this.etherspotWallet.createUnsignedUserOp({ ...tx, ...gas, }); @@ -146,7 +146,7 @@ export class PrimeSdk { partialtx.callGasLimit = BigNumber.from(bundlerGasEstimate.callGasLimit); } - return await this.etherspotWallet.signUserOp(partialtx); + return partialtx; } @@ -155,7 +155,8 @@ export class PrimeSdk { } async send(userOp: UserOperationStruct) { - return this.bundler.sendUserOpToBundler(userOp); + const signedUserOp = await this.etherspotWallet.signUserOp(userOp); + return this.bundler.sendUserOpToBundler(signedUserOp); } async getNativeBalance() { @@ -177,21 +178,8 @@ export class PrimeSdk { return ethers.utils.formatUnits(balance[0], dec); } - async getUserOpReceipt(userOpHash: string, timeout = 60000, interval = 5000): Promise { - const block = await this.etherspotWallet.provider.getBlock('latest'); - const endtime = Date.now() + timeout; - while (Date.now() < endtime) { - const events = await this.etherspotWallet.epView.queryFilter( - this.etherspotWallet.epView.filters.UserOperationEvent(userOpHash), - Math.max(100, block.number - 100), - ); - if (events.length > 0) { - console.log(events[0].args.actualGasUsed.toString()); - return events[0].transactionHash; - } - await new Promise((resolve) => setTimeout(resolve, interval)); - } - return null; + async getUserOpReceipt(userOpHash: string) { + return this.bundler.getUserOpsReceipt(userOpHash); } async getUserOpHash(userOp: UserOperationStruct) { @@ -201,6 +189,7 @@ export class PrimeSdk { async addUserOpsToBatch( tx: UserOpsRequest, ): Promise { + if (!tx.data && !tx.value) throw new Error('Data and Value both cannot be empty'); this.userOpsBatch.to.push(tx.to); this.userOpsBatch.value.push(tx.value ?? BigNumber.from(0)); this.userOpsBatch.data.push(tx.data ?? '0x');