@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.
Files changed (80) hide show
  1. package/README.md +177 -0
  2. package/dist/airkit.cjs.js +2662 -0
  3. package/dist/airkit.esm.js +2468 -0
  4. package/dist/airkit.umd.min.js +2 -0
  5. package/dist/airkit.umd.min.js.LICENSE.txt +12 -0
  6. package/dist/lib.cjs/common/src/error.js +25 -0
  7. package/dist/lib.cjs/common/src/realm/messaging/auth.js +28 -0
  8. package/dist/lib.cjs/common/src/realm/messaging/types.js +15 -0
  9. package/dist/lib.cjs/ws-embed/src/PopupHandler.js +64 -0
  10. package/dist/lib.cjs/ws-embed/src/airService.js +364 -0
  11. package/dist/lib.cjs/ws-embed/src/baseProvider.js +178 -0
  12. package/dist/lib.cjs/ws-embed/src/communicationProvider.js +346 -0
  13. package/dist/lib.cjs/ws-embed/src/embed.js +735 -0
  14. package/dist/lib.cjs/ws-embed/src/error.js +21 -0
  15. package/dist/lib.cjs/ws-embed/src/iframeController.js +68 -0
  16. package/dist/lib.cjs/ws-embed/src/inPageProvider.js +307 -0
  17. package/dist/lib.cjs/ws-embed/src/index.js +20 -0
  18. package/dist/lib.cjs/ws-embed/src/interfaces.js +29 -0
  19. package/dist/lib.cjs/ws-embed/src/isStream.js +20 -0
  20. package/dist/lib.cjs/ws-embed/src/loglevel.js +7 -0
  21. package/dist/lib.cjs/ws-embed/src/messageService.js +212 -0
  22. package/dist/lib.cjs/ws-embed/src/messages.js +22 -0
  23. package/dist/lib.cjs/ws-embed/src/siteMetadata.js +77 -0
  24. package/dist/lib.cjs/ws-embed/src/utils.js +95 -0
  25. package/dist/lib.esm/common/src/error.js +23 -0
  26. package/dist/lib.esm/common/src/realm/messaging/auth.js +26 -0
  27. package/dist/lib.esm/common/src/realm/messaging/types.js +13 -0
  28. package/dist/lib.esm/ws-embed/src/PopupHandler.js +62 -0
  29. package/dist/lib.esm/ws-embed/src/airService.js +362 -0
  30. package/dist/lib.esm/ws-embed/src/baseProvider.js +176 -0
  31. package/dist/lib.esm/ws-embed/src/communicationProvider.js +344 -0
  32. package/dist/lib.esm/ws-embed/src/embed.js +730 -0
  33. package/dist/lib.esm/ws-embed/src/error.js +18 -0
  34. package/dist/lib.esm/ws-embed/src/iframeController.js +66 -0
  35. package/dist/lib.esm/ws-embed/src/inPageProvider.js +302 -0
  36. package/dist/lib.esm/ws-embed/src/index.js +5 -0
  37. package/dist/lib.esm/ws-embed/src/interfaces.js +21 -0
  38. package/dist/lib.esm/ws-embed/src/isStream.js +15 -0
  39. package/dist/lib.esm/ws-embed/src/loglevel.js +5 -0
  40. package/dist/lib.esm/ws-embed/src/messageService.js +210 -0
  41. package/dist/lib.esm/ws-embed/src/messages.js +20 -0
  42. package/dist/lib.esm/ws-embed/src/siteMetadata.js +75 -0
  43. package/dist/lib.esm/ws-embed/src/utils.js +88 -0
  44. package/dist/types/PopupHandler.d.ts +24 -0
  45. package/dist/types/airService.d.ts +34 -0
  46. package/dist/types/baseProvider.d.ts +66 -0
  47. package/dist/types/common/custom.d.ts +4 -0
  48. package/dist/types/common/error.d.ts +17 -0
  49. package/dist/types/common/realm/error/auth.d.ts +1 -0
  50. package/dist/types/common/realm/error/types.d.ts +1 -0
  51. package/dist/types/common/realm/messaging/auth.d.ts +138 -0
  52. package/dist/types/common/realm/messaging/types.d.ts +95 -0
  53. package/dist/types/common/realm/partner/config.d.ts +68 -0
  54. package/dist/types/common/realm/user/types.d.ts +78 -0
  55. package/dist/types/common/realm/wallet/bybit/bybit.d.ts +2 -0
  56. package/dist/types/common/realm/wallet/coinbase/coinbase.d.ts +2 -0
  57. package/dist/types/common/realm/wallet/cryptoCom/cryptoCom.d.ts +2 -0
  58. package/dist/types/common/realm/wallet/index.d.ts +22 -0
  59. package/dist/types/common/realm/wallet/metamask/metamask.d.ts +2 -0
  60. package/dist/types/common/realm/wallet/okx/okx.d.ts +2 -0
  61. package/dist/types/common/realm/wallet/phantom/phantom.d.ts +2 -0
  62. package/dist/types/common/realm/wallet/rabby/rabby.d.ts +2 -0
  63. package/dist/types/common/realm/wallet/rainbow/rainbow.d.ts +2 -0
  64. package/dist/types/common/realm/wallet/trust/trust.d.ts +2 -0
  65. package/dist/types/common/types.d.ts +8 -0
  66. package/dist/types/common/utils.d.ts +2 -0
  67. package/dist/types/communicationProvider.d.ts +82 -0
  68. package/dist/types/embed.d.ts +42 -0
  69. package/dist/types/error.d.ts +9 -0
  70. package/dist/types/iframeController.d.ts +18 -0
  71. package/dist/types/inPageProvider.d.ts +106 -0
  72. package/dist/types/index.d.ts +4 -0
  73. package/dist/types/interfaces.d.ts +261 -0
  74. package/dist/types/isStream.d.ts +4 -0
  75. package/dist/types/loglevel.d.ts +3 -0
  76. package/dist/types/messageService.d.ts +51 -0
  77. package/dist/types/messages.d.ts +19 -0
  78. package/dist/types/siteMetadata.d.ts +9 -0
  79. package/dist/types/utils.d.ts +24 -0
  80. 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,7 @@
1
+ 'use strict';
2
+
3
+ var loglevel = require('loglevel');
4
+
5
+ var log = loglevel.getLogger("ws-embed");
6
+
7
+ module.exports = log;
@@ -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;