@dynamic-labs/sdk-react-core 4.91.1 → 4.91.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +24 -0
- package/package.cjs +2 -2
- package/package.js +2 -2
- package/package.json +13 -13
- package/src/lib/components/SendBalanceForm/SendBalanceForm.cjs +34 -6
- package/src/lib/components/SendBalanceForm/SendBalanceForm.d.ts +2 -1
- package/src/lib/components/SendBalanceForm/SendBalanceForm.js +35 -7
- package/src/lib/components/SendBalancePageLayout/SendBalancePageLayout.cjs +2 -2
- package/src/lib/components/SendBalancePageLayout/SendBalancePageLayout.js +2 -2
- package/src/lib/components/SendBalancePageLayout/components/TokensBalanceDropdown/TokensBalanceDropdown.cjs +8 -7
- package/src/lib/components/SendBalancePageLayout/components/TokensBalanceDropdown/TokensBalanceDropdown.d.ts +3 -1
- package/src/lib/components/SendBalancePageLayout/components/TokensBalanceDropdown/TokensBalanceDropdown.js +8 -7
- package/src/lib/utils/hooks/useDynamicWaas/useDynamicWaas.cjs +21 -3
- package/src/lib/utils/hooks/useDynamicWaas/useDynamicWaas.d.ts +7 -0
- package/src/lib/utils/hooks/useDynamicWaas/useDynamicWaas.js +21 -3
- package/src/lib/utils/hooks/useEmbeddedReveal/useEmbeddedReveal.cjs +5 -3
- package/src/lib/utils/hooks/useEmbeddedReveal/useEmbeddedReveal.d.ts +1 -1
- package/src/lib/utils/hooks/useEmbeddedReveal/useEmbeddedReveal.js +5 -3
- package/src/lib/utils/hooks/useSyncEmbeddedWalletFlow/useSyncEmbeddedWalletFlow.cjs +1 -1
- package/src/lib/utils/hooks/useSyncEmbeddedWalletFlow/useSyncEmbeddedWalletFlow.js +1 -1
- package/src/lib/views/EmbeddedReveal/EmbeddedRevealView/EmbeddedRevealView.cjs +18 -11
- package/src/lib/views/EmbeddedReveal/EmbeddedRevealView/EmbeddedRevealView.d.ts +1 -0
- package/src/lib/views/EmbeddedReveal/EmbeddedRevealView/EmbeddedRevealView.js +18 -11
- package/src/lib/widgets/DynamicWidget/components/ActiveMidnightWalletBalance/ActiveMidnightWalletBalance.cjs +33 -9
- package/src/lib/widgets/DynamicWidget/components/ActiveMidnightWalletBalance/ActiveMidnightWalletBalance.js +33 -9
- package/src/lib/widgets/DynamicWidget/views/AccountAndSecuritySettingsView/EmbeddedWalletExportSection/EmbeddedWalletExportSection.cjs +5 -2
- package/src/lib/widgets/DynamicWidget/views/AccountAndSecuritySettingsView/EmbeddedWalletExportSection/EmbeddedWalletExportSection.js +5 -2
- package/src/lib/widgets/DynamicWidget/views/ExportAndRecoveryView/ExportAndRecoveryView.cjs +3 -1
- package/src/lib/widgets/DynamicWidget/views/ExportAndRecoveryView/ExportAndRecoveryView.js +3 -1
package/CHANGELOG.md
CHANGED
|
@@ -1,4 +1,28 @@
|
|
|
1
1
|
|
|
2
|
+
### [4.91.2](https://github.com/dynamic-labs/dynamic-auth/compare/v4.91.1...v4.91.2) (2026-06-26)
|
|
3
|
+
|
|
4
|
+
|
|
5
|
+
### ⚠ BREAKING CHANGES
|
|
6
|
+
|
|
7
|
+
* **waas:** require expectedAddresses on migrateFromFireblocks (#11730)
|
|
8
|
+
|
|
9
|
+
### Features
|
|
10
|
+
|
|
11
|
+
* **midnight:** support shielded/unshielded transfers and dust states in the embedded Send flow ([#11731](https://github.com/dynamic-labs/dynamic-auth/issues/11731)) ([663d171](https://github.com/dynamic-labs/dynamic-auth/commit/663d171a9628c634586831ee35c234e9331e3f80))
|
|
12
|
+
* **react-native-extension:** instrument all embedded webview failure paths ([#11737](https://github.com/dynamic-labs/dynamic-auth/issues/11737)) ([172998b](https://github.com/dynamic-labs/dynamic-auth/commit/172998b56e9bee04fbb8da71e83ce8885bc378ff))
|
|
13
|
+
* **waas:** migrateFromFireblocks connector method + demo panel (browser-wallet-client 1.0.46) ([#11702](https://github.com/dynamic-labs/dynamic-auth/issues/11702)) ([6bfc844](https://github.com/dynamic-labs/dynamic-auth/commit/6bfc8443fbaedabe1e7bee0ed78742cbbe5d0084))
|
|
14
|
+
|
|
15
|
+
|
|
16
|
+
### Bug Fixes
|
|
17
|
+
|
|
18
|
+
* add coverage for scenario with passkey re-login and smart account ([#11726](https://github.com/dynamic-labs/dynamic-auth/issues/11726)) ([5364a72](https://github.com/dynamic-labs/dynamic-auth/commit/5364a72a750d835b9b2da602a91e8b5d7d305db7))
|
|
19
|
+
* remediate high-severity dependency vulnerabilities ([#11721](https://github.com/dynamic-labs/dynamic-auth/issues/11721)) ([cdb9306](https://github.com/dynamic-labs/dynamic-auth/commit/cdb93061365a20b8f73a1f8bea8352332e282c1e))
|
|
20
|
+
* replace node-fetch v2 with native fetch to fix Node 22 stream failure ([#11732](https://github.com/dynamic-labs/dynamic-auth/issues/11732)) ([b98f801](https://github.com/dynamic-labs/dynamic-auth/commit/b98f801e307b52dbd7e4b241a9a4a2d34d89118e))
|
|
21
|
+
* **zerodev-extension:** derive kernel 7702 vs 4337 per-wallet, not from global dashboard flag ([#11735](https://github.com/dynamic-labs/dynamic-auth/issues/11735)) ([72cf6a7](https://github.com/dynamic-labs/dynamic-auth/commit/72cf6a70a4857a4ea469faa555c485dbad8d0217))
|
|
22
|
+
|
|
23
|
+
|
|
24
|
+
* **waas:** require expectedAddresses on migrateFromFireblocks ([#11730](https://github.com/dynamic-labs/dynamic-auth/issues/11730)) ([c94824e](https://github.com/dynamic-labs/dynamic-auth/commit/c94824ebe11e0433a6ffbd2a5a9dd4283aeed31e))
|
|
25
|
+
|
|
2
26
|
### [4.91.1](https://github.com/dynamic-labs/dynamic-auth/compare/v4.91.0...v4.91.1) (2026-06-24)
|
|
3
27
|
|
|
4
28
|
|
package/package.cjs
CHANGED
|
@@ -3,11 +3,11 @@
|
|
|
3
3
|
|
|
4
4
|
Object.defineProperty(exports, '__esModule', { value: true });
|
|
5
5
|
|
|
6
|
-
var version = "4.91.
|
|
6
|
+
var version = "4.91.2";
|
|
7
7
|
var dependencies = {
|
|
8
8
|
"@dynamic-labs/sdk-api-core": "0.0.1046",
|
|
9
9
|
"@dynamic-labs-sdk/client": "1.12.1",
|
|
10
|
-
"@dynamic-labs-wallet/browser-wallet-client": "1.0.
|
|
10
|
+
"@dynamic-labs-wallet/browser-wallet-client": "1.0.48",
|
|
11
11
|
"@dynamic-labs-wallet/forward-mpc-client": "0.12.0",
|
|
12
12
|
"@hcaptcha/react-hcaptcha": "1.4.4",
|
|
13
13
|
"@thumbmarkjs/thumbmarkjs": "0.16.0",
|
package/package.js
CHANGED
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
'use client'
|
|
2
|
-
var version = "4.91.
|
|
2
|
+
var version = "4.91.2";
|
|
3
3
|
var dependencies = {
|
|
4
4
|
"@dynamic-labs/sdk-api-core": "0.0.1046",
|
|
5
5
|
"@dynamic-labs-sdk/client": "1.12.1",
|
|
6
|
-
"@dynamic-labs-wallet/browser-wallet-client": "1.0.
|
|
6
|
+
"@dynamic-labs-wallet/browser-wallet-client": "1.0.48",
|
|
7
7
|
"@dynamic-labs-wallet/forward-mpc-client": "0.12.0",
|
|
8
8
|
"@hcaptcha/react-hcaptcha": "1.4.4",
|
|
9
9
|
"@thumbmarkjs/thumbmarkjs": "0.16.0",
|
package/package.json
CHANGED
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@dynamic-labs/sdk-react-core",
|
|
3
|
-
"version": "4.91.
|
|
3
|
+
"version": "4.91.2",
|
|
4
4
|
"dependencies": {
|
|
5
5
|
"@dynamic-labs/sdk-api-core": "0.0.1046",
|
|
6
6
|
"@dynamic-labs-sdk/client": "1.12.1",
|
|
7
|
-
"@dynamic-labs-wallet/browser-wallet-client": "1.0.
|
|
7
|
+
"@dynamic-labs-wallet/browser-wallet-client": "1.0.48",
|
|
8
8
|
"@dynamic-labs-wallet/forward-mpc-client": "0.12.0",
|
|
9
9
|
"@hcaptcha/react-hcaptcha": "1.4.4",
|
|
10
10
|
"@thumbmarkjs/thumbmarkjs": "0.16.0",
|
|
@@ -17,17 +17,17 @@
|
|
|
17
17
|
"yup": "0.32.11",
|
|
18
18
|
"react-international-phone": "4.5.0",
|
|
19
19
|
"bs58": "5.0.0",
|
|
20
|
-
"@dynamic-labs/assert-package-version": "4.91.
|
|
21
|
-
"@dynamic-labs/iconic": "4.91.
|
|
22
|
-
"@dynamic-labs/locale": "4.91.
|
|
23
|
-
"@dynamic-labs/logger": "4.91.
|
|
24
|
-
"@dynamic-labs/multi-wallet": "4.91.
|
|
25
|
-
"@dynamic-labs/rpc-providers": "4.91.
|
|
26
|
-
"@dynamic-labs/store": "4.91.
|
|
27
|
-
"@dynamic-labs/types": "4.91.
|
|
28
|
-
"@dynamic-labs/utils": "4.91.
|
|
29
|
-
"@dynamic-labs/wallet-book": "4.91.
|
|
30
|
-
"@dynamic-labs/wallet-connector-core": "4.91.
|
|
20
|
+
"@dynamic-labs/assert-package-version": "4.91.2",
|
|
21
|
+
"@dynamic-labs/iconic": "4.91.2",
|
|
22
|
+
"@dynamic-labs/locale": "4.91.2",
|
|
23
|
+
"@dynamic-labs/logger": "4.91.2",
|
|
24
|
+
"@dynamic-labs/multi-wallet": "4.91.2",
|
|
25
|
+
"@dynamic-labs/rpc-providers": "4.91.2",
|
|
26
|
+
"@dynamic-labs/store": "4.91.2",
|
|
27
|
+
"@dynamic-labs/types": "4.91.2",
|
|
28
|
+
"@dynamic-labs/utils": "4.91.2",
|
|
29
|
+
"@dynamic-labs/wallet-book": "4.91.2",
|
|
30
|
+
"@dynamic-labs/wallet-connector-core": "4.91.2",
|
|
31
31
|
"eventemitter3": "5.0.1"
|
|
32
32
|
},
|
|
33
33
|
"devDependencies": {
|
|
@@ -82,7 +82,7 @@ const getDisplayErrorMessage = (errors, t, field, decimals) => {
|
|
|
82
82
|
}
|
|
83
83
|
return '';
|
|
84
84
|
};
|
|
85
|
-
const SendBalanceForm = ({ initialValues, onSubmit, decimals = 18, validateAddress = () => true, validateAmount = () => true, currentToken, transaction, tokenBalances, setCurrentToken, isLoading, supportsFeeTokenSelection = false, feeTokenOptions, currentFeeToken, setCurrentFeeToken, }) => {
|
|
85
|
+
const SendBalanceForm = ({ initialValues, onSubmit, decimals = 18, validateAddress = () => true, validateAmount = () => true, currentToken, transaction, tokenBalances, setCurrentToken, isLoading, supportsFeeTokenSelection = false, feeTokenOptions, currentFeeToken, setCurrentFeeToken, fallbackTokenIcon, }) => {
|
|
86
86
|
var _a;
|
|
87
87
|
const { t } = reactI18next.useTranslation();
|
|
88
88
|
const { showFiat } = useInternalDynamicContext.useInternalDynamicContext();
|
|
@@ -114,12 +114,34 @@ const SendBalanceForm = ({ initialValues, onSubmit, decimals = 18, validateAddre
|
|
|
114
114
|
var _a;
|
|
115
115
|
setMergeAction((_a = transaction === null || transaction === void 0 ? void 0 : transaction.getRecordMergeAction) === null || _a === void 0 ? void 0 : _a.call(transaction));
|
|
116
116
|
};
|
|
117
|
+
// With a mode toggle + per-token pool (Midnight), filter the picker to the
|
|
118
|
+
// selected pool. Chains without `getTokenPool` show the full list unchanged.
|
|
119
|
+
const filteredTokenBalances = React.useMemo(() => {
|
|
120
|
+
if (!hasModes || !selectedModeId || !(transaction === null || transaction === void 0 ? void 0 : transaction.getTokenPool)) {
|
|
121
|
+
return tokenBalances;
|
|
122
|
+
}
|
|
123
|
+
return tokenBalances === null || tokenBalances === void 0 ? void 0 : tokenBalances.filter((token) => { var _a; return ((_a = transaction.getTokenPool) === null || _a === void 0 ? void 0 : _a.call(transaction, token.address)) === selectedModeId; });
|
|
124
|
+
}, [tokenBalances, hasModes, selectedModeId, transaction]);
|
|
117
125
|
const handleModeChange = (modeId) => {
|
|
118
126
|
var _a;
|
|
119
127
|
setSelectedModeId(modeId);
|
|
128
|
+
// Set the mode + filter only — do NOT change `currentToken`, which would
|
|
129
|
+
// trip the Send view's transaction-recreation effect (reload). The picker
|
|
130
|
+
// resets to a placeholder + gates Preview until a valid token is picked.
|
|
120
131
|
(_a = transaction === null || transaction === void 0 ? void 0 : transaction.setTransactionMode) === null || _a === void 0 ? void 0 : _a.call(transaction, modeId);
|
|
121
132
|
refreshMergeAction();
|
|
122
133
|
};
|
|
134
|
+
// The selected token must belong to the active pool; while it doesn't, the
|
|
135
|
+
// picker shows a placeholder and Preview is disabled so we never carry an
|
|
136
|
+
// incompatible token into a transfer.
|
|
137
|
+
const selectionMatchesMode = !hasModes ||
|
|
138
|
+
!selectedModeId ||
|
|
139
|
+
!(transaction === null || transaction === void 0 ? void 0 : transaction.getTokenPool) ||
|
|
140
|
+
(currentToken !== undefined &&
|
|
141
|
+
transaction.getTokenPool(currentToken.address) === selectedModeId);
|
|
142
|
+
// Token shown as "selected" in the picker — hidden when it doesn't match the
|
|
143
|
+
// active pool so the row reads as unset rather than showing the wrong token.
|
|
144
|
+
const pickerToken = selectionMatchesMode ? currentToken : undefined;
|
|
123
145
|
const handleMergeAction = () => _tslib.__awaiter(void 0, void 0, void 0, function* () {
|
|
124
146
|
if (!mergeAction || isMerging)
|
|
125
147
|
return;
|
|
@@ -139,7 +161,10 @@ const SendBalanceForm = ({ initialValues, onSubmit, decimals = 18, validateAddre
|
|
|
139
161
|
}
|
|
140
162
|
}, [currentToken]);
|
|
141
163
|
const sendBalanceFormValidationSchema = React.useMemo(() => {
|
|
142
|
-
|
|
164
|
+
// For 0-decimal tokens (e.g. Midnight shielded tokens) only whole numbers
|
|
165
|
+
// are valid — a `\d{1,0}` quantifier is an invalid regex and throws, so
|
|
166
|
+
// build an integer-only pattern in that case.
|
|
167
|
+
const decimalsRegex = decimals > 0 ? new RegExp(`^\\d*(\\.\\d{1,${decimals}})?$`) : /^\d*$/;
|
|
143
168
|
return yup.object().shape({
|
|
144
169
|
amount: yup.string()
|
|
145
170
|
.required('required')
|
|
@@ -173,7 +198,7 @@ const SendBalanceForm = ({ initialValues, onSubmit, decimals = 18, validateAddre
|
|
|
173
198
|
}, [decimals, validateAddress, validateAmount]);
|
|
174
199
|
return (jsxRuntime.jsx(formik.Formik, { initialValues: initialValues || sendBalanceFormInitialValues, validationSchema: sendBalanceFormValidationSchema, onSubmit: (values) => onSubmit(values), validateOnChange: false, validateOnBlur: false, children: ({ errors, touched, values, handleChange, setFieldValue, setErrors, handleBlur, setFieldTouched, validateField, }) => {
|
|
175
200
|
var _a;
|
|
176
|
-
return (jsxRuntime.jsxs(formik.Form, { className: 'send-balance-form', children: [jsxRuntime.jsxs("div", { className: 'send-balance-page-layout__balance-container', children: [jsxRuntime.jsx(FormFieldLabel.FormFieldLabel, { copykey: 'dyn_send_transaction.data.select_token', children: t('dyn_send_transaction.data.select_token') }), jsxRuntime.jsx(TokensBalanceDropdown.TokensBalanceDropdown, { tokenBalances:
|
|
201
|
+
return (jsxRuntime.jsxs(formik.Form, { className: 'send-balance-form', children: [jsxRuntime.jsxs("div", { className: 'send-balance-page-layout__balance-container', children: [jsxRuntime.jsx(FormFieldLabel.FormFieldLabel, { copykey: 'dyn_send_transaction.data.select_token', children: t('dyn_send_transaction.data.select_token') }), jsxRuntime.jsx(TokensBalanceDropdown.TokensBalanceDropdown, { tokenBalances: filteredTokenBalances !== null && filteredTokenBalances !== void 0 ? filteredTokenBalances : (pickerToken && [pickerToken]), currentToken: pickerToken, setCurrentToken: setCurrentToken, isLoading: isLoading, setFieldValue: setFieldValue, setErrors: setErrors, fallbackTokenIcon: fallbackTokenIcon, placeholder: t('dyn_send_transaction.data.select_token') })] }), jsxRuntime.jsxs("div", { className: 'send-balance-form__amount-container', children: [jsxRuntime.jsx(formik.Field, { variant: 'regular', className: `send-balance-form__amount-container__field ${showFiat ? 'fiat' : ''}`, name: 'amount', id: 'amount', onChange: (e) => {
|
|
177
202
|
const newValue = e.target.value;
|
|
178
203
|
// Matching 123, 123.45, .45, 123.
|
|
179
204
|
if (newValue !== '' && !/^(?:\d+|\d*\.\d*|)$/.test(newValue)) {
|
|
@@ -200,8 +225,8 @@ const SendBalanceForm = ({ initialValues, onSubmit, decimals = 18, validateAddre
|
|
|
200
225
|
}, placeholder: t('dyn_send_transaction.data.amount.placeholder'), as: Input.Input, error: errors['amount'], copykey: 'dyn_send_transaction.data.amount.label', message: touched['amount'] &&
|
|
201
226
|
getDisplayErrorMessage(errors, t, 'amount', decimals), style: {
|
|
202
227
|
paddingLeft: `${leftSymbolPadding}px`,
|
|
203
|
-
} }), jsxRuntime.jsx("div", { className: 'send-balance-form__amount-container__floating_value', ref: floatingValueRef, children: jsxRuntime.jsx(Typography.Typography, { variant: 'title', weight: 'regular', color: 'secondary', children: currentToken === null || currentToken === void 0 ? void 0 : currentToken.symbol }) }), jsxRuntime.jsx("div", { className: 'send-balance-form__amount-container__balance', children: showFiat && !Number.isNaN(amount) && (jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [jsxRuntime.jsx(Typography.Typography, { variant: 'body_mini', weight: 'bold', color: 'secondary', children: "$" }), jsxRuntime.jsx(Typography.Typography, { variant: 'body_mini', weight: 'regular', color: 'secondary', children: utils.getDisplayFiatPrice(amount, currentToken) })] })) })] }), jsxRuntime.jsx(Typography.Typography, { className: 'send-balance-form__amount_available', variant: 'body_small', weight: 'regular', color: 'secondary', as: 'div', children: jsxRuntime.jsxs("div", { style: { display: 'flex', gap: '0.225rem' }, children: [jsxRuntime.jsx(Typography.Typography, { className: 'send-balance-form__amount_available__line', variant: 'body_small', weight: 'bold', color: 'primary', as: 'div', children: (_a =
|
|
204
|
-
symbol:
|
|
228
|
+
} }), jsxRuntime.jsx("div", { className: 'send-balance-form__amount-container__floating_value', ref: floatingValueRef, children: jsxRuntime.jsx(Typography.Typography, { variant: 'title', weight: 'regular', color: 'secondary', children: currentToken === null || currentToken === void 0 ? void 0 : currentToken.symbol }) }), jsxRuntime.jsx("div", { className: 'send-balance-form__amount-container__balance', children: showFiat && !Number.isNaN(amount) && (jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [jsxRuntime.jsx(Typography.Typography, { variant: 'body_mini', weight: 'bold', color: 'secondary', children: "$" }), jsxRuntime.jsx(Typography.Typography, { variant: 'body_mini', weight: 'regular', color: 'secondary', children: utils.getDisplayFiatPrice(amount, currentToken) })] })) })] }), jsxRuntime.jsx(Typography.Typography, { className: 'send-balance-form__amount_available', variant: 'body_small', weight: 'regular', color: 'secondary', as: 'div', children: jsxRuntime.jsxs("div", { style: { display: 'flex', gap: '0.225rem' }, children: [jsxRuntime.jsx(Typography.Typography, { className: 'send-balance-form__amount_available__line', variant: 'body_small', weight: 'bold', color: 'primary', as: 'div', children: (_a = pickerToken === null || pickerToken === void 0 ? void 0 : pickerToken.balance) !== null && _a !== void 0 ? _a : 0 }), t('dyn_send_transaction.data.symbol_available', {
|
|
229
|
+
symbol: pickerToken === null || pickerToken === void 0 ? void 0 : pickerToken.symbol,
|
|
205
230
|
})] }) }), supportsFeeTokenSelection &&
|
|
206
231
|
feeTokenOptions &&
|
|
207
232
|
feeTokenOptions.length > 0 &&
|
|
@@ -215,7 +240,10 @@ const SendBalanceForm = ({ initialValues, onSubmit, decimals = 18, validateAddre
|
|
|
215
240
|
refreshMergeAction();
|
|
216
241
|
} }), hasModes && (jsxRuntime.jsx(TransactionModeSegmentedControl.TransactionModeSegmentedControl, { options: transactionModes, selectedId: selectedModeId, onChange: handleModeChange, disabled: isMerging })), mergeAction && (jsxRuntime.jsx("div", { className: 'send-balance-form__inline-action', children: jsxRuntime.jsx(Alert.Alert, { icon: 'error', variant: 'warning', children: jsxRuntime.jsxs("div", { className: 'send-balance-form__inline-action-content', children: [jsxRuntime.jsx(Typography.Typography, { variant: 'body_small', weight: 'regular', children: mergeAction.message }), jsxRuntime.jsx(TypographyButton.TypographyButton, { dataTestId: 'sendBalanceFormMergeRecordsButton', type: 'button', buttonVariant: 'secondary', buttonPadding: 'small', onClick: handleMergeAction, disabled: isMerging, children: isMerging
|
|
217
242
|
? t('dyn_send_transaction.merging', 'Merging…')
|
|
218
|
-
: mergeAction.actionLabel })] }) }) })), jsxRuntime.jsx(TypographyButton.TypographyButton, { dataTestId: 'sendBalanceFormSubmitButton', expanded: true, type: 'submit', buttonVariant: 'primary', buttonPadding: 'small', buttonClassName: 'send-balance-form__button', copykey: 'dyn_send_transaction.preview_transaction', disabled: !modeReady ||
|
|
243
|
+
: mergeAction.actionLabel })] }) }) })), jsxRuntime.jsx(TypographyButton.TypographyButton, { dataTestId: 'sendBalanceFormSubmitButton', expanded: true, type: 'submit', buttonVariant: 'primary', buttonPadding: 'small', buttonClassName: 'send-balance-form__button', copykey: 'dyn_send_transaction.preview_transaction', disabled: !modeReady ||
|
|
244
|
+
!selectionMatchesMode ||
|
|
245
|
+
isMerging ||
|
|
246
|
+
Boolean(mergeAction), children: t('dyn_send_transaction.preview_transaction') })] }));
|
|
219
247
|
} }));
|
|
220
248
|
};
|
|
221
249
|
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { Dispatch, FC, SetStateAction } from 'react';
|
|
1
|
+
import { Dispatch, FC, type ReactNode, SetStateAction } from 'react';
|
|
2
2
|
import { TokenBalance } from '@dynamic-labs/sdk-api-core';
|
|
3
3
|
import { IUITransaction } from '@dynamic-labs/types';
|
|
4
4
|
export type SendBalanceFormValues = {
|
|
@@ -20,5 +20,6 @@ export type Props = {
|
|
|
20
20
|
feeTokenOptions?: TokenBalance[];
|
|
21
21
|
currentFeeToken?: TokenBalance;
|
|
22
22
|
setCurrentFeeToken?: Dispatch<SetStateAction<TokenBalance | undefined>>;
|
|
23
|
+
fallbackTokenIcon?: ReactNode;
|
|
23
24
|
};
|
|
24
25
|
export declare const SendBalanceForm: FC<Props>;
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
'use client'
|
|
2
2
|
import { __awaiter } from '../../../../_virtual/_tslib.js';
|
|
3
3
|
import { jsx, jsxs, Fragment } from 'react/jsx-runtime';
|
|
4
|
-
import { useRef, useState,
|
|
4
|
+
import { useRef, useState, useMemo, useEffect } from 'react';
|
|
5
5
|
import { Formik, Form, Field } from 'formik';
|
|
6
6
|
import { useTranslation } from 'react-i18next';
|
|
7
7
|
import { object, string } from 'yup';
|
|
@@ -78,7 +78,7 @@ const getDisplayErrorMessage = (errors, t, field, decimals) => {
|
|
|
78
78
|
}
|
|
79
79
|
return '';
|
|
80
80
|
};
|
|
81
|
-
const SendBalanceForm = ({ initialValues, onSubmit, decimals = 18, validateAddress = () => true, validateAmount = () => true, currentToken, transaction, tokenBalances, setCurrentToken, isLoading, supportsFeeTokenSelection = false, feeTokenOptions, currentFeeToken, setCurrentFeeToken, }) => {
|
|
81
|
+
const SendBalanceForm = ({ initialValues, onSubmit, decimals = 18, validateAddress = () => true, validateAmount = () => true, currentToken, transaction, tokenBalances, setCurrentToken, isLoading, supportsFeeTokenSelection = false, feeTokenOptions, currentFeeToken, setCurrentFeeToken, fallbackTokenIcon, }) => {
|
|
82
82
|
var _a;
|
|
83
83
|
const { t } = useTranslation();
|
|
84
84
|
const { showFiat } = useInternalDynamicContext();
|
|
@@ -110,12 +110,34 @@ const SendBalanceForm = ({ initialValues, onSubmit, decimals = 18, validateAddre
|
|
|
110
110
|
var _a;
|
|
111
111
|
setMergeAction((_a = transaction === null || transaction === void 0 ? void 0 : transaction.getRecordMergeAction) === null || _a === void 0 ? void 0 : _a.call(transaction));
|
|
112
112
|
};
|
|
113
|
+
// With a mode toggle + per-token pool (Midnight), filter the picker to the
|
|
114
|
+
// selected pool. Chains without `getTokenPool` show the full list unchanged.
|
|
115
|
+
const filteredTokenBalances = useMemo(() => {
|
|
116
|
+
if (!hasModes || !selectedModeId || !(transaction === null || transaction === void 0 ? void 0 : transaction.getTokenPool)) {
|
|
117
|
+
return tokenBalances;
|
|
118
|
+
}
|
|
119
|
+
return tokenBalances === null || tokenBalances === void 0 ? void 0 : tokenBalances.filter((token) => { var _a; return ((_a = transaction.getTokenPool) === null || _a === void 0 ? void 0 : _a.call(transaction, token.address)) === selectedModeId; });
|
|
120
|
+
}, [tokenBalances, hasModes, selectedModeId, transaction]);
|
|
113
121
|
const handleModeChange = (modeId) => {
|
|
114
122
|
var _a;
|
|
115
123
|
setSelectedModeId(modeId);
|
|
124
|
+
// Set the mode + filter only — do NOT change `currentToken`, which would
|
|
125
|
+
// trip the Send view's transaction-recreation effect (reload). The picker
|
|
126
|
+
// resets to a placeholder + gates Preview until a valid token is picked.
|
|
116
127
|
(_a = transaction === null || transaction === void 0 ? void 0 : transaction.setTransactionMode) === null || _a === void 0 ? void 0 : _a.call(transaction, modeId);
|
|
117
128
|
refreshMergeAction();
|
|
118
129
|
};
|
|
130
|
+
// The selected token must belong to the active pool; while it doesn't, the
|
|
131
|
+
// picker shows a placeholder and Preview is disabled so we never carry an
|
|
132
|
+
// incompatible token into a transfer.
|
|
133
|
+
const selectionMatchesMode = !hasModes ||
|
|
134
|
+
!selectedModeId ||
|
|
135
|
+
!(transaction === null || transaction === void 0 ? void 0 : transaction.getTokenPool) ||
|
|
136
|
+
(currentToken !== undefined &&
|
|
137
|
+
transaction.getTokenPool(currentToken.address) === selectedModeId);
|
|
138
|
+
// Token shown as "selected" in the picker — hidden when it doesn't match the
|
|
139
|
+
// active pool so the row reads as unset rather than showing the wrong token.
|
|
140
|
+
const pickerToken = selectionMatchesMode ? currentToken : undefined;
|
|
119
141
|
const handleMergeAction = () => __awaiter(void 0, void 0, void 0, function* () {
|
|
120
142
|
if (!mergeAction || isMerging)
|
|
121
143
|
return;
|
|
@@ -135,7 +157,10 @@ const SendBalanceForm = ({ initialValues, onSubmit, decimals = 18, validateAddre
|
|
|
135
157
|
}
|
|
136
158
|
}, [currentToken]);
|
|
137
159
|
const sendBalanceFormValidationSchema = useMemo(() => {
|
|
138
|
-
|
|
160
|
+
// For 0-decimal tokens (e.g. Midnight shielded tokens) only whole numbers
|
|
161
|
+
// are valid — a `\d{1,0}` quantifier is an invalid regex and throws, so
|
|
162
|
+
// build an integer-only pattern in that case.
|
|
163
|
+
const decimalsRegex = decimals > 0 ? new RegExp(`^\\d*(\\.\\d{1,${decimals}})?$`) : /^\d*$/;
|
|
139
164
|
return object().shape({
|
|
140
165
|
amount: string()
|
|
141
166
|
.required('required')
|
|
@@ -169,7 +194,7 @@ const SendBalanceForm = ({ initialValues, onSubmit, decimals = 18, validateAddre
|
|
|
169
194
|
}, [decimals, validateAddress, validateAmount]);
|
|
170
195
|
return (jsx(Formik, { initialValues: initialValues || sendBalanceFormInitialValues, validationSchema: sendBalanceFormValidationSchema, onSubmit: (values) => onSubmit(values), validateOnChange: false, validateOnBlur: false, children: ({ errors, touched, values, handleChange, setFieldValue, setErrors, handleBlur, setFieldTouched, validateField, }) => {
|
|
171
196
|
var _a;
|
|
172
|
-
return (jsxs(Form, { className: 'send-balance-form', children: [jsxs("div", { className: 'send-balance-page-layout__balance-container', children: [jsx(FormFieldLabel, { copykey: 'dyn_send_transaction.data.select_token', children: t('dyn_send_transaction.data.select_token') }), jsx(TokensBalanceDropdown, { tokenBalances:
|
|
197
|
+
return (jsxs(Form, { className: 'send-balance-form', children: [jsxs("div", { className: 'send-balance-page-layout__balance-container', children: [jsx(FormFieldLabel, { copykey: 'dyn_send_transaction.data.select_token', children: t('dyn_send_transaction.data.select_token') }), jsx(TokensBalanceDropdown, { tokenBalances: filteredTokenBalances !== null && filteredTokenBalances !== void 0 ? filteredTokenBalances : (pickerToken && [pickerToken]), currentToken: pickerToken, setCurrentToken: setCurrentToken, isLoading: isLoading, setFieldValue: setFieldValue, setErrors: setErrors, fallbackTokenIcon: fallbackTokenIcon, placeholder: t('dyn_send_transaction.data.select_token') })] }), jsxs("div", { className: 'send-balance-form__amount-container', children: [jsx(Field, { variant: 'regular', className: `send-balance-form__amount-container__field ${showFiat ? 'fiat' : ''}`, name: 'amount', id: 'amount', onChange: (e) => {
|
|
173
198
|
const newValue = e.target.value;
|
|
174
199
|
// Matching 123, 123.45, .45, 123.
|
|
175
200
|
if (newValue !== '' && !/^(?:\d+|\d*\.\d*|)$/.test(newValue)) {
|
|
@@ -196,8 +221,8 @@ const SendBalanceForm = ({ initialValues, onSubmit, decimals = 18, validateAddre
|
|
|
196
221
|
}, placeholder: t('dyn_send_transaction.data.amount.placeholder'), as: Input, error: errors['amount'], copykey: 'dyn_send_transaction.data.amount.label', message: touched['amount'] &&
|
|
197
222
|
getDisplayErrorMessage(errors, t, 'amount', decimals), style: {
|
|
198
223
|
paddingLeft: `${leftSymbolPadding}px`,
|
|
199
|
-
} }), jsx("div", { className: 'send-balance-form__amount-container__floating_value', ref: floatingValueRef, children: jsx(Typography, { variant: 'title', weight: 'regular', color: 'secondary', children: currentToken === null || currentToken === void 0 ? void 0 : currentToken.symbol }) }), jsx("div", { className: 'send-balance-form__amount-container__balance', children: showFiat && !Number.isNaN(amount) && (jsxs(Fragment, { children: [jsx(Typography, { variant: 'body_mini', weight: 'bold', color: 'secondary', children: "$" }), jsx(Typography, { variant: 'body_mini', weight: 'regular', color: 'secondary', children: getDisplayFiatPrice(amount, currentToken) })] })) })] }), jsx(Typography, { className: 'send-balance-form__amount_available', variant: 'body_small', weight: 'regular', color: 'secondary', as: 'div', children: jsxs("div", { style: { display: 'flex', gap: '0.225rem' }, children: [jsx(Typography, { className: 'send-balance-form__amount_available__line', variant: 'body_small', weight: 'bold', color: 'primary', as: 'div', children: (_a =
|
|
200
|
-
symbol:
|
|
224
|
+
} }), jsx("div", { className: 'send-balance-form__amount-container__floating_value', ref: floatingValueRef, children: jsx(Typography, { variant: 'title', weight: 'regular', color: 'secondary', children: currentToken === null || currentToken === void 0 ? void 0 : currentToken.symbol }) }), jsx("div", { className: 'send-balance-form__amount-container__balance', children: showFiat && !Number.isNaN(amount) && (jsxs(Fragment, { children: [jsx(Typography, { variant: 'body_mini', weight: 'bold', color: 'secondary', children: "$" }), jsx(Typography, { variant: 'body_mini', weight: 'regular', color: 'secondary', children: getDisplayFiatPrice(amount, currentToken) })] })) })] }), jsx(Typography, { className: 'send-balance-form__amount_available', variant: 'body_small', weight: 'regular', color: 'secondary', as: 'div', children: jsxs("div", { style: { display: 'flex', gap: '0.225rem' }, children: [jsx(Typography, { className: 'send-balance-form__amount_available__line', variant: 'body_small', weight: 'bold', color: 'primary', as: 'div', children: (_a = pickerToken === null || pickerToken === void 0 ? void 0 : pickerToken.balance) !== null && _a !== void 0 ? _a : 0 }), t('dyn_send_transaction.data.symbol_available', {
|
|
225
|
+
symbol: pickerToken === null || pickerToken === void 0 ? void 0 : pickerToken.symbol,
|
|
201
226
|
})] }) }), supportsFeeTokenSelection &&
|
|
202
227
|
feeTokenOptions &&
|
|
203
228
|
feeTokenOptions.length > 0 &&
|
|
@@ -211,7 +236,10 @@ const SendBalanceForm = ({ initialValues, onSubmit, decimals = 18, validateAddre
|
|
|
211
236
|
refreshMergeAction();
|
|
212
237
|
} }), hasModes && (jsx(TransactionModeSegmentedControl, { options: transactionModes, selectedId: selectedModeId, onChange: handleModeChange, disabled: isMerging })), mergeAction && (jsx("div", { className: 'send-balance-form__inline-action', children: jsx(Alert, { icon: 'error', variant: 'warning', children: jsxs("div", { className: 'send-balance-form__inline-action-content', children: [jsx(Typography, { variant: 'body_small', weight: 'regular', children: mergeAction.message }), jsx(TypographyButton, { dataTestId: 'sendBalanceFormMergeRecordsButton', type: 'button', buttonVariant: 'secondary', buttonPadding: 'small', onClick: handleMergeAction, disabled: isMerging, children: isMerging
|
|
213
238
|
? t('dyn_send_transaction.merging', 'Merging…')
|
|
214
|
-
: mergeAction.actionLabel })] }) }) })), jsx(TypographyButton, { dataTestId: 'sendBalanceFormSubmitButton', expanded: true, type: 'submit', buttonVariant: 'primary', buttonPadding: 'small', buttonClassName: 'send-balance-form__button', copykey: 'dyn_send_transaction.preview_transaction', disabled: !modeReady ||
|
|
239
|
+
: mergeAction.actionLabel })] }) }) })), jsx(TypographyButton, { dataTestId: 'sendBalanceFormSubmitButton', expanded: true, type: 'submit', buttonVariant: 'primary', buttonPadding: 'small', buttonClassName: 'send-balance-form__button', copykey: 'dyn_send_transaction.preview_transaction', disabled: !modeReady ||
|
|
240
|
+
!selectionMatchesMode ||
|
|
241
|
+
isMerging ||
|
|
242
|
+
Boolean(mergeAction), children: t('dyn_send_transaction.preview_transaction') })] }));
|
|
215
243
|
} }));
|
|
216
244
|
};
|
|
217
245
|
|
|
@@ -126,7 +126,7 @@ require('../../store/state/multichainBalances.cjs');
|
|
|
126
126
|
require('@dynamic-labs/store');
|
|
127
127
|
require('../../shared/utils/functions/getInitialUrl/getInitialUrl.cjs');
|
|
128
128
|
|
|
129
|
-
const SendBalancePageLayout = ({ error, onClickClose, onClickBack, onSubmit, displayPoweredByDynamicFooter = false, transaction, networkCurrencyDecimals, tokenBalances, currentToken, setCurrentToken, isLoading, isNativeToken, }) => {
|
|
129
|
+
const SendBalancePageLayout = ({ error, onClickClose, onClickBack, onSubmit, displayPoweredByDynamicFooter = false, transaction, networkIcon, networkCurrencyDecimals, tokenBalances, currentToken, setCurrentToken, isLoading, isNativeToken, }) => {
|
|
130
130
|
var _a, _b, _c;
|
|
131
131
|
const { t } = reactI18next.useTranslation();
|
|
132
132
|
const { primaryWallet, projectSettings, overrides } = useInternalDynamicContext.useInternalDynamicContext();
|
|
@@ -254,7 +254,7 @@ const SendBalancePageLayout = ({ error, onClickClose, onClickBack, onSubmit, dis
|
|
|
254
254
|
return false;
|
|
255
255
|
const amount = Number(transaction.parseNonNativeToken(amountText, (currentToken === null || currentToken === void 0 ? void 0 : currentToken.decimals) || 18));
|
|
256
256
|
return amount <= currentToken.rawBalance;
|
|
257
|
-
}, currentToken: currentToken, transaction: transaction }), displayPoweredByDynamicFooter && (jsxRuntime.jsx(PoweredByDynamic.PoweredByDynamic, { classNameRoot: 'send-balance-page-layout__footer' }))] })] }));
|
|
257
|
+
}, currentToken: currentToken, transaction: transaction, fallbackTokenIcon: networkIcon }), displayPoweredByDynamicFooter && (jsxRuntime.jsx(PoweredByDynamic.PoweredByDynamic, { classNameRoot: 'send-balance-page-layout__footer' }))] })] }));
|
|
258
258
|
};
|
|
259
259
|
|
|
260
260
|
exports.SendBalancePageLayout = SendBalancePageLayout;
|
|
@@ -122,7 +122,7 @@ import '../../store/state/multichainBalances.js';
|
|
|
122
122
|
import '@dynamic-labs/store';
|
|
123
123
|
import '../../shared/utils/functions/getInitialUrl/getInitialUrl.js';
|
|
124
124
|
|
|
125
|
-
const SendBalancePageLayout = ({ error, onClickClose, onClickBack, onSubmit, displayPoweredByDynamicFooter = false, transaction, networkCurrencyDecimals, tokenBalances, currentToken, setCurrentToken, isLoading, isNativeToken, }) => {
|
|
125
|
+
const SendBalancePageLayout = ({ error, onClickClose, onClickBack, onSubmit, displayPoweredByDynamicFooter = false, transaction, networkIcon, networkCurrencyDecimals, tokenBalances, currentToken, setCurrentToken, isLoading, isNativeToken, }) => {
|
|
126
126
|
var _a, _b, _c;
|
|
127
127
|
const { t } = useTranslation();
|
|
128
128
|
const { primaryWallet, projectSettings, overrides } = useInternalDynamicContext();
|
|
@@ -250,7 +250,7 @@ const SendBalancePageLayout = ({ error, onClickClose, onClickBack, onSubmit, dis
|
|
|
250
250
|
return false;
|
|
251
251
|
const amount = Number(transaction.parseNonNativeToken(amountText, (currentToken === null || currentToken === void 0 ? void 0 : currentToken.decimals) || 18));
|
|
252
252
|
return amount <= currentToken.rawBalance;
|
|
253
|
-
}, currentToken: currentToken, transaction: transaction }), displayPoweredByDynamicFooter && (jsx(PoweredByDynamic, { classNameRoot: 'send-balance-page-layout__footer' }))] })] }));
|
|
253
|
+
}, currentToken: currentToken, transaction: transaction, fallbackTokenIcon: networkIcon }), displayPoweredByDynamicFooter && (jsx(PoweredByDynamic, { classNameRoot: 'send-balance-page-layout__footer' }))] })] }));
|
|
254
254
|
};
|
|
255
255
|
|
|
256
256
|
export { SendBalancePageLayout };
|
|
@@ -121,7 +121,8 @@ require('../../../OverlayCard/OverlayCard.cjs');
|
|
|
121
121
|
require('../../../Popper/Popper/Popper.cjs');
|
|
122
122
|
require('../../../Popper/PopperContext/PopperContext.cjs');
|
|
123
123
|
|
|
124
|
-
const TokensBalanceDropdown = ({ tokenBalances, currentToken, setCurrentToken, isLoading, setFieldValue, setErrors, }) => {
|
|
124
|
+
const TokensBalanceDropdown = ({ tokenBalances, currentToken, setCurrentToken, isLoading, setFieldValue, setErrors, fallbackTokenIcon, placeholder, }) => {
|
|
125
|
+
var _a;
|
|
125
126
|
const { t } = reactI18next.useTranslation();
|
|
126
127
|
const [isDropdownOpen, setIsDropdownOpen] = React.useState(false);
|
|
127
128
|
// Hide rows the user can't actually send from: anonymous tokens (no
|
|
@@ -155,7 +156,7 @@ const TokensBalanceDropdown = ({ tokenBalances, currentToken, setCurrentToken, i
|
|
|
155
156
|
});
|
|
156
157
|
[balance, decimals] = results.map((v) => Number(v.result));
|
|
157
158
|
}
|
|
158
|
-
catch (
|
|
159
|
+
catch (_b) {
|
|
159
160
|
if (publicClient.readContract) {
|
|
160
161
|
const [balanceResult, decimalsResult] = yield Promise.all([
|
|
161
162
|
publicClient.readContract(Object.assign(Object.assign({}, erc20Contract), { args: [primaryWallet === null || primaryWallet === void 0 ? void 0 : primaryWallet.address], functionName: 'balanceOf' })),
|
|
@@ -183,14 +184,14 @@ const TokensBalanceDropdown = ({ tokenBalances, currentToken, setCurrentToken, i
|
|
|
183
184
|
}
|
|
184
185
|
});
|
|
185
186
|
const handleTokenClick = (selectedTokenName) => _tslib.__awaiter(void 0, void 0, void 0, function* () {
|
|
186
|
-
var
|
|
187
|
-
const selectedToken = (
|
|
187
|
+
var _c, _d;
|
|
188
|
+
const selectedToken = (_c = tokenBalances === null || tokenBalances === void 0 ? void 0 : tokenBalances.find((t) => t.name === selectedTokenName)) !== null && _c !== void 0 ? _c : undefined;
|
|
188
189
|
// we dont need to refetch solana balances because we simulate before sending
|
|
189
190
|
if ((selectedToken === null || selectedToken === void 0 ? void 0 : selectedToken.address) && (selectedToken === null || selectedToken === void 0 ? void 0 : selectedToken.address.startsWith('0x'))) {
|
|
190
191
|
fetchTokenData(selectedToken);
|
|
191
192
|
}
|
|
192
193
|
if (selectedToken) {
|
|
193
|
-
if (tokenBalances && ((
|
|
194
|
+
if (tokenBalances && ((_d = tokenBalances[0]) === null || _d === void 0 ? void 0 : _d.price))
|
|
194
195
|
sendBalances.setSendBalanceVariable('nativePrice', tokenBalances[0].price);
|
|
195
196
|
setCurrentToken(selectedToken);
|
|
196
197
|
setFieldValue('amount', '');
|
|
@@ -204,8 +205,8 @@ const TokensBalanceDropdown = ({ tokenBalances, currentToken, setCurrentToken, i
|
|
|
204
205
|
}
|
|
205
206
|
const tokenLogo = (token, size) => (jsxRuntime.jsx(Image.Image, { src: token === null || token === void 0 ? void 0 : token.logoURI, alt: token === null || token === void 0 ? void 0 : token.name, className: 'token-balance-item__icon', dataTestId: 'token-balance-item-icon', fallback:
|
|
206
207
|
// eslint-disable-next-line react/jsx-wrap-multilines
|
|
207
|
-
jsxRuntime.jsx("div", { className: 'token-balance-item__skeleton-icon', "data-testid": 'token-balance-item__skeleton-icon', style: { height: `${size}px`, width: `${size}px` } }) }));
|
|
208
|
-
return (jsxRuntime.jsxs("div", { className: 'tokens-balance-dropdown', ref: anchorRef, onClick: () => setIsDropdownOpen(!isDropdownOpen), "data-testid": 'tokens-balance-dropdown', children: [!isLoading && (jsxRuntime.jsxs("div", { className: 'tokens-balance-dropdown__selected', children: [tokenLogo(currentToken, '20'), jsxRuntime.jsx(Typography.Typography, { variant: 'body_normal', color: 'primary', children: currentToken === null || currentToken === void 0 ? void 0 : currentToken.name }), jsxRuntime.jsx(Icon.Icon, { color: 'text-primary', size: 'small', className: classNames.classNames('evm-network-control__arrow-icon', {
|
|
208
|
+
fallbackTokenIcon !== null && fallbackTokenIcon !== void 0 ? fallbackTokenIcon : (jsxRuntime.jsx("div", { className: 'token-balance-item__skeleton-icon', "data-testid": 'token-balance-item__skeleton-icon', style: { height: `${size}px`, width: `${size}px` } })) }));
|
|
209
|
+
return (jsxRuntime.jsxs("div", { className: 'tokens-balance-dropdown', ref: anchorRef, onClick: () => setIsDropdownOpen(!isDropdownOpen), "data-testid": 'tokens-balance-dropdown', children: [!isLoading && (jsxRuntime.jsxs("div", { className: 'tokens-balance-dropdown__selected', children: [tokenLogo(currentToken, '20'), jsxRuntime.jsx(Typography.Typography, { variant: 'body_normal', color: 'primary', children: (_a = currentToken === null || currentToken === void 0 ? void 0 : currentToken.name) !== null && _a !== void 0 ? _a : placeholder }), jsxRuntime.jsx(Icon.Icon, { color: 'text-primary', size: 'small', className: classNames.classNames('evm-network-control__arrow-icon', {
|
|
209
210
|
'evm-network-control__arrow-icon--active': isDropdownOpen,
|
|
210
211
|
}), children: jsxRuntime.jsx(stroke.ReactComponent, {}) })] })), jsxRuntime.jsx(MenuList.MenuList, { className: 'tokens-balance-dropdown__menu_list', isOpen: isDropdownOpen, popperProps: {
|
|
211
212
|
anchorOrigin: 'bottom-left',
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { Dispatch, FC, SetStateAction } from 'react';
|
|
1
|
+
import { Dispatch, FC, type ReactNode, SetStateAction } from 'react';
|
|
2
2
|
import { TokenBalance } from '@dynamic-labs/sdk-api-core';
|
|
3
3
|
type TokensBalanceDropdownProps = {
|
|
4
4
|
tokenBalances: TokenBalance[] | undefined;
|
|
@@ -7,6 +7,8 @@ type TokensBalanceDropdownProps = {
|
|
|
7
7
|
isLoading?: boolean;
|
|
8
8
|
setFieldValue: (field: string, value: string) => void;
|
|
9
9
|
setErrors: (errors: any) => void;
|
|
10
|
+
fallbackTokenIcon?: ReactNode;
|
|
11
|
+
placeholder?: string;
|
|
10
12
|
};
|
|
11
13
|
export declare const TokensBalanceDropdown: FC<TokensBalanceDropdownProps>;
|
|
12
14
|
export {};
|
|
@@ -117,7 +117,8 @@ import '../../../OverlayCard/OverlayCard.js';
|
|
|
117
117
|
import '../../../Popper/Popper/Popper.js';
|
|
118
118
|
import '../../../Popper/PopperContext/PopperContext.js';
|
|
119
119
|
|
|
120
|
-
const TokensBalanceDropdown = ({ tokenBalances, currentToken, setCurrentToken, isLoading, setFieldValue, setErrors, }) => {
|
|
120
|
+
const TokensBalanceDropdown = ({ tokenBalances, currentToken, setCurrentToken, isLoading, setFieldValue, setErrors, fallbackTokenIcon, placeholder, }) => {
|
|
121
|
+
var _a;
|
|
121
122
|
const { t } = useTranslation();
|
|
122
123
|
const [isDropdownOpen, setIsDropdownOpen] = useState(false);
|
|
123
124
|
// Hide rows the user can't actually send from: anonymous tokens (no
|
|
@@ -151,7 +152,7 @@ const TokensBalanceDropdown = ({ tokenBalances, currentToken, setCurrentToken, i
|
|
|
151
152
|
});
|
|
152
153
|
[balance, decimals] = results.map((v) => Number(v.result));
|
|
153
154
|
}
|
|
154
|
-
catch (
|
|
155
|
+
catch (_b) {
|
|
155
156
|
if (publicClient.readContract) {
|
|
156
157
|
const [balanceResult, decimalsResult] = yield Promise.all([
|
|
157
158
|
publicClient.readContract(Object.assign(Object.assign({}, erc20Contract), { args: [primaryWallet === null || primaryWallet === void 0 ? void 0 : primaryWallet.address], functionName: 'balanceOf' })),
|
|
@@ -179,14 +180,14 @@ const TokensBalanceDropdown = ({ tokenBalances, currentToken, setCurrentToken, i
|
|
|
179
180
|
}
|
|
180
181
|
});
|
|
181
182
|
const handleTokenClick = (selectedTokenName) => __awaiter(void 0, void 0, void 0, function* () {
|
|
182
|
-
var
|
|
183
|
-
const selectedToken = (
|
|
183
|
+
var _c, _d;
|
|
184
|
+
const selectedToken = (_c = tokenBalances === null || tokenBalances === void 0 ? void 0 : tokenBalances.find((t) => t.name === selectedTokenName)) !== null && _c !== void 0 ? _c : undefined;
|
|
184
185
|
// we dont need to refetch solana balances because we simulate before sending
|
|
185
186
|
if ((selectedToken === null || selectedToken === void 0 ? void 0 : selectedToken.address) && (selectedToken === null || selectedToken === void 0 ? void 0 : selectedToken.address.startsWith('0x'))) {
|
|
186
187
|
fetchTokenData(selectedToken);
|
|
187
188
|
}
|
|
188
189
|
if (selectedToken) {
|
|
189
|
-
if (tokenBalances && ((
|
|
190
|
+
if (tokenBalances && ((_d = tokenBalances[0]) === null || _d === void 0 ? void 0 : _d.price))
|
|
190
191
|
setSendBalanceVariable('nativePrice', tokenBalances[0].price);
|
|
191
192
|
setCurrentToken(selectedToken);
|
|
192
193
|
setFieldValue('amount', '');
|
|
@@ -200,8 +201,8 @@ const TokensBalanceDropdown = ({ tokenBalances, currentToken, setCurrentToken, i
|
|
|
200
201
|
}
|
|
201
202
|
const tokenLogo = (token, size) => (jsx(Image, { src: token === null || token === void 0 ? void 0 : token.logoURI, alt: token === null || token === void 0 ? void 0 : token.name, className: 'token-balance-item__icon', dataTestId: 'token-balance-item-icon', fallback:
|
|
202
203
|
// eslint-disable-next-line react/jsx-wrap-multilines
|
|
203
|
-
jsx("div", { className: 'token-balance-item__skeleton-icon', "data-testid": 'token-balance-item__skeleton-icon', style: { height: `${size}px`, width: `${size}px` } }) }));
|
|
204
|
-
return (jsxs("div", { className: 'tokens-balance-dropdown', ref: anchorRef, onClick: () => setIsDropdownOpen(!isDropdownOpen), "data-testid": 'tokens-balance-dropdown', children: [!isLoading && (jsxs("div", { className: 'tokens-balance-dropdown__selected', children: [tokenLogo(currentToken, '20'), jsx(Typography, { variant: 'body_normal', color: 'primary', children: currentToken === null || currentToken === void 0 ? void 0 : currentToken.name }), jsx(Icon, { color: 'text-primary', size: 'small', className: classNames('evm-network-control__arrow-icon', {
|
|
204
|
+
fallbackTokenIcon !== null && fallbackTokenIcon !== void 0 ? fallbackTokenIcon : (jsx("div", { className: 'token-balance-item__skeleton-icon', "data-testid": 'token-balance-item__skeleton-icon', style: { height: `${size}px`, width: `${size}px` } })) }));
|
|
205
|
+
return (jsxs("div", { className: 'tokens-balance-dropdown', ref: anchorRef, onClick: () => setIsDropdownOpen(!isDropdownOpen), "data-testid": 'tokens-balance-dropdown', children: [!isLoading && (jsxs("div", { className: 'tokens-balance-dropdown__selected', children: [tokenLogo(currentToken, '20'), jsx(Typography, { variant: 'body_normal', color: 'primary', children: (_a = currentToken === null || currentToken === void 0 ? void 0 : currentToken.name) !== null && _a !== void 0 ? _a : placeholder }), jsx(Icon, { color: 'text-primary', size: 'small', className: classNames('evm-network-control__arrow-icon', {
|
|
205
206
|
'evm-network-control__arrow-icon--active': isDropdownOpen,
|
|
206
207
|
}), children: jsx(SvgStroke, {}) })] })), jsx(MenuList, { className: 'tokens-balance-dropdown__menu_list', isOpen: isDropdownOpen, popperProps: {
|
|
207
208
|
anchorOrigin: 'bottom-left',
|
|
@@ -454,7 +454,24 @@ const useDynamicWaas = () => {
|
|
|
454
454
|
});
|
|
455
455
|
yield refresh();
|
|
456
456
|
});
|
|
457
|
-
const
|
|
457
|
+
const migrateFromFireblocks = (_h) => _tslib.__awaiter(void 0, [_h], void 0, function* ({ deviceId, jwt, password, storage, expectedAddresses, }) {
|
|
458
|
+
const [chainName] = enabledChainNames !== null && enabledChainNames !== void 0 ? enabledChainNames : [];
|
|
459
|
+
if (!chainName)
|
|
460
|
+
return undefined;
|
|
461
|
+
const walletConnector = getWaasWalletConnector(chainName);
|
|
462
|
+
if (!walletConnector)
|
|
463
|
+
return undefined;
|
|
464
|
+
const result = yield walletConnector.migrateFromFireblocks({
|
|
465
|
+
deviceId,
|
|
466
|
+
expectedAddresses,
|
|
467
|
+
jwt,
|
|
468
|
+
ncwStorage: storage,
|
|
469
|
+
walletPassword: password,
|
|
470
|
+
});
|
|
471
|
+
yield refresh();
|
|
472
|
+
return result;
|
|
473
|
+
});
|
|
474
|
+
const upgradeToDynamicWaas = React.useCallback((_j) => _tslib.__awaiter(void 0, [_j], void 0, function* ({ privateKey, wallet, password, }) {
|
|
458
475
|
isUpgrading.current = true;
|
|
459
476
|
if (!wallet) {
|
|
460
477
|
throw new utils.DynamicError('Wallet to upgrade was not provided');
|
|
@@ -534,14 +551,14 @@ const useDynamicWaas = () => {
|
|
|
534
551
|
values.VerifiedCredentialNameToChainEnum[cred.chain]);
|
|
535
552
|
}, [user === null || user === void 0 ? void 0 : user.verifiedCredentials]);
|
|
536
553
|
const processSignOnWalletSettings = React.useCallback(() => _tslib.__awaiter(void 0, void 0, void 0, function* () {
|
|
537
|
-
var
|
|
554
|
+
var _k;
|
|
538
555
|
if (!(user === null || user === void 0 ? void 0 : user.verifiedCredentials)) {
|
|
539
556
|
return;
|
|
540
557
|
}
|
|
541
558
|
const waasWallets = user.verifiedCredentials.filter((vc) => { var _a; return vc.walletName === 'dynamicwaas' && ((_a = vc.walletProperties) === null || _a === void 0 ? void 0 : _a.settings); });
|
|
542
559
|
for (const wallet of waasWallets) {
|
|
543
560
|
try {
|
|
544
|
-
const settings = (
|
|
561
|
+
const settings = (_k = wallet.walletProperties) === null || _k === void 0 ? void 0 : _k.settings;
|
|
545
562
|
const { address, chain } = wallet;
|
|
546
563
|
if (!settings || !address || !chain) {
|
|
547
564
|
continue;
|
|
@@ -612,6 +629,7 @@ const useDynamicWaas = () => {
|
|
|
612
629
|
getWaasWalletsByCredentials,
|
|
613
630
|
importPrivateKey,
|
|
614
631
|
initializeWaas,
|
|
632
|
+
migrateFromFireblocks,
|
|
615
633
|
needsAutoCreateWalletChains,
|
|
616
634
|
needsSettingsProcessing,
|
|
617
635
|
processSignOnWalletSettings,
|
|
@@ -54,6 +54,13 @@ export declare const useDynamicWaas: () => {
|
|
|
54
54
|
initializeWaas: ({ forceClientRebuild, }?: {
|
|
55
55
|
forceClientRebuild?: boolean;
|
|
56
56
|
}) => Promise<void>;
|
|
57
|
+
migrateFromFireblocks: ({ deviceId, jwt, password, storage, expectedAddresses, }: {
|
|
58
|
+
deviceId: string;
|
|
59
|
+
jwt: string;
|
|
60
|
+
password: string;
|
|
61
|
+
storage: Record<string, string>;
|
|
62
|
+
expectedAddresses: Record<string, string>;
|
|
63
|
+
}) => Promise<import("@dynamic-labs-wallet/browser-wallet-client").MigrateFromFireblocksResponse | undefined>;
|
|
57
64
|
needsAutoCreateWalletChains: WalletCreationRequirement[];
|
|
58
65
|
needsSettingsProcessing: boolean;
|
|
59
66
|
processSignOnWalletSettings: () => Promise<void>;
|
|
@@ -450,7 +450,24 @@ const useDynamicWaas = () => {
|
|
|
450
450
|
});
|
|
451
451
|
yield refresh();
|
|
452
452
|
});
|
|
453
|
-
const
|
|
453
|
+
const migrateFromFireblocks = (_h) => __awaiter(void 0, [_h], void 0, function* ({ deviceId, jwt, password, storage, expectedAddresses, }) {
|
|
454
|
+
const [chainName] = enabledChainNames !== null && enabledChainNames !== void 0 ? enabledChainNames : [];
|
|
455
|
+
if (!chainName)
|
|
456
|
+
return undefined;
|
|
457
|
+
const walletConnector = getWaasWalletConnector(chainName);
|
|
458
|
+
if (!walletConnector)
|
|
459
|
+
return undefined;
|
|
460
|
+
const result = yield walletConnector.migrateFromFireblocks({
|
|
461
|
+
deviceId,
|
|
462
|
+
expectedAddresses,
|
|
463
|
+
jwt,
|
|
464
|
+
ncwStorage: storage,
|
|
465
|
+
walletPassword: password,
|
|
466
|
+
});
|
|
467
|
+
yield refresh();
|
|
468
|
+
return result;
|
|
469
|
+
});
|
|
470
|
+
const upgradeToDynamicWaas = useCallback((_j) => __awaiter(void 0, [_j], void 0, function* ({ privateKey, wallet, password, }) {
|
|
454
471
|
isUpgrading.current = true;
|
|
455
472
|
if (!wallet) {
|
|
456
473
|
throw new DynamicError('Wallet to upgrade was not provided');
|
|
@@ -530,14 +547,14 @@ const useDynamicWaas = () => {
|
|
|
530
547
|
VerifiedCredentialNameToChainEnum[cred.chain]);
|
|
531
548
|
}, [user === null || user === void 0 ? void 0 : user.verifiedCredentials]);
|
|
532
549
|
const processSignOnWalletSettings = useCallback(() => __awaiter(void 0, void 0, void 0, function* () {
|
|
533
|
-
var
|
|
550
|
+
var _k;
|
|
534
551
|
if (!(user === null || user === void 0 ? void 0 : user.verifiedCredentials)) {
|
|
535
552
|
return;
|
|
536
553
|
}
|
|
537
554
|
const waasWallets = user.verifiedCredentials.filter((vc) => { var _a; return vc.walletName === 'dynamicwaas' && ((_a = vc.walletProperties) === null || _a === void 0 ? void 0 : _a.settings); });
|
|
538
555
|
for (const wallet of waasWallets) {
|
|
539
556
|
try {
|
|
540
|
-
const settings = (
|
|
557
|
+
const settings = (_k = wallet.walletProperties) === null || _k === void 0 ? void 0 : _k.settings;
|
|
541
558
|
const { address, chain } = wallet;
|
|
542
559
|
if (!settings || !address || !chain) {
|
|
543
560
|
continue;
|
|
@@ -608,6 +625,7 @@ const useDynamicWaas = () => {
|
|
|
608
625
|
getWaasWalletsByCredentials,
|
|
609
626
|
importPrivateKey,
|
|
610
627
|
initializeWaas,
|
|
628
|
+
migrateFromFireblocks,
|
|
611
629
|
needsAutoCreateWalletChains,
|
|
612
630
|
needsSettingsProcessing,
|
|
613
631
|
processSignOnWalletSettings,
|
|
@@ -63,9 +63,10 @@ const useEmbeddedReveal = () => {
|
|
|
63
63
|
throw new Error('Wallet is non-HD and does not have a recovery phrase');
|
|
64
64
|
}
|
|
65
65
|
};
|
|
66
|
-
const initExportProcess = React.useCallback((...args_1) => _tslib.__awaiter(void 0, [...args_1], void 0, function* (recoveryPhrase = false, isPromptForExport = false) {
|
|
67
|
-
|
|
68
|
-
|
|
66
|
+
const initExportProcess = React.useCallback((...args_1) => _tslib.__awaiter(void 0, [...args_1], void 0, function* (recoveryPhrase = false, isPromptForExport = false, walletId) {
|
|
67
|
+
const targetWalletId = walletId !== null && walletId !== void 0 ? walletId : primaryWallet === null || primaryWallet === void 0 ? void 0 : primaryWallet.id;
|
|
68
|
+
if (!targetWalletId) {
|
|
69
|
+
throw new Error('No wallet available for export');
|
|
69
70
|
}
|
|
70
71
|
if (!user) {
|
|
71
72
|
throw new Error(errors.USER_NOT_LOGGED_IN);
|
|
@@ -83,6 +84,7 @@ const useEmbeddedReveal = () => {
|
|
|
83
84
|
pushView('embedded-reveal-view', {
|
|
84
85
|
exportPrivateKey: !recoveryPhrase,
|
|
85
86
|
isPromptForExport,
|
|
87
|
+
walletId: targetWalletId,
|
|
86
88
|
});
|
|
87
89
|
return new Promise((resolve, reject) => {
|
|
88
90
|
dynamicEvents.dynamicEvents.once('embeddedWalletRevealCompleted', (wallet) => resolve(wallet));
|
|
@@ -1,4 +1,4 @@
|
|
|
1
1
|
import { Wallet } from '../../../shared';
|
|
2
2
|
export declare const useEmbeddedReveal: () => {
|
|
3
|
-
readonly initExportProcess: (recoveryPhrase?: boolean, isPromptForExport?: boolean) => Promise<Wallet>;
|
|
3
|
+
readonly initExportProcess: (recoveryPhrase?: boolean, isPromptForExport?: boolean, walletId?: string) => Promise<Wallet>;
|
|
4
4
|
};
|
|
@@ -59,9 +59,10 @@ const useEmbeddedReveal = () => {
|
|
|
59
59
|
throw new Error('Wallet is non-HD and does not have a recovery phrase');
|
|
60
60
|
}
|
|
61
61
|
};
|
|
62
|
-
const initExportProcess = useCallback((...args_1) => __awaiter(void 0, [...args_1], void 0, function* (recoveryPhrase = false, isPromptForExport = false) {
|
|
63
|
-
|
|
64
|
-
|
|
62
|
+
const initExportProcess = useCallback((...args_1) => __awaiter(void 0, [...args_1], void 0, function* (recoveryPhrase = false, isPromptForExport = false, walletId) {
|
|
63
|
+
const targetWalletId = walletId !== null && walletId !== void 0 ? walletId : primaryWallet === null || primaryWallet === void 0 ? void 0 : primaryWallet.id;
|
|
64
|
+
if (!targetWalletId) {
|
|
65
|
+
throw new Error('No wallet available for export');
|
|
65
66
|
}
|
|
66
67
|
if (!user) {
|
|
67
68
|
throw new Error(USER_NOT_LOGGED_IN);
|
|
@@ -79,6 +80,7 @@ const useEmbeddedReveal = () => {
|
|
|
79
80
|
pushView('embedded-reveal-view', {
|
|
80
81
|
exportPrivateKey: !recoveryPhrase,
|
|
81
82
|
isPromptForExport,
|
|
83
|
+
walletId: targetWalletId,
|
|
82
84
|
});
|
|
83
85
|
return new Promise((resolve, reject) => {
|
|
84
86
|
dynamicEvents.once('embeddedWalletRevealCompleted', (wallet) => resolve(wallet));
|
|
@@ -95,7 +95,7 @@ const useSyncEmbeddedWalletFlow = () => {
|
|
|
95
95
|
primaryWallet) {
|
|
96
96
|
try {
|
|
97
97
|
setShowAuthFlow(true);
|
|
98
|
-
yield initExportProcess(true, true);
|
|
98
|
+
yield initExportProcess(true, true, primaryWallet.id);
|
|
99
99
|
}
|
|
100
100
|
catch (error) {
|
|
101
101
|
logger.logger.error('Error initializing embedded wallet export', error);
|
|
@@ -91,7 +91,7 @@ const useSyncEmbeddedWalletFlow = () => {
|
|
|
91
91
|
primaryWallet) {
|
|
92
92
|
try {
|
|
93
93
|
setShowAuthFlow(true);
|
|
94
|
-
yield initExportProcess(true, true);
|
|
94
|
+
yield initExportProcess(true, true, primaryWallet.id);
|
|
95
95
|
}
|
|
96
96
|
catch (error) {
|
|
97
97
|
logger.error('Error initializing embedded wallet export', error);
|
|
@@ -55,7 +55,7 @@ require('../../../store/state/connectedWalletsInfo/connectedWalletsInfo.cjs');
|
|
|
55
55
|
require('../../../utils/functions/getWaasAddressTypeLabel/getWaasAddressTypeLabel.cjs');
|
|
56
56
|
require('../../../context/AccessDeniedContext/AccessDeniedContext.cjs');
|
|
57
57
|
require('../../../context/AccountExistsContext/AccountExistsContext.cjs');
|
|
58
|
-
require('../../../context/UserWalletsContext/UserWalletsContext.cjs');
|
|
58
|
+
var UserWalletsContext = require('../../../context/UserWalletsContext/UserWalletsContext.cjs');
|
|
59
59
|
require('../../../store/state/authMode/authMode.cjs');
|
|
60
60
|
require('../../../store/state/loadingAndLifecycle/loadingAndLifecycle.cjs');
|
|
61
61
|
require('../../../context/VerificationContext/VerificationContext.cjs');
|
|
@@ -66,7 +66,6 @@ require('../../../context/ThemeContext/ThemeContext.cjs');
|
|
|
66
66
|
var useSmartWallets = require('../../../utils/hooks/useSmartWallets/useSmartWallets.cjs');
|
|
67
67
|
require('../../../utils/hooks/useUserUpdateRequest/useUpdateUser/userFieldsSchema.cjs');
|
|
68
68
|
var useMutation = require('../../../utils/hooks/useMutation/useMutation.cjs');
|
|
69
|
-
var useIsTurnkeyWallet = require('../../../utils/hooks/useIsTurnkeyWallet/useIsTurnkeyWallet.cjs');
|
|
70
69
|
require('bs58');
|
|
71
70
|
require('@dynamic-labs/types');
|
|
72
71
|
require('../../../context/SocialRedirectContext/SocialRedirectContext.cjs');
|
|
@@ -136,32 +135,40 @@ var useSyncEmbeddedWalletFlow = require('../../../utils/hooks/useSyncEmbeddedWal
|
|
|
136
135
|
require('@dynamic-labs/store');
|
|
137
136
|
require('../../../shared/utils/functions/getInitialUrl/getInitialUrl.cjs');
|
|
138
137
|
|
|
139
|
-
const EmbeddedRevealView = ({ exportPrivateKey, isPromptForExport = false, }) => {
|
|
140
|
-
var _a, _b, _c;
|
|
138
|
+
const EmbeddedRevealView = ({ exportPrivateKey, isPromptForExport = false, walletId, }) => {
|
|
139
|
+
var _a, _b, _c, _d, _e;
|
|
141
140
|
const { primaryWallet, user, setShowAuthFlow, environmentId } = useInternalDynamicContext.useInternalDynamicContext();
|
|
141
|
+
const { userWallets } = UserWalletsContext.useInternalUserWallets();
|
|
142
142
|
const { handleAcknowledgeExportPrompt } = useSyncEmbeddedWalletFlow.useSyncEmbeddedWalletFlow();
|
|
143
|
-
const { isTurnkeyWallet } = useIsTurnkeyWallet.useIsTurnkeyWallet();
|
|
144
143
|
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'); }));
|
|
145
144
|
const { setDynamicWidgetView } = DynamicWidgetContext.useWidgetContext();
|
|
146
145
|
const { pushView } = ViewContext.useViewContext();
|
|
147
146
|
const { getEOAWallet, isSmartWallet } = useSmartWallets.useSmartWallets();
|
|
148
147
|
const [isAcknowledged, setIsAcknowledged] = React.useState(false);
|
|
149
148
|
const [iframeContainerRef, setIframeContainerRef] = React.useState(null);
|
|
150
|
-
|
|
149
|
+
const walletFromId = walletId
|
|
150
|
+
? userWallets.find((w) => w.id === walletId)
|
|
151
|
+
: undefined;
|
|
152
|
+
if (walletId && !walletFromId) {
|
|
153
|
+
throw new utils.DynamicError('Wallet not found. Please try again.', errors.INVALID_WALLET_DATA);
|
|
154
|
+
}
|
|
155
|
+
const targetWallet = walletFromId !== null && walletFromId !== void 0 ? walletFromId : primaryWallet;
|
|
156
|
+
if (!targetWallet) {
|
|
151
157
|
throw new utils.DynamicError('No primary wallet found', errors.INVALID_WALLET_DATA);
|
|
152
158
|
}
|
|
153
159
|
let primaryTurnkeyWalletId;
|
|
154
160
|
try {
|
|
155
|
-
primaryTurnkeyWalletId = getTurnkeyWalletId.getTurnkeyWalletId(
|
|
161
|
+
primaryTurnkeyWalletId = getTurnkeyWalletId.getTurnkeyWalletId(targetWallet.id, (user === null || user === void 0 ? void 0 : user.verifiedCredentials) || []);
|
|
156
162
|
}
|
|
157
163
|
catch (error) {
|
|
158
164
|
// waas wallet
|
|
159
165
|
}
|
|
160
166
|
const turnkeyCredential = (_a = user === null || user === void 0 ? void 0 : user.verifiedCredentials) === null || _a === void 0 ? void 0 : _a.find(({ walletName, id }) => (walletName === null || walletName === void 0 ? void 0 : walletName.startsWith('turnkey')) && id === primaryTurnkeyWalletId);
|
|
161
167
|
const walletProperties = turnkeyCredential === null || turnkeyCredential === void 0 ? void 0 : turnkeyCredential.walletProperties;
|
|
162
|
-
const walletCredential = (_b = user === null || user === void 0 ? void 0 : user.verifiedCredentials) === null || _b === void 0 ? void 0 : _b.find((cred) => cred.address ===
|
|
168
|
+
const walletCredential = (_b = user === null || user === void 0 ? void 0 : user.verifiedCredentials) === null || _b === void 0 ? void 0 : _b.find((cred) => cred.address === targetWallet.address);
|
|
163
169
|
const isTurnkeyHDWallet = walletProperties === null || walletProperties === void 0 ? void 0 : walletProperties.turnkeyHDWalletId;
|
|
164
|
-
const wallet = (_c = (
|
|
170
|
+
const wallet = (_c = (targetWallet && getEOAWallet(targetWallet))) !== null && _c !== void 0 ? _c : targetWallet;
|
|
171
|
+
const isTurnkeyWallet = Boolean((_e = (_d = wallet === null || wallet === void 0 ? void 0 : wallet.connector) === null || _d === void 0 ? void 0 : _d.key) === null || _e === void 0 ? void 0 : _e.startsWith('turnkey'));
|
|
165
172
|
// eslint-disable-next-line arrow-body-style
|
|
166
173
|
React.useEffect(() => {
|
|
167
174
|
return () => {
|
|
@@ -252,8 +259,8 @@ const EmbeddedRevealView = ({ exportPrivateKey, isPromptForExport = false, }) =>
|
|
|
252
259
|
}
|
|
253
260
|
return baseClass;
|
|
254
261
|
};
|
|
255
|
-
const isEip7702SmartWallet = Boolean(
|
|
256
|
-
const isErc4337SmartWallet = Boolean(
|
|
262
|
+
const isEip7702SmartWallet = Boolean(targetWallet === null || targetWallet === void 0 ? void 0 : targetWallet.id.endsWith('-zerodev'));
|
|
263
|
+
const isErc4337SmartWallet = Boolean(targetWallet && isSmartWallet(targetWallet)) &&
|
|
257
264
|
!isEip7702SmartWallet;
|
|
258
265
|
const shouldShowAaWarning = isErc4337SmartWallet && !isLoading && Boolean(data) && !error;
|
|
259
266
|
const aaWarning = shouldShowAaWarning && (jsxRuntime.jsxs("div", { className: 'embedded-reveal-view__zerodev-warning', children: [jsxRuntime.jsxs("div", { className: 'embedded-reveal-view__zerodev-warning__title-row', children: [jsxRuntime.jsx(info.ReactComponent, { className: 'embedded-reveal-view__zerodev-warning__icon' }), jsxRuntime.jsx(Typography.Typography, { variant: 'body_normal', weight: 'bold', copykey: 'dyn_embedded_reveal.aa_warning.title', children: t('dyn_embedded_reveal.aa_warning.title') })] }), jsxRuntime.jsxs(Typography.Typography, { variant: 'body_normal', weight: 'regular', copykey: 'dyn_embedded_reveal.aa_warning.subtitle', children: [t('dyn_embedded_reveal.aa_warning.subtitle'), jsxRuntime.jsx("button", { onClick: () => {
|
|
@@ -51,7 +51,7 @@ import '../../../store/state/connectedWalletsInfo/connectedWalletsInfo.js';
|
|
|
51
51
|
import '../../../utils/functions/getWaasAddressTypeLabel/getWaasAddressTypeLabel.js';
|
|
52
52
|
import '../../../context/AccessDeniedContext/AccessDeniedContext.js';
|
|
53
53
|
import '../../../context/AccountExistsContext/AccountExistsContext.js';
|
|
54
|
-
import '../../../context/UserWalletsContext/UserWalletsContext.js';
|
|
54
|
+
import { useInternalUserWallets } from '../../../context/UserWalletsContext/UserWalletsContext.js';
|
|
55
55
|
import '../../../store/state/authMode/authMode.js';
|
|
56
56
|
import '../../../store/state/loadingAndLifecycle/loadingAndLifecycle.js';
|
|
57
57
|
import '../../../context/VerificationContext/VerificationContext.js';
|
|
@@ -62,7 +62,6 @@ import '../../../context/ThemeContext/ThemeContext.js';
|
|
|
62
62
|
import { useSmartWallets } from '../../../utils/hooks/useSmartWallets/useSmartWallets.js';
|
|
63
63
|
import '../../../utils/hooks/useUserUpdateRequest/useUpdateUser/userFieldsSchema.js';
|
|
64
64
|
import { useMutation } from '../../../utils/hooks/useMutation/useMutation.js';
|
|
65
|
-
import { useIsTurnkeyWallet } from '../../../utils/hooks/useIsTurnkeyWallet/useIsTurnkeyWallet.js';
|
|
66
65
|
import 'bs58';
|
|
67
66
|
import '@dynamic-labs/types';
|
|
68
67
|
import '../../../context/SocialRedirectContext/SocialRedirectContext.js';
|
|
@@ -132,32 +131,40 @@ import { useSyncEmbeddedWalletFlow } from '../../../utils/hooks/useSyncEmbeddedW
|
|
|
132
131
|
import '@dynamic-labs/store';
|
|
133
132
|
import '../../../shared/utils/functions/getInitialUrl/getInitialUrl.js';
|
|
134
133
|
|
|
135
|
-
const EmbeddedRevealView = ({ exportPrivateKey, isPromptForExport = false, }) => {
|
|
136
|
-
var _a, _b, _c;
|
|
134
|
+
const EmbeddedRevealView = ({ exportPrivateKey, isPromptForExport = false, walletId, }) => {
|
|
135
|
+
var _a, _b, _c, _d, _e;
|
|
137
136
|
const { primaryWallet, user, setShowAuthFlow, environmentId } = useInternalDynamicContext();
|
|
137
|
+
const { userWallets } = useInternalUserWallets();
|
|
138
138
|
const { handleAcknowledgeExportPrompt } = useSyncEmbeddedWalletFlow();
|
|
139
|
-
const { isTurnkeyWallet } = useIsTurnkeyWallet();
|
|
140
139
|
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'); }));
|
|
141
140
|
const { setDynamicWidgetView } = useWidgetContext();
|
|
142
141
|
const { pushView } = useViewContext();
|
|
143
142
|
const { getEOAWallet, isSmartWallet } = useSmartWallets();
|
|
144
143
|
const [isAcknowledged, setIsAcknowledged] = useState(false);
|
|
145
144
|
const [iframeContainerRef, setIframeContainerRef] = useState(null);
|
|
146
|
-
|
|
145
|
+
const walletFromId = walletId
|
|
146
|
+
? userWallets.find((w) => w.id === walletId)
|
|
147
|
+
: undefined;
|
|
148
|
+
if (walletId && !walletFromId) {
|
|
149
|
+
throw new DynamicError('Wallet not found. Please try again.', INVALID_WALLET_DATA);
|
|
150
|
+
}
|
|
151
|
+
const targetWallet = walletFromId !== null && walletFromId !== void 0 ? walletFromId : primaryWallet;
|
|
152
|
+
if (!targetWallet) {
|
|
147
153
|
throw new DynamicError('No primary wallet found', INVALID_WALLET_DATA);
|
|
148
154
|
}
|
|
149
155
|
let primaryTurnkeyWalletId;
|
|
150
156
|
try {
|
|
151
|
-
primaryTurnkeyWalletId = getTurnkeyWalletId(
|
|
157
|
+
primaryTurnkeyWalletId = getTurnkeyWalletId(targetWallet.id, (user === null || user === void 0 ? void 0 : user.verifiedCredentials) || []);
|
|
152
158
|
}
|
|
153
159
|
catch (error) {
|
|
154
160
|
// waas wallet
|
|
155
161
|
}
|
|
156
162
|
const turnkeyCredential = (_a = user === null || user === void 0 ? void 0 : user.verifiedCredentials) === null || _a === void 0 ? void 0 : _a.find(({ walletName, id }) => (walletName === null || walletName === void 0 ? void 0 : walletName.startsWith('turnkey')) && id === primaryTurnkeyWalletId);
|
|
157
163
|
const walletProperties = turnkeyCredential === null || turnkeyCredential === void 0 ? void 0 : turnkeyCredential.walletProperties;
|
|
158
|
-
const walletCredential = (_b = user === null || user === void 0 ? void 0 : user.verifiedCredentials) === null || _b === void 0 ? void 0 : _b.find((cred) => cred.address ===
|
|
164
|
+
const walletCredential = (_b = user === null || user === void 0 ? void 0 : user.verifiedCredentials) === null || _b === void 0 ? void 0 : _b.find((cred) => cred.address === targetWallet.address);
|
|
159
165
|
const isTurnkeyHDWallet = walletProperties === null || walletProperties === void 0 ? void 0 : walletProperties.turnkeyHDWalletId;
|
|
160
|
-
const wallet = (_c = (
|
|
166
|
+
const wallet = (_c = (targetWallet && getEOAWallet(targetWallet))) !== null && _c !== void 0 ? _c : targetWallet;
|
|
167
|
+
const isTurnkeyWallet = Boolean((_e = (_d = wallet === null || wallet === void 0 ? void 0 : wallet.connector) === null || _d === void 0 ? void 0 : _d.key) === null || _e === void 0 ? void 0 : _e.startsWith('turnkey'));
|
|
161
168
|
// eslint-disable-next-line arrow-body-style
|
|
162
169
|
useEffect(() => {
|
|
163
170
|
return () => {
|
|
@@ -248,8 +255,8 @@ const EmbeddedRevealView = ({ exportPrivateKey, isPromptForExport = false, }) =>
|
|
|
248
255
|
}
|
|
249
256
|
return baseClass;
|
|
250
257
|
};
|
|
251
|
-
const isEip7702SmartWallet = Boolean(
|
|
252
|
-
const isErc4337SmartWallet = Boolean(
|
|
258
|
+
const isEip7702SmartWallet = Boolean(targetWallet === null || targetWallet === void 0 ? void 0 : targetWallet.id.endsWith('-zerodev'));
|
|
259
|
+
const isErc4337SmartWallet = Boolean(targetWallet && isSmartWallet(targetWallet)) &&
|
|
253
260
|
!isEip7702SmartWallet;
|
|
254
261
|
const shouldShowAaWarning = isErc4337SmartWallet && !isLoading && Boolean(data) && !error;
|
|
255
262
|
const aaWarning = shouldShowAaWarning && (jsxs("div", { className: 'embedded-reveal-view__zerodev-warning', children: [jsxs("div", { className: 'embedded-reveal-view__zerodev-warning__title-row', children: [jsx(SvgInfo, { className: 'embedded-reveal-view__zerodev-warning__icon' }), jsx(Typography, { variant: 'body_normal', weight: 'bold', copykey: 'dyn_embedded_reveal.aa_warning.title', children: t('dyn_embedded_reveal.aa_warning.title') })] }), jsxs(Typography, { variant: 'body_normal', weight: 'regular', copykey: 'dyn_embedded_reveal.aa_warning.subtitle', children: [t('dyn_embedded_reveal.aa_warning.subtitle'), jsx("button", { onClick: () => {
|
|
@@ -16,7 +16,7 @@ require('@dynamic-labs/iconic');
|
|
|
16
16
|
var midnightShielded = require('../../../../shared/assets/midnight-shielded.cjs');
|
|
17
17
|
var midnightUnshielded = require('../../../../shared/assets/midnight-unshielded.cjs');
|
|
18
18
|
require('../../../../context/ViewContext/ViewContext.cjs');
|
|
19
|
-
require('../../../../shared/logger.cjs');
|
|
19
|
+
var logger = require('../../../../shared/logger.cjs');
|
|
20
20
|
require('@dynamic-labs/wallet-book');
|
|
21
21
|
require('@dynamic-labs/utils');
|
|
22
22
|
require('../../../../utils/constants/colors.cjs');
|
|
@@ -80,7 +80,7 @@ const ActiveMidnightWalletBalance = ({ isLoading = false, }) => {
|
|
|
80
80
|
deps: [walletAddress, primaryWallet, dustPollTick],
|
|
81
81
|
enabled,
|
|
82
82
|
});
|
|
83
|
-
const { dustBalance,
|
|
83
|
+
const { dustBalance, shieldedTokenCount, unshieldedBalance, dustSyncing } = balances !== null && balances !== void 0 ? balances : {};
|
|
84
84
|
React.useEffect(() => {
|
|
85
85
|
if (!dustSyncing)
|
|
86
86
|
return undefined;
|
|
@@ -94,13 +94,29 @@ const ActiveMidnightWalletBalance = ({ isLoading = false, }) => {
|
|
|
94
94
|
// wallets manage dust themselves). When the embedded wallet has no dust
|
|
95
95
|
// registered yet, we surface a "Register DUST" button instead of the gauge.
|
|
96
96
|
const isWaasWallet = Boolean(primaryWallet && walletConnectorCore.isDynamicWaasConnector(primaryWallet.connector));
|
|
97
|
+
// True once registered. balance/cap can't tell us this on load (cap reads 0
|
|
98
|
+
// on current wallet-client builds), so we track it after a register call to
|
|
99
|
+
// flip from the "Register DUST" prompt to the generating state.
|
|
100
|
+
const [dustRegistered, setDustRegistered] = React.useState(false);
|
|
101
|
+
// Returns the promise so <Button> shows its built-in spinner while the heavy
|
|
102
|
+
// registerDust call runs.
|
|
97
103
|
const handleRegisterDust = () => _tslib.__awaiter(void 0, void 0, void 0, function* () {
|
|
98
104
|
const connector = primaryWallet === null || primaryWallet === void 0 ? void 0 : primaryWallet.connector;
|
|
99
105
|
if (!(connector === null || connector === void 0 ? void 0 : connector.registerDust))
|
|
100
106
|
return;
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
107
|
+
try {
|
|
108
|
+
const result = yield connector.registerDust();
|
|
109
|
+
if ((result === null || result === void 0 ? void 0 : result.status) === 'registered' ||
|
|
110
|
+
(result === null || result === void 0 ? void 0 : result.status) === 'already_registered' ||
|
|
111
|
+
(result === null || result === void 0 ? void 0 : result.status) === 'already_has_dust') {
|
|
112
|
+
setDustRegistered(true);
|
|
113
|
+
}
|
|
114
|
+
setDustPollTick((tick) => tick + 1);
|
|
115
|
+
}
|
|
116
|
+
catch (err) {
|
|
117
|
+
// Leave the prompt up so the user can retry rather than failing silently.
|
|
118
|
+
logger.logger.error('Failed to register dust', err);
|
|
119
|
+
}
|
|
104
120
|
});
|
|
105
121
|
// Only show the full skeleton on the very first load; background dust polls
|
|
106
122
|
// keep `balances` populated so the view never flashes back to a skeleton.
|
|
@@ -116,7 +132,10 @@ const ActiveMidnightWalletBalance = ({ isLoading = false, }) => {
|
|
|
116
132
|
cap: truncateToDecimals(dustBalance.cap, 2),
|
|
117
133
|
}
|
|
118
134
|
: undefined;
|
|
119
|
-
|
|
135
|
+
// Unshielded shows the native NIGHT amount; shielded has no NIGHT, so it
|
|
136
|
+
// shows the count of token types held in the pool instead.
|
|
137
|
+
const tokenCount = shieldedTokenCount !== null && shieldedTokenCount !== void 0 ? shieldedTokenCount : 0;
|
|
138
|
+
const shieldedDisplay = `${tokenCount} ${tokenCount === 1 ? 'token' : 'tokens'}`;
|
|
120
139
|
// Dust section has three mutually exclusive states (syncing, generating with
|
|
121
140
|
// a balance, and the WaaS "register dust" prompt). Resolved via a helper to
|
|
122
141
|
// avoid nesting ternaries in the JSX below.
|
|
@@ -124,8 +143,11 @@ const ActiveMidnightWalletBalance = ({ isLoading = false, }) => {
|
|
|
124
143
|
if (dustSyncing) {
|
|
125
144
|
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' })] }));
|
|
126
145
|
}
|
|
127
|
-
|
|
128
|
-
|
|
146
|
+
// Generating gauge: shown with a dust balance, or once registered (balance
|
|
147
|
+
// still 0 during the grace period). Bar renders either way; count only
|
|
148
|
+
// shows with a real balance.
|
|
149
|
+
if (dustBalance || (isWaasWallet && dustRegistered)) {
|
|
150
|
+
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') })] }), dustBalanceDisplay && (jsxRuntime.jsxs("span", { className: 'active-midnight-balance__dust-count', children: [dustBalanceDisplay.balance, "/", dustBalanceDisplay.cap] }))] }), jsxRuntime.jsx("div", { className: 'active-midnight-balance__dust-bar', children: DUST_SEGMENT_KEYS.map((segmentKey, i) => (jsxRuntime.jsx("div", { className: [
|
|
129
151
|
'active-midnight-balance__dust-segment',
|
|
130
152
|
i === 0 && 'active-midnight-balance__dust-segment--first',
|
|
131
153
|
i === DUST_SEGMENTS - 1 &&
|
|
@@ -143,7 +165,9 @@ const ActiveMidnightWalletBalance = ({ isLoading = false, }) => {
|
|
|
143
165
|
};
|
|
144
166
|
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', {
|
|
145
167
|
'active-midnight-balance__tab--active': activeTab === id,
|
|
146
|
-
}), "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.
|
|
168
|
+
}), "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.jsx("span", { className: 'active-midnight-balance__amount', children: activeTab === 'shielded'
|
|
169
|
+
? shieldedDisplay
|
|
170
|
+
: `${unshieldedBalance !== null && unshieldedBalance !== void 0 ? unshieldedBalance : '—'} NIGHT` })] })] }) }));
|
|
147
171
|
};
|
|
148
172
|
|
|
149
173
|
exports.ActiveMidnightWalletBalance = ActiveMidnightWalletBalance;
|
|
@@ -12,7 +12,7 @@ import '@dynamic-labs/iconic';
|
|
|
12
12
|
import { ReactComponent as SvgMidnightShielded } from '../../../../shared/assets/midnight-shielded.js';
|
|
13
13
|
import { ReactComponent as SvgMidnightUnshielded } from '../../../../shared/assets/midnight-unshielded.js';
|
|
14
14
|
import '../../../../context/ViewContext/ViewContext.js';
|
|
15
|
-
import '../../../../shared/logger.js';
|
|
15
|
+
import { logger } from '../../../../shared/logger.js';
|
|
16
16
|
import '@dynamic-labs/wallet-book';
|
|
17
17
|
import '@dynamic-labs/utils';
|
|
18
18
|
import '../../../../utils/constants/colors.js';
|
|
@@ -76,7 +76,7 @@ const ActiveMidnightWalletBalance = ({ isLoading = false, }) => {
|
|
|
76
76
|
deps: [walletAddress, primaryWallet, dustPollTick],
|
|
77
77
|
enabled,
|
|
78
78
|
});
|
|
79
|
-
const { dustBalance,
|
|
79
|
+
const { dustBalance, shieldedTokenCount, unshieldedBalance, dustSyncing } = balances !== null && balances !== void 0 ? balances : {};
|
|
80
80
|
useEffect(() => {
|
|
81
81
|
if (!dustSyncing)
|
|
82
82
|
return undefined;
|
|
@@ -90,13 +90,29 @@ const ActiveMidnightWalletBalance = ({ isLoading = false, }) => {
|
|
|
90
90
|
// wallets manage dust themselves). When the embedded wallet has no dust
|
|
91
91
|
// registered yet, we surface a "Register DUST" button instead of the gauge.
|
|
92
92
|
const isWaasWallet = Boolean(primaryWallet && isDynamicWaasConnector(primaryWallet.connector));
|
|
93
|
+
// True once registered. balance/cap can't tell us this on load (cap reads 0
|
|
94
|
+
// on current wallet-client builds), so we track it after a register call to
|
|
95
|
+
// flip from the "Register DUST" prompt to the generating state.
|
|
96
|
+
const [dustRegistered, setDustRegistered] = useState(false);
|
|
97
|
+
// Returns the promise so <Button> shows its built-in spinner while the heavy
|
|
98
|
+
// registerDust call runs.
|
|
93
99
|
const handleRegisterDust = () => __awaiter(void 0, void 0, void 0, function* () {
|
|
94
100
|
const connector = primaryWallet === null || primaryWallet === void 0 ? void 0 : primaryWallet.connector;
|
|
95
101
|
if (!(connector === null || connector === void 0 ? void 0 : connector.registerDust))
|
|
96
102
|
return;
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
103
|
+
try {
|
|
104
|
+
const result = yield connector.registerDust();
|
|
105
|
+
if ((result === null || result === void 0 ? void 0 : result.status) === 'registered' ||
|
|
106
|
+
(result === null || result === void 0 ? void 0 : result.status) === 'already_registered' ||
|
|
107
|
+
(result === null || result === void 0 ? void 0 : result.status) === 'already_has_dust') {
|
|
108
|
+
setDustRegistered(true);
|
|
109
|
+
}
|
|
110
|
+
setDustPollTick((tick) => tick + 1);
|
|
111
|
+
}
|
|
112
|
+
catch (err) {
|
|
113
|
+
// Leave the prompt up so the user can retry rather than failing silently.
|
|
114
|
+
logger.error('Failed to register dust', err);
|
|
115
|
+
}
|
|
100
116
|
});
|
|
101
117
|
// Only show the full skeleton on the very first load; background dust polls
|
|
102
118
|
// keep `balances` populated so the view never flashes back to a skeleton.
|
|
@@ -112,7 +128,10 @@ const ActiveMidnightWalletBalance = ({ isLoading = false, }) => {
|
|
|
112
128
|
cap: truncateToDecimals(dustBalance.cap, 2),
|
|
113
129
|
}
|
|
114
130
|
: undefined;
|
|
115
|
-
|
|
131
|
+
// Unshielded shows the native NIGHT amount; shielded has no NIGHT, so it
|
|
132
|
+
// shows the count of token types held in the pool instead.
|
|
133
|
+
const tokenCount = shieldedTokenCount !== null && shieldedTokenCount !== void 0 ? shieldedTokenCount : 0;
|
|
134
|
+
const shieldedDisplay = `${tokenCount} ${tokenCount === 1 ? 'token' : 'tokens'}`;
|
|
116
135
|
// Dust section has three mutually exclusive states (syncing, generating with
|
|
117
136
|
// a balance, and the WaaS "register dust" prompt). Resolved via a helper to
|
|
118
137
|
// avoid nesting ternaries in the JSX below.
|
|
@@ -120,8 +139,11 @@ const ActiveMidnightWalletBalance = ({ isLoading = false, }) => {
|
|
|
120
139
|
if (dustSyncing) {
|
|
121
140
|
return (jsxs(Fragment, { children: [jsx("div", { className: 'active-midnight-balance__dust', children: jsx("div", { className: 'active-midnight-balance__dust-header', children: jsxs("div", { className: 'active-midnight-balance__dust-title', children: [jsx("svg", { className: 'active-midnight-balance__dust-icon', width: '12', height: '12', viewBox: '0 0 24 24', children: jsx("path", { d: 'M13 2L3 14h9l-1 8 10-12h-9l1-8z' }) }), 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') })] }) }) }), jsx("div", { className: 'active-midnight-balance__divider' })] }));
|
|
122
141
|
}
|
|
123
|
-
|
|
124
|
-
|
|
142
|
+
// Generating gauge: shown with a dust balance, or once registered (balance
|
|
143
|
+
// still 0 during the grace period). Bar renders either way; count only
|
|
144
|
+
// shows with a real balance.
|
|
145
|
+
if (dustBalance || (isWaasWallet && dustRegistered)) {
|
|
146
|
+
return (jsxs(Fragment, { children: [jsxs("div", { className: 'active-midnight-balance__dust', children: [jsxs("div", { className: 'active-midnight-balance__dust-header', children: [jsxs("div", { className: 'active-midnight-balance__dust-title', children: [jsx("svg", { className: 'active-midnight-balance__dust-icon', width: '12', height: '12', viewBox: '0 0 24 24', children: jsx("path", { d: 'M13 2L3 14h9l-1 8 10-12h-9l1-8z' }) }), 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') })] }), dustBalanceDisplay && (jsxs("span", { className: 'active-midnight-balance__dust-count', children: [dustBalanceDisplay.balance, "/", dustBalanceDisplay.cap] }))] }), jsx("div", { className: 'active-midnight-balance__dust-bar', children: DUST_SEGMENT_KEYS.map((segmentKey, i) => (jsx("div", { className: [
|
|
125
147
|
'active-midnight-balance__dust-segment',
|
|
126
148
|
i === 0 && 'active-midnight-balance__dust-segment--first',
|
|
127
149
|
i === DUST_SEGMENTS - 1 &&
|
|
@@ -139,7 +161,9 @@ const ActiveMidnightWalletBalance = ({ isLoading = false, }) => {
|
|
|
139
161
|
};
|
|
140
162
|
return (jsx("div", { className: 'active-midnight-balance', children: jsxs("div", { className: 'active-midnight-balance__card', children: [renderDustSection(), jsx("div", { className: 'active-midnight-balance__tab-bar', children: TABS.map(({ id, copykey }) => (jsx("button", { className: classNames('active-midnight-balance__tab', {
|
|
141
163
|
'active-midnight-balance__tab--active': activeTab === id,
|
|
142
|
-
}), "data-copykey": copykey, onClick: () => setActiveTab(id), children: t(copykey) }, id))) }), jsxs("div", { className: 'active-midnight-balance__pocket', children: [activeTab === 'shielded' ? (jsx(SvgMidnightShielded, { className: 'active-midnight-balance__pocket-icon' })) : (jsx(SvgMidnightUnshielded, { className: 'active-midnight-balance__pocket-icon' })),
|
|
164
|
+
}), "data-copykey": copykey, onClick: () => setActiveTab(id), children: t(copykey) }, id))) }), jsxs("div", { className: 'active-midnight-balance__pocket', children: [activeTab === 'shielded' ? (jsx(SvgMidnightShielded, { className: 'active-midnight-balance__pocket-icon' })) : (jsx(SvgMidnightUnshielded, { className: 'active-midnight-balance__pocket-icon' })), jsx("span", { className: 'active-midnight-balance__amount', children: activeTab === 'shielded'
|
|
165
|
+
? shieldedDisplay
|
|
166
|
+
: `${unshieldedBalance !== null && unshieldedBalance !== void 0 ? unshieldedBalance : '—'} NIGHT` })] })] }) }));
|
|
143
167
|
};
|
|
144
168
|
|
|
145
169
|
export { ActiveMidnightWalletBalance };
|
|
@@ -177,9 +177,10 @@ const EmbeddedWalletExportSection = () => {
|
|
|
177
177
|
}, [setShowAuthFlow, pushView]);
|
|
178
178
|
const handleExportClick = React.useCallback((recoveryPhrase) => _tslib.__awaiter(void 0, void 0, void 0, function* () {
|
|
179
179
|
var _l;
|
|
180
|
+
const targetWalletId = wallet === null || wallet === void 0 ? void 0 : wallet.id;
|
|
180
181
|
logger.logger.info('Starting embedded wallet export process', {
|
|
181
182
|
userId: user === null || user === void 0 ? void 0 : user.userId,
|
|
182
|
-
walletId:
|
|
183
|
+
walletId: targetWalletId,
|
|
183
184
|
walletName: (_l = wallet === null || wallet === void 0 ? void 0 : wallet.connector) === null || _l === void 0 ? void 0 : _l.name,
|
|
184
185
|
});
|
|
185
186
|
const stepUpRequired = yield isStepUpRequired({
|
|
@@ -215,8 +216,10 @@ const EmbeddedWalletExportSection = () => {
|
|
|
215
216
|
});
|
|
216
217
|
}
|
|
217
218
|
}
|
|
218
|
-
return initExportProcess(recoveryPhrase);
|
|
219
|
+
return initExportProcess(recoveryPhrase, false, targetWalletId);
|
|
219
220
|
}), [
|
|
221
|
+
wallet,
|
|
222
|
+
user,
|
|
220
223
|
isStepUpRequired,
|
|
221
224
|
promptStepUpAuth,
|
|
222
225
|
isMfaRequiredForAction,
|
|
@@ -173,9 +173,10 @@ const EmbeddedWalletExportSection = () => {
|
|
|
173
173
|
}, [setShowAuthFlow, pushView]);
|
|
174
174
|
const handleExportClick = useCallback((recoveryPhrase) => __awaiter(void 0, void 0, void 0, function* () {
|
|
175
175
|
var _l;
|
|
176
|
+
const targetWalletId = wallet === null || wallet === void 0 ? void 0 : wallet.id;
|
|
176
177
|
logger.info('Starting embedded wallet export process', {
|
|
177
178
|
userId: user === null || user === void 0 ? void 0 : user.userId,
|
|
178
|
-
walletId:
|
|
179
|
+
walletId: targetWalletId,
|
|
179
180
|
walletName: (_l = wallet === null || wallet === void 0 ? void 0 : wallet.connector) === null || _l === void 0 ? void 0 : _l.name,
|
|
180
181
|
});
|
|
181
182
|
const stepUpRequired = yield isStepUpRequired({
|
|
@@ -211,8 +212,10 @@ const EmbeddedWalletExportSection = () => {
|
|
|
211
212
|
});
|
|
212
213
|
}
|
|
213
214
|
}
|
|
214
|
-
return initExportProcess(recoveryPhrase);
|
|
215
|
+
return initExportProcess(recoveryPhrase, false, targetWalletId);
|
|
215
216
|
}), [
|
|
217
|
+
wallet,
|
|
218
|
+
user,
|
|
216
219
|
isStepUpRequired,
|
|
217
220
|
promptStepUpAuth,
|
|
218
221
|
isMfaRequiredForAction,
|
|
@@ -42,6 +42,7 @@ const ExportAndRecoveryView = () => {
|
|
|
42
42
|
const isV3WaasWallet = Boolean(wallet && ((_b = (_a = wallet === null || wallet === void 0 ? void 0 : wallet.connector) === null || _a === void 0 ? void 0 : _a.key) === null || _b === void 0 ? void 0 : _b.startsWith('dynamicwaas')));
|
|
43
43
|
const handleBackClick = React.useCallback(() => setDynamicWidgetView('account-and-security-settings'), [setDynamicWidgetView]);
|
|
44
44
|
const handlePrivateKeyClick = React.useCallback(() => _tslib.__awaiter(void 0, void 0, void 0, function* () {
|
|
45
|
+
const targetWalletId = wallet === null || wallet === void 0 ? void 0 : wallet.id;
|
|
45
46
|
if (!isSessionKeyCompatible) {
|
|
46
47
|
if (yield shouldInitRecovery()) {
|
|
47
48
|
yield initPasskeyRecoveryProcess(undefined, {
|
|
@@ -49,8 +50,9 @@ const ExportAndRecoveryView = () => {
|
|
|
49
50
|
});
|
|
50
51
|
}
|
|
51
52
|
}
|
|
52
|
-
return initExportProcess();
|
|
53
|
+
return initExportProcess(false, false, targetWalletId);
|
|
53
54
|
}), [
|
|
55
|
+
wallet === null || wallet === void 0 ? void 0 : wallet.id,
|
|
54
56
|
isSessionKeyCompatible,
|
|
55
57
|
shouldInitRecovery,
|
|
56
58
|
initPasskeyRecoveryProcess,
|
|
@@ -38,6 +38,7 @@ const ExportAndRecoveryView = () => {
|
|
|
38
38
|
const isV3WaasWallet = Boolean(wallet && ((_b = (_a = wallet === null || wallet === void 0 ? void 0 : wallet.connector) === null || _a === void 0 ? void 0 : _a.key) === null || _b === void 0 ? void 0 : _b.startsWith('dynamicwaas')));
|
|
39
39
|
const handleBackClick = useCallback(() => setDynamicWidgetView('account-and-security-settings'), [setDynamicWidgetView]);
|
|
40
40
|
const handlePrivateKeyClick = useCallback(() => __awaiter(void 0, void 0, void 0, function* () {
|
|
41
|
+
const targetWalletId = wallet === null || wallet === void 0 ? void 0 : wallet.id;
|
|
41
42
|
if (!isSessionKeyCompatible) {
|
|
42
43
|
if (yield shouldInitRecovery()) {
|
|
43
44
|
yield initPasskeyRecoveryProcess(undefined, {
|
|
@@ -45,8 +46,9 @@ const ExportAndRecoveryView = () => {
|
|
|
45
46
|
});
|
|
46
47
|
}
|
|
47
48
|
}
|
|
48
|
-
return initExportProcess();
|
|
49
|
+
return initExportProcess(false, false, targetWalletId);
|
|
49
50
|
}), [
|
|
51
|
+
wallet === null || wallet === void 0 ? void 0 : wallet.id,
|
|
50
52
|
isSessionKeyCompatible,
|
|
51
53
|
shouldInitRecovery,
|
|
52
54
|
initPasskeyRecoveryProcess,
|