@dynamic-labs/sdk-react-core 4.90.0 → 4.91.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +17 -0
- package/README.md +1 -52
- package/package.cjs +2 -2
- package/package.js +2 -2
- package/package.json +13 -13
- package/src/lib/client/extension/functions/getSessionKeys/getSessionKeys.cjs +11 -0
- package/src/lib/client/extension/functions/getSessionKeys/getSessionKeys.js +7 -0
- package/src/lib/client/extension/functions/getSessionPublicKey/getSessionPublicKey.cjs +17 -0
- package/src/lib/client/extension/functions/getSessionPublicKey/getSessionPublicKey.d.ts +7 -0
- package/src/lib/client/extension/functions/getSessionPublicKey/getSessionPublicKey.js +13 -0
- package/src/lib/client/extension/index.d.ts +1 -0
- package/src/lib/context/DynamicContext/DynamicContext.cjs +9 -1
- package/src/lib/context/DynamicContext/DynamicContext.js +10 -2
- package/src/lib/styles/index.shadow.cjs +1 -1
- package/src/lib/styles/index.shadow.js +1 -1
- package/src/lib/utils/functions/getTransactionLink/blockExplorerPatterns.cjs +12 -0
- package/src/lib/utils/functions/getTransactionLink/blockExplorerPatterns.js +12 -0
- package/src/lib/utils/hooks/useCreateWalletConnectorOptions/utils/verifyZeroDevIsSetup/verifyZeroDevIsSetup.cjs +7 -3
- package/src/lib/utils/hooks/useCreateWalletConnectorOptions/utils/verifyZeroDevIsSetup/verifyZeroDevIsSetup.js +7 -3
- package/src/lib/utils/hooks/useDynamicWaas/useDynamicWaas.cjs +16 -3
- package/src/lib/utils/hooks/useDynamicWaas/useDynamicWaas.d.ts +3 -1
- package/src/lib/utils/hooks/useDynamicWaas/useDynamicWaas.js +16 -3
- package/src/lib/utils/hooks/useSetWalletConnectorFetchers/useSetWalletConnectorFetchers.cjs +8 -1
- package/src/lib/utils/hooks/useSetWalletConnectorFetchers/useSetWalletConnectorFetchers.d.ts +1 -1
- package/src/lib/utils/hooks/useSetWalletConnectorFetchers/useSetWalletConnectorFetchers.js +8 -1
- package/src/lib/views/TransactionConfirmationView/helpers/transactionErrorMessage.cjs +8 -0
- package/src/lib/views/TransactionConfirmationView/helpers/transactionErrorMessage.js +8 -0
- package/src/lib/widgets/DynamicWidget/components/ActiveMidnightWalletBalance/ActiveMidnightWalletBalance.cjs +56 -13
- package/src/lib/widgets/DynamicWidget/components/ActiveMidnightWalletBalance/ActiveMidnightWalletBalance.js +58 -15
- package/src/lib/widgets/DynamicWidget/components/ActiveWalletInformation/ActiveMidnightWalletAddresses/ActiveMidnightWalletAddresses.cjs +40 -2
- package/src/lib/widgets/DynamicWidget/components/ActiveWalletInformation/ActiveMidnightWalletAddresses/ActiveMidnightWalletAddresses.d.ts +7 -0
- package/src/lib/widgets/DynamicWidget/components/ActiveWalletInformation/ActiveMidnightWalletAddresses/ActiveMidnightWalletAddresses.js +41 -3
- package/src/lib/widgets/DynamicWidget/components/ActiveWalletInformation/ActiveWalletInformation.cjs +2 -0
- package/src/lib/widgets/DynamicWidget/components/ActiveWalletInformation/ActiveWalletInformation.js +2 -0
|
@@ -1,9 +1,10 @@
|
|
|
1
1
|
'use client'
|
|
2
2
|
import { __awaiter } from '../../../../../../_virtual/_tslib.js';
|
|
3
3
|
import { jsx, jsxs, Fragment } from 'react/jsx-runtime';
|
|
4
|
-
import { useState } from 'react';
|
|
4
|
+
import { useState, useEffect } from 'react';
|
|
5
5
|
import { useTranslation } from 'react-i18next';
|
|
6
|
-
import { isMidnightConnector, isMidnightWallet } from '@dynamic-labs/wallet-connector-core';
|
|
6
|
+
import { isMidnightConnector, isMidnightWallet, isDynamicWaasConnector } from '@dynamic-labs/wallet-connector-core';
|
|
7
|
+
import { Button } from '../../../../components/Button/Button.js';
|
|
7
8
|
import { Skeleton } from '../../../../components/Skeleton/Skeleton.js';
|
|
8
9
|
import '../../../../context/DynamicContext/useDynamicContext/useDynamicContext.js';
|
|
9
10
|
import { useInternalDynamicContext } from '../../../../context/DynamicContext/useDynamicContext/useInternalDynamicContext/useInternalDynamicContext.js';
|
|
@@ -22,6 +23,9 @@ import { classNames } from '../../../../utils/functions/classNames/classNames.js
|
|
|
22
23
|
import { usePromise } from '../../../../utils/hooks/usePromise/usePromise.js';
|
|
23
24
|
|
|
24
25
|
const DUST_SEGMENTS = 20;
|
|
26
|
+
// Stable keys for the fixed-length decorative dust bar so the segments don't
|
|
27
|
+
// rely on the array index as their React key.
|
|
28
|
+
const DUST_SEGMENT_KEYS = Array.from({ length: DUST_SEGMENTS }, (_, i) => `dust-segment-${i}`);
|
|
25
29
|
const truncateToDecimals = (value, decimals) => {
|
|
26
30
|
const [whole, fractional] = value.split('.');
|
|
27
31
|
if (!fractional || decimals <= 0)
|
|
@@ -57,6 +61,10 @@ const ActiveMidnightWalletBalance = ({ isLoading = false, }) => {
|
|
|
57
61
|
const [activeTab, setActiveTab] = useState('shielded');
|
|
58
62
|
const walletAddress = primaryWallet === null || primaryWallet === void 0 ? void 0 : primaryWallet.address;
|
|
59
63
|
const enabled = Boolean(!isLoading && primaryWallet && isMidnightConnector(primaryWallet.connector));
|
|
64
|
+
// Balance reads resolve on shielded+unshielded; dust finishes in the
|
|
65
|
+
// background. While dust is still syncing we re-fetch on an interval so the
|
|
66
|
+
// dust gauge fills in once it's ready (shielded/unshielded already final).
|
|
67
|
+
const [dustPollTick, setDustPollTick] = useState(0);
|
|
60
68
|
const { data: balances, isLoading: balancesLoading } = usePromise(() => __awaiter(void 0, void 0, void 0, function* () {
|
|
61
69
|
if (!primaryWallet ||
|
|
62
70
|
!isMidnightConnector(primaryWallet.connector) ||
|
|
@@ -65,11 +73,31 @@ const ActiveMidnightWalletBalance = ({ isLoading = false, }) => {
|
|
|
65
73
|
}
|
|
66
74
|
return primaryWallet.getFormattedBalances();
|
|
67
75
|
}), {
|
|
68
|
-
deps: [walletAddress, primaryWallet],
|
|
76
|
+
deps: [walletAddress, primaryWallet, dustPollTick],
|
|
69
77
|
enabled,
|
|
70
78
|
});
|
|
71
|
-
const { dustBalance, shieldedBalance, unshieldedBalance } = balances !== null && balances !== void 0 ? balances : {};
|
|
72
|
-
|
|
79
|
+
const { dustBalance, shieldedBalance, unshieldedBalance, dustSyncing } = balances !== null && balances !== void 0 ? balances : {};
|
|
80
|
+
useEffect(() => {
|
|
81
|
+
if (!dustSyncing)
|
|
82
|
+
return undefined;
|
|
83
|
+
const id = setInterval(() => setDustPollTick((tick) => tick + 1), 15000);
|
|
84
|
+
return () => clearInterval(id);
|
|
85
|
+
}, [dustSyncing]);
|
|
86
|
+
// `registerDust` is a WaaS-only connector method (external/injected Midnight
|
|
87
|
+
// wallets manage dust themselves). When the embedded wallet has no dust
|
|
88
|
+
// registered yet, we surface a "Register DUST" button instead of the gauge.
|
|
89
|
+
const isWaasWallet = Boolean(primaryWallet && isDynamicWaasConnector(primaryWallet.connector));
|
|
90
|
+
const handleRegisterDust = () => __awaiter(void 0, void 0, void 0, function* () {
|
|
91
|
+
const connector = primaryWallet === null || primaryWallet === void 0 ? void 0 : primaryWallet.connector;
|
|
92
|
+
if (!(connector === null || connector === void 0 ? void 0 : connector.registerDust))
|
|
93
|
+
return;
|
|
94
|
+
yield connector.registerDust();
|
|
95
|
+
// Dust generation begins after registration; re-fetch so the gauge appears.
|
|
96
|
+
setDustPollTick((tick) => tick + 1);
|
|
97
|
+
});
|
|
98
|
+
// Only show the full skeleton on the very first load; background dust polls
|
|
99
|
+
// keep `balances` populated so the view never flashes back to a skeleton.
|
|
100
|
+
if ((isLoading || balancesLoading) && !balances) {
|
|
73
101
|
return (jsx("div", { className: 'active-midnight-balance', children: jsx(Skeleton, { className: 'active-midnight-balance__skeleton' }) }));
|
|
74
102
|
}
|
|
75
103
|
const dustFill = dustBalance
|
|
@@ -82,16 +110,31 @@ const ActiveMidnightWalletBalance = ({ isLoading = false, }) => {
|
|
|
82
110
|
}
|
|
83
111
|
: undefined;
|
|
84
112
|
const activeBalance = activeTab === 'shielded' ? shieldedBalance : unshieldedBalance;
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
113
|
+
// Dust section has three mutually exclusive states (syncing, generating with
|
|
114
|
+
// a balance, and the WaaS "register dust" prompt). Resolved via a helper to
|
|
115
|
+
// avoid nesting ternaries in the JSX below.
|
|
116
|
+
const renderDustSection = () => {
|
|
117
|
+
if (dustSyncing) {
|
|
118
|
+
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' })] }));
|
|
119
|
+
}
|
|
120
|
+
if (dustBalance) {
|
|
121
|
+
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') })] }), jsxs("span", { className: 'active-midnight-balance__dust-count', children: [dustBalanceDisplay === null || dustBalanceDisplay === void 0 ? void 0 : dustBalanceDisplay.balance, "/", dustBalanceDisplay === null || dustBalanceDisplay === void 0 ? void 0 : dustBalanceDisplay.cap] })] }), jsx("div", { className: 'active-midnight-balance__dust-bar', children: DUST_SEGMENT_KEYS.map((segmentKey, i) => (jsx("div", { className: [
|
|
122
|
+
'active-midnight-balance__dust-segment',
|
|
123
|
+
i === 0 && 'active-midnight-balance__dust-segment--first',
|
|
124
|
+
i === DUST_SEGMENTS - 1 &&
|
|
125
|
+
'active-midnight-balance__dust-segment--last',
|
|
126
|
+
i < dustFill &&
|
|
127
|
+
'active-midnight-balance__dust-segment--filled',
|
|
128
|
+
]
|
|
129
|
+
.filter(Boolean)
|
|
130
|
+
.join(' ') }, segmentKey))) })] }), jsx("div", { className: 'active-midnight-balance__divider' })] }));
|
|
131
|
+
}
|
|
132
|
+
if (isWaasWallet) {
|
|
133
|
+
return (jsxs(Fragment, { children: [jsxs("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_generating', children: t('dyn_active_wallet_info.midnight_dust_generating') })] }) }), jsx(Button, { buttonPadding: 'small', buttonVariant: 'secondary', buttonClassName: 'active-midnight-balance__register-dust-button', onClick: handleRegisterDust, "data-copykey": 'dyn_active_wallet_info.midnight_register_dust', children: t('dyn_active_wallet_info.midnight_register_dust') })] }), jsx("div", { className: 'active-midnight-balance__divider' })] }));
|
|
134
|
+
}
|
|
135
|
+
return null;
|
|
136
|
+
};
|
|
137
|
+
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', {
|
|
95
138
|
'active-midnight-balance__tab--active': activeTab === id,
|
|
96
139
|
}), "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' })), jsxs("span", { className: 'active-midnight-balance__amount', children: [activeBalance !== null && activeBalance !== void 0 ? activeBalance : '—', " NIGHT"] })] })] }) }));
|
|
97
140
|
};
|
|
@@ -4,9 +4,10 @@
|
|
|
4
4
|
Object.defineProperty(exports, '__esModule', { value: true });
|
|
5
5
|
|
|
6
6
|
var jsxRuntime = require('react/jsx-runtime');
|
|
7
|
+
var React = require('react');
|
|
7
8
|
var reactI18next = require('react-i18next');
|
|
8
9
|
require('../../../../../components/Accordion/components/AccordionItem/AccordionItem.cjs');
|
|
9
|
-
require('
|
|
10
|
+
var copy = require('../../../../../shared/assets/copy.cjs');
|
|
10
11
|
require('@dynamic-labs/iconic');
|
|
11
12
|
require('../../../../../context/ViewContext/ViewContext.cjs');
|
|
12
13
|
require('../../../../../../../_virtual/_tslib.cjs');
|
|
@@ -71,6 +72,7 @@ require('../../../../../components/OverlayCardBase/OverlayCardTarget/OverlayCard
|
|
|
71
72
|
require('../../../../../context/WalletGroupContext/WalletGroupContext.cjs');
|
|
72
73
|
require('../../DynamicWidgetHeader/DynamicWidgetHeader.cjs');
|
|
73
74
|
require('react-focus-lock');
|
|
75
|
+
var Icon = require('../../../../../components/Icon/Icon.cjs');
|
|
74
76
|
var shortenWalletAddress = require('../../../../../shared/utils/functions/shortenWalletAddress/shortenWalletAddress.cjs');
|
|
75
77
|
require('../../../context/DynamicWidgetContext.cjs');
|
|
76
78
|
require('../../../../../components/IconButton/IconButton.cjs');
|
|
@@ -95,6 +97,7 @@ require('../../../views/CryptoComOnramp/CryptoComOnramp.cjs');
|
|
|
95
97
|
require('../../../../../context/OnrampContext/OnrampContext.cjs');
|
|
96
98
|
require('../../../../../../index.cjs');
|
|
97
99
|
require('../../../helpers/convertExchangeKeyAndProviderEnum.cjs');
|
|
100
|
+
var CopyButton = require('../../../../../components/CopyButton/CopyButton.cjs');
|
|
98
101
|
require('qrcode');
|
|
99
102
|
require('../../../views/ManagePasskeysMfaWidgetView/ManagePasskeysMfaWidgetView.cjs');
|
|
100
103
|
require('../../../views/ManageTotpMfaWidgetView/ManageTotpMfaWidgetView.cjs');
|
|
@@ -116,13 +119,48 @@ require('../../../../../components/IsBrowser/IsBrowser.cjs');
|
|
|
116
119
|
require('../../../../../components/Popper/Popper/Popper.cjs');
|
|
117
120
|
require('../../../../../components/Popper/PopperContext/PopperContext.cjs');
|
|
118
121
|
|
|
122
|
+
/**
|
|
123
|
+
* Midnight wallet address types as string literals.
|
|
124
|
+
* These correspond to WalletAddressType enum values that will be added in the backend.
|
|
125
|
+
*/
|
|
119
126
|
const MIDNIGHT_ADDRESS_TYPE_UNSHIELDED = 'midnight_unshielded';
|
|
127
|
+
const MIDNIGHT_ADDRESS_TYPE_DUST = 'midnight_dust';
|
|
128
|
+
const MIDNIGHT_ADDRESS_TYPE_SHIELDED = 'midnight_shielded';
|
|
129
|
+
/**
|
|
130
|
+
* Gets a Midnight address from the wallet's additional addresses by type.
|
|
131
|
+
* @param type - The address type to find
|
|
132
|
+
* @param wallet - The wallet containing additional addresses
|
|
133
|
+
* @returns The address string or undefined if not found
|
|
134
|
+
*/
|
|
120
135
|
const getMidnightAddressByType = (type, wallet) => { var _a, _b; return (_b = (_a = wallet === null || wallet === void 0 ? void 0 : wallet.additionalAddresses) === null || _a === void 0 ? void 0 : _a.find((addr) => addr.type === type)) === null || _b === void 0 ? void 0 : _b.address; };
|
|
136
|
+
/**
|
|
137
|
+
* Component for displaying Midnight wallet addresses.
|
|
138
|
+
* Midnight supports multiple address types:
|
|
139
|
+
* - Unshielded: For public/transparent transactions
|
|
140
|
+
* - Dust: For gas/fee management
|
|
141
|
+
* - Shielded: For private transfers (Phase 2)
|
|
142
|
+
*/
|
|
121
143
|
const ActiveMidnightWalletAddresses = ({ menuOption, wallet, }) => {
|
|
122
144
|
var _a;
|
|
123
145
|
const { t } = reactI18next.useTranslation();
|
|
124
146
|
const unshieldedAddress = (_a = getMidnightAddressByType(MIDNIGHT_ADDRESS_TYPE_UNSHIELDED, wallet)) !== null && _a !== void 0 ? _a : wallet === null || wallet === void 0 ? void 0 : wallet.address;
|
|
125
|
-
|
|
147
|
+
const dustAddress = getMidnightAddressByType(MIDNIGHT_ADDRESS_TYPE_DUST, wallet);
|
|
148
|
+
const shieldedAddress = getMidnightAddressByType(MIDNIGHT_ADDRESS_TYPE_SHIELDED, wallet);
|
|
149
|
+
// Collapse dust + shielded behind a toggle so the header shows only the
|
|
150
|
+
// primary (unshielded) address by default — the user reveals the rest on
|
|
151
|
+
// click, instead of all three being shown at once.
|
|
152
|
+
const [expanded, setExpanded] = React.useState(false);
|
|
153
|
+
const hasAdditionalAddresses = Boolean(dustAddress || shieldedAddress);
|
|
154
|
+
return (jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [jsxRuntime.jsxs("div", { className: 'active-wallet-information__address-container', children: [jsxRuntime.jsxs("div", { children: [jsxRuntime.jsx(Typography.Typography, { className: 'active-wallet-information__address', weight: 'regular', variant: 'body_small', color: 'secondary', copykey: 'dyn_active_wallet_info.midnight_unshielded_address', children: t('dyn_active_wallet_info.midnight_unshielded_address') }), jsxRuntime.jsx(Typography.Typography, { className: 'active-wallet-information__address', weight: 'medium', variant: 'body_normal', color: 'primary', children: shortenWalletAddress.shortenWalletAddress(unshieldedAddress) })] }), jsxRuntime.jsxs("div", { style: { alignItems: 'center', display: 'flex', gap: '4px' }, children: [hasAdditionalAddresses && (jsxRuntime.jsx("button", { type: 'button', "aria-expanded": expanded, "aria-label": t('dyn_active_wallet_info.midnight_toggle_addresses'), onClick: () => setExpanded((prev) => !prev), style: {
|
|
155
|
+
background: 'none',
|
|
156
|
+
border: 'none',
|
|
157
|
+
cursor: 'pointer',
|
|
158
|
+
display: 'flex',
|
|
159
|
+
padding: 0,
|
|
160
|
+
}, children: jsxRuntime.jsx("svg", { width: '16', height: '16', viewBox: '0 0 24 24', fill: 'none', stroke: 'currentColor', strokeWidth: '2', style: {
|
|
161
|
+
transform: expanded ? 'rotate(180deg)' : undefined,
|
|
162
|
+
transition: 'transform 0.15s ease',
|
|
163
|
+
}, children: jsxRuntime.jsx("path", { d: 'M6 9l6 6 6-6' }) }) })), jsxRuntime.jsx(DotsMenu.DotsMenu, { "data-testid": 'dots-menu', options: menuOption, buttonClassName: 'active-wallet-information__dots-menu', buttonClassNameWithOpenMenu: 'active-wallet-information__dots-menu' })] })] }), expanded && dustAddress && (jsxRuntime.jsxs("div", { className: 'active-wallet-information__address-container', children: [jsxRuntime.jsxs("div", { children: [jsxRuntime.jsx(Typography.Typography, { className: 'active-wallet-information__address', weight: 'regular', variant: 'body_small', color: 'secondary', copykey: 'dyn_active_wallet_info.midnight_dust_address', children: t('dyn_active_wallet_info.midnight_dust_address') }), jsxRuntime.jsx(Typography.Typography, { className: 'active-wallet-information__address', weight: 'regular', variant: 'body_small', color: 'primary', children: shortenWalletAddress.shortenWalletAddress(dustAddress) })] }), jsxRuntime.jsx(CopyButton.CopyButton, { textToCopy: dustAddress, children: jsxRuntime.jsx(Icon.Icon, { size: 'xsmall', children: jsxRuntime.jsx(copy.ReactComponent, {}) }) })] })), expanded && shieldedAddress && (jsxRuntime.jsxs("div", { className: 'active-wallet-information__address-container', children: [jsxRuntime.jsxs("div", { children: [jsxRuntime.jsx(Typography.Typography, { className: 'active-wallet-information__address', weight: 'regular', variant: 'body_small', color: 'secondary', copykey: 'dyn_active_wallet_info.midnight_shielded_address', children: t('dyn_active_wallet_info.midnight_shielded_address') }), jsxRuntime.jsx(Typography.Typography, { className: 'active-wallet-information__address', weight: 'regular', variant: 'body_small', color: 'primary', children: shortenWalletAddress.shortenWalletAddress(shieldedAddress) })] }), jsxRuntime.jsx(CopyButton.CopyButton, { textToCopy: shieldedAddress, children: jsxRuntime.jsx(Icon.Icon, { size: 'xsmall', children: jsxRuntime.jsx(copy.ReactComponent, {}) }) })] }))] }));
|
|
126
164
|
};
|
|
127
165
|
|
|
128
166
|
exports.ActiveMidnightWalletAddresses = ActiveMidnightWalletAddresses;
|
|
@@ -5,5 +5,12 @@ type Props = {
|
|
|
5
5
|
menuOption: MenuOption[];
|
|
6
6
|
wallet?: Wallet;
|
|
7
7
|
};
|
|
8
|
+
/**
|
|
9
|
+
* Component for displaying Midnight wallet addresses.
|
|
10
|
+
* Midnight supports multiple address types:
|
|
11
|
+
* - Unshielded: For public/transparent transactions
|
|
12
|
+
* - Dust: For gas/fee management
|
|
13
|
+
* - Shielded: For private transfers (Phase 2)
|
|
14
|
+
*/
|
|
8
15
|
export declare const ActiveMidnightWalletAddresses: ({ menuOption, wallet, }: Props) => JSX.Element;
|
|
9
16
|
export {};
|
|
@@ -1,8 +1,9 @@
|
|
|
1
1
|
'use client'
|
|
2
|
-
import { jsxs, jsx } from 'react/jsx-runtime';
|
|
2
|
+
import { jsxs, Fragment, jsx } from 'react/jsx-runtime';
|
|
3
|
+
import { useState } from 'react';
|
|
3
4
|
import { useTranslation } from 'react-i18next';
|
|
4
5
|
import '../../../../../components/Accordion/components/AccordionItem/AccordionItem.js';
|
|
5
|
-
import '
|
|
6
|
+
import { ReactComponent as SvgCopy } from '../../../../../shared/assets/copy.js';
|
|
6
7
|
import '@dynamic-labs/iconic';
|
|
7
8
|
import '../../../../../context/ViewContext/ViewContext.js';
|
|
8
9
|
import '../../../../../../../_virtual/_tslib.js';
|
|
@@ -67,6 +68,7 @@ import '../../../../../components/OverlayCardBase/OverlayCardTarget/OverlayCardT
|
|
|
67
68
|
import '../../../../../context/WalletGroupContext/WalletGroupContext.js';
|
|
68
69
|
import '../../DynamicWidgetHeader/DynamicWidgetHeader.js';
|
|
69
70
|
import 'react-focus-lock';
|
|
71
|
+
import { Icon } from '../../../../../components/Icon/Icon.js';
|
|
70
72
|
import { shortenWalletAddress } from '../../../../../shared/utils/functions/shortenWalletAddress/shortenWalletAddress.js';
|
|
71
73
|
import '../../../context/DynamicWidgetContext.js';
|
|
72
74
|
import '../../../../../components/IconButton/IconButton.js';
|
|
@@ -91,6 +93,7 @@ import '../../../views/CryptoComOnramp/CryptoComOnramp.js';
|
|
|
91
93
|
import '../../../../../context/OnrampContext/OnrampContext.js';
|
|
92
94
|
import '../../../../../../index.js';
|
|
93
95
|
import '../../../helpers/convertExchangeKeyAndProviderEnum.js';
|
|
96
|
+
import { CopyButton } from '../../../../../components/CopyButton/CopyButton.js';
|
|
94
97
|
import 'qrcode';
|
|
95
98
|
import '../../../views/ManagePasskeysMfaWidgetView/ManagePasskeysMfaWidgetView.js';
|
|
96
99
|
import '../../../views/ManageTotpMfaWidgetView/ManageTotpMfaWidgetView.js';
|
|
@@ -112,13 +115,48 @@ import '../../../../../components/IsBrowser/IsBrowser.js';
|
|
|
112
115
|
import '../../../../../components/Popper/Popper/Popper.js';
|
|
113
116
|
import '../../../../../components/Popper/PopperContext/PopperContext.js';
|
|
114
117
|
|
|
118
|
+
/**
|
|
119
|
+
* Midnight wallet address types as string literals.
|
|
120
|
+
* These correspond to WalletAddressType enum values that will be added in the backend.
|
|
121
|
+
*/
|
|
115
122
|
const MIDNIGHT_ADDRESS_TYPE_UNSHIELDED = 'midnight_unshielded';
|
|
123
|
+
const MIDNIGHT_ADDRESS_TYPE_DUST = 'midnight_dust';
|
|
124
|
+
const MIDNIGHT_ADDRESS_TYPE_SHIELDED = 'midnight_shielded';
|
|
125
|
+
/**
|
|
126
|
+
* Gets a Midnight address from the wallet's additional addresses by type.
|
|
127
|
+
* @param type - The address type to find
|
|
128
|
+
* @param wallet - The wallet containing additional addresses
|
|
129
|
+
* @returns The address string or undefined if not found
|
|
130
|
+
*/
|
|
116
131
|
const getMidnightAddressByType = (type, wallet) => { var _a, _b; return (_b = (_a = wallet === null || wallet === void 0 ? void 0 : wallet.additionalAddresses) === null || _a === void 0 ? void 0 : _a.find((addr) => addr.type === type)) === null || _b === void 0 ? void 0 : _b.address; };
|
|
132
|
+
/**
|
|
133
|
+
* Component for displaying Midnight wallet addresses.
|
|
134
|
+
* Midnight supports multiple address types:
|
|
135
|
+
* - Unshielded: For public/transparent transactions
|
|
136
|
+
* - Dust: For gas/fee management
|
|
137
|
+
* - Shielded: For private transfers (Phase 2)
|
|
138
|
+
*/
|
|
117
139
|
const ActiveMidnightWalletAddresses = ({ menuOption, wallet, }) => {
|
|
118
140
|
var _a;
|
|
119
141
|
const { t } = useTranslation();
|
|
120
142
|
const unshieldedAddress = (_a = getMidnightAddressByType(MIDNIGHT_ADDRESS_TYPE_UNSHIELDED, wallet)) !== null && _a !== void 0 ? _a : wallet === null || wallet === void 0 ? void 0 : wallet.address;
|
|
121
|
-
|
|
143
|
+
const dustAddress = getMidnightAddressByType(MIDNIGHT_ADDRESS_TYPE_DUST, wallet);
|
|
144
|
+
const shieldedAddress = getMidnightAddressByType(MIDNIGHT_ADDRESS_TYPE_SHIELDED, wallet);
|
|
145
|
+
// Collapse dust + shielded behind a toggle so the header shows only the
|
|
146
|
+
// primary (unshielded) address by default — the user reveals the rest on
|
|
147
|
+
// click, instead of all three being shown at once.
|
|
148
|
+
const [expanded, setExpanded] = useState(false);
|
|
149
|
+
const hasAdditionalAddresses = Boolean(dustAddress || shieldedAddress);
|
|
150
|
+
return (jsxs(Fragment, { children: [jsxs("div", { className: 'active-wallet-information__address-container', children: [jsxs("div", { children: [jsx(Typography, { className: 'active-wallet-information__address', weight: 'regular', variant: 'body_small', color: 'secondary', copykey: 'dyn_active_wallet_info.midnight_unshielded_address', children: t('dyn_active_wallet_info.midnight_unshielded_address') }), jsx(Typography, { className: 'active-wallet-information__address', weight: 'medium', variant: 'body_normal', color: 'primary', children: shortenWalletAddress(unshieldedAddress) })] }), jsxs("div", { style: { alignItems: 'center', display: 'flex', gap: '4px' }, children: [hasAdditionalAddresses && (jsx("button", { type: 'button', "aria-expanded": expanded, "aria-label": t('dyn_active_wallet_info.midnight_toggle_addresses'), onClick: () => setExpanded((prev) => !prev), style: {
|
|
151
|
+
background: 'none',
|
|
152
|
+
border: 'none',
|
|
153
|
+
cursor: 'pointer',
|
|
154
|
+
display: 'flex',
|
|
155
|
+
padding: 0,
|
|
156
|
+
}, children: jsx("svg", { width: '16', height: '16', viewBox: '0 0 24 24', fill: 'none', stroke: 'currentColor', strokeWidth: '2', style: {
|
|
157
|
+
transform: expanded ? 'rotate(180deg)' : undefined,
|
|
158
|
+
transition: 'transform 0.15s ease',
|
|
159
|
+
}, children: jsx("path", { d: 'M6 9l6 6 6-6' }) }) })), jsx(DotsMenu, { "data-testid": 'dots-menu', options: menuOption, buttonClassName: 'active-wallet-information__dots-menu', buttonClassNameWithOpenMenu: 'active-wallet-information__dots-menu' })] })] }), expanded && dustAddress && (jsxs("div", { className: 'active-wallet-information__address-container', children: [jsxs("div", { children: [jsx(Typography, { className: 'active-wallet-information__address', weight: 'regular', variant: 'body_small', color: 'secondary', copykey: 'dyn_active_wallet_info.midnight_dust_address', children: t('dyn_active_wallet_info.midnight_dust_address') }), jsx(Typography, { className: 'active-wallet-information__address', weight: 'regular', variant: 'body_small', color: 'primary', children: shortenWalletAddress(dustAddress) })] }), jsx(CopyButton, { textToCopy: dustAddress, children: jsx(Icon, { size: 'xsmall', children: jsx(SvgCopy, {}) }) })] })), expanded && shieldedAddress && (jsxs("div", { className: 'active-wallet-information__address-container', children: [jsxs("div", { children: [jsx(Typography, { className: 'active-wallet-information__address', weight: 'regular', variant: 'body_small', color: 'secondary', copykey: 'dyn_active_wallet_info.midnight_shielded_address', children: t('dyn_active_wallet_info.midnight_shielded_address') }), jsx(Typography, { className: 'active-wallet-information__address', weight: 'regular', variant: 'body_small', color: 'primary', children: shortenWalletAddress(shieldedAddress) })] }), jsx(CopyButton, { textToCopy: shieldedAddress, children: jsx(Icon, { size: 'xsmall', children: jsx(SvgCopy, {}) }) })] }))] }));
|
|
122
160
|
};
|
|
123
161
|
|
|
124
162
|
export { ActiveMidnightWalletAddresses };
|
package/src/lib/widgets/DynamicWidget/components/ActiveWalletInformation/ActiveWalletInformation.cjs
CHANGED
|
@@ -216,6 +216,8 @@ const ActiveWalletInformation = ({ isLoading = false, }) => {
|
|
|
216
216
|
if (isBitcoin && !isWaasWallet) {
|
|
217
217
|
return (jsxRuntime.jsx(ActiveBitcoinWalletAddresses.ActiveBitcoinWalletAddresses, { wallet: primaryWallet, menuOption: options }));
|
|
218
218
|
}
|
|
219
|
+
// Midnight wallets (WaaS and external/injected alike) expose multiple
|
|
220
|
+
// address types (Unshielded, Dust, Shielded) via additionalAddresses.
|
|
219
221
|
if (isMidnight) {
|
|
220
222
|
return (jsxRuntime.jsx(ActiveMidnightWalletAddresses.ActiveMidnightWalletAddresses, { wallet: primaryWallet, menuOption: options }));
|
|
221
223
|
}
|
package/src/lib/widgets/DynamicWidget/components/ActiveWalletInformation/ActiveWalletInformation.js
CHANGED
|
@@ -212,6 +212,8 @@ const ActiveWalletInformation = ({ isLoading = false, }) => {
|
|
|
212
212
|
if (isBitcoin && !isWaasWallet) {
|
|
213
213
|
return (jsx(ActiveBitcoinWalletAddresses, { wallet: primaryWallet, menuOption: options }));
|
|
214
214
|
}
|
|
215
|
+
// Midnight wallets (WaaS and external/injected alike) expose multiple
|
|
216
|
+
// address types (Unshielded, Dust, Shielded) via additionalAddresses.
|
|
215
217
|
if (isMidnight) {
|
|
216
218
|
return (jsx(ActiveMidnightWalletAddresses, { wallet: primaryWallet, menuOption: options }));
|
|
217
219
|
}
|