Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

HyperPlay package added and remember me functionality #984

Merged
merged 10 commits into from
May 30, 2024
Merged
Show file tree
Hide file tree
Changes from 6 commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
using System.Threading.Tasks;
using ChainSafe.Gaming.Evm.JsonRpc;
using ChainSafe.Gaming.UnityPackage;
using ChainSafe.Gaming.Web3.Build;
using ChainSafe.Gaming.Web3.Unity;

namespace ChainSafe.Gaming.HyperPlay
{
/// <summary>
/// Helper class to build preconfigured Web3 clients for HyperPlay.
/// </summary>
public static class HyperPlayWeb3
{
/// <summary>
/// Builds a lightweight Web3 client with basic HyperPlay functionality.
/// </summary>
/// <param name="config">Your HyperPlay config.</param>
/// <returns>A lightweight version of Web3 client with basic HyperPlay functionality.</returns>
public static ValueTask<Web3.Web3> BuildLightweightWeb3(IHyperPlayConfig config)
{
var projectConfig = ProjectConfigUtilities.Load();

return new Web3Builder(projectConfig).Configure(services =>
{
services.UseUnityEnvironment();
services.UseRpcProvider();
services.UseHyperPlay(config);
}).LaunchAsync();
}
}
}

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
{
"name": "io.chainsafe.web3-unity.hyperplay.runtime",
"rootNamespace": "ChainSafe.Gaming.HyperPlay",
"references": [
"GUID:5426c6b788696eb4c88f4198b59839eb"
],
"includePlatforms": [],
"excludePlatforms": [],
"allowUnsafeCode": false,
"overrideReferences": false,
"precompiledReferences": [],
"autoReferenced": true,
"defineConstraints": [],
"versionDefines": [],
"noEngineReferences": false
}

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

33 changes: 33 additions & 0 deletions Packages/io.chainsafe.web3-unity.hyperplay/package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
{
"name": "io.chainsafe.web3-unity.hyperplay",
"version": "1.0.0",
"displayName": "web3.unity SDK HyperPlay",
"description": "This package includes the integration of HyperPlay, which you can use with our Gaming SDK.",
"license": "LGPL-3.0-only",
"licensesUrl": "https://github.com/ChainSafe/web3.unity/blob/main/LICENSE",
"documentationUrl": "https://docs.gaming.chainsafe.io/",
"dependencies": {
"com.unity.nuget.newtonsoft-json": "3.0.2",
"io.chainsafe.web3-unity": "2.6.0"
},
"keywords": [
"web3",
"ethereum",
"evm",
"blockchain",
"nft",
"hyperplay"
],
"author": {
"name": "ChainSafe Gaming",
"email": "[email protected]",
"url": "https://gaming.chainsafe.io/"
},
"samples": [
{
"displayName": "HyperPlay Usage Sample",
"description": "Contains example of integration and usage of HyperPlay functionality.",
"path": "Samples~/Web3.Unity HyperPlay Samples"
}
]
}
7 changes: 7 additions & 0 deletions Packages/io.chainsafe.web3-unity.hyperplay/package.json.meta

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

