@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 +2 -0
- package/package.cjs +1 -1
- package/package.js +1 -1
- package/package.json +6 -6
- package/src/lib/actions/connectAction/createConnectAction.cjs +11 -10
- package/src/lib/actions/connectAction/createConnectAction.d.ts +2 -2
- package/src/lib/actions/connectAction/createConnectAction.js +11 -10
- package/src/lib/createGlobalWalletClient.cjs +4 -6
- package/src/lib/createGlobalWalletClient.d.ts +6 -6
- package/src/lib/createGlobalWalletClient.js +4 -6
- package/src/lib/ethereum/functions/eip1193Provider/createEIP1193Provider.cjs +8 -5
- package/src/lib/ethereum/functions/eip1193Provider/createEIP1193Provider.js +8 -5
- package/src/lib/functions/createEthereumModule/createEthereumModule.cjs +21 -0
- package/src/lib/functions/createEthereumModule/createEthereumModule.d.ts +10 -0
- package/src/lib/functions/createEthereumModule/createEthereumModule.js +17 -0
- package/src/lib/functions/createEthereumModule/index.d.ts +1 -0
- package/src/lib/functions/createPopupOpener/createPopupOpener.cjs +76 -38
- package/src/lib/functions/createPopupOpener/createPopupOpener.d.ts +2 -1
- package/src/lib/functions/createPopupOpener/createPopupOpener.js +76 -38
- package/src/lib/functions/mergeAndEncryptParams/mergeAndEncryptParams.d.ts +2 -2
- package/src/lib/store/createClientStore.cjs +18 -18
- package/src/lib/store/createClientStore.d.ts +36 -15
- package/src/lib/store/createClientStore.js +18 -18
- package/src/lib/types.d.ts +0 -28
package/CHANGELOG.md
CHANGED
package/package.cjs
CHANGED
package/package.js
CHANGED
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@dynamic-labs/global-wallet-client",
|
|
3
|
-
"version": "4.0.0-alpha.
|
|
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.
|
|
35
|
-
"@dynamic-labs/logger": "4.0.0-alpha.
|
|
36
|
-
"@dynamic-labs/store": "4.0.0-alpha.
|
|
37
|
-
"@dynamic-labs/types": "4.0.0-alpha.
|
|
38
|
-
"@dynamic-labs/utils": "4.0.0-alpha.
|
|
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
|
-
|
|
24
|
-
|
|
25
|
-
|
|
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
|
-
|
|
30
|
-
|
|
31
|
-
|
|
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
|
|
3
|
+
import { ConnectArgs } from '../../types';
|
|
4
4
|
type CreateConnectActionProps = {
|
|
5
5
|
store: ClientStore;
|
|
6
6
|
openPopup: OpenPopup;
|
|
7
|
-
onConnect?: (
|
|
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
|
-
|
|
20
|
-
|
|
21
|
-
|
|
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
|
-
|
|
26
|
-
|
|
27
|
-
|
|
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
|
-
|
|
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
|
|
39
|
-
return store.
|
|
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
|
-
|
|
10
|
-
|
|
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
|
-
|
|
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
|
|
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
|
-
|
|
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
|
|
35
|
-
return store.
|
|
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
|
|
16
|
-
if (!
|
|
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(
|
|
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
|
-
|
|
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
|
|
12
|
-
if (!
|
|
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(
|
|
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
|
-
|
|
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
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
const
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
}
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
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
|
-
|
|
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
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
const
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
}
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
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
|
-
|
|
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 {
|
|
2
|
-
export declare const mergeAndEncryptParams: (url: URL, params: Record<string, string>, activeConnection:
|
|
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
|
|
42
|
-
*
|
|
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
|
-
|
|
52
|
-
|
|
54
|
+
setInitialConnectionState: ({ connection, wallets, ethereum, }) => {
|
|
55
|
+
store$1.setState({ connection, ethereum, wallets });
|
|
53
56
|
},
|
|
54
57
|
/**
|
|
55
|
-
*
|
|
56
|
-
* @returns The current user's wallets
|
|
58
|
+
* Get all wallets connected to the current connection
|
|
57
59
|
*/
|
|
58
|
-
get
|
|
59
|
-
|
|
60
|
-
|
|
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 {
|
|
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
|
-
*
|
|
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
|
-
|
|
32
|
+
readonly ethereum: {
|
|
33
|
+
supportedNetworks: {
|
|
34
|
+
chainId: number;
|
|
35
|
+
}[];
|
|
36
|
+
currentNetworkId: number;
|
|
37
|
+
} | null;
|
|
15
38
|
/**
|
|
16
|
-
*
|
|
17
|
-
* @
|
|
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
|
-
|
|
42
|
+
getActiveConnection: () => GlobalWalletConnection | null;
|
|
20
43
|
/**
|
|
21
|
-
*
|
|
22
|
-
*
|
|
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
|
-
|
|
25
|
-
connection: Connection | null;
|
|
26
|
-
};
|
|
48
|
+
setInitialConnectionState: ({ connection, wallets, ethereum, }: Pick<ClientStoreState, 'connection' | 'wallets' | 'ethereum'>) => void;
|
|
27
49
|
/**
|
|
28
|
-
*
|
|
29
|
-
* @returns The current user's wallets
|
|
50
|
+
* Get all wallets connected to the current connection
|
|
30
51
|
*/
|
|
31
|
-
readonly
|
|
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
|
|
38
|
-
*
|
|
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
|
-
|
|
48
|
-
|
|
50
|
+
setInitialConnectionState: ({ connection, wallets, ethereum, }) => {
|
|
51
|
+
store.setState({ connection, ethereum, wallets });
|
|
49
52
|
},
|
|
50
53
|
/**
|
|
51
|
-
*
|
|
52
|
-
* @returns The current user's wallets
|
|
54
|
+
* Get all wallets connected to the current connection
|
|
53
55
|
*/
|
|
54
|
-
get
|
|
55
|
-
|
|
56
|
-
|
|
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
|
};
|
package/src/lib/types.d.ts
CHANGED
|
@@ -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
|
-
};
|