9
9
using Nethereum . Util ;
10
10
using Newtonsoft . Json . Linq ;
11
11
using System . Text . RegularExpressions ;
12
+ using Newtonsoft . Json ;
12
13
13
14
namespace Thirdweb
14
15
{
@@ -17,6 +18,9 @@ namespace Thirdweb
17
18
/// </summary>
18
19
public static class Utils
19
20
{
21
+ private static readonly Dictionary < BigInteger , bool > Eip155EnforcedCache = new Dictionary < BigInteger , bool > ( ) ;
22
+ private static readonly Dictionary < BigInteger , ThirdwebChainData > ChainDataCache = new Dictionary < BigInteger , ThirdwebChainData > ( ) ;
23
+
20
24
/// <summary>
21
25
/// Computes the client ID from the given secret key.
22
26
/// </summary>
@@ -322,6 +326,11 @@ public static BigInteger AdjustDecimals(this BigInteger value, int fromDecimals,
322
326
323
327
public static async Task < ThirdwebChainData > FetchThirdwebChainDataAsync ( ThirdwebClient client , BigInteger chainId )
324
328
{
329
+ if ( ChainDataCache . ContainsKey ( chainId ) )
330
+ {
331
+ return ChainDataCache [ chainId ] ;
332
+ }
333
+
325
334
if ( client == null )
326
335
{
327
336
throw new ArgumentNullException ( nameof ( client ) ) ;
@@ -337,17 +346,23 @@ public static async Task<ThirdwebChainData> FetchThirdwebChainDataAsync(Thirdweb
337
346
{
338
347
var response = await client . HttpClient . GetAsync ( url ) . ConfigureAwait ( false ) ;
339
348
var json = await response . Content . ReadAsStringAsync ( ) . ConfigureAwait ( false ) ;
340
- var deserializedResponse = Newtonsoft . Json . JsonConvert . DeserializeObject < ThirdwebChainDataResponse > ( json ) ;
349
+ var deserializedResponse = JsonConvert . DeserializeObject < ThirdwebChainDataResponse > ( json ) ;
341
350
342
- return deserializedResponse == null || deserializedResponse . Error != null
343
- ? throw new Exception ( $ "Failed to fetch chain data for chain ID { chainId } . Error: { Newtonsoft . Json . JsonConvert . SerializeObject ( deserializedResponse ? . Error ) } ")
344
- : deserializedResponse . Data ;
351
+ if ( deserializedResponse == null || deserializedResponse . Error != null )
352
+ {
353
+ throw new Exception ( $ "Failed to fetch chain data for chain ID { chainId } . Error: { JsonConvert . SerializeObject ( deserializedResponse ? . Error ) } ") ;
354
+ }
355
+ else
356
+ {
357
+ ChainDataCache [ chainId ] = deserializedResponse . Data ;
358
+ return deserializedResponse . Data ;
359
+ }
345
360
}
346
361
catch ( HttpRequestException httpEx )
347
362
{
348
363
throw new Exception ( $ "HTTP request error while fetching chain data for chain ID { chainId } : { httpEx . Message } ", httpEx ) ;
349
364
}
350
- catch ( Newtonsoft . Json . JsonException jsonEx )
365
+ catch ( JsonException jsonEx )
351
366
{
352
367
throw new Exception ( $ "JSON deserialization error while fetching chain data for chain ID { chainId } : { jsonEx . Message } ", jsonEx ) ;
353
368
}
@@ -487,5 +502,89 @@ private static List<JProperty> GetJProperties(string mainTypeName, MemberValue[]
487
502
488
503
return list ;
489
504
}
505
+
506
+ public static async Task < bool > IsEip155Enforced ( ThirdwebClient client , BigInteger chainId )
507
+ {
508
+ if ( Eip155EnforcedCache . ContainsKey ( chainId ) )
509
+ {
510
+ return Eip155EnforcedCache [ chainId ] ;
511
+ }
512
+
513
+ var result = false ;
514
+ var rpc = ThirdwebRPC . GetRpcInstance ( client , chainId ) ;
515
+
516
+ try
517
+ {
518
+ // Pre-155 tx that will fail
519
+ var rawTransaction =
520
+ "0xf8a58085174876e800830186a08080b853604580600e600039806000f350fe7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe03601600081602082378035828234f58015156039578182fd5b8082525050506014600cf31ba02222222222222222222222222222222222222222222222222222222222222222a02222222222222222222222222222222222222222222222222222222222222222" ;
521
+ _ = await rpc . SendRequestAsync < string > ( "eth_sendRawTransaction" , rawTransaction ) ;
522
+ }
523
+ catch ( Exception e )
524
+ {
525
+ var errorMsg = e . Message . ToLower ( ) ;
526
+
527
+ var errorSubstrings = new List < string >
528
+ {
529
+ "eip-155" ,
530
+ "eip155" ,
531
+ "protected" ,
532
+ "invalid chain id for signer" ,
533
+ "chain id none" ,
534
+ "chain_id mismatch" ,
535
+ "recovered sender mismatch" ,
536
+ "transaction hash mismatch" ,
537
+ "chainid no support" ,
538
+ "chainid (0)" ,
539
+ "chainid(0)" ,
540
+ "invalid sender"
541
+ } ;
542
+
543
+ if ( errorSubstrings . Any ( errorMsg . Contains ) )
544
+ {
545
+ result = true ;
546
+ }
547
+ else
548
+ {
549
+ // Check if all substrings in any of the composite substrings are present
550
+ var errorSubstringsComposite = new List < string [ ] > { new [ ] { "account" , "not found" } , new [ ] { "wrong" , "chainid" } } ;
551
+
552
+ result = errorSubstringsComposite . Any ( arr => arr . All ( substring => errorMsg . Contains ( substring ) ) ) ;
553
+ }
554
+ }
555
+
556
+ Eip155EnforcedCache [ chainId ] = result ;
557
+ return result ;
558
+ }
559
+
560
+ public static bool IsEip1559Supported ( string chainId )
561
+ {
562
+ switch ( chainId )
563
+ {
564
+ // BNB Mainnet
565
+ case "56" :
566
+ // BNB Testnet
567
+ case "97" :
568
+ // opBNB Mainnet
569
+ case "204" :
570
+ // opBNB Testnet
571
+ case "5611" :
572
+ // Oasys Mainnet
573
+ case "248" :
574
+ // Oasys Testnet
575
+ case "9372" :
576
+ // Vanar Mainnet
577
+ case "2040" :
578
+ // Vanar Testnet (Vanguard)
579
+ case "78600" :
580
+ // Taraxa Mainnet
581
+ case "841" :
582
+ // Taraxa Testnet
583
+ case "842" :
584
+ return false ;
585
+ default :
586
+ return true ;
587
+ }
588
+ }
490
589
}
491
590
}
0 commit comments