diff --git a/Runtime/codebase/SessionWallet.cs b/Runtime/codebase/SessionWallet.cs
index 69cd53d..3ba1c00 100644
--- a/Runtime/codebase/SessionWallet.cs
+++ b/Runtime/codebase/SessionWallet.cs
@@ -21,6 +21,7 @@ public class SessionWallet : InGameWallet
public PublicKey SessionTokenPDA { get; protected set; }
public static SessionWallet Instance;
+ private static WalletBase _externalWallet;
private SessionWallet(RpcCluster rpcCluster = RpcCluster.DevNet,
string customRpcUri = null, string customStreamingRpcUri = null,
@@ -58,25 +59,28 @@ private static PublicKey FindSessionToken(PublicKey TargetProgram, Account Accou
sessionSigner: Account.PublicKey
);
}
-
+
+ public void SignInitSessionTx(Transaction tx)
+ {
+ tx.PartialSign(new[] { _externalWallet.Account, Account });
+ }
+
+
///
/// Creates a new SessionWallet instance and logs in with the provided password if a session wallet exists, otherwise creates a new account and logs in.
///
/// The target program to interact with.
/// The password to decrypt the session keystore.
- /// The Solana RPC cluster to connect to.
- /// A custom URI to connect to the Solana RPC cluster.
- /// A custom URI to connect to the Solana streaming RPC cluster.
- /// Whether to automatically connect to the Solana RPC cluster on startup.
+ /// The external wallet
/// A SessionWallet instance.
- public static async Task GetSessionWallet(PublicKey targetProgram, string password, RpcCluster rpcCluster = RpcCluster.DevNet,
- string customRpcUri = null, string customStreamingRpcUri = null,
- bool autoConnectOnStartup = false)
+ public static async Task GetSessionWallet(PublicKey targetProgram, string password, WalletBase externalWallet = null)
{
if(Instance != null) return Instance;
- SessionWallet sessionWallet = new SessionWallet(rpcCluster, customRpcUri, customStreamingRpcUri, autoConnectOnStartup);
+ externalWallet ??= Web3.Wallet;
+ _externalWallet = externalWallet;
+ SessionWallet sessionWallet = new SessionWallet(externalWallet.RpcCluster, externalWallet.ActiveRpcClient.NodeAddress.ToString());
sessionWallet.TargetProgram = targetProgram;
- sessionWallet.EncryptedKeystoreKey = $"{Web3.Account.PublicKey}_SessionKeyStore";
+ sessionWallet.EncryptedKeystoreKey = $"{_externalWallet.Account.PublicKey}_SessionKeyStore";
var derivedPassword = DeriveSessionPassword(password);
if (sessionWallet.HasSessionWallet())
@@ -89,10 +93,10 @@ public static async Task GetSessionWallet(PublicKey targetProgram
sessionWallet.DeleteSessionWallet();
sessionWallet.Logout();
Instance = null;
- return await GetSessionWallet(targetProgram, password, rpcCluster, customRpcUri, customStreamingRpcUri, autoConnectOnStartup);
+ return await GetSessionWallet(targetProgram, password, externalWallet);
}
- sessionWallet.SessionTokenPDA = FindSessionToken(targetProgram, sessionWallet.Account, Web3.Account);
+ sessionWallet.SessionTokenPDA = FindSessionToken(targetProgram, sessionWallet.Account, _externalWallet.Account);
Debug.Log(sessionWallet.SessionTokenPDA);
@@ -109,14 +113,14 @@ public static async Task GetSessionWallet(PublicKey targetProgram
}
Debug.Log("Session Token is invalid");
- await sessionWallet.PrepareLogout();
+ await sessionWallet.CloseSession();
sessionWallet.Logout();
Instance = null;
- return await GetSessionWallet(targetProgram, password, rpcCluster, customRpcUri, customStreamingRpcUri, autoConnectOnStartup);
+ return await GetSessionWallet(targetProgram, password, externalWallet);
}
sessionWallet.Account = await sessionWallet.CreateAccount(password: derivedPassword);
- sessionWallet.SessionTokenPDA = FindSessionToken(targetProgram, sessionWallet.Account, Web3.Account);
+ sessionWallet.SessionTokenPDA = FindSessionToken(targetProgram, sessionWallet.Account, _externalWallet.Account);
return sessionWallet;
}
@@ -133,7 +137,7 @@ public TransactionInstruction CreateSessionIX(bool topUp, long sessionValidity)
{
SessionToken = SessionTokenPDA,
SessionSigner = Account.PublicKey,
- Authority = Web3.Account,
+ Authority = _externalWallet.Account,
TargetProgram = TargetProgram,
SystemProgram = SystemProgram.ProgramIdKey,
};
@@ -155,7 +159,7 @@ public TransactionInstruction RevokeSessionIX()
{
SessionToken = SessionTokenPDA,
// Only the authority of the session token can receive the refund
- Authority = Web3.Account,
+ Authority = _externalWallet.Account,
SystemProgram = SystemProgram.ProgramIdKey,
};
@@ -185,8 +189,15 @@ public async Task IsSessionTokenValid()
return SessionToken.Deserialize(Convert.FromBase64String(sessionTokenData)).ValidUntil > DateTimeOffset.UtcNow.ToUnixTimeSeconds();
}
+ public async Task Authority()
+ {
+ var sessionTokenData = (await ActiveRpcClient.GetAccountInfoAsync(SessionTokenPDA)).Result.Value.Data[0];
+ if (sessionTokenData == null) return null;
+ return SessionToken.Deserialize(Convert.FromBase64String(sessionTokenData)).Authority;
+ }
+
private static string DeriveSessionPassword(string password) {
- var rawData = Web3.Account.PublicKey.Key + password + Application.platform;
+ var rawData = _externalWallet.Account.PublicKey.Key + password + Application.platform;
using SHA256 sha256Hash = SHA256.Create();
// ComputeHash - returns byte array
var bytes = sha256Hash.ComputeHash(Encoding.UTF8.GetBytes(rawData));
@@ -207,7 +218,7 @@ private void DeleteSessionWallet()
/// NOTE: You must call PrepareLogout before calling Logout to ensure that the session token account is revoked and the refund is issued.
///
/// A task that represents the asynchronous operation.
- public async Task PrepareLogout()
+ public async Task CloseSession(Commitment commitment = Commitment.Confirmed)
{
Debug.Log("Preparing Logout");
// Revoke Session
@@ -215,7 +226,7 @@ public async Task PrepareLogout()
{
FeePayer = Account,
Instructions = new List(),
- RecentBlockHash = await Web3.BlockHash()
+ RecentBlockHash = await GetBlockHash(commitment)
};
// Get balance and calculate refund
@@ -226,9 +237,8 @@ public async Task PrepareLogout()
tx.Add(RevokeSessionIX());
// Issue Refund
- tx.Add(SystemProgram.Transfer(Account.PublicKey, Web3.Account.PublicKey, (ulong)refund));
- var rest = await SignAndSendTransaction(tx);
- Debug.Log("Session refund transaction: " + rest.RawRpcResponse);
+ tx.Add(SystemProgram.Transfer(Account.PublicKey, _externalWallet.Account.PublicKey, (ulong)refund));
+ var rest = await SignAndSendTransaction(tx, commitment: commitment);
DeleteSessionWallet();
}
}