Skip to content

Commit

Permalink
Authenticate (#18)
Browse files Browse the repository at this point in the history
* Authenticate

* dupe

* nulls and tests

* can't always get exactly value as diff due to gas fluctuations

* resources

* Update IThirdwebWallet.cs

* Revert "Update IThirdwebWallet.cs"

This reverts commit 619c12d.

* full payload test
  • Loading branch information
0xFirekeeper authored May 15, 2024
1 parent 6768e56 commit d0d24d7
Show file tree
Hide file tree
Showing 7 changed files with 414 additions and 77 deletions.
152 changes: 77 additions & 75 deletions Thirdweb.Console/Program.cs
Original file line number Diff line number Diff line change
Expand Up @@ -52,81 +52,83 @@

// Create smart wallet with InAppWallet signer
var smartWallet = await SmartWallet.Create(client: client, personalWallet: inAppWallet, factoryAddress: "0xbf1C9aA4B1A085f7DA890a44E82B0A1289A40052", gasless: true, chainId: 421614);

// Grant a session key to pk wallet (advanced use case)
_ = await smartWallet.CreateSessionKey(
signerAddress: await privateKeyWallet.GetAddress(),
approvedTargets: new List<string>() { Constants.ADDRESS_ZERO },
nativeTokenLimitPerTransactionInWei: "0",
permissionStartTimestamp: "0",
permissionEndTimestamp: (Utils.GetUnixTimeStampNow() + 86400).ToString(),
reqValidityStartTimestamp: "0",
reqValidityEndTimestamp: Utils.GetUnixTimeStampIn10Years().ToString()
);

// Reconnect to same smart wallet with pk wallet as signer (specifying wallet address override)
smartWallet = await SmartWallet.Create(
client: client,
personalWallet: privateKeyWallet,
factoryAddress: "0xbf1C9aA4B1A085f7DA890a44E82B0A1289A40052",
gasless: true,
chainId: 421614,
accountAddressOverride: await smartWallet.GetAddress()
);

// Log addresses
Console.WriteLine($"PrivateKey Wallet: {await privateKeyWallet.GetAddress()}");
Console.WriteLine($"InAppWallet: {await inAppWallet.GetAddress()}");
Console.WriteLine($"Smart Wallet: {await smartWallet.GetAddress()}");

// Sign, triggering deploy as needed and 1271 verification if it's a smart wallet
var message = "Hello, Thirdweb!";
var signature = await smartWallet.PersonalSign(message);
Console.WriteLine($"Signed message: {signature}");

var balanceBefore = await ThirdwebContract.Read<BigInteger>(contract, "balanceOf", await smartWallet.GetAddress());
Console.WriteLine($"Balance before mint: {balanceBefore}");

var writeResult = await ThirdwebContract.Write(smartWallet, contract, "mintTo", 0, await smartWallet.GetAddress(), 100);
Console.WriteLine($"Contract write result: {writeResult}");

var balanceAfter = await ThirdwebContract.Read<BigInteger>(contract, "balanceOf", await smartWallet.GetAddress());
Console.WriteLine($"Balance after mint: {balanceAfter}");

// Transaction Builder
var preparedTx = await ThirdwebContract.Prepare(wallet: smartWallet, contract: contract, method: "mintTo", weiValue: 0, parameters: new object[] { await smartWallet.GetAddress(), 100 });
Console.WriteLine($"Prepared transaction: {preparedTx}");
var estimatedCosts = await ThirdwebTransaction.EstimateGasCosts(preparedTx);
Console.WriteLine($"Estimated ETH gas cost: {estimatedCosts.ether}");
var totalCosts = await ThirdwebTransaction.EstimateTotalCosts(preparedTx);
Console.WriteLine($"Estimated ETH total cost: {totalCosts.ether}");
var simulationData = await ThirdwebTransaction.Simulate(preparedTx);
Console.WriteLine($"Simulation data: {simulationData}");
var txHash = await ThirdwebTransaction.Send(preparedTx);
Console.WriteLine($"Transaction hash: {txHash}");
var receipt = await ThirdwebTransaction.WaitForTransactionReceipt(client, 421614, txHash);
Console.WriteLine($"Transaction receipt: {JsonConvert.SerializeObject(receipt)}");

// Transaction Builder - raw transfer
var rawTx = new TransactionInput
{
From = await smartWallet.GetAddress(),
To = await smartWallet.GetAddress(),
Value = new HexBigInteger(BigInteger.Zero),
Data = "0x",
};
var preparedRawTx = await ThirdwebTransaction.Create(client: client, wallet: smartWallet, txInput: rawTx, chainId: 421614);
Console.WriteLine($"Prepared raw transaction: {preparedRawTx}");
var estimatedCostsRaw = await ThirdwebTransaction.EstimateGasCosts(preparedRawTx);
Console.WriteLine($"Estimated ETH gas cost: {estimatedCostsRaw.ether}");
var totalCostsRaw = await ThirdwebTransaction.EstimateTotalCosts(preparedRawTx);
Console.WriteLine($"Estimated ETH total cost: {totalCostsRaw.ether}");
var simulationDataRaw = await ThirdwebTransaction.Simulate(preparedRawTx);
Console.WriteLine($"Simulation data: {simulationDataRaw}");
var txHashRaw = await ThirdwebTransaction.Send(preparedRawTx);
Console.WriteLine($"Raw transaction hash: {txHashRaw}");
var receiptRaw = await ThirdwebTransaction.WaitForTransactionReceipt(client, 421614, txHashRaw);
Console.WriteLine($"Raw transaction receipt: {JsonConvert.SerializeObject(receiptRaw)}");
var res = await smartWallet.Authenticate("http://localhost:8000", 421614);
Console.WriteLine($"Smart wallet auth result: {res}");

// // Grant a session key to pk wallet (advanced use case)
// _ = await smartWallet.CreateSessionKey(
// signerAddress: await privateKeyWallet.GetAddress(),
// approvedTargets: new List<string>() { Constants.ADDRESS_ZERO },
// nativeTokenLimitPerTransactionInWei: "0",
// permissionStartTimestamp: "0",
// permissionEndTimestamp: (Utils.GetUnixTimeStampNow() + 86400).ToString(),
// reqValidityStartTimestamp: "0",
// reqValidityEndTimestamp: Utils.GetUnixTimeStampIn10Years().ToString()
// );

// // Reconnect to same smart wallet with pk wallet as signer (specifying wallet address override)
// smartWallet = await SmartWallet.Create(
// client: client,
// personalWallet: privateKeyWallet,
// factoryAddress: "0xbf1C9aA4B1A085f7DA890a44E82B0A1289A40052",
// gasless: true,
// chainId: 421614,
// accountAddressOverride: await smartWallet.GetAddress()
// );

// // Log addresses
// Console.WriteLine($"PrivateKey Wallet: {await privateKeyWallet.GetAddress()}");
// Console.WriteLine($"InAppWallet: {await inAppWallet.GetAddress()}");
// Console.WriteLine($"Smart Wallet: {await smartWallet.GetAddress()}");

// // Sign, triggering deploy as needed and 1271 verification if it's a smart wallet
// var message = "Hello, Thirdweb!";
// var signature = await smartWallet.PersonalSign(message);
// Console.WriteLine($"Signed message: {signature}");

// var balanceBefore = await ThirdwebContract.Read<BigInteger>(contract, "balanceOf", await smartWallet.GetAddress());
// Console.WriteLine($"Balance before mint: {balanceBefore}");

// var writeResult = await ThirdwebContract.Write(smartWallet, contract, "mintTo", 0, await smartWallet.GetAddress(), 100);
// Console.WriteLine($"Contract write result: {writeResult}");

// var balanceAfter = await ThirdwebContract.Read<BigInteger>(contract, "balanceOf", await smartWallet.GetAddress());
// Console.WriteLine($"Balance after mint: {balanceAfter}");

// // Transaction Builder
// var preparedTx = await ThirdwebContract.Prepare(wallet: smartWallet, contract: contract, method: "mintTo", weiValue: 0, parameters: new object[] { await smartWallet.GetAddress(), 100 });
// Console.WriteLine($"Prepared transaction: {preparedTx}");
// var estimatedCosts = await ThirdwebTransaction.EstimateGasCosts(preparedTx);
// Console.WriteLine($"Estimated ETH gas cost: {estimatedCosts.ether}");
// var totalCosts = await ThirdwebTransaction.EstimateTotalCosts(preparedTx);
// Console.WriteLine($"Estimated ETH total cost: {totalCosts.ether}");
// var simulationData = await ThirdwebTransaction.Simulate(preparedTx);
// Console.WriteLine($"Simulation data: {simulationData}");
// var txHash = await ThirdwebTransaction.Send(preparedTx);
// Console.WriteLine($"Transaction hash: {txHash}");
// var receipt = await ThirdwebTransaction.WaitForTransactionReceipt(client, 421614, txHash);
// Console.WriteLine($"Transaction receipt: {JsonConvert.SerializeObject(receipt)}");

// // Transaction Builder - raw transfer
// var rawTx = new TransactionInput
// {
// From = await smartWallet.GetAddress(),
// To = await smartWallet.GetAddress(),
// Value = new HexBigInteger(BigInteger.Zero),
// Data = "0x",
// };
// var preparedRawTx = await ThirdwebTransaction.Create(client: client, wallet: smartWallet, txInput: rawTx, chainId: 421614);
// Console.WriteLine($"Prepared raw transaction: {preparedRawTx}");
// var estimatedCostsRaw = await ThirdwebTransaction.EstimateGasCosts(preparedRawTx);
// Console.WriteLine($"Estimated ETH gas cost: {estimatedCostsRaw.ether}");
// var totalCostsRaw = await ThirdwebTransaction.EstimateTotalCosts(preparedRawTx);
// Console.WriteLine($"Estimated ETH total cost: {totalCostsRaw.ether}");
// var simulationDataRaw = await ThirdwebTransaction.Simulate(preparedRawTx);
// Console.WriteLine($"Simulation data: {simulationDataRaw}");
// var txHashRaw = await ThirdwebTransaction.Send(preparedRawTx);
// Console.WriteLine($"Raw transaction hash: {txHashRaw}");
// var receiptRaw = await ThirdwebTransaction.WaitForTransactionReceipt(client, 421614, txHashRaw);
// Console.WriteLine($"Raw transaction receipt: {JsonConvert.SerializeObject(receiptRaw)}");


// Storage actions
Expand Down
3 changes: 1 addition & 2 deletions Thirdweb.Tests/Thirdweb.Transactions.Tests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -218,14 +218,13 @@ public async Task EstimateGasCosts_SmartWalletHigherThanPrivateKeyWallet()
public async Task EstimateTotalCosts_HigherThanGasCostsByValue()
{
var transaction = await CreateSampleTransaction();
_ = transaction.SetValue(new BigInteger(1000));
_ = transaction.SetValue(new BigInteger(1000000000000000000)); // 100 gwei accounting for fluctuations
_ = transaction.SetGasLimit(21000);

var totalCosts = await ThirdwebTransaction.EstimateTotalCosts(transaction);
var gasCosts = await ThirdwebTransaction.EstimateGasCosts(transaction);

Assert.True(totalCosts.wei > gasCosts.wei);
Assert.True(totalCosts.wei - gasCosts.wei == transaction.Input.Value.Value);
}

[Fact]
Expand Down
173 changes: 173 additions & 0 deletions Thirdweb.Tests/Thirdweb.Utils.Tests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -202,4 +202,177 @@ public void FormatERC20_ThrowsOnInvalidWei()
var invalidWei = "not_a_number";
Assert.Throws<ArgumentException>(() => Utils.FormatERC20(invalidWei, 4));
}

