From be347294e44f16adb90d891c79229701e8e3855d Mon Sep 17 00:00:00 2001
From: Firekeeper <0xFirekeeper@gmail.com>
Date: Fri, 22 Nov 2024 23:27:54 +0700
Subject: [PATCH] TokenPaymaster v3 (#101)

---
 Thirdweb.Console/Program.cs                   | 51 ++++++++++++-------
 .../SmartWallet/SmartWallet.cs                | 28 ++++++++--
 2 files changed, 59 insertions(+), 20 deletions(-)

diff --git a/Thirdweb.Console/Program.cs b/Thirdweb.Console/Program.cs
index 905e3ea..9f480aa 100644
--- a/Thirdweb.Console/Program.cs
+++ b/Thirdweb.Console/Program.cs
@@ -299,28 +299,45 @@
 
 #endregion
 
-#region ERC20 Smart Wallet - Base USDC
+#region TokenPaymaster - Celo CUSD
+
+// var chainId = 42220; // celo
+
+// var erc20SmartWallet = await SmartWallet.Create(personalWallet: privateKeyWallet, chainId: chainId, tokenPaymaster: TokenPaymaster.CELO_CUSD);
 
-// var erc20SmartWallet = await SmartWallet.Create(
-//     personalWallet: privateKeyWallet,
-//     chainId: 8453, // base mainnet
-//     gasless: true,
-//     factoryAddress: "0xEc87d96E3F324Dcc828750b52994C6DC69C8162b",
-//     entryPoint: Constants.ENTRYPOINT_ADDRESS_V07,
-//     tokenPaymaster: TokenPaymaster.BASE_USDC
-// );
 // var erc20SmartWalletAddress = await erc20SmartWallet.GetAddress();
 // Console.WriteLine($"ERC20 Smart Wallet address: {erc20SmartWalletAddress}");
 
-// var selfTransfer = await ThirdwebTransaction.Create(wallet: erc20SmartWallet, txInput: new ThirdwebTransactionInput(chainId: 8453, to: erc20SmartWalletAddress, value: 0, data: "0x"));
+// var receipt = await erc20SmartWallet.Transfer(chainId: chainId, toAddress: erc20SmartWalletAddress, weiAmount: 0);
+// Console.WriteLine($"Receipt: {JsonConvert.SerializeObject(receipt, Formatting.Indented)}");
 
-// var estimateGas = await ThirdwebTransaction.EstimateGasCosts(selfTransfer);
-// Console.WriteLine($"Self transfer gas estimate: {estimateGas.Ether}");
-// Console.WriteLine("Make sure you have enough USDC!");
-// Console.ReadLine();
+#endregion
+
+#region TokenPaymaster - Base USDC
+
+// var chainId = 8453; // base
+
+// var erc20SmartWallet = await SmartWallet.Create(personalWallet: privateKeyWallet, chainId: chainId, tokenPaymaster: TokenPaymaster.BASE_USDC);
+
+// var erc20SmartWalletAddress = await erc20SmartWallet.GetAddress();
+// Console.WriteLine($"ERC20 Smart Wallet address: {erc20SmartWalletAddress}");
+
+// var receipt = await erc20SmartWallet.Transfer(chainId: chainId, toAddress: erc20SmartWalletAddress, weiAmount: 0);
+// Console.WriteLine($"Receipt: {JsonConvert.SerializeObject(receipt, Formatting.Indented)}");
+
+#endregion
+
+#region TokenPaymaster - Lisk LSK
+
+// var chainId = 1135; // lisk
+
+// var erc20SmartWallet = await SmartWallet.Create(personalWallet: privateKeyWallet, chainId: chainId, tokenPaymaster: TokenPaymaster.LISK_LSK);
+
+// var erc20SmartWalletAddress = await erc20SmartWallet.GetAddress();
+// Console.WriteLine($"ERC20 Smart Wallet address: {erc20SmartWalletAddress}");
 
-// var receipt = await ThirdwebTransaction.SendAndWaitForTransactionReceipt(selfTransfer);
-// Console.WriteLine($"Self transfer receipt: {JsonConvert.SerializeObject(receipt, Formatting.Indented)}");
+// var receipt = await erc20SmartWallet.Transfer(chainId: chainId, toAddress: erc20SmartWalletAddress, weiAmount: 0);
+// Console.WriteLine($"Receipt: {JsonConvert.SerializeObject(receipt, Formatting.Indented)}");
 
 #endregion
 
@@ -349,7 +366,7 @@
 
 #region InAppWallet - OAuth
 
-// var inAppWalletOAuth = await InAppWallet.Create(client: client, authProvider: AuthProvider.Twitch);
+// var inAppWalletOAuth = await InAppWallet.Create(client: client, authProvider: AuthProvider.Google);
 // if (!await inAppWalletOAuth.IsConnected())
 // {
 //     _ = await inAppWalletOAuth.LoginWithOauth(
diff --git a/Thirdweb/Thirdweb.Wallets/SmartWallet/SmartWallet.cs b/Thirdweb/Thirdweb.Wallets/SmartWallet/SmartWallet.cs
index 641205b..0208604 100644
--- a/Thirdweb/Thirdweb.Wallets/SmartWallet/SmartWallet.cs
+++ b/Thirdweb/Thirdweb.Wallets/SmartWallet/SmartWallet.cs
@@ -15,6 +15,8 @@ public enum TokenPaymaster
 {
     NONE,
     BASE_USDC,
+    CELO_CUSD,
+    LISK_LSK
 }
 
 public class SmartWallet : IThirdwebWallet
@@ -66,10 +68,30 @@ private struct TokenPaymasterConfig
                 new TokenPaymasterConfig()
                 {
                     ChainId = 8453,
-                    PaymasterAddress = "0xff4d12b1f8d276aa4a9e8cc80539e806791bfe28",
+                    PaymasterAddress = "0x2222f2738BE6bB7aA0Bfe4AEeAf2908172CF5539",
                     TokenAddress = "0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913",
                     BalanceStorageSlot = 9
                 }
+            },
+            {
+                TokenPaymaster.CELO_CUSD,
+                new TokenPaymasterConfig()
+                {
+                    ChainId = 42220,
+                    PaymasterAddress = "0x3feA3c5744D715ff46e91C4e5C9a94426DfF2aF9",
+                    TokenAddress = "0x765DE816845861e75A25fCA122bb6898B8B1282a",
+                    BalanceStorageSlot = 9
+                }
+            },
+            {
+                TokenPaymaster.LISK_LSK,
+                new TokenPaymasterConfig()
+                {
+                    ChainId = 1135,
+                    PaymasterAddress = "0x9eb8cf7fBa5ed9EeDCC97a0d52254cc0e9B1AC25",
+                    TokenAddress = "0xac485391EB2d7D88253a7F1eF18C37f4242D1A24",
+                    BalanceStorageSlot = 9
+                }
             }
         };
 
