@dynamic-labs/sdk-react-core 4.92.3 → 4.93.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (42) hide show
  1. package/CHANGELOG.md +24 -0
  2. package/package.cjs +5 -5
  3. package/package.js +5 -5
  4. package/package.json +16 -16
  5. package/src/lib/components/SendBalanceForm/SendBalanceForm.cjs +28 -4
  6. package/src/lib/components/SendBalanceForm/SendBalanceForm.js +28 -4
  7. package/src/lib/context/CaptchaContext/CaptchaContext.cjs +10 -2
  8. package/src/lib/context/CaptchaContext/CaptchaContext.d.ts +2 -1
  9. package/src/lib/context/CaptchaContext/CaptchaContext.js +10 -2
  10. package/src/lib/context/DynamicContext/types/DynamicContextProps.d.ts +1 -1
  11. package/src/lib/store/state/dynamicContextProps/defaultDynamicSettings.cjs +1 -1
  12. package/src/lib/store/state/dynamicContextProps/defaultDynamicSettings.d.ts +1 -1
  13. package/src/lib/store/state/dynamicContextProps/defaultDynamicSettings.js +1 -1
  14. package/src/lib/utils/functions/getEmbeddedBitcoinActiveAddress/getEmbeddedBitcoinActiveAddress.cjs +24 -0
  15. package/src/lib/utils/functions/getEmbeddedBitcoinActiveAddress/getEmbeddedBitcoinActiveAddress.d.ts +11 -0
  16. package/src/lib/utils/functions/getEmbeddedBitcoinActiveAddress/getEmbeddedBitcoinActiveAddress.js +20 -0
  17. package/src/lib/utils/functions/getEmbeddedBitcoinActiveAddress/index.d.ts +1 -0
  18. package/src/lib/utils/functions/getTransactionLink/blockExplorerPatterns.cjs +12 -0
  19. package/src/lib/utils/functions/getTransactionLink/blockExplorerPatterns.js +12 -0
  20. package/src/lib/utils/functions/getWalletAdditionalAddressByType/getWalletAdditionalAddressByType.cjs +16 -3
  21. package/src/lib/utils/functions/getWalletAdditionalAddressByType/getWalletAdditionalAddressByType.d.ts +8 -1
  22. package/src/lib/utils/functions/getWalletAdditionalAddressByType/getWalletAdditionalAddressByType.js +16 -3
  23. package/src/lib/utils/functions/index.d.ts +1 -0
  24. package/src/lib/utils/hooks/useDynamicWaas/useDynamicWaas.cjs +50 -2
  25. package/src/lib/utils/hooks/useDynamicWaas/useDynamicWaas.js +50 -2
  26. package/src/lib/utils/hooks/useSocialAuth/useSocialAuth.cjs +12 -0
  27. package/src/lib/utils/hooks/useSocialAuth/useSocialAuth.js +12 -0
  28. package/src/lib/utils/hooks/useTokenBalances/useTokenBalances.cjs +9 -5
  29. package/src/lib/utils/hooks/useTokenBalances/useTokenBalances.js +9 -5
  30. package/src/lib/utils/hooks/useWalletItemActions/useHandleWalletItem/useHandleWalletItem.cjs +6 -1
  31. package/src/lib/utils/hooks/useWalletItemActions/useHandleWalletItem/useHandleWalletItem.js +6 -1
  32. package/src/lib/widgets/DynamicWidget/components/ActiveMidnightWalletBalance/ActiveMidnightWalletBalance.cjs +40 -8
  33. package/src/lib/widgets/DynamicWidget/components/ActiveMidnightWalletBalance/ActiveMidnightWalletBalance.js +41 -9
  34. package/src/lib/widgets/DynamicWidget/components/ActiveWalletInformation/ActiveMidnightWalletAddresses/ActiveMidnightWalletAddresses.cjs +20 -6
  35. package/src/lib/widgets/DynamicWidget/components/ActiveWalletInformation/ActiveMidnightWalletAddresses/ActiveMidnightWalletAddresses.d.ts +7 -1
  36. package/src/lib/widgets/DynamicWidget/components/ActiveWalletInformation/ActiveMidnightWalletAddresses/ActiveMidnightWalletAddresses.js +20 -6
  37. package/src/lib/widgets/DynamicWidget/components/ActiveWalletInformation/ActiveWalletAddress/ActiveWalletAddress.cjs +5 -2
  38. package/src/lib/widgets/DynamicWidget/components/ActiveWalletInformation/ActiveWalletAddress/ActiveWalletAddress.js +5 -2
  39. package/src/lib/widgets/DynamicWidget/components/ActiveWalletInformation/ActiveWalletInformation.cjs +17 -9
  40. package/src/lib/widgets/DynamicWidget/components/ActiveWalletInformation/ActiveWalletInformation.js +18 -10
  41. package/src/lib/widgets/DynamicWidget/views/DepositView/DepositView.cjs +21 -6
  42. package/src/lib/widgets/DynamicWidget/views/DepositView/DepositView.js +22 -7
