Skip to content

Commit

Permalink
Automatic Smart Wallet network switching // Require chain id lowest l…
Browse files Browse the repository at this point in the history
…evel (#60)
  • Loading branch information
0xFirekeeper authored Aug 27, 2024
1 parent 1cc06e0 commit 371170e
Show file tree
Hide file tree
Showing 13 changed files with 332 additions and 132 deletions.
53 changes: 53 additions & 0 deletions Thirdweb.Tests/Thirdweb.Extensions/Thirdweb.Extensions.Tests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -197,6 +197,59 @@ public async Task GetBalance_Wallet_WithERC20()
Assert.True(balance >= 0);
}

[Fact(Timeout = 120000)]
public async Task GetTransactionCountRaw()
{
var address = "0xd8dA6BF26964aF9D7eEd9e03E53415D37aA96045"; // vitalik.eth
var chainId = BigInteger.One;
var transactionCount = await ThirdwebExtensions.GetTransactionCountRaw(this._client, chainId, address);
Assert.True(transactionCount >= 0);
}

[Fact(Timeout = 120000)]
public async Task GetTransactionCountRaw_WithBlockTag()
{
var address = "0xd8dA6BF26964aF9D7eEd9e03E53415D37aA96045"; // vitalik.eth
var chainId = this._chainId;
var blockTag = "latest";
var transactionCount = await ThirdwebExtensions.GetTransactionCountRaw(this._client, chainId, address, blockTag);
Assert.True(transactionCount >= 0);
}

[Fact(Timeout = 120000)]
public async Task GetTransactionCount_Contract()
{
var contract = await this.GetTokenERC20Contract();
var transactionCount = await contract.GetTransactionCount();
Assert.True(transactionCount >= 0);
}

[Fact(Timeout = 120000)]
public async Task GetTransactionCount_Contract_WithBlockTag()
{
var contract = await this.GetTokenERC20Contract();
var blockTag = "latest";
var transactionCount = await contract.GetTransactionCount(blockTag);
Assert.True(transactionCount >= 0);
}

[Fact(Timeout = 120000)]
public async Task GetTransactionCount_Wallet()
{
var wallet = await this.GetSmartWallet();
var transactionCount = await wallet.GetTransactionCount(this._chainId);
Assert.True(transactionCount >= 0);
}

[Fact(Timeout = 120000)]
public async Task GetTransactionCount_Wallet_WithBlockTag()
{
var wallet = await this.GetSmartWallet();
var blockTag = "latest";
var transactionCount = await wallet.GetTransactionCount(this._chainId, blockTag);
Assert.True(transactionCount >= 0);
}

[Fact(Timeout = 120000)]
public async Task Transfer()
{
Expand Down
100 changes: 47 additions & 53 deletions Thirdweb.Tests/Thirdweb.Transactions/Thirdweb.Transactions.Tests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -9,9 +9,7 @@ private async Task<ThirdwebTransaction> CreateSampleTransaction()
{
var client = ThirdwebClient.Create(secretKey: this.SecretKey);
var wallet = await PrivateKeyWallet.Generate(client);
var chainId = new BigInteger(421614);

var transaction = await ThirdwebTransaction.Create(wallet, new ThirdwebTransactionInput() { To = await wallet.GetAddress(), }, chainId);
var transaction = await ThirdwebTransaction.Create(wallet, new ThirdwebTransactionInput(421614) { To = await wallet.GetAddress(), });
return transaction;
}

Expand Down Expand Up @@ -50,9 +48,8 @@ public async Task Create_ValidatesInputParameters()
{
var client = ThirdwebClient.Create(secretKey: this.SecretKey);
var wallet = await PrivateKeyWallet.Generate(client);
var txInput = new ThirdwebTransactionInput() { To = Constants.ADDRESS_ZERO };
var chainId = new BigInteger(421614);
var transaction = await ThirdwebTransaction.Create(wallet, txInput, chainId);
var txInput = new ThirdwebTransactionInput(421614) { To = Constants.ADDRESS_ZERO };
var transaction = await ThirdwebTransaction.Create(wallet, txInput);
Assert.NotNull(transaction);
}

Expand All @@ -61,8 +58,8 @@ public async Task Create_ThrowsOnNoTo()
{
var client = ThirdwebClient.Create(secretKey: this.SecretKey);
var wallet = await PrivateKeyWallet.Generate(client);
var txInput = new ThirdwebTransactionInput() { };
var ex = await Assert.ThrowsAsync<ArgumentException>(() => ThirdwebTransaction.Create(wallet, txInput, 421614));
var txInput = new ThirdwebTransactionInput(421614) { };
var ex = await Assert.ThrowsAsync<ArgumentException>(() => ThirdwebTransaction.Create(wallet, txInput));
Assert.Contains("Transaction recipient (to) must be provided", ex.Message);
}

Expand All @@ -71,8 +68,8 @@ public async Task Create_ThrowsOnNoWallet()
{
var client = ThirdwebClient.Create(secretKey: this.SecretKey);
var wallet = await PrivateKeyWallet.Generate(client);
var txInput = new ThirdwebTransactionInput() { To = Constants.ADDRESS_ZERO };
var ex = await Assert.ThrowsAsync<ArgumentException>(() => ThirdwebTransaction.Create(null, txInput, 421614));
var txInput = new ThirdwebTransactionInput(421614) { To = Constants.ADDRESS_ZERO };
var ex = await Assert.ThrowsAsync<ArgumentException>(() => ThirdwebTransaction.Create(null, txInput));
Assert.Contains("Wallet must be provided", ex.Message);
}

Expand All @@ -81,8 +78,7 @@ public async Task Create_ThrowsOnChainIdZero()
{
var client = ThirdwebClient.Create(secretKey: this.SecretKey);
var wallet = await PrivateKeyWallet.Generate(client);
var txInput = new ThirdwebTransactionInput() { To = Constants.ADDRESS_ZERO };
var ex = await Assert.ThrowsAsync<ArgumentException>(() => ThirdwebTransaction.Create(wallet, txInput, BigInteger.Zero));
var ex = Assert.Throws<ArgumentException>(() => new ThirdwebTransactionInput(0) { To = Constants.ADDRESS_ZERO });
Assert.Contains("Invalid Chain ID", ex.Message);
}

Expand Down Expand Up @@ -166,7 +162,7 @@ public async Task Sign_SmartWallet_SignsTransaction()
var client = ThirdwebClient.Create(secretKey: this.SecretKey);
var privateKeyAccount = await PrivateKeyWallet.Generate(client);
var smartAccount = await SmartWallet.Create(personalWallet: privateKeyAccount, factoryAddress: "0xbf1C9aA4B1A085f7DA890a44E82B0A1289A40052", gasless: true, chainId: 421614);
var transaction = await ThirdwebTransaction.Create(smartAccount, new ThirdwebTransactionInput() { To = Constants.ADDRESS_ZERO, }, 421614);
var transaction = await ThirdwebTransaction.Create(smartAccount, new ThirdwebTransactionInput(421614) { To = Constants.ADDRESS_ZERO, });
var signed = await ThirdwebTransaction.Sign(transaction);
Assert.NotNull(signed);
}
Expand Down Expand Up @@ -218,43 +214,43 @@ public async Task SetZkSyncOptions_DefaultsToZeroNull()
Assert.Null(transaction.Input.ZkSync?.FactoryDeps);
}

