@dynamic-labs/sdk-react-core 4.102.0 → 4.104.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.
Files changed (28) hide show
  1. package/CHANGELOG.md +29 -0
  2. package/package.cjs +3 -3
  3. package/package.js +3 -3
  4. package/package.json +14 -14
  5. package/src/lib/components/NeedHelpSection/NeedHelpSection.cjs +3 -4
  6. package/src/lib/components/NeedHelpSection/NeedHelpSection.d.ts +4 -1
  7. package/src/lib/components/NeedHelpSection/NeedHelpSection.js +3 -4
  8. package/src/lib/components/TransactionCard/SendBalanceTransactionCard.cjs +8 -8
  9. package/src/lib/components/TransactionCard/SendBalanceTransactionCard.d.ts +3 -1
  10. package/src/lib/components/TransactionCard/SendBalanceTransactionCard.js +8 -8
  11. package/src/lib/components/TransactionConfirmationPageLayout/TransactionConfirmationPageLayout.cjs +1 -1
  12. package/src/lib/components/TransactionConfirmationPageLayout/TransactionConfirmationPageLayout.js +1 -1
  13. package/src/lib/shared/types/embeddedWallets.d.ts +2 -0
  14. package/src/lib/store/utils/settingsUtils/settingsUtils.cjs +21 -2
  15. package/src/lib/store/utils/settingsUtils/settingsUtils.js +21 -2
  16. package/src/lib/styles/index.shadow.cjs +1 -1
  17. package/src/lib/styles/index.shadow.js +1 -1
  18. package/src/lib/utils/hooks/usePasskeyRecovery/usePasskeyRecovery.cjs +10 -6
  19. package/src/lib/utils/hooks/usePasskeyRecovery/usePasskeyRecovery.js +10 -6
  20. package/src/lib/utils/hooks/useSyncDynamicWaas/useSyncDynamicWaas.cjs +3 -1
  21. package/src/lib/utils/hooks/useSyncDynamicWaas/useSyncDynamicWaas.js +3 -1
  22. package/src/lib/views/BackupUnsuccessfulView/BackupUnsuccessfulView.cjs +2 -2
  23. package/src/lib/views/BackupUnsuccessfulView/BackupUnsuccessfulView.d.ts +4 -1
  24. package/src/lib/views/BackupUnsuccessfulView/BackupUnsuccessfulView.js +2 -2
  25. package/src/lib/views/WalletUpgradeFlowView/WalletUpgradeFlowView.cjs +28 -7
  26. package/src/lib/views/WalletUpgradeFlowView/WalletUpgradeFlowView.d.ts +1 -0
  27. package/src/lib/views/WalletUpgradeFlowView/WalletUpgradeFlowView.js +30 -9
  28. package/src/lib/views/viewToComponentMap.d.ts +3 -1
@@ -99,7 +99,10 @@ const usePasskeyRecovery = () => {
99
99
  return true;
100
100
  }), [wallet, isTurnkeyWalletWithoutAuthenticator, isSessionRestored]);
