diff --git a/Runtime/codebase/DeepLinkWallets/PhantomDeepLink.cs b/Runtime/codebase/DeepLinkWallets/PhantomDeepLink.cs index 339566bb..3132fe2f 100644 --- a/Runtime/codebase/DeepLinkWallets/PhantomDeepLink.cs +++ b/Runtime/codebase/DeepLinkWallets/PhantomDeepLink.cs @@ -280,8 +280,10 @@ private void ParseSuccessfullySignedAllTransactions(string url) result.TryGetValue("errorCode", out var errorCode); _signedAllTransactionsTaskCompletionSource?.TrySetResult(null); Debug.LogError($"Deeplink error: Error: {errorMessage} + Data: {data}"); + SolanaWalletAdapter.TriggerUserApprovedTransaction(false); return; } + else SolanaWalletAdapter.TriggerUserApprovedTransaction(true); data = data.Replace("#", ""); var k = MontgomeryCurve25519.KeyExchange(_phantomEncryptionPubKey, PhantomConnectionAccountPrivateKey); @@ -302,9 +304,11 @@ private void ParseSuccessfullySignedTransaction(string url) result.TryGetValue("errorMessage", out var errorMessage); if (!string.IsNullOrEmpty(errorMessage) || string.IsNullOrEmpty(data)) { + SolanaWalletAdapter.TriggerUserApprovedTransaction(false); Debug.LogError($"Deeplink error: Error: {errorMessage} + Data: {data}"); return; } + else SolanaWalletAdapter.TriggerUserApprovedTransaction(true); data = data.Replace("#", ""); var k = MontgomeryCurve25519.KeyExchange(_phantomEncryptionPubKey, PhantomConnectionAccountPrivateKey); var unencryptedMessage = XSalsa20Poly1305.TryDecrypt(Encoders.Base58.DecodeData(data), k, Encoders.Base58.DecodeData(nonce)); @@ -323,9 +327,11 @@ private void ParseSuccessfullySignedMessage(string url) result.TryGetValue("errorMessage", out var errorMessage); if (!string.IsNullOrEmpty(errorMessage) || string.IsNullOrEmpty(data)) { + SolanaWalletAdapter.TriggerUserApprovedTransaction(false); Debug.LogError($"Deeplink error: Error: {errorMessage} + Data: {data}"); return; } + else SolanaWalletAdapter.TriggerUserApprovedTransaction(true); data = data.Replace("#", ""); var k = MontgomeryCurve25519.KeyExchange(_phantomEncryptionPubKey, PhantomConnectionAccountPrivateKey); var unencryptedMessage = XSalsa20Poly1305.TryDecrypt(Encoders.Base58.DecodeData(data), k, Encoders.Base58.DecodeData(nonce)); diff --git a/Runtime/codebase/SolanaMobileStack/SolanaMobileWalletAdapter.cs b/Runtime/codebase/SolanaMobileStack/SolanaMobileWalletAdapter.cs index 71b65c8b..fcd3b1e9 100644 --- a/Runtime/codebase/SolanaMobileStack/SolanaMobileWalletAdapter.cs +++ b/Runtime/codebase/SolanaMobileStack/SolanaMobileWalletAdapter.cs @@ -11,7 +11,7 @@ namespace Solana.Unity.SDK { - + [Serializable] public class SolanaMobileWalletAdapterOptions { @@ -20,13 +20,13 @@ public class SolanaMobileWalletAdapterOptions public string name = "Solana.Unity-SDK"; public bool keepConnectionAlive = true; } - - + + [Obsolete("Use SolanaWalletAdapter class instead, which is the cross platform wrapper.")] public class SolanaMobileWalletAdapter : WalletBase { private readonly SolanaMobileWalletAdapterOptions _walletOptions; - + private Transaction _currentTransaction; private TaskCompletionSource _loginTaskCompletionSource; @@ -36,9 +36,9 @@ public class SolanaMobileWalletAdapter : WalletBase public SolanaMobileWalletAdapter( SolanaMobileWalletAdapterOptions solanaWalletOptions, - RpcCluster rpcCluster = RpcCluster.DevNet, - string customRpcUri = null, - string customStreamingRpcUri = null, + RpcCluster rpcCluster = RpcCluster.DevNet, + string customRpcUri = null, + string customStreamingRpcUri = null, bool autoConnectOnStartup = false) : base(rpcCluster, customRpcUri, customStreamingRpcUri, autoConnectOnStartup ) { @@ -116,7 +116,7 @@ protected override async Task _SignAllTransactions(Transaction[] authorization = await client.Reauthorize( new Uri(_walletOptions.identityUri), new Uri(_walletOptions.iconUri, UriKind.Relative), - _walletOptions.name, _authToken); + _walletOptions.name, _authToken); } }, async client => @@ -125,6 +125,8 @@ protected override async Task _SignAllTransactions(Transaction[] } } ); + + SolanaWalletAdapter.TriggerUserApprovedTransaction(result.WasSuccessful); if (!result.WasSuccessful) { Debug.LogError(result.Error.Message); @@ -165,7 +167,7 @@ public override async Task SignMessage(byte[] message) authorization = await client.Reauthorize( new Uri(_walletOptions.identityUri), new Uri(_walletOptions.iconUri, UriKind.Relative), - _walletOptions.name, _authToken); + _walletOptions.name, _authToken); } }, async client => diff --git a/Runtime/codebase/SolanaWalletAdapter.cs b/Runtime/codebase/SolanaWalletAdapter.cs index 65658c6e..20e256fa 100644 --- a/Runtime/codebase/SolanaWalletAdapter.cs +++ b/Runtime/codebase/SolanaWalletAdapter.cs @@ -15,11 +15,18 @@ public class SolanaWalletAdapterOptions public SolanaWalletAdapterWebGLOptions solanaWalletAdapterWebGLOptions; public PhantomWalletOptions phantomWalletOptions; } - + public class SolanaWalletAdapter: WalletBase { private readonly WalletBase _internalWallet; + public static event EventHandler UserApprovedTransaction; + + internal static void TriggerUserApprovedTransaction(bool approvedTransaction) + { + UserApprovedTransaction?.Invoke(null, approvedTransaction); + } + public SolanaWalletAdapter(SolanaWalletAdapterOptions options, RpcCluster rpcCluster = RpcCluster.DevNet, string customRpcUri = null, string customStreamingRpcUri = null, bool autoConnectOnStartup = false) : base(rpcCluster, customRpcUri, customStreamingRpcUri, autoConnectOnStartup) { #if UNITY_ANDROID diff --git a/Runtime/codebase/SolanaWalletAdapterWebGL/SolanaWalletAdapterWebGL.cs b/Runtime/codebase/SolanaWalletAdapterWebGL/SolanaWalletAdapterWebGL.cs index 362db716..a89504f6 100644 --- a/Runtime/codebase/SolanaWalletAdapterWebGL/SolanaWalletAdapterWebGL.cs +++ b/Runtime/codebase/SolanaWalletAdapterWebGL/SolanaWalletAdapterWebGL.cs @@ -1,9 +1,8 @@ -using System; -using System.Runtime.InteropServices; -using System.Threading.Tasks; -using AOT; +using AOT; using Solana.Unity.Rpc.Models; using Solana.Unity.Wallet; +using System; +using System.Threading.Tasks; using UnityEngine; // ReSharper disable once CheckNamespace @@ -211,6 +210,7 @@ private static void OnWalletConnected(string walletPubKey) [MonoPInvokeCallback(typeof(Action))] public static void OnTransactionSigned(string transaction) { + SolanaWalletAdapter.TriggerUserApprovedTransaction(transaction != null); if (transaction == null) { _signedTransactionTaskCompletionSource.TrySetException(new Exception("Transaction signing cancelled")); @@ -228,6 +228,7 @@ public static void OnTransactionSigned(string transaction) [MonoPInvokeCallback(typeof(Action))] public static void OnAllTransactionsSigned(string transactions) { + SolanaWalletAdapter.TriggerUserApprovedTransaction(transactions != null); if (transactions == null) { _signedAllTransactionsTaskCompletionSource.TrySetException(new Exception("Transactions signing cancelled")); @@ -252,6 +253,7 @@ public static void OnAllTransactionsSigned(string transactions) [MonoPInvokeCallback(typeof(Action))] public static void OnMessageSigned(string signature) { + SolanaWalletAdapter.TriggerUserApprovedTransaction(signature != null); if (signature == null) { _signedMessageTaskCompletionSource.TrySetException(new Exception("Message signing cancelled")); diff --git a/Runtime/codebase/WalletBase.cs b/Runtime/codebase/WalletBase.cs index ab7835a3..15e38420 100644 --- a/Runtime/codebase/WalletBase.cs +++ b/Runtime/codebase/WalletBase.cs @@ -253,10 +253,11 @@ public virtual async Task> SignAndSendTransaction ( Transaction transaction, bool skipPreflight = false, - Commitment commitment = Commitment.Confirmed) + Commitment commitment = Commitment.Confirmed, + IRpcClient customClient = null) { var signedTransaction = await SignTransaction(transaction); - return await ActiveRpcClient.SendTransactionAsync( + return await (customClient ?? ActiveRpcClient).SendTransactionAsync( Convert.ToBase64String(signedTransaction.Serialize()), skipPreflight: skipPreflight, preFlightCommitment: commitment); }