// [Fact(Timeout = 120000)]
// public async Task Send_ZkSync_TransfersGaslessly()
// {
// var transaction = await CreateSampleTransaction();
// _ = transaction.SetChainId(300);
// _ = transaction.SetTo("0xbA226d47Cbb2731CBAA67C916c57d68484AA269F");
// _ = transaction.SetValue(BigInteger.Zero);
// _ = transaction.SetZkSyncOptions(
// new ZkSyncOptions(
// paymaster: "0xbA226d47Cbb2731CBAA67C916c57d68484AA269F",
// paymasterInput: "0x8c5a344500000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000000",
// gasPerPubdataByteLimit: 50000,
// factoryDeps: new List<byte[]>()
// )
// );
// var receipt = await ThirdwebTransaction.SendAndWaitForTransactionReceipt(transaction);
// Assert.NotNull(receipt);
// Assert.StartsWith("0x", receipt.TransactionHash);
// }
[Fact(Timeout = 120000)]
public async Task Send_ZkSync_TransfersGaslessly()
{
var transaction = await this.CreateSampleTransaction();
_ = transaction.SetChainId(300);
_ = transaction.SetTo("0xbA226d47Cbb2731CBAA67C916c57d68484AA269F");
_ = transaction.SetValue(BigInteger.Zero);
_ = transaction.SetZkSyncOptions(
new ZkSyncOptions(
paymaster: "0xbA226d47Cbb2731CBAA67C916c57d68484AA269F",
paymasterInput: "0x8c5a344500000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000000",
gasPerPubdataByteLimit: 50000,
factoryDeps: new List<byte[]>()
)
);
var receipt = await ThirdwebTransaction.SendAndWaitForTransactionReceipt(transaction);
Assert.NotNull(receipt);
Assert.StartsWith("0x", receipt.TransactionHash);
}

// [Fact(Timeout = 120000)]
// public async Task Send_ZkSync_NoGasPerPubFactoryDepsTransfersGaslessly()
// {
// var transaction = await CreateSampleTransaction();
// _ = transaction.SetChainId(300);
// _ = transaction.SetTo("0xbA226d47Cbb2731CBAA67C916c57d68484AA269F");
// _ = transaction.SetValue(BigInteger.Zero);
// _ = transaction.SetZkSyncOptions(
// new ZkSyncOptions(
// paymaster: "0xbA226d47Cbb2731CBAA67C916c57d68484AA269F",
// paymasterInput: "0x8c5a344500000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000000"
// )
// );
// var receipt = await ThirdwebTransaction.SendAndWaitForTransactionReceipt(transaction);
// Assert.NotNull(receipt);
// Assert.StartsWith("0x", receipt.TransactionHash);
// }
[Fact(Timeout = 120000)]
public async Task Send_ZkSync_NoGasPerPubFactoryDepsTransfersGaslessly()
{
var transaction = await this.CreateSampleTransaction();
_ = transaction.SetChainId(300);
_ = transaction.SetTo("0xbA226d47Cbb2731CBAA67C916c57d68484AA269F");
_ = transaction.SetValue(BigInteger.Zero);
_ = transaction.SetZkSyncOptions(
new ZkSyncOptions(
paymaster: "0xbA226d47Cbb2731CBAA67C916c57d68484AA269F",
paymasterInput: "0x8c5a344500000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000000"
)
);
var receipt = await ThirdwebTransaction.SendAndWaitForTransactionReceipt(transaction);
Assert.NotNull(receipt);
Assert.StartsWith("0x", receipt.TransactionHash);
}