101
101
  const initPasskeyRecoveryProcess = React.useCallback((authenticatorType, currentAction) => _tslib.__awaiter(void 0, void 0, void 0, function* () {
102
- var _f;
102
+ var _f, _g, _h;
103
+ // Recovery can target a non-primary wallet (e.g. a later wallet in the
104
+ // upgrade flow); fall back to the primary wallet.
105
+ const recoveryWallet = (_g = (_f = currentAction === null || currentAction === void 0 ? void 0 : currentAction.settings) === null || _f === void 0 ? void 0 : _f.wallet) !== null && _g !== void 0 ? _g : wallet;
103
106
  const validateRecoveryRequest = () => {
104
107
  if (!user$1) {
105
108
  throw new Error(errors.USER_NOT_LOGGED_IN);
@@ -110,25 +113,26 @@ const usePasskeyRecovery = () => {
110
113
  if (!hasEmbeddedWallet.hasEmbeddedWallet(user$1)) {
111
114
  throw new Error('Dynamic embedded wallet not found');
112
115
  }
113
- if (wallet && !walletConnectorCore.isPasskeyWalletConnector(wallet.connector)) {
116
+ if (recoveryWallet &&
117
+ !walletConnectorCore.isPasskeyWalletConnector(recoveryWallet.connector)) {
114
118
  throw new Error('Dynamic embedded wallet not found.');
115
119
  }
116
120
  };
117
121
  validateRecoveryRequest();
118
- const turnkeyRecoveryHandler = (wallet === null || wallet === void 0 ? void 0 : wallet.connector).getAuthenticatorHandler();
122
+ const turnkeyRecoveryHandler = (recoveryWallet === null || recoveryWallet === void 0 ? void 0 : recoveryWallet.connector).getAuthenticatorHandler();
119
123
  // email auth - session is still up, so create passkey authenticator usign the same session
120
124
  if (authenticatorType === 'passkey' &&
121
125
  turnkeyRecoveryHandler.isSessionActive()) {
122
126
  yield passkeyRecovery.addNewPasskeyAuthenticator({
123
127
  environmentId,
124
128
  user: user$1,
125
- wallet: wallet,
129
+ wallet: recoveryWallet,
126
130
  });
127
131
  setShowAuthFlow(false);
128
132
  // eslint-disable-next-line @typescript-eslint/no-non-null-assertion
129
- return wallet;
133
+ return recoveryWallet;
130
134
  }
131
- const supportedAuthenticators = getEnabledEmbeddedWalletsAuthenticators.getEnabledEmbeddedWalletsAuthenticators((_f = projectSettings === null || projectSettings === void 0 ? void 0 : projectSettings.sdk.embeddedWallets) === null || _f === void 0 ? void 0 : _f.supportedSecurityMethods);
135
+ const supportedAuthenticators = getEnabledEmbeddedWalletsAuthenticators.getEnabledEmbeddedWalletsAuthenticators((_h = projectSettings === null || projectSettings === void 0 ? void 0 : projectSettings.sdk.embeddedWallets) === null || _h === void 0 ? void 0 : _h.supportedSecurityMethods);
132
136
  const supportedAuthenticatorMethods = supportedAuthenticators
133
137
  ? Object.keys(supportedAuthenticators)
134
138
  : [];
@@ -95,7 +95,10 @@ const usePasskeyRecovery = () => {
95
95
  return true;
96
96
  }), [wallet, isTurnkeyWalletWithoutAuthenticator, isSessionRestored]);
97
97
  const initPasskeyRecoveryProcess = useCallback((authenticatorType, currentAction) => __awaiter(void 0, void 0, void 0, function* () {
98
- var _f;
98
+ var _f, _g, _h;
99
+ // Recovery can target a non-primary wallet (e.g. a later wallet in the
100
+ // upgrade flow); fall back to the primary wallet.
101
+ const recoveryWallet = (_g = (_f = currentAction === null || currentAction === void 0 ? void 0 : currentAction.settings) === null || _f === void 0 ? void 0 : _f.wallet) !== null && _g !== void 0 ? _g : wallet;
99
102
  const validateRecoveryRequest = () => {
100
103
  if (!user) {
101
104
  throw new Error(USER_NOT_LOGGED_IN);
@@ -106,25 +109,26 @@ const usePasskeyRecovery = () => {
106
109
  if (!hasEmbeddedWallet(user)) {
107
110
  throw new Error('Dynamic embedded wallet not found');
108
111
  }
109
- if (wallet && !isPasskeyWalletConnector(wallet.connector)) {
112
+ if (recoveryWallet &&
113
+ !isPasskeyWalletConnector(recoveryWallet.connector)) {
110
114
  throw new Error('Dynamic embedded wallet not found.');
111
115
  }
112
116
  };
113
117
  validateRecoveryRequest();
114
- const turnkeyRecoveryHandler = (wallet === null || wallet === void 0 ? void 0 : wallet.connector).getAuthenticatorHandler();
118
+ const turnkeyRecoveryHandler = (recoveryWallet === null || recoveryWallet === void 0 ? void 0 : recoveryWallet.connector).getAuthenticatorHandler();
115
119
  // email auth - session is still up, so create passkey authenticator usign the same session
116
120
  if (authenticatorType === 'passkey' &&
117
121
  turnkeyRecoveryHandler.isSessionActive()) {
118
122
  yield addNewPasskeyAuthenticator({
119
123
  environmentId,
120
124
  user,
121
- wallet: wallet,
125
+ wallet: recoveryWallet,
122
126
  });
123
127
  setShowAuthFlow(false);
124
128
  // eslint-disable-next-line @typescript-eslint/no-non-null-assertion
125
- return wallet;
129
+ return recoveryWallet;
126
130
  }
127
- const supportedAuthenticators = getEnabledEmbeddedWalletsAuthenticators((_f = projectSettings === null || projectSettings === void 0 ? void 0 : projectSettings.sdk.embeddedWallets) === null || _f === void 0 ? void 0 : _f.supportedSecurityMethods);
131
+ const supportedAuthenticators = getEnabledEmbeddedWalletsAuthenticators((_h = projectSettings === null || projectSettings === void 0 ? void 0 : projectSettings.sdk.embeddedWallets) === null || _h === void 0 ? void 0 : _h.supportedSecurityMethods);
128
132
  const supportedAuthenticatorMethods = supportedAuthenticators
129
133
  ? Object.keys(supportedAuthenticators)
130
134
  : [];
@@ -123,7 +123,9 @@ const useWalletCreation = () => {
123
123
  }
124
124
  logger.logger.error('Error creating dynamic waas wallet', error);
125
125
  setShowAuthFlow(true, { ignoreIfIsEmbeddedWidget: false });
126
- clearStackAndPush('backup-unsuccessful');
126
+ clearStackAndPush('backup-unsuccessful', {
127
+ errorMessage: error.message,
128
+ });
127
129
  },
128
130
  });
129
131
  };
@@ -119,7 +119,9 @@ const useWalletCreation = () => {
119
119
  }
120
120
  logger.error('Error creating dynamic waas wallet', error);
121
121
  setShowAuthFlow(true, { ignoreIfIsEmbeddedWidget: false });
122
- clearStackAndPush('backup-unsuccessful');
122
+ clearStackAndPush('backup-unsuccessful', {
123
+ errorMessage: error.message,
124
+ });
123
125
  },
124
126
  });
125
127
  };
@@ -124,7 +124,7 @@ require('../../components/IsBrowser/IsBrowser.cjs');
124
124
  require('../../components/Popper/Popper/Popper.cjs');
125
125
  require('../../components/Popper/PopperContext/PopperContext.cjs');
126
126
 
127
- const BackupUnsuccessfulView = () => {
127
+ const BackupUnsuccessfulView = ({ errorMessage, }) => {
128
128
  var _a, _b;
129
129
  const { t } = reactI18next.useTranslation();
130
130
  const projectSettings = useProjectSettings.useProjectSettings();
@@ -167,7 +167,7 @@ const BackupUnsuccessfulView = () => {
167
167
  position: 'absolute',
168
168
  top: '50%',
169
169
  transform: 'translate(-50%, -50%)',
170
- } })] })] }), jsxRuntime.jsx(Typography.Typography, { variant: 'body_normal', className: 'backup-message', color: 'primary', copykey: 'dyn_waas.backup_unsuccessful.description', children: t('dyn_waas.backup_unsuccessful.description') }), jsxRuntime.jsx("div", { className: classNames.classNames('button-group', {
170
+ } })] })] }), jsxRuntime.jsx(Typography.Typography, { variant: 'body_normal', className: 'backup-message', color: 'primary', copykey: 'dyn_waas.backup_unsuccessful.description', children: t('dyn_waas.backup_unsuccessful.description') }), errorMessage && (jsxRuntime.jsx(Typography.Typography, { variant: 'body_mini', color: 'error-1', className: 'backup-error-message', children: errorMessage })), jsxRuntime.jsx("div", { className: classNames.classNames('button-group', {
171
171
  'button-group--with-help-section': hasContactInfo,
172
172
  }), children: jsxRuntime.jsx(TypographyButton.TypographyButton, { buttonClassName: 'retry-button', buttonVariant: 'brand-primary', type: 'submit', onClick: onTryAgainClick, copykey: 'dyn_waas.backup_unsuccessful.try_again', typographyProps: {
173
173
  color: 'inherit',
@@ -1,3 +1,6 @@
1
1
  import React from 'react';
2
- export declare const BackupUnsuccessfulView: React.FC;
2
+ type BackupUnsuccessfulViewProps = {
3
+ errorMessage?: string;
4
+ };
5
+ export declare const BackupUnsuccessfulView: React.FC<BackupUnsuccessfulViewProps>;
3
6
  export default BackupUnsuccessfulView;
@@ -120,7 +120,7 @@ import '../../components/IsBrowser/IsBrowser.js';
120
120
  import '../../components/Popper/Popper/Popper.js';
121
121
  import '../../components/Popper/PopperContext/PopperContext.js';
122
122
 
123
- const BackupUnsuccessfulView = () => {
123
+ const BackupUnsuccessfulView = ({ errorMessage, }) => {
124
124
  var _a, _b;
125
125
  const { t } = useTranslation();
126
126
  const projectSettings = useProjectSettings();
@@ -163,7 +163,7 @@ const BackupUnsuccessfulView = () => {
163
163
  position: 'absolute',
164
164
  top: '50%',
165
165
  transform: 'translate(-50%, -50%)',
166
- } })] })] }), jsx(Typography, { variant: 'body_normal', className: 'backup-message', color: 'primary', copykey: 'dyn_waas.backup_unsuccessful.description', children: t('dyn_waas.backup_unsuccessful.description') }), jsx("div", { className: classNames('button-group', {
166
+ } })] })] }), jsx(Typography, { variant: 'body_normal', className: 'backup-message', color: 'primary', copykey: 'dyn_waas.backup_unsuccessful.description', children: t('dyn_waas.backup_unsuccessful.description') }), errorMessage && (jsx(Typography, { variant: 'body_mini', color: 'error-1', className: 'backup-error-message', children: errorMessage })), jsx("div", { className: classNames('button-group', {
167
167
  'button-group--with-help-section': hasContactInfo,
168
168
  }), children: jsx(TypographyButton, { buttonClassName: 'retry-button', buttonVariant: 'brand-primary', type: 'submit', onClick: onTryAgainClick, copykey: 'dyn_waas.backup_unsuccessful.try_again', typographyProps: {
169
169
  color: 'inherit',
@@ -78,6 +78,7 @@ var ErrorContainer = require('../../components/ErrorContainer/ErrorContainer.cjs
78
78
  require('../../components/IconButton/IconButton.cjs');
79
79
  var ModalHeader = require('../../components/ModalHeader/ModalHeader.cjs');
80
80
  var TypographyButton = require('../../components/TypographyButton/TypographyButton.cjs');
81
+ var getProperErrorMessage = require('../../modals/SignMessageConfirmationModal/getProperErrorMessage.cjs');
81
82
  var useDynamicWaas = require('../../utils/hooks/useDynamicWaas/useDynamicWaas.cjs');
82
83
  var useRefreshAuth = require('../../utils/hooks/useRefreshAuth/useRefreshAuth.cjs');
83
84
  require('../../utils/hooks/useWalletDelegation/DelegationError.cjs');
@@ -104,6 +105,7 @@ require('../../widgets/DynamicWidget/views/ManagePasskeysMfaWidgetView/ManagePas
104
105
  require('../../widgets/DynamicWidget/views/ManageTotpMfaWidgetView/ManageTotpMfaWidgetView.cjs');
105
106
  require('../../widgets/DynamicWidget/views/ReceiveWalletFunds/ReceiveWalletFunds.cjs');
106
107
  var Textarea = require('../../components/Textarea/Textarea.cjs');
108
+ var NeedHelpSection = require('../../components/NeedHelpSection/NeedHelpSection.cjs');
107
109
  require('@hcaptcha/react-hcaptcha');
108
110
  require('@marsidev/react-turnstile');
109
111
  require('../../context/IpConfigurationContext/IpConfigurationContext.cjs');
@@ -124,19 +126,20 @@ require('../../components/IsBrowser/IsBrowser.cjs');
124
126
  require('../../components/Popper/Popper/Popper.cjs');
125
127
  require('../../components/Popper/PopperContext/PopperContext.cjs');
126
128
 
127
- const WalletUpgradeFlowView = ({ wallets, method, onComplete, onCancel, }) => {
128
- var _a;
129
+ const WalletUpgradeFlowView = ({ wallets, method, startIndex = 0, onComplete, onCancel, }) => {
130
+ var _a, _b;
129
131
  const { setShowAuthFlow, user, environmentId } = useInternalDynamicContext.useInternalDynamicContext();
130
132
  const { upgradeToDynamicWaas } = useDynamicWaas.useDynamicWaas();
131
133
  const { t } = reactI18next.useTranslation();
132
134
  const { pushView } = ViewContext.useViewContext();
133
- const [currentWalletIndex, setCurrentWalletIndex] = React.useState(0);
135
+ const [currentWalletIndex, setCurrentWalletIndex] = React.useState(startIndex);
134
136
  const [privateKeyInput, setPrivateKeyInput] = React.useState('');
135
137
  const [iframeContainerRef, setIframeContainerRef] = React.useState(null);
136
138
  const isLastWallet = currentWalletIndex === wallets.length - 1;
137
139
  const completedSteps = currentWalletIndex;
138
140
  const totalSteps = wallets.length;
139
141
  const refresh = useRefreshAuth.useRefreshAuth();
142
+ const walletCredential = (_a = user === null || user === void 0 ? void 0 : user.verifiedCredentials) === null || _a === void 0 ? void 0 : _a.find((cred) => { var _a; return cred.address === ((_a = wallets[currentWalletIndex]) === null || _a === void 0 ? void 0 : _a.address); });
140
143
  // Check if current wallet is a WaaS wallet based on its properties
141
144
  const isWaasWallet = Boolean(user === null || user === void 0 ? void 0 : user.verifiedCredentials.find((vc) => { var _a; return (_a = vc.walletName) === null || _a === void 0 ? void 0 : _a.startsWith('dynamicwaas'); }));
142
145
  const onExportReady = (isReady, wallet) => {
@@ -159,6 +162,22 @@ const WalletUpgradeFlowView = ({ wallets, method, onComplete, onCancel, }) => {
159
162
  dynamicEvents.dynamicEvents.emit('embeddedWalletRevealFailed', err);
160
163
  },
161
164
  });
165
+ // Map the raw export failure (e.g. a rejected WebAuthn ceremony) to the
166
+ // same user-facing copy the main widget export view shows.
167
+ const exportErrorText = React.useMemo(() => {
168
+ if (!exportError) {
169
+ return undefined;
170
+ }
171
+ try {
172
+ return getProperErrorMessage.getProperErrorMessage(exportError, user);
173
+ }
174
+ catch (e) {
175
+ if (e instanceof utils.AccessBlockedError) {
176
+ pushView('access-blocked');
177
+ }
178
+ return undefined;
179
+ }
180
+ }, [exportError, pushView, user]);
162
181
  // Track successful export for emitting event on unmount
163
182
  const revealedWalletRef = React.useRef(null);
164
183
  React.useEffect(() => {
@@ -216,11 +235,13 @@ const WalletUpgradeFlowView = ({ wallets, method, onComplete, onCancel, }) => {
216
235
  ? 'wallet-upgrade-flow-view__step--completed'
217
236
  : ''} ${index === currentWalletIndex
218
237
  ? 'wallet-upgrade-flow-view__step--current'
219
- : ''}`, children: [jsxRuntime.jsx("div", { className: 'wallet-upgrade-flow-view__step-indicator', children: index < completedSteps ? (jsxRuntime.jsx("div", { className: 'wallet-upgrade-flow-view__step-check', children: "\u2713" })) : (jsxRuntime.jsx("div", { className: 'wallet-upgrade-flow-view__step-number', children: index + 1 })) }), jsxRuntime.jsx(Typography.Typography, { variant: 'body_small', color: index <= currentWalletIndex ? 'primary' : 'secondary', className: 'wallet-upgrade-flow-view__step-title', children: getStepTitle(index) })] }), index < totalSteps - 1 && (jsxRuntime.jsx("div", { className: 'wallet-upgrade-flow-view__step-separator' }))] }, index))) }) })) }), jsxRuntime.jsxs("div", { className: 'wallet-upgrade-flow-view__content', children: [exportError && (jsxRuntime.jsx(ErrorContainer.ErrorContainer, { className: 'wallet-upgrade-flow-view__error', children: exportError instanceof Error
220
- ? exportError.message
221
- : t('dyn_wallet_upgrade_flow.export_failed') })), upgradeError && (jsxRuntime.jsx(ErrorContainer.ErrorContainer, { className: 'wallet-upgrade-flow-view__error', children: upgradeError instanceof Error
238
+ : ''}`, children: [jsxRuntime.jsx("div", { className: 'wallet-upgrade-flow-view__step-indicator', children: index < completedSteps ? (jsxRuntime.jsx("div", { className: 'wallet-upgrade-flow-view__step-check', children: "\u2713" })) : (jsxRuntime.jsx("div", { className: 'wallet-upgrade-flow-view__step-number', children: index + 1 })) }), jsxRuntime.jsx(Typography.Typography, { variant: 'body_small', color: index <= currentWalletIndex ? 'primary' : 'secondary', className: 'wallet-upgrade-flow-view__step-title', children: getStepTitle(index) })] }), index < totalSteps - 1 && (jsxRuntime.jsx("div", { className: 'wallet-upgrade-flow-view__step-separator' }))] }, index))) }) })) }), jsxRuntime.jsxs("div", { className: 'wallet-upgrade-flow-view__content', children: [exportError && (jsxRuntime.jsx(ErrorContainer.ErrorContainer, { className: 'wallet-upgrade-flow-view__error', children: exportErrorText !== null && exportErrorText !== void 0 ? exportErrorText : t('dyn_wallet_upgrade_flow.export_failed') })), upgradeError && (jsxRuntime.jsx(ErrorContainer.ErrorContainer, { className: 'wallet-upgrade-flow-view__error', children: upgradeError instanceof Error
222
239
  ? upgradeError.message
223
- : t('dyn_wallet_upgrade_flow.upgrade_failed') })), jsxRuntime.jsxs("div", { className: 'wallet-upgrade-flow-view__title-section', children: [jsxRuntime.jsx(Typography.Typography, { as: 'h1', variant: 'title', color: 'primary', children: t('dyn_wallet_upgrade_flow.title') }), jsxRuntime.jsx(Typography.Typography, { color: 'secondary', className: 'wallet-upgrade-flow-view__subtitle', children: t('dyn_wallet_upgrade_flow.copy_private_key_subtitle') })] }), jsxRuntime.jsxs("div", { className: 'wallet-upgrade-flow-view__export-section', children: [jsxRuntime.jsx(Typography.Typography, { color: 'primary', variant: 'body_normal', weight: 'bold', className: 'wallet-upgrade-flow-view__section-title', children: t('dyn_wallet_upgrade_flow.copy_private_key_title') }), jsxRuntime.jsx(EmbeddedWalletExport.EmbeddedWalletExport, { wallet: wallets[currentWalletIndex], isTurnkeyWallet: true, isWaasWallet: isWaasWallet, data: exportData, onIframeContainerRef: setIframeContainerRef, onExportReady: onExportReady }, `wallet-export-${currentWalletIndex}-${(_a = wallets[currentWalletIndex]) === null || _a === void 0 ? void 0 : _a.id}`)] }), jsxRuntime.jsx("div", { className: 'wallet-upgrade-flow-view__input-section', children: jsxRuntime.jsxs("div", { className: 'wallet-upgrade-flow-view__input-container', children: [jsxRuntime.jsxs(Typography.Typography, { variant: 'body_normal', weight: 'bold', color: 'primary', copykey: 'dyn_embedded_reveal.step_2_title', children: [jsxRuntime.jsx("span", { className: 'wallet-upgrade-flow__step-description', children: t('dyn_wallet_upgrade_flow.step_2_upgrade_description') }), ' '] }), jsxRuntime.jsx(Textarea.Textarea, { id: 'paste-private-key-input', value: privateKeyInput, onChange: (e) => setPrivateKeyInput(e.target.value), variant: 'regular', className: 'wallet-upgrade-flow__paste-input', label: '' })] }) })] }), jsxRuntime.jsxs("div", { className: 'wallet-upgrade-flow-view__actions', children: [jsxRuntime.jsx(TypographyButton.TypographyButton, { buttonVariant: 'brand-primary', onClick: () => handleUpgradeWallet(), disabled: !privateKeyInput.trim() || isUpgrading, loading: isUpgrading, copykey: 'dyn_wallet_upgrade_flow.upgrade_button', typographyProps: {
240
+ : t('dyn_wallet_upgrade_flow.upgrade_failed') })), jsxRuntime.jsxs("div", { className: 'wallet-upgrade-flow-view__title-section', children: [jsxRuntime.jsx(Typography.Typography, { as: 'h1', variant: 'title', color: 'primary', children: t('dyn_wallet_upgrade_flow.title') }), jsxRuntime.jsx(Typography.Typography, { color: 'secondary', className: 'wallet-upgrade-flow-view__subtitle', children: t('dyn_wallet_upgrade_flow.copy_private_key_subtitle') })] }), jsxRuntime.jsxs("div", { className: 'wallet-upgrade-flow-view__export-section', children: [jsxRuntime.jsx(Typography.Typography, { color: 'primary', variant: 'body_normal', weight: 'bold', className: 'wallet-upgrade-flow-view__section-title', children: t('dyn_wallet_upgrade_flow.copy_private_key_title') }), jsxRuntime.jsx(EmbeddedWalletExport.EmbeddedWalletExport, { wallet: wallets[currentWalletIndex], isTurnkeyWallet: true, isWaasWallet: isWaasWallet, data: exportData, onIframeContainerRef: setIframeContainerRef, onExportReady: onExportReady }, `wallet-export-${currentWalletIndex}-${(_b = wallets[currentWalletIndex]) === null || _b === void 0 ? void 0 : _b.id}`)] }), jsxRuntime.jsx("div", { className: 'wallet-upgrade-flow-view__input-section', children: jsxRuntime.jsxs("div", { className: 'wallet-upgrade-flow-view__input-container', children: [jsxRuntime.jsxs(Typography.Typography, { variant: 'body_normal', weight: 'bold', color: 'primary', copykey: 'dyn_embedded_reveal.step_2_title', children: [jsxRuntime.jsx("span", { className: 'wallet-upgrade-flow__step-description', children: t('dyn_wallet_upgrade_flow.step_2_upgrade_description') }), ' '] }), jsxRuntime.jsx(Textarea.Textarea, { id: 'paste-private-key-input', value: privateKeyInput, onChange: (e) => setPrivateKeyInput(e.target.value), variant: 'regular', className: 'wallet-upgrade-flow__paste-input', label: '' })] }) }), exportError && (jsxRuntime.jsx(NeedHelpSection.NeedHelpSection, { isExport: true, walletCredential: walletCredential, wallet: wallets[currentWalletIndex], goBack: () => pushView('wallet-upgrade-flow-view', {
241
+ method,
242
+ startIndex: currentWalletIndex,
243
+ wallets,
244
+ }) }))] }), jsxRuntime.jsxs("div", { className: 'wallet-upgrade-flow-view__actions', children: [jsxRuntime.jsx(TypographyButton.TypographyButton, { buttonVariant: 'brand-primary', onClick: () => handleUpgradeWallet(), disabled: !privateKeyInput.trim() || isUpgrading, loading: isUpgrading, copykey: 'dyn_wallet_upgrade_flow.upgrade_button', typographyProps: {
224
245
  color: 'inherit',
225
246
  }, expanded: true, children: t('dyn_wallet_upgrade_flow.upgrade_wallet') }), jsxRuntime.jsx(TypographyButton.TypographyButton, { buttonVariant: 'tertiary', onClick: handleClose, disabled: isUpgrading, children: t('dyn_wallet_upgrade_flow.cancel') })] })] }));
