Skip to content

Commit 707023c

Browse files
committed
fix gas fee errors
1 parent 1229fde commit 707023c

File tree

14 files changed

+69
-114
lines changed

14 files changed

+69
-114
lines changed

CHANGELOG.md

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,11 @@
1+
## 0.1.5
2+
3+
* improve gas fees estimation
4+
* reduce copywith trigger in gas settings
5+
* change position of custom gas overrides to post sponsor useroperation
6+
* default to p256 precompile over contract verifiers.
7+
* revert to direct balance checking
8+
19
## 0.1.4
210

311
* add surpport for web3_signers v0.1+

example/lib/providers/wallet_provider.dart

Lines changed: 14 additions & 37 deletions
Original file line numberDiff line numberDiff line change
@@ -23,8 +23,7 @@ class WalletProvider extends ChangeNotifier {
2323
EthereumAddress.fromHex("0xf5bb7f874d8e3f41821175c0aa9910d30d10e193");
2424

2525
final salt = Uint256.zero;
26-
static const rpc =
27-
"https://api.pimlico.io/v2/84532/rpc?apikey=pim_NuuL4a9tBdyfoogF5LtP5A";
26+
static const rpc = "https://api.pimlico.io/v2/84532/rpc?apikey=API_KEY";
2827

2928
WalletProvider()
3029
: _chain = Chains.getChain(Network.baseTestnet)
@@ -67,8 +66,6 @@ class WalletProvider extends ChangeNotifier {
6766
Future<void> createEOAWallet() async {
6867
final signer = EOAWallet.createWallet(
6968
WordLength.word_12, const SignatureOptions(prefix: [0]));
70-
log("signer: ${signer.getAddress()}");
71-
7269
final SmartWalletFactory walletFactory = SmartWalletFactory(_chain, signer);
7370

7471
try {
@@ -87,14 +84,11 @@ class WalletProvider extends ChangeNotifier {
8784

8885
final signer = PrivateKeySigner.create(privateKey, "123456", random,
8986
options: const SignatureOptions(prefix: [0]));
90-
log("signer: ${signer.getAddress()}");
91-
log("pk: ${hexlify(privateKey.privateKey)}");
92-
9387
final SmartWalletFactory walletFactory = SmartWalletFactory(_chain, signer);
9488

9589
try {
9690
_wallet = await walletFactory.createAlchemyLightAccount(salt);
97-
log("pk wallet created ${_wallet?.address.hex} ");
91+
log("wallet created ${_wallet?.address.hex} ");
9892
} catch (e) {
9993
_errorMessage = e.toString();
10094
notifyListeners();
@@ -106,40 +100,26 @@ class WalletProvider extends ChangeNotifier {
106100
_chain.accountFactory = Constants.safeProxyFactoryAddress;
107101

108102
final signer = EOAWallet.createWallet();
109-
log("signer: ${signer.getAddress()}");
110-
111103
final SmartWalletFactory walletFactory = SmartWalletFactory(_chain, signer);
112104

113105
try {
114106
_wallet = await walletFactory.createSafeAccount(salt);
115-
log("safe created ${_wallet?.address.hex} ");
107+
log("wallet created ${_wallet?.address.hex} ");
116108
} catch (e) {
117109
log("something happened: $e");
118110
}
119111
}
120112

121113
Future<void> mintNFt() async {
122-
// pimlico requires us to get the gasfees from their bundler.
123-
// that cannot be built into the sdk so we modify the internal fees manually
124-
if (_chain.entrypoint.version == 0.7) {
125-
_wallet?.gasSettings = GasSettings(
126-
gasMultiplierPercentage: 5,
127-
userDefinedMaxFeePerGas: BigInt.parse("0x524e1909"),
128-
userDefinedMaxPriorityFeePerGas: BigInt.parse("0x52412100"));
129-
}
130-
// mints nft
131-
log(DateTime.timestamp().toString());
114+
// simple tx
132115
final tx1 = await _wallet?.sendTransaction(
133116
nft,
134117
Contract.encodeFunctionCall("safeMint", nft,
135118
ContractAbis.get("ERC721_SafeMint"), [_wallet?.address]));
136119
await tx1?.wait();
137120

138-
await sendBatchedTransaction();
139-
}
140-
141-
Future<void> sendBatchedTransaction() async {
142-
final tx = await _wallet?.sendBatchedTransaction([
121+
// batch tx
122+
final tx2 = await _wallet?.sendBatchedTransaction([
143123
erc20,
144124
erc20
145125
], [
@@ -152,21 +132,18 @@ class WalletProvider extends ChangeNotifier {
152132
erc20, deployer, w3d.EtherAmount.fromInt(w3d.EtherUnit.ether, 20))
153133
]);
154134

155-
await tx?.wait();
135+
await tx2?.wait();
156136
}
157137

158138
Future<void> sendTransaction(String recipient, String amount) async {
159-
if (_wallet != null) {
160-
final etherAmount = w3d.EtherAmount.fromBigInt(w3d.EtherUnit.wei,
161-
BigInt.from(double.parse(amount) * math.pow(10, 18)));
139+
final etherAmount = w3d.EtherAmount.fromBigInt(w3d.EtherUnit.wei,
140+
BigInt.from(double.parse(amount) * math.pow(10, 18)));
162141

163-
final response =
164-
await _wallet?.send(EthereumAddress.fromHex(recipient), etherAmount);
165-
final receipt = await response?.wait();
142+
final response = await _wallet?.send(
143+
EthereumAddress.fromHex("0xF5bB7F874D8e3f41821175c0Aa9910d30d10e193"),
144+
etherAmount);
145+
final receipt = await response?.wait();
166146

167-
log("Transaction receipt Hash: ${receipt?.userOpHash}");
168-
} else {
169-
log("No wallet available to send transaction");
170-
}
147+
log("Transaction receipt Hash: ${receipt?.userOpHash}");
171148
}
172149
}

example/lib/screens/home/home_widgets.dart

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,6 @@ import 'dart:async';
33
import 'package:flutter/material.dart';
44
import 'dart:ui' as ui;
55
import 'package:flutter/services.dart';
6-
import 'package:flutter/widgets.dart';
76
import 'package:flutter_screenutil/flutter_screenutil.dart';
87
import 'package:provider/provider.dart';
98
import 'package:qr_flutter/qr_flutter.dart';

lib/src/4337/providers.dart

Lines changed: 16 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -100,38 +100,26 @@ class JsonRPCProvider implements JsonRPCProviderBase {
100100
}
101101

102102
@override
103-
Future<Map<String, EtherAmount>> getEip1559GasPrice() async {
104-
final fee = await rpc.send<String>("eth_maxPriorityFeePerGas");
105-
final tip = Uint256.fromHex(fee);
106-
final mul = Uint256(BigInt.from(100 * 13));
107-
final buffer = tip / mul;
108-
final maxPriorityFeePerGas = tip + buffer;
109-
final maxFeePerGas = maxPriorityFeePerGas;
110-
return {
111-
'maxFeePerGas': EtherAmount.fromBigInt(EtherUnit.wei, maxFeePerGas.value),
112-
'maxPriorityFeePerGas':
113-
EtherAmount.fromBigInt(EtherUnit.wei, maxPriorityFeePerGas.value)
114-
};
115-
}
116-
117-
@override
118-
Future<Map<String, EtherAmount>> getGasPrice() async {
103+
Future<Fee> getGasPrice([GasEstimation rate = GasEstimation.normal]) async {
119104
try {
120-
return await getEip1559GasPrice();
105+
final [low, medium, high] = await getGasInEIP1559(rpc.url);
106+
switch (rate) {
107+
case GasEstimation.low:
108+
return low;
109+
case GasEstimation.normal:
110+
return medium;
111+
case GasEstimation.high:
112+
return high;
113+
}
121114
} catch (e) {
122-
final value = await getLegacyGasPrice();
123-
return {
124-
'maxFeePerGas': value,
125-
'maxPriorityFeePerGas': value,
126-
};
115+
final data = await rpc.send<String>('eth_gasPrice');
116+
final gasPrice = hexToInt(data);
117+
return Fee(
118+
maxPriorityFeePerGas: gasPrice,
119+
maxFeePerGas: gasPrice,
120+
estimatedGas: gasPrice);
127121
}
128122
}
129-
130-
@override
131-
Future<EtherAmount> getLegacyGasPrice() async {
132-
final data = await rpc.send<String>('eth_gasPrice');
133-
return EtherAmount.fromBigInt(EtherUnit.wei, hexToInt(data));
134-
}
135123
}
136124

137125
class RPCBase extends JsonRPC {

lib/src/4337/userop.dart

Lines changed: 3 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -252,15 +252,13 @@ class UserOperation implements UserOperationBase {
252252
}
253253

254254
@override
255-
UserOperation updateOpGas(
256-
UserOperationGas? opGas, Map<String, dynamic>? feePerGas) {
255+
UserOperation updateOpGas([UserOperationGas? opGas, Fee? fee]) {
257256
return copyWith(
258257
callGasLimit: opGas?.callGasLimit,
259258
verificationGasLimit: opGas?.verificationGasLimit,
260259
preVerificationGas: opGas?.preVerificationGas,
261-
maxFeePerGas: (feePerGas?["maxFeePerGas"] as EtherAmount?)?.getInWei,
262-
maxPriorityFeePerGas:
263-
(feePerGas?["maxPriorityFeePerGas"] as EtherAmount?)?.getInWei,
260+
maxFeePerGas: fee?.maxFeePerGas,
261+
maxPriorityFeePerGas: fee?.maxPriorityFeePerGas,
264262
);
265263
}
266264

lib/src/4337/wallet.dart

Lines changed: 7 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -158,6 +158,7 @@ class SmartWallet with _PluginManager, _GasSettings implements SmartWalletBase {
158158
op = await plugin<Paymaster>('paymaster').intercept(op);
159159
}
160160

161+
op = applyCustomGasSettings(op);
161162
// Validate the user operation
162163
op.validate(op.nonce > BigInt.zero, initCode);
163164

@@ -209,14 +210,11 @@ class SmartWallet with _PluginManager, _GasSettings implements SmartWalletBase {
209210
.then((value) => Uint256(value[0]))
210211
.catchError((e) => throw NonceError(e.toString(), _walletAddress)));
211212

212-
/// Returns the balance for the Smart Wallet address from the entrypoint.
213+
/// Returns the balance for the Smart Wallet address.
213214
///
214215
/// If an error occurs during the balance retrieval process, a [FetchBalanceError] exception is thrown.
215216
Future<EtherAmount> _getBalance() => plugin<Contract>("contract")
216-
.read(_chain.entrypoint.address, ContractAbis.get('getBalance'),
217-
"balanceOf",
218-
params: [_walletAddress])
219-
.then((value) => EtherAmount.fromBigInt(EtherUnit.wei, value[0]))
217+
.getBalance(_walletAddress)
220218
.catchError((e) => throw FetchBalanceError(e.toString(), _walletAddress));
221219

222220
/// Updates the user operation with the latest nonce and gas prices.
@@ -234,23 +232,21 @@ class SmartWallet with _PluginManager, _GasSettings implements SmartWalletBase {
234232
initCode: responses[0] > Uint256.zero ? Uint8List(0) : null,
235233
signature: dummySignature);
236234

237-
return _updateUserOperationGas(op, feePerGas: responses[1]);
235+
return _updateUserOperationGas(op, responses[1]);
238236
});
239237

240238
/// Updates the gas information for the user operation.
241239
///
242240
/// [op] is the user operation to update.
243-
/// [feePerGas] is an optional map containing the gas prices.
241+
/// [fee] is an optional Fee containing the gas prices.
244242
///
245243
/// Returns a [Future] that resolves to the updated [UserOperation] object.
246244
///
247245
/// If an error occurs during the gas estimation process, a [GasEstimationError] exception is thrown.
248-
Future<UserOperation> _updateUserOperationGas(UserOperation op,
249-
{Map<String, EtherAmount>? feePerGas}) =>
246+
Future<UserOperation> _updateUserOperationGas(UserOperation op, Fee fee) =>
250247
plugin<BundlerProviderBase>('bundler')
251248
.estimateUserOperationGas(
252249
op.toMap(_chain.entrypoint.version), _chain.entrypoint)
253-
.then((opGas) => op.updateOpGas(opGas, feePerGas))
254-
.then((op) => applyCustomGasSettings(op))
250+
.then((opGas) => op.updateOpGas(opGas, fee))
255251
.catchError((e) => throw GasEstimationError(e.toString(), op));
256252
}

lib/src/common/constants.dart

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,7 @@ class Constants {
2828
static final EthereumAddress safeMultiSendaddress =
2929
EthereumAddress.fromHex("0x38869bf66a61cF6bDB996A6aE40D5853Fd43B526");
3030
static final EthereumAddress p256VerifierAddress =
31-
EthereumAddress.fromHex("0x445a0683e494ea0c5AF3E83c5159fBE47Cf9e765");
31+
EthereumAddress.fromHex("0x0000000000000000000000000000000000000100");
3232

3333
Constants._();
3434
}

lib/src/common/mixins.dart

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -51,6 +51,8 @@ mixin _GasSettings {
5151
UserOperation applyCustomGasSettings(UserOperation op) {
5252
final multiplier = _gasParams.gasMultiplierPercentage / 100 + 1;
5353

54+
if (multiplier == 1) return op;
55+
5456
return op.copyWith(
5557
callGasLimit: BigInt.from(op.callGasLimit.toDouble() * multiplier),
5658
verificationGasLimit:

lib/src/interfaces/interfaces.dart

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
import 'dart:typed_data';
22

3+
import 'package:eip1559/eip1559.dart';
34
import 'package:web3_signers/web3_signers.dart' show PassKeyPair, Uint256;
45
import 'package:web3dart/web3dart.dart';
56

lib/src/interfaces/json_rpc_provider.dart

Lines changed: 11 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,15 @@
11
part of 'interfaces.dart';
22

3+
enum GasEstimation {
4+
low(rate: 0),
5+
normal(rate: 1),
6+
high(rate: 2);
7+
8+
final int rate;
9+
10+
const GasEstimation({required this.rate});
11+
}
12+
313
/// Abstract base class for interacting with an Bundler RPC provider.
414
///
515
/// Implementations of this class are expected to provide functionality for specifically interacting
@@ -59,18 +69,6 @@ abstract class JsonRPCProviderBase {
5969
bool isContainFullObj = true,
6070
});
6171

62-
/// Asynchronously retrieves the EIP-1559 gas prices, including `maxFeePerGas` and `maxPriorityFeePerGas`.
63-
///
64-
/// Returns:
65-
/// A [Future] that completes with a [Map] containing the gas prices in [EtherAmount].
66-
///
67-
/// Example:
68-
/// ```dart
69-
/// var gasPrices = await getEip1559GasPrice();
70-
/// ```
71-
/// This method uses an ethereum jsonRPC to fetch EIP-1559 gas prices from the Ethereum node.
72-
Future<Map<String, EtherAmount>> getEip1559GasPrice();
73-
7472
/// Asynchronously retrieves the gas prices, supporting both EIP-1559 and legacy gas models.
7573
///
7674
/// Returns:
@@ -81,17 +79,5 @@ abstract class JsonRPCProviderBase {
8179
/// var gasPrices = await getGasPrice();
8280
/// ```
8381
/// This method first attempts to fetch EIP-1559 gas prices and falls back to legacy gas prices if it fails.
84-
Future<Map<String, EtherAmount>> getGasPrice();
85-
86-
/// Asynchronously retrieves the legacy gas price from the Ethereum node.
87-
///
88-
/// Returns:
89-
/// A [Future] that completes with an [EtherAmount] representing the legacy gas price in [Wei].
90-
///
91-
/// Example:
92-
/// ```dart
93-
/// var legacyGasPrice = await getLegacyGasPrice();
94-
/// ```
95-
/// This method uses an ethereum jsonRPC to fetch the legacy gas price from the Ethereum node.
96-
Future<EtherAmount> getLegacyGasPrice();
82+
Future<Fee> getGasPrice([GasEstimation rate = GasEstimation.normal]);
9783
}

lib/src/interfaces/user_operations.dart

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -71,7 +71,7 @@ abstract class UserOperationBase {
7171
///
7272
/// Parameters:
7373
/// - `opGas`: Optional parameter of type [UserOperationGas] for specifying gas-related information.
74-
/// - `feePerGas`: Optional parameter of type [Map<String, EtherAmount>] for specifying maxFeePerGas and maxPriorityFeePerGas.
74+
/// - `fee`: Optional parameter of type [Fee] for specifying maxFeePerGas and maxPriorityFeePerGas.
7575
///
7676
/// Returns:
7777
/// A [UserOperation] instance created from the provided map.
@@ -85,8 +85,7 @@ abstract class UserOperationBase {
8585
/// // Other parameters can be updated as needed.
8686
/// );
8787
/// ```
88-
UserOperation updateOpGas(
89-
UserOperationGas? opGas, Map<String, EtherAmount>? feePerGas);
88+
UserOperation updateOpGas([UserOperationGas? opGas, Fee? fee]);
9089

9190
/// Validates the user operation fields for accuracy
9291
///

lib/variance_dart.dart

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ import 'dart:async';
44
import 'dart:convert';
55
import 'dart:typed_data';
66

7+
import 'package:eip1559/eip1559.dart';
78
import 'package:http/http.dart' as http;
89
import 'package:web3_signers/web3_signers.dart';
910
import 'package:web3dart/crypto.dart';
@@ -13,7 +14,6 @@ import 'package:web3dart/web3dart.dart';
1314
import 'src/abis/abis.dart';
1415
import 'src/interfaces/interfaces.dart';
1516

16-
export 'package:web3_signers/web3_signers.dart' show Logger;
1717
export 'src/abis/abis.dart' show ContractAbis;
1818

1919
part 'src/4337/chains.dart';

pubspec.lock

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -178,7 +178,7 @@ packages:
178178
source: hosted
179179
version: "2.3.6"
180180
eip1559:
181-
dependency: transitive
181+
dependency: "direct main"
182182
description:
183183
name: eip1559
184184
sha256: c2b81ac85f3e0e71aaf558201dd9a4600f051ece7ebacd0c5d70065c9b458004

pubspec.yaml

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
name: variance_dart
22
description: An Account Abstraction (4337) Development kit, for quickly building mobile web3 apps and smart wallets.
3-
version: 0.1.4
3+
version: 0.1.5
44
documentation: https://docs.variance.space
55
homepage: https://variance.space
66
repository: https://github.com/vaariance/variance-dart
@@ -19,6 +19,7 @@ dependencies:
1919
web3dart: ^2.7.3
2020
http: ^1.2.0
2121
web3_signers: ^0.1.6
22+
eip1559: ^0.6.2
2223

2324
dev_dependencies:
2425
web3dart_builders: ^0.1.2

0 commit comments

Comments
 (0)