[Fact(Timeout = 120000)]
public async Task EstimateTotalCosts_CalculatesCostsCorrectly()
Expand Down Expand Up @@ -355,9 +351,7 @@ public async Task EstimateGasFees_ReturnsCorrectly()
{
var transaction = await ThirdwebTransaction.Create(
await PrivateKeyWallet.Generate(ThirdwebClient.Create(secretKey: this.SecretKey)),
new ThirdwebTransactionInput() { To = Constants.ADDRESS_ZERO, },
250 // fantom for 1559 non zero prio
);
new ThirdwebTransactionInput(250) { To = Constants.ADDRESS_ZERO, });

(var maxFee, var maxPrio) = await ThirdwebTransaction.EstimateGasFees(transaction);

Expand Down Expand Up @@ -393,7 +387,7 @@ public async Task Simulate_ReturnsDataOrThrowsIntrinsic()
var client = ThirdwebClient.Create(secretKey: this.SecretKey);
var privateKeyAccount = await PrivateKeyWallet.Generate(client);
var smartAccount = await SmartWallet.Create(personalWallet: privateKeyAccount, factoryAddress: "0xbf1C9aA4B1A085f7DA890a44E82B0A1289A40052", gasless: true, chainId: 421614);
var transaction = await ThirdwebTransaction.Create(smartAccount, new ThirdwebTransactionInput() { To = Constants.ADDRESS_ZERO, Gas = new HexBigInteger(250000), }, 421614);
var transaction = await ThirdwebTransaction.Create(smartAccount, new ThirdwebTransactionInput(421614) { To = Constants.ADDRESS_ZERO, Gas = new HexBigInteger(250000), });

try
{
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -78,7 +78,7 @@ public async Task SendGaslessZkTx_Success()
{
var account = await this.GetSmartAccount();
var hash = await account.SendTransaction(
new ThirdwebTransactionInput()
new ThirdwebTransactionInput(300)
{
From = await account.GetAddress(),
To = await account.GetAddress(),
Expand All @@ -90,29 +90,29 @@ public async Task SendGaslessZkTx_Success()
Assert.True(hash.Length == 66);
}

// [Fact(Timeout = 120000)]
// public async Task SendGaslessZkTx_ZkCandy_Success()
// {
// var account = await GetSmartAccount(zkChainId: 302);
// var hash = await account.SendTransaction(
// new ThirdwebTransactionInput()
// {
// From = await account.GetAddress(),
// To = await account.GetAddress(),
// Value = new Nethereum.Hex.HexTypes.HexBigInteger(0),
// Data = "0x"
// }
// );
// Assert.NotNull(hash);
// Assert.True(hash.Length == 66);
// }
[Fact(Timeout = 120000)]
public async Task SendGaslessZkTx_ZkCandy_Success()
{
var account = await this.GetSmartAccount(zkChainId: 302);
var hash = await account.SendTransaction(
new ThirdwebTransactionInput(302)
{
From = await account.GetAddress(),
To = await account.GetAddress(),
Value = new Nethereum.Hex.HexTypes.HexBigInteger(0),
Data = "0x"
}
);
Assert.NotNull(hash);
Assert.True(hash.Length == 66);
}

[Fact(Timeout = 120000)]
public async Task SendGaslessZkTx_Abstract_Success()
{
var account = await this.GetSmartAccount(zkChainId: 11124);
var hash = await account.SendTransaction(
new ThirdwebTransactionInput()
new ThirdwebTransactionInput(11124)
{
From = await account.GetAddress(),
To = await account.GetAddress(),
Expand All @@ -123,4 +123,19 @@ public async Task SendGaslessZkTx_Abstract_Success()
Assert.NotNull(hash);
Assert.True(hash.Length == 66);
}

[Fact(Timeout = 120000)]
public async Task ZkSync_Switch()
{
var account = await this.GetSmartAccount(zkChainId: 300);
_ = await account.SendTransaction(
new ThirdwebTransactionInput(302)
{
From = await account.GetAddress(),
To = await account.GetAddress(),
Value = new Nethereum.Hex.HexTypes.HexBigInteger(0),
Data = "0x"
}
);
}
}
Loading

0 comments on commit 371170e

Please sign in to comment.