Skip to content

Commit

Permalink
Improve Analytics (#125)
Browse files Browse the repository at this point in the history
  • Loading branch information
0xFirekeeper authored Jan 24, 2025
1 parent 5348711 commit a6afc39
Show file tree
Hide file tree
Showing 10 changed files with 107 additions and 44 deletions.
1 change: 1 addition & 0 deletions Directory.Packages.props
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
<PrivateAssets>all</PrivateAssets>
</PackageVersion>
<PackageVersion Include="Moq" Version="4.20.72" />
<PackageVersion Include="Newtonsoft.Json" Version="13.0.3" />
<PackageVersion Include="dotenv.net" Version="3.1.3" />
<PackageVersion Include="Microsoft.NET.Test.Sdk" Version="17.7.1" />
Expand Down
26 changes: 5 additions & 21 deletions Thirdweb.Console/Program.cs
Original file line number Diff line number Diff line change
Expand Up @@ -44,32 +44,16 @@

#region AA 0.6

// var smartWallet06 = await SmartWallet.Create(
// personalWallet: privateKeyWallet,
// chainId: 421614,
// gasless: true,
// factoryAddress: "0xa8deE7854fb1eA8c13b713585C81d91ea86dAD84",
// entryPoint: Constants.ENTRYPOINT_ADDRESS_V06
// );

// var receipt06 = await smartWallet06.ExecuteTransaction(new ThirdwebTransactionInput(chainId: 421614, to: await smartWallet06.GetAddress(), value: 0, data: "0x"));

// var smartWallet06 = await SmartWallet.Create(personalWallet: privateKeyWallet, chainId: 421614, gasless: true);
// var receipt06 = await smartWallet06.Transfer(chainId: 421614, toAddress: await smartWallet06.GetAddress(), weiAmount: 0);
// Console.WriteLine($"Receipt: {receipt06}");

#endregion

#region AA 0.7

// var smartWallet07 = await SmartWallet.Create(
// personalWallet: privateKeyWallet,
// chainId: 421614,
// gasless: true,
// factoryAddress: "0x4f4e40E8F66e3Cc0FD7423E2fbd62A769ff551FB",
// entryPoint: Constants.ENTRYPOINT_ADDRESS_V07
// );

// var receipt07 = await smartWallet07.ExecuteTransaction(new ThirdwebTransactionInput(chainId: 421614, to: await smartWallet07.GetAddress(), value: 0, data: "0x"));

// var smartWallet07 = await SmartWallet.Create(personalWallet: privateKeyWallet, chainId: 421614, gasless: true, entryPoint: Constants.ENTRYPOINT_ADDRESS_V07);
// var receipt07 = await smartWallet07.Transfer(chainId: 421614, toAddress: await smartWallet07.GetAddress(), weiAmount: 0);
// Console.WriteLine($"Receipt: {receipt07}");

#endregion
Expand Down Expand Up @@ -179,7 +163,7 @@

#region Smart Ecosystem Wallet

// var eco = await EcosystemWallet.Create(client: client, ecosystemId: "ecosystem.the-bonfire", authProvider: AuthProvider.Twitch);
// var eco = await EcosystemWallet.Create(client: client, ecosystemId: "ecosystem.the-bonfire", authProvider: AuthProvider.Github);
// if (!await eco.IsConnected())
// {
// _ = await eco.LoginWithOauth(
Expand Down
1 change: 1 addition & 0 deletions Thirdweb.Tests/Thirdweb.Tests.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@
<PrivateAssets>all</PrivateAssets>
</PackageReference>
<PackageReference Include="dotenv.net" />
<PackageReference Include="Moq" />
</ItemGroup>

<ItemGroup>
Expand Down
37 changes: 19 additions & 18 deletions Thirdweb/Thirdweb.Transactions/ThirdwebTransaction.cs
Original file line number Diff line number Diff line change
Expand Up @@ -30,12 +30,12 @@ public class ThirdwebTransaction
{
public ThirdwebTransactionInput Input { get; }

private readonly IThirdwebWallet _wallet;
internal readonly IThirdwebWallet Wallet;

private ThirdwebTransaction(IThirdwebWallet wallet, ThirdwebTransactionInput txInput)
{
this.Input = txInput;
this._wallet = wallet;
this.Wallet = wallet;
}

/// <summary>
Expand Down Expand Up @@ -215,7 +215,7 @@ public static async Task<TotalCosts> EstimateTotalCosts(ThirdwebTransaction tran
/// <returns>The estimated gas price.</returns>
public static async Task<BigInteger> EstimateGasPrice(ThirdwebTransaction transaction, bool withBump = true)
{
return await Utils.FetchGasPrice(transaction._wallet.Client, transaction.Input.ChainId.Value, withBump).ConfigureAwait(false);
return await Utils.FetchGasPrice(transaction.Wallet.Client, transaction.Input.ChainId.Value, withBump).ConfigureAwait(false);
}

/// <summary>
Expand All @@ -226,10 +226,10 @@ public static async Task<BigInteger> EstimateGasPrice(ThirdwebTransaction transa
/// <returns>The estimated maximum fee per gas and maximum priority fee per gas.</returns>
public static async Task<(BigInteger maxFeePerGas, BigInteger maxPriorityFeePerGas)> EstimateGasFees(ThirdwebTransaction transaction, bool withBump = true)
{
var rpc = ThirdwebRPC.GetRpcInstance(transaction._wallet.Client, transaction.Input.ChainId.Value);
var rpc = ThirdwebRPC.GetRpcInstance(transaction.Wallet.Client, transaction.Input.ChainId.Value);
var chainId = transaction.Input.ChainId.Value;

if (await Utils.IsZkSync(transaction._wallet.Client, transaction.Input.ChainId.Value).ConfigureAwait(false))
if (await Utils.IsZkSync(transaction.Wallet.Client, transaction.Input.ChainId.Value).ConfigureAwait(false))
{
var fees = await rpc.SendRequestAsync<JToken>("zks_estimateFee", transaction.Input).ConfigureAwait(false);
var maxFee = fees["max_fee_per_gas"].ToObject<HexBigInteger>().Value;
Expand All @@ -238,7 +238,7 @@ public static async Task<BigInteger> EstimateGasPrice(ThirdwebTransaction transa
}
else
{
return await Utils.FetchGasFees(transaction._wallet.Client, chainId, withBump).ConfigureAwait(false);
return await Utils.FetchGasFees(transaction.Wallet.Client, chainId, withBump).ConfigureAwait(false);
}
}

Expand All @@ -249,7 +249,7 @@ public static async Task<BigInteger> EstimateGasPrice(ThirdwebTransaction transa
/// <returns>The result of the simulation.</returns>
public static async Task<string> Simulate(ThirdwebTransaction transaction)
{
var rpc = ThirdwebRPC.GetRpcInstance(transaction._wallet.Client, transaction.Input.ChainId.Value);
var rpc = ThirdwebRPC.GetRpcInstance(transaction.Wallet.Client, transaction.Input.ChainId.Value);
return await rpc.SendRequestAsync<string>("eth_call", transaction.Input, "latest");
}

Expand All @@ -260,8 +260,8 @@ public static async Task<string> Simulate(ThirdwebTransaction transaction)
/// <returns>The estimated gas limit.</returns>
public static async Task<BigInteger> EstimateGasLimit(ThirdwebTransaction transaction)
{
var rpc = ThirdwebRPC.GetRpcInstance(transaction._wallet.Client, transaction.Input.ChainId.Value);
var isZkSync = await Utils.IsZkSync(transaction._wallet.Client, transaction.Input.ChainId.Value).ConfigureAwait(false);
var rpc = ThirdwebRPC.GetRpcInstance(transaction.Wallet.Client, transaction.Input.ChainId.Value);
var isZkSync = await Utils.IsZkSync(transaction.Wallet.Client, transaction.Input.ChainId.Value).ConfigureAwait(false);
BigInteger divider = isZkSync
? 7
: transaction.Input.AuthorizationList == null
Expand All @@ -288,12 +288,12 @@ public static async Task<BigInteger> EstimateGasLimit(ThirdwebTransaction transa
/// <returns>The nonce.</returns>
public static async Task<BigInteger> GetNonce(ThirdwebTransaction transaction)
{
return await transaction._wallet.GetTransactionCount(chainId: transaction.Input.ChainId, blocktag: "pending").ConfigureAwait(false);
return await transaction.Wallet.GetTransactionCount(chainId: transaction.Input.ChainId, blocktag: "pending").ConfigureAwait(false);
}

private static async Task<BigInteger> GetGasPerPubData(ThirdwebTransaction transaction)
{
var rpc = ThirdwebRPC.GetRpcInstance(transaction._wallet.Client, transaction.Input.ChainId.Value);
var rpc = ThirdwebRPC.GetRpcInstance(transaction.Wallet.Client, transaction.Input.ChainId.Value);
var hex = (await rpc.SendRequestAsync<JToken>("zks_estimateFee", transaction.Input).ConfigureAwait(false))["gas_per_pubdata_limit"].ToString();
var finalGasPerPubData = new HexBigInteger(hex).Value * 10 / 5;
return finalGasPerPubData < 10000 ? 10000 : finalGasPerPubData;
Expand All @@ -306,7 +306,7 @@ private static async Task<BigInteger> GetGasPerPubData(ThirdwebTransaction trans
/// <returns>The signed transaction.</returns>
public static async Task<string> Sign(ThirdwebTransaction transaction)
{
return await transaction._wallet.SignTransaction(transaction.Input).ConfigureAwait(false);
return await transaction.Wallet.SignTransaction(transaction.Input).ConfigureAwait(false);
}

/// <summary>
Expand Down Expand Up @@ -362,31 +362,32 @@ public static async Task<string> Send(ThirdwebTransaction transaction)
{
transaction = await Prepare(transaction).ConfigureAwait(false);

var rpc = ThirdwebRPC.GetRpcInstance(transaction._wallet.Client, transaction.Input.ChainId.Value);
var rpc = ThirdwebRPC.GetRpcInstance(transaction.Wallet.Client, transaction.Input.ChainId.Value);
string hash;

if (await Utils.IsZkSync(transaction._wallet.Client, transaction.Input.ChainId.Value).ConfigureAwait(false) && transaction.Input.ZkSync.HasValue)
if (await Utils.IsZkSync(transaction.Wallet.Client, transaction.Input.ChainId.Value).ConfigureAwait(false) && transaction.Input.ZkSync.HasValue)
{
var zkTx = await ConvertToZkSyncTransaction(transaction).ConfigureAwait(false);
var zkTxSigned = await EIP712.GenerateSignature_ZkSyncTransaction("zkSync", "2", transaction.Input.ChainId.Value, zkTx, transaction._wallet).ConfigureAwait(false);
var zkTxSigned = await EIP712.GenerateSignature_ZkSyncTransaction("zkSync", "2", transaction.Input.ChainId.Value, zkTx, transaction.Wallet).ConfigureAwait(false);
hash = await rpc.SendRequestAsync<string>("eth_sendRawTransaction", zkTxSigned).ConfigureAwait(false);
}
else
{
switch (transaction._wallet.AccountType)
switch (transaction.Wallet.AccountType)
{
case ThirdwebAccountType.PrivateKeyAccount:
var signedTx = await Sign(transaction);
hash = await rpc.SendRequestAsync<string>("eth_sendRawTransaction", signedTx).ConfigureAwait(false);
break;
case ThirdwebAccountType.SmartAccount:
case ThirdwebAccountType.ExternalAccount:
hash = await transaction._wallet.SendTransaction(transaction.Input).ConfigureAwait(false);
hash = await transaction.Wallet.SendTransaction(transaction.Input).ConfigureAwait(false);
break;
default:
throw new NotImplementedException("Account type not supported");
}
}
Utils.TrackTransaction(transaction, hash);
return hash;
}

Expand All @@ -398,7 +399,7 @@ public static async Task<string> Send(ThirdwebTransaction transaction)
public static async Task<ThirdwebTransactionReceipt> SendAndWaitForTransactionReceipt(ThirdwebTransaction transaction)
{
var txHash = await Send(transaction).ConfigureAwait(false);
return await WaitForTransactionReceipt(transaction._wallet.Client, transaction.Input.ChainId.Value, txHash).ConfigureAwait(false);
return await WaitForTransactionReceipt(transaction.Wallet.Client, transaction.Input.ChainId.Value, txHash).ConfigureAwait(false);
}

/// <summary>
Expand Down
56 changes: 56 additions & 0 deletions Thirdweb/Thirdweb.Utils/Utils.cs
Original file line number Diff line number Diff line change
Expand Up @@ -1191,4 +1191,60 @@ internal static byte[] ToByteArrayForRLPEncoding(this BigInteger value)

return value.ToBytesForRLPEncoding();
}

internal static async void TrackTransaction(ThirdwebTransaction transaction, string transactionHash)
{
try
{
var wallet = transaction.Wallet;
var content = new StringContent(
JsonConvert.SerializeObject(
new
{
source = "sdk",
action = "transaction:sent",
clientId = wallet.Client.ClientId,
chainId = transaction.Input.ChainId.Value,
transactionHash,
walletAddress = await wallet.GetAddress().ConfigureAwait(false),
walletType = wallet.WalletId,
contractAddress = transaction.Input.To,
gasPrice = transaction.Input.GasPrice?.Value ?? transaction.Input.MaxFeePerGas?.Value
}
),
Encoding.UTF8,
"application/json"
);
_ = await wallet.Client.HttpClient.PostAsync("https://c.thirdweb.com/event", content);
}
catch
{
// Ignore
}
}

internal static async void TrackConnection(IThirdwebWallet wallet)
{
try
{
var content = new StringContent(
JsonConvert.SerializeObject(
new
{
source = "connectWallet",
action = "connect",
walletAddress = await wallet.GetAddress().ConfigureAwait(false),
walletType = wallet.WalletId,
}
),
Encoding.UTF8,
"application/json"
);
_ = await wallet.Client.HttpClient.PostAsync("https://c.thirdweb.com/event", content);
}
catch
{
// Ignore
}
}
}
5 changes: 5 additions & 0 deletions Thirdweb/Thirdweb.Wallets/IThirdwebWallet.cs
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,11 @@ public interface IThirdwebWallet
/// </summary>
public ThirdwebAccountType AccountType { get; }

/// <summary>
/// String identifier for the wallet to be used in analytics.
/// </summary>
public string WalletId { get; }

/// <summary>
/// Gets the address of the wallet.
/// </summary>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ public partial class EcosystemWallet : IThirdwebWallet
{
public ThirdwebClient Client { get; }
public ThirdwebAccountType AccountType => ThirdwebAccountType.PrivateKeyAccount;
public virtual string WalletId => "ecosystem";

internal readonly EmbeddedWallet EmbeddedWallet;
internal readonly IThirdwebHttpClient HttpClient;
Expand Down Expand Up @@ -259,6 +260,7 @@ private async Task<string> PostAuth(Server.VerifyResult result)
{
CreateEnclaveSession(this.EmbeddedWallet, result.AuthToken, this.Email, this.PhoneNumber, this.AuthProvider, result.AuthIdentifier);
this.Address = address.ToChecksumAddress();
Utils.TrackConnection(this);
return this.Address;
}
}
Expand Down
2 changes: 2 additions & 0 deletions Thirdweb/Thirdweb.Wallets/InAppWallet/InAppWallet.cs
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,8 @@ namespace Thirdweb;
/// </summary>
public class InAppWallet : EcosystemWallet
{
public override string WalletId => "inApp";

internal InAppWallet(
ThirdwebClient client,
EmbeddedWallet embeddedWallet,
Expand Down
15 changes: 11 additions & 4 deletions Thirdweb/Thirdweb.Wallets/PrivateKeyWallet/PrivateKeyWallet.cs
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,8 @@ public class PrivateKeyWallet : IThirdwebWallet

public ThirdwebAccountType AccountType => ThirdwebAccountType.PrivateKeyAccount;

public string WalletId => "privateKey";

protected EthECKey EcKey { get; set; }

protected PrivateKeyWallet(ThirdwebClient client, EthECKey key)
Expand Down Expand Up @@ -44,7 +46,9 @@ public static Task<PrivateKeyWallet> Create(ThirdwebClient client, string privat
throw new ArgumentNullException(nameof(privateKeyHex), "Private key cannot be null or empty.");
}

return Task.FromResult(new PrivateKeyWallet(client, new EthECKey(privateKeyHex)));
var wallet = new PrivateKeyWallet(client, new EthECKey(privateKeyHex));
Utils.TrackConnection(wallet);
return Task.FromResult(wallet);
}

#region PrivateKeyWallet Specific
Expand All @@ -61,8 +65,9 @@ public static Task<PrivateKeyWallet> Generate(ThirdwebClient client)
{
throw new ArgumentNullException(nameof(client));
}

return Task.FromResult(new PrivateKeyWallet(client, EthECKey.GenerateKey()));
var wallet = new PrivateKeyWallet(client, EthECKey.GenerateKey());
Utils.TrackConnection(wallet);
return Task.FromResult(wallet);
}

/// <summary>
Expand All @@ -83,7 +88,9 @@ public static async Task<PrivateKeyWallet> LoadOrGenerate(ThirdwebClient client)
if (File.Exists(path))
{
var privateKey = await File.ReadAllTextAsync(path);
return new PrivateKeyWallet(client, new EthECKey(privateKey));
var wallet = new PrivateKeyWallet(client, new EthECKey(privateKey));
Utils.TrackConnection(wallet);
return wallet;
}
else
{
Expand Down
6 changes: 5 additions & 1 deletion Thirdweb/Thirdweb.Wallets/SmartWallet/SmartWallet.cs
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,8 @@ public class SmartWallet : IThirdwebWallet

public ThirdwebAccountType AccountType => ThirdwebAccountType.SmartAccount;

public string WalletId => "smart";

public bool IsDeploying { get; private set; }

public BigInteger ActiveChainId { get; private set; }
Expand Down Expand Up @@ -215,7 +217,7 @@ public static async Task<SmartWallet> Create(
}
}

return new SmartWallet(
var smartWallet = new SmartWallet(
personalWallet,
gasless.Value,
chainId,
Expand All @@ -228,6 +230,8 @@ public static async Task<SmartWallet> Create(
erc20PmInfo.TokenAddress,
erc20PmInfo.BalanceStorageSlot
);
Utils.TrackConnection(smartWallet);
return smartWallet;
}

#endregion
Expand Down

0 comments on commit a6afc39

Please sign in to comment.