226
247
  };
@@ -3,6 +3,7 @@ import { Wallet, WalletConnectorCore } from '@dynamic-labs/wallet-connector-core
3
3
  export interface WalletUpgradeFlowViewProps {
4
4
  wallets: Wallet<WalletConnectorCore.WalletConnector>[];
5
5
  method: 'new' | 'existing';
6
+ startIndex?: number;
6
7
  onComplete?: () => void;
7
8
  onCancel?: () => void;
8
9
  }
@@ -1,9 +1,9 @@
1
1
  'use client'
2
2
  import { __awaiter } from '../../../../_virtual/_tslib.js';
3
3
  import { jsxs, jsx } from 'react/jsx-runtime';
4
- import { useState, useRef, useEffect } from 'react';
4
+ import { useState, useMemo, useRef, useEffect } from 'react';
5
5
  import { useTranslation } from 'react-i18next';
6
- import { DynamicError } from '@dynamic-labs/utils';
6
+ import { AccessBlockedError, DynamicError } from '@dynamic-labs/utils';
7
7
  import '../../components/Accordion/components/AccordionItem/AccordionItem.js';
8
8
  import '@dynamic-labs/iconic';
9
9
  import { useViewContext } from '../../context/ViewContext/ViewContext.js';
@@ -74,6 +74,7 @@ import { ErrorContainer } from '../../components/ErrorContainer/ErrorContainer.j
74
74
  import '../../components/IconButton/IconButton.js';