5 changes: 3 additions & 2 deletions scripts/data/published_dependencies.txt
Original file line number Diff line number Diff line change
@@ -1,2 +1,3 @@
Packages/io.chainsafe.web3-unity/Runtime/Libraries/:ADRaffy.ENSNormalize;Nethereum.Model;BouncyCastle.Crypto;Nethereum.RLP;ChainSafe.Gaming.Debugging;Nethereum.RPC;ChainSafe.Gaming.Gelato;ChainSafe.Gaming.SygmaClient;Nethereum.Signer.EIP712;ChainSafe.Gaming.InProcessSigner;Nethereum.Signer;ChainSafe.Gaming.InProcessTransactionExecutor;Nethereum.Util;ChainSafe.Gaming.Unity.ThirdParty;Nethereum.Web3;ChainSafe.Gaming.Unity;System.Buffers;ChainSafe.Gaming.WalletConnect;System.Memory;ChainSafe.Gaming;System.Numerics.Vectors;Microsoft.Bcl.AsyncInterfaces;System.Reactive;Microsoft.Extensions.DependencyInjection.Abstractions;System.Runtime.CompilerServices.Unsafe;Microsoft.Extensions.DependencyInjection;System.Runtime.InteropServices.WindowsRuntime;Microsoft.Extensions.Logging.Abstractions;System.Security.Cryptography.Cng;Microsoft.IdentityModel.Abstractions;System.Text.Encodings.Web;Microsoft.IdentityModel.Logging;System.Text.Json;Microsoft.IdentityModel.Tokens;System.Threading.Channels;NBitcoin;System.Threading.Tasks.Extensions;Nethereum.ABI;WalletConnectSharp.Auth;Nethereum.Accounts;WalletConnectSharp.Common;WalletConnectSharp.Events;Nethereum.BlockchainProcessing;WalletConnectSharp.Core;Nethereum.Contracts;WalletConnectSharp.Crypto;Nethereum.Hex;Nethereum.JsonRpc.Client;WalletConnectSharp.Network.Websocket;Nethereum.JsonRpc.IpcClient;WalletConnectSharp.Network;Nethereum.JsonRpc.RpcClient;WalletConnectSharp.Sign;Nethereum.KeyStore;WalletConnectSharp.Storage;Nethereum.Merkle.Patricia;WalletConnectSharp.Web3Wallet;Nethereum.Merkle;Websocket.Client;Nethereum.Metamask;Nethereum.Siwe.Core;Nethereum.Siwe;Nethereum.UI;Nethereum.Unity.Metamask;Nethereum.Unity;ChainSafe.Gaming.MetaMask;ChainSafe.Gaming.MetaMask.Unity;ChainSafe.Gaming.InProcessTransactionExecutor.Unity;ChainSafe.Gaming.Marketplace;ChainSafe.Gaming.HyperPlay
Packages/io.chainsafe.web3-unity.lootboxes/Chainlink/Runtime/Libraries/:Chainsafe.Gaming.Chainlink;ChainSafe.Gaming.Lootboxes.Chainlink
Packages/io.chainsafe.web3-unity/Runtime/Libraries/:ADRaffy.ENSNormalize;Nethereum.Model;BouncyCastle.Crypto;Nethereum.RLP;ChainSafe.Gaming.Debugging;Nethereum.RPC;ChainSafe.Gaming.Gelato;ChainSafe.Gaming.SygmaClient;Nethereum.Signer.EIP712;ChainSafe.Gaming.InProcessSigner;Nethereum.Signer;ChainSafe.Gaming.InProcessTransactionExecutor;Nethereum.Util;ChainSafe.Gaming.Unity.ThirdParty;Nethereum.Web3;ChainSafe.Gaming.Unity;System.Buffers;ChainSafe.Gaming.WalletConnect;System.Memory;ChainSafe.Gaming;System.Numerics.Vectors;Microsoft.Bcl.AsyncInterfaces;System.Reactive;Microsoft.Extensions.DependencyInjection.Abstractions;System.Runtime.CompilerServices.Unsafe;Microsoft.Extensions.DependencyInjection;System.Runtime.InteropServices.WindowsRuntime;Microsoft.Extensions.Logging.Abstractions;System.Security.Cryptography.Cng;Microsoft.IdentityModel.Abstractions;System.Text.Encodings.Web;Microsoft.IdentityModel.Logging;System.Text.Json;Microsoft.IdentityModel.Tokens;System.Threading.Channels;NBitcoin;System.Threading.Tasks.Extensions;Nethereum.ABI;WalletConnectSharp.Auth;Nethereum.Accounts;WalletConnectSharp.Common;WalletConnectSharp.Events;Nethereum.BlockchainProcessing;WalletConnectSharp.Core;Nethereum.Contracts;WalletConnectSharp.Crypto;Nethereum.Hex;Nethereum.JsonRpc.Client;WalletConnectSharp.Network.Websocket;Nethereum.JsonRpc.IpcClient;WalletConnectSharp.Network;Nethereum.JsonRpc.RpcClient;WalletConnectSharp.Sign;Nethereum.KeyStore;WalletConnectSharp.Storage;Nethereum.Merkle.Patricia;WalletConnectSharp.Web3Wallet;Nethereum.Merkle;Websocket.Client;Nethereum.Metamask;Nethereum.Siwe.Core;Nethereum.Siwe;Nethereum.UI;Nethereum.Unity.Metamask;Nethereum.Unity;ChainSafe.Gaming.MetaMask;ChainSafe.Gaming.MetaMask.Unity;ChainSafe.Gaming.InProcessTransactionExecutor.Unity;ChainSafe.Gaming.Marketplace
Packages/io.chainsafe.web3-unity.lootboxes/Chainlink/Runtime/Libraries/:Chainsafe.Gaming.Chainlink;ChainSafe.Gaming.Lootboxes.Chainlink
Packages/io.chainsafe.web3-unity.hyperplay/Runtime/Libraries/:ChainSafe.Gaming.HyperPlay
14 changes: 14 additions & 0 deletions src/ChainSafe.Gaming.HyperPlay/HyperPlayConfig.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
namespace ChainSafe.Gaming.HyperPlay
{
/// <summary>
/// Config for a HyperPlay connection.
/// </summary>
public class HyperPlayConfig : IHyperPlayConfig
{
/// <summary>
/// Remember the HyperPlay session.
/// Like remember me for login.
/// </summary>
public bool RememberSession { get; set; }
}
}
20 changes: 20 additions & 0 deletions src/ChainSafe.Gaming.HyperPlay/HyperPlayData.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
using Newtonsoft.Json;

