From 2c098f46f799cc459be5acd710598218c8cf5b22 Mon Sep 17 00:00:00 2001 From: Peter Anyaogu Date: Sat, 19 Oct 2024 17:57:37 +0100 Subject: [PATCH] gas optimization --- CHANGELOG.md | 6 ++ lib/src/4337/wallet.dart | 138 ++++++++++++++++++---------------- lib/src/common/factories.dart | 7 +- pubspec.yaml | 2 +- 4 files changed, 85 insertions(+), 68 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 6572704..21dadaa 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,9 @@ +## 0.1.6 + +* Remove repetated function call in safe plugin +* Split gas overrides individually +* Change point of gas override + ## 0.1.5 * improve gas fees estimation diff --git a/lib/src/4337/wallet.dart b/lib/src/4337/wallet.dart index 9a838ff..41336dc 100644 --- a/lib/src/4337/wallet.dart +++ b/lib/src/4337/wallet.dart @@ -85,61 +85,66 @@ class SmartWallet with _PluginManager, _GasSettings implements SmartWalletBase { UserOperation buildUserOperation({ required Uint8List callData, BigInt? customNonce, - }) => - UserOperation.partial( - callData: callData, - initCode: _initCode, - sender: _walletAddress, - nonce: customNonce); + }) { + return UserOperation.partial( + callData: callData, + initCode: _initCode, + sender: _walletAddress, + nonce: customNonce); + } @override Future send( - EthereumAddress recipient, EtherAmount amount) => - sendUserOperation(buildUserOperation( - callData: Contract.execute(_walletAddress, - to: recipient, amount: amount, isSafe: isSafe))); + EthereumAddress recipient, EtherAmount amount) { + final cd = Contract.execute(_walletAddress, + to: recipient, amount: amount, isSafe: isSafe); + return sendUserOperation(buildUserOperation(callData: cd)); + } @override Future sendTransaction( - EthereumAddress to, Uint8List encodedFunctionData, - {EtherAmount? amount}) => - sendUserOperation(buildUserOperation( - callData: Contract.execute(_walletAddress, - to: to, - amount: amount, - innerCallData: encodedFunctionData, - isSafe: isSafe))); + EthereumAddress to, Uint8List encodedFunctionData, + {EtherAmount? amount}) { + final cd = Contract.execute(_walletAddress, + to: to, + amount: amount, + innerCallData: encodedFunctionData, + isSafe: isSafe); + return sendUserOperation(buildUserOperation(callData: cd)); + } @override Future sendBatchedTransaction( List recipients, List calls, {List? amounts}) { + Uint8List cd; if (isSafe) { final innerCall = plugin<_SafePlugin>('safe') .getSafeMultisendCallData(recipients, amounts, calls); - return sendUserOperation(buildUserOperation( - callData: Contract.executeBatch( - walletAddress: _walletAddress, - recipients: [Constants.safeMultiSendaddress], - amounts: [], - innerCalls: [innerCall], - isSafe: true))); + cd = Contract.executeBatch( + walletAddress: _walletAddress, + recipients: [Constants.safeMultiSendaddress], + amounts: [], + innerCalls: [innerCall], + isSafe: true); + return sendUserOperation(buildUserOperation(callData: cd)); } else { - return sendUserOperation(buildUserOperation( - callData: Contract.executeBatch( - walletAddress: _walletAddress, - recipients: recipients, - amounts: amounts, - innerCalls: calls))); + cd = Contract.executeBatch( + walletAddress: _walletAddress, + recipients: recipients, + amounts: amounts, + innerCalls: calls); + return sendUserOperation(buildUserOperation(callData: cd)); } } @override - Future sendSignedUserOperation(UserOperation op) => - plugin('bundler') - .sendUserOperation( - op.toMap(_chain.entrypoint.version), _chain.entrypoint) - .catchError((e) => throw SendError(e.toString(), op)); + Future sendSignedUserOperation(UserOperation op) { + return plugin('bundler') + .sendUserOperation( + op.toMap(_chain.entrypoint.version), _chain.entrypoint) + .catchError((e) => throw SendError(e.toString(), op)); + } @override Future sendUserOperation(UserOperation op) => @@ -198,39 +203,41 @@ class SmartWallet with _PluginManager, _GasSettings implements SmartWalletBase { /// Otherwise, retrieves the nonce by calling the 'getNonce' function on the entrypoint. /// /// If an error occurs during the nonce retrieval process, a [NonceError] exception is thrown. - Future _getNonce() => isDeployed.then((deployed) => !deployed - ? Future.value(Uint256.zero) - : plugin("contract") - .read(_chain.entrypoint.address, ContractAbis.get('getNonce'), - "getNonce", - params: [_walletAddress, BigInt.zero]) - .then((value) => Uint256(value[0])) - .catchError((e) => throw NonceError(e.toString(), _walletAddress))); + Future _getNonce() { + return isDeployed.then((deployed) => !deployed + ? Future.value(Uint256.zero) + : plugin("contract") + .read(_chain.entrypoint.address, ContractAbis.get('getNonce'), + "getNonce", + params: [_walletAddress, BigInt.zero]) + .then((value) => Uint256(value[0])) + .catchError((e) => throw NonceError(e.toString(), _walletAddress))); + } /// Returns the balance for the Smart Wallet address. /// /// If an error occurs during the balance retrieval process, a [FetchBalanceError] exception is thrown. - Future _getBalance() => plugin("contract") - .getBalance(_walletAddress) - .catchError((e) => throw FetchBalanceError(e.toString(), _walletAddress)); + Future _getBalance() { + return plugin("contract").getBalance(_walletAddress).catchError( + (e) => throw FetchBalanceError(e.toString(), _walletAddress)); + } /// Updates the user operation with the latest nonce and gas prices. /// /// [op] is the user operation to update. /// /// Returns a [Future] that resolves to the updated [UserOperation] object. - Future _updateUserOperation(UserOperation op) => - Future.wait([ - _getNonce(), - plugin('jsonRpc').getGasPrice() - ]).then((responses) { - op = op.copyWith( - nonce: op.nonce > BigInt.zero ? op.nonce : responses[0].value, - initCode: responses[0] > Uint256.zero ? Uint8List(0) : null, - signature: dummySignature); - - return _updateUserOperationGas(op, responses[1]); - }); + Future _updateUserOperation(UserOperation op) async { + final responses = await Future.wait( + [_getNonce(), plugin('jsonRpc').getGasPrice()]); + + op = op.copyWith( + nonce: op.nonce > BigInt.zero ? op.nonce : responses[0].value, + initCode: responses[0] > Uint256.zero ? Uint8List(0) : null, + signature: dummySignature); + + return _updateUserOperationGas(op, responses[1]); + } /// Updates the gas information for the user operation. /// @@ -240,10 +247,11 @@ class SmartWallet with _PluginManager, _GasSettings implements SmartWalletBase { /// Returns a [Future] that resolves to the updated [UserOperation] object. /// /// If an error occurs during the gas estimation process, a [GasEstimationError] exception is thrown. - Future _updateUserOperationGas(UserOperation op, Fee fee) => - plugin('bundler') - .estimateUserOperationGas( - op.toMap(_chain.entrypoint.version), _chain.entrypoint) - .then((opGas) => op.updateOpGas(opGas, fee)) - .catchError((e) => throw GasEstimationError(e.toString(), op)); + Future _updateUserOperationGas(UserOperation op, Fee fee) { + return plugin('bundler') + .estimateUserOperationGas( + op.toMap(_chain.entrypoint.version), _chain.entrypoint) + .then((opGas) => op.updateOpGas(opGas, fee)) + .catchError((e) => throw GasEstimationError(e.toString(), op)); + } } diff --git a/lib/src/common/factories.dart b/lib/src/common/factories.dart index ec70cad..ac2b0bc 100644 --- a/lib/src/common/factories.dart +++ b/lib/src/common/factories.dart @@ -44,14 +44,17 @@ class _SafeProxyFactory extends SafeProxyFactory final setup = { "owners": owners.toList(), "threshold": BigInt.from(threshold), - "to": module.setup, - "data": encodeModuleSetup(), + "to": null, + "data": null, "fallbackHandler": module.address, }; if (encodeWebauthnSetup != null) { setup["to"] = Constants.safeMultiSendaddress; setup["data"] = encodeWebauthnSetup(encodeModuleSetup); + } else { + setup["to"] = module.setup; + setup["data"] = encodeModuleSetup(); } return Contract.encodeFunctionCall( diff --git a/pubspec.yaml b/pubspec.yaml index c455f1e..3a89b36 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -1,6 +1,6 @@ name: variance_dart description: An Account Abstraction (4337) Development kit, for quickly building mobile web3 apps and smart wallets. -version: 0.1.5 +version: 0.1.6 documentation: https://docs.variance.space homepage: https://variance.space repository: https://github.com/vaariance/variance-dart