|
3 | 3 |
|
4 | 4 | using System.Diagnostics;
|
5 | 5 | using System.Numerics;
|
| 6 | +using System.Text; |
6 | 7 | using dotenv.net;
|
| 8 | +using Nethereum.ABI; |
| 9 | +using Nethereum.Hex.HexConvertors.Extensions; |
7 | 10 | using Nethereum.Hex.HexTypes;
|
8 | 11 | using Newtonsoft.Json;
|
9 | 12 | using Newtonsoft.Json.Linq;
|
10 | 13 | using Thirdweb;
|
| 14 | +using Thirdweb.AccountAbstraction; |
11 | 15 | using Thirdweb.AI;
|
12 | 16 | using Thirdweb.Pay;
|
13 | 17 |
|
|
143 | 147 |
|
144 | 148 | #endregion
|
145 | 149 |
|
| 150 | +#region Engine Wallet |
| 151 | + |
| 152 | +// // EngineWallet is compatible with IThirdwebWallet and can be used with any SDK method/extension |
| 153 | +// var engineWallet = await EngineWallet.Create( |
| 154 | +// client: client, |
| 155 | +// engineUrl: Environment.GetEnvironmentVariable("ENGINE_URL"), |
| 156 | +// authToken: Environment.GetEnvironmentVariable("ENGINE_ACCESS_TOKEN"), |
| 157 | +// walletAddress: Environment.GetEnvironmentVariable("ENGINE_BACKEND_WALLET_ADDRESS"), |
| 158 | +// timeoutSeconds: null, // no timeout |
| 159 | +// additionalHeaders: null // can set things like x-account-address if using basic session keys |
| 160 | +// ); |
| 161 | + |
| 162 | +// // Simple self transfer |
| 163 | +// var receipt = await engineWallet.Transfer(chainId: 11155111, toAddress: await engineWallet.GetAddress(), weiAmount: 0); |
| 164 | +// Console.WriteLine($"Receipt: {receipt}"); |
| 165 | + |
| 166 | +#endregion |
| 167 | + |
146 | 168 | #region EIP-7702
|
147 | 169 |
|
148 |
| -// // Chain and contract addresses |
| 170 | +// // -------------------------------------------------------------------------- |
| 171 | +// // Configuration |
| 172 | +// // -------------------------------------------------------------------------- |
| 173 | + |
149 | 174 | // var chainWith7702 = 911867;
|
150 |
| -// var erc20ContractAddress = "0xAA462a5BE0fc5214507FDB4fB2474a7d5c69065b"; // Fake ERC20 |
151 |
| -// var delegationContractAddress = "0x654F42b74885EE6803F403f077bc0409f1066c58"; // BatchCallDelegation |
| 175 | +// var delegationContractAddress = "0xb012446cba783d0f7723daf96cf4c49005022307"; // MinimalAccount |
| 176 | + |
| 177 | +// // Required environment variables |
| 178 | +// var backendWalletAddress = Environment.GetEnvironmentVariable("ENGINE_BACKEND_WALLET_ADDRESS") ?? throw new Exception("ENGINE_BACKEND_WALLET_ADDRESS is required"); |
| 179 | +// var engineUrl = Environment.GetEnvironmentVariable("ENGINE_URL") ?? throw new Exception("ENGINE_URL is required"); |
| 180 | +// var engineAccessToken = Environment.GetEnvironmentVariable("ENGINE_ACCESS_TOKEN") ?? throw new Exception("ENGINE_ACCESS_TOKEN is required"); |
| 181 | + |
| 182 | +// // -------------------------------------------------------------------------- |
| 183 | +// // Initialize Engine Wallet |
| 184 | +// // -------------------------------------------------------------------------- |
| 185 | + |
| 186 | +// var engineWallet = await EngineWallet.Create(client, engineUrl, engineAccessToken, backendWalletAddress, 15); |
| 187 | + |
| 188 | +// // -------------------------------------------------------------------------- |
| 189 | +// // Delegation Contract Implementation |
| 190 | +// // -------------------------------------------------------------------------- |
152 | 191 |
|
153 |
| -// // Initialize contracts normally |
154 |
| -// var erc20Contract = await ThirdwebContract.Create(client: client, address: erc20ContractAddress, chain: chainWith7702); |
155 |
| -// var delegationContract = await ThirdwebContract.Create(client: client, address: delegationContractAddress, chain: chainWith7702); |
| 192 | +// var delegationContract = await ThirdwebContract.Create(client, delegationContractAddress, chainWith7702); |
156 | 193 |
|
157 | 194 | // // Initialize a (to-be) 7702 EOA
|
158 | 195 | // var eoaWallet = await PrivateKeyWallet.Generate(client);
|
159 | 196 | // var eoaWalletAddress = await eoaWallet.GetAddress();
|
160 | 197 | // Console.WriteLine($"EOA address: {eoaWalletAddress}");
|
161 | 198 |
|
162 |
| -// // Initialize another wallet, the "executor" that will hit the eoa's (to-be) execute function |
163 |
| -// var executorWallet = await PrivateKeyWallet.Generate(client); |
164 |
| -// var executorWalletAddress = await executorWallet.GetAddress(); |
165 |
| -// Console.WriteLine($"Executor address: {executorWalletAddress}"); |
| 199 | +// // Sign the authorization to point to the delegation contract |
| 200 | +// var authorization = await eoaWallet.SignAuthorization(chainWith7702, delegationContractAddress, willSelfExecute: false); |
| 201 | +// Console.WriteLine($"Authorization: {JsonConvert.SerializeObject(authorization, Formatting.Indented)}"); |
166 | 202 |
|
167 |
| -// // Fund the executor wallet |
168 |
| -// var fundingWallet = await PrivateKeyWallet.Create(client, privateKey); |
169 |
| -// var fundingHash = (await fundingWallet.Transfer(chainWith7702, executorWalletAddress, BigInteger.Parse("0.001".ToWei()))).TransactionHash; |
170 |
| -// Console.WriteLine($"Funded Executor Wallet: {fundingHash}"); |
| 203 | +// // Sign message for session key |
| 204 | +// var sessionKeyParams = new SessionKeyParams_7702() |
| 205 | +// { |
| 206 | +// Signer = backendWalletAddress, |
| 207 | +// NativeTokenLimitPerTransaction = 0, |
| 208 | +// StartTimestamp = 0, |
| 209 | +// EndTimestamp = Utils.GetUnixTimeStampNow() + (3600 * 24), |
| 210 | +// ApprovedTargets = new List<string> { Constants.ADDRESS_ZERO }, |
| 211 | +// Uid = Guid.NewGuid().ToByteArray() |
| 212 | +// }; |
| 213 | +// var sessionKeySig = await EIP712.GenerateSignature_SmartAccount_7702("MinimalAccount", "1", chainWith7702, eoaWalletAddress, sessionKeyParams, eoaWallet); |
171 | 214 |
|
172 |
| -// // Sign the authorization to make it point to the delegation contract |
173 |
| -// var authorization = await eoaWallet.SignAuthorization(chainId: chainWith7702, contractAddress: delegationContractAddress, willSelfExecute: false); |
174 |
| -// Console.WriteLine($"Authorization: {JsonConvert.SerializeObject(authorization, Formatting.Indented)}"); |
| 215 | +// // Create call data for the session key |
| 216 | +// var sessionKeyCallData = delegationContract.CreateCallData("createSessionKeyWithSig", sessionKeyParams, sessionKeySig.HexToBytes()); |
175 | 217 |
|
176 |
| -// // Execute the delegation |
177 |
| -// var tx = await ThirdwebTransaction.Create(executorWallet, new ThirdwebTransactionInput(chainId: chainWith7702, to: executorWalletAddress, authorization: authorization)); |
178 |
| -// var hash = (await ThirdwebTransaction.SendAndWaitForTransactionReceipt(tx)).TransactionHash; |
179 |
| -// Console.WriteLine($"Authorization execution transaction hash: {hash}"); |
| 218 | +// // Execute the delegation & session key creation in one go, from the backend! |
| 219 | +// var delegationReceipt = await engineWallet.ExecuteTransaction(new ThirdwebTransactionInput(chainId: chainWith7702, to: eoaWalletAddress, data: sessionKeyCallData, authorization: authorization)); |
| 220 | +// Console.WriteLine($"Delegation Execution Receipt: {JsonConvert.SerializeObject(delegationReceipt, Formatting.Indented)}"); |
180 | 221 |
|
181 |
| -// // Prove that code has been deployed to the eoa |
| 222 | +// // Verify contract code deployed to the EOA |
182 | 223 | // var rpc = ThirdwebRPC.GetRpcInstance(client, chainWith7702);
|
183 | 224 | // var code = await rpc.SendRequestAsync<string>("eth_getCode", eoaWalletAddress, "latest");
|
184 | 225 | // Console.WriteLine($"EOA code: {code}");
|
185 | 226 |
|
186 |
| -// // Log erc20 balance of executor before the claim |
187 |
| -// var executorBalanceBefore = await erc20Contract.ERC20_BalanceOf(executorWalletAddress); |
188 |
| -// Console.WriteLine($"Executor balance before: {executorBalanceBefore}"); |
| 227 | +// // The EOA is now a contract |
| 228 | +// var eoaContract = await ThirdwebContract.Create(client, eoaWalletAddress, chainWith7702, delegationContract.Abi); |
189 | 229 |
|
190 |
| -// // Prepare the claim call |
191 |
| -// var claimCallData = erc20Contract.CreateCallData( |
192 |
| -// "claim", |
193 |
| -// new object[] |
194 |
| -// { |
195 |
| -// executorWalletAddress, // receiver |
196 |
| -// 100, // quantity |
197 |
| -// Constants.NATIVE_TOKEN_ADDRESS, // currency |
198 |
| -// 0, // pricePerToken |
199 |
| -// new object[] { Array.Empty<byte>(), BigInteger.Zero, BigInteger.Zero, Constants.ADDRESS_ZERO }, // allowlistProof |
200 |
| -// Array.Empty<byte>() // data |
201 |
| -// } |
202 |
| -// ); |
| 230 | +// // -------------------------------------------------------------------------- |
| 231 | +// // Mint Tokens (DropERC20) to the EOA Using the backend session key |
| 232 | +// // -------------------------------------------------------------------------- |
| 233 | + |
| 234 | +// var erc20ContractAddress = "0xAA462a5BE0fc5214507FDB4fB2474a7d5c69065b"; // DropERC20 |
| 235 | +// var erc20Contract = await ThirdwebContract.Create(client, erc20ContractAddress, chainWith7702); |
203 | 236 |
|
204 |
| -// // Embed the claim call in the execute call |
205 |
| -// var executeCallData = delegationContract.CreateCallData( |
206 |
| -// method: "execute", |
207 |
| -// parameters: new object[] |
| 237 | +// // Log ERC20 balance before mint |
| 238 | +// var eoaBalanceBefore = await erc20Contract.ERC20_BalanceOf(eoaWalletAddress); |
| 239 | +// Console.WriteLine($"EOA balance before: {eoaBalanceBefore}"); |
| 240 | + |
| 241 | +// // Create execution call data (calling 'claim' on the DropERC20) |
| 242 | +// var executeCallData = eoaContract.CreateCallData( |
| 243 | +// "execute", |
| 244 | +// new object[] |
208 | 245 | // {
|
209 |
| -// new List<Thirdweb.Console.Call> |
| 246 | +// new List<Call> |
210 | 247 | // {
|
211 | 248 | // new()
|
212 | 249 | // {
|
213 |
| -// Data = claimCallData.HexToBytes(), |
| 250 | +// Data = erc20Contract |
| 251 | +// .CreateCallData( |
| 252 | +// "claim", |
| 253 | +// new object[] |
| 254 | +// { |
| 255 | +// eoaWalletAddress, // receiver |
| 256 | +// 100, // quantity |
| 257 | +// Constants.NATIVE_TOKEN_ADDRESS, // currency |
| 258 | +// 0, // pricePerToken |
| 259 | +// new object[] { Array.Empty<byte>(), BigInteger.Zero, BigInteger.Zero, Constants.ADDRESS_ZERO }, // allowlistProof |
| 260 | +// Array.Empty<byte>() // data |
| 261 | +// } |
| 262 | +// ) |
| 263 | +// .HexToBytes(), |
214 | 264 | // To = erc20ContractAddress,
|
215 | 265 | // Value = BigInteger.Zero
|
216 | 266 | // }
|
217 | 267 | // }
|
218 | 268 | // }
|
219 | 269 | // );
|
220 | 270 |
|
221 |
| -// // Execute from the executor wallet targeting the eoa which is pointing to the delegation contract |
222 |
| -// var tx2 = await ThirdwebTransaction.Create(executorWallet, new ThirdwebTransactionInput(chainId: chainWith7702, to: eoaWalletAddress, data: executeCallData)); |
223 |
| -// var hash2 = (await ThirdwebTransaction.SendAndWaitForTransactionReceipt(tx2)).TransactionHash; |
224 |
| -// Console.WriteLine($"Token claim transaction hash: {hash2}"); |
| 271 | +// var executeReceipt = await engineWallet.ExecuteTransaction(new ThirdwebTransactionInput(chainId: chainWith7702, to: eoaWalletAddress, data: executeCallData)); |
| 272 | +// Console.WriteLine($"Execute receipt: {JsonConvert.SerializeObject(executeReceipt, Formatting.Indented)}"); |
225 | 273 |
|
226 |
| -// // Log erc20 balance of executor after the claim |
227 |
| -// var executorBalanceAfter = await erc20Contract.ERC20_BalanceOf(executorWalletAddress); |
228 |
| -// Console.WriteLine($"Executor balance after: {executorBalanceAfter}"); |
| 274 | +// // Log ERC20 balance after mint |
| 275 | +// var eoaBalanceAfter = await erc20Contract.ERC20_BalanceOf(eoaWalletAddress); |
| 276 | +// Console.WriteLine($"EOA balance after: {eoaBalanceAfter}"); |
229 | 277 |
|
230 | 278 | #endregion
|
231 | 279 |
|
|
0 commit comments