@@ -154,7 +176,7 @@ public static async Task<SmartWallet> Create(
             }
         }
 
-        entryPoint ??= Constants.ENTRYPOINT_ADDRESS_V06;
+        entryPoint ??= tokenPaymaster == TokenPaymaster.NONE ? Constants.ENTRYPOINT_ADDRESS_V06 : Constants.ENTRYPOINT_ADDRESS_V07;
 
         var entryPointVersion = Utils.GetEntryPointVersion(entryPoint);
 
@@ -719,7 +741,7 @@ private async Task<object> SignUserOp(ThirdwebTransactionInput transactionInput,
                 partialUserOp.VerificationGasLimit = new HexBigInteger(gasEstimates.VerificationGasLimit).Value;
                 partialUserOp.PreVerificationGas = new HexBigInteger(gasEstimates.PreVerificationGas).Value;
                 partialUserOp.PaymasterVerificationGasLimit = new HexBigInteger(gasEstimates.PaymasterVerificationGasLimit).Value;
-                partialUserOp.PaymasterPostOpGasLimit = new HexBigInteger(gasEstimates.PaymasterPostOpGasLimit).Value;
+                partialUserOp.PaymasterPostOpGasLimit = this.UseERC20Paymaster && !this._isApproving ? 500_000 : new HexBigInteger(gasEstimates.PaymasterPostOpGasLimit).Value;
             }
 
             // Hash, sign and encode the user operation