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