75
75
  import { ModalHeader } from '../../components/ModalHeader/ModalHeader.js';
76
76
  import { TypographyButton } from '../../components/TypographyButton/TypographyButton.js';
77
+ import { getProperErrorMessage } from '../../modals/SignMessageConfirmationModal/getProperErrorMessage.js';
77
78
  import { useDynamicWaas } from '../../utils/hooks/useDynamicWaas/useDynamicWaas.js';
78
79
  import { useRefreshAuth } from '../../utils/hooks/useRefreshAuth/useRefreshAuth.js';
79
80
  import '../../utils/hooks/useWalletDelegation/DelegationError.js';
@@ -100,6 +101,7 @@ import '../../widgets/DynamicWidget/views/ManagePasskeysMfaWidgetView/ManagePass
100
101
  import '../../widgets/DynamicWidget/views/ManageTotpMfaWidgetView/ManageTotpMfaWidgetView.js';
101
102
  import '../../widgets/DynamicWidget/views/ReceiveWalletFunds/ReceiveWalletFunds.js';
102
103
  import { Textarea } from '../../components/Textarea/Textarea.js';
104
+ import { NeedHelpSection } from '../../components/NeedHelpSection/NeedHelpSection.js';
103
105
  import '@hcaptcha/react-hcaptcha';