namespace ChainSafe.Gaming.HyperPlay
{
/// <summary>
/// Concrete implementation of <see cref="IHyperPlayData"/>.
/// </summary>
public class HyperPlayData : IHyperPlayData
{
[JsonIgnore]
public string StoragePath => "hyperplay-data.json";

[JsonIgnore]
public bool LoadOnInitialize => true;

public bool RememberSession { get; set; }

public string SavedAccount { get; set; }
}
}
12 changes: 10 additions & 2 deletions src/ChainSafe.Gaming.HyperPlay/HyperPlayExtensions.cs
Original file line number Diff line number Diff line change
@@ -1,9 +1,12 @@
using ChainSafe.Gaming.Evm.Signers;
using ChainSafe.Gaming.LocalStorage;
using ChainSafe.Gaming.Web3.Build;
using ChainSafe.Gaming.Web3.Core;
using ChainSafe.Gaming.Web3.Core.Evm;
using ChainSafe.Gaming.Web3.Core.Logout;
using ChainSafe.Gaming.Web3.Evm.Wallet;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.DependencyInjection.Extensions;

namespace ChainSafe.Gaming.HyperPlay
{
Expand All @@ -13,13 +16,18 @@ public static class HyperPlayExtensions
/// Binds implementation of <see cref="IWalletProvider"/> as <see cref="HyperPlayProvider"/> to Web3 as a service.
/// </summary>
/// <param name="collection">Service collection to bind implementations to.</param>
/// <param name="config">Config for connecting via HyperPlay.</param>
/// <returns>The same service collection that was passed in. This enables fluent style.</returns>
public static IWeb3ServiceCollection UseHyperPlay(this IWeb3ServiceCollection collection)
public static IWeb3ServiceCollection UseHyperPlay(this IWeb3ServiceCollection collection, IHyperPlayConfig config)
{
collection.AssertServiceNotBound<IWalletProvider>();

collection.AddSingleton<IWalletProvider, HyperPlayProvider>();

collection.AddSingleton<IHyperPlayData, IStorable, HyperPlayData>();

collection.Replace(ServiceDescriptor.Singleton(typeof(IHyperPlayConfig), config));

return collection;
}

Expand All @@ -32,7 +40,7 @@ public static IWeb3ServiceCollection UseHyperPlaySigner(this IWeb3ServiceCollect
{
collection.AssertServiceNotBound<ISigner>();

collection.AddSingleton<ILifecycleParticipant, ISigner, HyperPlaySigner>();
collection.AddSingleton<ILifecycleParticipant, ISigner, ILogoutHandler, HyperPlaySigner>();

return collection;
}
Expand Down
34 changes: 31 additions & 3 deletions src/ChainSafe.Gaming.HyperPlay/HyperPlayProvider.cs
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,11 @@
using System.Threading.Tasks;
using ChainSafe.Gaming.Evm;
using ChainSafe.Gaming.HyperPlay.Dto;
using ChainSafe.Gaming.LocalStorage;
using ChainSafe.Gaming.Web3;
using ChainSafe.Gaming.Web3.Core;
using ChainSafe.Gaming.Web3.Core.Debug;
using ChainSafe.Gaming.Web3.Core.Logout;
using ChainSafe.Gaming.Web3.Environment;
using ChainSafe.Gaming.Web3.Evm.Wallet;
using Nethereum.Signer;
Expand All @@ -18,18 +21,27 @@ namespace ChainSafe.Gaming.HyperPlay
/// </summary>
public class HyperPlayProvider : WalletProvider
{
private readonly IHyperPlayConfig config;
private readonly IHyperPlayData data;
private readonly DataStorage dataStorage;
private readonly IHttpClient httpClient;
private readonly IChainConfig chainConfig;

/// <summary>
/// Initializes a new instance of the <see cref="HyperPlayProvider"/> class.
/// </summary>
/// <param name="config">Injected <see cref="HyperPlayConfig"/>.</param>
/// <param name="data">Injected <see cref="IHyperPlayData"/>.</param>
/// <param name="dataStorage">Injected <see cref="DataStorage"/>.</param>
/// <param name="httpClient">HttpClient to make requests.</param>
/// <param name="chainConfig">ChainConfig to fetch chain data.</param>
/// <param name="chainRegistryProvider">Injected <see cref="ChainRegistryProvider"/>.</param>
public HyperPlayProvider(IHttpClient httpClient, IChainConfig chainConfig, ChainRegistryProvider chainRegistryProvider)
public HyperPlayProvider(IHyperPlayConfig config, IHyperPlayData data, DataStorage dataStorage, IHttpClient httpClient, IChainConfig chainConfig, ChainRegistryProvider chainRegistryProvider)
: base(chainRegistryProvider: chainRegistryProvider)
{
this.config = config;
this.data = data;
this.dataStorage = dataStorage;
this.httpClient = httpClient;
this.chainConfig = chainConfig;
}
Expand All @@ -44,6 +56,12 @@ public override async Task<string> Connect()

string account = accounts[0].AssertIsPublicAddress(nameof(account));

// Saved account exists.
if (data.RememberSession && data.SavedAccount == account)
{
return account;
}

string message = "Sign-in with Ethereum";

string hash = await Perform<string>("personal_sign", message, account);
Expand All @@ -63,12 +81,22 @@ public override async Task<string> Connect()
throw new Web3Exception("Fetched address does not match the signing address.");
}

if (config.RememberSession)
{
data.RememberSession = true;

data.SavedAccount = account;

await dataStorage.Save(data);
}

return account;
}

public override Task Disconnect()
{
// currently HyperPlay doesn't support disconnecting.
dataStorage.Clear(data);

return Task.CompletedTask;
}

Expand All @@ -94,7 +122,7 @@ public override async Task<T> Perform<T>(string method, params object[] paramete
},
});

