@mocanetwork/airkit 0.5.0-beta.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +177 -0
- package/dist/airkit.cjs.js +2662 -0
- package/dist/airkit.esm.js +2468 -0
- package/dist/airkit.umd.min.js +2 -0
- package/dist/airkit.umd.min.js.LICENSE.txt +12 -0
- package/dist/lib.cjs/common/src/error.js +25 -0
- package/dist/lib.cjs/common/src/realm/messaging/auth.js +28 -0
- package/dist/lib.cjs/common/src/realm/messaging/types.js +15 -0
- package/dist/lib.cjs/ws-embed/src/PopupHandler.js +64 -0
- package/dist/lib.cjs/ws-embed/src/airService.js +364 -0
- package/dist/lib.cjs/ws-embed/src/baseProvider.js +178 -0
- package/dist/lib.cjs/ws-embed/src/communicationProvider.js +346 -0
- package/dist/lib.cjs/ws-embed/src/embed.js +735 -0
- package/dist/lib.cjs/ws-embed/src/error.js +21 -0
- package/dist/lib.cjs/ws-embed/src/iframeController.js +68 -0
- package/dist/lib.cjs/ws-embed/src/inPageProvider.js +307 -0
- package/dist/lib.cjs/ws-embed/src/index.js +20 -0
- package/dist/lib.cjs/ws-embed/src/interfaces.js +29 -0
- package/dist/lib.cjs/ws-embed/src/isStream.js +20 -0
- package/dist/lib.cjs/ws-embed/src/loglevel.js +7 -0
- package/dist/lib.cjs/ws-embed/src/messageService.js +212 -0
- package/dist/lib.cjs/ws-embed/src/messages.js +22 -0
- package/dist/lib.cjs/ws-embed/src/siteMetadata.js +77 -0
- package/dist/lib.cjs/ws-embed/src/utils.js +95 -0
- package/dist/lib.esm/common/src/error.js +23 -0
- package/dist/lib.esm/common/src/realm/messaging/auth.js +26 -0
- package/dist/lib.esm/common/src/realm/messaging/types.js +13 -0
- package/dist/lib.esm/ws-embed/src/PopupHandler.js +62 -0
- package/dist/lib.esm/ws-embed/src/airService.js +362 -0
- package/dist/lib.esm/ws-embed/src/baseProvider.js +176 -0
- package/dist/lib.esm/ws-embed/src/communicationProvider.js +344 -0
- package/dist/lib.esm/ws-embed/src/embed.js +730 -0
- package/dist/lib.esm/ws-embed/src/error.js +18 -0
- package/dist/lib.esm/ws-embed/src/iframeController.js +66 -0
- package/dist/lib.esm/ws-embed/src/inPageProvider.js +302 -0
- package/dist/lib.esm/ws-embed/src/index.js +5 -0
- package/dist/lib.esm/ws-embed/src/interfaces.js +21 -0
- package/dist/lib.esm/ws-embed/src/isStream.js +15 -0
- package/dist/lib.esm/ws-embed/src/loglevel.js +5 -0
- package/dist/lib.esm/ws-embed/src/messageService.js +210 -0
- package/dist/lib.esm/ws-embed/src/messages.js +20 -0
- package/dist/lib.esm/ws-embed/src/siteMetadata.js +75 -0
- package/dist/lib.esm/ws-embed/src/utils.js +88 -0
- package/dist/types/PopupHandler.d.ts +24 -0
- package/dist/types/airService.d.ts +34 -0
- package/dist/types/baseProvider.d.ts +66 -0
- package/dist/types/common/custom.d.ts +4 -0
- package/dist/types/common/error.d.ts +17 -0
- package/dist/types/common/realm/error/auth.d.ts +1 -0
- package/dist/types/common/realm/error/types.d.ts +1 -0
- package/dist/types/common/realm/messaging/auth.d.ts +138 -0
- package/dist/types/common/realm/messaging/types.d.ts +95 -0
- package/dist/types/common/realm/partner/config.d.ts +68 -0
- package/dist/types/common/realm/user/types.d.ts +78 -0
- package/dist/types/common/realm/wallet/bybit/bybit.d.ts +2 -0
- package/dist/types/common/realm/wallet/coinbase/coinbase.d.ts +2 -0
- package/dist/types/common/realm/wallet/cryptoCom/cryptoCom.d.ts +2 -0
- package/dist/types/common/realm/wallet/index.d.ts +22 -0
- package/dist/types/common/realm/wallet/metamask/metamask.d.ts +2 -0
- package/dist/types/common/realm/wallet/okx/okx.d.ts +2 -0
- package/dist/types/common/realm/wallet/phantom/phantom.d.ts +2 -0
- package/dist/types/common/realm/wallet/rabby/rabby.d.ts +2 -0
- package/dist/types/common/realm/wallet/rainbow/rainbow.d.ts +2 -0
- package/dist/types/common/realm/wallet/trust/trust.d.ts +2 -0
- package/dist/types/common/types.d.ts +8 -0
- package/dist/types/common/utils.d.ts +2 -0
- package/dist/types/communicationProvider.d.ts +82 -0
- package/dist/types/embed.d.ts +42 -0
- package/dist/types/error.d.ts +9 -0
- package/dist/types/iframeController.d.ts +18 -0
- package/dist/types/inPageProvider.d.ts +106 -0
- package/dist/types/index.d.ts +4 -0
- package/dist/types/interfaces.d.ts +261 -0
- package/dist/types/isStream.d.ts +4 -0
- package/dist/types/loglevel.d.ts +3 -0
- package/dist/types/messageService.d.ts +51 -0
- package/dist/types/messages.d.ts +19 -0
- package/dist/types/siteMetadata.d.ts +9 -0
- package/dist/types/utils.d.ts +24 -0
- package/package.json +76 -0
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
var error = require('../../common/src/error.js');
|
|
4
|
+
|
|
5
|
+
class AirServiceError extends error.BaseError {
|
|
6
|
+
static from(error) {
|
|
7
|
+
if (error instanceof AirServiceError) {
|
|
8
|
+
return error;
|
|
9
|
+
} else if (error instanceof Object && "message" in error) {
|
|
10
|
+
if (error.message === "User cancelled login") {
|
|
11
|
+
return new AirServiceError("USER_CANCELLED", error.message);
|
|
12
|
+
}
|
|
13
|
+
return new AirServiceError("UNKNOWN_ERROR", error.message.toString());
|
|
14
|
+
}
|
|
15
|
+
return new AirServiceError("UNKNOWN_ERROR");
|
|
16
|
+
}
|
|
17
|
+
}
|
|
18
|
+
class RealmEmbedError extends AirServiceError {}
|
|
19
|
+
|
|
20
|
+
exports.AirServiceError = AirServiceError;
|
|
21
|
+
exports.RealmEmbedError = RealmEmbedError;
|
|
@@ -0,0 +1,68 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
var _objectSpread = require('@babel/runtime/helpers/objectSpread2');
|
|
4
|
+
var _defineProperty = require('@babel/runtime/helpers/defineProperty');
|
|
5
|
+
|
|
6
|
+
class IframeController {
|
|
7
|
+
constructor(iframeUrl, iframeId, state) {
|
|
8
|
+
_defineProperty(this, "state", void 0);
|
|
9
|
+
_defineProperty(this, "_iframeElement", null);
|
|
10
|
+
_defineProperty(this, "iframeUrl", void 0);
|
|
11
|
+
_defineProperty(this, "iframeId", void 0);
|
|
12
|
+
this.state = _objectSpread(_objectSpread({}, IframeController.defaultState), state);
|
|
13
|
+
this.iframeUrl = iframeUrl;
|
|
14
|
+
this.iframeId = iframeId;
|
|
15
|
+
}
|
|
16
|
+
get iframeElement() {
|
|
17
|
+
return this._iframeElement;
|
|
18
|
+
}
|
|
19
|
+
createIframe() {
|
|
20
|
+
if (this._iframeElement) return this._iframeElement;
|
|
21
|
+
const iframe = document.createElement("iframe");
|
|
22
|
+
iframe.id = this.iframeId;
|
|
23
|
+
iframe.allow = "publickey-credentials-get *; publickey-credentials-create *";
|
|
24
|
+
iframe.src = this.iframeUrl;
|
|
25
|
+
iframe.style.position = "fixed";
|
|
26
|
+
iframe.style.zIndex = "999999";
|
|
27
|
+
iframe.style.border = "none";
|
|
28
|
+
iframe.style.margin = "0";
|
|
29
|
+
iframe.style.padding = "0";
|
|
30
|
+
iframe.style.display = "none";
|
|
31
|
+
document.body.appendChild(iframe);
|
|
32
|
+
this._iframeElement = iframe;
|
|
33
|
+
return iframe;
|
|
34
|
+
}
|
|
35
|
+
setIframeVisibility(isVisible) {
|
|
36
|
+
this.state.isVisible = isVisible;
|
|
37
|
+
}
|
|
38
|
+
updateIframeState() {
|
|
39
|
+
if (!this.iframeElement) return;
|
|
40
|
+
const style = {};
|
|
41
|
+
style.display = this.state.isVisible ? "block" : "none";
|
|
42
|
+
style.width = "100%";
|
|
43
|
+
style.height = "100%";
|
|
44
|
+
style.top = "0px";
|
|
45
|
+
style.right = "0px";
|
|
46
|
+
style.left = "0px";
|
|
47
|
+
style.bottom = "0px";
|
|
48
|
+
Object.assign(this.iframeElement.style, style);
|
|
49
|
+
}
|
|
50
|
+
destroy() {
|
|
51
|
+
if (this.iframeElement) {
|
|
52
|
+
this.iframeElement.remove();
|
|
53
|
+
this._iframeElement = null;
|
|
54
|
+
}
|
|
55
|
+
}
|
|
56
|
+
postMessage(message) {
|
|
57
|
+
if (!this.iframeElement) return;
|
|
58
|
+
const {
|
|
59
|
+
origin
|
|
60
|
+
} = new URL(this.iframeElement.src);
|
|
61
|
+
this.iframeElement.contentWindow.postMessage(message, origin);
|
|
62
|
+
}
|
|
63
|
+
}
|
|
64
|
+
_defineProperty(IframeController, "defaultState", {
|
|
65
|
+
isVisible: false
|
|
66
|
+
});
|
|
67
|
+
|
|
68
|
+
exports.IframeController = IframeController;
|
|
@@ -0,0 +1,307 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
Object.defineProperty(exports, '__esModule', { value: true });
|
|
4
|
+
|
|
5
|
+
var _objectSpread = require('@babel/runtime/helpers/objectSpread2');
|
|
6
|
+
var _defineProperty = require('@babel/runtime/helpers/defineProperty');
|
|
7
|
+
var baseControllers = require('@toruslabs/base-controllers');
|
|
8
|
+
var auth = require('@web3auth/auth');
|
|
9
|
+
var dequal = require('fast-deep-equal');
|
|
10
|
+
var baseProvider = require('./baseProvider.js');
|
|
11
|
+
var loglevel = require('./loglevel.js');
|
|
12
|
+
var messages = require('./messages.js');
|
|
13
|
+
var utils = require('./utils.js');
|
|
14
|
+
|
|
15
|
+
/**
|
|
16
|
+
* @param connectionStream - A Node.js duplex stream
|
|
17
|
+
* @param opts - An options bag
|
|
18
|
+
*/
|
|
19
|
+
class AirInPageProvider extends baseProvider {
|
|
20
|
+
constructor(connectionStream, {
|
|
21
|
+
maxEventListeners = 100,
|
|
22
|
+
jsonRpcStreamName = "provider"
|
|
23
|
+
}) {
|
|
24
|
+
super(connectionStream, {
|
|
25
|
+
maxEventListeners,
|
|
26
|
+
jsonRpcStreamName
|
|
27
|
+
});
|
|
28
|
+
|
|
29
|
+
// private state
|
|
30
|
+
/**
|
|
31
|
+
* The chain ID of the currently connected EVM chain.
|
|
32
|
+
* See [chainId.network]{@link https://chainid.network} for more information.
|
|
33
|
+
*/
|
|
34
|
+
_defineProperty(this, "chainId", void 0);
|
|
35
|
+
/**
|
|
36
|
+
* The user's currently selected EVM address.
|
|
37
|
+
* If null, Torus is either locked or the user has not permitted any
|
|
38
|
+
* addresses to be viewed.
|
|
39
|
+
*/
|
|
40
|
+
_defineProperty(this, "selectedAddress", void 0);
|
|
41
|
+
_defineProperty(this, "tryWindowHandle", void 0);
|
|
42
|
+
this.state = _objectSpread({}, AirInPageProvider.defaultState);
|
|
43
|
+
|
|
44
|
+
// public state
|
|
45
|
+
this.selectedAddress = null;
|
|
46
|
+
this.chainId = null;
|
|
47
|
+
this.handleAccountsChanged = this.handleAccountsChanged.bind(this);
|
|
48
|
+
this.handleChainChanged = this.handleChainChanged.bind(this);
|
|
49
|
+
this.handleUnlockStateChanged = this.handleUnlockStateChanged.bind(this);
|
|
50
|
+
|
|
51
|
+
// setup own event listeners
|
|
52
|
+
|
|
53
|
+
// EIP-1193 connect
|
|
54
|
+
this.on("connect", () => {
|
|
55
|
+
this.state.isConnected = true;
|
|
56
|
+
});
|
|
57
|
+
const jsonRpcNotificationHandler = payload => {
|
|
58
|
+
const {
|
|
59
|
+
method,
|
|
60
|
+
params
|
|
61
|
+
} = payload;
|
|
62
|
+
if (method === baseControllers.PROVIDER_NOTIFICATIONS.ACCOUNTS_CHANGED) {
|
|
63
|
+
this.handleAccountsChanged(params);
|
|
64
|
+
} else if (method === baseControllers.PROVIDER_NOTIFICATIONS.UNLOCK_STATE_CHANGED) {
|
|
65
|
+
this.handleUnlockStateChanged(params);
|
|
66
|
+
} else if (method === baseControllers.PROVIDER_NOTIFICATIONS.CHAIN_CHANGED) {
|
|
67
|
+
this.handleChainChanged(params);
|
|
68
|
+
} else if (utils.EMITTED_NOTIFICATIONS.includes(method)) {
|
|
69
|
+
this.emit("data", payload);
|
|
70
|
+
this.emit("notification", params.result);
|
|
71
|
+
this.emit("message", {
|
|
72
|
+
type: method,
|
|
73
|
+
data: params
|
|
74
|
+
});
|
|
75
|
+
}
|
|
76
|
+
};
|
|
77
|
+
|
|
78
|
+
// json rpc notification listener
|
|
79
|
+
this.jsonRpcConnectionEvents.on("notification", jsonRpcNotificationHandler);
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
/**
|
|
83
|
+
* Returns whether the inpage provider is connected to Torus.
|
|
84
|
+
*/
|
|
85
|
+
isConnected() {
|
|
86
|
+
return this.state.isConnected;
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
// Private Methods
|
|
90
|
+
//= ===================
|
|
91
|
+
/**
|
|
92
|
+
* Constructor helper.
|
|
93
|
+
* Populates initial state by calling 'wallet_getProviderState' and emits
|
|
94
|
+
* necessary events.
|
|
95
|
+
*/
|
|
96
|
+
async initializeState() {
|
|
97
|
+
try {
|
|
98
|
+
const {
|
|
99
|
+
accounts,
|
|
100
|
+
chainId,
|
|
101
|
+
isUnlocked
|
|
102
|
+
} = await this.request({
|
|
103
|
+
method: baseControllers.PROVIDER_JRPC_METHODS.GET_PROVIDER_STATE,
|
|
104
|
+
params: []
|
|
105
|
+
});
|
|
106
|
+
|
|
107
|
+
// indicate that we've connected, for EIP-1193 compliance
|
|
108
|
+
this.emit("connect", {
|
|
109
|
+
chainId
|
|
110
|
+
});
|
|
111
|
+
this.handleChainChanged({
|
|
112
|
+
chainId
|
|
113
|
+
});
|
|
114
|
+
this.handleUnlockStateChanged({
|
|
115
|
+
accounts,
|
|
116
|
+
isUnlocked
|
|
117
|
+
});
|
|
118
|
+
this.handleAccountsChanged(accounts);
|
|
119
|
+
} catch (error) {
|
|
120
|
+
loglevel.error("WsEmbed: Failed to get initial state. Please report this bug.", error);
|
|
121
|
+
} finally {
|
|
122
|
+
loglevel.info("initialized provider state");
|
|
123
|
+
this.state.initialized = true;
|
|
124
|
+
}
|
|
125
|
+
}
|
|
126
|
+
|
|
127
|
+
/**
|
|
128
|
+
* Internal RPC method. Forwards requests to background via the RPC engine.
|
|
129
|
+
* Also remap ids inbound and outbound
|
|
130
|
+
*/
|
|
131
|
+
rpcRequest(payload, callback, isInternal = false) {
|
|
132
|
+
let cb = callback;
|
|
133
|
+
const _payload = payload;
|
|
134
|
+
if (!Array.isArray(_payload)) {
|
|
135
|
+
if (!_payload.jsonrpc) {
|
|
136
|
+
_payload.jsonrpc = "2.0";
|
|
137
|
+
}
|
|
138
|
+
if (_payload.method === "eth_accounts" || _payload.method === "eth_requestAccounts") {
|
|
139
|
+
// handle accounts changing
|
|
140
|
+
cb = (err, res) => {
|
|
141
|
+
this.handleAccountsChanged(res.result || [], _payload.method === "eth_accounts", isInternal);
|
|
142
|
+
callback(err, res);
|
|
143
|
+
};
|
|
144
|
+
} else if (_payload.method === "wallet_getProviderState") {
|
|
145
|
+
this.rpcEngine.handle(payload, cb);
|
|
146
|
+
return;
|
|
147
|
+
}
|
|
148
|
+
}
|
|
149
|
+
this.tryWindowHandle(_payload, cb);
|
|
150
|
+
}
|
|
151
|
+
|
|
152
|
+
/**
|
|
153
|
+
* When the provider becomes connected, updates internal state and emits
|
|
154
|
+
* required events. Idempotent.
|
|
155
|
+
*
|
|
156
|
+
* @param chainId - The ID of the newly connected chain.
|
|
157
|
+
* emits TorusInpageProvider#connect
|
|
158
|
+
*/
|
|
159
|
+
handleConnect(chainId) {
|
|
160
|
+
if (!this.state.isConnected) {
|
|
161
|
+
this.state.isConnected = true;
|
|
162
|
+
this.emit("connect", {
|
|
163
|
+
chainId
|
|
164
|
+
});
|
|
165
|
+
loglevel.debug(messages.info.connected(chainId));
|
|
166
|
+
}
|
|
167
|
+
}
|
|
168
|
+
|
|
169
|
+
/**
|
|
170
|
+
* When the provider becomes disconnected, updates internal state and emits
|
|
171
|
+
* required events. Idempotent with respect to the isRecoverable parameter.
|
|
172
|
+
*
|
|
173
|
+
* Error codes per the CloseEvent status codes as required by EIP-1193:
|
|
174
|
+
* https://developer.mozilla.org/en-US/docs/Web/API/CloseEvent#Status_codes
|
|
175
|
+
*
|
|
176
|
+
* @param isRecoverable - Whether the disconnection is recoverable.
|
|
177
|
+
* @param errorMessage - A custom error message.
|
|
178
|
+
* emits TorusInpageProvider#disconnect
|
|
179
|
+
*/
|
|
180
|
+
handleDisconnect(isRecoverable, errorMessage) {
|
|
181
|
+
if (this.state.isConnected || !this.state.isPermanentlyDisconnected && !isRecoverable) {
|
|
182
|
+
this.state.isConnected = false;
|
|
183
|
+
let error;
|
|
184
|
+
if (isRecoverable) {
|
|
185
|
+
error = new auth.EthereumProviderError(1013,
|
|
186
|
+
// Try again later
|
|
187
|
+
errorMessage || messages.errors.disconnected());
|
|
188
|
+
loglevel.debug(error);
|
|
189
|
+
} else {
|
|
190
|
+
error = new auth.EthereumProviderError(1011,
|
|
191
|
+
// Internal error
|
|
192
|
+
errorMessage || messages.errors.permanentlyDisconnected());
|
|
193
|
+
loglevel.error(error);
|
|
194
|
+
this.chainId = null;
|
|
195
|
+
this.state.accounts = null;
|
|
196
|
+
this.selectedAddress = null;
|
|
197
|
+
this.state.isUnlocked = false;
|
|
198
|
+
this.state.isPermanentlyDisconnected = true;
|
|
199
|
+
}
|
|
200
|
+
this.emit("disconnect", error);
|
|
201
|
+
}
|
|
202
|
+
}
|
|
203
|
+
|
|
204
|
+
/**
|
|
205
|
+
* Called when accounts may have changed.
|
|
206
|
+
*/
|
|
207
|
+
handleAccountsChanged(accounts, isEthAccounts = false, isInternal = false) {
|
|
208
|
+
// defensive programming
|
|
209
|
+
let finalAccounts = accounts;
|
|
210
|
+
if (!Array.isArray(finalAccounts)) {
|
|
211
|
+
loglevel.error("WsEmbed: Received non-array accounts parameter. Please report this bug.", finalAccounts);
|
|
212
|
+
finalAccounts = [];
|
|
213
|
+
}
|
|
214
|
+
for (const account of accounts) {
|
|
215
|
+
if (typeof account !== "string") {
|
|
216
|
+
loglevel.error("WsEmbed: Received non-string account. Please report this bug.", accounts);
|
|
217
|
+
finalAccounts = [];
|
|
218
|
+
break;
|
|
219
|
+
}
|
|
220
|
+
}
|
|
221
|
+
|
|
222
|
+
// emit accountsChanged if anything about the accounts array has changed
|
|
223
|
+
if (!dequal(this.state.accounts, finalAccounts)) {
|
|
224
|
+
// we should always have the correct accounts even before eth_accounts
|
|
225
|
+
// returns, except in cases where isInternal is true
|
|
226
|
+
if (isEthAccounts && Array.isArray(this.state.accounts) && this.state.accounts.length > 0 && !isInternal) {
|
|
227
|
+
loglevel.error('WsEmbed: "eth_accounts" unexpectedly updated accounts. Please report this bug.', finalAccounts);
|
|
228
|
+
}
|
|
229
|
+
this.state.accounts = finalAccounts;
|
|
230
|
+
this.emit("accountsChanged", finalAccounts);
|
|
231
|
+
}
|
|
232
|
+
|
|
233
|
+
// handle selectedAddress
|
|
234
|
+
if (this.selectedAddress !== finalAccounts[0]) {
|
|
235
|
+
this.selectedAddress = finalAccounts[0] || null;
|
|
236
|
+
}
|
|
237
|
+
}
|
|
238
|
+
|
|
239
|
+
/**
|
|
240
|
+
* Upon receipt of a new chainId and networkVersion, emits corresponding
|
|
241
|
+
* events and sets relevant public state.
|
|
242
|
+
* Does nothing if neither the chainId nor the networkVersion are different
|
|
243
|
+
* from existing values.
|
|
244
|
+
*
|
|
245
|
+
* emits TorusInpageProvider#chainChanged
|
|
246
|
+
* @param networkInfo - An object with network info.
|
|
247
|
+
*/
|
|
248
|
+
handleChainChanged({
|
|
249
|
+
chainId
|
|
250
|
+
} = {}) {
|
|
251
|
+
if (!chainId) {
|
|
252
|
+
loglevel.error("WsEmbed: Received invalid network parameters. Please report this bug.", {
|
|
253
|
+
chainId
|
|
254
|
+
});
|
|
255
|
+
return;
|
|
256
|
+
}
|
|
257
|
+
if (chainId === "loading") {
|
|
258
|
+
this.handleDisconnect(true);
|
|
259
|
+
} else {
|
|
260
|
+
this.handleConnect(chainId);
|
|
261
|
+
if (chainId !== this.chainId) {
|
|
262
|
+
this.chainId = chainId;
|
|
263
|
+
if (this.state.initialized) {
|
|
264
|
+
this.emit("chainChanged", this.chainId);
|
|
265
|
+
}
|
|
266
|
+
}
|
|
267
|
+
}
|
|
268
|
+
}
|
|
269
|
+
|
|
270
|
+
/**
|
|
271
|
+
* Upon receipt of a new isUnlocked state, sets relevant public state.
|
|
272
|
+
* Calls the accounts changed handler with the received accounts, or an empty
|
|
273
|
+
* array.
|
|
274
|
+
*
|
|
275
|
+
* Does nothing if the received value is equal to the existing value.
|
|
276
|
+
* There are no lock/unlock events.
|
|
277
|
+
*
|
|
278
|
+
* @param opts - Options bag.
|
|
279
|
+
*/
|
|
280
|
+
handleUnlockStateChanged({
|
|
281
|
+
accounts,
|
|
282
|
+
isUnlocked
|
|
283
|
+
} = {}) {
|
|
284
|
+
if (typeof isUnlocked !== "boolean") {
|
|
285
|
+
loglevel.error("WsEmbed: Received invalid isUnlocked parameter. Please report this bug.", {
|
|
286
|
+
isUnlocked
|
|
287
|
+
});
|
|
288
|
+
return;
|
|
289
|
+
}
|
|
290
|
+
if (isUnlocked !== this.state.isUnlocked) {
|
|
291
|
+
this.state.isUnlocked = isUnlocked;
|
|
292
|
+
this.handleAccountsChanged(accounts || []);
|
|
293
|
+
}
|
|
294
|
+
}
|
|
295
|
+
}
|
|
296
|
+
_defineProperty(AirInPageProvider, "defaultState", {
|
|
297
|
+
accounts: null,
|
|
298
|
+
isConnected: false,
|
|
299
|
+
isUnlocked: false,
|
|
300
|
+
initialized: false,
|
|
301
|
+
isPermanentlyDisconnected: false,
|
|
302
|
+
hasEmittedConnection: false
|
|
303
|
+
});
|
|
304
|
+
class TorusInPageProvider extends AirInPageProvider {}
|
|
305
|
+
|
|
306
|
+
exports.TorusInPageProvider = TorusInPageProvider;
|
|
307
|
+
exports.default = AirInPageProvider;
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
var airService = require('./airService.js');
|
|
4
|
+
var embed = require('./embed.js');
|
|
5
|
+
var inPageProvider = require('./inPageProvider.js');
|
|
6
|
+
var interfaces = require('./interfaces.js');
|
|
7
|
+
var baseControllers = require('@toruslabs/base-controllers');
|
|
8
|
+
|
|
9
|
+
|
|
10
|
+
|
|
11
|
+
exports.AirService = airService;
|
|
12
|
+
exports.RealmEmbed = embed.default;
|
|
13
|
+
exports.AirInPageProvider = inPageProvider.default;
|
|
14
|
+
exports.BUTTON_POSITION = interfaces.BUTTON_POSITION;
|
|
15
|
+
exports.EMBED_BUILD_ENV = interfaces.EMBED_BUILD_ENV;
|
|
16
|
+
exports.EXTERNAL_LOGIN_PROVIDER = interfaces.EXTERNAL_LOGIN_PROVIDER;
|
|
17
|
+
Object.defineProperty(exports, "CONFIRMATION_STRATEGY", {
|
|
18
|
+
enumerable: true,
|
|
19
|
+
get: function () { return baseControllers.CONFIRMATION_STRATEGY; }
|
|
20
|
+
});
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
var baseControllers = require('@toruslabs/base-controllers');
|
|
4
|
+
|
|
5
|
+
const EMBED_BUILD_ENV = {
|
|
6
|
+
PRODUCTION: "production",
|
|
7
|
+
STAGING: "staging",
|
|
8
|
+
DEVELOPMENT: "development",
|
|
9
|
+
TESTING: "testing"
|
|
10
|
+
};
|
|
11
|
+
const BUTTON_POSITION = {
|
|
12
|
+
BOTTOM_LEFT: "bottom-left",
|
|
13
|
+
TOP_LEFT: "top-left",
|
|
14
|
+
BOTTOM_RIGHT: "bottom-right",
|
|
15
|
+
TOP_RIGHT: "top-right"
|
|
16
|
+
};
|
|
17
|
+
const EXTERNAL_LOGIN_PROVIDER = {
|
|
18
|
+
METAMASK: "metamask",
|
|
19
|
+
WALLET_CONNECT: "walletconnect",
|
|
20
|
+
WAGMI: "wagmi"
|
|
21
|
+
};
|
|
22
|
+
|
|
23
|
+
Object.defineProperty(exports, "CONFIRMATION_STRATEGY", {
|
|
24
|
+
enumerable: true,
|
|
25
|
+
get: function () { return baseControllers.CONFIRMATION_STRATEGY; }
|
|
26
|
+
});
|
|
27
|
+
exports.BUTTON_POSITION = BUTTON_POSITION;
|
|
28
|
+
exports.EMBED_BUILD_ENV = EMBED_BUILD_ENV;
|
|
29
|
+
exports.EXTERNAL_LOGIN_PROVIDER = EXTERNAL_LOGIN_PROVIDER;
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
/* eslint-disable @typescript-eslint/no-explicit-any */
|
|
4
|
+
function isStream(stream) {
|
|
5
|
+
return stream !== null && typeof stream === "object" && typeof stream.pipe === "function";
|
|
6
|
+
}
|
|
7
|
+
function isWritableStream(stream) {
|
|
8
|
+
return isStream(stream) && stream.writable !== false && typeof stream._write === "function" && typeof stream._writableState === "object";
|
|
9
|
+
}
|
|
10
|
+
function isReadableStream(stream) {
|
|
11
|
+
return isStream(stream) && stream.readable !== false && typeof stream._read === "function" && typeof stream._readableState === "object";
|
|
12
|
+
}
|
|
13
|
+
function isDuplexStream(stream) {
|
|
14
|
+
return isWritableStream(stream) && isReadableStream(stream);
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
exports.isDuplexStream = isDuplexStream;
|
|
18
|
+
exports.isReadableStream = isReadableStream;
|
|
19
|
+
exports.isStream = isStream;
|
|
20
|
+
exports.isWritableStream = isWritableStream;
|
|
@@ -0,0 +1,212 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
var _defineProperty = require('@babel/runtime/helpers/defineProperty');
|
|
4
|
+
var dequal = require('fast-deep-equal');
|
|
5
|
+
var rxjs = require('rxjs');
|
|
6
|
+
var auth = require('../../common/src/realm/messaging/auth.js');
|
|
7
|
+
var types = require('../../common/src/realm/messaging/types.js');
|
|
8
|
+
var error = require('./error.js');
|
|
9
|
+
var loglevel = require('./loglevel.js');
|
|
10
|
+
|
|
11
|
+
const REALM_EMBED_MESSAGES = [types.AirMessageTypes.LOGIN_CLAIM_STATE, types.AirMessageTypes.CLOSE_MODAL, types.AirMessageTypes.SERVICE_INITIALIZED, types.AirMessageTypes.SERVICE_INITIALIZED_ERROR, types.AirMessageTypes.DEPLOY_SMART_ACCOUNT_RESPONSE];
|
|
12
|
+
const AUTH_EMBED_MESSAGES = [auth.AirAuthMessageTypes.LOGIN_RESPONSE, auth.AirAuthMessageTypes.USER_INFO_RESPONSE, auth.AirAuthMessageTypes.PARTNER_USER_INFO_RESPONSE, auth.AirAuthMessageTypes.REFRESH_TOKEN_RESPONSE, auth.AirAuthMessageTypes.INITIALIZATION_RESPONSE, auth.AirAuthMessageTypes.LOGOUT_RESPONSE, auth.AirAuthMessageTypes.IFRAME_VISIBILITY_REQUEST, auth.AirAuthMessageTypes.SETUP_WALLET_REQUEST];
|
|
13
|
+
class AirMessageService {
|
|
14
|
+
constructor() {
|
|
15
|
+
_defineProperty(this, "airMessages$", void 0);
|
|
16
|
+
_defineProperty(this, "_loginState$", void 0);
|
|
17
|
+
_defineProperty(this, "_authMessage$", void 0);
|
|
18
|
+
_defineProperty(this, "_authIframe", null);
|
|
19
|
+
_defineProperty(this, "closeAuthMessageListeners", null);
|
|
20
|
+
_defineProperty(this, "closeRealmMessageListeners", null);
|
|
21
|
+
}
|
|
22
|
+
static get instance() {
|
|
23
|
+
if (!AirMessageService._instance) {
|
|
24
|
+
AirMessageService._instance = new AirMessageService();
|
|
25
|
+
}
|
|
26
|
+
return AirMessageService._instance;
|
|
27
|
+
}
|
|
28
|
+
get messages$() {
|
|
29
|
+
return this.airMessages$.asObservable();
|
|
30
|
+
}
|
|
31
|
+
get loginState$() {
|
|
32
|
+
return this._loginState$;
|
|
33
|
+
}
|
|
34
|
+
get authMessage$() {
|
|
35
|
+
return this._authMessage$.asObservable();
|
|
36
|
+
}
|
|
37
|
+
async openAuthObservables({
|
|
38
|
+
authIframeOrigin
|
|
39
|
+
}) {
|
|
40
|
+
this.closeAuthObservables();
|
|
41
|
+
this.setupAuthObservables();
|
|
42
|
+
const handleAuthMessage = async ev => {
|
|
43
|
+
if (ev.origin !== authIframeOrigin || !ev.data || !(ev.data instanceof Object)) return;
|
|
44
|
+
loglevel.debug("Embed auth message received from auth", ev.data);
|
|
45
|
+
if (AUTH_EMBED_MESSAGES.includes(ev.data.type)) {
|
|
46
|
+
this._authMessage$.next(ev.data);
|
|
47
|
+
}
|
|
48
|
+
};
|
|
49
|
+
window.addEventListener("message", handleAuthMessage);
|
|
50
|
+
this.closeAuthMessageListeners = () => {
|
|
51
|
+
window.removeEventListener("message", handleAuthMessage);
|
|
52
|
+
};
|
|
53
|
+
}
|
|
54
|
+
async openRealmObservables({
|
|
55
|
+
walletIframeOrigin
|
|
56
|
+
}) {
|
|
57
|
+
this.closeRealmObservables();
|
|
58
|
+
this.setupRealmObservables();
|
|
59
|
+
const handleMessage = async ev => {
|
|
60
|
+
if (ev.origin !== walletIframeOrigin || !ev.data || !(ev.data instanceof Object)) return;
|
|
61
|
+
// filter out torus and communication provider messages
|
|
62
|
+
if ("target" in ev.data && (ev.data.target === "embed_torus" || ev.data.target === "embed_communication")) return;
|
|
63
|
+
loglevel.debug("Embed realm message received from wallet", ev.data);
|
|
64
|
+
if (REALM_EMBED_MESSAGES.includes(ev.data.type)) {
|
|
65
|
+
this.airMessages$.next(ev.data);
|
|
66
|
+
}
|
|
67
|
+
};
|
|
68
|
+
window.addEventListener("message", handleMessage);
|
|
69
|
+
this.closeRealmMessageListeners = () => {
|
|
70
|
+
window.removeEventListener("message", handleMessage);
|
|
71
|
+
};
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
// Note: Only use when embed is needed in airAuth
|
|
75
|
+
setupAuthIframe(authIframe) {
|
|
76
|
+
this._authIframe = authIframe;
|
|
77
|
+
}
|
|
78
|
+
setupIframeCommunication(walletIframe) {
|
|
79
|
+
if (!this._authIframe) return;
|
|
80
|
+
const channel = new MessageChannel();
|
|
81
|
+
const authOrigin = new URL(this._authIframe.src).origin;
|
|
82
|
+
this._authIframe.contentWindow.postMessage({
|
|
83
|
+
type: auth.AirAuthMessageTypes.INIT_WALLET_COMMUNICATION
|
|
84
|
+
}, authOrigin, [channel.port1]);
|
|
85
|
+
const walletOrigin = new URL(walletIframe.src).origin;
|
|
86
|
+
walletIframe.contentWindow.postMessage({
|
|
87
|
+
type: types.AirMessageTypes.INIT_AUTH_COMMUNICATION
|
|
88
|
+
}, walletOrigin, [channel.port2]);
|
|
89
|
+
this._authIframe = undefined;
|
|
90
|
+
}
|
|
91
|
+
onInitialized() {
|
|
92
|
+
return rxjs.firstValueFrom(this.messages$.pipe(rxjs.filter(msg => msg.type === types.AirMessageTypes.SERVICE_INITIALIZED)));
|
|
93
|
+
}
|
|
94
|
+
sendLoginRequest(walletIframe, payload) {
|
|
95
|
+
const response = rxjs.lastValueFrom(this.loginState$.pipe(rxjs.takeWhile(msg => (!payload.skipClaimFlow || msg.payload.state !== "connected") && msg.payload.state !== "logged_in" && msg.payload.state !== "claim_flow_cancelled", true), rxjs.tap(msg => {
|
|
96
|
+
switch (msg.payload.state) {
|
|
97
|
+
case "claim_flow_cancelled":
|
|
98
|
+
throw new error.RealmEmbedError(msg.payload.errorName, msg.payload.errorMessage);
|
|
99
|
+
}
|
|
100
|
+
})));
|
|
101
|
+
const {
|
|
102
|
+
origin
|
|
103
|
+
} = new URL(walletIframe.src);
|
|
104
|
+
walletIframe.contentWindow.postMessage({
|
|
105
|
+
type: types.AirMessageTypes.LOGIN_REQUEST,
|
|
106
|
+
payload
|
|
107
|
+
}, origin);
|
|
108
|
+
return response;
|
|
109
|
+
}
|
|
110
|
+
sendClaimRequest(walletIframe, options) {
|
|
111
|
+
const response = rxjs.lastValueFrom(rxjs.forkJoin([this.loginState$.pipe(rxjs.takeWhile(msg => !["logged_in", "claim_flow_cancelled"].includes(msg.payload.state), true), rxjs.tap(msg => {
|
|
112
|
+
if (msg.payload.state === "claim_flow_cancelled") {
|
|
113
|
+
throw new error.RealmEmbedError(msg.payload.errorName, msg.payload.errorMessage);
|
|
114
|
+
}
|
|
115
|
+
}), rxjs.last()), this.messages$.pipe(rxjs.filter(msg => msg.type === types.AirMessageTypes.CLOSE_MODAL), rxjs.first())]));
|
|
116
|
+
const {
|
|
117
|
+
origin
|
|
118
|
+
} = new URL(walletIframe.src);
|
|
119
|
+
walletIframe.contentWindow.postMessage({
|
|
120
|
+
type: types.AirMessageTypes.CLAIM_REQUEST,
|
|
121
|
+
payload: {
|
|
122
|
+
token: options === null || options === void 0 ? void 0 : options.token,
|
|
123
|
+
claimInBackground: options === null || options === void 0 ? void 0 : options.background
|
|
124
|
+
}
|
|
125
|
+
}, origin);
|
|
126
|
+
return response;
|
|
127
|
+
}
|
|
128
|
+
sendDeploySmartAccountRequest(walletIframe) {
|
|
129
|
+
const response = rxjs.firstValueFrom(this.messages$.pipe(rxjs.filter(msg => msg.type === types.AirMessageTypes.DEPLOY_SMART_ACCOUNT_RESPONSE)));
|
|
130
|
+
const {
|
|
131
|
+
origin
|
|
132
|
+
} = new URL(walletIframe.src);
|
|
133
|
+
walletIframe.contentWindow.postMessage({
|
|
134
|
+
type: types.AirMessageTypes.DEPLOY_SMART_ACCOUNT_REQUEST
|
|
135
|
+
}, origin);
|
|
136
|
+
return response;
|
|
137
|
+
}
|
|
138
|
+
async sendUserInfoRequest(authIframe) {
|
|
139
|
+
const response = rxjs.firstValueFrom(this.authMessage$.pipe(rxjs.filter(msg => msg.type === auth.AirAuthMessageTypes.USER_INFO_RESPONSE)));
|
|
140
|
+
const {
|
|
141
|
+
origin
|
|
142
|
+
} = new URL(authIframe.src);
|
|
143
|
+
authIframe.contentWindow.postMessage({
|
|
144
|
+
type: auth.AirAuthMessageTypes.USER_INFO_REQUEST
|
|
145
|
+
}, origin);
|
|
146
|
+
return response;
|
|
147
|
+
}
|
|
148
|
+
async sendPartnerUserInfoRequest(authIframe) {
|
|
149
|
+
const response = rxjs.firstValueFrom(this.authMessage$.pipe(rxjs.filter(msg => msg.type === auth.AirAuthMessageTypes.PARTNER_USER_INFO_RESPONSE)));
|
|
150
|
+
const {
|
|
151
|
+
origin
|
|
152
|
+
} = new URL(authIframe.src);
|
|
153
|
+
authIframe.contentWindow.postMessage({
|
|
154
|
+
type: auth.AirAuthMessageTypes.PARTNER_USER_INFO_REQUEST
|
|
155
|
+
}, origin);
|
|
156
|
+
return response;
|
|
157
|
+
}
|
|
158
|
+
async sendAuthLoginRequest(authIframe, payload) {
|
|
159
|
+
const response = rxjs.firstValueFrom(this.authMessage$.pipe(rxjs.filter(msg => msg.type === auth.AirAuthMessageTypes.LOGIN_RESPONSE)));
|
|
160
|
+
const {
|
|
161
|
+
origin
|
|
162
|
+
} = new URL(authIframe.src);
|
|
163
|
+
authIframe.contentWindow.postMessage({
|
|
164
|
+
type: auth.AirAuthMessageTypes.LOGIN_REQUEST,
|
|
165
|
+
payload
|
|
166
|
+
}, origin);
|
|
167
|
+
return response;
|
|
168
|
+
}
|
|
169
|
+
async logoutAuth(authIframe) {
|
|
170
|
+
const response = rxjs.firstValueFrom(this.authMessage$.pipe(rxjs.filter(msg => msg.type === auth.AirAuthMessageTypes.LOGOUT_RESPONSE)));
|
|
171
|
+
const {
|
|
172
|
+
origin
|
|
173
|
+
} = new URL(authIframe.src);
|
|
174
|
+
authIframe.contentWindow.postMessage({
|
|
175
|
+
type: auth.AirAuthMessageTypes.LOGOUT_REQUEST
|
|
176
|
+
}, origin);
|
|
177
|
+
return response;
|
|
178
|
+
}
|
|
179
|
+
async waitForAuthInitialization() {
|
|
180
|
+
const response = await rxjs.firstValueFrom(this._authMessage$.pipe(rxjs.filter(msg => msg.type === auth.AirAuthMessageTypes.INITIALIZATION_RESPONSE)));
|
|
181
|
+
if (response.payload.success === false) {
|
|
182
|
+
throw new error.RealmEmbedError(response.payload.errorName, response.payload.errorMessage);
|
|
183
|
+
}
|
|
184
|
+
return response.payload;
|
|
185
|
+
}
|
|
186
|
+
async waitForWalletInitialization() {
|
|
187
|
+
const response = await rxjs.firstValueFrom(this.messages$.pipe(rxjs.filter(msg => msg.type === types.AirMessageTypes.SERVICE_INITIALIZED || msg.type === types.AirMessageTypes.SERVICE_INITIALIZED_ERROR)));
|
|
188
|
+
if (response.type === types.AirMessageTypes.SERVICE_INITIALIZED_ERROR) {
|
|
189
|
+
throw new error.RealmEmbedError(response.payload.errorName, response.payload.errorMessage);
|
|
190
|
+
}
|
|
191
|
+
}
|
|
192
|
+
closeAuthObservables() {
|
|
193
|
+
if (this._authMessage$ && !this._authMessage$.closed) this._authMessage$.complete();
|
|
194
|
+
if (this.closeAuthMessageListeners) this.closeAuthMessageListeners();
|
|
195
|
+
}
|
|
196
|
+
closeRealmObservables() {
|
|
197
|
+
if (this.airMessages$ && !this.airMessages$.closed) this.airMessages$.complete();
|
|
198
|
+
if (this.closeRealmMessageListeners) this.closeRealmMessageListeners();
|
|
199
|
+
}
|
|
200
|
+
setupAuthObservables() {
|
|
201
|
+
this._authMessage$ = new rxjs.Subject();
|
|
202
|
+
}
|
|
203
|
+
setupRealmObservables() {
|
|
204
|
+
this.airMessages$ = new rxjs.Subject();
|
|
205
|
+
this._loginState$ = this.airMessages$.pipe(rxjs.filter(msg => msg.type === types.AirMessageTypes.LOGIN_CLAIM_STATE), rxjs.distinctUntilChanged(dequal));
|
|
206
|
+
}
|
|
207
|
+
}
|
|
208
|
+
// eslint-disable-next-line no-use-before-define
|
|
209
|
+
_defineProperty(AirMessageService, "_instance", void 0);
|
|
210
|
+
var AirMessageService$1 = AirMessageService.instance;
|
|
211
|
+
|
|
212
|
+
module.exports = AirMessageService$1;
|