@dynamic-labs/global-wallet-client 4.0.0-alpha.51 → 4.0.0-alpha.52

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/CHANGELOG.md CHANGED
@@ -1,4 +1,6 @@
1
1
 
2
+ ## [4.0.0-alpha.52](https://github.com/dynamic-labs/dynamic-auth/compare/v4.0.0-alpha.51...v4.0.0-alpha.52) (2025-01-02)
3
+
2
4
  ## [4.0.0-alpha.51](https://github.com/dynamic-labs/dynamic-auth/compare/v4.0.0-alpha.50...v4.0.0-alpha.51) (2024-12-30)
3
5
 
4
6
 
package/package.cjs CHANGED
@@ -3,6 +3,6 @@
3
3
 
4
4
  Object.defineProperty(exports, '__esModule', { value: true });
5
5
 
6
- var version = "4.0.0-alpha.51";
6
+ var version = "4.0.0-alpha.52";
7
7
 
8
8
  exports.version = version;
package/package.js CHANGED
@@ -1,4 +1,4 @@
1
1
  'use client'
2
- var version = "4.0.0-alpha.51";
2
+ var version = "4.0.0-alpha.52";
3
3
 
4
4
  export { version };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@dynamic-labs/global-wallet-client",
3
- "version": "4.0.0-alpha.51",
3
+ "version": "4.0.0-alpha.52",
4
4
  "description": "Core package for building Dynamic's Global Wallet",
5
5
  "author": "Dynamic Labs, Inc.",
6
6
  "license": "MIT",
@@ -31,11 +31,11 @@
31
31
  },
32
32
  "homepage": "https://www.dynamic.xyz/",
33
33
  "dependencies": {
34
- "@dynamic-labs/assert-package-version": "4.0.0-alpha.51",
35
- "@dynamic-labs/logger": "4.0.0-alpha.51",
36
- "@dynamic-labs/store": "4.0.0-alpha.51",
37
- "@dynamic-labs/types": "4.0.0-alpha.51",
38
- "@dynamic-labs/utils": "4.0.0-alpha.51",
34
+ "@dynamic-labs/assert-package-version": "4.0.0-alpha.52",
35
+ "@dynamic-labs/logger": "4.0.0-alpha.52",
36
+ "@dynamic-labs/store": "4.0.0-alpha.52",
37
+ "@dynamic-labs/types": "4.0.0-alpha.52",
38
+ "@dynamic-labs/utils": "4.0.0-alpha.52",
39
39
  "eventemitter3": "5.0.1"
40
40
  },
41
41
  "peerDependencies": {
@@ -20,18 +20,19 @@ const createConnectAction = ({ store, openPopup, onConnect }) => (_a) => _tslib.
20
20
  const sharedSecret = yield utils.deriveSharedSecret(keyPair.privateKey, yield utils.convertPublicKeyHexToCryptoKey(providerPublicKey));
21
21
  const message = yield utils.decryptMessage(sharedSecret, encryptedMessage, iv);
22
22
  const { network, wallet } = JSON.parse(message);
23
- const connection = {
24
- evm: {
25
- network,
23
+ store.setInitialConnectionState({
24
+ connection: {
25
+ expiresAt,
26
+ origin: window.location.origin,
27
+ sharedSecret,
28
+ },
29
+ ethereum: {
30
+ currentNetworkId: network,
26
31
  supportedNetworks: [],
27
- wallets: [wallet],
28
32
  },
29
- expiresAt,
30
- sharedSecret,
31
- solana: null,
32
- };
33
- store.setConnection(connection);
34
- onConnect === null || onConnect === void 0 ? void 0 : onConnect(connection);
33
+ wallets: [wallet],
34
+ });
35
+ onConnect === null || onConnect === void 0 ? void 0 : onConnect();
35
36
  return wallet;
36
37
  });
37
38
 
@@ -1,10 +1,10 @@
1
1
  import { ClientStore } from '../../store';
2
2
  import { OpenPopup } from '../../functions/createPopupOpener/createPopupOpener';
3
- import { ConnectArgs, Connection } from '../../types';
3
+ import { ConnectArgs } from '../../types';
4
4
  type CreateConnectActionProps = {
5
5
  store: ClientStore;
6
6
  openPopup: OpenPopup;
7
- onConnect?: (connection: Connection) => void;
7
+ onConnect?: () => void;
8
8
  };
9
9
  export declare const createConnectAction: ({ store, openPopup, onConnect }: CreateConnectActionProps) => ({ chain }: ConnectArgs) => Promise<import("@dynamic-labs/types").BaseWallet>;
10
10
  export {};
@@ -16,18 +16,19 @@ const createConnectAction = ({ store, openPopup, onConnect }) => (_a) => __await
16
16
  const sharedSecret = yield deriveSharedSecret(keyPair.privateKey, yield convertPublicKeyHexToCryptoKey(providerPublicKey));
17
17
  const message = yield decryptMessage(sharedSecret, encryptedMessage, iv);
18
18
  const { network, wallet } = JSON.parse(message);
