diff --git a/Assets/Thirdweb/Core/Prefabs/WalletProvider_MagicAuth.prefab b/Assets/Thirdweb/Core/Prefabs/WalletProvider_MagicAuth.prefab index 36371026..553ad48e 100644 --- a/Assets/Thirdweb/Core/Prefabs/WalletProvider_MagicAuth.prefab +++ b/Assets/Thirdweb/Core/Prefabs/WalletProvider_MagicAuth.prefab @@ -9,7 +9,7 @@ GameObject: serializedVersion: 6 m_Component: - component: {fileID: 8849381089353801714} - - component: {fileID: 8849381089353801717} + - component: {fileID: 1354709178478519460} m_Layer: 0 m_Name: WalletProvider_MagicAuth m_TagString: Untagged @@ -32,7 +32,7 @@ Transform: m_Father: {fileID: 0} m_RootOrder: 0 m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} ---- !u!114 &8849381089353801717 +--- !u!114 &1354709178478519460 MonoBehaviour: m_ObjectHideFlags: 0 m_CorrespondingSourceObject: {fileID: 0} diff --git a/Assets/Thirdweb/Core/Prefabs/WalletProvider_Metamask.prefab b/Assets/Thirdweb/Core/Prefabs/WalletProvider_Metamask.prefab index 2bbd59da..98a8b351 100644 --- a/Assets/Thirdweb/Core/Prefabs/WalletProvider_Metamask.prefab +++ b/Assets/Thirdweb/Core/Prefabs/WalletProvider_Metamask.prefab @@ -2989,7 +2989,7 @@ Transform: m_ConstrainProportionsScale: 0 m_Children: [] m_Father: {fileID: 4036888909731852399} - m_RootOrder: 2 + m_RootOrder: 1 m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} --- !u!20 &3503421935344847224 Camera: @@ -5102,6 +5102,7 @@ GameObject: m_Component: - component: {fileID: 3503421935870801902} - component: {fileID: 2433011551695929986} + - component: {fileID: 4559418603046196302} m_Layer: 0 m_Name: WalletProvider_Metamask m_TagString: Untagged @@ -5139,6 +5140,27 @@ MonoBehaviour: m_Name: m_EditorClassIdentifier: config: {fileID: 11400000, guid: 6cbb8289bcfbdba43817188b3b4f15e0, type: 2} +--- !u!114 &4559418603046196302 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 3503421935870801903} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: f9088d607e1d7b3478fcc73da2791fec, type: 3} + m_Name: + m_EditorClassIdentifier: + MetamaskCanvas: {fileID: 8744985464267693835} + ConnectButton: {fileID: 3503421936221029119} + welcomeScreen: {fileID: 3503421936027490483} + mainScreen: {fileID: 3503421936428190661} + DeeplinkButton: {fileID: 3503421936066145370} + HeaderText: {fileID: 3503421936426239605} + DescriptionText: {fileID: 3503421935881847325} + loadingSprite: {fileID: 21300000, guid: 717e217158e3e694eb447a4a5910fbbd, type: 3} + QRCodeImage: {fileID: 32878201333017964} --- !u!1 &3503421935881847323 GameObject: m_ObjectHideFlags: 0 @@ -6522,7 +6544,7 @@ Transform: m_ConstrainProportionsScale: 0 m_Children: [] m_Father: {fileID: 4036888909731852399} - m_RootOrder: 3 + m_RootOrder: 2 m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} --- !u!114 &3503421936118848201 MonoBehaviour: @@ -6737,19 +6759,7 @@ MonoBehaviour: m_OnClick: m_PersistentCalls: m_Calls: - - m_Target: {fileID: 2433011551695929986} - m_TargetAssemblyTypeName: MetaMask.Unity.MetaMaskUnity, MetaMaskUnity.Runtime - m_MethodName: Connect - m_Mode: 1 - m_Arguments: - m_ObjectArgument: {fileID: 0} - m_ObjectArgumentAssemblyTypeName: UnityEngine.Object, UnityEngine - m_IntArgument: 0 - m_FloatArgument: 0 - m_StringArgument: - m_BoolArgument: 0 - m_CallState: 2 - - m_Target: {fileID: 3503421936427613058} + - m_Target: {fileID: 4559418603046196302} m_TargetAssemblyTypeName: MetaMask.Unity.Samples.VisualController, Assembly-CSharp m_MethodName: OpenMainScreen m_Mode: 1 @@ -7964,59 +7974,6 @@ MonoBehaviour: m_hasFontAssetChanged: 0 m_baseMaterial: {fileID: 0} m_maskOffset: {x: 0, y: 0, z: 0, w: 0} ---- !u!1 &3503421936427613057 -GameObject: - m_ObjectHideFlags: 0 - m_CorrespondingSourceObject: {fileID: 0} - m_PrefabInstance: {fileID: 0} - m_PrefabAsset: {fileID: 0} - serializedVersion: 6 - m_Component: - - component: {fileID: 3503421936427613059} - - component: {fileID: 3503421936427613058} - m_Layer: 0 - m_Name: Controller - m_TagString: Untagged - m_Icon: {fileID: 0} - m_NavMeshLayer: 0 - m_StaticEditorFlags: 0 - m_IsActive: 1 ---- !u!4 &3503421936427613059 -Transform: - m_ObjectHideFlags: 0 - m_CorrespondingSourceObject: {fileID: 0} - m_PrefabInstance: {fileID: 0} - m_PrefabAsset: {fileID: 0} - m_GameObject: {fileID: 3503421936427613057} - 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: 4036888909731852399} - m_RootOrder: 1 - m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} ---- !u!114 &3503421936427613058 -MonoBehaviour: - m_ObjectHideFlags: 0 - m_CorrespondingSourceObject: {fileID: 0} - m_PrefabInstance: {fileID: 0} - m_PrefabAsset: {fileID: 0} - m_GameObject: {fileID: 3503421936427613057} - m_Enabled: 1 - m_EditorHideFlags: 0 - m_Script: {fileID: 11500000, guid: f9088d607e1d7b3478fcc73da2791fec, type: 3} - m_Name: - m_EditorClassIdentifier: - MetamaskCanvas: {fileID: 8744985464267693835} - ConnectButton: {fileID: 3503421936221029119} - welcomeScreen: {fileID: 3503421936027490483} - mainScreen: {fileID: 3503421936428190661} - DeeplinkButton: {fileID: 3503421936066145370} - HeaderText: {fileID: 3503421936426239605} - DescriptionText: {fileID: 3503421935881847325} - loadingSprite: {fileID: 21300000, guid: 717e217158e3e694eb447a4a5910fbbd, type: 3} - QRCodeImage: {fileID: 32878201333017964} --- !u!1 &3503421936427620979 GameObject: m_ObjectHideFlags: 0 @@ -9547,7 +9504,6 @@ Transform: m_ConstrainProportionsScale: 0 m_Children: - {fileID: 3503421936374056257} - - {fileID: 3503421936427613059} - {fileID: 3503421935344847227} - {fileID: 3503421936118848200} m_Father: {fileID: 3503421935870801902} diff --git a/Assets/Thirdweb/Core/Scripts/Contract.cs b/Assets/Thirdweb/Core/Scripts/Contract.cs index d2f6fae4..2baacc3c 100644 --- a/Assets/Thirdweb/Core/Scripts/Contract.cs +++ b/Assets/Thirdweb/Core/Scripts/Contract.cs @@ -44,7 +44,8 @@ public class Contract : Routable /// public Events events; - public Contract(string chain, string address, string abi = null) : base(abi != null ? $"{address}{Routable.subSeparator}{abi}" : address) + public Contract(string chain, string address, string abi = null) + : base(abi != null ? $"{address}{Routable.subSeparator}{abi}" : address) { this.chain = chain; this.address = address; @@ -65,7 +66,7 @@ public async Task GetBalance() } else { - BigInteger balance = await ThirdwebManager.Instance.SDK.nativeSession.web3.Eth.GetBalance.SendRequestAsync(address); + BigInteger balance = await ThirdwebManager.Instance.SDK.session.Web3.Eth.GetBalance.SendRequestAsync(address); CurrencyValue cv = new CurrencyValue(); cv.value = balance.ToString(); cv.displayValue = balance.ToString().ToEth(); @@ -90,7 +91,7 @@ public async Task Read(string functionName, params object[] args) if (this.abi == null) throw new UnityException("You must pass an ABI for native platform custom calls"); - var contract = ThirdwebManager.Instance.SDK.nativeSession.web3.Eth.GetContract(this.abi, this.address); + var contract = ThirdwebManager.Instance.SDK.session.Web3.Eth.GetContract(this.abi, this.address); var function = contract.GetFunction(functionName); return await function.CallAsync(args); } @@ -126,7 +127,7 @@ public async Task Write(string functionName, TransactionReque if (this.abi == null) throw new UnityException("You must pass an ABI for native platform custom calls"); - var contract = ThirdwebManager.Instance.SDK.nativeSession.web3.Eth.GetContract(this.abi, this.address); + var contract = ThirdwebManager.Instance.SDK.session.Web3.Eth.GetContract(this.abi, this.address); var function = contract.GetFunction(functionName); diff --git a/Assets/Thirdweb/Core/Scripts/Deployer.cs b/Assets/Thirdweb/Core/Scripts/Deployer.cs index e37acc85..19d206c9 100644 --- a/Assets/Thirdweb/Core/Scripts/Deployer.cs +++ b/Assets/Thirdweb/Core/Scripts/Deployer.cs @@ -37,9 +37,9 @@ public async Task DeployNFTDrop(NFTContractDeployMetadata metadata) throw new UnityException("This functionality is not yet available on your current platform."); var deploymentMessage = new DropERC721Deployment(); - var deploymentHandler = ThirdwebManager.Instance.SDK.nativeSession.web3.Eth.GetContractDeploymentHandler(); + var deploymentHandler = ThirdwebManager.Instance.SDK.session.Web3.Eth.GetContractDeploymentHandler(); var deploymentReceipt = await deploymentHandler.SendRequestAndWaitForReceiptAsync(deploymentMessage); - DropERC721Service dropERC721Service = new DropERC721Service(ThirdwebManager.Instance.SDK.nativeSession.web3, deploymentReceipt.ContractAddress); + DropERC721Service dropERC721Service = new DropERC721Service(ThirdwebManager.Instance.SDK.session.Web3, deploymentReceipt.ContractAddress); var initializeReceipt = await dropERC721Service.InitializeRequestAndWaitForReceiptAsync( defaultAdmin: await ThirdwebManager.Instance.SDK.wallet.GetAddress(), name: metadata.name, diff --git a/Assets/Thirdweb/Core/Scripts/ERC20.cs b/Assets/Thirdweb/Core/Scripts/ERC20.cs index 61ea168f..d55d4e54 100644 --- a/Assets/Thirdweb/Core/Scripts/ERC20.cs +++ b/Assets/Thirdweb/Core/Scripts/ERC20.cs @@ -488,8 +488,10 @@ public async Task Generate(ERC20MintPayload payloadToSign, s Uid = payloadToSign.uid.HexStringToByteArray() }; + var name = await TransactionManager.ThirdwebRead(contractAddress, new TokenERC20Contract.NameFunction() { }); + string signature = await Thirdweb.EIP712.GenerateSignature_TokenERC20( - "TokenERC20", + name.ReturnValue1, "1", await ThirdwebManager.Instance.SDK.wallet.GetChainId(), contractAddress, diff --git a/Assets/Thirdweb/Core/Scripts/Marketplace.cs b/Assets/Thirdweb/Core/Scripts/Marketplace.cs index a74961b9..bcfd27a0 100644 --- a/Assets/Thirdweb/Core/Scripts/Marketplace.cs +++ b/Assets/Thirdweb/Core/Scripts/Marketplace.cs @@ -905,7 +905,7 @@ public async Task MakeOffer(MakeOfferInput input) AssetContract = input.assetContractAddress, TokenId = BigInteger.Parse(input.tokenId), Quantity = BigInteger.Parse(input.quantity ?? "1"), - Currency = input.currencyContractAddress ?? Utils.GetNativeTokenWrapper(ThirdwebManager.Instance.SDK.nativeSession.lastChainId), + Currency = input.currencyContractAddress ?? Utils.GetNativeTokenWrapper(ThirdwebManager.Instance.SDK.session.ChainId), TotalPrice = BigInteger.Parse(input.totalPrice.ToWei()), ExpirationTimestamp = (BigInteger)(input.endTimestamp ?? Utils.GetUnixTimeStampIn10Years()) } diff --git a/Assets/Thirdweb/Core/Scripts/Multicall.cs b/Assets/Thirdweb/Core/Scripts/Multicall.cs index 89cc73ed..4ae962b7 100644 --- a/Assets/Thirdweb/Core/Scripts/Multicall.cs +++ b/Assets/Thirdweb/Core/Scripts/Multicall.cs @@ -38,7 +38,7 @@ public static async Task> GetOwnedTokenData721(string contrac public static async Task> GetAllOwners721(string contractAddress, int startTokenId, int endTokenId) { - MultiQueryHandler multiqueryHandler = ThirdwebManager.Instance.SDK.nativeSession.web3.Eth.GetMultiQueryHandler(); + MultiQueryHandler multiqueryHandler = ThirdwebManager.Instance.SDK.session.Web3.Eth.GetMultiQueryHandler(); var calls = new List>(); for (int i = startTokenId; i <= endTokenId; i++) { @@ -61,7 +61,7 @@ public static async Task> GetAllOwners721(string contractAddr public static async Task> GetSpecificOwners721(string contractAddress, int[] tokenIds) { - MultiQueryHandler multiqueryHandler = ThirdwebManager.Instance.SDK.nativeSession.web3.Eth.GetMultiQueryHandler(); + MultiQueryHandler multiqueryHandler = ThirdwebManager.Instance.SDK.session.Web3.Eth.GetMultiQueryHandler(); var calls = new List>(); for (int i = 0; i < tokenIds.Length; i++) { @@ -84,7 +84,7 @@ public static async Task> GetSpecificOwners721(string contrac public static async Task> GetAllTokenUris721(string contractAddress, int startTokenId, int endTokenId) { - MultiQueryHandler multiqueryHandler = ThirdwebManager.Instance.SDK.nativeSession.web3.Eth.GetMultiQueryHandler(); + MultiQueryHandler multiqueryHandler = ThirdwebManager.Instance.SDK.session.Web3.Eth.GetMultiQueryHandler(); var calls = new List>(); for (int i = startTokenId; i <= endTokenId; i++) { @@ -107,7 +107,7 @@ public static async Task> GetAllTokenUris721(string contractA public static async Task> GetSpecificTokenUris721(string contractAddress, int[] tokenIds) { - MultiQueryHandler multiqueryHandler = ThirdwebManager.Instance.SDK.nativeSession.web3.Eth.GetMultiQueryHandler(); + MultiQueryHandler multiqueryHandler = ThirdwebManager.Instance.SDK.session.Web3.Eth.GetMultiQueryHandler(); var calls = new List>(); for (int i = 0; i < tokenIds.Length; i++) { @@ -130,7 +130,7 @@ public static async Task> GetSpecificTokenUris721(string cont public static async Task> GetOwnedTokenIds721(string contractAddress, string ownerAddress) { - MultiQueryHandler multiqueryHandler = ThirdwebManager.Instance.SDK.nativeSession.web3.Eth.GetMultiQueryHandler(); + MultiQueryHandler multiqueryHandler = ThirdwebManager.Instance.SDK.session.Web3.Eth.GetMultiQueryHandler(); var contract = ThirdwebManager.Instance.SDK.GetContract(contractAddress); var balance = BigInteger.Parse(await contract.ERC721.BalanceOf(ownerAddress)); var calls = new List>(); diff --git a/Assets/Thirdweb/Core/Scripts/ThirdwebInterceptor.cs b/Assets/Thirdweb/Core/Scripts/ThirdwebInterceptor.cs new file mode 100644 index 00000000..928218f4 --- /dev/null +++ b/Assets/Thirdweb/Core/Scripts/ThirdwebInterceptor.cs @@ -0,0 +1,44 @@ +using System; +using System.Collections.Generic; +using System.Threading.Tasks; +using MetaMask.Unity; +using Nethereum.JsonRpc.Client; +using Newtonsoft.Json; + +namespace Thirdweb +{ + public class ThirdwebInterceptor : RequestInterceptor + { + private readonly ThirdwebSession _thirdwebSession; + + public ThirdwebInterceptor(ThirdwebSession thirdwebSession) + { + _thirdwebSession = thirdwebSession; + } + + public override async Task InterceptSendRequestAsync(Func> interceptedSendRequestAsync, RpcRequest request, string route = null) + { + if (request.Method == "eth_accounts" && _thirdwebSession.IsConnected) + { + return await _thirdwebSession.GetAddress().ConfigureAwait(false); + } + + return await interceptedSendRequestAsync(request, route).ConfigureAwait(false); + } + + public override async Task InterceptSendRequestAsync( + Func> interceptedSendRequestAsync, + string method, + string route = null, + params object[] paramList + ) + { + if (method == "eth_accounts") + { + return await _thirdwebSession.GetAddress().ConfigureAwait(false); + } + + return await interceptedSendRequestAsync(method, route, paramList).ConfigureAwait(false); + } + } +} diff --git a/Assets/Thirdweb/Core/Scripts/ThirdwebInterceptor.cs.meta b/Assets/Thirdweb/Core/Scripts/ThirdwebInterceptor.cs.meta new file mode 100644 index 00000000..96f35c9a --- /dev/null +++ b/Assets/Thirdweb/Core/Scripts/ThirdwebInterceptor.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: b4751464e13d1c443a0b6eb9a37ec745 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Thirdweb/Core/Scripts/ThirdwebSDK.cs b/Assets/Thirdweb/Core/Scripts/ThirdwebSDK.cs index 801507a6..235c3b3a 100644 --- a/Assets/Thirdweb/Core/Scripts/ThirdwebSDK.cs +++ b/Assets/Thirdweb/Core/Scripts/ThirdwebSDK.cs @@ -1,11 +1,5 @@ using System.Collections.Generic; -using System.Numerics; -using Nethereum.Hex.HexConvertors.Extensions; -using Nethereum.Siwe; -using Nethereum.Web3; -using Nethereum.Web3.Accounts; using UnityEngine; -using WalletConnectSharp.Core.Models.Ethereum; namespace Thirdweb { @@ -108,31 +102,7 @@ public struct BiconomyOptions public Storage storage; - public EthChainData currentChainData; - - public class NativeSession - { - public WalletProvider provider = WalletProvider.LocalWallet; - public int lastChainId = -1; - public string lastRPC = null; - public Account account = null; - public Web3 web3 = null; - public Options options = new Options(); - public SiweMessageService siweSession = new SiweMessageService(); - - public NativeSession(WalletProvider provider, int lastChainId, string lastRPC, Account account, Web3 web3, Options options, SiweMessageService siweSession) - { - this.provider = provider; - this.lastChainId = lastChainId; - this.lastRPC = lastRPC; - this.account = account; - this.web3 = web3; - this.options = options; - this.siweSession = siweSession; - } - } - - public NativeSession nativeSession; + public ThirdwebSession session; /// /// Create an instance of the thirdweb SDK. Requires a webGL browser context. @@ -146,28 +116,16 @@ public NativeSession(WalletProvider provider, int lastChainId, string lastRPC, A this.deployer = new Deployer(); this.storage = new Storage(options.storage); - if (!Utils.IsWebGLBuild()) + if (Utils.IsWebGLBuild()) { - if (chainId == -1) - throw new UnityException("Chain ID override required for native platforms!"); - - string rpc = !chainOrRPC.StartsWith("https://") ? $"https://{chainOrRPC}.rpc.thirdweb.com/339d65590ba0fa79e4c8be0af33d64eda709e13652acb02c6be63f5a1fbef9c3" : chainOrRPC; - nativeSession = new NativeSession(WalletProvider.LocalWallet, chainId, rpc, null, new Web3(rpc), options, new SiweMessageService()); - // Set default WalletOptions - nativeSession.options.wallet = new WalletOptions() - { - appName = options.wallet?.appName ?? "Thirdweb Game", - appDescription = options.wallet?.appDescription ?? "Thirdweb Game Demo", - appIcons = options.wallet?.appIcons ?? new string[] { "https://thirdweb.com/favicon.ico" }, - appUrl = options.wallet?.appUrl ?? "https://thirdweb.com", - magicLinkApiKey = options.wallet?.magicLinkApiKey, - }; - - FetchChainData(); + Bridge.Initialize(chainOrRPC, options); } else { - Bridge.Initialize(chainOrRPC, options); + if (chainId == -1) + throw new UnityException("Chain ID override required for native platforms!"); + string rpc = !chainOrRPC.StartsWith("https://") ? $"https://{chainOrRPC}.rpc.thirdweb.com/339d65590ba0fa79e4c8be0af33d64eda709e13652acb02c6be63f5a1fbef9c3" : chainOrRPC; + this.session = new ThirdwebSession(options, chainId, rpc); } } @@ -181,71 +139,5 @@ public Contract GetContract(string address, string abi = null) { return new Contract(this.chainOrRPC, address, abi); } - - void FetchChainData() - { - var allChainsJson = (TextAsset)Resources.Load("all_chains", typeof(TextAsset)); - // Get networks from chainidnetwork - List allNetworkData = Newtonsoft.Json.JsonConvert.DeserializeObject>(allChainsJson.text); - // Get current network - ChainIDNetworkData currentNetwork = allNetworkData.Find(x => x.chainId == nativeSession.lastChainId.ToString()); - // Get block explorer urls - List explorerUrls = new List(); - foreach (var explorer in currentNetwork.explorers) - explorerUrls.Add(explorer.url); - if (explorerUrls.Count == 0) - explorerUrls.Add("https://etherscan.io"); - // Add chain - currentChainData = new EthChainData() - { - chainId = BigInteger.Parse(currentNetwork.chainId).ToHex(false, true) ?? BigInteger.Parse(nativeSession.lastChainId.ToString()).ToHex(false, true), - blockExplorerUrls = explorerUrls.ToArray(), - chainName = currentNetwork.name ?? ThirdwebManager.Instance.GetCurrentChainIdentifier(), - iconUrls = new string[] { "ipfs://QmdwQDr6vmBtXmK2TmknkEuZNoaDqTasFdZdu3DRw8b2wt" }, - nativeCurrency = new NativeCurrency() - { - name = currentNetwork.nativeCurrency?.name ?? "Ether", - symbol = currentNetwork.nativeCurrency?.symbol ?? "ETH", - decimals = int.Parse(currentNetwork.nativeCurrency?.decimals ?? "18") - }, - rpcUrls = new string[] { nativeSession.lastRPC } - }; - } - - [System.Serializable] - public class ChainIDNetworkData - { - public string name; - public string chain; - public string icon; - public List rpc; - public ChainIDNetworkNativeCurrency nativeCurrency; - public string chainId; - public List explorers; - } - - [System.Serializable] - public class ChainIDNetworkNativeCurrency - { - public string name; - public string symbol; - public string decimals; - } - - [System.Serializable] - public class ChainIDNetworkExplorer - { - public string name; - public string url; - public string standard; - } - - public struct ChaiNIDNetworkIcon - { - public string url; - public int width; - public int height; - public string format; - } } } diff --git a/Assets/Thirdweb/Core/Scripts/ThirdwebSession.cs b/Assets/Thirdweb/Core/Scripts/ThirdwebSession.cs new file mode 100644 index 00000000..854580f3 --- /dev/null +++ b/Assets/Thirdweb/Core/Scripts/ThirdwebSession.cs @@ -0,0 +1,331 @@ +using System; +using System.Collections.Generic; +using System.Numerics; +using System.Threading.Tasks; +using link.magic.unity.sdk; +using MetaMask.NEthereum; +using MetaMask.Unity; +using Nethereum.Hex.HexConvertors.Extensions; +using Nethereum.JsonRpc.Client; +using Nethereum.Siwe; +using Nethereum.Web3; +using Nethereum.Web3.Accounts; +using UnityEngine; +using WalletConnectSharp.Core.Models.Ethereum; +using WalletConnectSharp.NEthereum.Client; +using WalletConnectSharp.Unity; + +namespace Thirdweb +{ + public class ThirdwebSession + { + #region Properties + + public ThirdwebSDK.Options Options { get; private set; } + public int ChainId { get; private set; } + public string RPC { get; private set; } + public SiweMessageService SiweSession { get; private set; } + public Web3 Web3 { get; private set; } + public WalletProvider WalletProvider { get; private set; } + public Account LocalAccount { get; private set; } + public Account PersonalAccount { get; private set; } + public string Email { get; private set; } + public ThirdwebChainData CurrentChainData { get; private set; } + public ThirdwebInterceptor Interceptor { get; private set; } + + public bool IsConnected + { + get { return LocalAccount != null || ThirdwebManager.Instance.SDK.session.WalletProvider != WalletProvider.LocalWallet; } + } + + private static int Nonce = 0; + + #endregion + + #region Constructors + + public ThirdwebSession(ThirdwebSDK.Options options, int chainId, string rpcUrl) + { + Options = options; + ChainId = chainId; + RPC = rpcUrl; + SiweSession = new SiweMessageService(); + Web3 = new Web3(rpcUrl); + WalletProvider = WalletProvider.LocalWallet; + LocalAccount = null; + PersonalAccount = null; + Email = null; + Interceptor = null; + CurrentChainData = FetchChainData(); + } + + #endregion + + #region Public Methods + + public async Task Connect(WalletProvider walletProvider, string password = null, string email = null) + { + WalletProvider = walletProvider; + Email = email; + + switch (walletProvider) + { + case WalletProvider.LocalWallet: + InitializeLocalWallet(password); + break; + case WalletProvider.WalletConnectV1: + await InitializeWalletConnect(); + break; + case WalletProvider.MagicLink: + await InitializeMagicLink(); + break; + case WalletProvider.Metamask: + await InitializeMetaMask(); + break; + default: + throw new UnityException("This wallet connection method is not supported on this platform!"); + } + + Interceptor = new ThirdwebInterceptor(this); + Web3.Client.OverridingRequestInterceptor = Interceptor; + + var connectedChainId = await ThirdwebManager.Instance.SDK.wallet.GetChainId(); + if (connectedChainId != ChainId) + { + try + { + await SwitchNetwork(new ThirdwebChain() { chainId = CurrentChainData.chainId }); + } + catch (System.Exception e) + { + Debug.LogWarning("Switching chain error, attempting to add chain: " + e.Message); + try + { + await AddNetwork(CurrentChainData); + await SwitchNetwork(new ThirdwebChain() { chainId = CurrentChainData.chainId }); + } + catch (System.Exception f) + { + Debug.LogWarning("Adding chain error: " + f.Message); + } + } + } + + return await GetAddress(); + } + + public void Disconnect() + { + switch (WalletProvider) + { + case WalletProvider.WalletConnectV1: + WalletConnect.Instance.DisableWalletConnect(); + break; + case WalletProvider.MagicLink: + MagicUnity.Instance.DisableMagicAuth(); + break; + case WalletProvider.Metamask: + MetaMaskUnity.Instance.Disconnect(); + break; + default: + break; + } + + ThirdwebManager.Instance.SDK.session = new ThirdwebSession(Options, ChainId, RPC); + } + + public async Task GetAddress() + { + string address = null; + switch (WalletProvider) + { + case WalletProvider.LocalWallet: + if (LocalAccount == null) + throw new UnityException("No Account Connected!"); + address = LocalAccount.Address; + break; + case WalletProvider.WalletConnectV1: + address = WalletConnect.Instance.Session.Accounts[0]; + break; + case WalletProvider.MagicLink: + address = await MagicUnity.Instance.GetAddress(); + break; + case WalletProvider.Metamask: + address = MetaMaskUnity.Instance.Wallet.SelectedAddress; + break; + default: + throw new UnityException("No Account Connected!"); + } + return Nethereum.Util.AddressUtil.Current.ConvertToChecksumAddress(address); + } + + public async Task Request(string method, params object[] parameters) + { + var request = new RpcRequest(Nonce, method, parameters); + Nonce++; + return await Web3.Client.SendRequestAsync(request); + } + + #endregion + + #region Private Methods + + private async Task SwitchNetwork(ThirdwebChain newChain) + { + await Request("wallet_switchEthereumChain", new object[] { newChain }); + CurrentChainData.chainId = newChain.chainId; + } + + private async Task AddNetwork(ThirdwebChainData newChainData) + { + await Request("wallet_addEthereumChain", new object[] { newChainData }); + CurrentChainData = newChainData; + } + + private void InitializeLocalWallet(string password) + { + LocalAccount = Utils.UnlockOrGenerateLocalAccount(ChainId, password); + Web3 = new Web3(LocalAccount, RPC); + PersonalAccount = null; + } + + private async Task InitializeWalletConnect() + { + if (WalletConnect.Instance == null) + { + GameObject.Instantiate(ThirdwebManager.Instance.WalletConnectPrefab); + await new WaitForSeconds(0.5f); + WalletConnect.Instance.Initialize(); + } + + await WalletConnect.Instance.EnableWalletConnect(); + Web3 = new Web3(new WalletConnectClient(WalletConnect.Instance.Session)); + LocalAccount = null; + PersonalAccount = null; + } + + private async Task InitializeMagicLink() + { + if (MagicUnity.Instance == null) + { + GameObject.Instantiate(ThirdwebManager.Instance.MagicAuthPrefab); + await new WaitForSeconds(0.5f); + if (Options.wallet?.magicLinkApiKey == null) + throw new UnityException("MagicLink API Key is not set!"); + MagicUnity.Instance.Initialize(Options.wallet?.magicLinkApiKey, new link.magic.unity.sdk.Relayer.CustomNodeConfiguration(RPC, ChainId)); + } + + await MagicUnity.Instance.EnableMagicAuth(Email); + Web3 = new Web3(Magic.Instance.Provider); + LocalAccount = null; + PersonalAccount = null; + } + + private async Task InitializeMetaMask() + { + if (MetaMaskUnity.Instance == null) + { + GameObject.Instantiate(ThirdwebManager.Instance.MetamaskPrefab); + await new WaitForSeconds(0.5f); + MetaMaskUnity.Instance.Initialize(); + } + + MetaMaskUnity.Instance.Connect(); + bool connected = false; + MetaMaskUnity.Instance.Wallet.WalletAuthorized += (sender, e) => + { + Web3 = MetaMaskUnity.Instance.Wallet.CreateWeb3(); + LocalAccount = null; + PersonalAccount = null; + connected = true; + }; + await new WaitUntil(() => connected); + } + + private ThirdwebChainData FetchChainData() + { + var allChainsJson = (TextAsset)Resources.Load("all_chains", typeof(TextAsset)); + + List allNetworkData = Newtonsoft.Json.JsonConvert.DeserializeObject>(allChainsJson.text); + + ChainIDNetworkData currentNetwork = allNetworkData.Find(x => x.chainId == ChainId.ToString()); + + List explorerUrls = new List(); + foreach (var explorer in currentNetwork.explorers) + explorerUrls.Add(explorer.url); + if (explorerUrls.Count == 0) + explorerUrls.Add("https://etherscan.io"); + + return new ThirdwebChainData() + { + chainId = BigInteger.Parse(currentNetwork.chainId).ToHex(false, true) ?? BigInteger.Parse(ChainId.ToString()).ToHex(false, true), + blockExplorerUrls = explorerUrls.ToArray(), + chainName = currentNetwork.name ?? ThirdwebManager.Instance.GetCurrentChainIdentifier(), + iconUrls = new string[] { "ipfs://QmdwQDr6vmBtXmK2TmknkEuZNoaDqTasFdZdu3DRw8b2wt" }, + nativeCurrency = new NativeCurrency() + { + name = currentNetwork.nativeCurrency?.name ?? "Ether", + symbol = currentNetwork.nativeCurrency?.symbol ?? "ETH", + decimals = int.Parse(currentNetwork.nativeCurrency?.decimals ?? "18") + }, + rpcUrls = new string[] { RPC } + }; + } + + #endregion + + #region Nested Classes + + public class ThirdwebChainData : ThirdwebChain + { + public string[] blockExplorerUrls; + public string chainName; + public string[] iconUrls; + public NativeCurrency nativeCurrency; + public string[] rpcUrls; + } + + public class ThirdwebChain + { + public string chainId; + } + + [System.Serializable] + public class ChainIDNetworkData + { + public string name; + public string chain; + public string icon; + public List rpc; + public ChainIDNetworkNativeCurrency nativeCurrency; + public string chainId; + public List explorers; + } + + [System.Serializable] + public class ChainIDNetworkNativeCurrency + { + public string name; + public string symbol; + public string decimals; + } + + [System.Serializable] + public class ChainIDNetworkExplorer + { + public string name; + public string url; + public string standard; + } + + public struct ChaiNIDNetworkIcon + { + public string url; + public int width; + public int height; + public string format; + } + + #endregion + } +} diff --git a/Assets/Thirdweb/Core/Scripts/ThirdwebSession.cs.meta b/Assets/Thirdweb/Core/Scripts/ThirdwebSession.cs.meta new file mode 100644 index 00000000..e7749762 --- /dev/null +++ b/Assets/Thirdweb/Core/Scripts/ThirdwebSession.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 15aaced52c60c234f91d10bd86beceb0 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Thirdweb/Core/Scripts/TransactionManager.cs b/Assets/Thirdweb/Core/Scripts/TransactionManager.cs index 7c2211a0..a18dd34b 100644 --- a/Assets/Thirdweb/Core/Scripts/TransactionManager.cs +++ b/Assets/Thirdweb/Core/Scripts/TransactionManager.cs @@ -7,6 +7,9 @@ using UnityEngine.Networking; using Newtonsoft.Json; using Thirdweb.Contracts.Forwarder.ContractDefinition; +using Nethereum.RPC.Eth.Transactions; +using Nethereum.Hex.HexTypes; +using Nethereum.Web3; namespace Thirdweb { @@ -29,7 +32,7 @@ public static async Task ThirdwebRead(string con warned = true; } } - var queryHandler = ThirdwebManager.Instance.SDK.nativeSession.web3.Eth.GetContractQueryHandler(); + var queryHandler = ThirdwebManager.Instance.SDK.session.Web3.Eth.GetContractQueryHandler(); return await queryHandler.QueryAsync(contractAddress, functionMessage); } @@ -43,18 +46,39 @@ public static async Task ThirdwebWrite(string con public static async Task ThirdwebWriteRawResult(string contractAddress, TWFunction functionMessage, BigInteger? weiValue = null) where TWFunction : FunctionMessage, new() { - functionMessage.AmountToSend = weiValue ?? 0; + string txHash = null; + functionMessage.FromAddress = await ThirdwebManager.Instance.SDK.wallet.GetAddress(); - var gasEstimator = new Nethereum.Web3.Web3(ThirdwebManager.Instance.SDK.nativeSession.lastRPC).Eth.GetContractTransactionHandler(); + functionMessage.AmountToSend = weiValue ?? 0; + + var gasEstimator = new Web3(ThirdwebManager.Instance.SDK.session.RPC).Eth.GetContractTransactionHandler(); var gas = await gasEstimator.EstimateGasAsync(contractAddress, functionMessage); + functionMessage.Gas = gas.Value < 100000 ? 100000 : gas.Value; - if (ThirdwebManager.Instance.SDK.nativeSession.options.gasless != null && ThirdwebManager.Instance.SDK.nativeSession.options.gasless.Value.openzeppelin != null) + bool isGasless = ThirdwebManager.Instance.SDK.session.Options.gasless.HasValue && ThirdwebManager.Instance.SDK.session.Options.gasless.Value.openzeppelin.HasValue; + + if (!isGasless) { - string relayerUrl = ThirdwebManager.Instance.SDK.nativeSession.options.gasless.Value.openzeppelin?.relayerUrl; - string forwarderAddress = ThirdwebManager.Instance.SDK.nativeSession.options.gasless.Value.openzeppelin?.relayerForwarderAddress; - string forwarderDomain = ThirdwebManager.Instance.SDK.nativeSession.options.gasless.Value.openzeppelin?.domainName; - string forwarderVersion = ThirdwebManager.Instance.SDK.nativeSession.options.gasless.Value.openzeppelin?.domainVersion; + if (ThirdwebManager.Instance.SDK.session.WalletProvider == WalletProvider.LocalWallet) + { + var transactionHandler = ThirdwebManager.Instance.SDK.session.Web3.Eth.GetContractTransactionHandler(); + // txHash = await transactionHandler.SendRequestAsync(contractAddress, functionMessage); + return await transactionHandler.SendRequestAndWaitForReceiptAsync(contractAddress, functionMessage); + } + else + { + var transaction = new EthSendTransaction(ThirdwebManager.Instance.SDK.session.Web3.Client); + var transactionInput = functionMessage.CreateTransactionInput(contractAddress); + txHash = await transaction.SendRequestAsync(transactionInput); + } + } + else + { + string relayerUrl = ThirdwebManager.Instance.SDK.session.Options.gasless.Value.openzeppelin?.relayerUrl; + string forwarderAddress = ThirdwebManager.Instance.SDK.session.Options.gasless.Value.openzeppelin?.relayerForwarderAddress; + string forwarderDomain = ThirdwebManager.Instance.SDK.session.Options.gasless.Value.openzeppelin?.domainName; + string forwarderVersion = ThirdwebManager.Instance.SDK.session.Options.gasless.Value.openzeppelin?.domainVersion; functionMessage.Nonce = ( await ThirdwebRead( @@ -73,12 +97,10 @@ public static async Task ThirdwebWriteRawResult( Data = functionMessage.GetCallData().ByteArrayToHexString() }; - var signature = await EIP712.GenerateSignature_MinimalForwarder(forwarderDomain, forwarderVersion, ThirdwebManager.Instance.SDK.nativeSession.lastChainId, forwarderAddress, request); + var signature = await EIP712.GenerateSignature_MinimalForwarder(forwarderDomain, forwarderVersion, ThirdwebManager.Instance.SDK.session.ChainId, forwarderAddress, request); var postData = new RelayerRequest(request, signature, forwarderAddress); - string txHash = null; - using (UnityWebRequest req = UnityWebRequest.Post(relayerUrl, "")) { byte[] bodyRaw = System.Text.Encoding.UTF8.GetBytes(JsonConvert.SerializeObject(postData)); @@ -100,13 +122,10 @@ public static async Task ThirdwebWriteRawResult( Debug.Log(txHash); } } - return await ThirdwebManager.Instance.SDK.nativeSession.web3.TransactionReceiptPolling.PollForReceiptAsync(txHash); - } - else - { - var transactionHandler = ThirdwebManager.Instance.SDK.nativeSession.web3.Eth.GetContractTransactionHandler(); - return await transactionHandler.SendRequestAndWaitForReceiptAsync(contractAddress, functionMessage); } + Debug.Log("txHash: " + txHash); + var receiptPoller = new Web3(ThirdwebManager.Instance.SDK.session.RPC); + return await receiptPoller.TransactionReceiptPolling.PollForReceiptAsync(txHash); } [System.Serializable] diff --git a/Assets/Thirdweb/Core/Scripts/Types.cs b/Assets/Thirdweb/Core/Scripts/Types.cs index 6e81944a..89a6de0e 100644 --- a/Assets/Thirdweb/Core/Scripts/Types.cs +++ b/Assets/Thirdweb/Core/Scripts/Types.cs @@ -388,6 +388,16 @@ public struct TransactionRequest public string gasLimit; public string gasPrice; + public TransactionRequest(string from, string to, string data, string value, string gasLimit, string gasPrice) + { + this.from = from; + this.to = to; + this.data = data; + this.value = value; + this.gasLimit = gasLimit; + this.gasPrice = gasPrice; + } + public override string ToString() { return $"TransactionRequest:" + $"\n>from: {from}" + $"\n>to: {to}" + $"\n>data: {data}" + $"\n>value: {value}" + $"\n>gasLimit: {gasLimit}" + $"\n>gasPrice: {gasPrice}"; diff --git a/Assets/Thirdweb/Core/Scripts/Utils.cs b/Assets/Thirdweb/Core/Scripts/Utils.cs index c037b69c..20b011d0 100644 --- a/Assets/Thirdweb/Core/Scripts/Utils.cs +++ b/Assets/Thirdweb/Core/Scripts/Utils.cs @@ -8,7 +8,6 @@ using Nethereum.Web3.Accounts; using System.IO; using UnityEngine; -using WalletConnectSharp.Unity; namespace Thirdweb { @@ -246,8 +245,8 @@ public static BigInteger GetMaxUint256() public async static Task GetCurrentBlockTimeStamp() { - var blockNumber = await ThirdwebManager.Instance.SDK.nativeSession.web3.Eth.Blocks.GetBlockNumber.SendRequestAsync(); - var block = await ThirdwebManager.Instance.SDK.nativeSession.web3.Eth.Blocks.GetBlockWithTransactionsByNumber.SendRequestAsync(new Nethereum.Hex.HexTypes.HexBigInteger(blockNumber)); + var blockNumber = await ThirdwebManager.Instance.SDK.session.Web3.Eth.Blocks.GetBlockNumber.SendRequestAsync(); + var block = await ThirdwebManager.Instance.SDK.session.Web3.Eth.Blocks.GetBlockWithTransactionsByNumber.SendRequestAsync(new Nethereum.Hex.HexTypes.HexBigInteger(blockNumber)); return block.Timestamp.Value; } @@ -315,7 +314,12 @@ public static Account UnlockOrGenerateLocalAccount(int chainId, string password R = 1, P = 8 }; - var ecKey = Nethereum.Signer.EthECKey.GenerateKey(); + byte[] seed = new byte[32]; + using (var rng = new System.Security.Cryptography.RNGCryptoServiceProvider()) + { + rng.GetBytes(seed); + } + var ecKey = Nethereum.Signer.EthECKey.GenerateKey(seed); var keyStore = keyStoreService.EncryptAndGenerateKeyStore(password, ecKey.GetPrivateKeyAsBytes(), ecKey.GetPublicAddress(), scryptParams); var json = keyStoreService.SerializeKeyStoreToJson(keyStore); File.WriteAllText(path, json); @@ -324,6 +328,17 @@ public static Account UnlockOrGenerateLocalAccount(int chainId, string password } } + public static Account GenerateRandomAccount(int chainId) + { + byte[] seed = new byte[32]; + using (var rng = new System.Security.Cryptography.RNGCryptoServiceProvider()) + { + rng.GetBytes(seed); + } + var ecKey = Nethereum.Signer.EthECKey.GenerateKey(seed); + return new Account(ecKey, chainId); + } + public static string cidToIpfsUrl(this string cid, bool useGateway = false) { string ipfsRaw = $"ipfs://{cid}"; diff --git a/Assets/Thirdweb/Core/Scripts/Wallet.cs b/Assets/Thirdweb/Core/Scripts/Wallet.cs index f48beedd..1ac814e0 100644 --- a/Assets/Thirdweb/Core/Scripts/Wallet.cs +++ b/Assets/Thirdweb/Core/Scripts/Wallet.cs @@ -1,24 +1,17 @@ using System.Numerics; using System.Threading.Tasks; using Nethereum.Signer; -using Nethereum.Web3; using UnityEngine; using System; -using WalletConnectSharp.Unity; -using WalletConnectSharp.NEthereum; using Nethereum.Siwe.Core; using System.Collections.Generic; -using Nethereum.Web3.Accounts; -using WalletConnectSharp.Core.Models.Ethereum; -using link.magic.unity.sdk; -using Nethereum.RPC; -using MetaMask.Unity; -using MetaMask.NEthereum; using Nethereum.Hex.HexConvertors.Extensions; -using Nethereum.Hex.HexTypes; using Nethereum.ABI.EIP712; using Nethereum.Signer.EIP712; -using Newtonsoft.Json; +using Newtonsoft.Json.Linq; +using Nethereum.RPC.Eth.Transactions; +using Nethereum.RPC.Eth.DTOs; +using Nethereum.Hex.HexTypes; //using WalletConnectSharp.NEthereum; @@ -44,139 +37,7 @@ public async Task Connect(WalletConnection walletConnection) } else { - ThirdwebSDK.NativeSession oldSession = ThirdwebManager.Instance.SDK.nativeSession; - - switch (walletConnection.provider) - { - case WalletProvider.LocalWallet: - Account acc = Utils.UnlockOrGenerateLocalAccount(oldSession.lastChainId, walletConnection.password); - ThirdwebManager.Instance.SDK.nativeSession = new ThirdwebSDK.NativeSession( - walletConnection.provider, - oldSession.lastChainId, - oldSession.lastRPC, - acc, - new Web3(acc, oldSession.lastRPC), - oldSession.options, - oldSession.siweSession - ); - break; - case WalletProvider.WalletConnectV1: - if (WalletConnect.Instance == null) - { - GameObject.Instantiate(ThirdwebManager.Instance.WalletConnectPrefab); - await new WaitForSeconds(0.5f); - } - - WalletConnect.Instance.Initialize(); - - await WalletConnect.Instance.EnableWalletConnect(); - - ThirdwebManager.Instance.SDK.nativeSession = new ThirdwebSDK.NativeSession( - walletConnection.provider, - oldSession.lastChainId, - oldSession.lastRPC, - null, - WalletConnect.Instance.Session.BuildWeb3(new Uri(oldSession.lastRPC)).AsWalletAccount(true), - oldSession.options, - oldSession.siweSession - ); - - try - { - await WalletConnect.Instance.WalletSwitchEthChain(new EthChain() { chainId = ThirdwebManager.Instance.SDK.currentChainData.chainId }); - } - catch (System.Exception e) - { - Debug.LogWarning("Switching chain error, attempting to add chain: " + e.Message); - try - { - await WalletConnect.Instance.WalletAddEthChain(ThirdwebManager.Instance.SDK.currentChainData); - await WalletConnect.Instance.WalletSwitchEthChain(new EthChain() { chainId = ThirdwebManager.Instance.SDK.currentChainData.chainId }); - } - catch (System.Exception f) - { - Debug.LogWarning("Adding chain error: " + f.Message); - } - } - break; - case WalletProvider.MagicLink: - if (MagicUnity.Instance == null) - { - GameObject.Instantiate(ThirdwebManager.Instance.MagicAuthPrefab); - await new WaitForSeconds(0.5f); - } - - if (ThirdwebManager.Instance.SDK.nativeSession.options.wallet?.magicLinkApiKey == null) - throw new UnityException("MagicLink API Key is not set!"); - - MagicUnity.Instance.Initialize( - ThirdwebManager.Instance.SDK.nativeSession.options.wallet?.magicLinkApiKey, - new link.magic.unity.sdk.Relayer.CustomNodeConfiguration(oldSession.lastRPC, oldSession.lastChainId) - ); - - await MagicUnity.Instance.EnableMagicAuth(walletConnection.email); - - ThirdwebManager.Instance.SDK.nativeSession = new ThirdwebSDK.NativeSession( - walletConnection.provider, - oldSession.lastChainId, - oldSession.lastRPC, - null, - new Web3(Magic.Instance.Provider), - oldSession.options, - oldSession.siweSession - ); - break; - case WalletProvider.MetaMask: - if (MetaMaskUnity.Instance == null) - { - GameObject.Instantiate(ThirdwebManager.Instance.MetamaskPrefab); - MetaMaskUnity.Instance.Initialize(); - await new WaitForSeconds(1f); - } - - MetaMaskUnity.Instance.Connect(); - - bool connected = false; - MetaMaskUnity.Instance.Wallet.WalletAuthorized += (sender, e) => - { - ThirdwebManager.Instance.SDK.nativeSession = new ThirdwebSDK.NativeSession( - walletConnection.provider, - oldSession.lastChainId, - oldSession.lastRPC, - null, - MetaMaskUnity.Instance.Wallet.CreateWeb3(), - oldSession.options, - oldSession.siweSession - ); - connected = true; - }; - - await new WaitUntil(() => connected); - - try - { - await MetaMaskUnity.Instance.WalletSwitchEthChain(new EthChain() { chainId = ThirdwebManager.Instance.SDK.currentChainData.chainId }); - } - catch (System.Exception e) - { - Debug.LogWarning("Switching chain error, attempting to add chain: " + e.Message); - try - { - await MetaMaskUnity.Instance.WalletAddEthChain(ThirdwebManager.Instance.SDK.currentChainData); - await MetaMaskUnity.Instance.WalletSwitchEthChain(new EthChain() { chainId = ThirdwebManager.Instance.SDK.currentChainData.chainId }); - } - catch (System.Exception f) - { - Debug.LogWarning("Adding chain error: " + f.Message); - } - } - - break; - default: - throw new UnityException("This wallet connection method is not supported on this platform!"); - } - - return await GetAddress(); + return await ThirdwebManager.Instance.SDK.session.Connect(walletConnection.provider, walletConnection.password, walletConnection.email); } } @@ -191,32 +52,7 @@ public async Task Disconnect() } else { - ThirdwebSDK.NativeSession oldSession = ThirdwebManager.Instance.SDK.nativeSession; - - switch (oldSession.provider) - { - case WalletProvider.WalletConnectV1: - WalletConnect.Instance.DisableWalletConnect(); - break; - case WalletProvider.MagicLink: - MagicUnity.Instance.DisableMagicAuth(); - break; - case WalletProvider.MetaMask: - MetaMaskUnity.Instance.Wallet.Disconnect(); - break; - default: - break; - } - - ThirdwebManager.Instance.SDK.nativeSession = new ThirdwebSDK.NativeSession( - WalletProvider.LocalWallet, - oldSession.lastChainId, - oldSession.lastRPC, - null, - new Web3(oldSession.lastRPC), - oldSession.options, - oldSession.siweSession - ); + ThirdwebManager.Instance.SDK.session.Disconnect(); } } @@ -232,7 +68,7 @@ public async Task Authenticate(string domain) } else { - var siwe = ThirdwebManager.Instance.SDK.nativeSession.siweSession; + var siwe = ThirdwebManager.Instance.SDK.session.SiweSession; var siweMsg = new SiweMessage() { Resources = new List(), @@ -285,7 +121,7 @@ public async Task Verify(LoginPayload payload) } else { - var siwe = ThirdwebManager.Instance.SDK.nativeSession.siweSession; + var siwe = ThirdwebManager.Instance.SDK.session.SiweSession; var siweMessage = new SiweMessage() { Domain = payload.payload.domain, @@ -357,8 +193,8 @@ public async Task GetBalance(string currencyAddress = Utils.Nativ } else { - var balance = await ThirdwebManager.Instance.SDK.nativeSession.web3.Eth.GetBalance.SendRequestAsync(await ThirdwebManager.Instance.SDK.wallet.GetAddress()); - var nativeCurrency = ThirdwebManager.Instance.SDK.currentChainData.nativeCurrency; + var balance = await ThirdwebManager.Instance.SDK.session.Web3.Eth.GetBalance.SendRequestAsync(await GetAddress()); + var nativeCurrency = ThirdwebManager.Instance.SDK.session.CurrentChainData.nativeCurrency; return new CurrencyValue(nativeCurrency.name, nativeCurrency.symbol, nativeCurrency.decimals.ToString(), balance.Value.ToString(), balance.Value.ToString().ToEth()); } } @@ -375,27 +211,7 @@ public async Task GetAddress() } else { - string address = null; - - switch (ThirdwebManager.Instance.SDK.nativeSession.provider) - { - case WalletProvider.LocalWallet: - address = ThirdwebManager.Instance.SDK.nativeSession.account.Address; - break; - case WalletProvider.WalletConnectV1: - address = WalletConnect.Instance.Session.Accounts[0]; - break; - case WalletProvider.MagicLink: - address = await MagicUnity.Instance.GetAddress(); - break; - case WalletProvider.MetaMask: - address = MetaMaskUnity.Instance.Wallet.SelectedAddress; - break; - default: - throw new UnityException("No Account Connected!"); - } - - return Nethereum.Util.AddressUtil.Current.ConvertToChecksumAddress(address); + return await ThirdwebManager.Instance.SDK.session.Request("eth_accounts"); } } @@ -410,7 +226,7 @@ public async Task IsConnected() } else { - return ThirdwebManager.Instance.SDK.nativeSession.account != null || ThirdwebManager.Instance.SDK.nativeSession.provider != WalletProvider.LocalWallet; + return ThirdwebManager.Instance.SDK.session.IsConnected; } } @@ -425,9 +241,8 @@ public async Task GetChainId() } else { - int chainId = (int)(await ThirdwebManager.Instance.SDK.nativeSession.web3.Eth.ChainId.SendRequestAsync()).Value; - ThirdwebManager.Instance.SDK.nativeSession.lastChainId = chainId; - return chainId; + var hexChainId = await ThirdwebManager.Instance.SDK.session.Request("eth_chainId"); + return (int)hexChainId.HexToBigInteger(false); } } @@ -464,7 +279,7 @@ public async Task Transfer(string to, string amount, string c } else { - var receipt = await ThirdwebManager.Instance.SDK.nativeSession.web3.Eth.GetEtherTransferService().TransferEtherAndWaitForReceiptAsync(to, decimal.Parse(amount)); + var receipt = await ThirdwebManager.Instance.SDK.session.Web3.Eth.GetEtherTransferService().TransferEtherAndWaitForReceiptAsync(to, decimal.Parse(amount)); return receipt.ToTransactionResult(); } } @@ -481,19 +296,22 @@ public async Task Sign(string message) } else { - switch (ThirdwebManager.Instance.SDK.nativeSession.provider) + if (ThirdwebManager.Instance.SDK.session.WalletProvider == WalletProvider.LocalWallet) + { + var signer = new EthereumMessageSigner(); + return signer.EncodeUTF8AndSign(message, new EthECKey(ThirdwebManager.Instance.SDK.session.LocalAccount.PrivateKey)); + } + else { - case WalletProvider.LocalWallet: - var signer = new EthereumMessageSigner(); - return signer.EncodeUTF8AndSign(message, new EthECKey(ThirdwebManager.Instance.SDK.nativeSession.account.PrivateKey)); - case WalletProvider.WalletConnectV1: - return await WalletConnect.Instance.PersonalSign(message); - case WalletProvider.MagicLink: - return await MagicUnity.Instance.PersonalSign(message); - case WalletProvider.MetaMask: - return await MetaMaskUnity.Instance.PersonalSign(message); - default: - throw new UnityException("Invalid Wallet Provider!"); + try + { + return await ThirdwebManager.Instance.SDK.session.Request("personal_sign", await GetAddress(), message); + } + catch (System.Exception e) + { + Debug.LogWarning(e.Message); + return await ThirdwebManager.Instance.SDK.session.Request("eth_sign", await GetAddress(), message); + } } } } @@ -501,20 +319,32 @@ public async Task Sign(string message) public async Task SignTypedDataV4(T data, TypedData typedData) where TDomain : IDomain { - switch (ThirdwebManager.Instance.SDK.nativeSession.provider) + if (ThirdwebManager.Instance.SDK.session.WalletProvider == WalletProvider.LocalWallet) { - case WalletProvider.LocalWallet: - var signer = new Eip712TypedDataSigner(); - var key = new EthECKey(ThirdwebManager.Instance.SDK.nativeSession.account.PrivateKey); - return signer.SignTypedDataV4(data, typedData, key); - case WalletProvider.WalletConnectV1: - return await WalletConnect.Instance.SignTypedDataV4(data, typedData); - case WalletProvider.MagicLink: - return await MagicUnity.Instance.SignTypedDataV4(data, typedData); - case WalletProvider.MetaMask: - return await MetaMaskUnity.Instance.SignTypedDataV4(data, typedData); - default: - throw new UnityException("Invalid Wallet Provider!"); + var signer = new Eip712TypedDataSigner(); + var key = new EthECKey(ThirdwebManager.Instance.SDK.session.LocalAccount.PrivateKey); + return signer.SignTypedDataV4(data, typedData, key); + } + else + { + var json = typedData.ToJson(data); + var jsonObject = JObject.Parse(json); + + var uidToken = jsonObject.SelectToken("$.message.uid"); + if (uidToken != null) + { + var uidBase64 = uidToken.Value(); + var uidBytes = Convert.FromBase64String(uidBase64); + var uidHex = uidBytes.ByteArrayToHexString(); + uidToken.Replace(uidHex); + } + + var messageObject = jsonObject.GetValue("message") as JObject; + foreach (var property in messageObject.Properties()) + property.Value = property.Value.ToString(); + + string safeJson = jsonObject.ToString(); + return await ThirdwebManager.Instance.SDK.session.Request("eth_signTypedData_v4", await GetAddress(), safeJson); } } @@ -546,14 +376,15 @@ public async Task SendRawTransaction(TransactionRequest trans } else { - Nethereum.RPC.Eth.DTOs.TransactionInput input = new Nethereum.RPC.Eth.DTOs.TransactionInput( + var input = new Nethereum.RPC.Eth.DTOs.TransactionInput( transactionRequest.data, transactionRequest.to, - transactionRequest.value, + transactionRequest.from, new Nethereum.Hex.HexTypes.HexBigInteger(BigInteger.Parse(transactionRequest.gasLimit)), - new Nethereum.Hex.HexTypes.HexBigInteger(BigInteger.Parse(transactionRequest.gasPrice)) + new Nethereum.Hex.HexTypes.HexBigInteger(BigInteger.Parse(transactionRequest.gasPrice)), + new Nethereum.Hex.HexTypes.HexBigInteger(transactionRequest.value) ); - var receipt = await ThirdwebManager.Instance.SDK.nativeSession.web3.TransactionManager.SendTransactionAndWaitForReceiptAsync(input); + var receipt = await ThirdwebManager.Instance.SDK.session.Web3.Eth.TransactionManager.SendTransactionAndWaitForReceiptAsync(input); return receipt.ToTransactionResult(); } } @@ -597,8 +428,8 @@ public WalletConnection(WalletProvider provider = WalletProvider.LocalWallet, in public enum WalletProvider { - MetaMask, - CoinbaseWallet, + Metamask, + Coinbase, WalletConnectV1, Injected, MagicLink, diff --git a/Assets/Thirdweb/Examples/Scenes/Scene_Prefabs.unity b/Assets/Thirdweb/Examples/Scenes/Scene_Prefabs.unity index 925fc248..bbb8863a 100644 --- a/Assets/Thirdweb/Examples/Scenes/Scene_Prefabs.unity +++ b/Assets/Thirdweb/Examples/Scenes/Scene_Prefabs.unity @@ -1268,63 +1268,67 @@ PrefabInstance: m_Modifications: - target: {fileID: 351517270, guid: a6218c0a90161f349bc6bc87fbc624da, type: 3} propertyPath: m_AnchorMax.y - value: 0 + value: 1 objectReference: {fileID: 0} - target: {fileID: 351517270, guid: a6218c0a90161f349bc6bc87fbc624da, type: 3} propertyPath: m_AnchorMin.y - value: 0 + value: 1 objectReference: {fileID: 0} - target: {fileID: 351517270, guid: a6218c0a90161f349bc6bc87fbc624da, type: 3} propertyPath: m_SizeDelta.x - value: 0 + value: 290 objectReference: {fileID: 0} - target: {fileID: 351517270, guid: a6218c0a90161f349bc6bc87fbc624da, type: 3} propertyPath: m_AnchoredPosition.x - value: 0 + value: 150 objectReference: {fileID: 0} - target: {fileID: 351517270, guid: a6218c0a90161f349bc6bc87fbc624da, type: 3} propertyPath: m_AnchoredPosition.y + value: -230 + objectReference: {fileID: 0} + - target: {fileID: 472489313, guid: a6218c0a90161f349bc6bc87fbc624da, type: 3} + propertyPath: m_IsActive value: 0 objectReference: {fileID: 0} - target: {fileID: 679192014, guid: a6218c0a90161f349bc6bc87fbc624da, type: 3} propertyPath: m_AnchorMax.y - value: 0 + value: 1 objectReference: {fileID: 0} - target: {fileID: 679192014, guid: a6218c0a90161f349bc6bc87fbc624da, type: 3} propertyPath: m_AnchorMin.y - value: 0 + value: 1 objectReference: {fileID: 0} - target: {fileID: 679192014, guid: a6218c0a90161f349bc6bc87fbc624da, type: 3} propertyPath: m_SizeDelta.x - value: 0 + value: 290 objectReference: {fileID: 0} - target: {fileID: 679192014, guid: a6218c0a90161f349bc6bc87fbc624da, type: 3} propertyPath: m_AnchoredPosition.x - value: 0 + value: 150 objectReference: {fileID: 0} - target: {fileID: 679192014, guid: a6218c0a90161f349bc6bc87fbc624da, type: 3} propertyPath: m_AnchoredPosition.y - value: 0 + value: -295 objectReference: {fileID: 0} - target: {fileID: 1045367076, guid: a6218c0a90161f349bc6bc87fbc624da, type: 3} propertyPath: m_AnchorMax.y - value: 0 + value: 1 objectReference: {fileID: 0} - target: {fileID: 1045367076, guid: a6218c0a90161f349bc6bc87fbc624da, type: 3} propertyPath: m_AnchorMin.y - value: 0 + value: 1 objectReference: {fileID: 0} - target: {fileID: 1045367076, guid: a6218c0a90161f349bc6bc87fbc624da, type: 3} propertyPath: m_SizeDelta.x - value: 0 + value: 290 objectReference: {fileID: 0} - target: {fileID: 1045367076, guid: a6218c0a90161f349bc6bc87fbc624da, type: 3} propertyPath: m_AnchoredPosition.x - value: 0 + value: 150 objectReference: {fileID: 0} - target: {fileID: 1045367076, guid: a6218c0a90161f349bc6bc87fbc624da, type: 3} propertyPath: m_AnchoredPosition.y - value: 0 + value: -165 objectReference: {fileID: 0} - target: {fileID: 696252699284340127, guid: a6218c0a90161f349bc6bc87fbc624da, type: 3} propertyPath: m_Name @@ -1332,47 +1336,51 @@ PrefabInstance: objectReference: {fileID: 0} - target: {fileID: 1335404546759128317, guid: a6218c0a90161f349bc6bc87fbc624da, type: 3} propertyPath: m_AnchorMax.y - value: 0 + value: 1 objectReference: {fileID: 0} - target: {fileID: 1335404546759128317, guid: a6218c0a90161f349bc6bc87fbc624da, type: 3} propertyPath: m_AnchorMin.y - value: 0 + value: 1 objectReference: {fileID: 0} - target: {fileID: 1335404546759128317, guid: a6218c0a90161f349bc6bc87fbc624da, type: 3} propertyPath: m_SizeDelta.x - value: 0 + value: 290 objectReference: {fileID: 0} - target: {fileID: 1335404546759128317, guid: a6218c0a90161f349bc6bc87fbc624da, type: 3} propertyPath: m_AnchoredPosition.x - value: 0 + value: 150 objectReference: {fileID: 0} - target: {fileID: 1335404546759128317, guid: a6218c0a90161f349bc6bc87fbc624da, type: 3} propertyPath: m_AnchoredPosition.y + value: -35 + objectReference: {fileID: 0} + - target: {fileID: 1335404547797609896, guid: a6218c0a90161f349bc6bc87fbc624da, type: 3} + propertyPath: m_IsActive value: 0 objectReference: {fileID: 0} - target: {fileID: 1335404547797609897, guid: a6218c0a90161f349bc6bc87fbc624da, type: 3} propertyPath: m_SizeDelta.y - value: 0 + value: 460 objectReference: {fileID: 0} - target: {fileID: 2894011472420110484, guid: a6218c0a90161f349bc6bc87fbc624da, type: 3} propertyPath: m_AnchorMax.y - value: 0 + value: 1 objectReference: {fileID: 0} - target: {fileID: 2894011472420110484, guid: a6218c0a90161f349bc6bc87fbc624da, type: 3} propertyPath: m_AnchorMin.y - value: 0 + value: 1 objectReference: {fileID: 0} - target: {fileID: 2894011472420110484, guid: a6218c0a90161f349bc6bc87fbc624da, type: 3} propertyPath: m_SizeDelta.x - value: 0 + value: 290 objectReference: {fileID: 0} - target: {fileID: 2894011472420110484, guid: a6218c0a90161f349bc6bc87fbc624da, type: 3} propertyPath: m_AnchoredPosition.x - value: 0 + value: 150 objectReference: {fileID: 0} - target: {fileID: 2894011472420110484, guid: a6218c0a90161f349bc6bc87fbc624da, type: 3} propertyPath: m_AnchoredPosition.y - value: 0 + value: -425 objectReference: {fileID: 0} - target: {fileID: 4988122251934112428, guid: a6218c0a90161f349bc6bc87fbc624da, type: 3} propertyPath: m_AnchorMax.y @@ -1396,23 +1404,23 @@ PrefabInstance: objectReference: {fileID: 0} - target: {fileID: 6243171688188928066, guid: a6218c0a90161f349bc6bc87fbc624da, type: 3} propertyPath: m_AnchorMax.y - value: 0 + value: 1 objectReference: {fileID: 0} - target: {fileID: 6243171688188928066, guid: a6218c0a90161f349bc6bc87fbc624da, type: 3} propertyPath: m_AnchorMin.y - value: 0 + value: 1 objectReference: {fileID: 0} - target: {fileID: 6243171688188928066, guid: a6218c0a90161f349bc6bc87fbc624da, type: 3} propertyPath: m_SizeDelta.x - value: 0 + value: 290 objectReference: {fileID: 0} - target: {fileID: 6243171688188928066, guid: a6218c0a90161f349bc6bc87fbc624da, type: 3} propertyPath: m_AnchoredPosition.x - value: 0 + value: 150 objectReference: {fileID: 0} - target: {fileID: 6243171688188928066, guid: a6218c0a90161f349bc6bc87fbc624da, type: 3} propertyPath: m_AnchoredPosition.y - value: 0 + value: -360 objectReference: {fileID: 0} - target: {fileID: 6539300962087038060, guid: a6218c0a90161f349bc6bc87fbc624da, type: 3} propertyPath: m_Pivot.x @@ -1500,23 +1508,23 @@ PrefabInstance: objectReference: {fileID: 0} - target: {fileID: 7558163674396937018, guid: a6218c0a90161f349bc6bc87fbc624da, type: 3} propertyPath: m_AnchorMax.y - value: 0 + value: 1 objectReference: {fileID: 0} - target: {fileID: 7558163674396937018, guid: a6218c0a90161f349bc6bc87fbc624da, type: 3} propertyPath: m_AnchorMin.y - value: 0 + value: 1 objectReference: {fileID: 0} - target: {fileID: 7558163674396937018, guid: a6218c0a90161f349bc6bc87fbc624da, type: 3} propertyPath: m_SizeDelta.x - value: 0 + value: 290 objectReference: {fileID: 0} - target: {fileID: 7558163674396937018, guid: a6218c0a90161f349bc6bc87fbc624da, type: 3} propertyPath: m_AnchoredPosition.x - value: 0 + value: 150 objectReference: {fileID: 0} - target: {fileID: 7558163674396937018, guid: a6218c0a90161f349bc6bc87fbc624da, type: 3} propertyPath: m_AnchoredPosition.y - value: 0 + value: -100 objectReference: {fileID: 0} m_RemovedComponents: [] m_SourcePrefab: {fileID: 100100000, guid: a6218c0a90161f349bc6bc87fbc624da, type: 3} diff --git a/Assets/Thirdweb/Examples/Scripts/Prefabs/Prefab_ConnectWallet.cs b/Assets/Thirdweb/Examples/Scripts/Prefabs/Prefab_ConnectWallet.cs index 90ffaa00..497c2c67 100644 --- a/Assets/Thirdweb/Examples/Scripts/Prefabs/Prefab_ConnectWallet.cs +++ b/Assets/Thirdweb/Examples/Scripts/Prefabs/Prefab_ConnectWallet.cs @@ -85,6 +85,10 @@ private void Start() { connectButton.GetComponent