-
Notifications
You must be signed in to change notification settings - Fork 245
Expand file tree
/
Copy pathWeb3AuthProvider.cs
More file actions
157 lines (127 loc) · 4.42 KB
/
Web3AuthProvider.cs
File metadata and controls
157 lines (127 loc) · 4.42 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
using System.Threading.Tasks;
using ChainSafe.Gaming.Evm;
using ChainSafe.Gaming.InProcessSigner;
using ChainSafe.Gaming.Web3;
using ChainSafe.Gaming.Web3.Core.Operations;
using ChainSafe.Gaming.Web3.Environment;
using ChainSafe.Gaming.Web3.Evm.Wallet;
using ChainSafe.GamingSdk.Web3Auth;
using Nethereum.RPC.Accounts;
using Nethereum.Web3.Accounts;
using UnityEngine;
/// <summary>
/// Web3Auth provider allowing users to connect a Web3Auth wallet.
/// </summary>
public class Web3AuthProvider : WalletProvider, IAccountProvider
{
private readonly Web3AuthWalletConfig _config;
private readonly IOperationTracker operationTracker;
private Web3Auth _coreInstance;
private TaskCompletionSource<Web3AuthResponse> _connectTcs;
private TaskCompletionSource<object> _disconnectTcs;
public Web3AuthProvider(
Web3AuthWalletConfig config,
Web3Environment environment,
IChainConfig chainConfig,
IOperationTracker operationTracker,
IOperatingSystemMediator operatingSystemMediator)
: base(environment, chainConfig, operationTracker, operatingSystemMediator)
{
this.operationTracker = operationTracker;
_config = config;
}
public IAccount Account { get; private set; }
/// <summary>
/// Connects Web3Auth wallet.
/// </summary>
/// <returns>Connected Account.</returns>
public override async Task<string> Connect()
{
_coreInstance = Object.FindObjectOfType<Web3Auth>();
if (_coreInstance == null)
{
var gameObject = new GameObject("Web3Auth", typeof(Web3Auth));
Object.DontDestroyOnLoad(gameObject);
_coreInstance = gameObject.GetComponent<Web3Auth>();
}
if (_connectTcs != null && !_connectTcs.Task.IsCompleted)
{
Cancel();
}
_connectTcs = new TaskCompletionSource<Web3AuthResponse>();
_coreInstance.onLogin += OnLogin;
_coreInstance.Initialize();
_coreInstance.setOptions(_config.Web3AuthOptions, _config.RememberMe);
var providerTask = _config.ProviderTask;
if (!_config.AutoLogin && providerTask != null
//On webGL providerTask is always completed, so we don't have to go through another login flow.
#if UNITY_WEBGL && !UNITY_EDITOR
&& !providerTask.IsCompleted
#endif
)
{
var provider = await providerTask;
_coreInstance.login(new LoginParams
{
loginProvider = provider,
});
}
await using (_config.CancellationToken.Register(Cancel))
{
using (operationTracker.TrackOperation("Connecting with Web3Auth...")) // TODO make this cancelable
{
var response = await _connectTcs.Task;
Account = new Account(response.privKey);
Account.TransactionManager.Client = this;
return Account.Address;
}
}
}
private void Cancel()
{
_coreInstance.onLogin -= OnLogin;
_connectTcs.SetCanceled();
}
private void OnLogin(Web3AuthResponse response)
{
_coreInstance.onLogin -= OnLogin;
if (string.IsNullOrEmpty(response.error))
{
_connectTcs.SetResult(response);
}
else
{
_connectTcs.SetException(new Web3Exception(response.error));
}
}
/// <summary>
/// Disconnect Web3Auth wallet.
/// </summary>
public override async Task Disconnect()
{
if (_disconnectTcs != null && !_disconnectTcs.Task.IsCompleted)
{
_disconnectTcs.SetCanceled();
}
_disconnectTcs = new TaskCompletionSource<object>();
_coreInstance.onLogout += OnLogout;
_coreInstance.logout();
await _disconnectTcs.Task;
Object.Destroy(_coreInstance.gameObject);
void OnLogout()
{
_disconnectTcs.SetResult(null);
}
}
/// <summary>
/// Make RPC requests to the Web3Auth wallet.
/// </summary>
/// <param name="method">RPC request method.</param>
/// <param name="parameters">RPC request parameters.</param>
/// <typeparam name="T">Type of response.</typeparam>
/// <returns>RPC request response.</returns>
public override Task<T> Request<T>(string method, params object[] parameters)
{
return Perform<T>(method, parameters);
}
}