Skip to content

Commit

Permalink
Merge branch 'main' into rob/add-inline-docstring-669
Browse files Browse the repository at this point in the history
  • Loading branch information
kalambet authored Oct 25, 2023
2 parents e6c166c + 77ee22d commit cfeb6dc
Show file tree
Hide file tree
Showing 29 changed files with 618 additions and 94 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,7 @@ public async Task<Erc1155MetaData> Fetch(string uri, BigInteger tokenId)


var response = await httpClient.Get<Erc1155MetaData>(uri);
return response.EnsureResponse();
return response.AssertSuccess();
}

private Erc1155MetaData DecodeUri(string uri)
Expand Down
12 changes: 6 additions & 6 deletions src/ChainSafe.Gaming.Gelato/GelatoClient.cs
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,7 @@ public async Task<TResponse> Post<TRequest, TResponse>(RelayCall relayCall, TReq
_ => throw new Web3Exception("relayCall option not found")
};

return (await httpClient.Post<TRequest, TResponse>(url, request)).EnsureResponse();
return (await httpClient.Post<TRequest, TResponse>(url, request)).AssertSuccess();
}

/// <summary>
Expand All @@ -61,7 +61,7 @@ public async Task<string[]> GetSupportedNetworks()
{
try
{
return (await httpClient.Get<SupportedNetworksResponse>($"{config.Url}/relays/v2")).EnsureResponse().Relays;
return (await httpClient.Get<SupportedNetworksResponse>($"{config.Url}/relays/v2")).AssertSuccess().Relays;
}
catch (Exception e)
{
Expand All @@ -83,7 +83,7 @@ public async Task<string[]> GetGelatoOracles()
{
try
{
return (await httpClient.Get<OraclesResponse>($"{config.Url}/oracles/")).EnsureResponse().Oracles;
return (await httpClient.Get<OraclesResponse>($"{config.Url}/oracles/")).AssertSuccess().Oracles;
}
catch (Exception e)
{
Expand All @@ -106,7 +106,7 @@ public async Task<string[]> GetPaymentTokens(string chainId)
{
try
{
return (await httpClient.Get<PaymentTokensResponse>($"{config.Url}/oracles/${chainId}/paymentTokens/")).EnsureResponse().PaymentTokens;
return (await httpClient.Get<PaymentTokensResponse>($"{config.Url}/oracles/${chainId}/paymentTokens/")).AssertSuccess().PaymentTokens;
}
catch (Exception e)
{
Expand All @@ -124,7 +124,7 @@ public async Task<HexBigInteger> GetEstimatedFeeRequest(EstimatedFeeRequest requ
{
try
{
return (await httpClient.Post<EstimatedFeeRequest, EstimatedFeeResponse>($"{config.Url}/oracles/${request.ChainId}/estimate/", request)).EnsureResponse().EstimatedFee;
return (await httpClient.Post<EstimatedFeeRequest, EstimatedFeeResponse>($"{config.Url}/oracles/${request.ChainId}/estimate/", request)).AssertSuccess().EstimatedFee;
}
catch (Exception e)
{
Expand All @@ -142,7 +142,7 @@ public async Task<RelayedTask> GetTaskStatus(string taskId)
{
try
{
return (await httpClient.Get<TransactionStatusResponse>($"{config.Url}/tasks/status/{taskId}")).EnsureResponse().Task;
return (await httpClient.Get<TransactionStatusResponse>($"{config.Url}/tasks/status/{taskId}")).AssertSuccess().Task;
}
catch (Exception e)
{
Expand Down
Original file line number Diff line number Diff line change
@@ -1,10 +1,9 @@
using ChainSafe.Gaming.Web3.Core;
using ChainSafe.Gaming.Web3.Environment;
using Newtonsoft.Json;

namespace ChainSafe.Gaming.Web3.Analytics
{
public class ApiAnalyticsClient : IAnalyticsClient
internal class ApiAnalyticsClient : IAnalyticsClient
{
private const string LoggingUrl = "https://api.gaming.chainsafe.io/logging/logEvent";
private const string AnalyticsVersion = "2.5";
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,3 @@
using System.Linq;
using ChainSafe.Gaming.Web3.Build;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.DependencyInjection.Extensions;
Expand All @@ -7,6 +6,10 @@ namespace ChainSafe.Gaming.Web3.Analytics
{
public static class ApiAnalyticsClientExtensions
{
/// <summary>
/// Binds <see cref="ApiAnalyticsClient"/> thereby enabling analytics.
/// </summary>
/// <returns>Service collection to enable fluent syntax.</returns>
public static IWeb3ServiceCollection UseApiAnalytics(this IWeb3ServiceCollection serviceCollection)
{
if (serviceCollection.AnalyticsDisabled())
Expand All @@ -17,12 +20,5 @@ public static IWeb3ServiceCollection UseApiAnalytics(this IWeb3ServiceCollection
serviceCollection.Replace(ServiceDescriptor.Singleton<IAnalyticsClient, ApiAnalyticsClient>());
return serviceCollection;
}

public static bool AnalyticsDisabled(this IWeb3ServiceCollection serviceCollection)
{
return serviceCollection.Any(d =>
d.ServiceType == typeof(IAnalyticsClient)
&& d.ImplementationType == typeof(NoOpAnalyticsClient));
}
}
}
7 changes: 7 additions & 0 deletions src/ChainSafe.Gaming/Web3/Core/Analytics/IAnalyticsClient.cs
Original file line number Diff line number Diff line change
@@ -1,7 +1,14 @@
namespace ChainSafe.Gaming.Web3.Analytics
{
/// <summary>
/// Interface for the Analytics Client.
/// </summary>
public interface IAnalyticsClient
{
/// <summary>
/// Captures an analytics event.
/// </summary>
/// <param name="eventData">The analytics event data.</param>
void CaptureEvent(AnalyticsEvent eventData);
}
}
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
namespace ChainSafe.Gaming.Web3.Analytics
{
public class NoOpAnalyticsClient : IAnalyticsClient
internal class NoOpAnalyticsClient : IAnalyticsClient
{
public void CaptureEvent(AnalyticsEvent eventData)
{
Expand Down
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
using System.Linq;
using ChainSafe.Gaming.Web3.Build;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.DependencyInjection.Extensions;
Expand All @@ -6,10 +7,27 @@ namespace ChainSafe.Gaming.Web3.Analytics
{
public static class NoOpAnalyticsClientExtensions
{
/// <summary>
/// Disables analytics for the <see cref="Web3"/> instance.
/// </summary>
/// <param name="serviceCollection">The Web3 service collection.</param>
/// <returns>Service collection to enable fluent syntax.</returns>
public static IWeb3ServiceCollection DisableAnalytics(this IWeb3ServiceCollection serviceCollection)
{
serviceCollection.Replace(ServiceDescriptor.Singleton<IAnalyticsClient, NoOpAnalyticsClient>());
return serviceCollection;
}

/// <summary>
/// Returns true if analytics are disabled.
/// </summary>
/// <param name="serviceCollection">The Web3 service collection.</param>
/// <returns>True if analytics are disabled.</returns>
public static bool AnalyticsDisabled(this IWeb3ServiceCollection serviceCollection)
{
return serviceCollection.Any(d =>
d.ServiceType == typeof(IAnalyticsClient)
&& d.ImplementationType == typeof(NoOpAnalyticsClient));
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -2,10 +2,16 @@

namespace ChainSafe.Gaming.Web3.Build
{
/// <summary>
/// Collection of services to register in the Web3 dependency injection system.
/// </summary>
public interface IWeb3ServiceCollection : IServiceCollection
{
}

/// <summary>
/// Collection of services to register in the Web3 dependency injection system.
/// </summary>
public class Web3ServiceCollection : ServiceCollection, IWeb3ServiceCollection
{
}
Expand Down
3 changes: 3 additions & 0 deletions src/ChainSafe.Gaming/Web3/Core/Build/Web3BuildException.cs
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,9 @@

namespace ChainSafe.Gaming.Web3.Build
{
/// <summary>
/// Exception that indicates an error during <see cref="Web3"/> build process.
/// </summary>
public class Web3BuildException : Web3Exception
{
public Web3BuildException(string message)
Expand Down
35 changes: 28 additions & 7 deletions src/ChainSafe.Gaming/Web3/Core/Build/Web3Builder.cs
Original file line number Diff line number Diff line change
Expand Up @@ -10,13 +10,13 @@
namespace ChainSafe.Gaming.Web3.Build
{
/// <summary>
/// Builder object for Web3. Used to configure set of services.
/// Builder object for <see cref="Web3"/>. Used to configure the set of services and other settings.
/// </summary>
public class Web3Builder
{
private readonly Web3ServiceCollection serviceCollection;

public Web3Builder()
private Web3Builder()
{
serviceCollection = new Web3ServiceCollection();

Expand All @@ -27,31 +27,49 @@ public Web3Builder()
.AddSingleton<IContractBuilder, ContractBuilder>();
}

// TODO: inline parameterless constructor into this one (therefore remove that overload)
/// <summary>
/// Initializes a new instance of the <see cref="Web3Builder"/> class.
/// </summary>
/// <param name="projectConfig">Project config to use with the resulting Web3 instance.</param>
/// <param name="chainConfig">Chain config to use with the resulting Web3 instance.</param>
/// <exception cref="ArgumentException">One of the arguments is null.</exception>
public Web3Builder(IProjectConfig projectConfig, IChainConfig chainConfig)
: this()
{
if (projectConfig == null)
{
throw new Web3Exception($"{nameof(IProjectConfig)} is required for Web3 to work.");
throw new ArgumentNullException(nameof(projectConfig), $"{nameof(IProjectConfig)} is required for Web3 to work.");
}

if (chainConfig == null)
{
throw new Web3Exception($"{nameof(IChainConfig)} is required for Web3 to work.");
throw new ArgumentNullException(nameof(chainConfig), $"{nameof(IChainConfig)} is required for Web3 to work.");
}

serviceCollection.AddSingleton(projectConfig);
serviceCollection.AddSingleton(chainConfig);
}

/// <summary>
/// Initializes a new instance of the <see cref="Web3Builder"/> class.
/// </summary>
/// <param name="projectConfig">Complete project config to use with the resulting Web3 instance.</param>
/// <exception cref="ArgumentException">"projectConfig" is null.</exception>
public Web3Builder(ICompleteProjectConfig projectConfig)
: this(projectConfig, projectConfig)
{
}

/// <summary>
/// Delegate used to configure services for <see cref="Web3"/>.
/// </summary>
public delegate void ConfigureServicesDelegate(IWeb3ServiceCollection services);

/// <summary>
/// Configure services for <see cref="Web3"/>.
/// </summary>
/// <param name="configureMethod">Delegate used to configure services for <see cref="Web3"/>.</param>
/// <returns>Builder object to enable fluent syntax.</returns>
public Web3Builder Configure(ConfigureServicesDelegate configureMethod)
{
if (configureMethod is null)
Expand All @@ -63,13 +81,16 @@ public Web3Builder Configure(ConfigureServicesDelegate configureMethod)
return this;
}

/// <summary>
/// Build <see cref="Web3"/> object using the settings provided by this Web3Builder object.
/// </summary>
/// <returns><see cref="Web3"/> object.</returns>
public async ValueTask<Web3> BuildAsync()
{
var serviceProvider = serviceCollection.BuildServiceProvider();
AssertWeb3EnvironmentBound(serviceProvider);

var web3 = new Web3(serviceProvider);

await web3.InitializeAsync();

return web3;
Expand All @@ -86,7 +107,7 @@ private static void AssertWeb3EnvironmentBound(IServiceProvider serviceProvider)
{
var message = $"{nameof(Web3Environment)} is required for Web3 to work." +
"Don't forget to bind it when building Web3.";
throw new Web3Exception(message, e);
throw new Web3BuildException(message, e);
}
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,12 @@ namespace ChainSafe.Gaming.Web3.Build
{
public static class Web3ServiceCollectionExtensions
{
/// <summary>
/// Assert that service of the specified type was not yet registered.
/// </summary>
/// <typeparam name="T">The type of the service.</typeparam>
/// <param name="services">The Web3 service collection.</param>
/// <exception cref="Web3BuildException">Service of the specified type was already bound.</exception>
public static void AssertServiceNotBound<T>(this IWeb3ServiceCollection services)
{
var assertType = typeof(T);
Expand All @@ -16,6 +22,12 @@ public static void AssertServiceNotBound<T>(this IWeb3ServiceCollection services
}
}

/// <summary>
/// Assert that configuration object of the specified type was not yet registered.
/// </summary>
/// <typeparam name="T">The type of the configuration object.</typeparam>
/// <param name="services">The Web3 service collection.</param>
/// <exception cref="Web3BuildException">The configuration object of the specified type was already bound.</exception>
public static void AssertConfigurationNotBound<T>(this IWeb3ServiceCollection services)
{
var assertType = typeof(T);
Expand All @@ -26,6 +38,13 @@ public static void AssertConfigurationNotBound<T>(this IWeb3ServiceCollection se
}
}

/// <summary>
/// Register the specified implementation using 2 contract types.
/// </summary>
/// <typeparam name="TInterface1">The first contract type.</typeparam>
/// <typeparam name="TInterface2">The second contract type.</typeparam>
/// <typeparam name="TImplementation">The implementation type.</typeparam>
/// <param name="serviceCollection">The Web3 service collection.</param>
public static void AddSingleton<TInterface1, TInterface2, TImplementation>(this IWeb3ServiceCollection serviceCollection)
where TInterface1 : class
where TInterface2 : class
Expand All @@ -43,6 +62,14 @@ public static void AddSingleton<TInterface1, TInterface2, TImplementation>(this
serviceCollection.AddSingleton<TInterface2, TImplementation>(sp => sp.GetRequiredService<TImplementation>());
}

/// <summary>
/// Register the specified implementation for 2 contract types using the factory method.
/// </summary>
/// <param name="serviceCollection">The Web3 service collection.</param>
/// <param name="implementationFactory">The factory method.</param>
/// <typeparam name="TInterface1">The first contract type.</typeparam>
/// <typeparam name="TInterface2">The second contract type.</typeparam>
/// <typeparam name="TImplementation">The implementation type.</typeparam>
public static void AddSingleton<TInterface1, TInterface2, TImplementation>(this IWeb3ServiceCollection serviceCollection, Func<IServiceProvider, TImplementation> implementationFactory)
where TInterface1 : class
where TInterface2 : class
Expand All @@ -53,6 +80,14 @@ public static void AddSingleton<TInterface1, TInterface2, TImplementation>(this
serviceCollection.AddSingleton<TInterface2, TImplementation>(sp => sp.GetRequiredService<TImplementation>());
}

/// <summary>
/// Register the specified implementation using 3 contract types.
/// </summary>
/// <param name="serviceCollection">The Web3 service collection.</param>
/// <typeparam name="TInterface1">The first contract type.</typeparam>
/// <typeparam name="TInterface2">The second contract type.</typeparam>
/// <typeparam name="TInterface3">The third contract type.</typeparam>
/// <typeparam name="TImplementation">The implementation type.</typeparam>
public static void AddSingleton<TInterface1, TInterface2, TInterface3, TImplementation>(this IWeb3ServiceCollection serviceCollection)
where TInterface1 : class
where TInterface2 : class
Expand All @@ -65,6 +100,15 @@ public static void AddSingleton<TInterface1, TInterface2, TInterface3, TImplemen
serviceCollection.AddSingleton<TInterface3, TImplementation>(sp => sp.GetRequiredService<TImplementation>());
}

/// <summary>
/// Register the specified implementation for 3 contract types using the factory method.
/// </summary>
/// <param name="serviceCollection">The Web3 service collection.</param>
/// <param name="implementationFactory">Factory method.</param>
/// <typeparam name="TInterface1">The first contract type.</typeparam>
/// <typeparam name="TInterface2">The second contract type.</typeparam>
/// <typeparam name="TInterface3">The third contract type.</typeparam>
/// <typeparam name="TImplementation">The implementation type.</typeparam>
public static void AddSingleton<TInterface1, TInterface2, TInterface3, TImplementation>(this IWeb3ServiceCollection serviceCollection, Func<IServiceProvider, TImplementation> implementationFactory)
where TInterface1 : class
where TInterface2 : class
Expand Down
Loading

0 comments on commit cfeb6dc

Please sign in to comment.