-
Notifications
You must be signed in to change notification settings - Fork 127
improvement: Added customClient option in SignAndSendTransaction & Added detection of denial of transaction #268
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -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); | ||
|
Comment on lines
328
to
+334
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Critical: Same issue as Proposed fix if (!string.IsNullOrEmpty(errorMessage) || string.IsNullOrEmpty(data))
{
SolanaWalletAdapter.TriggerUserApprovedTransaction(false);
+ _signedMessageTaskCompletionSource?.TrySetException(new Exception($"Deeplink error: {errorMessage}"));
+ _signedMessageTaskCompletionSource?.TrySetResult(null);
Debug.LogError($"Deeplink error: Error: {errorMessage} + Data: {data}");
return;
}🤖 Prompt for AI Agents |
||
| data = data.Replace("#", ""); | ||
| var k = MontgomeryCurve25519.KeyExchange(_phantomEncryptionPubKey, PhantomConnectionAccountPrivateKey); | ||
| var unencryptedMessage = XSalsa20Poly1305.TryDecrypt(Encoders.Base58.DecodeData(data), k, Encoders.Base58.DecodeData(nonce)); | ||
|
|
||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -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<Account> _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<Transaction[]> _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<Transaction[]> _SignAllTransactions(Transaction[] | |
| } | ||
| } | ||
| ); | ||
|
|
||
| SolanaWalletAdapter.TriggerUserApprovedTransaction(result.WasSuccessful); | ||
|
Comment on lines
+128
to
+129
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. LGTM - but missing trigger in The trigger placement here is correct, firing after However, the Proposed fix to add trigger in SignMessage }
);
+ SolanaWalletAdapter.TriggerUserApprovedTransaction(result.WasSuccessful);
if (!result.WasSuccessful)
{
Debug.LogError(result.Error.Message);Add this after line 181, before the 🤖 Prompt for AI Agents |
||
| if (!result.WasSuccessful) | ||
| { | ||
| Debug.LogError(result.Error.Message); | ||
|
|
@@ -165,7 +167,7 @@ public override async Task<byte[]> 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 => | ||
|
|
||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -253,10 +253,11 @@ public virtual async Task<RequestResult<string>> SignAndSendTransaction | |
| ( | ||
| Transaction transaction, | ||
| bool skipPreflight = false, | ||
| Commitment commitment = Commitment.Confirmed) | ||
| Commitment commitment = Commitment.Confirmed, | ||
| IRpcClient customClient = null) | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This is not the place to pass a custom rpc. Like I mentioned in TG, this is unnecessary as well if you create an additional wallet for the ER connection. |
||
| { | ||
| var signedTransaction = await SignTransaction(transaction); | ||
| return await ActiveRpcClient.SendTransactionAsync( | ||
| return await (customClient ?? ActiveRpcClient).SendTransactionAsync( | ||
| Convert.ToBase64String(signedTransaction.Serialize()), | ||
| skipPreflight: skipPreflight, preFlightCommitment: commitment); | ||
| } | ||
|
|
||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Critical:
TaskCompletionSourcenever completed on error path - callers will hang indefinitely.The new trigger code is placed in an error path that returns early without completing
_signedTransactionTaskCompletionSource. Any code awaiting_SignTransactionwill hang forever when the user declines.Compare with the WebGL implementation which properly handles this:
Proposed fix
if (!string.IsNullOrEmpty(errorMessage) || string.IsNullOrEmpty(data)) { SolanaWalletAdapter.TriggerUserApprovedTransaction(false); + _signedTransactionTaskCompletionSource?.TrySetException(new Exception($"Deeplink error: {errorMessage}")); + _signedTransactionTaskCompletionSource?.TrySetResult(null); Debug.LogError($"Deeplink error: Error: {errorMessage} + Data: {data}"); return; }🤖 Prompt for AI Agents