@dynamic-labs/sdk-react-core 4.80.0 → 4.82.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 (68) hide show
  1. package/CHANGELOG.md +38 -0
  2. package/package.cjs +1 -1
  3. package/package.js +1 -1
  4. package/package.json +12 -12
  5. package/src/lib/components/SendBalanceForm/SendBalanceForm.cjs +63 -3
  6. package/src/lib/components/SendBalanceForm/SendBalanceForm.js +63 -3
  7. package/src/lib/components/SendBalanceForm/TransactionModeSegmentedControl/TransactionModeSegmentedControl.cjs +40 -0
  8. package/src/lib/components/SendBalanceForm/TransactionModeSegmentedControl/TransactionModeSegmentedControl.d.ts +16 -0
  9. package/src/lib/components/SendBalanceForm/TransactionModeSegmentedControl/TransactionModeSegmentedControl.js +36 -0
  10. package/src/lib/components/SendBalanceForm/TransactionModeSegmentedControl/icons.cjs +17 -0
  11. package/src/lib/components/SendBalanceForm/TransactionModeSegmentedControl/icons.d.ts +8 -0
  12. package/src/lib/components/SendBalanceForm/TransactionModeSegmentedControl/icons.js +12 -0
  13. package/src/lib/components/SendBalanceForm/TransactionModeSegmentedControl/index.d.ts +1 -0
  14. package/src/lib/data/api/aleo/getAleoCuratedPrices.cjs +73 -0
  15. package/src/lib/data/api/aleo/getAleoCuratedPrices.d.ts +38 -0
  16. package/src/lib/data/api/aleo/getAleoCuratedPrices.js +69 -0
  17. package/src/lib/shared/assets/index.d.ts +2 -0
  18. package/src/lib/shared/assets/midnight-shielded.cjs +54 -0
  19. package/src/lib/shared/assets/midnight-shielded.js +30 -0
  20. package/src/lib/shared/assets/midnight-unshielded.cjs +54 -0
  21. package/src/lib/shared/assets/midnight-unshielded.js +30 -0
  22. package/src/lib/styles/index.shadow.cjs +1 -1
  23. package/src/lib/styles/index.shadow.js +1 -1
  24. package/src/lib/utils/functions/compareChains/compareChains.cjs +1 -0
  25. package/src/lib/utils/functions/compareChains/compareChains.js +1 -0
  26. package/src/lib/utils/functions/getTransactionLink/blockExplorerPatterns.cjs +12 -0
  27. package/src/lib/utils/functions/getTransactionLink/blockExplorerPatterns.js +12 -0
  28. package/src/lib/utils/hooks/useAleoAutoMergeRecords/index.d.ts +1 -0
  29. package/src/lib/utils/hooks/useAleoAutoMergeRecords/useAleoAutoMergeRecords.cjs +246 -0
  30. package/src/lib/utils/hooks/useAleoAutoMergeRecords/useAleoAutoMergeRecords.d.ts +17 -0
  31. package/src/lib/utils/hooks/useAleoAutoMergeRecords/useAleoAutoMergeRecords.js +242 -0
  32. package/src/lib/utils/hooks/useAleoAutoShieldSponsoredTokens/index.d.ts +1 -0
  33. package/src/lib/utils/hooks/useAleoAutoShieldSponsoredTokens/useAleoAutoShieldSponsoredTokens.cjs +263 -0
  34. package/src/lib/utils/hooks/useAleoAutoShieldSponsoredTokens/useAleoAutoShieldSponsoredTokens.d.ts +59 -0
  35. package/src/lib/utils/hooks/useAleoAutoShieldSponsoredTokens/useAleoAutoShieldSponsoredTokens.js +259 -0
  36. package/src/lib/utils/hooks/useAleoShieldedBalances/index.d.ts +1 -0
  37. package/src/lib/utils/hooks/useAleoShieldedBalances/useAleoShieldedBalances.cjs +443 -0
  38. package/src/lib/utils/hooks/useAleoShieldedBalances/useAleoShieldedBalances.d.ts +24 -0
  39. package/src/lib/utils/hooks/useAleoShieldedBalances/useAleoShieldedBalances.js +439 -0
  40. package/src/lib/utils/hooks/useEmbeddedWallet/useEmbeddedWallet.cjs +1 -0
  41. package/src/lib/utils/hooks/useEmbeddedWallet/useEmbeddedWallet.d.ts +1 -0
  42. package/src/lib/utils/hooks/useEmbeddedWallet/useEmbeddedWallet.js +1 -0
  43. package/src/lib/views/BackupUnsuccessfulView/BackupUnsuccessfulView.cjs +12 -1
  44. package/src/lib/views/BackupUnsuccessfulView/BackupUnsuccessfulView.js +12 -1
  45. package/src/lib/views/SendBalanceView/SendBalanceView.cjs +53 -0
  46. package/src/lib/views/SendBalanceView/SendBalanceView.js +53 -0
  47. package/src/lib/widgets/DynamicWidget/components/ActiveMidnightWalletBalance/ActiveMidnightWalletBalance.cjs +193 -0
  48. package/src/lib/widgets/DynamicWidget/components/ActiveMidnightWalletBalance/ActiveMidnightWalletBalance.d.ts +7 -0
  49. package/src/lib/widgets/DynamicWidget/components/ActiveMidnightWalletBalance/ActiveMidnightWalletBalance.js +189 -0
  50. package/src/lib/widgets/DynamicWidget/components/ActiveMidnightWalletBalance/index.d.ts +1 -0
  51. package/src/lib/widgets/DynamicWidget/components/ActiveWalletBalance/ActiveWalletBalance.cjs +216 -11
  52. package/src/lib/widgets/DynamicWidget/components/ActiveWalletBalance/ActiveWalletBalance.js +216 -11
  53. package/src/lib/widgets/DynamicWidget/components/ActiveWalletBalance/TokenBalanceItem/TokenBalanceItem.cjs +5 -2
  54. package/src/lib/widgets/DynamicWidget/components/ActiveWalletBalance/TokenBalanceItem/TokenBalanceItem.d.ts +10 -1
  55. package/src/lib/widgets/DynamicWidget/components/ActiveWalletBalance/TokenBalanceItem/TokenBalanceItem.js +5 -2
  56. package/src/lib/widgets/DynamicWidget/components/ActiveWalletBalance/TokenBalanceItem/index.d.ts +1 -0
  57. package/src/lib/widgets/DynamicWidget/components/ActiveWalletBalance/TokenBalanceList/TokenBalanceList.cjs +2 -2
  58. package/src/lib/widgets/DynamicWidget/components/ActiveWalletBalance/TokenBalanceList/TokenBalanceList.d.ts +3 -1
  59. package/src/lib/widgets/DynamicWidget/components/ActiveWalletBalance/TokenBalanceList/TokenBalanceList.js +2 -2
  60. package/src/lib/widgets/DynamicWidget/components/ActiveWalletInformation/ActiveMidnightWalletAddresses/ActiveMidnightWalletAddresses.cjs +124 -0
  61. package/src/lib/widgets/DynamicWidget/components/ActiveWalletInformation/ActiveMidnightWalletAddresses/ActiveMidnightWalletAddresses.d.ts +9 -0
  62. package/src/lib/widgets/DynamicWidget/components/ActiveWalletInformation/ActiveMidnightWalletAddresses/ActiveMidnightWalletAddresses.js +120 -0
  63. package/src/lib/widgets/DynamicWidget/components/ActiveWalletInformation/ActiveMidnightWalletAddresses/index.d.ts +1 -0
  64. package/src/lib/widgets/DynamicWidget/components/ActiveWalletInformation/ActiveWalletInformation.cjs +21 -10
  65. package/src/lib/widgets/DynamicWidget/components/ActiveWalletInformation/ActiveWalletInformation.js +22 -11
  66. package/src/lib/widgets/DynamicWidget/components/WalletDetailsCard/WalletDetailsCard.cjs +22 -2
  67. package/src/lib/widgets/DynamicWidget/components/WalletDetailsCard/WalletDetailsCard.d.ts +8 -1
  68. package/src/lib/widgets/DynamicWidget/components/WalletDetailsCard/WalletDetailsCard.js +23 -3
