@dynamic-labs/sdk-react-core 4.91.1 → 4.91.3
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 +36 -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/context/ErrorContext/ErrorContext.cjs +48 -28
- package/src/lib/context/ErrorContext/ErrorContext.js +49 -29
- package/src/lib/context/OnrampContext/OnrampContext.cjs +20 -15
- package/src/lib/context/OnrampContext/OnrampContext.js +20 -15
- package/src/lib/data/api/embeddedWallets/embeddedWallets.cjs +15 -14
- package/src/lib/data/api/embeddedWallets/embeddedWallets.js +3 -2
- package/src/lib/data/api/user/user.cjs +1 -1
- package/src/lib/data/api/user/user.js +2 -2
- package/src/lib/data/api/utils.cjs +6 -1
- package/src/lib/data/api/utils.d.ts +1 -0
- package/src/lib/data/api/utils.js +6 -2
- package/src/lib/data/api/wallets/wallets.cjs +2 -2
- package/src/lib/data/api/wallets/wallets.js +3 -3
- package/src/lib/events/auth.d.ts +3 -2
- package/src/lib/shared/types/dynamicEventsCallbacks.d.ts +2 -1
- package/src/lib/utils/functions/getVerifyArgs/getVerifyArgs.cjs +4 -0
- package/src/lib/utils/functions/getVerifyArgs/getVerifyArgs.js +5 -1
- package/src/lib/utils/hooks/authenticationHooks/useConnectAndSign/useConnectAndSign.cjs +1 -1
- package/src/lib/utils/hooks/authenticationHooks/useConnectAndSign/useConnectAndSign.js +2 -2
- 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/useSocialAccounts/useSocialAccounts.cjs +2 -2
- package/src/lib/utils/hooks/useSocialAccounts/useSocialAccounts.js +2 -2
- package/src/lib/utils/hooks/useSyncEmbeddedWalletFlow/useSyncEmbeddedWalletFlow.cjs +1 -1
- package/src/lib/utils/hooks/useSyncEmbeddedWalletFlow/useSyncEmbeddedWalletFlow.js +1 -1
- package/src/lib/views/EmailVerification/EmailVerification.cjs +4 -4
- package/src/lib/views/EmailVerification/EmailVerification.js +4 -4
- package/src/lib/views/EmailWalletOTPVerificationView/EmailWalletOTPVerificationView.cjs +2 -2
- package/src/lib/views/EmailWalletOTPVerificationView/EmailWalletOTPVerificationView.js +2 -2
- 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/views/LoginView/sections/SocialSignInSection/DynamicSocialSignIn/DynamicSocialSignIn.cjs +2 -2
- package/src/lib/views/LoginView/sections/SocialSignInSection/DynamicSocialSignIn/DynamicSocialSignIn.js +2 -2
- package/src/lib/views/SmsVerification/useSmsVerification/useSmsVerification.cjs +2 -2
- package/src/lib/views/SmsVerification/useSmsVerification/useSmsVerification.js +2 -2
- 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,40 @@
|
|
|
1
1
|
|
|
2
|
+
### [4.91.3](https://github.com/dynamic-labs/dynamic-auth/compare/v4.91.2...v4.91.3) (2026-06-30)
|
|
3
|
+
|
|
4
|
+
|
|
5
|
+
### Bug Fixes
|
|
6
|
+
|
|
7
|
+
* **bitcoin:** detect late-registering wallet-standard wallets (DYNT-1210) ([#11747](https://github.com/dynamic-labs/dynamic-auth/issues/11747)) ([17809f6](https://github.com/dynamic-labs/dynamic-auth/commit/17809f6e811fe101367cc31a2d899a8d0b0d107e))
|
|
8
|
+
* fetch onramp providers lazily instead of eagerly on mount ([#11767](https://github.com/dynamic-labs/dynamic-auth/issues/11767)) ([3ee6708](https://github.com/dynamic-labs/dynamic-auth/commit/3ee67087142ae1942f865e0ab37b7108700b3327))
|
|
9
|
+
* **iframe-setup:** sync parent URL to iframe on pushState/replaceState ([#11751](https://github.com/dynamic-labs/dynamic-auth/issues/11751)) ([c8be3af](https://github.com/dynamic-labs/dynamic-auth/commit/c8be3afc301f77b349f23398bed940ce40f93b73))
|
|
10
|
+
* **nonce:** fetch nonce on demand when missing before wallet verification ([#11753](https://github.com/dynamic-labs/dynamic-auth/issues/11753)) ([4f01a21](https://github.com/dynamic-labs/dynamic-auth/commit/4f01a21b6081c852f32868c8a5e04d70aaf280a2)), closes [#1](https://github.com/dynamic-labs/dynamic-auth/issues/1)
|
|
11
|
+
* **react-native-extension:** arm loading timer before setUrl to cover pre-onLoadStart gap ([#11764](https://github.com/dynamic-labs/dynamic-auth/issues/11764)) ([31f2015](https://github.com/dynamic-labs/dynamic-auth/commit/31f20151a4b59279f9c133b723e50de771b06436))
|
|
12
|
+
* **webview-controller:** unwrap ZeroDev smart wallet for native gasless ([#11758](https://github.com/dynamic-labs/dynamic-auth/issues/11758)) ([989714e](https://github.com/dynamic-labs/dynamic-auth/commit/989714e414556868c8e0c54401aac1ed7354331b))
|
|
13
|
+
|
|
14
|
+
### [4.91.2](https://github.com/dynamic-labs/dynamic-auth/compare/v4.91.1...v4.91.2) (2026-06-26)
|
|
15
|
+
|
|
16
|
+
|
|
17
|
+
### ⚠ BREAKING CHANGES
|
|
18
|
+
|
|
19
|
+
* **waas:** require expectedAddresses on migrateFromFireblocks (#11730)
|
|
20
|
+
|
|
21
|
+
### Features
|
|
22
|
+
|
|
23
|
+
* **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))
|
|
24
|
+
* **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))
|
|
25
|
+
* **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))
|
|
26
|
+
|
|
27
|
+
|
|
28
|
+
### Bug Fixes
|
|
29
|
+
|
|
30
|
+
* 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))
|
|
31
|
+
* 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))
|
|
32
|
+
* 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))
|
|
33
|
+
* **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))
|
|
34
|
+
|
|
35
|
+
|
|
36
|
+
* **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))
|
|
37
|
+
|
|
2
38
|
### [4.91.1](https://github.com/dynamic-labs/dynamic-auth/compare/v4.91.0...v4.91.1) (2026-06-24)
|
|
3
39
|
|
|
4
40
|
|
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.3";
|
|
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.3";
|
|
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.3",
|
|
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.3",
|
|
21
|
+
"@dynamic-labs/iconic": "4.91.3",
|
|
22
|
+
"@dynamic-labs/locale": "4.91.3",
|
|
23
|
+
"@dynamic-labs/logger": "4.91.3",
|
|
24
|
+
"@dynamic-labs/multi-wallet": "4.91.3",
|
|
25
|
+
"@dynamic-labs/rpc-providers": "4.91.3",
|
|
26
|
+
"@dynamic-labs/store": "4.91.3",
|
|
27
|
+
"@dynamic-labs/types": "4.91.3",
|
|
28
|
+
"@dynamic-labs/utils": "4.91.3",
|
|
29
|
+
"@dynamic-labs/wallet-book": "4.91.3",
|
|
30
|
+
"@dynamic-labs/wallet-connector-core": "4.91.3",
|
|
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',
|
|
@@ -10,30 +10,50 @@ var logger = require('../../shared/logger.cjs');
|
|
|
10
10
|
var createProviderHook = require('../../shared/utils/functions/createProviderHook/createProviderHook.cjs');
|
|
11
11
|
|
|
12
12
|
const FALLBACK_ERROR_LOG_EVENT = 'ui.fallback_error_shown';
|
|
13
|
-
|
|
14
|
-
const
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
13
|
+
const DEFAULT_ERROR_MESSAGE = 'Something went wrong. Please try again.';
|
|
14
|
+
const MESSAGE_SIGNATURE_DENIED = 'Message signature denied.';
|
|
15
|
+
const UNLOCK_WALLET_MESSAGE = 'Please unlock your wallet extension and try again.';
|
|
16
|
+
const INTERNAL_ERROR_MESSAGE = 'There was an internal error. Please try again.';
|
|
17
|
+
let _errorMessageMap;
|
|
18
|
+
const getErrorMessageMap = () => {
|
|
19
|
+
if (!_errorMessageMap) {
|
|
20
|
+
_errorMessageMap = {
|
|
21
|
+
'-1': DEFAULT_ERROR_MESSAGE,
|
|
22
|
+
'-32000': MESSAGE_SIGNATURE_DENIED,
|
|
23
|
+
'-32002': UNLOCK_WALLET_MESSAGE,
|
|
24
|
+
'-32003': MESSAGE_SIGNATURE_DENIED,
|
|
25
|
+
'-32602': 'Invalid parameters. Please try again.',
|
|
26
|
+
'-32603': INTERNAL_ERROR_MESSAGE,
|
|
27
|
+
0: MESSAGE_SIGNATURE_DENIED,
|
|
28
|
+
4001: MESSAGE_SIGNATURE_DENIED,
|
|
29
|
+
4100: UNLOCK_WALLET_MESSAGE,
|
|
30
|
+
4900: INTERNAL_ERROR_MESSAGE,
|
|
31
|
+
5001: MESSAGE_SIGNATURE_DENIED,
|
|
32
|
+
5002: MESSAGE_SIGNATURE_DENIED,
|
|
33
|
+
account_already_linked_to_different_profile: 'This social account is already linked to a different profile.',
|
|
34
|
+
[utils.SdkErrorCode.CONNECTION_REJECTED]: 'Connection rejected. Please try again.',
|
|
35
|
+
general_error: DEFAULT_ERROR_MESSAGE,
|
|
36
|
+
[utils.SdkErrorCode.INVALID_EMAIL_VERIFICATION]: 'The verification link is no longer valid. Please start again.',
|
|
37
|
+
metamask_timeout: 'Whoops. Looks like something went wrong. Please try again.',
|
|
38
|
+
[utils.SdkErrorCode.MISSING_NONCE]: DEFAULT_ERROR_MESSAGE,
|
|
39
|
+
'missing-public-address': 'Connection cancelled. Please try again',
|
|
40
|
+
no_webauthn_support_error: 'Your browser does not support passkeys. Please try a different browser.',
|
|
41
|
+
oauth_error: 'Authentication failed. Please try again.',
|
|
42
|
+
oauth_window_blocked: 'To connect to your social account, enable popups in your browser and then try again.',
|
|
43
|
+
oauth_window_timeout: 'Session time out. Please try again.',
|
|
44
|
+
provider_not_enabled: 'This sign-in provider is not enabled. Please contact the app administrator.',
|
|
45
|
+
signin_error: 'Sign-in failed. Please try again.',
|
|
46
|
+
social_linking_not_enabled: 'Social account linking is not enabled for this application.',
|
|
47
|
+
[utils.SdkErrorCode.TOO_MANY_EMAIL_VERIFICATION_ATTEMPTS]: 'Too many email verification attempts, please try again later',
|
|
48
|
+
[utils.SdkErrorCode.UNKNOWN_ERROR]: 'An unexpected error occurred. Please try again.',
|
|
49
|
+
[utils.SdkErrorCode.USER_CANCELLED]: '',
|
|
50
|
+
[utils.SdkErrorCode.USER_CANCELLED_OAUTH]: '',
|
|
51
|
+
verification_error: 'Verification failed. Please try again.',
|
|
52
|
+
[utils.SdkErrorCode.WALLET_NOT_DEPLOYED]: 'Your smart wallet has not been deployed.',
|
|
53
|
+
wrong_email_verification_token: 'The code you entered is incorrect. Please try again.',
|
|
54
|
+
};
|
|
55
|
+
}
|
|
56
|
+
return _errorMessageMap;
|
|
37
57
|
};
|
|
38
58
|
const ErrorContext = React.createContext(undefined);
|
|
39
59
|
const ErrorContextProvider = ({ children }) => {
|
|
@@ -54,12 +74,12 @@ const ErrorContextProvider = ({ children }) => {
|
|
|
54
74
|
source: 'setDefaultError',
|
|
55
75
|
time: 0,
|
|
56
76
|
});
|
|
57
|
-
setError(
|
|
77
|
+
setError(DEFAULT_ERROR_MESSAGE, utils.ErrorCode.DEFAULT);
|
|
58
78
|
}, [setError]);
|
|
59
79
|
/** @deprecated Prefer setError with a translation key instead */
|
|
60
80
|
const setErrorMessage = React.useCallback((status, error, source) => {
|
|
61
|
-
const mappedMessage =
|
|
62
|
-
if (
|
|
81
|
+
const mappedMessage = getErrorMessageMap()[status];
|
|
82
|
+
if (mappedMessage === undefined) {
|
|
63
83
|
logger.logger.instrument(FALLBACK_ERROR_LOG_EVENT, {
|
|
64
84
|
error: error instanceof Error ? error.message : undefined,
|
|
65
85
|
errorCode: status,
|
|
@@ -68,7 +88,7 @@ const ErrorContextProvider = ({ children }) => {
|
|
|
68
88
|
time: 0,
|
|
69
89
|
});
|
|
70
90
|
}
|
|
71
|
-
setError(mappedMessage !== null && mappedMessage !== void 0 ? mappedMessage :
|
|
91
|
+
setError(mappedMessage !== null && mappedMessage !== void 0 ? mappedMessage : DEFAULT_ERROR_MESSAGE);
|
|
72
92
|
}, [setError]);
|
|
73
93
|
const clearError = React.useCallback(() => {
|
|
74
94
|
_setError(undefined);
|