@dynamic-labs/sdk-react-core 4.90.0 → 4.91.0
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 +17 -0
- package/README.md +1 -52
- package/package.cjs +2 -2
- package/package.js +2 -2
- package/package.json +13 -13
- package/src/lib/client/extension/functions/getSessionKeys/getSessionKeys.cjs +11 -0
- package/src/lib/client/extension/functions/getSessionKeys/getSessionKeys.js +7 -0
- package/src/lib/client/extension/functions/getSessionPublicKey/getSessionPublicKey.cjs +17 -0
- package/src/lib/client/extension/functions/getSessionPublicKey/getSessionPublicKey.d.ts +7 -0
- package/src/lib/client/extension/functions/getSessionPublicKey/getSessionPublicKey.js +13 -0
- package/src/lib/client/extension/index.d.ts +1 -0
- package/src/lib/context/DynamicContext/DynamicContext.cjs +9 -1
- package/src/lib/context/DynamicContext/DynamicContext.js +10 -2
- package/src/lib/styles/index.shadow.cjs +1 -1
- package/src/lib/styles/index.shadow.js +1 -1
- package/src/lib/utils/functions/getTransactionLink/blockExplorerPatterns.cjs +12 -0
- package/src/lib/utils/functions/getTransactionLink/blockExplorerPatterns.js +12 -0
- package/src/lib/utils/hooks/useCreateWalletConnectorOptions/utils/verifyZeroDevIsSetup/verifyZeroDevIsSetup.cjs +7 -3
- package/src/lib/utils/hooks/useCreateWalletConnectorOptions/utils/verifyZeroDevIsSetup/verifyZeroDevIsSetup.js +7 -3
- package/src/lib/utils/hooks/useDynamicWaas/useDynamicWaas.cjs +16 -3
- package/src/lib/utils/hooks/useDynamicWaas/useDynamicWaas.d.ts +3 -1
- package/src/lib/utils/hooks/useDynamicWaas/useDynamicWaas.js +16 -3
- package/src/lib/utils/hooks/useSetWalletConnectorFetchers/useSetWalletConnectorFetchers.cjs +8 -1
- package/src/lib/utils/hooks/useSetWalletConnectorFetchers/useSetWalletConnectorFetchers.d.ts +1 -1
- package/src/lib/utils/hooks/useSetWalletConnectorFetchers/useSetWalletConnectorFetchers.js +8 -1
- package/src/lib/views/TransactionConfirmationView/helpers/transactionErrorMessage.cjs +8 -0
- package/src/lib/views/TransactionConfirmationView/helpers/transactionErrorMessage.js +8 -0
- package/src/lib/widgets/DynamicWidget/components/ActiveMidnightWalletBalance/ActiveMidnightWalletBalance.cjs +56 -13
- package/src/lib/widgets/DynamicWidget/components/ActiveMidnightWalletBalance/ActiveMidnightWalletBalance.js +58 -15
- package/src/lib/widgets/DynamicWidget/components/ActiveWalletInformation/ActiveMidnightWalletAddresses/ActiveMidnightWalletAddresses.cjs +40 -2
- package/src/lib/widgets/DynamicWidget/components/ActiveWalletInformation/ActiveMidnightWalletAddresses/ActiveMidnightWalletAddresses.d.ts +7 -0
- package/src/lib/widgets/DynamicWidget/components/ActiveWalletInformation/ActiveMidnightWalletAddresses/ActiveMidnightWalletAddresses.js +41 -3
- package/src/lib/widgets/DynamicWidget/components/ActiveWalletInformation/ActiveWalletInformation.cjs +2 -0
- package/src/lib/widgets/DynamicWidget/components/ActiveWalletInformation/ActiveWalletInformation.js +2 -0
|
@@ -32,6 +32,18 @@ const BLOCK_EXPLORER_PATTERNS = [
|
|
|
32
32
|
return url.toString();
|
|
33
33
|
},
|
|
34
34
|
},
|
|
35
|
+
{
|
|
36
|
+
// The Midnight explorer indexes by the canonical transaction hash and
|
|
37
|
+
// serves detail pages at `/transactions/{hash}`. Matching the bare
|
|
38
|
+
// `midnight.network` substring covers the preview/testnet subdomains.
|
|
39
|
+
description: 'Midnight - Uses /transactions/{hash}',
|
|
40
|
+
domain: 'midnight.network',
|
|
41
|
+
generateUrl: (baseUrl, hash) => {
|
|
42
|
+
const url = new URL(baseUrl);
|
|
43
|
+
url.pathname = `/transactions/${hash}`;
|
|
44
|
+
return url.toString();
|
|
45
|
+
},
|
|
46
|
+
},
|
|
35
47
|
];
|
|
36
48
|
/**
|
|
37
49
|
* Default pattern for standard block explorers
|
|
@@ -28,6 +28,18 @@ const BLOCK_EXPLORER_PATTERNS = [
|
|
|
28
28
|
return url.toString();
|
|
29
29
|
},
|
|
30
30
|
},
|
|
31
|
+
{
|
|
32
|
+
// The Midnight explorer indexes by the canonical transaction hash and
|
|
33
|
+
// serves detail pages at `/transactions/{hash}`. Matching the bare
|
|
34
|
+
// `midnight.network` substring covers the preview/testnet subdomains.
|
|
35
|
+
description: 'Midnight - Uses /transactions/{hash}',
|
|
36
|
+
domain: 'midnight.network',
|
|
37
|
+
generateUrl: (baseUrl, hash) => {
|
|
38
|
+
const url = new URL(baseUrl);
|
|
39
|
+
url.pathname = `/transactions/${hash}`;
|
|
40
|
+
return url.toString();
|
|
41
|
+
},
|
|
42
|
+
},
|
|
31
43
|
];
|
|
32
44
|
/**
|
|
33
45
|
* Default pattern for standard block explorers
|
|
@@ -8,7 +8,7 @@ require('../../../../constants/values.cjs');
|
|
|
8
8
|
require('@dynamic-labs/utils');
|
|
9
9
|
require('../../../../../../../_virtual/_tslib.cjs');
|
|
10
10
|
require('@dynamic-labs/multi-wallet');
|
|
11
|
-
require('../../../../../shared/logger.cjs');
|
|
11
|
+
var logger = require('../../../../../shared/logger.cjs');
|
|
12
12
|
require('react-international-phone');
|
|
13
13
|
require('../../../../constants/colors.cjs');
|
|
14
14
|
require('@dynamic-labs/iconic');
|
|
@@ -31,7 +31,6 @@ require('../../../../../store/state/dynamicContextProps/dynamicContextProps.cjs'
|
|
|
31
31
|
require('../../../../../store/state/primaryWalletId/primaryWalletId.cjs');
|
|
32
32
|
require('../../../../../store/state/connectedWalletsInfo/connectedWalletsInfo.cjs');
|
|
33
33
|
require('../../../../functions/getWaasAddressTypeLabel/getWaasAddressTypeLabel.cjs');
|
|
34
|
-
var ConnectorSetupError = require('../errors/ConnectorSetupError.cjs');
|
|
35
34
|
|
|
36
35
|
const zeroDevWalletConnectorKey = 'zerodev';
|
|
37
36
|
const verifyZeroDevIsSetup = (projectSettings, walletConnectors) => {
|
|
@@ -39,7 +38,12 @@ const verifyZeroDevIsSetup = (projectSettings, walletConnectors) => {
|
|
|
39
38
|
const isZeroDevEnabled = isProviderEnabled.isProviderEnabled((_a = projectSettings.providers) !== null && _a !== void 0 ? _a : [], sdkApiCore.ProviderEnum.Zerodev);
|
|
40
39
|
const isZeroDevWalletConnectorPresent = walletConnectors.some(({ key }) => key === zeroDevWalletConnectorKey);
|
|
41
40
|
if (isZeroDevEnabled && !isZeroDevWalletConnectorPresent) {
|
|
42
|
-
|
|
41
|
+
// A ZeroDev connector that's enabled in project settings but absent from
|
|
42
|
+
// `walletConnectors` is an explicit decision to migrate off ZeroDev —
|
|
43
|
+
// whether to native EVM gas sponsorship or to plain EOAs with no
|
|
44
|
+
// sponsorship at all. Warn and continue (wallets fall back to the embedded
|
|
45
|
+
// EOA) instead of hard-throwing and white-screening the app.
|
|
46
|
+
logger.logger.warn('ZeroDev is enabled in project settings but ZeroDevSmartWalletConnectors is not in walletConnectors. Continuing without ZeroDev — wallets will fall back to the embedded EOA (gas is sponsored only if native EVM gas sponsorship is enabled).');
|
|
43
47
|
}
|
|
44
48
|
};
|
|
45
49
|
|
|
@@ -4,7 +4,7 @@ import '../../../../constants/values.js';
|
|
|
4
4
|
import '@dynamic-labs/utils';
|
|
5
5
|
import '../../../../../../../_virtual/_tslib.js';
|
|
6
6
|
import '@dynamic-labs/multi-wallet';
|
|
7
|
-
import '../../../../../shared/logger.js';
|
|
7
|
+
import { logger } from '../../../../../shared/logger.js';
|
|
8
8
|
import 'react-international-phone';
|
|
9
9
|
import '../../../../constants/colors.js';
|
|
10
10
|
import '@dynamic-labs/iconic';
|
|
@@ -27,7 +27,6 @@ import '../../../../../store/state/dynamicContextProps/dynamicContextProps.js';
|
|
|
27
27
|
import '../../../../../store/state/primaryWalletId/primaryWalletId.js';
|
|
28
28
|
import '../../../../../store/state/connectedWalletsInfo/connectedWalletsInfo.js';
|
|
29
29
|
import '../../../../functions/getWaasAddressTypeLabel/getWaasAddressTypeLabel.js';
|
|
30
|
-
import { ConnectorSetupError } from '../errors/ConnectorSetupError.js';
|
|
31
30
|
|
|
32
31
|
const zeroDevWalletConnectorKey = 'zerodev';
|
|
33
32
|
const verifyZeroDevIsSetup = (projectSettings, walletConnectors) => {
|
|
@@ -35,7 +34,12 @@ const verifyZeroDevIsSetup = (projectSettings, walletConnectors) => {
|
|
|
35
34
|
const isZeroDevEnabled = isProviderEnabled((_a = projectSettings.providers) !== null && _a !== void 0 ? _a : [], ProviderEnum.Zerodev);
|
|
36
35
|
const isZeroDevWalletConnectorPresent = walletConnectors.some(({ key }) => key === zeroDevWalletConnectorKey);
|
|
37
36
|
if (isZeroDevEnabled && !isZeroDevWalletConnectorPresent) {
|
|
38
|
-
|
|
37
|
+
// A ZeroDev connector that's enabled in project settings but absent from
|
|
38
|
+
// `walletConnectors` is an explicit decision to migrate off ZeroDev —
|
|
39
|
+
// whether to native EVM gas sponsorship or to plain EOAs with no
|
|
40
|
+
// sponsorship at all. Warn and continue (wallets fall back to the embedded
|
|
41
|
+
// EOA) instead of hard-throwing and white-screening the app.
|
|
42
|
+
logger.warn('ZeroDev is enabled in project settings but ZeroDevSmartWalletConnectors is not in walletConnectors. Continuing without ZeroDev — wallets will fall back to the embedded EOA (gas is sponsored only if native EVM gas sponsorship is enabled).');
|
|
39
43
|
}
|
|
40
44
|
};
|
|
41
45
|
|
|
@@ -39,6 +39,7 @@ var useProjectSettings = require('../../../client/extension/projectSettings/useP
|
|
|
39
39
|
var isCookieEnabled = require('../../../client/extension/functions/isCookieEnabled/isCookieEnabled.cjs');
|
|
40
40
|
var getMinAuthToken = require('../../../client/extension/functions/getMinAuthToken/getMinAuthToken.cjs');
|
|
41
41
|
var generateChainingSignature = require('../../../client/extension/functions/generateChainingSignature/generateChainingSignature.cjs');
|
|
42
|
+
var getSessionPublicKey = require('../../../client/extension/functions/getSessionPublicKey/getSessionPublicKey.cjs');
|
|
42
43
|
require('../../../context/DynamicContext/useDynamicContext/useDynamicContext.cjs');
|
|
43
44
|
var useInternalDynamicContext = require('../../../context/DynamicContext/useDynamicContext/useInternalDynamicContext/useInternalDynamicContext.cjs');
|
|
44
45
|
var UserWalletsContext = require('../../../context/UserWalletsContext/UserWalletsContext.cjs');
|
|
@@ -55,8 +56,8 @@ var normalizeWaasChainName = require('./normalizeWaasChainName.cjs');
|
|
|
55
56
|
var normalizeWalletRequirements = require('./normalizeWalletRequirements.cjs');
|
|
56
57
|
|
|
57
58
|
const dynamicWaasKey = 'dynamicwaas';
|
|
58
|
-
const configWaasWalletConnector = ({ walletConnector, environmentId, apiBaseUrl, relayUrl, baseClientKeysharesRelayApiUrl, authMode = 'header', getSignedSessionId, getMfaToken, getWalletPassword, getSvmGasSponsorshipEnabled = () => false, getElevatedAccessToken, }) => {
|
|
59
|
-
var _a;
|
|
59
|
+
const configWaasWalletConnector = ({ walletConnector, environmentId, apiBaseUrl, relayUrl, baseClientKeysharesRelayApiUrl, authMode = 'header', getSignedSessionId, getSessionPublicKey, getMfaToken, getWalletPassword, getSvmGasSponsorshipEnabled = () => false, getElevatedAccessToken, onUnauthorized, }) => {
|
|
60
|
+
var _a, _b;
|
|
60
61
|
walletConnector.setEnvironmentId(environmentId);
|
|
61
62
|
walletConnector.setBaseApiUrl((_a = (apiBaseUrl || apiUrl.DEFAULT_WAAS_API_URL)) === null || _a === void 0 ? void 0 : _a.replace('/api/v0', ''));
|
|
62
63
|
if (authMode === 'cookie') {
|
|
@@ -68,6 +69,11 @@ const configWaasWalletConnector = ({ walletConnector, environmentId, apiBaseUrl,
|
|
|
68
69
|
walletConnector.setGetAuthTokenFunction(getMinAuthToken.getMinAuthToken);
|
|
69
70
|
}
|
|
70
71
|
walletConnector.setGetSignedSessionIdFunction(getSignedSessionId);
|
|
72
|
+
// Optional + best-effort: a connector build predating this method must not
|
|
73
|
+
// break wiring — the backup pubkey header simply stays absent.
|
|
74
|
+
if (getSessionPublicKey) {
|
|
75
|
+
(_b = walletConnector.setGetSessionPublicKeyFunction) === null || _b === void 0 ? void 0 : _b.call(walletConnector, getSessionPublicKey);
|
|
76
|
+
}
|
|
71
77
|
walletConnector.setRelayUrl(relayUrl);
|
|
72
78
|
walletConnector.setGetMfaTokenFunction(getMfaToken);
|
|
73
79
|
walletConnector.setBaseClientKeysharesRelayApiUrl(baseClientKeysharesRelayApiUrl);
|
|
@@ -79,6 +85,10 @@ const configWaasWalletConnector = ({ walletConnector, environmentId, apiBaseUrl,
|
|
|
79
85
|
if (getWalletPassword) {
|
|
80
86
|
walletConnector.setGetWalletPasswordFunction(getWalletPassword);
|
|
81
87
|
}
|
|
88
|
+
// Log the user out when the iframe reports a 401 (e.g. token forcibly revoked)
|
|
89
|
+
if (onUnauthorized) {
|
|
90
|
+
walletConnector.setOnUnauthorizedFunction(onUnauthorized);
|
|
91
|
+
}
|
|
82
92
|
// Sync SVM gas sponsorship setting for SOL connectors
|
|
83
93
|
const isSolConnector = walletConnector.connectedChain === 'SOL';
|
|
84
94
|
const supportsSponsorshipSetting = 'setSvmGasSponsorshipEnabled' in walletConnector;
|
|
@@ -89,7 +99,7 @@ const configWaasWalletConnector = ({ walletConnector, environmentId, apiBaseUrl,
|
|
|
89
99
|
};
|
|
90
100
|
const useDynamicWaas = () => {
|
|
91
101
|
var _a, _b, _c, _d, _e, _f;
|
|
92
|
-
const { setShowAuthFlow } = useInternalDynamicContext.useInternalDynamicContext();
|
|
102
|
+
const { setShowAuthFlow, handleLogOutWithReason } = useInternalDynamicContext.useInternalDynamicContext();
|
|
93
103
|
const { addedWalletsIds, userWallets } = UserWalletsContext.useInternalUserWallets();
|
|
94
104
|
const user = useUser.useUser();
|
|
95
105
|
const apiBaseUrl = dynamicContextProps.useApiBaseUrl();
|
|
@@ -149,9 +159,11 @@ const useDynamicWaas = () => {
|
|
|
149
159
|
environmentId,
|
|
150
160
|
getElevatedAccessToken,
|
|
151
161
|
getMfaToken,
|
|
162
|
+
getSessionPublicKey: getSessionPublicKey.getSessionPublicKey,
|
|
152
163
|
getSignedSessionId: generateChainingSignature.generateChainingSignature,
|
|
153
164
|
getSvmGasSponsorshipEnabled: () => svmGasSponsorshipEnabledRef.current,
|
|
154
165
|
getWalletPassword,
|
|
166
|
+
onUnauthorized: () => handleLogOutWithReason('session-refresh-unauthorized'),
|
|
155
167
|
relayUrl: relayUrl !== null && relayUrl !== void 0 ? relayUrl : '',
|
|
156
168
|
walletConnector,
|
|
157
169
|
});
|
|
@@ -165,6 +177,7 @@ const useDynamicWaas = () => {
|
|
|
165
177
|
getElevatedAccessToken,
|
|
166
178
|
getMfaToken,
|
|
167
179
|
getWalletPassword,
|
|
180
|
+
handleLogOutWithReason,
|
|
168
181
|
relayUrl,
|
|
169
182
|
baseClientKeysharesRelayApiUrl,
|
|
170
183
|
]);
|
|
@@ -12,7 +12,7 @@ export type WalletCreationRequirement = {
|
|
|
12
12
|
network?: string;
|
|
13
13
|
};
|
|
14
14
|
};
|
|
15
|
-
export declare const configWaasWalletConnector: ({ walletConnector, environmentId, apiBaseUrl, relayUrl, baseClientKeysharesRelayApiUrl, authMode, getSignedSessionId, getMfaToken, getWalletPassword, getSvmGasSponsorshipEnabled, getElevatedAccessToken, }: {
|
|
15
|
+
export declare const configWaasWalletConnector: ({ walletConnector, environmentId, apiBaseUrl, relayUrl, baseClientKeysharesRelayApiUrl, authMode, getSignedSessionId, getSessionPublicKey, getMfaToken, getWalletPassword, getSvmGasSponsorshipEnabled, getElevatedAccessToken, onUnauthorized, }: {
|
|
16
16
|
walletConnector: IDynamicWaasConnector;
|
|
17
17
|
environmentId: string;
|
|
18
18
|
apiBaseUrl: string;
|
|
@@ -20,6 +20,7 @@ export declare const configWaasWalletConnector: ({ walletConnector, environmentI
|
|
|
20
20
|
baseClientKeysharesRelayApiUrl?: string;
|
|
21
21
|
authMode?: 'cookie' | 'header';
|
|
22
22
|
getSignedSessionId: () => Promise<string>;
|
|
23
|
+
getSessionPublicKey?: () => Promise<string | undefined>;
|
|
23
24
|
getMfaToken: (props?: {
|
|
24
25
|
mfaAction?: MFAAction;
|
|
25
26
|
}) => Promise<string | undefined>;
|
|
@@ -28,6 +29,7 @@ export declare const configWaasWalletConnector: ({ walletConnector, environmentI
|
|
|
28
29
|
getElevatedAccessToken?: (params: {
|
|
29
30
|
scope: TokenScope;
|
|
30
31
|
}) => Promise<string | undefined>;
|
|
32
|
+
onUnauthorized?: () => void | Promise<void>;
|
|
31
33
|
}) => IDynamicWaasConnector;
|
|
32
34
|
export declare const useDynamicWaas: () => {
|
|
33
35
|
areWalletsReadyForSettings: () => boolean;
|
|
@@ -35,6 +35,7 @@ import { useProjectSettings } from '../../../client/extension/projectSettings/us
|
|
|
35
35
|
import { isCookieEnabled } from '../../../client/extension/functions/isCookieEnabled/isCookieEnabled.js';
|
|
36
36
|
import { getMinAuthToken } from '../../../client/extension/functions/getMinAuthToken/getMinAuthToken.js';
|
|
37
37
|
import { generateChainingSignature } from '../../../client/extension/functions/generateChainingSignature/generateChainingSignature.js';
|
|
38
|
+
import { getSessionPublicKey } from '../../../client/extension/functions/getSessionPublicKey/getSessionPublicKey.js';
|
|
38
39
|
import '../../../context/DynamicContext/useDynamicContext/useDynamicContext.js';
|
|
39
40
|
import { useInternalDynamicContext } from '../../../context/DynamicContext/useDynamicContext/useInternalDynamicContext/useInternalDynamicContext.js';
|
|
40
41
|
import { useInternalUserWallets } from '../../../context/UserWalletsContext/UserWalletsContext.js';
|
|
@@ -51,8 +52,8 @@ import { normalizeWaasChainName } from './normalizeWaasChainName.js';
|
|
|
51
52
|
import { normalizeWalletRequirements } from './normalizeWalletRequirements.js';
|
|
52
53
|
|
|
53
54
|
const dynamicWaasKey = 'dynamicwaas';
|
|
54
|
-
const configWaasWalletConnector = ({ walletConnector, environmentId, apiBaseUrl, relayUrl, baseClientKeysharesRelayApiUrl, authMode = 'header', getSignedSessionId, getMfaToken, getWalletPassword, getSvmGasSponsorshipEnabled = () => false, getElevatedAccessToken, }) => {
|
|
55
|
-
var _a;
|
|
55
|
+
const configWaasWalletConnector = ({ walletConnector, environmentId, apiBaseUrl, relayUrl, baseClientKeysharesRelayApiUrl, authMode = 'header', getSignedSessionId, getSessionPublicKey, getMfaToken, getWalletPassword, getSvmGasSponsorshipEnabled = () => false, getElevatedAccessToken, onUnauthorized, }) => {
|
|
56
|
+
var _a, _b;
|
|
56
57
|
walletConnector.setEnvironmentId(environmentId);
|
|
57
58
|
walletConnector.setBaseApiUrl((_a = (apiBaseUrl || DEFAULT_WAAS_API_URL)) === null || _a === void 0 ? void 0 : _a.replace('/api/v0', ''));
|
|
58
59
|
if (authMode === 'cookie') {
|
|
@@ -64,6 +65,11 @@ const configWaasWalletConnector = ({ walletConnector, environmentId, apiBaseUrl,
|
|
|
64
65
|
walletConnector.setGetAuthTokenFunction(getMinAuthToken);
|
|
65
66
|
}
|
|
66
67
|
walletConnector.setGetSignedSessionIdFunction(getSignedSessionId);
|
|
68
|
+
// Optional + best-effort: a connector build predating this method must not
|
|
69
|
+
// break wiring — the backup pubkey header simply stays absent.
|
|
70
|
+
if (getSessionPublicKey) {
|
|
71
|
+
(_b = walletConnector.setGetSessionPublicKeyFunction) === null || _b === void 0 ? void 0 : _b.call(walletConnector, getSessionPublicKey);
|
|
72
|
+
}
|
|
67
73
|
walletConnector.setRelayUrl(relayUrl);
|
|
68
74
|
walletConnector.setGetMfaTokenFunction(getMfaToken);
|
|
69
75
|
walletConnector.setBaseClientKeysharesRelayApiUrl(baseClientKeysharesRelayApiUrl);
|
|
@@ -75,6 +81,10 @@ const configWaasWalletConnector = ({ walletConnector, environmentId, apiBaseUrl,
|
|
|
75
81
|
if (getWalletPassword) {
|
|
76
82
|
walletConnector.setGetWalletPasswordFunction(getWalletPassword);
|
|
77
83
|
}
|
|
84
|
+
// Log the user out when the iframe reports a 401 (e.g. token forcibly revoked)
|
|
85
|
+
if (onUnauthorized) {
|
|
86
|
+
walletConnector.setOnUnauthorizedFunction(onUnauthorized);
|
|
87
|
+
}
|
|
78
88
|
// Sync SVM gas sponsorship setting for SOL connectors
|
|
79
89
|
const isSolConnector = walletConnector.connectedChain === 'SOL';
|
|
80
90
|
const supportsSponsorshipSetting = 'setSvmGasSponsorshipEnabled' in walletConnector;
|
|
@@ -85,7 +95,7 @@ const configWaasWalletConnector = ({ walletConnector, environmentId, apiBaseUrl,
|
|
|
85
95
|
};
|
|
86
96
|
const useDynamicWaas = () => {
|
|
87
97
|
var _a, _b, _c, _d, _e, _f;
|
|
88
|
-
const { setShowAuthFlow } = useInternalDynamicContext();
|
|
98
|
+
const { setShowAuthFlow, handleLogOutWithReason } = useInternalDynamicContext();
|
|
89
99
|
const { addedWalletsIds, userWallets } = useInternalUserWallets();
|
|
90
100
|
const user = useUser();
|
|
91
101
|
const apiBaseUrl = useApiBaseUrl();
|
|
@@ -145,9 +155,11 @@ const useDynamicWaas = () => {
|
|
|
145
155
|
environmentId,
|
|
146
156
|
getElevatedAccessToken,
|
|
147
157
|
getMfaToken,
|
|
158
|
+
getSessionPublicKey,
|
|
148
159
|
getSignedSessionId: generateChainingSignature,
|
|
149
160
|
getSvmGasSponsorshipEnabled: () => svmGasSponsorshipEnabledRef.current,
|
|
150
161
|
getWalletPassword,
|
|
162
|
+
onUnauthorized: () => handleLogOutWithReason('session-refresh-unauthorized'),
|
|
151
163
|
relayUrl: relayUrl !== null && relayUrl !== void 0 ? relayUrl : '',
|
|
152
164
|
walletConnector,
|
|
153
165
|
});
|
|
@@ -161,6 +173,7 @@ const useDynamicWaas = () => {
|
|
|
161
173
|
getElevatedAccessToken,
|
|
162
174
|
getMfaToken,
|
|
163
175
|
getWalletPassword,
|
|
176
|
+
handleLogOutWithReason,
|
|
164
177
|
relayUrl,
|
|
165
178
|
baseClientKeysharesRelayApiUrl,
|
|
166
179
|
]);
|
|
@@ -31,6 +31,7 @@ require('@dynamic-labs-sdk/client');
|
|
|
31
31
|
require('../../../config/ApiEndpoint.cjs');
|
|
32
32
|
var isCookieEnabled = require('../../../client/extension/functions/isCookieEnabled/isCookieEnabled.cjs');
|
|
33
33
|
var generateChainingSignature = require('../../../client/extension/functions/generateChainingSignature/generateChainingSignature.cjs');
|
|
34
|
+
var getSessionPublicKey = require('../../../client/extension/functions/getSessionPublicKey/getSessionPublicKey.cjs');
|
|
34
35
|
var apiUrl = require('../../constants/waas/apiUrl.cjs');
|
|
35
36
|
require('@dynamic-labs/locale');
|
|
36
37
|
var dynamicContextProps = require('../../../store/state/dynamicContextProps/dynamicContextProps.cjs');
|
|
@@ -118,7 +119,11 @@ require('../../../store/state/multichainBalances.cjs');
|
|
|
118
119
|
require('@dynamic-labs/store');
|
|
119
120
|
require('../../../shared/utils/functions/getInitialUrl/getInitialUrl.cjs');
|
|
120
121
|
|
|
121
|
-
const useSetWalletConnectorFetchers = (walletOptions, environmentId, projectSettings
|
|
122
|
+
const useSetWalletConnectorFetchers = (walletOptions, environmentId, projectSettings,
|
|
123
|
+
// Logs the user out when the iframe reports a 401. Passed in (rather than read
|
|
124
|
+
// from context) because this hook runs inside DynamicContextProvider itself,
|
|
125
|
+
// where the context value isn't available to consume.
|
|
126
|
+
onUnauthorized) => {
|
|
122
127
|
var _a, _b, _c;
|
|
123
128
|
const apiBaseUrl = dynamicContextProps.useApiBaseUrl();
|
|
124
129
|
const { registerEmbeddedWalletSessionKey, removeSessionKey } = useEmbeddedWalletSessionKeys.useEmbeddedWalletSessionKeys({ environmentId, projectSettings });
|
|
@@ -141,8 +146,10 @@ const useSetWalletConnectorFetchers = (walletOptions, environmentId, projectSett
|
|
|
141
146
|
authMode: isCookieAuthEnabled ? 'cookie' : 'header',
|
|
142
147
|
environmentId,
|
|
143
148
|
getMfaToken,
|
|
149
|
+
getSessionPublicKey: getSessionPublicKey.getSessionPublicKey,
|
|
144
150
|
getSignedSessionId: generateChainingSignature.generateChainingSignature,
|
|
145
151
|
getSvmGasSponsorshipEnabled: () => svmGasSponsorshipEnabledRef.current,
|
|
152
|
+
onUnauthorized,
|
|
146
153
|
relayUrl: (_e = (_d = (_c = projectSettings === null || projectSettings === void 0 ? void 0 : projectSettings.sdk) === null || _c === void 0 ? void 0 : _c.waas) === null || _d === void 0 ? void 0 : _d.relayUrl) !== null && _e !== void 0 ? _e : '',
|
|
147
154
|
walletConnector: walletOption.walletConnector,
|
|
148
155
|
});
|
package/src/lib/utils/hooks/useSetWalletConnectorFetchers/useSetWalletConnectorFetchers.d.ts
CHANGED
|
@@ -1,3 +1,3 @@
|
|
|
1
1
|
import { ProjectSettings } from '@dynamic-labs/sdk-api-core';
|
|
2
2
|
import { WalletOption } from '../../../shared';
|
|
3
|
-
export declare const useSetWalletConnectorFetchers: (walletOptions: WalletOption[] | undefined, environmentId: string, projectSettings: ProjectSettings | undefined) => void;
|
|
3
|
+
export declare const useSetWalletConnectorFetchers: (walletOptions: WalletOption[] | undefined, environmentId: string, projectSettings: ProjectSettings | undefined, onUnauthorized?: () => void | Promise<void>) => void;
|
|
@@ -27,6 +27,7 @@ import '@dynamic-labs-sdk/client';
|
|
|
27
27
|
import '../../../config/ApiEndpoint.js';
|
|
28
28
|
import { isCookieEnabled } from '../../../client/extension/functions/isCookieEnabled/isCookieEnabled.js';
|
|
29
29
|
import { generateChainingSignature } from '../../../client/extension/functions/generateChainingSignature/generateChainingSignature.js';
|
|
30
|
+
import { getSessionPublicKey } from '../../../client/extension/functions/getSessionPublicKey/getSessionPublicKey.js';
|
|
30
31
|
import { DEFAULT_WAAS_API_URL } from '../../constants/waas/apiUrl.js';
|
|
31
32
|
import '@dynamic-labs/locale';
|
|
32
33
|
import { useApiBaseUrl } from '../../../store/state/dynamicContextProps/dynamicContextProps.js';
|
|
@@ -114,7 +115,11 @@ import '../../../store/state/multichainBalances.js';
|
|
|
114
115
|
import '@dynamic-labs/store';
|
|
115
116
|
import '../../../shared/utils/functions/getInitialUrl/getInitialUrl.js';
|
|
116
117
|
|
|
117
|
-
const useSetWalletConnectorFetchers = (walletOptions, environmentId, projectSettings
|
|
118
|
+
const useSetWalletConnectorFetchers = (walletOptions, environmentId, projectSettings,
|
|
119
|
+
// Logs the user out when the iframe reports a 401. Passed in (rather than read
|
|
120
|
+
// from context) because this hook runs inside DynamicContextProvider itself,
|
|
121
|
+
// where the context value isn't available to consume.
|
|
122
|
+
onUnauthorized) => {
|
|
118
123
|
var _a, _b, _c;
|
|
119
124
|
const apiBaseUrl = useApiBaseUrl();
|
|
120
125
|
const { registerEmbeddedWalletSessionKey, removeSessionKey } = useEmbeddedWalletSessionKeys({ environmentId, projectSettings });
|
|
@@ -137,8 +142,10 @@ const useSetWalletConnectorFetchers = (walletOptions, environmentId, projectSett
|
|
|
137
142
|
authMode: isCookieAuthEnabled ? 'cookie' : 'header',
|
|
138
143
|
environmentId,
|
|
139
144
|
getMfaToken,
|
|
145
|
+
getSessionPublicKey,
|
|
140
146
|
getSignedSessionId: generateChainingSignature,
|
|
141
147
|
getSvmGasSponsorshipEnabled: () => svmGasSponsorshipEnabledRef.current,
|
|
148
|
+
onUnauthorized,
|
|
142
149
|
relayUrl: (_e = (_d = (_c = projectSettings === null || projectSettings === void 0 ? void 0 : projectSettings.sdk) === null || _c === void 0 ? void 0 : _c.waas) === null || _d === void 0 ? void 0 : _d.relayUrl) !== null && _e !== void 0 ? _e : '',
|
|
143
150
|
walletConnector: walletOption.walletConnector,
|
|
144
151
|
});
|
|
@@ -57,6 +57,7 @@ const isPolicyViolationError = (error) => {
|
|
|
57
57
|
(message === null || message === void 0 ? void 0 : message.toLowerCase().includes('explicitly denied by policy')));
|
|
58
58
|
};
|
|
59
59
|
const transactionErrorMessage = (err) => {
|
|
60
|
+
var _a, _b;
|
|
60
61
|
let error = err;
|
|
61
62
|
if (isTransactionExecutionError(err)) {
|
|
62
63
|
error = err.walk();
|
|
@@ -84,6 +85,13 @@ const transactionErrorMessage = (err) => {
|
|
|
84
85
|
if (isConfirmationTimeoutError(error)) {
|
|
85
86
|
return undefined; // Use translation key in UI for timeout message
|
|
86
87
|
}
|
|
88
|
+
// Midnight: every transaction needs DUST to pay fees. The wallet client throws
|
|
89
|
+
// "No dust balance — register dust first" when the wallet has no registered
|
|
90
|
+
// dust, so surface an actionable message instead of the generic fallback.
|
|
91
|
+
const message = (_b = (_a = getMessage(error)) === null || _a === void 0 ? void 0 : _a.toLowerCase()) !== null && _b !== void 0 ? _b : '';
|
|
92
|
+
if (message.includes('no dust') || message.includes('register dust')) {
|
|
93
|
+
return 'You need DUST to pay network fees. Register DUST first, then try again.';
|
|
94
|
+
}
|
|
87
95
|
return 'Something went wrong with the transaction. Please try again.';
|
|
88
96
|
};
|
|
89
97
|
const isMagicInsufficientFundsError = (error) => {
|
|
@@ -53,6 +53,7 @@ const isPolicyViolationError = (error) => {
|
|
|
53
53
|
(message === null || message === void 0 ? void 0 : message.toLowerCase().includes('explicitly denied by policy')));
|
|
54
54
|
};
|
|
55
55
|
const transactionErrorMessage = (err) => {
|
|
56
|
+
var _a, _b;
|
|
56
57
|
let error = err;
|
|
57
58
|
if (isTransactionExecutionError(err)) {
|
|
58
59
|
error = err.walk();
|
|
@@ -80,6 +81,13 @@ const transactionErrorMessage = (err) => {
|
|
|
80
81
|
if (isConfirmationTimeoutError(error)) {
|
|
81
82
|
return undefined; // Use translation key in UI for timeout message
|
|
82
83
|
}
|
|
84
|
+
// Midnight: every transaction needs DUST to pay fees. The wallet client throws
|
|
85
|
+
// "No dust balance — register dust first" when the wallet has no registered
|
|
86
|
+
// dust, so surface an actionable message instead of the generic fallback.
|
|
87
|
+
const message = (_b = (_a = getMessage(error)) === null || _a === void 0 ? void 0 : _a.toLowerCase()) !== null && _b !== void 0 ? _b : '';
|
|
88
|
+
if (message.includes('no dust') || message.includes('register dust')) {
|
|
89
|
+
return 'You need DUST to pay network fees. Register DUST first, then try again.';
|
|
90
|
+
}
|
|
83
91
|
return 'Something went wrong with the transaction. Please try again.';
|
|
84
92
|
};
|
|
85
93
|
const isMagicInsufficientFundsError = (error) => {
|
|
@@ -8,6 +8,7 @@ var jsxRuntime = require('react/jsx-runtime');
|
|
|
8
8
|
var React = require('react');
|
|
9
9
|
var reactI18next = require('react-i18next');
|
|
10
10
|
var walletConnectorCore = require('@dynamic-labs/wallet-connector-core');
|
|
11
|
+
var Button = require('../../../../components/Button/Button.cjs');
|
|
11
12
|
var Skeleton = require('../../../../components/Skeleton/Skeleton.cjs');
|
|
12
13
|
require('../../../../context/DynamicContext/useDynamicContext/useDynamicContext.cjs');
|
|
13
14
|
var useInternalDynamicContext = require('../../../../context/DynamicContext/useDynamicContext/useInternalDynamicContext/useInternalDynamicContext.cjs');
|
|
@@ -26,6 +27,9 @@ var classNames = require('../../../../utils/functions/classNames/classNames.cjs'
|
|
|
26
27
|
var usePromise = require('../../../../utils/hooks/usePromise/usePromise.cjs');
|
|
27
28
|
|
|
28
29
|
const DUST_SEGMENTS = 20;
|
|
30
|
+
// Stable keys for the fixed-length decorative dust bar so the segments don't
|
|
31
|
+
// rely on the array index as their React key.
|
|
32
|
+
const DUST_SEGMENT_KEYS = Array.from({ length: DUST_SEGMENTS }, (_, i) => `dust-segment-${i}`);
|
|
29
33
|
const truncateToDecimals = (value, decimals) => {
|
|
30
34
|
const [whole, fractional] = value.split('.');
|
|
31
35
|
if (!fractional || decimals <= 0)
|
|
@@ -61,6 +65,10 @@ const ActiveMidnightWalletBalance = ({ isLoading = false, }) => {
|
|
|
61
65
|
const [activeTab, setActiveTab] = React.useState('shielded');
|
|
62
66
|
const walletAddress = primaryWallet === null || primaryWallet === void 0 ? void 0 : primaryWallet.address;
|
|
63
67
|
const enabled = Boolean(!isLoading && primaryWallet && walletConnectorCore.isMidnightConnector(primaryWallet.connector));
|
|
68
|
+
// Balance reads resolve on shielded+unshielded; dust finishes in the
|
|
69
|
+
// background. While dust is still syncing we re-fetch on an interval so the
|
|
70
|
+
// dust gauge fills in once it's ready (shielded/unshielded already final).
|
|
71
|
+
const [dustPollTick, setDustPollTick] = React.useState(0);
|
|
64
72
|
const { data: balances, isLoading: balancesLoading } = usePromise.usePromise(() => _tslib.__awaiter(void 0, void 0, void 0, function* () {
|
|
65
73
|
if (!primaryWallet ||
|
|
66
74
|
!walletConnectorCore.isMidnightConnector(primaryWallet.connector) ||
|
|
@@ -69,11 +77,31 @@ const ActiveMidnightWalletBalance = ({ isLoading = false, }) => {
|
|
|
69
77
|
}
|
|
70
78
|
return primaryWallet.getFormattedBalances();
|
|
71
79
|
}), {
|
|
72
|
-
deps: [walletAddress, primaryWallet],
|
|
80
|
+
deps: [walletAddress, primaryWallet, dustPollTick],
|
|
73
81
|
enabled,
|
|
74
82
|
});
|
|
75
|
-
const { dustBalance, shieldedBalance, unshieldedBalance } = balances !== null && balances !== void 0 ? balances : {};
|
|
76
|
-
|
|
83
|
+
const { dustBalance, shieldedBalance, unshieldedBalance, dustSyncing } = balances !== null && balances !== void 0 ? balances : {};
|
|
84
|
+
React.useEffect(() => {
|
|
85
|
+
if (!dustSyncing)
|
|
86
|
+
return undefined;
|
|
87
|
+
const id = setInterval(() => setDustPollTick((tick) => tick + 1), 15000);
|
|
88
|
+
return () => clearInterval(id);
|
|
89
|
+
}, [dustSyncing]);
|
|
90
|
+
// `registerDust` is a WaaS-only connector method (external/injected Midnight
|
|
91
|
+
// wallets manage dust themselves). When the embedded wallet has no dust
|
|
92
|
+
// registered yet, we surface a "Register DUST" button instead of the gauge.
|
|
93
|
+
const isWaasWallet = Boolean(primaryWallet && walletConnectorCore.isDynamicWaasConnector(primaryWallet.connector));
|
|
94
|
+
const handleRegisterDust = () => _tslib.__awaiter(void 0, void 0, void 0, function* () {
|
|
95
|
+
const connector = primaryWallet === null || primaryWallet === void 0 ? void 0 : primaryWallet.connector;
|
|
96
|
+
if (!(connector === null || connector === void 0 ? void 0 : connector.registerDust))
|
|
97
|
+
return;
|
|
98
|
+
yield connector.registerDust();
|
|
99
|
+
// Dust generation begins after registration; re-fetch so the gauge appears.
|
|
100
|
+
setDustPollTick((tick) => tick + 1);
|
|
101
|
+
});
|
|
102
|
+
// Only show the full skeleton on the very first load; background dust polls
|
|
103
|
+
// keep `balances` populated so the view never flashes back to a skeleton.
|
|
104
|
+
if ((isLoading || balancesLoading) && !balances) {
|
|
77
105
|
return (jsxRuntime.jsx("div", { className: 'active-midnight-balance', children: jsxRuntime.jsx(Skeleton.Skeleton, { className: 'active-midnight-balance__skeleton' }) }));
|
|
78
106
|
}
|
|
79
107
|
const dustFill = dustBalance
|
|
@@ -86,16 +114,31 @@ const ActiveMidnightWalletBalance = ({ isLoading = false, }) => {
|
|
|
86
114
|
}
|
|
87
115
|
: undefined;
|
|
88
116
|
const activeBalance = activeTab === 'shielded' ? shieldedBalance : unshieldedBalance;
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
117
|
+
// Dust section has three mutually exclusive states (syncing, generating with
|
|
118
|
+
// a balance, and the WaaS "register dust" prompt). Resolved via a helper to
|
|
119
|
+
// avoid nesting ternaries in the JSX below.
|
|
120
|
+
const renderDustSection = () => {
|
|
121
|
+
if (dustSyncing) {
|
|
122
|
+
return (jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [jsxRuntime.jsx("div", { className: 'active-midnight-balance__dust', children: jsxRuntime.jsx("div", { className: 'active-midnight-balance__dust-header', children: jsxRuntime.jsxs("div", { className: 'active-midnight-balance__dust-title', children: [jsxRuntime.jsx("svg", { className: 'active-midnight-balance__dust-icon', width: '12', height: '12', viewBox: '0 0 24 24', children: jsxRuntime.jsx("path", { d: 'M13 2L3 14h9l-1 8 10-12h-9l1-8z' }) }), jsxRuntime.jsx("span", { className: 'active-midnight-balance__dust-label', "data-copykey": 'dyn_active_wallet_info.midnight_dust_syncing', children: t('dyn_active_wallet_info.midnight_dust_syncing') })] }) }) }), jsxRuntime.jsx("div", { className: 'active-midnight-balance__divider' })] }));
|
|
123
|
+
}
|
|
124
|
+
if (dustBalance) {
|
|
125
|
+
return (jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [jsxRuntime.jsxs("div", { className: 'active-midnight-balance__dust', children: [jsxRuntime.jsxs("div", { className: 'active-midnight-balance__dust-header', children: [jsxRuntime.jsxs("div", { className: 'active-midnight-balance__dust-title', children: [jsxRuntime.jsx("svg", { className: 'active-midnight-balance__dust-icon', width: '12', height: '12', viewBox: '0 0 24 24', children: jsxRuntime.jsx("path", { d: 'M13 2L3 14h9l-1 8 10-12h-9l1-8z' }) }), jsxRuntime.jsx("span", { className: 'active-midnight-balance__dust-label', "data-copykey": 'dyn_active_wallet_info.midnight_dust_generating', children: t('dyn_active_wallet_info.midnight_dust_generating') })] }), jsxRuntime.jsxs("span", { className: 'active-midnight-balance__dust-count', children: [dustBalanceDisplay === null || dustBalanceDisplay === void 0 ? void 0 : dustBalanceDisplay.balance, "/", dustBalanceDisplay === null || dustBalanceDisplay === void 0 ? void 0 : dustBalanceDisplay.cap] })] }), jsxRuntime.jsx("div", { className: 'active-midnight-balance__dust-bar', children: DUST_SEGMENT_KEYS.map((segmentKey, i) => (jsxRuntime.jsx("div", { className: [
|
|
126
|
+
'active-midnight-balance__dust-segment',
|
|
127
|
+
i === 0 && 'active-midnight-balance__dust-segment--first',
|
|
128
|
+
i === DUST_SEGMENTS - 1 &&
|
|
129
|
+
'active-midnight-balance__dust-segment--last',
|
|
130
|
+
i < dustFill &&
|
|
131
|
+
'active-midnight-balance__dust-segment--filled',
|
|
132
|
+
]
|
|
133
|
+
.filter(Boolean)
|
|
134
|
+
.join(' ') }, segmentKey))) })] }), jsxRuntime.jsx("div", { className: 'active-midnight-balance__divider' })] }));
|
|
135
|
+
}
|
|
136
|
+
if (isWaasWallet) {
|
|
137
|
+
return (jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [jsxRuntime.jsxs("div", { className: 'active-midnight-balance__dust', children: [jsxRuntime.jsx("div", { className: 'active-midnight-balance__dust-header', children: jsxRuntime.jsxs("div", { className: 'active-midnight-balance__dust-title', children: [jsxRuntime.jsx("svg", { className: 'active-midnight-balance__dust-icon', width: '12', height: '12', viewBox: '0 0 24 24', children: jsxRuntime.jsx("path", { d: 'M13 2L3 14h9l-1 8 10-12h-9l1-8z' }) }), jsxRuntime.jsx("span", { className: 'active-midnight-balance__dust-label', "data-copykey": 'dyn_active_wallet_info.midnight_dust_generating', children: t('dyn_active_wallet_info.midnight_dust_generating') })] }) }), jsxRuntime.jsx(Button.Button, { buttonPadding: 'small', buttonVariant: 'secondary', buttonClassName: 'active-midnight-balance__register-dust-button', onClick: handleRegisterDust, "data-copykey": 'dyn_active_wallet_info.midnight_register_dust', children: t('dyn_active_wallet_info.midnight_register_dust') })] }), jsxRuntime.jsx("div", { className: 'active-midnight-balance__divider' })] }));
|
|
138
|
+
}
|
|
139
|
+
return null;
|
|
140
|
+
};
|
|
141
|
+
return (jsxRuntime.jsx("div", { className: 'active-midnight-balance', children: jsxRuntime.jsxs("div", { className: 'active-midnight-balance__card', children: [renderDustSection(), jsxRuntime.jsx("div", { className: 'active-midnight-balance__tab-bar', children: TABS.map(({ id, copykey }) => (jsxRuntime.jsx("button", { className: classNames.classNames('active-midnight-balance__tab', {
|
|
99
142
|
'active-midnight-balance__tab--active': activeTab === id,
|
|
100
143
|
}), "data-copykey": copykey, onClick: () => setActiveTab(id), children: t(copykey) }, id))) }), jsxRuntime.jsxs("div", { className: 'active-midnight-balance__pocket', children: [activeTab === 'shielded' ? (jsxRuntime.jsx(midnightShielded.ReactComponent, { className: 'active-midnight-balance__pocket-icon' })) : (jsxRuntime.jsx(midnightUnshielded.ReactComponent, { className: 'active-midnight-balance__pocket-icon' })), jsxRuntime.jsxs("span", { className: 'active-midnight-balance__amount', children: [activeBalance !== null && activeBalance !== void 0 ? activeBalance : '—', " NIGHT"] })] })] }) }));
|
|
101
144
|
};
|