@@ -75,7 +75,21 @@ public Transaction(ThirdwebSDK sdk, TransactionInput txInput)
75
75
/// <returns>The JSON string representation of the transaction input.</returns>
76
76
public override string ToString ( )
77
77
{
78
- return JsonConvert . SerializeObject ( Input ) ;
78
+ var readableInput = new
79
+ {
80
+ from = Input . From ,
81
+ to = Input . To ,
82
+ value = Input . Value ? . Value . ToString ( ) ,
83
+ gas = Input . Gas ? . Value . ToString ( ) ,
84
+ gasPrice = Input . GasPrice ? . Value . ToString ( ) ,
85
+ data = Input . Data ,
86
+ nonce = Input . Nonce ? . Value . ToString ( ) ,
87
+ chainId = Input . ChainId ? . Value . ToString ( ) ,
88
+ maxFeePerGas = Input . MaxFeePerGas ? . Value . ToString ( ) ,
89
+ maxPriorityFeePerGas = Input . MaxPriorityFeePerGas ? . Value . ToString ( ) ,
90
+ type = Input . Type ? . Value . ToString ( )
91
+ } ;
92
+ return JsonConvert . SerializeObject ( readableInput ) ;
79
93
}
80
94
81
95
/// <summary>
@@ -206,17 +220,10 @@ public Transaction SetNonce(string nonce)
206
220
/// <returns>The modified <see cref="Transaction"/> object.</returns>
207
221
public Transaction SetArgs ( params object [ ] args )
208
222
{
209
- if ( Utils . IsWebGLBuild ( ) )
210
- {
211
- this . FunctionArgs = args ;
212
- }
213
- else
214
- {
215
- var web3 = Utils . GetWeb3 ( _sdk . Session . ChainId , _sdk . Session . Options . clientId , _sdk . Session . Options . bundleId ) ;
216
- var contract = web3 . Eth . GetContract ( Contract . ABI , Contract . Address ) ;
217
- var function = Utils . GetFunctionMatchSignature ( contract , FunctionName , args ) ;
218
- Input . Data = function . GetData ( args ) ;
219
- }
223
+ this . FunctionArgs = args ;
224
+ var contract = new Nethereum . Contracts . Contract ( null , Contract . ABI , Contract . Address ) ;
225
+ var function = Utils . GetFunctionMatchSignature ( contract , FunctionName , args ) ;
226
+ Input . Data = function . GetData ( args ) ;
220
227
return this ;
221
228
}
222
229
@@ -237,6 +244,18 @@ public async Task<BigInteger> GetGasPrice()
237
244
}
238
245
}
239
246
247
+ public async Task < GasPriceParameters > GetGasFees ( )
248
+ {
249
+ if ( Utils . IsWebGLBuild ( ) )
250
+ {
251
+ return await Bridge . InvokeRoute < GasPriceParameters > ( GetTxBuilderRoute ( "getGasFees" ) , Utils . ToJsonStringArray ( Input , FunctionName , FunctionArgs ) ) ;
252
+ }
253
+ else
254
+ {
255
+ return await Utils . GetGasPriceAsync ( _sdk . Session . ChainId , _sdk . Session . Options . clientId , _sdk . Session . Options . bundleId ) ;
256
+ }
257
+ }
258
+
240
259
/// <summary>
241
260
/// Estimates the gas limit for the transaction asynchronously.
242
261
/// </summary>
@@ -328,34 +347,57 @@ public async Task<string> Sign()
328
347
}
329
348
330
349
/// <summary>
331
- /// Sends the transaction asynchronously.
350
+ /// Populates the transaction asynchronously, setting the gas limit, gas price, nonce, and other parameters .
332
351
/// </summary>
333
- /// <param name="gasless">Specifies whether to send the transaction as a gasless transaction. Default is null (uses gasless if set up).</param >
334
- /// <returns>The transaction hash as a string .</returns >
335
- public async Task < string > Send ( bool ? gasless = null )
352
+ /// <returns>The prepared <see cref="Transaction"/> object.</returns >
353
+ /// <remarks> There is no guarantee the gas and nonce values will be preserved when using Account Abstraction .</remarks >
354
+ public async Task < Transaction > Populate ( )
336
355
{
337
- if ( Utils . IsWebGLBuild ( ) )
356
+ Input . Gas ??= new HexBigInteger ( await EstimateGasLimit ( ) ) ;
357
+
358
+ Input . Value ??= new HexBigInteger ( 0 ) ;
359
+
360
+ Input . Nonce ??= new HexBigInteger ( await _sdk . Wallet . GetNonce ( ) ) ;
361
+
362
+ var force1559 = Input . Type != null && Input . Type . HexValue == new HexBigInteger ( ( int ) TransactionType . EIP1559 ) . HexValue ;
363
+ var supports1559 = force1559 || ( Input . Type == null && Utils . Supports1559 ( _sdk . Session . ChainId . ToString ( ) ) ) ;
364
+ if ( supports1559 )
338
365
{
339
- if ( gasless == null || gasless == false )
340
- return await Send ( ) ;
341
- else
342
- return await SendGasless ( ) ;
366
+ if ( Input . GasPrice == null )
367
+ {
368
+ var fees = await GetGasFees ( ) ;
369
+ Input . MaxFeePerGas ??= new HexBigInteger ( fees . MaxFeePerGas ) ;
370
+ Input . MaxPriorityFeePerGas ??= new HexBigInteger ( fees . MaxPriorityFeePerGas ) ;
371
+ }
343
372
}
344
373
else
345
374
{
346
- if ( Input . Gas == null )
347
- await EstimateAndSetGasLimitAsync ( ) ;
348
- if ( Input . Value == null )
349
- Input . Value = new HexBigInteger ( 0 ) ;
350
- bool isGaslessSetup = _sdk . Session . Options . gasless . HasValue && ! string . IsNullOrEmpty ( _sdk . Session . Options . gasless ? . engine . relayerUrl ) ;
351
- if ( gasless != null && gasless . Value && ! isGaslessSetup )
352
- throw new UnityException ( "Gasless relayer transactions are not enabled. Please enable them in the SDK options." ) ;
353
- bool sendGaslessly = gasless == null ? isGaslessSetup : gasless . Value ;
354
- if ( sendGaslessly )
355
- return await SendGasless ( ) ;
356
- else
357
- return await Send ( ) ;
375
+ if ( Input . MaxFeePerGas == null && Input . MaxPriorityFeePerGas == null )
376
+ {
377
+ ThirdwebDebug . Log ( "Using Legacy Gas Pricing" ) ;
378
+ var gasPrice = await GetGasPrice ( ) ;
379
+ Input . GasPrice = new HexBigInteger ( gasPrice ) ;
380
+ }
358
381
}
382
+ return this ;
383
+ }
384
+
385
+ /// <summary>
386
+ /// Sends the transaction asynchronously.
387
+ /// </summary>
388
+ /// <param name="gasless">Specifies whether to send the transaction as a gasless transaction (through thirdweb Engine relayer). Default is null (uses gasless if set up).</param>
389
+ /// <returns>The transaction hash as a string.</returns>
390
+ public async Task < string > Send ( bool ? gasless = null )
391
+ {
392
+ var tx = await Populate ( ) ;
393
+ bool isGaslessSetup = _sdk . Session . Options . gasless . HasValue && ! string . IsNullOrEmpty ( _sdk . Session . Options . gasless ? . engine . relayerUrl ) ;
394
+ if ( gasless != null && gasless . Value && ! isGaslessSetup )
395
+ throw new UnityException ( "Gasless relayer transactions are not enabled. Please enable them in the SDK options." ) ;
396
+ bool sendGaslessly = gasless == null ? isGaslessSetup : gasless . Value ;
397
+ if ( sendGaslessly )
398
+ return await tx . SendGasless ( ) ;
399
+ else
400
+ return await tx . Send ( ) ;
359
401
}
360
402
361
403
/// <summary>
@@ -437,35 +479,13 @@ public static async Task<TransactionReceipt> WaitForTransactionResultRaw(string
437
479
438
480
private async Task < string > Send ( )
439
481
{
482
+ string hash ;
440
483
if ( Utils . IsWebGLBuild ( ) )
441
484
{
442
- return await Bridge . InvokeRoute < string > ( GetTxBuilderRoute ( "send" ) , Utils . ToJsonStringArray ( Input , FunctionName , FunctionArgs ) ) ;
485
+ hash = await Bridge . InvokeRoute < string > ( GetTxBuilderRoute ( "send" ) , Utils . ToJsonStringArray ( Input , FunctionName , FunctionArgs ) ) ;
443
486
}
444
487
else
445
488
{
446
- var force1559 = Input . Type != null && Input . Type . HexValue == new HexBigInteger ( ( int ) TransactionType . EIP1559 ) . HexValue ;
447
- var supports1559 = force1559 || ( Input . Type == null && Utils . Supports1559 ( _sdk . Session . ChainId . ToString ( ) ) ) ;
448
- if ( supports1559 )
449
- {
450
- if ( Input . GasPrice == null )
451
- {
452
- var fees = await Utils . GetGasPriceAsync ( _sdk . Session . ChainId , _sdk . Session . Options . clientId , _sdk . Session . Options . bundleId ) ;
453
- if ( Input . MaxFeePerGas == null )
454
- Input . MaxFeePerGas = new HexBigInteger ( fees . MaxFeePerGas ) ;
455
- if ( Input . MaxPriorityFeePerGas == null )
456
- Input . MaxPriorityFeePerGas = new HexBigInteger ( fees . MaxPriorityFeePerGas ) ;
457
- }
458
- }
459
- else
460
- {
461
- if ( Input . MaxFeePerGas == null && Input . MaxPriorityFeePerGas == null )
462
- {
463
- ThirdwebDebug . Log ( "Using Legacy Gas Pricing" ) ;
464
- Input . GasPrice = new HexBigInteger ( await Utils . GetLegacyGasPriceAsync ( _sdk . Session . ChainId , _sdk . Session . Options . clientId , _sdk . Session . Options . bundleId ) ) ;
465
- }
466
- }
467
-
468
- string hash ;
469
489
if ( _sdk . Session . ActiveWallet . GetSignerProvider ( ) == WalletProvider . LocalWallet && _sdk . Session . ActiveWallet . GetProvider ( ) != WalletProvider . SmartWallet )
470
490
{
471
491
hash = await _sdk . Session . Web3 . Eth . TransactionManager . SendTransactionAsync ( Input ) ;
@@ -475,9 +495,9 @@ private async Task<string> Send()
475
495
var ethSendTx = new EthSendTransaction ( _sdk . Session . Web3 . Client ) ;
476
496
hash = await ethSendTx . SendRequestAsync ( Input ) ;
477
497
}
478
- ThirdwebDebug . Log ( $ "Transaction hash: { hash } ") ;
479
- return hash ;
480
498
}
499
+ ThirdwebDebug . Log ( $ "Transaction hash: { hash } ") ;
500
+ return hash ;
481
501
}
482
502
483
503
private async Task < string > SendGasless ( )
0 commit comments