104
106
  import '@marsidev/react-turnstile';
105
107
  import '../../context/IpConfigurationContext/IpConfigurationContext.js';
@@ -120,19 +122,20 @@ import '../../components/IsBrowser/IsBrowser.js';
120
122
  import '../../components/Popper/Popper/Popper.js';
121
123
  import '../../components/Popper/PopperContext/PopperContext.js';
122
124
 
123
- const WalletUpgradeFlowView = ({ wallets, method, onComplete, onCancel, }) => {
124
- var _a;
125
+ const WalletUpgradeFlowView = ({ wallets, method, startIndex = 0, onComplete, onCancel, }) => {
126
+ var _a, _b;
125
127
  const { setShowAuthFlow, user, environmentId } = useInternalDynamicContext();
126
128
  const { upgradeToDynamicWaas } = useDynamicWaas();
127
129
  const { t } = useTranslation();
128
130
  const { pushView } = useViewContext();
129
- const [currentWalletIndex, setCurrentWalletIndex] = useState(0);
131
+ const [currentWalletIndex, setCurrentWalletIndex] = useState(startIndex);
130
132
  const [privateKeyInput, setPrivateKeyInput] = useState('');
131
133
  const [iframeContainerRef, setIframeContainerRef] = useState(null);
132
134
  const isLastWallet = currentWalletIndex === wallets.length - 1;
133
135
  const completedSteps = currentWalletIndex;
134
136
  const totalSteps = wallets.length;
135
137
  const refresh = useRefreshAuth();
138
+ const walletCredential = (_a = user === null || user === void 0 ? void 0 : user.verifiedCredentials) === null || _a === void 0 ? void 0 : _a.find((cred) => { var _a; return cred.address === ((_a = wallets[currentWalletIndex]) === null || _a === void 0 ? void 0 : _a.address); });
136
139
  // Check if current wallet is a WaaS wallet based on its properties
137
140
  const isWaasWallet = Boolean(user === null || user === void 0 ? void 0 : user.verifiedCredentials.find((vc) => { var _a; return (_a = vc.walletName) === null || _a === void 0 ? void 0 : _a.startsWith('dynamicwaas'); }));
138
141
  const onExportReady = (isReady, wallet) => {
@@ -155,6 +158,22 @@ const WalletUpgradeFlowView = ({ wallets, method, onComplete, onCancel, }) => {
155
158
  dynamicEvents.emit('embeddedWalletRevealFailed', err);
156
159
  },
157
160
  });
161
+ // Map the raw export failure (e.g. a rejected WebAuthn ceremony) to the
162
+ // same user-facing copy the main widget export view shows.
163
+ const exportErrorText = useMemo(() => {
164
+ if (!exportError) {
165
+ return undefined;
166
+ }
167
+ try {
168
+ return getProperErrorMessage(exportError, user);
169
+ }
170
+ catch (e) {
171
+ if (e instanceof AccessBlockedError) {
172
+ pushView('access-blocked');
173
+ }
174
+ return undefined;
175
+ }
176
+ }, [exportError, pushView, user]);
158
177
  // Track successful export for emitting event on unmount
159
178
  const revealedWalletRef = useRef(null);
160
179
  useEffect(() => {
@@ -212,11 +231,13 @@ const WalletUpgradeFlowView = ({ wallets, method, onComplete, onCancel, }) => {
212
231
  ? 'wallet-upgrade-flow-view__step--completed'
213
232
  : ''} ${index === currentWalletIndex
214
233
  ? 'wallet-upgrade-flow-view__step--current'
215
- : ''}`, children: [jsx("div", { className: 'wallet-upgrade-flow-view__step-indicator', children: index < completedSteps ? (jsx("div", { className: 'wallet-upgrade-flow-view__step-check', children: "\u2713" })) : (jsx("div", { className: 'wallet-upgrade-flow-view__step-number', children: index + 1 })) }), jsx(Typography, { variant: 'body_small', color: index <= currentWalletIndex ? 'primary' : 'secondary', className: 'wallet-upgrade-flow-view__step-title', children: getStepTitle(index) })] }), index < totalSteps - 1 && (jsx("div", { className: 'wallet-upgrade-flow-view__step-separator' }))] }, index))) }) })) }), jsxs("div", { className: 'wallet-upgrade-flow-view__content', children: [exportError && (jsx(ErrorContainer, { className: 'wallet-upgrade-flow-view__error', children: exportError instanceof Error
216
- ? exportError.message
217
- : t('dyn_wallet_upgrade_flow.export_failed') })), upgradeError && (jsx(ErrorContainer, { className: 'wallet-upgrade-flow-view__error', children: upgradeError instanceof Error
234
+ : ''}`, children: [jsx("div", { className: 'wallet-upgrade-flow-view__step-indicator', children: index < completedSteps ? (jsx("div", { className: 'wallet-upgrade-flow-view__step-check', children: "\u2713" })) : (jsx("div", { className: 'wallet-upgrade-flow-view__step-number', children: index + 1 })) }), jsx(Typography, { variant: 'body_small', color: index <= currentWalletIndex ? 'primary' : 'secondary', className: 'wallet-upgrade-flow-view__step-title', children: getStepTitle(index) })] }), index < totalSteps - 1 && (jsx("div", { className: 'wallet-upgrade-flow-view__step-separator' }))] }, index))) }) })) }), jsxs("div", { className: 'wallet-upgrade-flow-view__content', children: [exportError && (jsx(ErrorContainer, { className: 'wallet-upgrade-flow-view__error', children: exportErrorText !== null && exportErrorText !== void 0 ? exportErrorText : t('dyn_wallet_upgrade_flow.export_failed') })), upgradeError && (jsx(ErrorContainer, { className: 'wallet-upgrade-flow-view__error', children: upgradeError instanceof Error
218
235
  ? upgradeError.message
219
- : t('dyn_wallet_upgrade_flow.upgrade_failed') })), jsxs("div", { className: 'wallet-upgrade-flow-view__title-section', children: [jsx(Typography, { as: 'h1', variant: 'title', color: 'primary', children: t('dyn_wallet_upgrade_flow.title') }), jsx(Typography, { color: 'secondary', className: 'wallet-upgrade-flow-view__subtitle', children: t('dyn_wallet_upgrade_flow.copy_private_key_subtitle') })] }), jsxs("div", { className: 'wallet-upgrade-flow-view__export-section', children: [jsx(Typography, { color: 'primary', variant: 'body_normal', weight: 'bold', className: 'wallet-upgrade-flow-view__section-title', children: t('dyn_wallet_upgrade_flow.copy_private_key_title') }), jsx(EmbeddedWalletExport, { wallet: wallets[currentWalletIndex], isTurnkeyWallet: true, isWaasWallet: isWaasWallet, data: exportData, onIframeContainerRef: setIframeContainerRef, onExportReady: onExportReady }, `wallet-export-${currentWalletIndex}-${(_a = wallets[currentWalletIndex]) === null || _a === void 0 ? void 0 : _a.id}`)] }), jsx("div", { className: 'wallet-upgrade-flow-view__input-section', children: jsxs("div", { className: 'wallet-upgrade-flow-view__input-container', children: [jsxs(Typography, { variant: 'body_normal', weight: 'bold', color: 'primary', copykey: 'dyn_embedded_reveal.step_2_title', children: [jsx("span", { className: 'wallet-upgrade-flow__step-description', children: t('dyn_wallet_upgrade_flow.step_2_upgrade_description') }), ' '] }), jsx(Textarea, { id: 'paste-private-key-input', value: privateKeyInput, onChange: (e) => setPrivateKeyInput(e.target.value), variant: 'regular', className: 'wallet-upgrade-flow__paste-input', label: '' })] }) })] }), jsxs("div", { className: 'wallet-upgrade-flow-view__actions', children: [jsx(TypographyButton, { buttonVariant: 'brand-primary', onClick: () => handleUpgradeWallet(), disabled: !privateKeyInput.trim() || isUpgrading, loading: isUpgrading, copykey: 'dyn_wallet_upgrade_flow.upgrade_button', typographyProps: {
236
+ : t('dyn_wallet_upgrade_flow.upgrade_failed') })), jsxs("div", { className: 'wallet-upgrade-flow-view__title-section', children: [jsx(Typography, { as: 'h1', variant: 'title', color: 'primary', children: t('dyn_wallet_upgrade_flow.title') }), jsx(Typography, { color: 'secondary', className: 'wallet-upgrade-flow-view__subtitle', children: t('dyn_wallet_upgrade_flow.copy_private_key_subtitle') })] }), jsxs("div", { className: 'wallet-upgrade-flow-view__export-section', children: [jsx(Typography, { color: 'primary', variant: 'body_normal', weight: 'bold', className: 'wallet-upgrade-flow-view__section-title', children: t('dyn_wallet_upgrade_flow.copy_private_key_title') }), jsx(EmbeddedWalletExport, { wallet: wallets[currentWalletIndex], isTurnkeyWallet: true, isWaasWallet: isWaasWallet, data: exportData, onIframeContainerRef: setIframeContainerRef, onExportReady: onExportReady }, `wallet-export-${currentWalletIndex}-${(_b = wallets[currentWalletIndex]) === null || _b === void 0 ? void 0 : _b.id}`)] }), jsx("div", { className: 'wallet-upgrade-flow-view__input-section', children: jsxs("div", { className: 'wallet-upgrade-flow-view__input-container', children: [jsxs(Typography, { variant: 'body_normal', weight: 'bold', color: 'primary', copykey: 'dyn_embedded_reveal.step_2_title', children: [jsx("span", { className: 'wallet-upgrade-flow__step-description', children: t('dyn_wallet_upgrade_flow.step_2_upgrade_description') }), ' '] }), jsx(Textarea, { id: 'paste-private-key-input', value: privateKeyInput, onChange: (e) => setPrivateKeyInput(e.target.value), variant: 'regular', className: 'wallet-upgrade-flow__paste-input', label: '' })] }) }), exportError && (jsx(NeedHelpSection, { isExport: true, walletCredential: walletCredential, wallet: wallets[currentWalletIndex], goBack: () => pushView('wallet-upgrade-flow-view', {
237
+ method,
238
+ startIndex: currentWalletIndex,
239
+ wallets,
240
+ }) }))] }), jsxs("div", { className: 'wallet-upgrade-flow-view__actions', children: [jsx(TypographyButton, { buttonVariant: 'brand-primary', onClick: () => handleUpgradeWallet(), disabled: !privateKeyInput.trim() || isUpgrading, loading: isUpgrading, copykey: 'dyn_wallet_upgrade_flow.upgrade_button', typographyProps: {
220
241
  color: 'inherit',
221
242
  }, expanded: true, children: t('dyn_wallet_upgrade_flow.upgrade_wallet') }), jsx(TypographyButton, { buttonVariant: 'tertiary', onClick: handleClose, disabled: isUpgrading, children: t('dyn_wallet_upgrade_flow.cancel') })] })] }));
222
243
  };
@@ -4,7 +4,9 @@ export declare const viewToComponentMap: {
4
4
  'account-exists': () => JSX.Element;
5
5
  'account-upgraded': import("react").FC;
6
6
  'auth-loading': import("react").FC;
7
- 'backup-unsuccessful': import("react").FC<{}>;
7
+ 'backup-unsuccessful': import("react").FC<{
8
+ errorMessage?: string | undefined;
9
+ }>;
8
10
  'bridge-next-wallet-connection': import("react").FC;
9
11
  'bridge-summary': () => JSX.Element;
10
12
  'bridge-welcome': () => JSX.Element;