diff --git a/Explorer/Assets/DCL/AuthenticationScreenFlow/AuthenticationScreenController.cs b/Explorer/Assets/DCL/AuthenticationScreenFlow/AuthenticationScreenController.cs index 25cae69162..2643c00d54 100644 --- a/Explorer/Assets/DCL/AuthenticationScreenFlow/AuthenticationScreenController.cs +++ b/Explorer/Assets/DCL/AuthenticationScreenFlow/AuthenticationScreenController.cs @@ -1,6 +1,7 @@ using Arch.Core; using Cysharp.Threading.Tasks; using DCL.Audio; +using DCL.Web3; using DCL.Browser; using DCL.CharacterPreview; using DCL.Diagnostics; @@ -10,13 +11,12 @@ using DCL.Profiles.Self; using DCL.SceneLoadingScreens.SplashScreen; using DCL.UI; -using DCL.Web3; using DCL.Web3.Authenticators; using DCL.Web3.Identities; using MVC; using System; -using System.Collections.Generic; using System.Threading; +using System.Collections.Generic; using UnityEngine; using UnityEngine.Assertions; using UnityEngine.Localization.SmartFormat.PersistentVariables; @@ -34,6 +34,7 @@ private enum ViewState Loading, Finalize, } + private const int ANIMATION_DELAY = 300; private const string REQUEST_BETA_ACCESS_LINK = "https://68zbqa0m12c.typeform.com/to/y9fZeNWm"; @@ -153,6 +154,7 @@ private async UniTaskVoid CheckValidIdentityAndStartInitialFlowAsync() IWeb3Identity? storedIdentity = storedIdentityProvider.Identity; if (storedIdentity is { IsExpired: false } + // Force to re-login if the identity will expire in 24hs or less, so we mitigate the chances on // getting the identity expired while in-world, provoking signed-fetch requests to fail && storedIdentity.Expiration - DateTime.UtcNow > TimeSpan.FromDays(1)) diff --git a/Explorer/Assets/DCL/AuthenticationScreenFlow/AuthenticationScreenFlow.asmdef b/Explorer/Assets/DCL/AuthenticationScreenFlow/AuthenticationScreenFlow.asmdef index a23ec16f82..d9956eea4c 100644 --- a/Explorer/Assets/DCL/AuthenticationScreenFlow/AuthenticationScreenFlow.asmdef +++ b/Explorer/Assets/DCL/AuthenticationScreenFlow/AuthenticationScreenFlow.asmdef @@ -22,7 +22,8 @@ "GUID:ace653ac543d483ba8abee112a3ba2a6", "GUID:e169fa6683c924c7e99a85981a91d953", "GUID:e7751264a6735a942a64770d71eb49e0", - "GUID:0401f68d61b24c63a3abf51e27bb46f1" + "GUID:0401f68d61b24c63a3abf51e27bb46f1", + "GUID:ca4e81cdd6a34d1aa54c32ad41fc5b3b" ], "includePlatforms": [], "excludePlatforms": [], diff --git a/Explorer/Assets/DCL/AvatarRendering/Wearables/Wearables.asmdef b/Explorer/Assets/DCL/AvatarRendering/Wearables/Wearables.asmdef index c1c0871b55..0c2e1fc6a2 100644 --- a/Explorer/Assets/DCL/AvatarRendering/Wearables/Wearables.asmdef +++ b/Explorer/Assets/DCL/AvatarRendering/Wearables/Wearables.asmdef @@ -18,6 +18,7 @@ "GUID:b46779583a009f04ba9f5f31d0e7e6ac", "GUID:56e8195b069a4dca9c4c4f313c65f526", "GUID:e25ef972de004615a22937e739de2def", + "GUID:ca4e81cdd6a34d1aa54c32ad41fc5b3b", "GUID:5ab29fa8ae5769b49ab29e390caca7a4", "GUID:91cf8206af184dac8e30eb46747e9939" ], diff --git a/Explorer/Assets/DCL/Backpack/Backpack.asmdef b/Explorer/Assets/DCL/Backpack/Backpack.asmdef index 82349ab277..5e205eebe8 100644 --- a/Explorer/Assets/DCL/Backpack/Backpack.asmdef +++ b/Explorer/Assets/DCL/Backpack/Backpack.asmdef @@ -27,7 +27,8 @@ "GUID:eec0964c48f6f4e40bc3ec2257ccf8c5", "GUID:ac3295688c7c22745a96e6ac34718181", "GUID:d832748739a186646b8656bdbd447ad0", - "GUID:f95dba842fdbb470fb6d1dced822ba04" + "GUID:f95dba842fdbb470fb6d1dced822ba04", + "GUID:ca4e81cdd6a34d1aa54c32ad41fc5b3b" ], "includePlatforms": [], "excludePlatforms": [], diff --git a/Explorer/Assets/DCL/Chat/Chat.asmdef b/Explorer/Assets/DCL/Chat/Chat.asmdef index 48762ec264..120d228112 100644 --- a/Explorer/Assets/DCL/Chat/Chat.asmdef +++ b/Explorer/Assets/DCL/Chat/Chat.asmdef @@ -28,7 +28,8 @@ "GUID:e0eedfa2deb9406daf86fd8368728e39", "GUID:7175400a68914a45acecc9fb068de3b8", "GUID:875a5d5129614170bd769ed012c2eb3d", - "GUID:f4a0f40a2545482b8929d4c3c642f50a" + "GUID:f4a0f40a2545482b8929d4c3c642f50a", + "GUID:ca4e81cdd6a34d1aa54c32ad41fc5b3b" ], "includePlatforms": [], "excludePlatforms": [], diff --git a/Explorer/Assets/DCL/FeatureFlags/DCL.FeatureFlags.asmdef b/Explorer/Assets/DCL/FeatureFlags/DCL.FeatureFlags.asmdef index a2310e5f4a..7d072193bc 100644 --- a/Explorer/Assets/DCL/FeatureFlags/DCL.FeatureFlags.asmdef +++ b/Explorer/Assets/DCL/FeatureFlags/DCL.FeatureFlags.asmdef @@ -7,6 +7,7 @@ "GUID:5ab29fa8ae5769b49ab29e390caca7a4", "GUID:f51ebe6a0ceec4240a699833d6309b23", "GUID:101b8b6ebaf64668909b49c4b7a1420d", + "GUID:ca4e81cdd6a34d1aa54c32ad41fc5b3b", "GUID:91cf8206af184dac8e30eb46747e9939", "GUID:8baf705856414dad9a73b3f382f1bc8b" ], diff --git a/Explorer/Assets/DCL/Multiplayer/Connections/DCL.Multiplayer.Connections.asmdef b/Explorer/Assets/DCL/Multiplayer/Connections/DCL.Multiplayer.Connections.asmdef index 00810b6c0e..18767fef3b 100644 --- a/Explorer/Assets/DCL/Multiplayer/Connections/DCL.Multiplayer.Connections.asmdef +++ b/Explorer/Assets/DCL/Multiplayer/Connections/DCL.Multiplayer.Connections.asmdef @@ -15,7 +15,8 @@ "GUID:006c0e0a70294dbba8a4cbcfb77e1f7d", "GUID:e0eedfa2deb9406daf86fd8368728e39", "GUID:3640f3c0b42946b0b8794a1ed8e06ca5", - "GUID:d414ef88f3b15f746a4b97636b50dfb4" + "GUID:d414ef88f3b15f746a4b97636b50dfb4", + "GUID:ca4e81cdd6a34d1aa54c32ad41fc5b3b" ], "includePlatforms": [], "excludePlatforms": [], diff --git a/Explorer/Assets/DCL/Multiplayer/Connections/Demo/ArchipelagoFakeIdentityCache.cs b/Explorer/Assets/DCL/Multiplayer/Connections/Demo/ArchipelagoFakeIdentityCache.cs index 8357533fee..1fa7dfa384 100644 --- a/Explorer/Assets/DCL/Multiplayer/Connections/Demo/ArchipelagoFakeIdentityCache.cs +++ b/Explorer/Assets/DCL/Multiplayer/Connections/Demo/ArchipelagoFakeIdentityCache.cs @@ -1,5 +1,6 @@ using Cysharp.Threading.Tasks; using DCL.Multiplayer.Connections.DecentralandUrls; +using DCL.Web3.Abstract; using DCL.Web3.Authenticators; using DCL.Web3.Identities; using System.Threading; @@ -8,19 +9,24 @@ namespace DCL.Multiplayer.Connections.Demo { public static class ArchipelagoFakeIdentityCache { - public static async UniTask NewAsync(IDecentralandUrlsSource decentralandUrlsSource) + public static async UniTask NewAsync( + IDecentralandUrlsSource decentralandUrlsSource, + IWeb3AccountFactory web3AccountFactory + ) { IWeb3IdentityCache identityCache = new ProxyIdentityCache( new MemoryWeb3IdentityCache(), new PlayerPrefsIdentityProvider( - new PlayerPrefsIdentityProvider.DecentralandIdentityWithNethereumAccountJsonSerializer(), + new PlayerPrefsIdentityProvider.DecentralandIdentityWithNethereumAccountJsonSerializer( + web3AccountFactory + ), "ArchipelagoTestIdentity" ) ); if (identityCache.Identity is null) { - IWeb3Identity? identity = await new DappWeb3Authenticator.Default(identityCache, decentralandUrlsSource) + IWeb3Identity? identity = await new DappWeb3Authenticator.Default(identityCache, decentralandUrlsSource, web3AccountFactory) .LoginAsync(CancellationToken.None); identityCache.Identity = identity; diff --git a/Explorer/Assets/DCL/Multiplayer/Connections/Demo/ArchipelagoRoomPlayground.cs b/Explorer/Assets/DCL/Multiplayer/Connections/Demo/ArchipelagoRoomPlayground.cs index 674b0df9d4..c627e526e3 100644 --- a/Explorer/Assets/DCL/Multiplayer/Connections/Demo/ArchipelagoRoomPlayground.cs +++ b/Explorer/Assets/DCL/Multiplayer/Connections/Demo/ArchipelagoRoomPlayground.cs @@ -12,6 +12,7 @@ using DCL.Multiplayer.Connections.Pools; using DCL.Multiplayer.Connections.Systems; using DCL.UserInAppInitializationFlow; +using DCL.Web3.Accounts.Factory; using DCL.Web3.Identities; using ECS; using ECS.Abstract; @@ -59,7 +60,7 @@ private async UniTaskVoid LaunchAsync() multiPool ).WithLog(); - IWeb3IdentityCache? identityCache = await ArchipelagoFakeIdentityCache.NewAsync(new DecentralandUrlsSource(DecentralandEnvironment.Zone)); + IWeb3IdentityCache? identityCache = await ArchipelagoFakeIdentityCache.NewAsync(new DecentralandUrlsSource(DecentralandEnvironment.Zone), new Web3AccountFactory()); var archipelagoIslandRoom = new ArchipelagoIslandRoom( identityCache, diff --git a/Explorer/Assets/DCL/Multiplayer/Connections/Demo/GateKeeperRoomPlayground.cs b/Explorer/Assets/DCL/Multiplayer/Connections/Demo/GateKeeperRoomPlayground.cs index 9d6629ec7c..b5fcba3a04 100644 --- a/Explorer/Assets/DCL/Multiplayer/Connections/Demo/GateKeeperRoomPlayground.cs +++ b/Explorer/Assets/DCL/Multiplayer/Connections/Demo/GateKeeperRoomPlayground.cs @@ -8,6 +8,7 @@ using DCL.Multiplayer.Connections.GateKeeper.Meta; using DCL.Multiplayer.Connections.GateKeeper.Rooms; using DCL.PlacesAPIService; +using DCL.Web3.Accounts.Factory; using DCL.Web3.Identities; using DCL.WebRequests; using ECS; @@ -32,7 +33,7 @@ private async UniTaskVoid LaunchAsync() var urlsSource = new DecentralandUrlsSource(DecentralandEnvironment.Zone); - IWeb3IdentityCache? identityCache = await ArchipelagoFakeIdentityCache.NewAsync(urlsSource); + IWeb3IdentityCache? identityCache = await ArchipelagoFakeIdentityCache.NewAsync(urlsSource, new Web3AccountFactory()); var character = new ICharacterObject.Fake(Vector3.zero); var webRequests = new LogWebRequestController(new WebRequestController(identityCache)); var places = new PlacesAPIService.PlacesAPIService(new PlacesAPIClient(webRequests, urlsSource)); diff --git a/Explorer/Assets/DCL/PerformanceAndDiagnostics/Analytics/DCL.Analytics.asmdef b/Explorer/Assets/DCL/PerformanceAndDiagnostics/Analytics/DCL.Analytics.asmdef index 3d14444e5b..7fab6ce537 100644 --- a/Explorer/Assets/DCL/PerformanceAndDiagnostics/Analytics/DCL.Analytics.asmdef +++ b/Explorer/Assets/DCL/PerformanceAndDiagnostics/Analytics/DCL.Analytics.asmdef @@ -21,7 +21,8 @@ "GUID:5eabe9a3d4dd19d42a16208ea5411062", "GUID:6830e2f56251b492e9934f1fafbc8c7d", "GUID:45fc0f02fe4e57c4a93a421d8f6f53df", - "GUID:e169fa6683c924c7e99a85981a91d953" + "GUID:e169fa6683c924c7e99a85981a91d953", + "GUID:ca4e81cdd6a34d1aa54c32ad41fc5b3b" ], "includePlatforms": [], "excludePlatforms": [], diff --git a/Explorer/Assets/DCL/PluginSystem/DCL.Plugins.asmdef b/Explorer/Assets/DCL/PluginSystem/DCL.Plugins.asmdef index 1ccf0bae3e..a640c94226 100644 --- a/Explorer/Assets/DCL/PluginSystem/DCL.Plugins.asmdef +++ b/Explorer/Assets/DCL/PluginSystem/DCL.Plugins.asmdef @@ -124,7 +124,8 @@ "GUID:c5db5ed4ea75a402dba1512abe9482ec", "GUID:a285ec5e26824438b1b2ab8f22969298", "GUID:a0d83a4df040477894e767d4333169ec", - "GUID:8baf705856414dad9a73b3f382f1bc8b" + "GUID:8baf705856414dad9a73b3f382f1bc8b", + "GUID:ca4e81cdd6a34d1aa54c32ad41fc5b3b" ], "includePlatforms": [], "excludePlatforms": [], diff --git a/Explorer/Assets/DCL/Profiles/DCL.Profiles.asmdef b/Explorer/Assets/DCL/Profiles/DCL.Profiles.asmdef index 2caf431685..5e92c2c3c9 100644 --- a/Explorer/Assets/DCL/Profiles/DCL.Profiles.asmdef +++ b/Explorer/Assets/DCL/Profiles/DCL.Profiles.asmdef @@ -20,7 +20,8 @@ "GUID:9e314663ce958b746873cb22d57ede55", "GUID:9e24947de15b9834991c9d8411ea37cf", "GUID:166b65e6dfc848bb9fb075f53c293a38", - "GUID:3c7b57a14671040bd8c549056adc04f5" + "GUID:3c7b57a14671040bd8c549056adc04f5", + "GUID:ca4e81cdd6a34d1aa54c32ad41fc5b3b" ], "includePlatforms": [], "excludePlatforms": [], diff --git a/Explorer/Assets/DCL/SDKComponents/AudioSources/Tests/PlayMode/SDKAudioSourcesAutomatedTests.cs b/Explorer/Assets/DCL/SDKComponents/AudioSources/Tests/PlayMode/SDKAudioSourcesAutomatedTests.cs index 68da7a4592..58b3165cbe 100644 --- a/Explorer/Assets/DCL/SDKComponents/AudioSources/Tests/PlayMode/SDKAudioSourcesAutomatedTests.cs +++ b/Explorer/Assets/DCL/SDKComponents/AudioSources/Tests/PlayMode/SDKAudioSourcesAutomatedTests.cs @@ -11,6 +11,7 @@ using DCL.PluginSystem.World; using DCL.Profiles; using DCL.Web3; +using DCL.Web3.Accounts.Factory; using DCL.Web3.Authenticators; using DCL.Web3.Identities; using DCL.WebRequests; @@ -90,8 +91,9 @@ private async UniTask InitializationFlowAsync(CancellationToken ct) try { var identityCache = new MemoryWeb3IdentityCache(); + var web3AccountFactory = new Web3AccountFactory(); - var web3Authenticator = new ProxyWeb3Authenticator(new RandomGeneratedWeb3Authenticator(), identityCache); + var web3Authenticator = new ProxyWeb3Authenticator(new RandomGeneratedWeb3Authenticator(web3AccountFactory), identityCache); await web3Authenticator.LoginAsync(ct); SceneSharedContainer sceneSharedContainer; diff --git a/Explorer/Assets/DCL/Tests/Editor/ValidationTests.cs b/Explorer/Assets/DCL/Tests/Editor/ValidationTests.cs index df1e08554d..5c7b582d7c 100644 --- a/Explorer/Assets/DCL/Tests/Editor/ValidationTests.cs +++ b/Explorer/Assets/DCL/Tests/Editor/ValidationTests.cs @@ -34,6 +34,7 @@ public class ValidationTests private readonly IReadOnlyCollection pathIgnores = new List { "node_modules", + "sign-server" }; [Test] diff --git a/Explorer/Assets/DCL/Tests/PlayMode/DCL.PlayMode.Tests.asmdef b/Explorer/Assets/DCL/Tests/PlayMode/DCL.PlayMode.Tests.asmdef index 0d4b0b5bbf..8cb5576f0a 100644 --- a/Explorer/Assets/DCL/Tests/PlayMode/DCL.PlayMode.Tests.asmdef +++ b/Explorer/Assets/DCL/Tests/PlayMode/DCL.PlayMode.Tests.asmdef @@ -60,8 +60,9 @@ "GUID:c54a193e9535e43d8a25007ab5ee28b1", "GUID:91cf8206af184dac8e30eb46747e9939", "GUID:7175400a68914a45acecc9fb068de3b8", + "GUID:8baf705856414dad9a73b3f382f1bc8b", "GUID:a0d83a4df040477894e767d4333169ec", - "GUID:8baf705856414dad9a73b3f382f1bc8b" + "GUID:ca4e81cdd6a34d1aa54c32ad41fc5b3b" ], "includePlatforms": [], "excludePlatforms": [ diff --git a/Explorer/Assets/DCL/UI/Profile/ProfileElements/UI.ProfileElements.asmdef b/Explorer/Assets/DCL/UI/Profile/ProfileElements/UI.ProfileElements.asmdef index bf1264c5b5..d5795c05a5 100644 --- a/Explorer/Assets/DCL/UI/Profile/ProfileElements/UI.ProfileElements.asmdef +++ b/Explorer/Assets/DCL/UI/Profile/ProfileElements/UI.ProfileElements.asmdef @@ -10,7 +10,8 @@ "GUID:45f6fff651a0a514f8edfdaf9cce45af", "GUID:5ab29fa8ae5769b49ab29e390caca7a4", "GUID:4a12c0b1b77ec6b418a8d7bd5c925be3", - "GUID:fa7b3fdbb04d67549916da7bd2af58ab" + "GUID:fa7b3fdbb04d67549916da7bd2af58ab", + "GUID:ca4e81cdd6a34d1aa54c32ad41fc5b3b" ], "includePlatforms": [], "excludePlatforms": [], diff --git a/Explorer/Assets/DCL/UI/Sidebar/UI.Sidebar.asmdef b/Explorer/Assets/DCL/UI/Sidebar/UI.Sidebar.asmdef index 747968a20d..c142774715 100644 --- a/Explorer/Assets/DCL/UI/Sidebar/UI.Sidebar.asmdef +++ b/Explorer/Assets/DCL/UI/Sidebar/UI.Sidebar.asmdef @@ -21,7 +21,8 @@ "GUID:a327cdd867b4c134c92b67c566c92ad7", "GUID:766b242fb43af451aaa331f39872177d", "GUID:52421c42d33594c47a6fbd48b45b1259", - "GUID:df934776371151c45b473e9aa39efd1b" + "GUID:df934776371151c45b473e9aa39efd1b", + "GUID:ca4e81cdd6a34d1aa54c32ad41fc5b3b" ], "includePlatforms": [], "excludePlatforms": [], diff --git a/Explorer/Assets/DCL/UI/Sidebar/csc.rsp b/Explorer/Assets/DCL/UI/Sidebar/csc.rsp new file mode 100644 index 0000000000..dcc377f897 --- /dev/null +++ b/Explorer/Assets/DCL/UI/Sidebar/csc.rsp @@ -0,0 +1 @@ +-nullable:enable \ No newline at end of file diff --git a/Explorer/Assets/DCL/UI/Sidebar/csc.rsp.meta b/Explorer/Assets/DCL/UI/Sidebar/csc.rsp.meta new file mode 100644 index 0000000000..d2378a07ae --- /dev/null +++ b/Explorer/Assets/DCL/UI/Sidebar/csc.rsp.meta @@ -0,0 +1,3 @@ +fileFormatVersion: 2 +guid: 82a49858310e4aff912c46dc1de42d2c +timeCreated: 1724144729 \ No newline at end of file diff --git a/Explorer/Assets/DCL/UI/SystemMenu/UI.SystemMenu.asmdef b/Explorer/Assets/DCL/UI/SystemMenu/UI.SystemMenu.asmdef index 02704fd834..8c6e3a4d8a 100644 --- a/Explorer/Assets/DCL/UI/SystemMenu/UI.SystemMenu.asmdef +++ b/Explorer/Assets/DCL/UI/SystemMenu/UI.SystemMenu.asmdef @@ -11,7 +11,8 @@ "GUID:ae249ee11a6e0ea4aa01cefc0246a151", "GUID:f51ebe6a0ceec4240a699833d6309b23", "GUID:2f30d6e5229a74284acedda491abcc6e", - "GUID:029c1c1b674aaae47a6841a0b89ad80e" + "GUID:029c1c1b674aaae47a6841a0b89ad80e", + "GUID:ca4e81cdd6a34d1aa54c32ad41fc5b3b" ], "includePlatforms": [], "excludePlatforms": [], diff --git a/Explorer/Assets/DCL/UserInAppInitializationFlow/DCL.UserInAppInitializationFlow.asmdef b/Explorer/Assets/DCL/UserInAppInitializationFlow/DCL.UserInAppInitializationFlow.asmdef index 8d60a1a28a..6d9d415cb4 100644 --- a/Explorer/Assets/DCL/UserInAppInitializationFlow/DCL.UserInAppInitializationFlow.asmdef +++ b/Explorer/Assets/DCL/UserInAppInitializationFlow/DCL.UserInAppInitializationFlow.asmdef @@ -27,8 +27,9 @@ "GUID:91cf8206af184dac8e30eb46747e9939", "GUID:3584eeba5aa04262ac61bf2cd833becc", "GUID:4a12c0b1b77ec6b418a8d7bd5c925be3", + "GUID:8baf705856414dad9a73b3f382f1bc8b", "GUID:7175400a68914a45acecc9fb068de3b8", - "GUID:8baf705856414dad9a73b3f382f1bc8b" + "GUID:ca4e81cdd6a34d1aa54c32ad41fc5b3b" ], "includePlatforms": [], "excludePlatforms": [], diff --git a/Explorer/Assets/DCL/Web3/Abstract.meta b/Explorer/Assets/DCL/Web3/Abstract.meta new file mode 100644 index 0000000000..8b70a104c8 --- /dev/null +++ b/Explorer/Assets/DCL/Web3/Abstract.meta @@ -0,0 +1,3 @@ +fileFormatVersion: 2 +guid: 8a70592fe2d947278ef0986eece590d8 +timeCreated: 1724143710 \ No newline at end of file diff --git a/Explorer/Assets/DCL/Web3/Accounts/IWeb3Account.cs b/Explorer/Assets/DCL/Web3/Abstract/IWeb3Account.cs similarity index 87% rename from Explorer/Assets/DCL/Web3/Accounts/IWeb3Account.cs rename to Explorer/Assets/DCL/Web3/Abstract/IWeb3Account.cs index 416047c662..d543b5bea4 100644 --- a/Explorer/Assets/DCL/Web3/Accounts/IWeb3Account.cs +++ b/Explorer/Assets/DCL/Web3/Abstract/IWeb3Account.cs @@ -1,9 +1,11 @@ -namespace DCL.Web3.Accounts +namespace DCL.Web3.Abstract { public interface IWeb3Account { public Web3Address Address { get; } + public string PrivateKey { get; } + string Sign(string message); /// diff --git a/Explorer/Assets/DCL/Web3/Accounts/IWeb3Account.cs.meta b/Explorer/Assets/DCL/Web3/Abstract/IWeb3Account.cs.meta similarity index 100% rename from Explorer/Assets/DCL/Web3/Accounts/IWeb3Account.cs.meta rename to Explorer/Assets/DCL/Web3/Abstract/IWeb3Account.cs.meta diff --git a/Explorer/Assets/DCL/Web3/Abstract/IWeb3AccountFactory.cs b/Explorer/Assets/DCL/Web3/Abstract/IWeb3AccountFactory.cs new file mode 100644 index 0000000000..2f40ee16a3 --- /dev/null +++ b/Explorer/Assets/DCL/Web3/Abstract/IWeb3AccountFactory.cs @@ -0,0 +1,11 @@ +using Nethereum.Signer; + +namespace DCL.Web3.Abstract +{ + public interface IWeb3AccountFactory + { + IWeb3Account CreateAccount(EthECKey key); + + IWeb3Account CreateRandomAccount(); + } +} diff --git a/Explorer/Assets/DCL/Web3/Abstract/IWeb3AccountFactory.cs.meta b/Explorer/Assets/DCL/Web3/Abstract/IWeb3AccountFactory.cs.meta new file mode 100644 index 0000000000..85f1211dd2 --- /dev/null +++ b/Explorer/Assets/DCL/Web3/Abstract/IWeb3AccountFactory.cs.meta @@ -0,0 +1,3 @@ +fileFormatVersion: 2 +guid: b3408b9da439426aa2c1c703f9f11f57 +timeCreated: 1724143607 \ No newline at end of file diff --git a/Explorer/Assets/DCL/Web3/Abstract/Web3.Abstract.asmdef b/Explorer/Assets/DCL/Web3/Abstract/Web3.Abstract.asmdef new file mode 100644 index 0000000000..ef33803d52 --- /dev/null +++ b/Explorer/Assets/DCL/Web3/Abstract/Web3.Abstract.asmdef @@ -0,0 +1,28 @@ +{ + "name": "Web3.Abstract", + "rootNamespace": "", + "references": [ + "GUID:f51ebe6a0ceec4240a699833d6309b23", + "GUID:fa7b3fdbb04d67549916da7bd2af58ab", + "GUID:3640f3c0b42946b0b8794a1ed8e06ca5", + "GUID:91cf8206af184dac8e30eb46747e9939", + "GUID:29f99fa49221a4df7aecb5cd50457e5f", + "GUID:92920c790fc0443e9a7ec2f7d1e5308f", + "GUID:101b8b6ebaf64668909b49c4b7a1420d" + ], + "includePlatforms": [], + "excludePlatforms": [], + "allowUnsafeCode": false, + "overrideReferences": true, + "precompiledReferences": [ + "Newtonsoft.Json.dll", + "Nethereum.Signer.dll", + "SocketIO.Serializer.Core.dll", + "SocketIO.Serializer.SystemTextJson.dll", + "System.Text.Json.dll" + ], + "autoReferenced": true, + "defineConstraints": [], + "versionDefines": [], + "noEngineReferences": false +} \ No newline at end of file diff --git a/Explorer/Assets/DCL/Web3/Abstract/Web3.Abstract.asmdef.meta b/Explorer/Assets/DCL/Web3/Abstract/Web3.Abstract.asmdef.meta new file mode 100644 index 0000000000..cc9c350476 --- /dev/null +++ b/Explorer/Assets/DCL/Web3/Abstract/Web3.Abstract.asmdef.meta @@ -0,0 +1,3 @@ +fileFormatVersion: 2 +guid: ca4e81cdd6a34d1aa54c32ad41fc5b3b +timeCreated: 1724143758 \ No newline at end of file diff --git a/Explorer/Assets/DCL/Web3/Web3Address.cs b/Explorer/Assets/DCL/Web3/Abstract/Web3Address.cs similarity index 88% rename from Explorer/Assets/DCL/Web3/Web3Address.cs rename to Explorer/Assets/DCL/Web3/Abstract/Web3Address.cs index 0f71e22135..7e1c3a3694 100644 --- a/Explorer/Assets/DCL/Web3/Web3Address.cs +++ b/Explorer/Assets/DCL/Web3/Abstract/Web3Address.cs @@ -1,3 +1,4 @@ +using DCL.Web3.Abstract; using System; namespace DCL.Web3 @@ -6,9 +7,12 @@ public readonly struct Web3Address { private readonly string address; + public Web3Address(IWeb3Account web3Account) : this(web3Account.Address.address) { + } + public Web3Address(string address) { - this.address = address; + this.address = address.ToLower(); } public override string ToString() => diff --git a/Explorer/Assets/DCL/Web3/Web3Address.cs.meta b/Explorer/Assets/DCL/Web3/Abstract/Web3Address.cs.meta similarity index 100% rename from Explorer/Assets/DCL/Web3/Web3Address.cs.meta rename to Explorer/Assets/DCL/Web3/Abstract/Web3Address.cs.meta diff --git a/Explorer/Assets/DCL/Web3/Abstract/csc.rsp b/Explorer/Assets/DCL/Web3/Abstract/csc.rsp new file mode 100644 index 0000000000..dcc377f897 --- /dev/null +++ b/Explorer/Assets/DCL/Web3/Abstract/csc.rsp @@ -0,0 +1 @@ +-nullable:enable \ No newline at end of file diff --git a/Explorer/Assets/DCL/Web3/Abstract/csc.rsp.meta b/Explorer/Assets/DCL/Web3/Abstract/csc.rsp.meta new file mode 100644 index 0000000000..15d445e729 --- /dev/null +++ b/Explorer/Assets/DCL/Web3/Abstract/csc.rsp.meta @@ -0,0 +1,3 @@ +fileFormatVersion: 2 +guid: a6fba947926d4dfc8750362462570ec0 +timeCreated: 1724144166 \ No newline at end of file diff --git a/Explorer/Assets/DCL/Web3/Accounts/Factory.meta b/Explorer/Assets/DCL/Web3/Accounts/Factory.meta new file mode 100644 index 0000000000..ea27939bb4 --- /dev/null +++ b/Explorer/Assets/DCL/Web3/Accounts/Factory.meta @@ -0,0 +1,3 @@ +fileFormatVersion: 2 +guid: 3d34f177e2114231861d091857df868b +timeCreated: 1724143598 \ No newline at end of file diff --git a/Explorer/Assets/DCL/Web3/Accounts/Factory/Web3AccountFactory.cs b/Explorer/Assets/DCL/Web3/Accounts/Factory/Web3AccountFactory.cs new file mode 100644 index 0000000000..21163d6f9f --- /dev/null +++ b/Explorer/Assets/DCL/Web3/Accounts/Factory/Web3AccountFactory.cs @@ -0,0 +1,18 @@ +using DCL.Web3.Abstract; +using Nethereum.Signer; +using Plugins.RustEthereum.SignServerWrap; + +namespace DCL.Web3.Accounts.Factory +{ + public class Web3AccountFactory : IWeb3AccountFactory + { + public IWeb3Account CreateAccount(EthECKey key) => + new RustEthereumAccount(key); + + public IWeb3Account CreateRandomAccount() + { + var randomKey = EthECKey.GenerateKey()!; + return CreateAccount(randomKey); + } + } +} diff --git a/Explorer/Assets/DCL/Web3/Accounts/Factory/Web3AccountFactory.cs.meta b/Explorer/Assets/DCL/Web3/Accounts/Factory/Web3AccountFactory.cs.meta new file mode 100644 index 0000000000..179a60d663 --- /dev/null +++ b/Explorer/Assets/DCL/Web3/Accounts/Factory/Web3AccountFactory.cs.meta @@ -0,0 +1,3 @@ +fileFormatVersion: 2 +guid: e1a791fda83c4ebc97c961db1209f630 +timeCreated: 1724143636 \ No newline at end of file diff --git a/Explorer/Assets/DCL/Web3/Accounts/IEthKeyOwner.cs b/Explorer/Assets/DCL/Web3/Accounts/IEthKeyOwner.cs deleted file mode 100644 index a4cf3f43ea..0000000000 --- a/Explorer/Assets/DCL/Web3/Accounts/IEthKeyOwner.cs +++ /dev/null @@ -1,9 +0,0 @@ -using Nethereum.Signer; - -namespace DCL.Web3.Accounts -{ - public interface IEthKeyOwner - { - EthECKey Key { get; } - } -} diff --git a/Explorer/Assets/DCL/Web3/Accounts/IEthKeyOwner.cs.meta b/Explorer/Assets/DCL/Web3/Accounts/IEthKeyOwner.cs.meta deleted file mode 100644 index f118cd0389..0000000000 --- a/Explorer/Assets/DCL/Web3/Accounts/IEthKeyOwner.cs.meta +++ /dev/null @@ -1,3 +0,0 @@ -fileFormatVersion: 2 -guid: 8b144600619f443eb049cce578c03f89 -timeCreated: 1707836804 \ No newline at end of file diff --git a/Explorer/Assets/DCL/Web3/Accounts/LogWeb3Account.cs b/Explorer/Assets/DCL/Web3/Accounts/LogWeb3Account.cs index 165998dd8c..994bd3597c 100644 --- a/Explorer/Assets/DCL/Web3/Accounts/LogWeb3Account.cs +++ b/Explorer/Assets/DCL/Web3/Accounts/LogWeb3Account.cs @@ -1,11 +1,12 @@ using DCL.Diagnostics; +using DCL.Web3.Abstract; using Nethereum.Signer; using System; using UnityEngine; namespace DCL.Web3.Accounts { - public class LogWeb3Account : IWeb3Account, IEthKeyOwner + public class LogWeb3Account : IWeb3Account { private readonly IWeb3Account origin; private readonly Action log; @@ -27,6 +28,15 @@ public Web3Address Address } } + public string PrivateKey + { + get + { + log($"Web3Account PrivateKey requested: {origin.PrivateKey}"); + return origin.PrivateKey; + } + } + public string Sign(string message) { log($"Web3Account Sign requested: {message}"); @@ -42,9 +52,5 @@ public bool Verify(string message, string signature) log($"Web3Account Verify result: {result} for {message} with {signature}"); return result; } - - public EthECKey Key => origin is IEthKeyOwner ethKeyOwner - ? ethKeyOwner.Key - : throw new InvalidOperationException("The origin is not an IEthKeyOwner"); } } diff --git a/Explorer/Assets/DCL/Web3/Accounts/NethereumAccount.cs b/Explorer/Assets/DCL/Web3/Accounts/NethereumAccount.cs deleted file mode 100644 index a754309f6c..0000000000 --- a/Explorer/Assets/DCL/Web3/Accounts/NethereumAccount.cs +++ /dev/null @@ -1,29 +0,0 @@ -using Nethereum.Signer; - -namespace DCL.Web3.Accounts -{ - public class NethereumAccount : IWeb3Account, IEthKeyOwner - { - private static readonly EthereumMessageSigner signer = new (); - internal readonly EthECKey key; - - public Web3Address Address { get; } - - public EthECKey Key => key; - - public NethereumAccount(EthECKey key) - { - this.key = key; - Address = new Web3Address(key.GetPublicAddress()); - } - - public static NethereumAccount CreateRandom() => - new (EthECKey.GenerateKey()); - - public string Sign(string message) => - signer.EncodeUTF8AndSign(message, key); - - public bool Verify(string message, string signature) => - signer.EncodeUTF8AndEcRecover(message, signature) == Address; - } -} diff --git a/Explorer/Assets/DCL/Web3/Authenticators/DappWeb3Authenticator.cs b/Explorer/Assets/DCL/Web3/Authenticators/DappWeb3Authenticator.cs index ed077db2c8..214fbb5f35 100644 --- a/Explorer/Assets/DCL/Web3/Authenticators/DappWeb3Authenticator.cs +++ b/Explorer/Assets/DCL/Web3/Authenticators/DappWeb3Authenticator.cs @@ -1,7 +1,9 @@ using Cysharp.Threading.Tasks; using DCL.Browser; using DCL.Multiplayer.Connections.DecentralandUrls; +using DCL.Web3.Abstract; using DCL.Web3.Accounts; +using DCL.Web3.Accounts.Factory; using DCL.Web3.Chains; using DCL.Web3.Identities; using Newtonsoft.Json; @@ -24,6 +26,7 @@ public partial class DappWeb3Authenticator : IWeb3VerifiedAuthenticator, IVerifi private readonly string serverUrl; private readonly string signatureUrl; private readonly IWeb3IdentityCache identityCache; + private readonly IWeb3AccountFactory web3AccountFactory; private readonly HashSet whitelistMethods; private SocketIO? webSocket; @@ -35,12 +38,15 @@ public DappWeb3Authenticator(IWebBrowser webBrowser, string serverUrl, string signatureUrl, IWeb3IdentityCache identityCache, - HashSet whitelistMethods) + IWeb3AccountFactory web3AccountFactory, + HashSet whitelistMethods + ) { this.webBrowser = webBrowser; this.serverUrl = serverUrl; this.signatureUrl = signatureUrl; this.identityCache = identityCache; + this.web3AccountFactory = web3AccountFactory; this.whitelistMethods = whitelistMethods; } @@ -101,7 +107,7 @@ public async UniTask LoginAsync(CancellationToken ct) { await ConnectToServerAsync(); - var ephemeralAccount = NethereumAccount.CreateRandom(); + var ephemeralAccount = web3AccountFactory.CreateRandomAccount(); // 1 week expiration day, just like unity-renderer DateTime sessionExpiration = DateTime.UtcNow.AddDays(7); @@ -134,7 +140,7 @@ public async UniTask LoginAsync(CancellationToken ct) AuthChain authChain = CreateAuthChain(response, ephemeralMessage); // To keep cohesiveness between the platform, convert the user address to lower case - return new DecentralandIdentity(new Web3Address(response.sender.ToLower()), + return new DecentralandIdentity(new Web3Address(response.sender), ephemeralAccount, sessionExpiration, authChain); } finally @@ -261,7 +267,7 @@ public class Default : IWeb3VerifiedAuthenticator, IVerifiedEthereumApi private readonly IWeb3VerifiedAuthenticator originAuth; private readonly IVerifiedEthereumApi originApi; - public Default(IWeb3IdentityCache identityCache, IDecentralandUrlsSource decentralandUrlsSource) + public Default(IWeb3IdentityCache identityCache, IDecentralandUrlsSource decentralandUrlsSource, IWeb3AccountFactory web3AccountFactory) { string serverUrl = decentralandUrlsSource.Url(DecentralandUrl.ApiAuth); string signatureUrl = decentralandUrlsSource.Url(DecentralandUrl.AuthSignature); @@ -271,6 +277,7 @@ public Default(IWeb3IdentityCache identityCache, IDecentralandUrlsSource decentr serverUrl, signatureUrl, identityCache, + web3AccountFactory, new HashSet( new[] { diff --git a/Explorer/Assets/DCL/Web3/Authenticators/RandomGeneratedWeb3Authenticator.cs b/Explorer/Assets/DCL/Web3/Authenticators/RandomGeneratedWeb3Authenticator.cs index 4f79a53ee3..6fd918dfeb 100644 --- a/Explorer/Assets/DCL/Web3/Authenticators/RandomGeneratedWeb3Authenticator.cs +++ b/Explorer/Assets/DCL/Web3/Authenticators/RandomGeneratedWeb3Authenticator.cs @@ -1,22 +1,28 @@ using Cysharp.Threading.Tasks; -using DCL.Web3.Accounts; +using DCL.Web3.Abstract; using DCL.Web3.Chains; using DCL.Web3.Identities; using System; using System.Threading; +using Utility.Tasks; namespace DCL.Web3.Authenticators { public class RandomGeneratedWeb3Authenticator : IWeb3Authenticator { - public void Dispose() + private readonly IWeb3AccountFactory accountFactory; + + public RandomGeneratedWeb3Authenticator(IWeb3AccountFactory accountFactory) { + this.accountFactory = accountFactory; } + public void Dispose() { } + public UniTask LoginAsync(CancellationToken ct) { - var signer = NethereumAccount.CreateRandom(); - var ephemeralAccount = NethereumAccount.CreateRandom(); + var signer = accountFactory.CreateRandomAccount(); + var ephemeralAccount = accountFactory.CreateRandomAccount(); DateTime expiration = DateTime.Now.AddMinutes(600); var ephemeralMessage = $"Decentraland Login\nEphemeral address: {ephemeralAccount.Address}\nExpiration: {expiration:s}"; @@ -34,9 +40,12 @@ public UniTask LoginAsync(CancellationToken ct) }); // To keep cohesiveness between the platform, convert the user address to lower case - return new UniTask( - new DecentralandIdentity(new Web3Address(signer.Address.ToString().ToLower()), ephemeralAccount, expiration, authChain) - ); + return new DecentralandIdentity( + new Web3Address(signer), + ephemeralAccount, + expiration, + authChain + ).AsUniTaskResult(); } public UniTask LogoutAsync(CancellationToken cancellationToken) => diff --git a/Explorer/Assets/DCL/Web3/Identities/DecentralandIdentity.cs b/Explorer/Assets/DCL/Web3/Identities/DecentralandIdentity.cs index 546e0b7e2b..a4fb591c13 100644 --- a/Explorer/Assets/DCL/Web3/Identities/DecentralandIdentity.cs +++ b/Explorer/Assets/DCL/Web3/Identities/DecentralandIdentity.cs @@ -1,3 +1,4 @@ +using DCL.Web3.Abstract; using DCL.Web3.Accounts; using DCL.Web3.Chains; using System; diff --git a/Explorer/Assets/DCL/Web3/Identities/IWeb3Identity.cs b/Explorer/Assets/DCL/Web3/Identities/IWeb3Identity.cs index 729f582ebc..1e2063b40a 100644 --- a/Explorer/Assets/DCL/Web3/Identities/IWeb3Identity.cs +++ b/Explorer/Assets/DCL/Web3/Identities/IWeb3Identity.cs @@ -1,4 +1,5 @@ -using DCL.Web3.Accounts; +using DCL.Web3.Abstract; +using DCL.Web3.Accounts.Factory; using DCL.Web3.Chains; using System; @@ -16,10 +17,16 @@ public interface IWeb3Identity : IDisposable class Random : IWeb3Identity { - public Random(IWeb3Account? account = null) : this( - NethereumAccount.CreateRandom().Address, + public Random() : this(new Web3AccountFactory()) { } + + public Random(IWeb3AccountFactory web3AccountFactory) : this( + web3AccountFactory.CreateRandomAccount() + ) { } + + public Random(IWeb3Account account) : this( + account.Address, DateTime.MaxValue, - account ?? NethereumAccount.CreateRandom(), + account, false, AuthChain.Create() ) { } diff --git a/Explorer/Assets/DCL/Web3/Identities/IWeb3IdentityCache.cs b/Explorer/Assets/DCL/Web3/Identities/IWeb3IdentityCache.cs index 163005488a..5f84b5df04 100644 --- a/Explorer/Assets/DCL/Web3/Identities/IWeb3IdentityCache.cs +++ b/Explorer/Assets/DCL/Web3/Identities/IWeb3IdentityCache.cs @@ -1,3 +1,4 @@ +using DCL.Web3.Accounts.Factory; using System; namespace DCL.Web3.Identities @@ -50,7 +51,9 @@ public Default() new ProxyIdentityCache( new MemoryWeb3IdentityCache(), new PlayerPrefsIdentityProvider( - new PlayerPrefsIdentityProvider.DecentralandIdentityWithNethereumAccountJsonSerializer() + new PlayerPrefsIdentityProvider.DecentralandIdentityWithNethereumAccountJsonSerializer( + new Web3AccountFactory() + ) ) ) ); diff --git a/Explorer/Assets/DCL/Web3/Identities/LogWeb3Identity.cs b/Explorer/Assets/DCL/Web3/Identities/LogWeb3Identity.cs index 211a1be8b4..a288e244b9 100644 --- a/Explorer/Assets/DCL/Web3/Identities/LogWeb3Identity.cs +++ b/Explorer/Assets/DCL/Web3/Identities/LogWeb3Identity.cs @@ -1,4 +1,5 @@ using DCL.Diagnostics; +using DCL.Web3.Abstract; using DCL.Web3.Accounts; using DCL.Web3.Chains; using System; diff --git a/Explorer/Assets/DCL/Web3/Identities/PlayerPrefsIdentityProvider.DecentralandIdentityWithNethereumAccountJsonSerializer.cs b/Explorer/Assets/DCL/Web3/Identities/PlayerPrefsIdentityProvider.DecentralandIdentityWithNethereumAccountJsonSerializer.cs index b21a2629ae..7198a16c57 100644 --- a/Explorer/Assets/DCL/Web3/Identities/PlayerPrefsIdentityProvider.DecentralandIdentityWithNethereumAccountJsonSerializer.cs +++ b/Explorer/Assets/DCL/Web3/Identities/PlayerPrefsIdentityProvider.DecentralandIdentityWithNethereumAccountJsonSerializer.cs @@ -1,4 +1,4 @@ -using DCL.Web3.Accounts; +using DCL.Web3.Abstract; using DCL.Web3.Chains; using Nethereum.Signer; using Newtonsoft.Json; @@ -12,6 +12,12 @@ public partial class PlayerPrefsIdentityProvider public class DecentralandIdentityWithNethereumAccountJsonSerializer : IWeb3IdentityJsonSerializer { private readonly IdentityJsonDto jsonRoot = new (); + private readonly IWeb3AccountFactory accountFactory; + + public DecentralandIdentityWithNethereumAccountJsonSerializer(IWeb3AccountFactory accountFactory) + { + this.accountFactory = accountFactory; + } public IWeb3Identity? Deserialize(string json) { @@ -26,21 +32,18 @@ public class DecentralandIdentityWithNethereumAccountJsonSerializer : IWeb3Ident authChain.Set(link); return new DecentralandIdentity(new Web3Address(jsonRoot.address), - new NethereumAccount(new EthECKey(jsonRoot.key)), + accountFactory.CreateAccount(new EthECKey(jsonRoot.key)), DateTime.Parse(jsonRoot.expiration, null, DateTimeStyles.RoundtripKind), authChain); } public string Serialize(IWeb3Identity identity) { - var account = identity.EphemeralAccount as IEthKeyOwner - ?? throw new Exception("The identity account is not an IEthKeyOwner"); - jsonRoot.Clear(); jsonRoot.address = identity.Address; jsonRoot.expiration = $"{identity.Expiration:O}"; jsonRoot.ephemeralAuthChain.AddRange(identity.AuthChain); - jsonRoot.key = account.Key.GetPrivateKey()!; + jsonRoot.key = identity.EphemeralAccount.PrivateKey; return JsonConvert.SerializeObject(jsonRoot); } diff --git a/Explorer/Assets/DCL/Web3/Nethereum.meta b/Explorer/Assets/DCL/Web3/Nethereum.meta new file mode 100644 index 0000000000..54dc385396 --- /dev/null +++ b/Explorer/Assets/DCL/Web3/Nethereum.meta @@ -0,0 +1,3 @@ +fileFormatVersion: 2 +guid: 5524cb341a4d47d693a71c1ef8814fd4 +timeCreated: 1724143796 \ No newline at end of file diff --git a/Explorer/Assets/DCL/Web3/Nethereum/NethereumAccount.cs b/Explorer/Assets/DCL/Web3/Nethereum/NethereumAccount.cs new file mode 100644 index 0000000000..a33ae4938b --- /dev/null +++ b/Explorer/Assets/DCL/Web3/Nethereum/NethereumAccount.cs @@ -0,0 +1,30 @@ +using DCL.Web3.Abstract; +using Nethereum.Signer; + +namespace DCL.Web3.Accounts +{ + public class NethereumAccount : IWeb3Account + { + private static readonly EthereumMessageSigner SIGNER = new (); + internal readonly EthECKey key; + + public Web3Address Address { get; } + + public string PrivateKey => key.GetPrivateKey()!; + + private NethereumAccount(EthECKey key) + { + this.key = key; + Address = new Web3Address(key.GetPublicAddress()); + } + + public static NethereumAccount CreateForVerifyOnly(EthECKey key) => + new (key); + + public string Sign(string message) => + SIGNER.EncodeUTF8AndSign(message, key); + + public bool Verify(string message, string signature) => + SIGNER.EncodeUTF8AndEcRecover(message, signature) == Address; + } +} diff --git a/Explorer/Assets/DCL/Web3/Accounts/NethereumAccount.cs.meta b/Explorer/Assets/DCL/Web3/Nethereum/NethereumAccount.cs.meta similarity index 100% rename from Explorer/Assets/DCL/Web3/Accounts/NethereumAccount.cs.meta rename to Explorer/Assets/DCL/Web3/Nethereum/NethereumAccount.cs.meta diff --git a/Explorer/Assets/DCL/Web3/Nethereum/Web3.Nethereum.asmdef b/Explorer/Assets/DCL/Web3/Nethereum/Web3.Nethereum.asmdef new file mode 100644 index 0000000000..032b9a0efc --- /dev/null +++ b/Explorer/Assets/DCL/Web3/Nethereum/Web3.Nethereum.asmdef @@ -0,0 +1,29 @@ +{ + "name": "Web3.Nethereum", + "rootNamespace": "", + "references": [ + "GUID:f51ebe6a0ceec4240a699833d6309b23", + "GUID:fa7b3fdbb04d67549916da7bd2af58ab", + "GUID:3640f3c0b42946b0b8794a1ed8e06ca5", + "GUID:91cf8206af184dac8e30eb46747e9939", + "GUID:29f99fa49221a4df7aecb5cd50457e5f", + "GUID:92920c790fc0443e9a7ec2f7d1e5308f", + "GUID:101b8b6ebaf64668909b49c4b7a1420d", + "GUID:ca4e81cdd6a34d1aa54c32ad41fc5b3b" + ], + "includePlatforms": [], + "excludePlatforms": [], + "allowUnsafeCode": false, + "overrideReferences": true, + "precompiledReferences": [ + "Newtonsoft.Json.dll", + "Nethereum.Signer.dll", + "SocketIO.Serializer.Core.dll", + "SocketIO.Serializer.SystemTextJson.dll", + "System.Text.Json.dll" + ], + "autoReferenced": true, + "defineConstraints": [], + "versionDefines": [], + "noEngineReferences": false +} \ No newline at end of file diff --git a/Explorer/Assets/DCL/Web3/Nethereum/Web3.Nethereum.asmdef.meta b/Explorer/Assets/DCL/Web3/Nethereum/Web3.Nethereum.asmdef.meta new file mode 100644 index 0000000000..689301396e --- /dev/null +++ b/Explorer/Assets/DCL/Web3/Nethereum/Web3.Nethereum.asmdef.meta @@ -0,0 +1,3 @@ +fileFormatVersion: 2 +guid: 1d67e2d749f242e7a5dc246253ef5832 +timeCreated: 1724143861 \ No newline at end of file diff --git a/Explorer/Assets/DCL/Web3/Nethereum/csc.rsp b/Explorer/Assets/DCL/Web3/Nethereum/csc.rsp new file mode 100644 index 0000000000..dcc377f897 --- /dev/null +++ b/Explorer/Assets/DCL/Web3/Nethereum/csc.rsp @@ -0,0 +1 @@ +-nullable:enable \ No newline at end of file diff --git a/Explorer/Assets/DCL/Web3/Nethereum/csc.rsp.meta b/Explorer/Assets/DCL/Web3/Nethereum/csc.rsp.meta new file mode 100644 index 0000000000..e4feb2ae1c --- /dev/null +++ b/Explorer/Assets/DCL/Web3/Nethereum/csc.rsp.meta @@ -0,0 +1,3 @@ +fileFormatVersion: 2 +guid: 9017709b2e8440d6b640bc73ea4b6db3 +timeCreated: 1724144161 \ No newline at end of file diff --git a/Explorer/Assets/DCL/Web3/Web3.asmdef b/Explorer/Assets/DCL/Web3/Web3.asmdef index 1188a868f9..e262742c0c 100644 --- a/Explorer/Assets/DCL/Web3/Web3.asmdef +++ b/Explorer/Assets/DCL/Web3/Web3.asmdef @@ -8,7 +8,9 @@ "GUID:91cf8206af184dac8e30eb46747e9939", "GUID:29f99fa49221a4df7aecb5cd50457e5f", "GUID:92920c790fc0443e9a7ec2f7d1e5308f", - "GUID:101b8b6ebaf64668909b49c4b7a1420d" + "GUID:101b8b6ebaf64668909b49c4b7a1420d", + "GUID:ca4e81cdd6a34d1aa54c32ad41fc5b3b", + "GUID:9428ba407ade34e4ebcf01cca4669d4b" ], "includePlatforms": [], "excludePlatforms": [], diff --git a/Explorer/Assets/DCL/WebRequests/DCL.WebRequests.asmdef b/Explorer/Assets/DCL/WebRequests/DCL.WebRequests.asmdef index ca4ebf271f..44de30548f 100644 --- a/Explorer/Assets/DCL/WebRequests/DCL.WebRequests.asmdef +++ b/Explorer/Assets/DCL/WebRequests/DCL.WebRequests.asmdef @@ -11,7 +11,8 @@ "GUID:56e8195b069a4dca9c4c4f313c65f526", "GUID:5ab29fa8ae5769b49ab29e390caca7a4", "GUID:4725c02394ab4ce19f889e4e8001f989", - "GUID:166b65e6dfc848bb9fb075f53c293a38" + "GUID:166b65e6dfc848bb9fb075f53c293a38", + "GUID:ca4e81cdd6a34d1aa54c32ad41fc5b3b" ], "includePlatforms": [], "excludePlatforms": [], diff --git a/Explorer/Assets/DCL/WebRequests/IWebRequestController.cs b/Explorer/Assets/DCL/WebRequests/IWebRequestController.cs index 33693d4172..af42d1c071 100644 --- a/Explorer/Assets/DCL/WebRequests/IWebRequestController.cs +++ b/Explorer/Assets/DCL/WebRequests/IWebRequestController.cs @@ -1,4 +1,5 @@ using Cysharp.Threading.Tasks; +using DCL.Web3.Accounts.Factory; using DCL.Web3.Identities; using System.Collections.Generic; @@ -8,7 +9,9 @@ public interface IWebRequestController { static readonly IWebRequestController DEFAULT = new WebRequestController( new PlayerPrefsIdentityProvider( - new PlayerPrefsIdentityProvider.DecentralandIdentityWithNethereumAccountJsonSerializer() + new PlayerPrefsIdentityProvider.DecentralandIdentityWithNethereumAccountJsonSerializer( + new Web3AccountFactory() + ) ) ); diff --git a/Explorer/Assets/Plugins/RustEthereum.meta b/Explorer/Assets/Plugins/RustEthereum.meta new file mode 100644 index 0000000000..43288a22b7 --- /dev/null +++ b/Explorer/Assets/Plugins/RustEthereum.meta @@ -0,0 +1,3 @@ +fileFormatVersion: 2 +guid: 88cdbc4dc99845418c75df850ee65bf9 +timeCreated: 1724093541 \ No newline at end of file diff --git a/Explorer/Assets/Plugins/RustEthereum/SignServerWrap.meta b/Explorer/Assets/Plugins/RustEthereum/SignServerWrap.meta new file mode 100644 index 0000000000..2fdd8fca41 --- /dev/null +++ b/Explorer/Assets/Plugins/RustEthereum/SignServerWrap.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: b5565f5f4c2b0486180b9fd3334cbb23 +folderAsset: yes +DefaultImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Explorer/Assets/Plugins/RustEthereum/SignServerWrap/Libraries.meta b/Explorer/Assets/Plugins/RustEthereum/SignServerWrap/Libraries.meta new file mode 100644 index 0000000000..cab3093cd0 --- /dev/null +++ b/Explorer/Assets/Plugins/RustEthereum/SignServerWrap/Libraries.meta @@ -0,0 +1,3 @@ +fileFormatVersion: 2 +guid: 82a40c7a92204a1a89ed119d7a0d59b0 +timeCreated: 1724100955 \ No newline at end of file diff --git a/Explorer/Assets/Plugins/RustEthereum/SignServerWrap/Libraries/Linux.meta b/Explorer/Assets/Plugins/RustEthereum/SignServerWrap/Libraries/Linux.meta new file mode 100644 index 0000000000..1459cdb08b --- /dev/null +++ b/Explorer/Assets/Plugins/RustEthereum/SignServerWrap/Libraries/Linux.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: 1686283187c584ac8a69c2fb874aaa01 +folderAsset: yes +DefaultImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Explorer/Assets/Plugins/RustEthereum/SignServerWrap/Libraries/Linux/sign-server.so b/Explorer/Assets/Plugins/RustEthereum/SignServerWrap/Libraries/Linux/sign-server.so new file mode 100755 index 0000000000..41ca677b07 Binary files /dev/null and b/Explorer/Assets/Plugins/RustEthereum/SignServerWrap/Libraries/Linux/sign-server.so differ diff --git a/Explorer/Assets/Plugins/RustEthereum/SignServerWrap/Libraries/Linux/sign-server.so.meta b/Explorer/Assets/Plugins/RustEthereum/SignServerWrap/Libraries/Linux/sign-server.so.meta new file mode 100644 index 0000000000..8e956aa726 --- /dev/null +++ b/Explorer/Assets/Plugins/RustEthereum/SignServerWrap/Libraries/Linux/sign-server.so.meta @@ -0,0 +1,27 @@ +fileFormatVersion: 2 +guid: ec8d5bc94bff7470189f91976fa4c9fc +PluginImporter: + externalObjects: {} + serializedVersion: 2 + iconMap: {} + executionOrder: {} + defineConstraints: [] + isPreloaded: 0 + isOverridable: 0 + isExplicitlyReferenced: 0 + validateReferences: 1 + platformData: + - first: + Any: + second: + enabled: 1 + settings: {} + - first: + Editor: Editor + second: + enabled: 0 + settings: + DefaultValueInitialized: true + userData: + assetBundleName: + assetBundleVariant: diff --git a/Explorer/Assets/Plugins/RustEthereum/SignServerWrap/Libraries/Mac.meta b/Explorer/Assets/Plugins/RustEthereum/SignServerWrap/Libraries/Mac.meta new file mode 100644 index 0000000000..b725c224a7 --- /dev/null +++ b/Explorer/Assets/Plugins/RustEthereum/SignServerWrap/Libraries/Mac.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: 218397dc54a7c4a76b8a6467f62c02ba +folderAsset: yes +DefaultImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Explorer/Assets/Plugins/RustEthereum/SignServerWrap/Libraries/Mac/sign-server.dylib b/Explorer/Assets/Plugins/RustEthereum/SignServerWrap/Libraries/Mac/sign-server.dylib new file mode 100755 index 0000000000..f35a32903c Binary files /dev/null and b/Explorer/Assets/Plugins/RustEthereum/SignServerWrap/Libraries/Mac/sign-server.dylib differ diff --git a/Explorer/Assets/Plugins/RustEthereum/SignServerWrap/Libraries/Mac/sign-server.dylib.meta b/Explorer/Assets/Plugins/RustEthereum/SignServerWrap/Libraries/Mac/sign-server.dylib.meta new file mode 100644 index 0000000000..30c882c205 --- /dev/null +++ b/Explorer/Assets/Plugins/RustEthereum/SignServerWrap/Libraries/Mac/sign-server.dylib.meta @@ -0,0 +1,3 @@ +fileFormatVersion: 2 +guid: c8b245f4f04741529d0591cad2a6b00f +timeCreated: 1724100956 \ No newline at end of file diff --git a/Explorer/Assets/Plugins/RustEthereum/SignServerWrap/Libraries/Windows.meta b/Explorer/Assets/Plugins/RustEthereum/SignServerWrap/Libraries/Windows.meta new file mode 100644 index 0000000000..dcc6e1d36c --- /dev/null +++ b/Explorer/Assets/Plugins/RustEthereum/SignServerWrap/Libraries/Windows.meta @@ -0,0 +1,3 @@ +fileFormatVersion: 2 +guid: 074f344ddf8b45d4adc5756f4a70cfe9 +timeCreated: 1724150569 \ No newline at end of file diff --git a/Explorer/Assets/Plugins/RustEthereum/SignServerWrap/Libraries/Windows/sign-server.dll b/Explorer/Assets/Plugins/RustEthereum/SignServerWrap/Libraries/Windows/sign-server.dll new file mode 100644 index 0000000000..1bc7419644 --- /dev/null +++ b/Explorer/Assets/Plugins/RustEthereum/SignServerWrap/Libraries/Windows/sign-server.dll @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:8e5fe7ce2eb2ed55ac629d1a17da1677ef12dc79ba1a99a9dee932c9d654b057 +size 244736 diff --git a/Explorer/Assets/Plugins/RustEthereum/SignServerWrap/Libraries/Windows/sign-server.dll.meta b/Explorer/Assets/Plugins/RustEthereum/SignServerWrap/Libraries/Windows/sign-server.dll.meta new file mode 100644 index 0000000000..d1924a2718 --- /dev/null +++ b/Explorer/Assets/Plugins/RustEthereum/SignServerWrap/Libraries/Windows/sign-server.dll.meta @@ -0,0 +1,3 @@ +fileFormatVersion: 2 +guid: db9d82e8bc8141c3bf3f639bb7bc251f +timeCreated: 1724150590 \ No newline at end of file diff --git a/Explorer/Assets/Plugins/RustEthereum/SignServerWrap/NativeMethods.cs b/Explorer/Assets/Plugins/RustEthereum/SignServerWrap/NativeMethods.cs new file mode 100644 index 0000000000..758d3dd67d --- /dev/null +++ b/Explorer/Assets/Plugins/RustEthereum/SignServerWrap/NativeMethods.cs @@ -0,0 +1,18 @@ +using System; +using System.Runtime.InteropServices; + +namespace Plugins.RustEthereum.SignServerWrap +{ + public static class NativeMethods + { + private const string LIBRARY_NAME = "sign-server"; + + [DllImport(LIBRARY_NAME, CallingConvention = CallingConvention.Cdecl, EntryPoint = "sign_server_initialize")] + internal extern static unsafe bool SignServerInitialize(byte* privateKey, UIntPtr len); + + /// A message to sign + /// Signatures size is always 65 bytes + [DllImport(LIBRARY_NAME, CallingConvention = CallingConvention.Cdecl, EntryPoint = "sign_server_sign_message")] + internal extern static unsafe void SignServerSignMessage(string message, byte* signatureOutput); + } +} diff --git a/Explorer/Assets/Plugins/RustEthereum/SignServerWrap/NativeMethods.cs.meta b/Explorer/Assets/Plugins/RustEthereum/SignServerWrap/NativeMethods.cs.meta new file mode 100644 index 0000000000..aba61be41f --- /dev/null +++ b/Explorer/Assets/Plugins/RustEthereum/SignServerWrap/NativeMethods.cs.meta @@ -0,0 +1,3 @@ +fileFormatVersion: 2 +guid: 7082aa315f7a48a8ae730b90b315ac37 +timeCreated: 1724099120 \ No newline at end of file diff --git a/Explorer/Assets/Plugins/RustEthereum/SignServerWrap/Playground.meta b/Explorer/Assets/Plugins/RustEthereum/SignServerWrap/Playground.meta new file mode 100644 index 0000000000..7a899d71b6 --- /dev/null +++ b/Explorer/Assets/Plugins/RustEthereum/SignServerWrap/Playground.meta @@ -0,0 +1,3 @@ +fileFormatVersion: 2 +guid: 5136893db94b47ab972849e662de63d0 +timeCreated: 1724109588 \ No newline at end of file diff --git a/Explorer/Assets/Plugins/RustEthereum/SignServerWrap/Playground/SignServerWrapPlayground.cs b/Explorer/Assets/Plugins/RustEthereum/SignServerWrap/Playground/SignServerWrapPlayground.cs new file mode 100644 index 0000000000..0c413edfc8 --- /dev/null +++ b/Explorer/Assets/Plugins/RustEthereum/SignServerWrap/Playground/SignServerWrapPlayground.cs @@ -0,0 +1,36 @@ +using DCL.Web3.Abstract; +using DCL.Web3.Accounts; +using Nethereum.Signer; +using UnityEngine; + +namespace Plugins.RustEthereum.SignServerWrap.Playground +{ + public class SignServerWrapPlayground : MonoBehaviour + { + public enum Mode + { + Nethereum, + Rust, + } + + [SerializeField] private int callsPerSecond = 1000; + [SerializeField] private string exampleMessage = "Hello world! Best day ever!"; + [SerializeField] private Mode mode = Mode.Nethereum; + + private RustEthereumAccount rustEthereumAccount = null!; + private NethereumAccount nethereumAccount = null!; + + private void Start() + { + var key = EthECKey.GenerateKey()!; + rustEthereumAccount = new RustEthereumAccount(key); + nethereumAccount = NethereumAccount.CreateForVerifyOnly(key)!; + } + + private void Update() + { + IWeb3Account account = mode is Mode.Nethereum ? nethereumAccount : rustEthereumAccount; + for (var i = 0; i < callsPerSecond; i++) account.Sign(exampleMessage); + } + } +} diff --git a/Explorer/Assets/Plugins/RustEthereum/SignServerWrap/Playground/SignServerWrapPlayground.cs.meta b/Explorer/Assets/Plugins/RustEthereum/SignServerWrap/Playground/SignServerWrapPlayground.cs.meta new file mode 100644 index 0000000000..d40560fb8e --- /dev/null +++ b/Explorer/Assets/Plugins/RustEthereum/SignServerWrap/Playground/SignServerWrapPlayground.cs.meta @@ -0,0 +1,3 @@ +fileFormatVersion: 2 +guid: ac1c85f65ee844bf8b81e60cb48cff4d +timeCreated: 1724109596 \ No newline at end of file diff --git a/Explorer/Assets/Plugins/RustEthereum/SignServerWrap/Playground/SignServerWrapPlayground.unity b/Explorer/Assets/Plugins/RustEthereum/SignServerWrap/Playground/SignServerWrapPlayground.unity new file mode 100644 index 0000000000..71c0497dbf --- /dev/null +++ b/Explorer/Assets/Plugins/RustEthereum/SignServerWrap/Playground/SignServerWrapPlayground.unity @@ -0,0 +1,388 @@ +%YAML 1.1 +%TAG !u! tag:unity3d.com,2011: +--- !u!29 &1 +OcclusionCullingSettings: + m_ObjectHideFlags: 0 + serializedVersion: 2 + m_OcclusionBakeSettings: + smallestOccluder: 5 + smallestHole: 0.25 + backfaceThreshold: 100 + m_SceneGUID: 00000000000000000000000000000000 + m_OcclusionCullingData: {fileID: 0} +--- !u!104 &2 +RenderSettings: + m_ObjectHideFlags: 0 + serializedVersion: 9 + m_Fog: 1 + m_FogColor: {r: 0.5, g: 0.5, b: 0.5, a: 1} + m_FogMode: 3 + m_FogDensity: 0.01 + m_LinearFogStart: 0 + m_LinearFogEnd: 300 + m_AmbientSkyColor: {r: 0.212, g: 0.227, b: 0.259, a: 1} + m_AmbientEquatorColor: {r: 0.114, g: 0.125, b: 0.133, a: 1} + m_AmbientGroundColor: {r: 0.047, g: 0.043, b: 0.035, a: 1} + m_AmbientIntensity: 1 + m_AmbientMode: 0 + m_SubtractiveShadowColor: {r: 0.42, g: 0.478, b: 0.627, a: 1} + m_SkyboxMaterial: {fileID: 10304, guid: 0000000000000000f000000000000000, type: 0} + m_HaloStrength: 0.5 + m_FlareStrength: 1 + m_FlareFadeSpeed: 3 + m_HaloTexture: {fileID: 0} + m_SpotCookie: {fileID: 10001, guid: 0000000000000000e000000000000000, type: 0} + m_DefaultReflectionMode: 0 + m_DefaultReflectionResolution: 128 + m_ReflectionBounces: 1 + m_ReflectionIntensity: 1 + m_CustomReflection: {fileID: 0} + m_Sun: {fileID: 0} + m_UseRadianceAmbientProbe: 0 +--- !u!157 &3 +LightmapSettings: + m_ObjectHideFlags: 0 + serializedVersion: 12 + m_GIWorkflowMode: 1 + m_GISettings: + serializedVersion: 2 + m_BounceScale: 1 + m_IndirectOutputScale: 1 + m_AlbedoBoost: 1 + m_EnvironmentLightingMode: 0 + m_EnableBakedLightmaps: 1 + m_EnableRealtimeLightmaps: 0 + m_LightmapEditorSettings: + serializedVersion: 12 + m_Resolution: 2 + m_BakeResolution: 40 + m_AtlasSize: 1024 + m_AO: 0 + m_AOMaxDistance: 1 + m_CompAOExponent: 1 + m_CompAOExponentDirect: 0 + m_ExtractAmbientOcclusion: 0 + m_Padding: 2 + m_LightmapParameters: {fileID: 0} + m_LightmapsBakeMode: 1 + m_TextureCompression: 1 + m_FinalGather: 0 + m_FinalGatherFiltering: 1 + m_FinalGatherRayCount: 256 + m_ReflectionCompression: 2 + m_MixedBakeMode: 2 + m_BakeBackend: 1 + m_PVRSampling: 1 + m_PVRDirectSampleCount: 32 + m_PVRSampleCount: 512 + m_PVRBounces: 2 + m_PVREnvironmentSampleCount: 256 + m_PVREnvironmentReferencePointCount: 2048 + m_PVRFilteringMode: 1 + m_PVRDenoiserTypeDirect: 1 + m_PVRDenoiserTypeIndirect: 1 + m_PVRDenoiserTypeAO: 1 + m_PVRFilterTypeDirect: 0 + m_PVRFilterTypeIndirect: 0 + m_PVRFilterTypeAO: 0 + m_PVREnvironmentMIS: 1 + m_PVRCulling: 1 + m_PVRFilteringGaussRadiusDirect: 1 + m_PVRFilteringGaussRadiusIndirect: 5 + m_PVRFilteringGaussRadiusAO: 2 + m_PVRFilteringAtrousPositionSigmaDirect: 0.5 + m_PVRFilteringAtrousPositionSigmaIndirect: 2 + m_PVRFilteringAtrousPositionSigmaAO: 1 + m_ExportTrainingData: 0 + m_TrainingDataDestination: TrainingData + m_LightProbeSampleCountMultiplier: 4 + m_LightingDataAsset: {fileID: 0} + m_LightingSettings: {fileID: 0} +--- !u!196 &4 +NavMeshSettings: + serializedVersion: 2 + m_ObjectHideFlags: 0 + m_BuildSettings: + serializedVersion: 3 + agentTypeID: 0 + agentRadius: 0.5 + agentHeight: 2 + agentSlope: 45 + agentClimb: 0.4 + ledgeDropHeight: 0 + maxJumpAcrossDistance: 0 + minRegionArea: 2 + manualCellSize: 0 + cellSize: 0.16666667 + manualTileSize: 0 + tileSize: 256 + buildHeightMesh: 0 + maxJobWorkers: 0 + preserveTilesOutsideBounds: 0 + debug: + m_Flags: 0 + m_NavMeshData: {fileID: 0} +--- !u!1 &353505144 +GameObject: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + serializedVersion: 6 + m_Component: + - component: {fileID: 353505146} + - component: {fileID: 353505145} + - component: {fileID: 353505147} + m_Layer: 0 + m_Name: Directional Light + m_TagString: Untagged + m_Icon: {fileID: 0} + m_NavMeshLayer: 0 + m_StaticEditorFlags: 0 + m_IsActive: 1 +--- !u!108 &353505145 +Light: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 353505144} + m_Enabled: 1 + serializedVersion: 10 + m_Type: 1 + m_Shape: 0 + m_Color: {r: 1, g: 0.95686275, b: 0.8392157, a: 1} + m_Intensity: 1 + m_Range: 10 + m_SpotAngle: 30 + m_InnerSpotAngle: 21.80208 + m_CookieSize: 10 + m_Shadows: + m_Type: 2 + m_Resolution: -1 + m_CustomResolution: -1 + m_Strength: 1 + m_Bias: 0.05 + m_NormalBias: 0.4 + m_NearPlane: 0.2 + m_CullingMatrixOverride: + e00: 1 + e01: 0 + e02: 0 + e03: 0 + e10: 0 + e11: 1 + e12: 0 + e13: 0 + e20: 0 + e21: 0 + e22: 1 + e23: 0 + e30: 0 + e31: 0 + e32: 0 + e33: 1 + m_UseCullingMatrixOverride: 0 + m_Cookie: {fileID: 0} + m_DrawHalo: 0 + m_Flare: {fileID: 0} + m_RenderMode: 0 + m_CullingMask: + serializedVersion: 2 + m_Bits: 4294967295 + m_RenderingLayerMask: 1 + m_Lightmapping: 4 + m_LightShadowCasterMode: 0 + m_AreaSize: {x: 1, y: 1} + m_BounceIntensity: 1 + m_ColorTemperature: 6570 + m_UseColorTemperature: 0 + m_BoundingSphereOverride: {x: 0, y: 0, z: 0, w: 0} + m_UseBoundingSphereOverride: 0 + m_UseViewFrustumForShadowCasterCull: 1 + m_ShadowRadius: 0 + m_ShadowAngle: 0 +--- !u!4 &353505146 +Transform: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 353505144} + serializedVersion: 2 + m_LocalRotation: {x: 0.40821788, y: -0.23456968, z: 0.10938163, w: 0.8754261} + m_LocalPosition: {x: 0, y: 3, z: 0} + m_LocalScale: {x: 1, y: 1, z: 1} + m_ConstrainProportionsScale: 0 + m_Children: [] + m_Father: {fileID: 0} + m_LocalEulerAnglesHint: {x: 50, y: -30, z: 0} +--- !u!114 &353505147 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 353505144} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: 474bcb49853aa07438625e644c072ee6, type: 3} + m_Name: + m_EditorClassIdentifier: + m_Version: 3 + m_UsePipelineSettings: 1 + m_AdditionalLightsShadowResolutionTier: 2 + m_LightLayerMask: 1 + m_RenderingLayers: 1 + m_CustomShadowLayers: 0 + m_ShadowLayerMask: 1 + m_ShadowRenderingLayers: 1 + m_LightCookieSize: {x: 1, y: 1} + m_LightCookieOffset: {x: 0, y: 0} + m_SoftShadowQuality: 0 +--- !u!1 &363499623 +GameObject: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + serializedVersion: 6 + m_Component: + - component: {fileID: 363499626} + - component: {fileID: 363499625} + - component: {fileID: 363499624} + m_Layer: 0 + m_Name: Main Camera + m_TagString: MainCamera + m_Icon: {fileID: 0} + m_NavMeshLayer: 0 + m_StaticEditorFlags: 0 + m_IsActive: 1 +--- !u!81 &363499624 +AudioListener: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 363499623} + m_Enabled: 1 +--- !u!20 &363499625 +Camera: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 363499623} + m_Enabled: 1 + serializedVersion: 2 + m_ClearFlags: 1 + m_BackGroundColor: {r: 0.19215687, g: 0.3019608, b: 0.4745098, a: 0} + m_projectionMatrixMode: 1 + m_GateFitMode: 2 + m_FOVAxisMode: 0 + m_Iso: 200 + m_ShutterSpeed: 0.005 + m_Aperture: 16 + m_FocusDistance: 10 + m_FocalLength: 50 + m_BladeCount: 5 + m_Curvature: {x: 2, y: 11} + m_BarrelClipping: 0.25 + m_Anamorphism: 0 + m_SensorSize: {x: 36, y: 24} + m_LensShift: {x: 0, y: 0} + m_NormalizedViewPortRect: + serializedVersion: 2 + x: 0 + y: 0 + width: 1 + height: 1 + near clip plane: 0.3 + far clip plane: 1000 + field of view: 60 + orthographic: 0 + orthographic size: 5 + m_Depth: -1 + m_CullingMask: + serializedVersion: 2 + m_Bits: 4294967295 + m_RenderingPath: -1 + m_TargetTexture: {fileID: 0} + m_TargetDisplay: 0 + m_TargetEye: 3 + m_HDR: 1 + m_AllowMSAA: 1 + m_AllowDynamicResolution: 0 + m_ForceIntoRT: 0 + m_OcclusionCulling: 1 + m_StereoConvergence: 10 + m_StereoSeparation: 0.022 +--- !u!4 &363499626 +Transform: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 363499623} + serializedVersion: 2 + m_LocalRotation: {x: 0, y: 0, z: 0, w: 1} + m_LocalPosition: {x: 0, y: 1, z: -10} + m_LocalScale: {x: 1, y: 1, z: 1} + m_ConstrainProportionsScale: 0 + m_Children: [] + m_Father: {fileID: 0} + m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} +--- !u!1 &540129978 +GameObject: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + serializedVersion: 6 + m_Component: + - component: {fileID: 540129979} + - component: {fileID: 540129980} + m_Layer: 0 + m_Name: Playground + m_TagString: Untagged + m_Icon: {fileID: 0} + m_NavMeshLayer: 0 + m_StaticEditorFlags: 0 + m_IsActive: 1 +--- !u!4 &540129979 +Transform: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 540129978} + serializedVersion: 2 + m_LocalRotation: {x: 0, y: 0, z: 0, w: 1} + m_LocalPosition: {x: 0, y: 0, z: 0} + m_LocalScale: {x: 1, y: 1, z: 1} + m_ConstrainProportionsScale: 0 + m_Children: [] + m_Father: {fileID: 0} + m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} +--- !u!114 &540129980 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 540129978} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: ac1c85f65ee844bf8b81e60cb48cff4d, type: 3} + m_Name: + m_EditorClassIdentifier: + callsPerSecond: 10 + exampleMessage: Hello world! Best day ever! + mode: 0 +--- !u!1660057539 &9223372036854775807 +SceneRoots: + m_ObjectHideFlags: 0 + m_Roots: + - {fileID: 363499626} + - {fileID: 353505146} + - {fileID: 540129979} diff --git a/Explorer/Assets/Plugins/RustEthereum/SignServerWrap/Playground/SignServerWrapPlayground.unity.meta b/Explorer/Assets/Plugins/RustEthereum/SignServerWrap/Playground/SignServerWrapPlayground.unity.meta new file mode 100644 index 0000000000..9e03368112 --- /dev/null +++ b/Explorer/Assets/Plugins/RustEthereum/SignServerWrap/Playground/SignServerWrapPlayground.unity.meta @@ -0,0 +1,7 @@ +fileFormatVersion: 2 +guid: 17a41fdfa92284087a0d6f6ff52d2ac3 +DefaultImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Explorer/Assets/Plugins/RustEthereum/SignServerWrap/RustEthereum.SignServer.asmdef b/Explorer/Assets/Plugins/RustEthereum/SignServerWrap/RustEthereum.SignServer.asmdef new file mode 100644 index 0000000000..d9cdb14757 --- /dev/null +++ b/Explorer/Assets/Plugins/RustEthereum/SignServerWrap/RustEthereum.SignServer.asmdef @@ -0,0 +1,18 @@ +{ + "name": "RustEthereum.SignServer", + "rootNamespace": "", + "references": [ + "GUID:166b65e6dfc848bb9fb075f53c293a38", + "GUID:ca4e81cdd6a34d1aa54c32ad41fc5b3b", + "GUID:1d67e2d749f242e7a5dc246253ef5832" + ], + "includePlatforms": [], + "excludePlatforms": [], + "allowUnsafeCode": true, + "overrideReferences": false, + "precompiledReferences": ["Nethereum.Signer.dll"], + "autoReferenced": true, + "defineConstraints": [], + "versionDefines": [], + "noEngineReferences": false +} \ No newline at end of file diff --git a/Explorer/Assets/Plugins/RustEthereum/SignServerWrap/RustEthereum.SignServer.asmdef.meta b/Explorer/Assets/Plugins/RustEthereum/SignServerWrap/RustEthereum.SignServer.asmdef.meta new file mode 100644 index 0000000000..af89568ccd --- /dev/null +++ b/Explorer/Assets/Plugins/RustEthereum/SignServerWrap/RustEthereum.SignServer.asmdef.meta @@ -0,0 +1,7 @@ +fileFormatVersion: 2 +guid: 9428ba407ade34e4ebcf01cca4669d4b +AssemblyDefinitionImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Explorer/Assets/Plugins/RustEthereum/SignServerWrap/RustEthereumAccount.cs b/Explorer/Assets/Plugins/RustEthereum/SignServerWrap/RustEthereumAccount.cs new file mode 100644 index 0000000000..302bb8b0bd --- /dev/null +++ b/Explorer/Assets/Plugins/RustEthereum/SignServerWrap/RustEthereumAccount.cs @@ -0,0 +1,62 @@ +using DCL.Utilities.Extensions; +using DCL.Web3; +using DCL.Web3.Abstract; +using DCL.Web3.Accounts; +using Nethereum.Signer; +using System; + +namespace Plugins.RustEthereum.SignServerWrap +{ + public class RustEthereumAccount : IWeb3Account + { + private readonly IWeb3Account verifierAccount; + + public Web3Address Address { get; } + + public string PrivateKey { get; } + + public RustEthereumAccount(EthECKey key) + { + this.verifierAccount = NethereumAccount.CreateForVerifyOnly(key); + + PrivateKey = key.GetPrivateKey().EnsureNotNull(); + Address = new Web3Address(key.GetPublicAddress()!); + byte[] bytes = key.GetPrivateKeyAsBytes().EnsureNotNull(); + var bytesLen = new UIntPtr((ulong)bytes.Length); + + unsafe + { + fixed (byte* ptr = bytes) + { + bool result = NativeMethods.SignServerInitialize(ptr, bytesLen); + + if (result == false) + throw new Exception("Failed to initialize sign server"); + } + } + } + + public string Sign(string message) + { + const int SIZE_OF_SIGN = 65; + + unsafe + { + byte* signatureBuffer = stackalloc byte[SIZE_OF_SIGN]; + NativeMethods.SignServerSignMessage(message, signatureBuffer); + return ToHex(new Span(signatureBuffer, SIZE_OF_SIGN), true); + } + } + + public bool Verify(string message, string signature) => + verifierAccount.Verify(message, signature); + + public static string ToHex(ReadOnlySpan value, bool prefix = false) + { + string currentPrefix = prefix ? "0x" : ""; + var buffer = new string[value.Length]; + for (var i = 0; i < value.Length; i++) buffer[i] = value[i].ToString("x2"); + return currentPrefix + string.Concat(buffer); + } + } +} diff --git a/Explorer/Assets/Plugins/RustEthereum/SignServerWrap/RustEthereumAccount.cs.meta b/Explorer/Assets/Plugins/RustEthereum/SignServerWrap/RustEthereumAccount.cs.meta new file mode 100644 index 0000000000..48ec93924d --- /dev/null +++ b/Explorer/Assets/Plugins/RustEthereum/SignServerWrap/RustEthereumAccount.cs.meta @@ -0,0 +1,3 @@ +fileFormatVersion: 2 +guid: fa6cf23da5f04e7099ec4039739905a0 +timeCreated: 1724096231 \ No newline at end of file diff --git a/Explorer/Assets/Plugins/RustEthereum/SignServerWrap/Tests.meta b/Explorer/Assets/Plugins/RustEthereum/SignServerWrap/Tests.meta new file mode 100644 index 0000000000..6785b88f0b --- /dev/null +++ b/Explorer/Assets/Plugins/RustEthereum/SignServerWrap/Tests.meta @@ -0,0 +1,3 @@ +fileFormatVersion: 2 +guid: fe6677625a4a4b81bd15f7b9e0445d82 +timeCreated: 1724095830 \ No newline at end of file diff --git a/Explorer/Assets/Plugins/RustEthereum/SignServerWrap/Tests/RustEthereum.SignServer.Tests.asmdef b/Explorer/Assets/Plugins/RustEthereum/SignServerWrap/Tests/RustEthereum.SignServer.Tests.asmdef new file mode 100644 index 0000000000..d3c9f13009 --- /dev/null +++ b/Explorer/Assets/Plugins/RustEthereum/SignServerWrap/Tests/RustEthereum.SignServer.Tests.asmdef @@ -0,0 +1,29 @@ +{ + "name": "RustEthereum.SignServer.Tests", + "rootNamespace": "", + "references": [ + "GUID:5ab29fa8ae5769b49ab29e390caca7a4", + "GUID:9428ba407ade34e4ebcf01cca4669d4b", + "GUID:1d67e2d749f242e7a5dc246253ef5832" + ], + "includePlatforms": [ + "Editor" + ], + "excludePlatforms": [], + "allowUnsafeCode": false, + "overrideReferences": true, + "precompiledReferences": [ + "nunit.framework.dll", + "Nethereum.Signer.dll", + "NSubstitute.dll", + "Arch.dll", + "Arch.System.dll", + "Arch.SystemGroups.dll" + ], + "autoReferenced": false, + "defineConstraints": [ + "UNITY_INCLUDE_TESTS" + ], + "versionDefines": [], + "noEngineReferences": false +} \ No newline at end of file diff --git a/Explorer/Assets/Plugins/RustEthereum/SignServerWrap/Tests/RustEthereum.SignServer.Tests.asmdef.meta b/Explorer/Assets/Plugins/RustEthereum/SignServerWrap/Tests/RustEthereum.SignServer.Tests.asmdef.meta new file mode 100644 index 0000000000..a127f108b7 --- /dev/null +++ b/Explorer/Assets/Plugins/RustEthereum/SignServerWrap/Tests/RustEthereum.SignServer.Tests.asmdef.meta @@ -0,0 +1,3 @@ +fileFormatVersion: 2 +guid: 7800ea85a76544e797fee071dc96ab90 +timeCreated: 1724095991 \ No newline at end of file diff --git a/Explorer/Assets/Plugins/RustEthereum/SignServerWrap/Tests/ValidSigningTest.cs b/Explorer/Assets/Plugins/RustEthereum/SignServerWrap/Tests/ValidSigningTest.cs new file mode 100644 index 0000000000..3cde15cd20 --- /dev/null +++ b/Explorer/Assets/Plugins/RustEthereum/SignServerWrap/Tests/ValidSigningTest.cs @@ -0,0 +1,36 @@ +using DCL.Web3.Accounts; +using Nethereum.Signer; +using NUnit.Framework; + +namespace Plugins.RustEthereum.SignServerWrap.Tests +{ + public class ValidSigningTest + { + private const string TEST_KEY = "0x64fdd126fe0e2de2ccbea065d710e9939d083ec96bb9933b750013f30ee81004"; + private const string MESSAGE = "Test message"; + + [Test] + public void TestSign() + { + var key = new EthECKey(TEST_KEY); + var verifiedAccount = NethereumAccount.CreateForVerifyOnly(key); + string verifiedSignature = verifiedAccount.Sign(MESSAGE + MESSAGE + MESSAGE + MESSAGE); + + var testableAccount = new RustEthereumAccount(key); + string signature = testableAccount.Sign(MESSAGE); + + Assert.True( + verifiedAccount.Verify(MESSAGE, signature), + $"Failed to verify the signature: {signature}\nit should be: {verifiedSignature}" + ); + } + + [Test] + public void TestVerify() + { + var account = new RustEthereumAccount(new EthECKey(TEST_KEY)); + string signature= account.Sign(MESSAGE); + Assert.True(account.Verify(MESSAGE, signature)); + } + } +} diff --git a/Explorer/Assets/Plugins/RustEthereum/SignServerWrap/Tests/ValidSigningTest.cs.meta b/Explorer/Assets/Plugins/RustEthereum/SignServerWrap/Tests/ValidSigningTest.cs.meta new file mode 100644 index 0000000000..267726191d --- /dev/null +++ b/Explorer/Assets/Plugins/RustEthereum/SignServerWrap/Tests/ValidSigningTest.cs.meta @@ -0,0 +1,3 @@ +fileFormatVersion: 2 +guid: 41f47f99e8a8490d8e6b7fc381338f15 +timeCreated: 1724096091 \ No newline at end of file diff --git a/Explorer/Assets/Plugins/RustEthereum/SignServerWrap/Tests/csc.rsp b/Explorer/Assets/Plugins/RustEthereum/SignServerWrap/Tests/csc.rsp new file mode 100644 index 0000000000..dcc377f897 --- /dev/null +++ b/Explorer/Assets/Plugins/RustEthereum/SignServerWrap/Tests/csc.rsp @@ -0,0 +1 @@ +-nullable:enable \ No newline at end of file diff --git a/Explorer/Assets/Plugins/RustEthereum/SignServerWrap/Tests/csc.rsp.meta b/Explorer/Assets/Plugins/RustEthereum/SignServerWrap/Tests/csc.rsp.meta new file mode 100644 index 0000000000..85cd017e08 --- /dev/null +++ b/Explorer/Assets/Plugins/RustEthereum/SignServerWrap/Tests/csc.rsp.meta @@ -0,0 +1,3 @@ +fileFormatVersion: 2 +guid: c0f02ffe13414d8192267a52f4f39435 +timeCreated: 1724096196 \ No newline at end of file diff --git a/Explorer/Assets/Plugins/RustEthereum/SignServerWrap/csc.rsp b/Explorer/Assets/Plugins/RustEthereum/SignServerWrap/csc.rsp new file mode 100644 index 0000000000..dcc377f897 --- /dev/null +++ b/Explorer/Assets/Plugins/RustEthereum/SignServerWrap/csc.rsp @@ -0,0 +1 @@ +-nullable:enable \ No newline at end of file diff --git a/Explorer/Assets/Plugins/RustEthereum/SignServerWrap/csc.rsp.meta b/Explorer/Assets/Plugins/RustEthereum/SignServerWrap/csc.rsp.meta new file mode 100644 index 0000000000..698092576c --- /dev/null +++ b/Explorer/Assets/Plugins/RustEthereum/SignServerWrap/csc.rsp.meta @@ -0,0 +1,3 @@ +fileFormatVersion: 2 +guid: ffa633809ea149269a923a16afdb5d3a +timeCreated: 1724096200 \ No newline at end of file diff --git a/Explorer/Assets/Plugins/RustEthereum/sign-server.meta b/Explorer/Assets/Plugins/RustEthereum/sign-server.meta new file mode 100644 index 0000000000..49894b5b3a --- /dev/null +++ b/Explorer/Assets/Plugins/RustEthereum/sign-server.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: 1413ed33379ed40b0a4ec87cf32a96c2 +folderAsset: yes +DefaultImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Explorer/Assets/Plugins/RustEthereum/sign-server/.gitignore b/Explorer/Assets/Plugins/RustEthereum/sign-server/.gitignore new file mode 100644 index 0000000000..d01bd1a990 --- /dev/null +++ b/Explorer/Assets/Plugins/RustEthereum/sign-server/.gitignore @@ -0,0 +1,21 @@ +# Generated by Cargo +# will have compiled files and executables +debug/ +target/ + +# Remove Cargo.lock from gitignore if creating an executable, leave it for libraries +# More information here https://doc.rust-lang.org/cargo/guide/cargo-toml-vs-cargo-lock.html +Cargo.lock + +# These are backup files generated by rustfmt +**/*.rs.bk + +# MSVC Windows builds of rustc generate these, which store debugging information +*.pdb + +# RustRover +# JetBrains specific template is maintained in a separate JetBrains.gitignore that can +# be found at https://github.com/github/gitignore/blob/main/Global/JetBrains.gitignore +# and can be added to the global gitignore or merged into this file. For a more nuclear +# option (not recommended) you can uncomment the following to ignore the entire idea folder. +#.idea/ \ No newline at end of file diff --git a/Explorer/Assets/Plugins/RustEthereum/sign-server/Cargo.lock.meta b/Explorer/Assets/Plugins/RustEthereum/sign-server/Cargo.lock.meta new file mode 100644 index 0000000000..f474b05354 --- /dev/null +++ b/Explorer/Assets/Plugins/RustEthereum/sign-server/Cargo.lock.meta @@ -0,0 +1,7 @@ +fileFormatVersion: 2 +guid: 14f32fefad7774296a7954fc676d4e80 +DefaultImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Explorer/Assets/Plugins/RustEthereum/sign-server/Cargo.toml b/Explorer/Assets/Plugins/RustEthereum/sign-server/Cargo.toml new file mode 100644 index 0000000000..2ea35a3a25 --- /dev/null +++ b/Explorer/Assets/Plugins/RustEthereum/sign-server/Cargo.toml @@ -0,0 +1,14 @@ +[package] +name = "sign_server" +version = "0.1.0" +edition = "2021" + +[dependencies] +alloy-primitives = "0.7.7" +alloy-signer = "0.2.1" +alloy-signer-local = "0.2.1" +hex = "0.4.3" +lazy_static = "1.5.0" + +[lib] +crate-type = ["lib", "cdylib"] diff --git a/Explorer/Assets/Plugins/RustEthereum/sign-server/Cargo.toml.meta b/Explorer/Assets/Plugins/RustEthereum/sign-server/Cargo.toml.meta new file mode 100644 index 0000000000..1c2d5f3d0d --- /dev/null +++ b/Explorer/Assets/Plugins/RustEthereum/sign-server/Cargo.toml.meta @@ -0,0 +1,7 @@ +fileFormatVersion: 2 +guid: e62e2d91fab8244da9fe295a7b01baf5 +DefaultImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Explorer/Assets/Plugins/RustEthereum/sign-server/src.meta b/Explorer/Assets/Plugins/RustEthereum/sign-server/src.meta new file mode 100644 index 0000000000..399c852c94 --- /dev/null +++ b/Explorer/Assets/Plugins/RustEthereum/sign-server/src.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: 8b6a5378af8b943ca9b9de9d1c90050d +folderAsset: yes +DefaultImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Explorer/Assets/Plugins/RustEthereum/sign-server/src/cabi.rs b/Explorer/Assets/Plugins/RustEthereum/sign-server/src/cabi.rs new file mode 100644 index 0000000000..dfbe437bc4 --- /dev/null +++ b/Explorer/Assets/Plugins/RustEthereum/sign-server/src/cabi.rs @@ -0,0 +1,25 @@ +use std::{ + ffi::{c_char, CStr}, + ptr, +}; + +use crate::SIGN_SERVER; + +/// # Safety +/// +/// The foreign language must only provide valid pointers +#[no_mangle] +pub unsafe extern "C" fn sign_server_initialize(data: *const u8, len: usize) -> bool { + let data = unsafe { std::slice::from_raw_parts(data, len) }; + SIGN_SERVER.setup(data).is_ok() +} + +/// # Safety +/// +/// The foreign language must only provide valid pointers that handles 65 bytes +#[no_mangle] +pub unsafe extern "C" fn sign_server_sign_message(message: *const c_char, res_ptr: *mut *const u8) { + let string_message = CStr::from_ptr(message).to_str().unwrap(); + let signature = SIGN_SERVER.sign_message(string_message).unwrap(); + ptr::copy(signature.as_ptr(), res_ptr as *mut u8, signature.len()); +} diff --git a/Explorer/Assets/Plugins/RustEthereum/sign-server/src/cabi.rs.meta b/Explorer/Assets/Plugins/RustEthereum/sign-server/src/cabi.rs.meta new file mode 100644 index 0000000000..420400ba7e --- /dev/null +++ b/Explorer/Assets/Plugins/RustEthereum/sign-server/src/cabi.rs.meta @@ -0,0 +1,7 @@ +fileFormatVersion: 2 +guid: 2cab7fff52cdc4becabbcca2b33c6fec +DefaultImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Explorer/Assets/Plugins/RustEthereum/sign-server/src/lib.rs b/Explorer/Assets/Plugins/RustEthereum/sign-server/src/lib.rs new file mode 100644 index 0000000000..868df3c253 --- /dev/null +++ b/Explorer/Assets/Plugins/RustEthereum/sign-server/src/lib.rs @@ -0,0 +1,8 @@ +pub mod cabi; +pub mod server; + +use lazy_static::lazy_static; + +lazy_static! { + pub static ref SIGN_SERVER: server::SignServer = server::SignServer::default(); +} diff --git a/Explorer/Assets/Plugins/RustEthereum/sign-server/src/lib.rs.meta b/Explorer/Assets/Plugins/RustEthereum/sign-server/src/lib.rs.meta new file mode 100644 index 0000000000..534470a646 --- /dev/null +++ b/Explorer/Assets/Plugins/RustEthereum/sign-server/src/lib.rs.meta @@ -0,0 +1,7 @@ +fileFormatVersion: 2 +guid: 8733dff57f8314c1cb7641d86216c82c +DefaultImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Explorer/Assets/Plugins/RustEthereum/sign-server/src/server.rs b/Explorer/Assets/Plugins/RustEthereum/sign-server/src/server.rs new file mode 100644 index 0000000000..220d31ebfe --- /dev/null +++ b/Explorer/Assets/Plugins/RustEthereum/sign-server/src/server.rs @@ -0,0 +1,82 @@ +use std::sync::Mutex; + +use alloy_primitives::B256; +use alloy_signer::{k256::ecdsa::SigningKey, SignerSync}; +use alloy_signer_local::{LocalSigner, PrivateKeySigner}; + +pub struct SignServer { + signer: Mutex>>, +} + +impl Default for SignServer { + fn default() -> Self { + Self { + signer: Default::default(), + } + } +} + +impl SignServer { + pub fn setup(&self, private_key: &[u8]) -> Result<(), std::fmt::Error> { + let fixed_bytes = B256::from_slice(private_key); + let create_result = PrivateKeySigner::from_bytes(&fixed_bytes); + if create_result.is_err() { + return Err(std::fmt::Error); + } + + let signer = create_result.unwrap(); + + match self.signer.lock() { + Ok(mut guard) => { + // If lock is successful, set the signer + *guard = Some(signer); + Ok(()) + } + Err(_e) => Err(std::fmt::Error::default()), + } + } + + pub fn sign_message(&self, message: &str) -> Result<[u8; 65], std::fmt::Error> { + match self.signer.lock() { + Ok(guard) => { + let signer = guard.as_ref().unwrap(); + let bytes = message.as_bytes(); + let sign_result = signer.sign_message_sync(bytes); + match sign_result { + Ok(signature) => { + return Ok(signature.as_bytes()); + } + Err(_e) => { + return Err(std::fmt::Error::default()); + } + } + } + Err(_e) => Err(std::fmt::Error::default()), + } + } +} + +#[cfg(test)] +mod tests { + use super::*; + + #[test] + fn sign() { + //0x64fdd126fe0e2de2ccbea065d710e9939d083ec96bb9933b750013f30ee81004 + let key_str = "64fdd126fe0e2de2ccbea065d710e9939d083ec96bb9933b750013f30ee81004"; + let message = "Test message"; + //0x578d0780163581456421895b03b79e038ab898d013450b3b58e20432fd89a0b54b86ae68348972fb8ca7544a88327e8628d32ba3e3a703b0e988f348ba26c3da1b + let required_signature = "578d0780163581456421895b03b79e038ab898d013450b3b58e20432fd89a0b54b86ae68348972fb8ca7544a88327e8628d32ba3e3a703b0e988f348ba26c3da1b"; + + let server = SignServer::default(); + let vec_key = hex::decode(key_str).unwrap(); + let private_key = vec_key.as_slice(); + server.setup(private_key).unwrap(); + + let signature = server.sign_message(message).unwrap(); + + let signature_str = hex::encode(signature); + + assert_eq!(signature_str, required_signature); + } +} diff --git a/Explorer/Assets/Plugins/RustEthereum/sign-server/src/server.rs.meta b/Explorer/Assets/Plugins/RustEthereum/sign-server/src/server.rs.meta new file mode 100644 index 0000000000..4aa08d7fcf --- /dev/null +++ b/Explorer/Assets/Plugins/RustEthereum/sign-server/src/server.rs.meta @@ -0,0 +1,7 @@ +fileFormatVersion: 2 +guid: f06343ea58c1144fb921a319b09b1315 +DefaultImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Explorer/Assets/Plugins/RustEthereum/sign-server/target.meta b/Explorer/Assets/Plugins/RustEthereum/sign-server/target.meta new file mode 100644 index 0000000000..f6ba948d73 --- /dev/null +++ b/Explorer/Assets/Plugins/RustEthereum/sign-server/target.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: 1c4a1633204134601893289a31103eb5 +folderAsset: yes +DefaultImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Explorer/Assets/Scripts/Global/Dynamic/BootstrapContainer.cs b/Explorer/Assets/Scripts/Global/Dynamic/BootstrapContainer.cs index de2371a0c2..b52512d847 100644 --- a/Explorer/Assets/Scripts/Global/Dynamic/BootstrapContainer.cs +++ b/Explorer/Assets/Scripts/Global/Dynamic/BootstrapContainer.cs @@ -7,6 +7,8 @@ using DCL.PerformanceAndDiagnostics.Analytics; using DCL.PluginSystem; using DCL.Web3; +using DCL.Web3.Abstract; +using DCL.Web3.Accounts.Factory; using DCL.Web3.Authenticators; using DCL.Web3.Identities; using Global.AppArgs; @@ -27,6 +29,7 @@ public class BootstrapContainer : DCLGlobalContainer public IDecentralandUrlsSource DecentralandUrlsSource { get; private set; } public IWebBrowser WebBrowser { get; private set; } + public IWeb3AccountFactory Web3AccountFactory { get; private set; } public IAssetsProvisioner? AssetsProvisioner { get; private init; } public IBootstrap? Bootstrap { get; private set; } public IWeb3IdentityCache? IdentityCache { get; private set; } @@ -34,7 +37,6 @@ public class BootstrapContainer : DCLGlobalContainer public IWeb3VerifiedAuthenticator? Web3Authenticator { get; private set; } public IAnalyticsController? Analytics { get; private set; } public IDebugSettings DebugSettings { get; private set; } - public IAppArgs CommandLineArgs { get; private set; } public IReportsHandlingSettings ReportHandlingSettings => reportHandlingSettings.Value; public IAppArgs ApplicationParametersParser { get; private set; } @@ -59,9 +61,11 @@ public static async UniTask CreateAsync( { var decentralandUrlsSource = new DecentralandUrlsSource(sceneLoaderSettings.DecentralandEnvironment); var browser = new UnityAppWebBrowser(decentralandUrlsSource); + var web3AccountFactory = new Web3AccountFactory(); var bootstrapContainer = new BootstrapContainer { + Web3AccountFactory = web3AccountFactory, AssetsProvisioner = new AddressablesProvisioner(), DecentralandUrlsSource = decentralandUrlsSource, WebBrowser = browser, @@ -73,7 +77,7 @@ await bootstrapContainer.InitializeContainerAsync(sceneLoaderSettings.Web3WhitelistMethods)); + identityCache, + web3AccountFactory, + new HashSet(sceneLoaderSettings.Web3WhitelistMethods) + ); IWeb3VerifiedAuthenticator coreWeb3Authenticator = new ProxyVerifiedWeb3Authenticator(dappWeb3Authenticator, identityCache); diff --git a/Explorer/Assets/Scripts/Global/Static/StaticSceneLauncher.cs b/Explorer/Assets/Scripts/Global/Static/StaticSceneLauncher.cs index a3e4084be3..bf0751dd10 100644 --- a/Explorer/Assets/Scripts/Global/Static/StaticSceneLauncher.cs +++ b/Explorer/Assets/Scripts/Global/Static/StaticSceneLauncher.cs @@ -20,6 +20,7 @@ using System.Threading; using DCL.PerformanceAndDiagnostics.DotNetLogging; using DCL.Utilities.Extensions; +using DCL.Web3.Accounts.Factory; using Global.AppArgs; using Global.Dynamic; using UnityEngine; @@ -66,26 +67,42 @@ public async UniTask InitializationFlowAsync(CancellationToken ct) DotNetLoggingPlugin.Initialize(); if (useStoredCredentials && useRealAuthentication) // avoid storing invalid credentials - identityCache = new ProxyIdentityCache(new MemoryWeb3IdentityCache(), - new PlayerPrefsIdentityProvider(new PlayerPrefsIdentityProvider.DecentralandIdentityWithNethereumAccountJsonSerializer())); + identityCache = new ProxyIdentityCache( + new MemoryWeb3IdentityCache(), + new PlayerPrefsIdentityProvider( + new PlayerPrefsIdentityProvider.DecentralandIdentityWithNethereumAccountJsonSerializer( + new Web3AccountFactory() + ) + ) + ); else identityCache = new MemoryWeb3IdentityCache(); + var web3AccountFactory = new Web3AccountFactory(); + var decentralandUrlsSource = new DecentralandUrlsSource(DecentralandEnvironment.Org); - var dappWeb3Authenticator = new DappWeb3Authenticator(new UnityAppWebBrowser(decentralandUrlsSource), - authenticationServerUrl, authenticationSignatureUrl, + var dappWeb3Authenticator = new DappWeb3Authenticator( + new UnityAppWebBrowser(decentralandUrlsSource), + authenticationServerUrl, + authenticationSignatureUrl, identityCache, - new HashSet(ethWhitelistMethods)); + web3AccountFactory, + new HashSet(ethWhitelistMethods) + ); IWeb3Authenticator web3Authenticator; if (useRealAuthentication) - web3Authenticator = new ProxyWeb3Authenticator(dappWeb3Authenticator, - identityCache); + web3Authenticator = new ProxyWeb3Authenticator( + dappWeb3Authenticator, + identityCache + ); else - web3Authenticator = new ProxyWeb3Authenticator(new RandomGeneratedWeb3Authenticator(), - identityCache); + web3Authenticator = new ProxyWeb3Authenticator( + new RandomGeneratedWeb3Authenticator(web3AccountFactory), + identityCache + ); if (useRealAuthentication) { diff --git a/Explorer/Assets/Scripts/SceneRuntime/SceneRuntime.asmdef b/Explorer/Assets/Scripts/SceneRuntime/SceneRuntime.asmdef index 7720d71a23..76c458d512 100644 --- a/Explorer/Assets/Scripts/SceneRuntime/SceneRuntime.asmdef +++ b/Explorer/Assets/Scripts/SceneRuntime/SceneRuntime.asmdef @@ -22,8 +22,9 @@ "GUID:3c7b57a14671040bd8c549056adc04f5", "GUID:b4018cfd60a549f6ab9f20b9a5db4a56", "GUID:91cf8206af184dac8e30eb46747e9939", + "GUID:4725c02394ab4ce19f889e4e8001f989", "GUID:7175400a68914a45acecc9fb068de3b8", - "GUID:4725c02394ab4ce19f889e4e8001f989" + "GUID:ca4e81cdd6a34d1aa54c32ad41fc5b3b" ], "includePlatforms": [], "excludePlatforms": [], diff --git a/Explorer/Assets/Scripts/Utility/Tasks/UniTaskExtensions.cs b/Explorer/Assets/Scripts/Utility/Tasks/UniTaskExtensions.cs new file mode 100644 index 0000000000..7c283ef19d --- /dev/null +++ b/Explorer/Assets/Scripts/Utility/Tasks/UniTaskExtensions.cs @@ -0,0 +1,10 @@ +using Cysharp.Threading.Tasks; + +namespace Utility.Tasks +{ + public static class UniTaskExtensions + { + public static UniTask AsUniTaskResult(this T value) => + new (value); + } +} diff --git a/Explorer/Assets/Scripts/Utility/Tasks/UniTaskExtensions.cs.meta b/Explorer/Assets/Scripts/Utility/Tasks/UniTaskExtensions.cs.meta new file mode 100644 index 0000000000..3ef2e669f4 --- /dev/null +++ b/Explorer/Assets/Scripts/Utility/Tasks/UniTaskExtensions.cs.meta @@ -0,0 +1,3 @@ +fileFormatVersion: 2 +guid: 016fd0e89692430fba38fc900f4aebc6 +timeCreated: 1724397134 \ No newline at end of file