package/CHANGELOG.md CHANGED
@@ -1,4 +1,28 @@
1
1
 
2
+ ## [4.93.0](https://github.com/dynamic-labs/dynamic-auth/compare/v4.92.4...v4.93.0) (2026-07-20)
3
+
4
+
5
+ ### Features
6
+
7
+ * **react-native:** add retry API and granular loading state ([#11938](https://github.com/dynamic-labs/dynamic-auth/issues/11938)) ([#11999](https://github.com/dynamic-labs/dynamic-auth/issues/11999)) ([8f4e6aa](https://github.com/dynamic-labs/dynamic-auth/commit/8f4e6aa2466da5e6b4d8ee802c814c51e79cf27c))
8
+
9
+ ### [4.92.4](https://github.com/dynamic-labs/dynamic-auth/compare/v4.92.3...v4.92.4) (2026-07-16)
10
+
11
+
12
+ ### Features
13
+
14
+ * **bitcoin:** per-network address switching and dust-limit send validation [v4] ([#11970](https://github.com/dynamic-labs/dynamic-auth/issues/11970)) ([76a4a9a](https://github.com/dynamic-labs/dynamic-auth/commit/76a4a9a5025d78798ebd1beffe6c0af59d2d029a)), closes [#11896](https://github.com/dynamic-labs/dynamic-auth/issues/11896) [#11800](https://github.com/dynamic-labs/dynamic-auth/issues/11800)
15
+ * **midnight:** per-network addresses in deposit and wallet info views [v4] ([#11949](https://github.com/dynamic-labs/dynamic-auth/issues/11949)) ([978446a](https://github.com/dynamic-labs/dynamic-auth/commit/978446aca8546eb038ba9ed3be0503d10594ee15))
16
+ * **midnight:** resolve wallet address per selected network [v4] ([#11948](https://github.com/dynamic-labs/dynamic-auth/issues/11948)) ([d6f858c](https://github.com/dynamic-labs/dynamic-auth/commit/d6f858c5e35defda7ed73cf97b3fdbe5ed9d131d))
17
+ * set useMetamaskSdk to true by default ([#11926](https://github.com/dynamic-labs/dynamic-auth/issues/11926)) ([75b5a4a](https://github.com/dynamic-labs/dynamic-auth/commit/75b5a4a0fe8b1a375afce145c0b8bdc3ce761117))
18
+
19
+
20
+ ### Bug Fixes
21
+
22
+ * **midnight:** align per-network code with the final main iteration [v4] ([#11971](https://github.com/dynamic-labs/dynamic-auth/issues/11971)) ([3ef3ba8](https://github.com/dynamic-labs/dynamic-auth/commit/3ef3ba8c090dfd9e4286b4e51bf350ea5e6feac7))
23
+ * settle social sign-in when captcha is backed out or oauth popup never responds (v4) ([#11956](https://github.com/dynamic-labs/dynamic-auth/issues/11956)) ([ad49477](https://github.com/dynamic-labs/dynamic-auth/commit/ad49477f2acf61a154bb79cbe26b24f803cdb0e2))
24
+ * validate that private key is not empty before upgrading to WaaS ([#11952](https://github.com/dynamic-labs/dynamic-auth/issues/11952)) ([21dfb83](https://github.com/dynamic-labs/dynamic-auth/commit/21dfb83cb29e42b335bc94a0cdd2062cf14a262a))
25
+
2
26
  ### [4.92.3](https://github.com/dynamic-labs/dynamic-auth/compare/v4.92.2...v4.92.3) (2026-07-10)
3
27
 
4
28
 
package/package.cjs CHANGED
@@ -3,12 +3,12 @@
3
3
 
4
4
  Object.defineProperty(exports, '__esModule', { value: true });
5
5
 
6
- var version = "4.92.3";
6
+ var version = "4.93.0";
7
7
  var dependencies = {
8
- "@dynamic-labs/sdk-api-core": "0.0.1067",
9
- "@dynamic-labs-sdk/client": "1.18.0",
10
- "@dynamic-labs-wallet/browser-wallet-client": "1.0.48",
11
- "@dynamic-labs-wallet/forward-mpc-client": "0.12.0",
8
+ "@dynamic-labs/sdk-api-core": "0.0.1082",
9
+ "@dynamic-labs-sdk/client": "1.20.0",
10
+ "@dynamic-labs-wallet/browser-wallet-client": "1.0.70",
11
+ "@dynamic-labs-wallet/forward-mpc-client": "1.0.1",
12
12
  "@hcaptcha/react-hcaptcha": "1.4.4",
13
13
  "@marsidev/react-turnstile": "1.5.2",
14
14
  "@thumbmarkjs/thumbmarkjs": "0.16.0",
package/package.js CHANGED
@@ -1,10 +1,10 @@
1
1
  'use client'
2
- var version = "4.92.3";
2
+ var version = "4.93.0";
3
3
  var dependencies = {
4
- "@dynamic-labs/sdk-api-core": "0.0.1067",
5
- "@dynamic-labs-sdk/client": "1.18.0",
6
- "@dynamic-labs-wallet/browser-wallet-client": "1.0.48",
7
- "@dynamic-labs-wallet/forward-mpc-client": "0.12.0",
4
+ "@dynamic-labs/sdk-api-core": "0.0.1082",
5
+ "@dynamic-labs-sdk/client": "1.20.0",
6
+ "@dynamic-labs-wallet/browser-wallet-client": "1.0.70",
7
+ "@dynamic-labs-wallet/forward-mpc-client": "1.0.1",
8
8
  "@hcaptcha/react-hcaptcha": "1.4.4",
9
9
  "@marsidev/react-turnstile": "1.5.2",
10
10
  "@thumbmarkjs/thumbmarkjs": "0.16.0",
package/package.json CHANGED
@@ -1,11 +1,11 @@
1
1
  {
2
2
  "name": "@dynamic-labs/sdk-react-core",
3
- "version": "4.92.3",
3
+ "version": "4.93.0",
4
4
  "dependencies": {
5
- "@dynamic-labs/sdk-api-core": "0.0.1067",
6
- "@dynamic-labs-sdk/client": "1.18.0",
7
- "@dynamic-labs-wallet/browser-wallet-client": "1.0.48",
8
- "@dynamic-labs-wallet/forward-mpc-client": "0.12.0",
5
+ "@dynamic-labs/sdk-api-core": "0.0.1082",
6
+ "@dynamic-labs-sdk/client": "1.20.0",
7
+ "@dynamic-labs-wallet/browser-wallet-client": "1.0.70",
8
+ "@dynamic-labs-wallet/forward-mpc-client": "1.0.1",
9
9
  "@hcaptcha/react-hcaptcha": "1.4.4",
10
10
  "@marsidev/react-turnstile": "1.5.2",
11
11
  "@thumbmarkjs/thumbmarkjs": "0.16.0",
@@ -18,17 +18,17 @@
18
18
  "react-i18next": "13.5.0",
19
19
  "react-international-phone": "4.5.0",
20
20
  "yup": "0.32.11",
21
- "@dynamic-labs/assert-package-version": "4.92.3",
22
- "@dynamic-labs/iconic": "4.92.3",
23
- "@dynamic-labs/locale": "4.92.3",
24
- "@dynamic-labs/logger": "4.92.3",
25
- "@dynamic-labs/multi-wallet": "4.92.3",
26
- "@dynamic-labs/rpc-providers": "4.92.3",
27
- "@dynamic-labs/store": "4.92.3",
28
- "@dynamic-labs/types": "4.92.3",
29
- "@dynamic-labs/utils": "4.92.3",
30
- "@dynamic-labs/wallet-book": "4.92.3",
31
- "@dynamic-labs/wallet-connector-core": "4.92.3",
21
+ "@dynamic-labs/assert-package-version": "4.93.0",
22
+ "@dynamic-labs/iconic": "4.93.0",
23
+ "@dynamic-labs/locale": "4.93.0",
24
+ "@dynamic-labs/logger": "4.93.0",
25
+ "@dynamic-labs/multi-wallet": "4.93.0",
26
+ "@dynamic-labs/rpc-providers": "4.93.0",
27
+ "@dynamic-labs/store": "4.93.0",
28
+ "@dynamic-labs/types": "4.93.0",
29
+ "@dynamic-labs/utils": "4.93.0",
30
+ "@dynamic-labs/wallet-book": "4.93.0",
31
+ "@dynamic-labs/wallet-connector-core": "4.93.0",
32
32
  "eventemitter3": "5.0.1"
33
33
  },
34
34
  "devDependencies": {
@@ -51,7 +51,7 @@ const sendBalanceFormInitialValues = {
51
51
  amount: '',
52
52
  recipient: '',
53
53
  };
54
- const getDisplayErrorMessage = (errors, t, field, decimals) => {
54
+ const getDisplayErrorMessage = (errors, t, field, decimals, minAmountDisplay) => {
55
55
  var _a;
56
56
  const mapFieldAndErrorToMessage = {
57
57
  amount: {
@@ -60,6 +60,9 @@ const getDisplayErrorMessage = (errors, t, field, decimals) => {
60
60
  nonZero: t('dyn_send_transaction.validation.amount.non_zero'),
61
61
  overBalance: t('dyn_send_transaction.validation.amount.over_balance'),
62
62
  required: t('dyn_send_transaction.validation.amount.required'),
63
+ underMinimum: t('dyn_send_transaction.validation.amount.under_minimum', {
64
+ minAmount: minAmountDisplay,
65
+ }),
63
66
  },
64
67
  recipient: {
65
68
  invalidFormat: t('dyn_send_transaction.validation.recipient.invalid_format'),
@@ -83,7 +86,7 @@ const getDisplayErrorMessage = (errors, t, field, decimals) => {
83
86
  return '';
84
87
  };
85
88
  const SendBalanceForm = ({ initialValues, onSubmit, decimals = 18, validateAddress = () => true, validateAmount = () => true, currentToken, transaction, tokenBalances, setCurrentToken, isLoading, supportsFeeTokenSelection = false, feeTokenOptions, currentFeeToken, setCurrentFeeToken, fallbackTokenIcon, }) => {
86
- var _a;
89
+ var _a, _b;
87
90
  const { t } = reactI18next.useTranslation();
88
91
  const { showFiat } = useInternalDynamicContext.useInternalDynamicContext();
89
92
  const floatingValueRef = React.useRef(null);
@@ -183,6 +186,24 @@ const SendBalanceForm = ({ initialValues, onSubmit, decimals = 18, validateAddre
183
186
  return true;
184
187
  return /^0*(?:\.0+)?$/.test(value) === false;
185
188
  },
189
+ })
190
+ // Chains with a minimum sendable value (e.g. Bitcoin's dust limit)
191
+ // would otherwise accept the amount here and fail when the
192
+ // transaction is built, with no feedback in the UI.
193
+ .test({
194
+ message: 'underMinimum',
195
+ test: (value) => {
196
+ if (!value || !(transaction === null || transaction === void 0 ? void 0 : transaction.minAmount))
197
+ return true;
198
+ if (currentToken && currentToken.isNative !== true)
199
+ return true;
200
+ try {
201
+ return transaction.parse(value) >= transaction.minAmount;
202
+ }
203
+ catch (_a) {
204
+ return true;
205
+ }
206
+ },
186
207
  })
187
208
  .test({
188
209
  message: 'overBalance',
@@ -195,7 +216,10 @@ const SendBalanceForm = ({ initialValues, onSubmit, decimals = 18, validateAddre
195
216
  test: (value) => validateAddress(value),
196
217
  }),
197
218
  });
198
- }, [decimals, validateAddress, validateAmount]);
219
+ }, [decimals, validateAddress, validateAmount, transaction, currentToken]);
220
+ const minAmountDisplay = (transaction === null || transaction === void 0 ? void 0 : transaction.minAmount)
221
+ ? `${transaction.format(transaction.minAmount)} ${(_b = currentToken === null || currentToken === void 0 ? void 0 : currentToken.symbol) !== null && _b !== void 0 ? _b : ''}`.trim()
222
+ : undefined;
199
223
  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, }) => {
200
224
  var _a;
201
225
  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) => {
@@ -223,7 +247,7 @@ const SendBalanceForm = ({ initialValues, onSubmit, decimals = 18, validateAddre
223
247
  (_a = transaction === null || transaction === void 0 ? void 0 : transaction.setPendingAmount) === null || _a === void 0 ? void 0 : _a.call(transaction, (_b = e.target.value) !== null && _b !== void 0 ? _b : '');
224
248
  refreshMergeAction();
225
249
  }, placeholder: t('dyn_send_transaction.data.amount.placeholder'), as: Input.Input, error: errors['amount'], copykey: 'dyn_send_transaction.data.amount.label', message: touched['amount'] &&
226
- getDisplayErrorMessage(errors, t, 'amount', decimals), style: {
250
+ getDisplayErrorMessage(errors, t, 'amount', decimals, minAmountDisplay), style: {
227
251
  paddingLeft: `${leftSymbolPadding}px`,
228
252
  } }), 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
253
  symbol: pickerToken === null || pickerToken === void 0 ? void 0 : pickerToken.symbol,
@@ -47,7 +47,7 @@ const sendBalanceFormInitialValues = {
47
47
  amount: '',
48
48
  recipient: '',
49
49
  };
50
- const getDisplayErrorMessage = (errors, t, field, decimals) => {
50
+ const getDisplayErrorMessage = (errors, t, field, decimals, minAmountDisplay) => {
51
51
  var _a;
52
52
  const mapFieldAndErrorToMessage = {
53
53
  amount: {
@@ -56,6 +56,9 @@ const getDisplayErrorMessage = (errors, t, field, decimals) => {
56
56
  nonZero: t('dyn_send_transaction.validation.amount.non_zero'),
57
57
  overBalance: t('dyn_send_transaction.validation.amount.over_balance'),
58
58
  required: t('dyn_send_transaction.validation.amount.required'),
59
+ underMinimum: t('dyn_send_transaction.validation.amount.under_minimum', {
60
+ minAmount: minAmountDisplay,
61
+ }),
59
62
  },
60
63
  recipient: {
61
64
  invalidFormat: t('dyn_send_transaction.validation.recipient.invalid_format'),
@@ -79,7 +82,7 @@ const getDisplayErrorMessage = (errors, t, field, decimals) => {
79
82
  return '';
80
83
  };
81
84
  const SendBalanceForm = ({ initialValues, onSubmit, decimals = 18, validateAddress = () => true, validateAmount = () => true, currentToken, transaction, tokenBalances, setCurrentToken, isLoading, supportsFeeTokenSelection = false, feeTokenOptions, currentFeeToken, setCurrentFeeToken, fallbackTokenIcon, }) => {
82
- var _a;
85
+ var _a, _b;
83
86
  const { t } = useTranslation();
84
87
  const { showFiat } = useInternalDynamicContext();
85
88
  const floatingValueRef = useRef(null);
@@ -179,6 +182,24 @@ const SendBalanceForm = ({ initialValues, onSubmit, decimals = 18, validateAddre
179
182
  return true;
180
183
  return /^0*(?:\.0+)?$/.test(value) === false;
181
184
  },
185
+ })
186
+ // Chains with a minimum sendable value (e.g. Bitcoin's dust limit)
187
+ // would otherwise accept the amount here and fail when the
188
+ // transaction is built, with no feedback in the UI.
189
+ .test({
190
+ message: 'underMinimum',
191
+ test: (value) => {
192
+ if (!value || !(transaction === null || transaction === void 0 ? void 0 : transaction.minAmount))
193
+ return true;
194
+ if (currentToken && currentToken.isNative !== true)
195
+ return true;
196
+ try {
197
+ return transaction.parse(value) >= transaction.minAmount;
198
+ }
199
+ catch (_a) {
200
+ return true;
201
+ }
202
+ },
182
203
  })
183
204
  .test({
184
205
  message: 'overBalance',
@@ -191,7 +212,10 @@ const SendBalanceForm = ({ initialValues, onSubmit, decimals = 18, validateAddre
191
212
  test: (value) => validateAddress(value),
192
213
  }),
193
214
  });
194
- }, [decimals, validateAddress, validateAmount]);
215
+ }, [decimals, validateAddress, validateAmount, transaction, currentToken]);
216
+ const minAmountDisplay = (transaction === null || transaction === void 0 ? void 0 : transaction.minAmount)
217
+ ? `${transaction.format(transaction.minAmount)} ${(_b = currentToken === null || currentToken === void 0 ? void 0 : currentToken.symbol) !== null && _b !== void 0 ? _b : ''}`.trim()
218
+ : undefined;
195
219
  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, }) => {
196
220
  var _a;
197
221
  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) => {
@@ -219,7 +243,7 @@ const SendBalanceForm = ({ initialValues, onSubmit, decimals = 18, validateAddre
219
243
  (_a = transaction === null || transaction === void 0 ? void 0 : transaction.setPendingAmount) === null || _a === void 0 ? void 0 : _a.call(transaction, (_b = e.target.value) !== null && _b !== void 0 ? _b : '');
220
244
  refreshMergeAction();
221
245
  }, placeholder: t('dyn_send_transaction.data.amount.placeholder'), as: Input, error: errors['amount'], copykey: 'dyn_send_transaction.data.amount.label', message: touched['amount'] &&
222
- getDisplayErrorMessage(errors, t, 'amount', decimals), style: {
246
+ getDisplayErrorMessage(errors, t, 'amount', decimals, minAmountDisplay), style: {
223
247
  paddingLeft: `${leftSymbolPadding}px`,
224
248
  } }), 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
249
  symbol: pickerToken === null || pickerToken === void 0 ? void 0 : pickerToken.symbol,
@@ -34,9 +34,17 @@ const CaptchaContextProvider = ({ children, }) => {
34
34
  const { setShowAuthFlow } = useInternalDynamicContext.useInternalDynamicContext();
35
35
  const [captchaToken, setCaptchaToken, removeCaptchaToken] = useLocalStorage.useLocalStorage(localStorage.CAPTCHA_TOKEN, undefined);
36
36
  const [captchaAuthState, setCaptchaAuthState] = React.useState();
37
- const engageCaptcha = React.useCallback(({ authMethod, onCaptchaSuccess, }) => {
37
+ const engageCaptcha = React.useCallback(({ authMethod, onCaptchaSuccess, onCaptchaCancel, }) => {
38
38
  setCaptchaAuthState({ authMethod, onCaptchaSuccess });
39
- pushView('captcha');
39
+ pushView('captcha', undefined, {
40
+ // Navigating back abandons the pending onCaptchaSuccess continuation,
41
+ // so let the caller settle its flow (eg dismiss a pending view)
42
+ // instead of leaving it waiting for a captcha token forever
43
+ onBackClick: () => {
44
+ setCaptchaAuthState(undefined);
45
+ onCaptchaCancel === null || onCaptchaCancel === void 0 ? void 0 : onCaptchaCancel();
46
+ },
47
+ });
40
48
  setShowAuthFlow(true);
41
49
  }, [pushView, setCaptchaAuthState, setShowAuthFlow]);
42
50
  const getCaptchaToken = React.useCallback(() => {
@@ -4,9 +4,10 @@ type CaptchaContextProps = {
4
4
  setCaptchaToken: Dispatch<SetStateAction<string | undefined>>;
5
5
  captchaAuthState: CaptchaAuthenticationState | undefined;
6
6
  setCaptchaAuthState: Dispatch<SetStateAction<CaptchaAuthenticationState | undefined>>;
7
- engageCaptcha: ({ authMethod, onCaptchaSuccess, }: {
7
+ engageCaptcha: ({ authMethod, onCaptchaSuccess, onCaptchaCancel, }: {
8
8
  authMethod: AuthMethod;
9
9
  onCaptchaSuccess: (captchaToken: string) => Promise<void>;
10
+ onCaptchaCancel?: () => void;
10
11
  }) => void;
11
12
  };
12
13
  export type AuthMethod = 'wallet' | 'email' | 'social' | 'phone';
@@ -30,9 +30,17 @@ const CaptchaContextProvider = ({ children, }) => {
30
30
  const { setShowAuthFlow } = useInternalDynamicContext();
31
31
  const [captchaToken, setCaptchaToken, removeCaptchaToken] = useLocalStorage(CAPTCHA_TOKEN, undefined);
32
32
  const [captchaAuthState, setCaptchaAuthState] = useState();
33
- const engageCaptcha = useCallback(({ authMethod, onCaptchaSuccess, }) => {
33
+ const engageCaptcha = useCallback(({ authMethod, onCaptchaSuccess, onCaptchaCancel, }) => {
34
34
  setCaptchaAuthState({ authMethod, onCaptchaSuccess });
35
- pushView('captcha');
35
+ pushView('captcha', undefined, {
36
+ // Navigating back abandons the pending onCaptchaSuccess continuation,
37
+ // so let the caller settle its flow (eg dismiss a pending view)
38
+ // instead of leaving it waiting for a captcha token forever
39
+ onBackClick: () => {
40
+ setCaptchaAuthState(undefined);
41
+ onCaptchaCancel === null || onCaptchaCancel === void 0 ? void 0 : onCaptchaCancel();
42
+ },
43
+ });
36
44
  setShowAuthFlow(true);
37
45
  }, [pushView, setCaptchaAuthState, setShowAuthFlow]);
38
46
  const getCaptchaToken = useCallback(() => {
@@ -119,7 +119,7 @@ export interface DynamicContextProps {
119
119
  /**
120
120
  * If true, the Metamask SDK will be used to connect to the wallet.
121
121
  * If false, the injected eip6963 provider will be used and WalletConnect for mobile.
122
- * @default false
122
+ * @default true
123
123
  */
124
124
  useMetamaskSdk?: boolean;
125
125
  };
@@ -23,7 +23,7 @@ const defaultDynamicSettings = {
23
23
  shadowDOMEnabled: true,
24
24
  showLockedWalletView: false,
25
25
  tokensFilter: (tokens) => tokens,
26
- useMetamaskSdk: false,
26
+ useMetamaskSdk: true,
27
27
  };
28
28
 
29
29
  exports.PUBLIC_PROJECT_LIVE_ENVIRONMENT_ID = PUBLIC_PROJECT_LIVE_ENVIRONMENT_ID;
@@ -16,5 +16,5 @@ export declare const defaultDynamicSettings: {
16
16
  shadowDOMEnabled: true;
17
17
  showLockedWalletView: false;
18
18
  tokensFilter: (tokens: import("@dynamic-labs/sdk-api-core").TokenBalance[]) => import("@dynamic-labs/sdk-api-core").TokenBalance[];
19
- useMetamaskSdk: false;
19
+ useMetamaskSdk: true;
20
20
  };
@@ -19,7 +19,7 @@ const defaultDynamicSettings = {
19
19
  shadowDOMEnabled: true,
20
20
  showLockedWalletView: false,
21
21
  tokensFilter: (tokens) => tokens,
22
- useMetamaskSdk: false,
22
+ useMetamaskSdk: true,
23
23
  };
24
24
 
25
25
  export { PUBLIC_PROJECT_LIVE_ENVIRONMENT_ID, defaultDynamicSettings };
@@ -0,0 +1,24 @@
1
+ 'use client'
2
+ 'use strict';
3
+
4
+ Object.defineProperty(exports, '__esModule', { value: true });
5
+
6
+ /**
7
+ * Embedded Bitcoin wallets expose a per-network payment address (one key,
8
+ * network-tagged additional addresses). The connector swaps its active
9
+ * address when the selected network changes, so per-network UI (displayed
10
+ * address, deposit QR, balance queries) must read the connector's active
11
+ * address rather than the wallet's static primary (mainnet) address.
12
+ *
13
+ * @returns the active address for embedded Bitcoin connectors, undefined otherwise
14
+ */
15
+ const getEmbeddedBitcoinActiveAddress = (connector) => {
16
+ if (!connector ||
17
+ connector.connectedChain !== 'BTC' ||
18
+ !connector.isEmbeddedWallet) {
19
+ return undefined;
20
+ }
21
+ return connector.activeAccountAddress;
22
+ };
23
+
24
+ exports.getEmbeddedBitcoinActiveAddress = getEmbeddedBitcoinActiveAddress;
@@ -0,0 +1,11 @@
1
+ import { WalletConnector } from '@dynamic-labs/wallet-connector-core';
2
+ /**
3
+ * Embedded Bitcoin wallets expose a per-network payment address (one key,
4
+ * network-tagged additional addresses). The connector swaps its active
5
+ * address when the selected network changes, so per-network UI (displayed
6
+ * address, deposit QR, balance queries) must read the connector's active
7
+ * address rather than the wallet's static primary (mainnet) address.
8
+ *
9
+ * @returns the active address for embedded Bitcoin connectors, undefined otherwise
10
+ */
11
+ export declare const getEmbeddedBitcoinActiveAddress: (connector?: WalletConnector) => string | undefined;
@@ -0,0 +1,20 @@
1
+ 'use client'
2
+ /**
3
+ * Embedded Bitcoin wallets expose a per-network payment address (one key,
4
+ * network-tagged additional addresses). The connector swaps its active
5
+ * address when the selected network changes, so per-network UI (displayed
6
+ * address, deposit QR, balance queries) must read the connector's active
7
+ * address rather than the wallet's static primary (mainnet) address.
8
+ *
9
+ * @returns the active address for embedded Bitcoin connectors, undefined otherwise
10
+ */
11
+ const getEmbeddedBitcoinActiveAddress = (connector) => {
12
+ if (!connector ||
13
+ connector.connectedChain !== 'BTC' ||
14
+ !connector.isEmbeddedWallet) {
15
+ return undefined;
16
+ }
17
+ return connector.activeAccountAddress;
18
+ };
19
+
20
+ export { getEmbeddedBitcoinActiveAddress };
@@ -0,0 +1 @@
1
+ export * from './getEmbeddedBitcoinActiveAddress';
@@ -32,6 +32,18 @@ const BLOCK_EXPLORER_PATTERNS = [
32
32
  return url.toString();
33
33
  },
34
34
  },
35
+ {
36
+ // mempool.space scopes networks by path (/testnet, /signet); the network
37
+ // segment must be preserved or testnet links resolve to mainnet.
38
+ description: 'mempool.space - keeps the network path segment',
39
+ domain: 'mempool.space',
40
+ generateUrl: (baseUrl, hash) => {
41
+ const url = new URL(baseUrl);
42
+ const basePath = url.pathname.replace(/\/$/, '');
43
+ url.pathname = `${basePath}/tx/${hash}`;
44
+ return url.toString();
45
+ },
46
+ },
35
47
  {
36
48
  // The Midnight explorer indexes by the canonical transaction hash and
37
49
  // serves detail pages at `/transactions/{hash}`. Matching the bare
@@ -28,6 +28,18 @@ const BLOCK_EXPLORER_PATTERNS = [
28
28
  return url.toString();
29
29
  },
30
30
  },
31
+ {
32
+ // mempool.space scopes networks by path (/testnet, /signet); the network
33
+ // segment must be preserved or testnet links resolve to mainnet.
34
+ description: 'mempool.space - keeps the network path segment',
35
+ domain: 'mempool.space',
36
+ generateUrl: (baseUrl, hash) => {
37
+ const url = new URL(baseUrl);
38
+ const basePath = url.pathname.replace(/\/$/, '');
39
+ url.pathname = `${basePath}/tx/${hash}`;
40
+ return url.toString();
41
+ },
42
+ },
31
43
  {
32
44
  // The Midnight explorer indexes by the canonical transaction hash and
33
45
  // serves detail pages at `/transactions/{hash}`. Matching the bare
@@ -3,9 +3,22 @@
3
3
 
4
4
  Object.defineProperty(exports, '__esModule', { value: true });
5
5
 
6
- const getWalletAdditionalAddressByType = (type, wallet) => {
7
- var _a, _b;
8
- return (_b = (_a = wallet === null || wallet === void 0 ? void 0 : wallet.additionalAddresses) === null || _a === void 0 ? void 0 : _a.find((address) => address.type === type)) === null || _b === void 0 ? void 0 : _b.address;
6
+ /**
7
+ * Returns an additional address of the given type. When a `network` tag is
8
+ * provided (e.g. Midnight's 'mainnet' | 'preview'), the variant matching that
9
+ * network is preferred, falling back to the first address of the type for
10
+ * legacy/untagged wallets. Callers that don't pass `network` keep the previous
11
+ * "first match" behavior.
12
+ */
13
+ const getWalletAdditionalAddressByType = (type, wallet, network) => {
14
+ var _a, _b, _c;
15
+ const matches = (_b = (_a = wallet === null || wallet === void 0 ? void 0 : wallet.additionalAddresses) === null || _a === void 0 ? void 0 : _a.filter((address) => address.type === type)) !== null && _b !== void 0 ? _b : [];
16
+ if (network) {
17
+ const networkMatch = matches.find((address) => address.network === network);
18
+ if (networkMatch)
19
+ return networkMatch.address;
20
+ }
21
+ return (_c = matches[0]) === null || _c === void 0 ? void 0 : _c.address;
9
22
  };
10
23
 
11
24
  exports.getWalletAdditionalAddressByType = getWalletAdditionalAddressByType;
@@ -1,3 +1,10 @@
1
1
  import { WalletAddressType } from '@dynamic-labs/sdk-api-core';
2
2
  import { Wallet } from '../../../shared';
3
- export declare const getWalletAdditionalAddressByType: (type: WalletAddressType, wallet?: Wallet) => string | undefined;
3
+ /**
4
+ * Returns an additional address of the given type. When a `network` tag is
5
+ * provided (e.g. Midnight's 'mainnet' | 'preview'), the variant matching that
6
+ * network is preferred, falling back to the first address of the type for
7
+ * legacy/untagged wallets. Callers that don't pass `network` keep the previous
8
+ * "first match" behavior.
9
+ */
10
+ export declare const getWalletAdditionalAddressByType: (type: WalletAddressType, wallet?: Wallet, network?: string) => string | undefined;
@@ -1,7 +1,20 @@
1
1
  'use client'
2
- const getWalletAdditionalAddressByType = (type, wallet) => {
3
- var _a, _b;
4
- return (_b = (_a = wallet === null || wallet === void 0 ? void 0 : wallet.additionalAddresses) === null || _a === void 0 ? void 0 : _a.find((address) => address.type === type)) === null || _b === void 0 ? void 0 : _b.address;
2
+ /**
3
+ * Returns an additional address of the given type. When a `network` tag is
4
+ * provided (e.g. Midnight's 'mainnet' | 'preview'), the variant matching that
5
+ * network is preferred, falling back to the first address of the type for
6
+ * legacy/untagged wallets. Callers that don't pass `network` keep the previous
7
+ * "first match" behavior.
8
+ */
9
+ const getWalletAdditionalAddressByType = (type, wallet, network) => {
10
+ var _a, _b, _c;
11
+ const matches = (_b = (_a = wallet === null || wallet === void 0 ? void 0 : wallet.additionalAddresses) === null || _a === void 0 ? void 0 : _a.filter((address) => address.type === type)) !== null && _b !== void 0 ? _b : [];
12
+ if (network) {
13
+ const networkMatch = matches.find((address) => address.network === network);
14
+ if (networkMatch)
15
+ return networkMatch.address;
16
+ }
17
+ return (_c = matches[0]) === null || _c === void 0 ? void 0 : _c.address;
5
18
  };
6
19
 
7
20
  export { getWalletAdditionalAddressByType };
@@ -54,6 +54,7 @@ export * from './requiresTwoStepAuthentication';
54
54
  export * from './shouldManuallyReconnectOnRefresh';
55
55
  export * from './stringifyURIQuery';
56
56
  export * from './getEnabledEmbeddedWalletsAuthenticators';
57
+ export * from './getEmbeddedBitcoinActiveAddress';
57
58
  export * from './getWalletAdditionalAddressByType';
58
59
  export * from './isHardwareWalletEnabled';
59
60
  export * from './getEnabledEmbeddedWalletProviders';