@@ -0,0 +1,443 @@
1
+ 'use client'
2
+ 'use strict';
3
+
4
+ Object.defineProperty(exports, '__esModule', { value: true });
5
+
6
+ var _tslib = require('../../../../../_virtual/_tslib.cjs');
7
+ var React = require('react');
8
+ var sdkApiCore = require('@dynamic-labs/sdk-api-core');
9
+ require('../../../context/DynamicContext/DynamicContext.cjs');
10
+ require('../../../store/state/loadingAndLifecycle/loadingAndLifecycle.cjs');
11
+ require('@dynamic-labs/iconic');
12
+ require('@dynamic-labs/wallet-connector-core');
13
+ require('react/jsx-runtime');
14
+ require('../../../context/ViewContext/ViewContext.cjs');
15
+ require('../../../shared/logger.cjs');
16
+ require('@dynamic-labs/wallet-book');
17
+ require('@dynamic-labs/utils');
18
+ require('../../constants/colors.cjs');
19
+ require('../../constants/values.cjs');
20
+ require('../../../shared/consts/index.cjs');
21
+ require('../../../events/dynamicEvents.cjs');
22
+ require('../../../context/CaptchaContext/CaptchaContext.cjs');
23
+ require('../../../context/ErrorContext/ErrorContext.cjs');
24
+ require('@dynamic-labs/multi-wallet');
25
+ require('react-international-phone');
26
+ require('../../../store/state/nonce/nonce.cjs');
27
+ require('@dynamic-labs-sdk/client/core');
28
+ require('eventemitter3');
29
+ require('@dynamic-labs-sdk/client');
30
+ require('../../../config/ApiEndpoint.cjs');
31
+ require('@dynamic-labs/locale');
32
+ var dynamicContextProps = require('../../../store/state/dynamicContextProps/dynamicContextProps.cjs');
33
+ require('../../../store/state/primaryWalletId/primaryWalletId.cjs');
34
+ require('../../../store/state/connectedWalletsInfo/connectedWalletsInfo.cjs');
35
+ require('../../functions/getWaasAddressTypeLabel/getWaasAddressTypeLabel.cjs');
36
+ require('../../../context/AccessDeniedContext/AccessDeniedContext.cjs');
37
+ require('../../../context/AccountExistsContext/AccountExistsContext.cjs');
38
+ require('../../../context/UserWalletsContext/UserWalletsContext.cjs');
39
+ require('../../../store/state/authMode/authMode.cjs');
40
+ require('../../../context/VerificationContext/VerificationContext.cjs');
41
+ require('react-dom');
42
+ require('../../functions/compareChains/compareChains.cjs');
43
+ require('../../../views/Passkey/utils/findPrimaryEmbeddedChain/findPrimaryEmbeddedChain.cjs');
44
+ require('../../../context/ThemeContext/ThemeContext.cjs');
45
+ require('../useUserUpdateRequest/useUpdateUser/userFieldsSchema.cjs');
46
+ require('bs58');
47
+ require('@dynamic-labs/types');
48
+ require('../../../context/SocialRedirectContext/SocialRedirectContext.cjs');
49
+ require('../../../context/LoadingContext/LoadingContext.cjs');
50
+ require('../../../context/WalletContext/WalletContext.cjs');
51
+ require('../useEmbeddedWallet/useSecureEnclaveEmbeddedWallet/constants.cjs');
52
+ require('yup');
53
+ require('../../../context/MockContext/MockContext.cjs');
54
+ require('../../../views/CollectUserDataView/useFields.cjs');
55
+ require('../../../context/FieldsStateContext/FieldsStateContext.cjs');
56
+ require('../../../context/UserFieldEditorContext/UserFieldEditorContext.cjs');
57
+ require('@dynamic-labs/rpc-providers');
58
+ require('../../../store/state/walletOptions/walletOptions.cjs');
59
+ require('react-i18next');
60
+ require('../../../components/Accordion/components/AccordionItem/AccordionItem.cjs');
61
+ require('../../../components/Alert/Alert.cjs');
62
+ require('../../../components/ShadowDOM/ShadowDOM.cjs');
63
+ require('../../../components/IconButton/IconButton.cjs');
64
+ require('../../../components/InlineWidget/InlineWidget.cjs');
65
+ require('../../../components/Input/Input.cjs');
66
+ require('../../../components/IsBrowser/IsBrowser.cjs');
67
+ require('../../../components/MenuList/Dropdown/Dropdown.cjs');
68
+ require('../../../components/OverlayCard/OverlayCard.cjs');
69
+ require('../../../components/Transition/ZoomTransition/ZoomTransition.cjs');
70
+ require('../../../components/Transition/SlideInUpTransition/SlideInUpTransition.cjs');
71
+ require('../../../components/Transition/OpacityTransition/OpacityTransition.cjs');
72
+ require('../../../components/PasskeyCreatedSuccessBanner/PasskeyCreatedSuccessBanner.cjs');
73
+ require('../../../components/Popper/Popper/Popper.cjs');
74
+ require('../../../components/Popper/PopperContext/PopperContext.cjs');
75
+ require('react-focus-lock');
76
+ require('qrcode');
77
+ require('formik');
78
+ require('../useSubdomainCheck/useSubdomainCheck.cjs');
79
+ require('../../../context/WalletGroupContext/WalletGroupContext.cjs');
80
+ require('../../../widgets/DynamicWidget/context/DynamicWidgetContext.cjs');
81
+ require('../useGetMfaToken/useGetMfaToken.cjs');
82
+ require('../useWalletBackup/useWalletBackup.cjs');
83
+ require('../useWalletBackup/types.cjs');
84
+ require('../useWalletBackup/cloudProviders.cjs');
85
+ require('../../../context/IpConfigurationContext/IpConfigurationContext.cjs');
86
+ require('../../../context/ConnectWithOtpContext/ConnectWithOtpContext.cjs');
87
+ require('../../../widgets/DynamicBridgeWidget/views/WalletsView/components/SecondaryWallets/SecondaryWallets.cjs');
88
+ require('@hcaptcha/react-hcaptcha');
89
+ require('../../../widgets/DynamicWidget/helpers/convertExchangeKeyAndProviderEnum.cjs');
90
+ require('../../../views/ExchangeWhitelistWarning/ExchangeWhitelistWarning.cjs');
91
+ require('../../../context/ErrorContext/hooks/useErrorText/useErrorText.cjs');
92
+ require('../../../context/FooterAnimationContext/index.cjs');
93
+ require('../../../views/MfaChooseDeviceView/useGetMfaOptions/useGetMfaOptions.cjs');
94
+ require('../../../context/PasskeyContext/PasskeyContext.cjs');
95
+ require('../../../context/OnrampContext/OnrampContext.cjs');
96
+ require('../../../store/state/sendBalances.cjs');
97
+ require('../../../store/state/connectorsInitializing/connectorsInitializing.cjs');
98
+ require('../../../components/OverlayCardBase/OverlayCardTarget/OverlayCardTarget.cjs');
99
+ require('../../../widgets/DynamicWidget/components/DynamicWidgetHeader/DynamicWidgetHeader.cjs');
100
+ require('../../../views/TransactionConfirmationView/TransactionConfirmationView.cjs');
101
+ require('../../../widgets/DynamicWidget/components/PasskeyCard/PasskeyCard.cjs');
102
+ require('../../../widgets/DynamicWidget/views/CryptoComOnramp/CryptoComOnramp.cjs');
103
+ require('../../../../index.cjs');
104
+ require('../../../widgets/DynamicWidget/views/ManagePasskeysMfaWidgetView/ManagePasskeysMfaWidgetView.cjs');
105
+ require('../../../widgets/DynamicWidget/views/ManageTotpMfaWidgetView/ManageTotpMfaWidgetView.cjs');
106
+ require('../../../widgets/DynamicWidget/views/ReceiveWalletFunds/ReceiveWalletFunds.cjs');
107
+ require('../../../store/state/tokenBalances.cjs');
108
+ require('../../../store/state/multichainBalances.cjs');
109
+ require('@dynamic-labs/store');
110
+ require('../../../shared/utils/functions/getInitialUrl/getInitialUrl.cjs');
111
+ var useInternalDynamicContext = require('../../../context/DynamicContext/useDynamicContext/useInternalDynamicContext/useInternalDynamicContext.cjs');
112
+ var getAleoCuratedPrices = require('../../../data/api/aleo/getAleoCuratedPrices.cjs');
113
+
114
+ const MICROCREDITS_PER_CREDIT = 1000000;
115
+ const ALEO_CREDITS_LOGO = 'https://app.dynamic.xyz/assets/networks/aleo.svg';
116
+ // Generic dark "?" token icon — matches redcoast's `DEFAULT_TOKEN_LOGO_URI`
117
+ // used by the multichain endpoint when an unshielded token has no curated
118
+ // logo. Reusing it here keeps the Shielded tab visually consistent with
119
+ // the Unshielded tab for the same token.
120
+ const UNKNOWN_TOKEN_LOGO = 'https://app.dynamic.xyz/assets/tokens/unknown.svg';
121
+ const TOKEN_REGISTRY_PROGRAM = 'token_registry.aleo';
122
+ const TOKEN_REGISTRY_RECORD = 'Token';
123
+ // Non-credits tokens deliberately omit `logoURI` — Aleo doesn't have a
124
+ // curated icon list yet, so leaving it undefined surfaces the widget's
125
+ // generic placeholder (`?` skeleton) consistent with the unshielded feed.
126
+ const KNOWN_SHIELDED_TOKENS = [
127
+ {
128
+ contractAddress: 'usad_stablecoin.aleo',
129
+ decimals: 6,
130
+ name: 'USAD',
131
+ programName: 'usad_stablecoin.aleo',
132
+ recordName: 'Token',
133
+ symbol: 'USAD',
134
+ },
135
+ {
136
+ contractAddress: 'test_usad_stablecoin.aleo',
137
+ decimals: 6,
138
+ name: 'USAD',
139
+ programName: 'test_usad_stablecoin.aleo',
140
+ recordName: 'Token',
141
+ symbol: 'USAD',
142
+ },
143
+ {
144
+ contractAddress: 'usdcx_stablecoin.aleo',
145
+ decimals: 6,
146
+ name: 'USDCx',
147
+ programName: 'usdcx_stablecoin.aleo',
148
+ recordName: 'Token',
149
+ symbol: 'USDCx',
150
+ },
151
+ {
152
+ contractAddress: 'test_usdcx_stablecoin.aleo',
153
+ decimals: 6,
154
+ name: 'USDCx',
155
+ programName: 'test_usdcx_stablecoin.aleo',
156
+ recordName: 'Token',
157
+ symbol: 'USDCx',
158
+ },
159
+ // ARC-21 (Hyperlane warp routes) — mainnet only. Token IDs match the
160
+ // values pinned in `packages/aleo/src/utils/aleoSendableTokens` and the
161
+ // redcoast `aleoArc21Tokens` registry. Decimals match each token's
162
+ // `token_info` metadata on-chain.
163
+ {
164
+ contractAddress: 'hyp_warp_token_sol.aleo',
165
+ decimals: 9,
166
+ name: 'Wrapped SOL',
167
+ programName: TOKEN_REGISTRY_PROGRAM,
168
+ recordName: TOKEN_REGISTRY_RECORD,
169
+ symbol: 'wSOL',
170
+ tokenId: '2045969100091121326225168054634646230244820821909676777152465722877810201564field',
171
+ },
172
+ {
173
+ contractAddress: 'hyp_warp_token_eth.aleo',
174
+ decimals: 18,
175
+ name: 'Wrapped ETH',
176
+ programName: TOKEN_REGISTRY_PROGRAM,
177
+ recordName: TOKEN_REGISTRY_RECORD,
178
+ symbol: 'wETH',
179
+ tokenId: '8189585964265444162798552221009403350643900573290534096996249214099143169251field',
180
+ },
181
+ {
182
+ contractAddress: 'hyp_warp_token_wbtc.aleo',
183
+ decimals: 8,
184
+ name: 'Wrapped BTC',
185
+ programName: TOKEN_REGISTRY_PROGRAM,
186
+ recordName: TOKEN_REGISTRY_RECORD,
187
+ symbol: 'wBTC',
188
+ tokenId: '3491859903473482085250871387962132231204352466326026409883548131580582527809field',
189
+ },
190
+ {
191
+ contractAddress: 'hyp_warp_token_usdt.aleo',
192
+ decimals: 6,
193
+ name: 'Tether USD',
194
+ programName: TOKEN_REGISTRY_PROGRAM,
195
+ recordName: TOKEN_REGISTRY_RECORD,
196
+ symbol: 'USDT',
197
+ tokenId: '7881654794448182580124231856035865816599796419758925654292946277940935117913field',
198
+ },
199
+ {
200
+ contractAddress: 'hyp_warp_token_usdc.aleo',
201
+ decimals: 6,
202
+ name: 'USD Coin',
203
+ programName: TOKEN_REGISTRY_PROGRAM,
204
+ recordName: TOKEN_REGISTRY_RECORD,
205
+ symbol: 'USDC',
206
+ tokenId: '4697275201844475848710842677807162058146139844643350200269139278887318953049field',
207
+ },
208
+ ];
209
+ /**
210
+ * Match a record to a shielded-token spec. Stablecoins match on
211
+ * (program, record); ARC-21 entries additionally require the spec's
212
+ * `tokenId` to appear inside `record_plaintext` (since every ARC-21 token
213
+ * shares `token_registry.aleo / Token`).
214
+ */
215
+ const findTokenSpec = (record) => {
216
+ for (const spec of KNOWN_SHIELDED_TOKENS) {
217
+ if (record.program_name !== spec.programName)
218
+ continue;
219
+ if (record.record_name !== spec.recordName)
220
+ continue;
221
+ if (spec.tokenId) {
222
+ if (typeof record.record_plaintext !== 'string' ||
223
+ !record.record_plaintext.includes(`token_id: ${spec.tokenId}`)) {
224
+ continue;
225
+ }
226
+ }
227
+ return spec;
228
+ }
229
+ return undefined;
230
+ };
231
+ /**
232
+ * Coerces the widget-context `network` value into an Aleo network id
233
+ * (`0 = mainnet`, `1 = testnet`) and the matching param string for the
234
+ * `/waas/aleo/prices` endpoint. Pulled out of the callback to flatten
235
+ * cognitive complexity AND to avoid a SonarCloud-flagged nested
236
+ * ternary.
237
+ */
238
+ const resolveAleoNetwork = (networkKey) => {
239
+ const numeric = Number(networkKey);
240
+ const safeNetworkId = Number.isFinite(numeric) ? numeric : undefined;
241
+ if (safeNetworkId === 0)
242
+ return { aleoNetworkParam: 'mainnet', safeNetworkId };
243
+ if (safeNetworkId === 1)
244
+ return { aleoNetworkParam: 'testnet', safeNetworkId };
245
+ return { aleoNetworkParam: undefined, safeNetworkId };
246
+ };
247
+ /**
248
+ * Build a `(address, isNative) → price` lookup from the curated-prices
249
+ * endpoint response. The key shape matches the multichain balance feed
250
+ * (native ALEO at `'0x0' + isNative=true`, every other token at its
251
+ * program id + `isNative=false`) so the join is a straight read.
252
+ */
253
+ const buildPriceLookup = (priceList) => {
254
+ const priceByKey = new Map();
255
+ for (const entry of priceList) {
256
+ priceByKey.set(`${entry.address}|${entry.isNative ? 1 : 0}`, entry.price);
257
+ }
258
+ return (address, isNative) => { var _a; return (_a = priceByKey.get(`${address}|${isNative ? 1 : 0}`)) !== null && _a !== void 0 ? _a : null; };
259
+ };
260
+ /**
261
+ * Aggregate `credits.aleo / credits` records into the native ALEO
262
+ * `TokenBalance`. Returns `undefined` when the wallet owns no credits
263
+ * records so the caller can omit the row entirely.
264
+ */
265
+ const buildCreditsBalance = (records, networkId, priceFor) => {
266
+ const creditsRecords = records.filter((r) => (r === null || r === void 0 ? void 0 : r.program_name) === 'credits.aleo' &&
267
+ (r === null || r === void 0 ? void 0 : r.record_name) === 'credits' &&
268
+ typeof (r === null || r === void 0 ? void 0 : r.microcredits) === 'string');
269
+ if (creditsRecords.length === 0)
270
+ return undefined;
271
+ const totalMicrocredits = creditsRecords.reduce((sum, r) => sum + BigInt(r.microcredits), BigInt(0));
272
+ // BigInt → number for the TokenBalance shape. Aleo balances stay well
273
+ // below Number.MAX_SAFE_INTEGER for a single wallet (max u64 supply is
274
+ // 1.5B credits = 1.5e15 microcredits; Number can hold up to ~9e15).
275
+ const rawBalance = Number(totalMicrocredits);
276
+ const balance = rawBalance / MICROCREDITS_PER_CREDIT;
277
+ const price = priceFor('0x0', true);
278
+ return {
279
+ address: '0x0',
280
+ balance,
281
+ decimals: 6,
282
+ isNative: true,
283
+ logoURI: ALEO_CREDITS_LOGO,
284
+ marketValue: price !== null ? balance * price : undefined,
285
+ name: 'Aleo Credits',
286
+ networkId,
287
+ price: price !== null ? price : undefined,
288
+ rawBalance,
289
+ symbol: 'ALEO',
290
+ };
291
+ };
292
+ /**
293
+ * Aggregate stablecoin + ARC-21 `Token` records by `(program, tokenId)`
294
+ * and emit one `TokenBalance` per matched spec. Records that don't
295
+ * match a curated spec, lack an `amount`, or have a malformed amount
296
+ * string are silently skipped.
297
+ */
298
+ const buildTokenBalances = (records, networkId, priceFor) => {
299
+ var _a, _b;
300
+ const sumsByContract = new Map();
301
+ const specsByContract = new Map();
302
+ for (const r of records) {
303
+ const spec = findTokenSpec(r);
304
+ if (!spec || typeof r.amount !== 'string')
305
+ continue;
306
+ try {
307
+ const prev = (_a = sumsByContract.get(spec.contractAddress)) !== null && _a !== void 0 ? _a : BigInt(0);
308
+ sumsByContract.set(spec.contractAddress, prev + BigInt(r.amount));
309
+ specsByContract.set(spec.contractAddress, spec);
310
+ }
311
+ catch (_c) {
312
+ /* ignore — malformed amount string */
313
+ }
314
+ }
315
+ const out = [];
316
+ for (const [contractAddress, total] of sumsByContract.entries()) {
317
+ const spec = specsByContract.get(contractAddress);
318
+ if (!spec)
319
+ continue;
320
+ const rawBalance = Number(total);
321
+ const balance = rawBalance / Math.pow(10, spec.decimals);
322
+ const price = priceFor(spec.contractAddress, false);
323
+ out.push({
324
+ address: spec.contractAddress,
325
+ balance,
326
+ decimals: spec.decimals,
327
+ // Use redcoast's `DEFAULT_TOKEN_LOGO_URI` for stablecoins + ARC-21
328
+ // so they render the same dark "?" icon the Unshielded tab shows
329
+ // for these tokens (the multichain endpoint applies that fallback
330
+ // itself; we mirror it here for visual parity).
331
+ logoURI: (_b = spec.logoURI) !== null && _b !== void 0 ? _b : UNKNOWN_TOKEN_LOGO,
332
+ marketValue: price !== null ? balance * price : undefined,
333
+ name: spec.name,
334
+ networkId,
335
+ price: price !== null ? price : undefined,
336
+ rawBalance,
337
+ symbol: spec.symbol,
338
+ });
339
+ }
340
+ return out;
341
+ };
342
+ /**
343
+ * Hook that returns the active wallet's shielded (private) Aleo token
344
+ * balances as a `TokenBalance[]` so the widget can render them through the
345
+ * same TokenBalanceList path it uses for unshielded balances.
346
+ *
347
+ * - Records come from the iframe via `connector.listOwnedRecords()` (the
348
+ * Provable RecordScanner; view key never leaves the iframe).
349
+ * - Aggregates `credits.aleo/credits` (sum `microcredits` → ALEO) plus any
350
+ * tier-3 stablecoin Token records (sum `amount` per program → USAD/USDCx).
351
+ * ARC-21 multi-token grouped-by-`token_id` is Phase 2B.
352
+ *
353
+ * Returns an empty list when:
354
+ * - The wallet isn't Aleo
355
+ * - The connector doesn't expose `listOwnedRecords` (e.g. external Aleo wallet)
356
+ * - The user owns no records that match a known program/record pair
357
+ */
358
+ const useAleoShieldedBalances = () => {
359
+ const { primaryWallet, network } = useInternalDynamicContext.useInternalDynamicContext();
360
+ const [tokenBalances, setTokenBalances] = React.useState([]);
361
+ const [isLoading, setIsLoading] = React.useState(false);
362
+ const [error, setError] = React.useState();
363
+ const connector = primaryWallet === null || primaryWallet === void 0 ? void 0 : primaryWallet.connector;
364
+ const isAleo = (connector === null || connector === void 0 ? void 0 : connector.connectedChain) === sdkApiCore.ChainEnum.Aleo;
365
+ const supportsShielded = isAleo &&
366
+ typeof (connector === null || connector === void 0 ? void 0 : connector.listOwnedRecords) === 'function';
367
+ // Mirror the live connector into a ref so `fetchShielded` can read it
368
+ // without depending on the (often unstable) object reference. Some test
369
+ // setups mock context with a factory that returns a fresh `primaryWallet`
370
+ // every render — depending on that ref directly turned this into an
371
+ // infinite render loop.
372
+ const connectorRef = React.useRef(connector);
373
+ connectorRef.current = connector;
374
+ const connectorKey = connector === null || connector === void 0 ? void 0 : connector.key;
375
+ const networkKey = network !== undefined && network !== null ? String(network) : undefined;
376
+ const fetchShielded = React.useCallback(() => _tslib.__awaiter(void 0, void 0, void 0, function* () {
377
+ var _a;
378
+ const liveConnector = connectorRef.current;
379
+ if (!supportsShielded || !liveConnector) {
380
+ setTokenBalances((prev) => (prev.length === 0 ? prev : []));
381
+ return;
382
+ }
383
+ setIsLoading(true);
384
+ setError(undefined);
385
+ try {
386
+ // Fetch records and the curated-token price list in parallel. The
387
+ // price list comes from the Aleo-only `/waas/aleo/prices` endpoint
388
+ // (independent of balance) so the join works even when the user
389
+ // holds a shielded token with zero unshielded balance — the
390
+ // multichain `/accountBalances` endpoint would have stripped that
391
+ // token row, leaving the widget with no price source. Prices are
392
+ // best-effort: a failure leaves balances unpriced rather than
393
+ // dropping the shielded list entirely.
394
+ const { safeNetworkId, aleoNetworkParam } = resolveAleoNetwork(networkKey);
395
+ const environmentId = dynamicContextProps.getEnvironmentId();
396
+ const shouldFetchPrices = Boolean(aleoNetworkParam && environmentId);
397
+ const [result, priceList] = yield Promise.all([
398
+ liveConnector.listOwnedRecords(),
399
+ shouldFetchPrices && aleoNetworkParam
400
+ ? getAleoCuratedPrices.getAleoCuratedPrices({
401
+ environmentId,
402
+ network: aleoNetworkParam,
403
+ }).catch(() => [])
404
+ : Promise.resolve([]),
405
+ ]);
406
+ const records = (_a = result === null || result === void 0 ? void 0 : result.records) !== null && _a !== void 0 ? _a : [];
407
+ const priceFor = buildPriceLookup(priceList);
408
+ const balances = [];
409
+ const credits = buildCreditsBalance(records, safeNetworkId, priceFor);
410
+ if (credits)
411
+ balances.push(credits);
412
+ balances.push(...buildTokenBalances(records, safeNetworkId, priceFor));
413
+ setTokenBalances(balances);
414
+ }
415
+ catch (err) {
416
+ const msg = err instanceof Error ? err.message : String(err);
417
+ setError(msg);
418
+ setTokenBalances((prev) => (prev.length === 0 ? prev : []));
419
+ }
420
+ finally {
421
+ setIsLoading(false);
422
+ }
423
+ }), [connectorKey, networkKey, supportsShielded]);
424
+ React.useEffect(() => {
425
+ if (!supportsShielded) {
426
+ setTokenBalances((prev) => (prev.length === 0 ? prev : []));
427
+ return;
428
+ }
429
+ fetchShielded().catch(() => {
430
+ // fetchShielded already records the error in component state;
431
+ // the .catch keeps the fire-and-forget shape lint-clean.
432
+ });
433
+ }, [supportsShielded, fetchShielded]);
434
+ return {
435
+ error,
436
+ isLoading,
437
+ refetch: fetchShielded,
438
+ supportsShielded,
439
+ tokenBalances,
440
+ };
441
+ };
442
+
443
+ exports.useAleoShieldedBalances = useAleoShieldedBalances;
@@ -0,0 +1,24 @@
1
+ import { TokenBalance } from '@dynamic-labs/sdk-api-core';
2
+ /**
3
+ * Hook that returns the active wallet's shielded (private) Aleo token
4
+ * balances as a `TokenBalance[]` so the widget can render them through the
5
+ * same TokenBalanceList path it uses for unshielded balances.
6
+ *
7
+ * - Records come from the iframe via `connector.listOwnedRecords()` (the
8
+ * Provable RecordScanner; view key never leaves the iframe).
9
+ * - Aggregates `credits.aleo/credits` (sum `microcredits` → ALEO) plus any
10
+ * tier-3 stablecoin Token records (sum `amount` per program → USAD/USDCx).
11
+ * ARC-21 multi-token grouped-by-`token_id` is Phase 2B.
12
+ *
13
+ * Returns an empty list when:
14
+ * - The wallet isn't Aleo
15
+ * - The connector doesn't expose `listOwnedRecords` (e.g. external Aleo wallet)
16
+ * - The user owns no records that match a known program/record pair
17
+ */
18
+ export declare const useAleoShieldedBalances: () => {
19
+ tokenBalances: TokenBalance[];
20
+ isLoading: boolean;
21
+ error: string | undefined;
22
+ refetch: () => Promise<void>;
23
+ supportsShielded: boolean;
24
+ };