[Fact]
public void GenerateSIWE_ReturnsCorrectValue()
{
var loginPayloadData = new LoginPayloadData
{
Version = "1",
ChainId = "421614",
Nonce = "0",
Address = Constants.ADDRESS_ZERO,
Domain = "thirdweb.com",
IssuedAt = "0",
ExpirationTime = "0",
InvalidBefore = "0"
};
var expectedSIWE =
"thirdweb.com wants you to sign in with your Ethereum account:\n0x0000000000000000000000000000000000000000\n\n\nVersion: 1\nChain ID: 421614\nNonce: 0\nIssued At: 0\nExpiration Time: 0\nNot Before: 0";
var siwe = Utils.GenerateSIWE(loginPayloadData);
Assert.Equal(expectedSIWE, siwe);
}

[Fact]
public void GenerateSIWE_WithAllOptional_ReturnsCorrectValue()
{
var loginPayloadData = new LoginPayloadData
{
Version = "1",
ChainId = "421614",
Nonce = "0",
Address = Constants.ADDRESS_ZERO,
Domain = "thirdweb.com",
IssuedAt = "0",
ExpirationTime = "0",
InvalidBefore = "0",
Statement = "This is a statement",
Uri = "https://thirdweb.com",
Resources = new List<string>() { "resource1", "resource2" }
};
var expectedSIWE =
"thirdweb.com wants you to sign in with your Ethereum account:\n0x0000000000000000000000000000000000000000\n\nThis is a statement\n\nURI: https://thirdweb.com\nVersion: 1\nChain ID: 421614\nNonce: 0\nIssued At: 0\nExpiration Time: 0\nNot Before: 0\nResources:\n- resource1\n- resource2";
var siwe = Utils.GenerateSIWE(loginPayloadData);
Assert.Equal(expectedSIWE, siwe);
}

