Skip to content

Commit 2726e5c

Browse files
authored
Migrate all paths to bundler v2 (#81)
1 parent d24a886 commit 2726e5c

File tree

3 files changed

+59
-62
lines changed

3 files changed

+59
-62
lines changed

Thirdweb.Console/Program.cs

Lines changed: 15 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -37,7 +37,13 @@
3737

3838
#region AA 0.6
3939

40-
// var smartWallet06 = await SmartWallet.Create(personalWallet: privateKeyWallet, chainId: 421614, gasless: true, entryPoint: Constants.ENTRYPOINT_ADDRESS_V06);
40+
// var smartWallet06 = await SmartWallet.Create(
41+
// personalWallet: privateKeyWallet,
42+
// chainId: 421614,
43+
// gasless: true,
44+
// factoryAddress: "0xa8deE7854fb1eA8c13b713585C81d91ea86dAD84",
45+
// entryPoint: Constants.ENTRYPOINT_ADDRESS_V06
46+
// );
4147

4248
// var receipt06 = await smartWallet06.ExecuteTransaction(new ThirdwebTransactionInput(chainId: 421614, to: await smartWallet06.GetAddress(), value: 0, data: "0x"));
4349

@@ -47,7 +53,13 @@
4753

4854
#region AA 0.7
4955

50-
// var smartWallet07 = await SmartWallet.Create(personalWallet: privateKeyWallet, chainId: 421614, gasless: true, entryPoint: Constants.ENTRYPOINT_ADDRESS_V07);
56+
// var smartWallet07 = await SmartWallet.Create(
57+
// personalWallet: privateKeyWallet,
58+
// chainId: 421614,
59+
// gasless: true,
60+
// factoryAddress: "0x4f4e40E8F66e3Cc0FD7423E2fbd62A769ff551FB",
61+
// entryPoint: Constants.ENTRYPOINT_ADDRESS_V07
62+
// );
5163

5264
// var receipt07 = await smartWallet07.ExecuteTransaction(new ThirdwebTransactionInput(chainId: 421614, to: await smartWallet07.GetAddress(), value: 0, data: "0x"));
5365

@@ -273,11 +285,7 @@
273285
// var erc20SmartWalletAddress = await erc20SmartWallet.GetAddress();
274286
// Console.WriteLine($"ERC20 Smart Wallet address: {erc20SmartWalletAddress}");
275287

276-
// var selfTransfer = await ThirdwebTransaction.Create(
277-
// wallet: erc20SmartWallet,
278-
// txInput: new ThirdwebTransactionInput() { To = erc20SmartWalletAddress, },
279-
// chainId: 8453
280-
// );
288+
// var selfTransfer = await ThirdwebTransaction.Create(wallet: erc20SmartWallet, txInput: new ThirdwebTransactionInput(chainId: 8453, to: erc20SmartWalletAddress, value: 0, data: "0x"));
281289

282290
// var estimateGas = await ThirdwebTransaction.EstimateGasCosts(selfTransfer);
283291
// Console.WriteLine($"Self transfer gas estimate: {estimateGas.Ether}");

Thirdweb/Thirdweb.Wallets/SmartWallet/SmartWallet.cs

Lines changed: 42 additions & 38 deletions
Original file line numberDiff line numberDiff line change
@@ -66,7 +66,7 @@ private struct TokenPaymasterConfig
6666
new TokenPaymasterConfig()
6767
{
6868
ChainId = 8453,
69-
PaymasterAddress = "0x0c6199eE133EB4ff8a6bbD03370336C5A5d9D536",
69+
PaymasterAddress = "0xff4d12b1f8d276aa4a9e8cc80539e806791bfe28",
7070
TokenAddress = "0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913",
7171
BalanceStorageSlot = 9
7272
}
@@ -125,8 +125,8 @@ public static async Task<SmartWallet> Create(
125125

126126
var entryPointVersion = Utils.GetEntryPointVersion(entryPoint);
127127

128-
bundlerUrl ??= entryPointVersion == 6 ? $"https://{chainId}.bundler.thirdweb.com" : $"https://{chainId}.bundler.thirdweb.com/v2";
129-
paymasterUrl ??= entryPointVersion == 6 ? $"https://{chainId}.bundler.thirdweb.com" : $"https://{chainId}.bundler.thirdweb.com/v2";
128+
bundlerUrl ??= $"https://{chainId}.bundler.thirdweb.com/v2";
129+
paymasterUrl ??= $"https://{chainId}.bundler.thirdweb.com/v2";
130130
factoryAddress ??= entryPointVersion == 6 ? Constants.DEFAULT_FACTORY_ADDRESS_V06 : Constants.DEFAULT_FACTORY_ADDRESS_V07;
131131

132132
ThirdwebContract entryPointContract = null;
@@ -160,9 +160,6 @@ public static async Task<SmartWallet> Create(
160160
{
161161
throw new InvalidOperationException("Token paymaster chain ID does not match the smart account chain ID.");
162162
}
163-
164-
// TODO: Re-enable token paymasters
165-
throw new InvalidOperationException("Token paymasters are currently disabled.");
166163
}
167164

168165
return new SmartWallet(
@@ -199,9 +196,8 @@ public async Task SwitchNetwork(BigInteger chainId)
199196

200197
this._chainId = chainId;
201198

202-
var entryPointVersion = Utils.GetEntryPointVersion(this._entryPointContract?.Address);
203-
this._bundlerUrl = entryPointVersion == 6 ? $"https://{chainId}.bundler.thirdweb.com" : $"https://{chainId}.bundler.thirdweb.com/v2";
204-
this._paymasterUrl = entryPointVersion == 6 ? $"https://{chainId}.bundler.thirdweb.com" : $"https://{chainId}.bundler.thirdweb.com/v2";
199+
this._bundlerUrl = this._bundlerUrl.Contains(".thirdweb.com") ? $"https://{chainId}.bundler.thirdweb.com/v2" : this._bundlerUrl;
200+
this._paymasterUrl = this._paymasterUrl.Contains(".thirdweb.com") ? $"https://{chainId}.bundler.thirdweb.com/v2" : this._paymasterUrl;
205201
if (!Utils.IsZkSync(chainId))
206202
{
207203
this._entryPointContract = await ThirdwebContract.Create(this.Client, this._entryPointContract.Address, chainId, this._entryPointContract.Abi).ConfigureAwait(false);
@@ -314,6 +310,7 @@ private async Task<object> SignUserOp(ThirdwebTransactionInput transactionInput,
314310
_ = await tokenContract.ERC20_Approve(this, this._erc20PaymasterAddress, BigInteger.Pow(2, 96) - 1).ConfigureAwait(false);
315311
}
316312
this._isApproved = true;
313+
await ThirdwebTask.Delay(1000).ConfigureAwait(false);
317314
(initCode, factory, factoryData) = await this.GetInitCode().ConfigureAwait(false);
318315
}
319316
catch (Exception e)
@@ -370,7 +367,7 @@ private async Task<object> SignUserOp(ThirdwebTransactionInput transactionInput,
370367
Nonce = await this.GetNonce().ConfigureAwait(false),
371368
InitCode = initCode,
372369
CallData = executeInput.Data.HexToBytes(),
373-
CallGasLimit = 0,
370+
CallGasLimit = transactionInput.Gas == null ? 0 : 21000 + transactionInput.Gas.Value,
374371
VerificationGasLimit = 0,
375372
PreVerificationGas = 0,
376373
MaxFeePerGas = maxFee,
@@ -379,20 +376,24 @@ private async Task<object> SignUserOp(ThirdwebTransactionInput transactionInput,
379376
Signature = Constants.DUMMY_SIG.HexToBytes(),
380377
};
381378

382-
// Update paymaster data if any
383-
384-
partialUserOp.PaymasterAndData = (await this.GetPaymasterAndData(requestId, EncodeUserOperation(partialUserOp), simulation).ConfigureAwait(false)).PaymasterAndData.HexToBytes();
379+
// Update paymaster data and gas
385380

386-
// Estimate gas
381+
var pmSponsorResult = await this.GetPaymasterAndData(requestId, EncodeUserOperation(partialUserOp), simulation).ConfigureAwait(false);
382+
partialUserOp.PaymasterAndData = pmSponsorResult.PaymasterAndData.HexToBytes();
387383

388-
var gasEstimates = await BundlerClient.EthEstimateUserOperationGas(this.Client, this._bundlerUrl, requestId, EncodeUserOperation(partialUserOp), this._entryPointContract.Address);
389-
partialUserOp.CallGasLimit = Math.Max((long)(50000 + new HexBigInteger(gasEstimates.CallGasLimit).Value), (long?)transactionInput.Gas?.Value ?? 0);
390-
partialUserOp.VerificationGasLimit = new HexBigInteger(gasEstimates.VerificationGasLimit).Value;
391-
partialUserOp.PreVerificationGas = new HexBigInteger(gasEstimates.PreVerificationGas).Value;
392-
393-
// Update paymaster data if any
394-
395-
partialUserOp.PaymasterAndData = (await this.GetPaymasterAndData(requestId, EncodeUserOperation(partialUserOp), simulation).ConfigureAwait(false)).PaymasterAndData.HexToBytes();
384+
if (pmSponsorResult.VerificationGasLimit == null || pmSponsorResult.PreVerificationGas == null)
385+
{
386+
var gasEstimates = await BundlerClient.EthEstimateUserOperationGas(this.Client, this._bundlerUrl, requestId, EncodeUserOperation(partialUserOp), this._entryPointContract.Address);
387+
partialUserOp.CallGasLimit = new HexBigInteger(gasEstimates.CallGasLimit).Value;
388+
partialUserOp.VerificationGasLimit = new HexBigInteger(gasEstimates.VerificationGasLimit).Value;
389+
partialUserOp.PreVerificationGas = new HexBigInteger(gasEstimates.PreVerificationGas).Value;
390+
}
391+
else
392+
{
393+
partialUserOp.CallGasLimit = new HexBigInteger(pmSponsorResult.CallGasLimit).Value;
394+
partialUserOp.VerificationGasLimit = new HexBigInteger(pmSponsorResult.VerificationGasLimit).Value;
395+
partialUserOp.PreVerificationGas = new HexBigInteger(pmSponsorResult.PreVerificationGas).Value;
396+
}
396397

397398
// Hash, sign and encode the user operation
398399

@@ -435,6 +436,12 @@ private async Task<object> SignUserOp(ThirdwebTransactionInput transactionInput,
435436

436437
// Update Paymaster Data / Estimate gas
437438

439+
var pmSponsorResult = await this.GetPaymasterAndData(requestId, EncodeUserOperation(partialUserOp), simulation).ConfigureAwait(false);
440+
partialUserOp.Paymaster = pmSponsorResult.Paymaster;
441+
partialUserOp.PaymasterData = pmSponsorResult.PaymasterData?.HexToBytes() ?? Array.Empty<byte>();
442+
443+
Dictionary<string, object> stateDict = null;
444+
438445
if (this.UseERC20Paymaster && !this._isApproving)
439446
{
440447
var abiEncoder = new ABIEncode();
@@ -444,31 +451,28 @@ private async Task<object> SignUserOp(ThirdwebTransactionInput transactionInput,
444451
{
445452
{ new Sha3Keccack().CalculateHash(slotBytes).BytesToHex().ToString(), desiredBalance.ToHexBigInteger().HexValue.HexToBytes32().BytesToHex() }
446453
};
447-
var stateDict = new Dictionary<string, object> { { this._erc20PaymasterToken, new { stateDiff = storageDict } } };
448-
var res = await this.GetPaymasterAndData(requestId, EncodeUserOperation(partialUserOp), simulation).ConfigureAwait(false);
449-
partialUserOp.Paymaster = res.Paymaster;
450-
partialUserOp.PaymasterData = res.PaymasterData.HexToBytes();
454+
stateDict = new Dictionary<string, object> { { this._erc20PaymasterToken, new { stateDiff = storageDict } } };
455+
}
456+
else
457+
{
458+
partialUserOp.PreVerificationGas = new HexBigInteger(pmSponsorResult.PreVerificationGas ?? "0x0").Value;
459+
partialUserOp.VerificationGasLimit = new HexBigInteger(pmSponsorResult.VerificationGasLimit ?? "0x0").Value;
460+
partialUserOp.CallGasLimit = new HexBigInteger(pmSponsorResult.CallGasLimit ?? "0x0").Value;
461+
partialUserOp.PaymasterVerificationGasLimit = new HexBigInteger(pmSponsorResult.PaymasterVerificationGasLimit ?? "0x0").Value;
462+
partialUserOp.PaymasterPostOpGasLimit = new HexBigInteger(pmSponsorResult.PaymasterPostOpGasLimit ?? "0x0").Value;
463+
}
451464

465+
if (partialUserOp.PreVerificationGas == 0 || partialUserOp.VerificationGasLimit == 0)
466+
{
452467
var gasEstimates = await BundlerClient
453468
.EthEstimateUserOperationGas(this.Client, this._bundlerUrl, requestId, EncodeUserOperation(partialUserOp), this._entryPointContract.Address, stateDict)
454469
.ConfigureAwait(false);
455-
partialUserOp.CallGasLimit = 21000 + new HexBigInteger(gasEstimates.CallGasLimit).Value;
470+
partialUserOp.CallGasLimit = new HexBigInteger(gasEstimates.CallGasLimit).Value;
456471
partialUserOp.VerificationGasLimit = new HexBigInteger(gasEstimates.VerificationGasLimit).Value;
457472
partialUserOp.PreVerificationGas = new HexBigInteger(gasEstimates.PreVerificationGas).Value;
458473
partialUserOp.PaymasterVerificationGasLimit = new HexBigInteger(gasEstimates.PaymasterVerificationGasLimit).Value;
459474
partialUserOp.PaymasterPostOpGasLimit = new HexBigInteger(gasEstimates.PaymasterPostOpGasLimit).Value;
460475
}
461-
else
462-
{
463-
var res = await this.GetPaymasterAndData(requestId, EncodeUserOperation(partialUserOp), simulation).ConfigureAwait(false);
464-
partialUserOp.Paymaster = res.Paymaster;
465-
partialUserOp.PaymasterData = res.PaymasterData?.HexToBytes() ?? Array.Empty<byte>();
466-
partialUserOp.PreVerificationGas = new HexBigInteger(res.PreVerificationGas ?? "0x0").Value;
467-
partialUserOp.VerificationGasLimit = new HexBigInteger(res.VerificationGasLimit ?? "0x0").Value;
468-
partialUserOp.CallGasLimit = new HexBigInteger(res.CallGasLimit ?? "0x0").Value;
469-
partialUserOp.PaymasterVerificationGasLimit = new HexBigInteger(res.PaymasterVerificationGasLimit ?? "0x0").Value;
470-
partialUserOp.PaymasterPostOpGasLimit = new HexBigInteger(res.PaymasterPostOpGasLimit ?? "0x0").Value;
471-
}
472476

473477
// Hash, sign and encode the user operation
474478

Thirdweb/Thirdweb.Wallets/SmartWallet/Thirdweb.AccountAbstraction/BundlerClient.cs

Lines changed: 2 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -42,23 +42,8 @@ public static async Task<ThirdwebGetUserOperationGasPriceResponse> ThirdwebGetUs
4242

4343
public static async Task<PMSponsorOperationResponse> PMSponsorUserOperation(ThirdwebClient client, string paymasterUrl, object requestId, object userOp, string entryPoint)
4444
{
45-
var response = await BundlerRequest(
46-
client,
47-
paymasterUrl,
48-
requestId,
49-
"pm_sponsorUserOperation",
50-
userOp,
51-
entryPoint == Constants.ENTRYPOINT_ADDRESS_V06 ? new EntryPointWrapper() { EntryPoint = entryPoint } : entryPoint
52-
)
53-
.ConfigureAwait(false);
54-
try
55-
{
56-
return JsonConvert.DeserializeObject<PMSponsorOperationResponse>(response.Result.ToString());
57-
}
58-
catch
59-
{
60-
return new PMSponsorOperationResponse() { PaymasterAndData = response.Result.ToString() };
61-
}
45+
var response = await BundlerRequest(client, paymasterUrl, requestId, "pm_sponsorUserOperation", userOp, entryPoint).ConfigureAwait(false);
46+
return JsonConvert.DeserializeObject<PMSponsorOperationResponse>(response.Result.ToString());
6247
}
6348

6449
public static async Task<ZkPaymasterDataResponse> ZkPaymasterData(ThirdwebClient client, string paymasterUrl, object requestId, ThirdwebTransactionInput txInput)

0 commit comments

Comments
 (0)