string response = (await httpClient.PostRaw("http://localhost:9680/rpc", body, "application/json")).Response;
string response = (await httpClient.PostRaw(config.Url, body, "application/json")).Response;

// In case response is just a primitive type like string/number...
// Deserializing it directly doesn't work.
Expand Down
8 changes: 7 additions & 1 deletion src/ChainSafe.Gaming.HyperPlay/HyperPlaySigner.cs
Original file line number Diff line number Diff line change
Expand Up @@ -2,14 +2,15 @@
using ChainSafe.Gaming.Evm.Signers;
using ChainSafe.Gaming.Web3.Core;
using ChainSafe.Gaming.Web3.Core.Evm;
using ChainSafe.Gaming.Web3.Core.Logout;
using ChainSafe.Gaming.Web3.Evm.Wallet;

namespace ChainSafe.Gaming.HyperPlay
{
/// <summary>
/// Concrete implementation of <see cref="ISigner"/> via HyperPlay desktop client.
/// </summary>
public class HyperPlaySigner : ISigner, ILifecycleParticipant
public class HyperPlaySigner : ISigner, ILifecycleParticipant, ILogoutHandler
{
private readonly IWalletProvider walletProvider;

Expand Down Expand Up @@ -57,5 +58,10 @@ public ValueTask WillStopAsync()
{
return new ValueTask(Task.CompletedTask);
}

public async Task OnLogout()
{
await walletProvider.Disconnect();
}
}
}
18 changes: 18 additions & 0 deletions src/ChainSafe.Gaming.HyperPlay/IHyperPlayConfig.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
namespace ChainSafe.Gaming.HyperPlay
{
/// <summary>
/// Config for a HyperPlay connection.
/// </summary>
public interface IHyperPlayConfig
{
/// <summary>
/// Url for connecting to HyperPlay desktop client.
/// </summary>
public string Url => "http://localhost:9680/rpc";

/// <summary>
/// Remember a connected session.
/// </summary>
public bool RememberSession { get; set; }
}
}
21 changes: 21 additions & 0 deletions src/ChainSafe.Gaming.HyperPlay/IHyperPlayData.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
using ChainSafe.Gaming.LocalStorage;

namespace ChainSafe.Gaming.HyperPlay
{
/// <summary>
/// <see cref="IStorable"/> data for HyperPlay.
/// Persisted data for HyperPlay.
/// </summary>
public interface IHyperPlayData : IStorable
{
/// <summary>
/// Remember session from a previous connection.
/// </summary>
public bool RememberSession { get; set; }

/// <summary>
/// Saved account from a previous session.
/// </summary>
public string SavedAccount { get; set; }
}
}
Loading