[Fact]
public void GenerateSIWE_WithResources_ReturnsCorrectValue()
{
var loginPayloadData = new LoginPayloadData
{
Version = "1",
ChainId = "421614",
Nonce = "0",
Address = Constants.ADDRESS_ZERO,
Domain = "thirdweb.com",
IssuedAt = "0",
ExpirationTime = "0",
InvalidBefore = "0",
Resources = new List<string>() { "resource1", "resource2" }
};
var expectedSIWE =
"thirdweb.com wants you to sign in with your Ethereum account:\n0x0000000000000000000000000000000000000000\n\n\nVersion: 1\nChain ID: 421614\nNonce: 0\nIssued At: 0\nExpiration Time: 0\nNot Before: 0\nResources:\n- resource1\n- resource2";
var siwe = Utils.GenerateSIWE(loginPayloadData);
Assert.Equal(expectedSIWE, siwe);
}

[Fact]
public void GenerateSIWE_ThrowsOnNullLoginPayloadData()
{
LoginPayloadData? loginPayloadData = null;
_ = Assert.Throws<ArgumentNullException>(() => Utils.GenerateSIWE(loginPayloadData));
}

[Fact]
public void GenerateSIWE_ThrowsOnNullDomain()
{
var loginPayloadData = new LoginPayloadData
{
Version = "1",
ChainId = "421614",
Nonce = "0",
Address = Constants.ADDRESS_ZERO,
Domain = null!,
IssuedAt = "0",
ExpirationTime = "0",
InvalidBefore = "0"
};
_ = Assert.Throws<ArgumentNullException>(() => Utils.GenerateSIWE(loginPayloadData));
}