19
- const connection = {
20
- evm: {
21
- network,
19
+ store.setInitialConnectionState({
20
+ connection: {
21
+ expiresAt,
22
+ origin: window.location.origin,
23
+ sharedSecret,
24
+ },
25
+ ethereum: {
26
+ currentNetworkId: network,
22
27
  supportedNetworks: [],
23
- wallets: [wallet],
24
28
  },
25
- expiresAt,
26
- sharedSecret,
27
- solana: null,
28
- };
29
- store.setConnection(connection);
30
- onConnect === null || onConnect === void 0 ? void 0 : onConnect(connection);
29
+ wallets: [wallet],
30
+ });
31
+ onConnect === null || onConnect === void 0 ? void 0 : onConnect();
31
32
  return wallet;
32
33
  });
33
34
 
@@ -8,6 +8,7 @@ var createPopupOpener = require('./functions/createPopupOpener/createPopupOpener
8
8
  var createClientStore = require('./store/createClientStore.cjs');
9
9
  var createClientEventEmitter = require('./functions/createClientEventEmitter/createClientEventEmitter.cjs');
10
10
  var createDisconnectAction = require('./actions/disconnectAction/createDisconnectAction.cjs');
11
+ var createEthereumModule = require('./functions/createEthereumModule/createEthereumModule.cjs');
11
12
 
12
13
  const createGlobalWalletClient = ({ environmentId, popup: popupInfo, }) => {
13
14
  const eventEmitter = createClientEventEmitter.createClientEventEmitter();
@@ -25,18 +26,15 @@ const createGlobalWalletClient = ({ environmentId, popup: popupInfo, }) => {
25
26
  return {
26
27
  connect,
27
28
  disconnect,
28
- get ethereum() {
29
- var _a, _b;
30
- return (_b = (_a = store.getActiveConnection()) === null || _a === void 0 ? void 0 : _a.evm) !== null && _b !== void 0 ? _b : null;
31
- },
29
+ ethereum: createEthereumModule.createEthereumModule({ store }),
32
30
  invoke: openPopup,
33
31
  off: eventEmitter.off.bind(eventEmitter),
34
32
  on: eventEmitter.on.bind(eventEmitter),
35
33
  once: eventEmitter.once.bind(eventEmitter),
36
34
  removeAllListeners: eventEmitter.removeAllListeners.bind(eventEmitter),
37
35
  removeListener: eventEmitter.removeListener.bind(eventEmitter),
38
- get userWallets() {
39
- return store.userWallets;
36
+ get wallets() {
37
+ return store.wallets;
40
38
  },
41
39
  };
42
40
  };
@@ -6,13 +6,13 @@ export type CreateGlobalWalletClientProps = {
6
6
  export declare const createGlobalWalletClient: ({ environmentId, popup: popupInfo, }: CreateGlobalWalletClientProps) => {
7
7
  connect: ({ chain }: import("./types").ConnectArgs) => Promise<import("dist/packages/types/src").BaseWallet>;
8
8
  disconnect: () => void;
9
- readonly ethereum: {
10
- supportedNetworks: {
9
+ ethereum: {
10
+ readonly currentNetworkId: number | null;
11
+ readonly supportedNetworks: {
11
12
  chainId: number;
12
13
  }[];
13
- wallets: import("dist/packages/types/src").BaseWallet[];
14
- network: string;
15
- } | null;
14
+ readonly wallets: import("dist/packages/types/src").BaseWallet[];
15
+ };
16
16
  invoke: <TPopupAction extends import("dist/packages/types/src").IPopupAction>({ params, pathname, }: {
17
17
  params: import("dist/packages/types/src").GetPopupActionFuncArgs<TPopupAction>;
18
18
  pathname: import("dist/packages/types/src").GetPopupActionName<TPopupAction>;
@@ -49,6 +49,6 @@ export declare const createGlobalWalletClient: ({ environmentId, popup: popupInf
49
49
  connect: () => void;
50
50
  disconnect: () => void;
51
51
  }, any>;
52
- readonly userWallets: import("dist/packages/types/src").BaseWallet[];
52
+ readonly wallets: import("dist/packages/types/src").BaseWallet[];
53
53
  };
54
54
  export type GlobalWalletClient = ReturnType<typeof createGlobalWalletClient>;
@@ -4,6 +4,7 @@ import { createPopupOpener } from './functions/createPopupOpener/createPopupOpen
4
4
  import { createClientStore } from './store/createClientStore.js';
5
5
  import { createClientEventEmitter } from './functions/createClientEventEmitter/createClientEventEmitter.js';
6
6
  import { createDisconnectAction } from './actions/disconnectAction/createDisconnectAction.js';
7
+ import { createEthereumModule } from './functions/createEthereumModule/createEthereumModule.js';
7
8
 
8
9
  const createGlobalWalletClient = ({ environmentId, popup: popupInfo, }) => {
9
10
  const eventEmitter = createClientEventEmitter();
@@ -21,18 +22,15 @@ const createGlobalWalletClient = ({ environmentId, popup: popupInfo, }) => {
21
22
  return {
22
23
  connect,
23
24
  disconnect,
24
- get ethereum() {
25
- var _a, _b;
26
- return (_b = (_a = store.getActiveConnection()) === null || _a === void 0 ? void 0 : _a.evm) !== null && _b !== void 0 ? _b : null;
27
- },
25
+ ethereum: createEthereumModule({ store }),
28
26
  invoke: openPopup,
29
27
  off: eventEmitter.off.bind(eventEmitter),
30
28
  on: eventEmitter.on.bind(eventEmitter),
31
29
  once: eventEmitter.once.bind(eventEmitter),
32
30
  removeAllListeners: eventEmitter.removeAllListeners.bind(eventEmitter),
33
31
  removeListener: eventEmitter.removeListener.bind(eventEmitter),
34
- get userWallets() {
35
- return store.userWallets;
32
+ get wallets() {
33
+ return store.wallets;
36
34
  },
37
35
  };
38
36
  };
@@ -12,11 +12,11 @@ const createEIP1193Provider = (client) => {
12
12
  const eventEmitter = new eventemitter3.EventEmitter();
13
13
  client.on('connect', () => {
14
14
  var _a;
15
- const chainId = (_a = client.ethereum) === null || _a === void 0 ? void 0 : _a.network;
16
- if (!chainId)
15
+ const currentNetwork = (_a = client.ethereum) === null || _a === void 0 ? void 0 : _a.currentNetworkId;
16
+ if (!currentNetwork)
17
17
  return;
18
18
  eventEmitter.emit('connect', {
19
- chainId: viem.toHex(parseInt(chainId, 10)),
19
+ chainId: viem.toHex(currentNetwork),
20
20
  });
21
21
  });
22
22
  client.on('disconnect', () => {
@@ -26,7 +26,7 @@ const createEIP1193Provider = (client) => {
26
26
  on: eventEmitter.on.bind(eventEmitter),
27
27
  removeListener: eventEmitter.removeListener.bind(eventEmitter),
28
28
  request: ((_a) => _tslib.__awaiter(void 0, [_a], void 0, function* ({ method, params }) {
29
- var _b, _c, _d;
29
+ var _b, _c, _d, _e;
30
30
  const wallets = (_c = (_b = client === null || client === void 0 ? void 0 : client.ethereum) === null || _b === void 0 ? void 0 : _b.wallets) !== null && _c !== void 0 ? _c : [];
31
31
  const connectedAddresses = wallets.map((wallet) => wallet.address);
32
32
  // Define if user is connected with ethereum wallets
@@ -55,7 +55,10 @@ const createEIP1193Provider = (client) => {
55
55
  .then(({ address }) => [address]);
56
56
  }
57
57
  if (method === 'eth_chainId') {
58
- return (_d = client.ethereum) === null || _d === void 0 ? void 0 : _d.network;
58
+ if ((_d = client.ethereum) === null || _d === void 0 ? void 0 : _d.currentNetworkId) {
59
+ return viem.toHex((_e = client.ethereum) === null || _e === void 0 ? void 0 : _e.currentNetworkId);
60
+ }
61
+ return null;
59
62
  }
60
63
  /**
61
64
  * Opens the popup to request user confirmation for the request
@@ -8,11 +8,11 @@ const createEIP1193Provider = (client) => {
8
8
  const eventEmitter = new EventEmitter();
9
9
  client.on('connect', () => {
10
10
  var _a;
11
- const chainId = (_a = client.ethereum) === null || _a === void 0 ? void 0 : _a.network;
12
- if (!chainId)
11
+ const currentNetwork = (_a = client.ethereum) === null || _a === void 0 ? void 0 : _a.currentNetworkId;
12
+ if (!currentNetwork)
13
13
  return;
14
14
  eventEmitter.emit('connect', {
15
- chainId: toHex(parseInt(chainId, 10)),
15
+ chainId: toHex(currentNetwork),
16
16
  });
17
17
  });
18
18
  client.on('disconnect', () => {
@@ -22,7 +22,7 @@ const createEIP1193Provider = (client) => {
22
22
  on: eventEmitter.on.bind(eventEmitter),
23
23
  removeListener: eventEmitter.removeListener.bind(eventEmitter),
24
24
  request: ((_a) => __awaiter(void 0, [_a], void 0, function* ({ method, params }) {
25
- var _b, _c, _d;
25
+ var _b, _c, _d, _e;
26
26
  const wallets = (_c = (_b = client === null || client === void 0 ? void 0 : client.ethereum) === null || _b === void 0 ? void 0 : _b.wallets) !== null && _c !== void 0 ? _c : [];
27
27
  const connectedAddresses = wallets.map((wallet) => wallet.address);
28
28
  // Define if user is connected with ethereum wallets
@@ -51,7 +51,10 @@ const createEIP1193Provider = (client) => {
51
51
  .then(({ address }) => [address]);
52
52
  }
53
53
  if (method === 'eth_chainId') {
54
- return (_d = client.ethereum) === null || _d === void 0 ? void 0 : _d.network;
54
+ if ((_d = client.ethereum) === null || _d === void 0 ? void 0 : _d.currentNetworkId) {
55
+ return toHex((_e = client.ethereum) === null || _e === void 0 ? void 0 : _e.currentNetworkId);
56
+ }
57
+ return null;
55
58
  }
56
59
  /**
57
60
  * Opens the popup to request user confirmation for the request
@@ -0,0 +1,21 @@
1
+ 'use client'
2
+ 'use strict';
3
+
4
+ Object.defineProperty(exports, '__esModule', { value: true });
5
+
6
+ const createEthereumModule = ({ store }) => ({
7
+ get currentNetworkId() {
8
+ var _a, _b;
9
+ return (_b = (_a = store.ethereum) === null || _a === void 0 ? void 0 : _a.currentNetworkId) !== null && _b !== void 0 ? _b : null;
10
+ },
11
+ get supportedNetworks() {
12
+ var _a, _b;
13
+ return (_b = (_a = store.ethereum) === null || _a === void 0 ? void 0 : _a.supportedNetworks) !== null && _b !== void 0 ? _b : [];
14
+ },
15
+ get wallets() {
16
+ var _a;
17
+ return (_a = store.wallets.filter(({ chain }) => chain === 'EVM')) !== null && _a !== void 0 ? _a : [];
18
+ },
19
+ });
20
+
21
+ exports.createEthereumModule = createEthereumModule;
@@ -0,0 +1,10 @@
1
+ import { ClientStore } from '../../store';
2
+ export declare const createEthereumModule: ({ store }: {
3
+ store: ClientStore;
4
+ }) => {
5
+ readonly currentNetworkId: number | null;
6
+ readonly supportedNetworks: {
7
+ chainId: number;
8
+ }[];
9
+ readonly wallets: import("dist/packages/types/src").BaseWallet[];
10
+ };
@@ -0,0 +1,17 @@
1
+ 'use client'
2
+ const createEthereumModule = ({ store }) => ({
3
+ get currentNetworkId() {
4
+ var _a, _b;
5
+ return (_b = (_a = store.ethereum) === null || _a === void 0 ? void 0 : _a.currentNetworkId) !== null && _b !== void 0 ? _b : null;
6
+ },
7
+ get supportedNetworks() {
8
+ var _a, _b;
9
+ return (_b = (_a = store.ethereum) === null || _a === void 0 ? void 0 : _a.supportedNetworks) !== null && _b !== void 0 ? _b : [];
10
+ },
11
+ get wallets() {
12
+ var _a;
13
+ return (_a = store.wallets.filter(({ chain }) => chain === 'EVM')) !== null && _a !== void 0 ? _a : [];
14
+ },
15
+ });
16
+
17
+ export { createEthereumModule };
@@ -0,0 +1 @@
1
+ export { createEthereumModule } from './createEthereumModule';
@@ -9,44 +9,82 @@ var waitForPopupResponse = require('../waitForPopupResponse/waitForPopupResponse
9
9
  var onPopupClose = require('../onPopupClose/onPopupClose.cjs');
10
10
  var mergeAndEncryptParams = require('../mergeAndEncryptParams/mergeAndEncryptParams.cjs');
11
11
 
12
- const createPopupOpener = ({ environmentId, popupInfo, store }) => (_a) => _tslib.__awaiter(void 0, [_a], void 0, function* ({ params, pathname, }) {
13
- var _b, _c;
14
- const popupFinalUrl = new URL(popupInfo.url);
15
- const activeConnection = store.getActiveConnection();
16
- const resultDeferredPromise = new utils.DeferredPromise();
17
- const popupWidth = (_b = popupInfo.width) !== null && _b !== void 0 ? _b : 420;
18
- const popupHeight = (_c = popupInfo.height) !== null && _c !== void 0 ? _c : 520;
19
- // Setup popup URL and data
20
- popupFinalUrl.hash = `/${pathname}`;
21
- popupFinalUrl.searchParams.set('provider_env_id', environmentId);
22
- popupFinalUrl.searchParams.set('requester_origin', window.location.origin);
23
- // Encrypt params if active connection is present
24
- if (params) {
25
- yield mergeAndEncryptParams.mergeAndEncryptParams(popupFinalUrl, params, activeConnection);
26
- }
27
- // Open popup
28
- const popup = window.open('', '_blank', `width=${popupWidth},height=${popupHeight}`);
29
- if (popup === null) {
30
- throw new Error('Failed to open popup');
31
- }
32
- waitForPopupResponse.waitForPopupResponse({
33
- decode: (data) => _tslib.__awaiter(void 0, void 0, void 0, function* () {
34
- if (activeConnection && utils.isEncryptedMessage(data)) {
35
- const decryptedData = yield utils.decryptMessage(activeConnection.sharedSecret, data.encryptedMessage, data.iv);
36
- return JSON.parse(decryptedData);
37
- }
38
- return data;
39
- }),
40
- onError: (error) => resultDeferredPromise.reject(error),
41
- onResponse: (response) => resultDeferredPromise.resolve(response.data),
42
- popupUrl: popupFinalUrl.toString(),
12
+ const createPopupOpener = ({ environmentId, popupInfo, store, popupActionTimeout = 100, }) => {
13
+ let popup = null;
14
+ let didOpenPopup = false;
15
+ let lastActionId = null;
16
+ const closePopup = () => {
17
+ popup === null || popup === void 0 ? void 0 : popup.close();
18
+ popup = null;
19
+ didOpenPopup = false;
20
+ lastActionId = null;
21
+ };
22
+ return (_a) => _tslib.__awaiter(void 0, [_a], void 0, function* ({ params, pathname, }) {
23
+ var _b, _c;
24
+ // Used as a unique identifier for the action
25
+ const actionId = new Date().getTime();
26
+ lastActionId = actionId;
27
+ const popupFinalUrl = new URL(popupInfo.url);
28
+ const activeConnection = store.getActiveConnection();
29
+ const resultDeferredPromise = new utils.DeferredPromise();
30
+ const popupWidth = (_b = popupInfo.width) !== null && _b !== void 0 ? _b : 420;
31
+ const popupHeight = (_c = popupInfo.height) !== null && _c !== void 0 ? _c : 520;
32
+ // Setup popup URL and data
33
+ popupFinalUrl.hash = `/${pathname}`;
34
+ popupFinalUrl.searchParams.set('provider_env_id', environmentId);
35
+ popupFinalUrl.searchParams.set('requester_origin', window.location.origin);
36
+ // Encrypt params if active connection is present
37
+ if (params) {
38
+ yield mergeAndEncryptParams.mergeAndEncryptParams(popupFinalUrl, params, activeConnection);
39
+ }
40
+ if (popup === null) {
41
+ // Open popup
42
+ popup = window.open('', '_blank', `width=${popupWidth},height=${popupHeight}`);
43
+ }
44
+ if (popup === null) {
45
+ throw new Error('Failed to open popup');
46
+ }
47
+ waitForPopupResponse.waitForPopupResponse({
48
+ decode: (data) => _tslib.__awaiter(void 0, void 0, void 0, function* () {
49
+ if (activeConnection && utils.isEncryptedMessage(data)) {
50
+ const decryptedData = yield utils.decryptMessage(activeConnection.sharedSecret, data.encryptedMessage, data.iv);
51
+ return JSON.parse(decryptedData);
52
+ }
53
+ return data;
54
+ }),
55
+ onError: (error) => resultDeferredPromise.reject(error),
56
+ onResponse: (response) => resultDeferredPromise.resolve(response.data),
57
+ popupUrl: popupFinalUrl.toString(),
58
+ });
59
+ onPopupClose.onPopupClose(popup, () => {
60
+ resultDeferredPromise.reject(new Error('Popup closed'));
61
+ });
62
+ /**
63
+ * Assign action to popup
64
+ */
65
+ if (didOpenPopup) {
66
+ popup === null || popup === void 0 ? void 0 : popup.postMessage({
67
+ actionPath: popupFinalUrl.search + popupFinalUrl.hash,
68
+ event: 'new-action',
69
+ }, popupFinalUrl.origin);
70
+ }
71
+ else {
72
+ // Load popup
73
+ popup.location.assign(popupFinalUrl.toString());
74
+ }
75
+ didOpenPopup = true;
76
+ return resultDeferredPromise.promise.finally(() => {
77
+ /**
78
+ * Sets a timeout to close the popup.
79
+ * It will only no new actions were fired.
80
+ */
81
+ setTimeout(() => {
82
+ if (lastActionId === actionId) {
83
+ closePopup();
84
+ }
85
+ }, popupActionTimeout);
86
+ });
43
87
  });
44
- onPopupClose.onPopupClose(popup, () => {
45
- resultDeferredPromise.reject(new Error('Popup closed'));
46
- });
47
- // Load popup
48
- popup.location.assign(popupFinalUrl.toString());
49
- return resultDeferredPromise.promise.finally(popup.close);
50
- });
88
+ };
51
89
 
52
90
  exports.createPopupOpener = createPopupOpener;
@@ -5,11 +5,12 @@ type CreatePopupOpenerProps = {
5
5
  environmentId: string;
6
6
  popupInfo: PopupInfo;
7
7
  store: ClientStore;
8
+ popupActionTimeout?: number;
8
9
  };
9
10
  type OpenPopupProps<TAction extends IPopupAction> = {
10
11
  params: GetPopupActionFuncArgs<TAction>;
11
12
  pathname: GetPopupActionName<TAction>;
12
13
  };
13
- export declare const createPopupOpener: ({ environmentId, popupInfo, store }: CreatePopupOpenerProps) => <TPopupAction extends IPopupAction>({ params, pathname, }: OpenPopupProps<TPopupAction>) => Promise<GetPopupActionResult<TPopupAction>>;
14
+ export declare const createPopupOpener: ({ environmentId, popupInfo, store, popupActionTimeout, }: CreatePopupOpenerProps) => <TPopupAction extends IPopupAction>({ params, pathname, }: OpenPopupProps<TPopupAction>) => Promise<GetPopupActionResult<TPopupAction>>;
14
15
  export type OpenPopup = ReturnType<typeof createPopupOpener>;
15
16
  export {};
@@ -5,44 +5,82 @@ import { waitForPopupResponse } from '../waitForPopupResponse/waitForPopupRespon
5
5
  import { onPopupClose } from '../onPopupClose/onPopupClose.js';
6
6
  import { mergeAndEncryptParams } from '../mergeAndEncryptParams/mergeAndEncryptParams.js';
7
7
 
8
- const createPopupOpener = ({ environmentId, popupInfo, store }) => (_a) => __awaiter(void 0, [_a], void 0, function* ({ params, pathname, }) {
9
- var _b, _c;
10
- const popupFinalUrl = new URL(popupInfo.url);
11
- const activeConnection = store.getActiveConnection();
12
- const resultDeferredPromise = new DeferredPromise();
13
- const popupWidth = (_b = popupInfo.width) !== null && _b !== void 0 ? _b : 420;
14
- const popupHeight = (_c = popupInfo.height) !== null && _c !== void 0 ? _c : 520;
15
- // Setup popup URL and data
16
- popupFinalUrl.hash = `/${pathname}`;
17
- popupFinalUrl.searchParams.set('provider_env_id', environmentId);
18
- popupFinalUrl.searchParams.set('requester_origin', window.location.origin);
19
- // Encrypt params if active connection is present
20
- if (params) {
21
- yield mergeAndEncryptParams(popupFinalUrl, params, activeConnection);
22
- }
23
- // Open popup
24
- const popup = window.open('', '_blank', `width=${popupWidth},height=${popupHeight}`);
25
- if (popup === null) {
26
- throw new Error('Failed to open popup');
27
- }
28
- waitForPopupResponse({
29
- decode: (data) => __awaiter(void 0, void 0, void 0, function* () {
30
- if (activeConnection && isEncryptedMessage(data)) {
31
- const decryptedData = yield decryptMessage(activeConnection.sharedSecret, data.encryptedMessage, data.iv);
32
- return JSON.parse(decryptedData);
33
- }
34
- return data;
35
- }),
36
- onError: (error) => resultDeferredPromise.reject(error),
37
- onResponse: (response) => resultDeferredPromise.resolve(response.data),
38
- popupUrl: popupFinalUrl.toString(),
8
+ const createPopupOpener = ({ environmentId, popupInfo, store, popupActionTimeout = 100, }) => {
9
+ let popup = null;
10
+ let didOpenPopup = false;
11
+ let lastActionId = null;
12
+ const closePopup = () => {
13
+ popup === null || popup === void 0 ? void 0 : popup.close();
14
+ popup = null;
15
+ didOpenPopup = false;
16
+ lastActionId = null;
17
+ };
18
+ return (_a) => __awaiter(void 0, [_a], void 0, function* ({ params, pathname, }) {
19
+ var _b, _c;
20
+ // Used as a unique identifier for the action
21
+ const actionId = new Date().getTime();
22
+ lastActionId = actionId;
23
+ const popupFinalUrl = new URL(popupInfo.url);
24
+ const activeConnection = store.getActiveConnection();
25
+ const resultDeferredPromise = new DeferredPromise();
26
+ const popupWidth = (_b = popupInfo.width) !== null && _b !== void 0 ? _b : 420;
27
+ const popupHeight = (_c = popupInfo.height) !== null && _c !== void 0 ? _c : 520;
28
+ // Setup popup URL and data
29
+ popupFinalUrl.hash = `/${pathname}`;
30
+ popupFinalUrl.searchParams.set('provider_env_id', environmentId);
31
+ popupFinalUrl.searchParams.set('requester_origin', window.location.origin);
32
+ // Encrypt params if active connection is present
33
+ if (params) {
34
+ yield mergeAndEncryptParams(popupFinalUrl, params, activeConnection);
35
+ }
36
+ if (popup === null) {
37
+ // Open popup
38
+ popup = window.open('', '_blank', `width=${popupWidth},height=${popupHeight}`);
39
+ }
40
+ if (popup === null) {
41
+ throw new Error('Failed to open popup');
42
+ }
43
+ waitForPopupResponse({
44
+ decode: (data) => __awaiter(void 0, void 0, void 0, function* () {
45
+ if (activeConnection && isEncryptedMessage(data)) {
46
+ const decryptedData = yield decryptMessage(activeConnection.sharedSecret, data.encryptedMessage, data.iv);
47
+ return JSON.parse(decryptedData);
48
+ }
49
+ return data;
50
+ }),
51
+ onError: (error) => resultDeferredPromise.reject(error),
52
+ onResponse: (response) => resultDeferredPromise.resolve(response.data),
53
+ popupUrl: popupFinalUrl.toString(),
54
+ });
55
+ onPopupClose(popup, () => {
56
+ resultDeferredPromise.reject(new Error('Popup closed'));
57
+ });
58
+ /**
59
+ * Assign action to popup
60
+ */
61
+ if (didOpenPopup) {
62
+ popup === null || popup === void 0 ? void 0 : popup.postMessage({
63
+ actionPath: popupFinalUrl.search + popupFinalUrl.hash,
64
+ event: 'new-action',
65
+ }, popupFinalUrl.origin);
66
+ }
67
+ else {
68
+ // Load popup
69
+ popup.location.assign(popupFinalUrl.toString());
70
+ }
71
+ didOpenPopup = true;
72
+ return resultDeferredPromise.promise.finally(() => {
73
+ /**
74
+ * Sets a timeout to close the popup.
75
+ * It will only no new actions were fired.
76
+ */
77
+ setTimeout(() => {
78
+ if (lastActionId === actionId) {
79
+ closePopup();
80
+ }
81
+ }, popupActionTimeout);
82
+ });
39
83
  });
40
- onPopupClose(popup, () => {
41
- resultDeferredPromise.reject(new Error('Popup closed'));
42
- });
43
- // Load popup
44
- popup.location.assign(popupFinalUrl.toString());
45
- return resultDeferredPromise.promise.finally(popup.close);
46
- });
84
+ };
47
85
 
48
86
  export { createPopupOpener };
@@ -1,2 +1,2 @@
1
- import { Connection } from '../../types';
2
- export declare const mergeAndEncryptParams: (url: URL, params: Record<string, string>, activeConnection: Connection | null) => Promise<void>;
1
+ import { GlobalWalletConnection } from '@dynamic-labs/types';
2
+ export declare const mergeAndEncryptParams: (url: URL, params: Record<string, string>, activeConnection: GlobalWalletConnection | null) => Promise<void>;
@@ -12,6 +12,8 @@ const createClientStore = ({ storage = localStorage, } = {}) => {
12
12
  storage,
13
13
  store: store.createStore(() => ({
14
14
  connection: null,
15
+ ethereum: null,
16
+ wallets: [],
15
17
  })),
16
18
  });
17
19
  return {
@@ -21,6 +23,13 @@ const createClientStore = ({ storage = localStorage, } = {}) => {
21
23
  clear: () => {
22
24
  store$1.setState(store$1.getInitialState());
23
25
  },
26
+ /**
27
+ * Get all Ethereum state from the current connection
28
+ */
29
+ get ethereum() {
30
+ this.getActiveConnection();
31
+ return store$1.getState().ethereum;
32
+ },
24
33
  /**
25
34
  * Retrieves the current active connection if it exists and hasn't expired
26
35
  * @returns {Connection | null} The current connection or null if no connection exists or it has expired
@@ -38,28 +47,19 @@ const createClientStore = ({ storage = localStorage, } = {}) => {
38
47
  return connection;
39
48
  },
40
49
  /**
41
- * Updates the connection in the store
42
- * @param {Connection | null} connection - The connection to store, or null to clear it
43
- */
44
- setConnection: (connection) => {
45
- store$1.setState({ connection });
46
- },
47
- /**
48
- * Gets the current state of the store
49
- * @returns The complete store state
50
+ * Updates current connection, wallets
51
+ * Used when the popup confirm a connection
52
+ * @param {GlobalWalletConnection | null} connection - The connection to store, or null to clear it
50
53
  */
51
- get state() {
52
- return store$1.getState();
54
+ setInitialConnectionState: ({ connection, wallets, ethereum, }) => {
55
+ store$1.setState({ connection, ethereum, wallets });
53
56
  },
54
57
  /**
55
- * Gets the current user's wallets
56
- * @returns The current user's wallets
58
+ * Get all wallets connected to the current connection
57
59
  */
58
- get userWallets() {
59
- var _a, _b, _c, _d, _e;
60
- const evm = (_c = (_b = (_a = store$1.getState().connection) === null || _a === void 0 ? void 0 : _a.evm) === null || _b === void 0 ? void 0 : _b.wallets) !== null && _c !== void 0 ? _c : [];
61
- const solana = (_e = (_d = store$1.getState().connection) === null || _d === void 0 ? void 0 : _d.solana) === null || _e === void 0 ? void 0 : _e.wallet;
62
- return solana ? [...evm, solana] : evm;
60
+ get wallets() {
61
+ this.getActiveConnection();
62
+ return store$1.getState().wallets;
63
63
  },
64
64
  };
65
65
  };
@@ -1,34 +1,55 @@
1
- import { Connection } from '../types';
1
+ import { BaseWallet, GlobalWalletConnection } from '@dynamic-labs/types';
2
2
  type CreateClientStoreProps = {
3
3
  storage?: Storage;
4
4
  };
5
+ type ClientStoreState = {
6
+ /**
7
+ * Connection data between client and popup
8
+ */
9
+ connection: GlobalWalletConnection | null;
10
+ /**
11
+ * All EVM and Solana wallets connected to this Dapp
12
+ */
13
+ wallets: BaseWallet[];
14
+ /**
15
+ * Ethereum specific state
16
+ */
17
+ ethereum: {
18
+ supportedNetworks: {
19
+ chainId: number;
20
+ }[];
21
+ currentNetworkId: number;
22
+ } | null;
23
+ };
5
24
  export declare const createClientStore: ({ storage, }?: CreateClientStoreProps) => {
6
25
  /**
7
26
  * Resets the store to its initial state
8
27
  */
9
28
  clear: () => void;
10
29
  /**
11
- * Retrieves the current active connection if it exists and hasn't expired
12
- * @returns {Connection | null} The current connection or null if no connection exists or it has expired
30
+ * Get all Ethereum state from the current connection
13
31
  */
14
- getActiveConnection: () => Connection | null;
32
+ readonly ethereum: {
33
+ supportedNetworks: {
34
+ chainId: number;
35
+ }[];
36
+ currentNetworkId: number;
37
+ } | null;
15
38
  /**
16
- * Updates the connection in the store
17
- * @param {Connection | null} connection - The connection to store, or null to clear it
39
+ * Retrieves the current active connection if it exists and hasn't expired
40
+ * @returns {Connection | null} The current connection or null if no connection exists or it has expired
18
41
  */
19
- setConnection: (connection: Connection | null) => void;
42
+ getActiveConnection: () => GlobalWalletConnection | null;
20
43
  /**
21
- * Gets the current state of the store
22
- * @returns The complete store state
44
+ * Updates current connection, wallets
45
+ * Used when the popup confirm a connection
46
+ * @param {GlobalWalletConnection | null} connection - The connection to store, or null to clear it
23
47
  */
24
- readonly state: {
25
- connection: Connection | null;
26
- };
48
+ setInitialConnectionState: ({ connection, wallets, ethereum, }: Pick<ClientStoreState, 'connection' | 'wallets' | 'ethereum'>) => void;
27
49
  /**
28
- * Gets the current user's wallets
29
- * @returns The current user's wallets
50
+ * Get all wallets connected to the current connection
30
51
  */
31
- readonly userWallets: import("dist/packages/types/src").BaseWallet[];
52
+ readonly wallets: BaseWallet[];
32
53
  };
33
54
  export type ClientStore = ReturnType<typeof createClientStore>;
34
55
  export {};
@@ -8,6 +8,8 @@ const createClientStore = ({ storage = localStorage, } = {}) => {
8
8
  storage,
9
9
  store: createStore(() => ({
10
10
  connection: null,
11
+ ethereum: null,
12
+ wallets: [],
11
13
  })),
12
14
  });
13
15
  return {
@@ -17,6 +19,13 @@ const createClientStore = ({ storage = localStorage, } = {}) => {
17
19
  clear: () => {
18
20
  store.setState(store.getInitialState());
19
21
  },
22
+ /**
23
+ * Get all Ethereum state from the current connection
24
+ */
25
+ get ethereum() {
26
+ this.getActiveConnection();
27
+ return store.getState().ethereum;
28
+ },
20
29
  /**
21
30
  * Retrieves the current active connection if it exists and hasn't expired
22
31
  * @returns {Connection | null} The current connection or null if no connection exists or it has expired
@@ -34,28 +43,19 @@ const createClientStore = ({ storage = localStorage, } = {}) => {
34
43
  return connection;
35
44
  },
36
45
  /**
37
- * Updates the connection in the store
38
- * @param {Connection | null} connection - The connection to store, or null to clear it
39
- */
40
- setConnection: (connection) => {
41
- store.setState({ connection });
42
- },
43
- /**
44
- * Gets the current state of the store
45
- * @returns The complete store state
46
+ * Updates current connection, wallets
47
+ * Used when the popup confirm a connection
48
+ * @param {GlobalWalletConnection | null} connection - The connection to store, or null to clear it
46
49
  */
47
- get state() {
48
- return store.getState();
50
+ setInitialConnectionState: ({ connection, wallets, ethereum, }) => {
51
+ store.setState({ connection, ethereum, wallets });
49
52
  },
50
53
  /**
51
- * Gets the current user's wallets
52
- * @returns The current user's wallets
54
+ * Get all wallets connected to the current connection
53
55
  */
54
- get userWallets() {
55
- var _a, _b, _c, _d, _e;
56
- const evm = (_c = (_b = (_a = store.getState().connection) === null || _a === void 0 ? void 0 : _a.evm) === null || _b === void 0 ? void 0 : _b.wallets) !== null && _c !== void 0 ? _c : [];
57
- const solana = (_e = (_d = store.getState().connection) === null || _d === void 0 ? void 0 : _d.solana) === null || _e === void 0 ? void 0 : _e.wallet;
58
- return solana ? [...evm, solana] : evm;
56
+ get wallets() {
57
+ this.getActiveConnection();
58
+ return store.getState().wallets;
59
59
  },
60
60
  };
61
61
  };
@@ -1,4 +1,3 @@
1
- import { BaseWallet } from '@dynamic-labs/types';
2
1
  export type IconCode = `data:image/png;base64,${string}`;
3
2
  export type PopupInfo = {
4
3
  url: string;
@@ -8,30 +7,3 @@ export type PopupInfo = {
8
7
  export type ConnectArgs = {
9
8
  chain: 'evm' | 'solana';
10
9
  };
11
- /**
12
- * Defines the current dapp connection
13
- */
14
- export type Connection = {
15
- /** Unix timestamp when the connection expires */
16
- expiresAt: number;
17
- /** EVM blockchain configuration */
18
- evm: {
19
- /** List of networks that can be switched to */
20
- supportedNetworks: {
21
- chainId: number;
22
- }[];
23
- /** Connected EVM wallets */
24
- wallets: BaseWallet[];
25
- /** Currently active network identifier */
26
- network: string;
27
- } | null;
28
- /** Solana blockchain configuration */
29
- solana: {
30
- /** Connected Solana wallet */
31
- wallet: BaseWallet;
32
- /** Currently active network identifier */
33
- network: string;
34
- } | null;
35
- /** Encryption key for secure communication */
36
- sharedSecret: string;
37
- };