[Fact]
public void GenerateSIWE_ThrowsOnNullAddress()
{
var loginPayloadData = new LoginPayloadData
{
Version = "1",
ChainId = "421614",
Nonce = "0",
Address = null!,
Domain = "thirdweb.com",
IssuedAt = "0",
ExpirationTime = "0",
InvalidBefore = "0"
};
_ = Assert.Throws<ArgumentNullException>(() => Utils.GenerateSIWE(loginPayloadData));
}

[Fact]
public void GenerateSIWE_ThrowsOnNullVersion()
{
var loginPayloadData = new LoginPayloadData
{
Version = null!,
ChainId = "421614",
Nonce = "0",
Address = Constants.ADDRESS_ZERO,
Domain = "thirdweb.com",
IssuedAt = "0",
ExpirationTime = "0",
InvalidBefore = "0"
};
_ = Assert.Throws<ArgumentNullException>(() => Utils.GenerateSIWE(loginPayloadData));
}

[Fact]
public void GenerateSIWE_ThrowsOnNullChainId()
{
var loginPayloadData = new LoginPayloadData
{
Version = "1",
ChainId = null!,
Nonce = "0",
Address = Constants.ADDRESS_ZERO,
Domain = "thirdweb.com",
IssuedAt = "0",
ExpirationTime = "0",
InvalidBefore = "0"
};
_ = Assert.Throws<ArgumentNullException>(() => Utils.GenerateSIWE(loginPayloadData));
}

[Fact]
public void GenerateSIWE_ThrowsOnNullNonce()
{
var loginPayloadData = new LoginPayloadData
{
Version = "1",
ChainId = "421614",
Nonce = null!,
Address = Constants.ADDRESS_ZERO,
Domain = "thirdweb.com",
IssuedAt = "0",
ExpirationTime = "0",
InvalidBefore = "0"
};
_ = Assert.Throws<ArgumentNullException>(() => Utils.GenerateSIWE(loginPayloadData));
}

[Fact]
public void GenerateSIWE_ThrowsOnNullIssuedAt()
{
var loginPayloadData = new LoginPayloadData
{
Version = "1",
ChainId = "421614",
Nonce = "0",
Address = Constants.ADDRESS_ZERO,
Domain = "thirdweb.com",
IssuedAt = null!,
ExpirationTime = "0",
InvalidBefore = "0"
};
_ = Assert.Throws<ArgumentNullException>(() => Utils.GenerateSIWE(loginPayloadData));
}
}
Loading

0 comments on commit d0d24d7

Please sign in to comment.