@hsuite/native-connect-angular 2.1.0 → 2.1.1

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 (183) hide show
  1. package/coverage/coverage-summary.json +25 -21
  2. package/coverage/index.html +108 -108
  3. package/coverage/lcov-report/index.html +108 -108
  4. package/coverage/lcov-report/lib/components/account-selector/account-actions/account-actions.component.ts.html +1 -1
  5. package/coverage/lcov-report/lib/components/account-selector/account-actions/index.html +1 -1
  6. package/coverage/lcov-report/lib/components/account-selector/account-filter/account-filter.component.ts.html +1 -1
  7. package/coverage/lcov-report/lib/components/account-selector/account-filter/index.html +1 -1
  8. package/coverage/lcov-report/lib/components/account-selector/account-formatting.service.ts.html +13 -19
  9. package/coverage/lcov-report/lib/components/account-selector/account-grouping.service.ts.html +1 -1
  10. package/coverage/lcov-report/lib/components/account-selector/account-list/account-list.component.ts.html +1 -1
  11. package/coverage/lcov-report/lib/components/account-selector/account-list/index.html +1 -1
  12. package/coverage/lcov-report/lib/components/account-selector/account-selector.component.ts.html +1 -1
  13. package/coverage/lcov-report/lib/components/account-selector/account-selector.service.ts.html +1 -1
  14. package/coverage/lcov-report/lib/components/account-selector/index.html +5 -5
  15. package/coverage/lcov-report/lib/components/wallet-account-display/index.html +1 -1
  16. package/coverage/lcov-report/lib/components/wallet-account-display/wallet-account-display.component.ts.html +10 -10
  17. package/coverage/lcov-report/lib/components/wallet-connect-button/index.html +1 -1
  18. package/coverage/lcov-report/lib/components/wallet-connect-button/wallet-connect-button.component.ts.html +1 -1
  19. package/coverage/lcov-report/lib/components/wallet-connect-prompt/index.html +1 -1
  20. package/coverage/lcov-report/lib/components/wallet-connect-prompt/wallet-connect-prompt.component.ts.html +1 -1
  21. package/coverage/lcov-report/lib/components/wallet-connected-guard/index.html +1 -1
  22. package/coverage/lcov-report/lib/components/wallet-connected-guard/wallet-connected-guard.component.ts.html +1 -1
  23. package/coverage/lcov-report/lib/components/wallet-connection-modal/connection-method-step/connection-method-step.component.ts.html +1 -1
  24. package/coverage/lcov-report/lib/components/wallet-connection-modal/connection-method-step/index.html +1 -1
  25. package/coverage/lcov-report/lib/components/wallet-connection-modal/index.html +15 -15
  26. package/coverage/lcov-report/lib/components/wallet-connection-modal/qr-pairing-step/index.html +1 -1
  27. package/coverage/lcov-report/lib/components/wallet-connection-modal/qr-pairing-step/qr-pairing-step.component.ts.html +1 -1
  28. package/coverage/lcov-report/lib/components/wallet-connection-modal/wallet-connection-modal.component.ts.html +84 -36
  29. package/coverage/lcov-report/lib/components/wallet-session-display/index.html +1 -1
  30. package/coverage/lcov-report/lib/components/wallet-session-display/wallet-session-display.component.ts.html +1 -1
  31. package/coverage/lcov-report/lib/components/wallet-transaction-status/index.html +1 -1
  32. package/coverage/lcov-report/lib/components/wallet-transaction-status/wallet-transaction-status.component.ts.html +1 -1
  33. package/coverage/lcov-report/lib/directives/index.html +1 -1
  34. package/coverage/lcov-report/lib/directives/wallet-connected.directive.ts.html +1 -1
  35. package/coverage/lcov-report/lib/directives/wallet-context.directive.ts.html +1 -1
  36. package/coverage/lcov-report/lib/directives/wallet-events.directive.ts.html +1 -1
  37. package/coverage/lcov-report/lib/hsuite-wallet.module.ts.html +1 -1
  38. package/coverage/lcov-report/lib/index.html +1 -1
  39. package/coverage/lcov-report/lib/models/connection-config.model.ts.html +1 -1
  40. package/coverage/lcov-report/lib/models/index.html +7 -7
  41. package/coverage/lcov-report/lib/models/provider-types.ts.html +11 -5
  42. package/coverage/lcov-report/lib/providers/base-wallet-provider.ts.html +20 -20
  43. package/coverage/lcov-report/lib/providers/hsuite-native/channel-client.service.ts.html +639 -636
  44. package/coverage/lcov-report/lib/providers/hsuite-native/index.html +19 -19
  45. package/coverage/lcov-report/lib/providers/hsuite-native-provider.ts.html +1 -1
  46. package/coverage/lcov-report/lib/providers/index.html +18 -18
  47. package/coverage/lcov-report/lib/providers/p2p-native/index.html +22 -22
  48. package/coverage/lcov-report/lib/providers/p2p-native/p2p-native.provider.ts.html +993 -993
  49. package/coverage/lcov-report/lib/providers/p2p-native/p2p-session-manager.ts.html +7 -4
  50. package/coverage/lcov-report/lib/providers/wallet-error-handler.ts.html +1 -1
  51. package/coverage/lcov-report/lib/providers/walletconnect/core/index.html +65 -65
  52. package/coverage/lcov-report/lib/providers/walletconnect/core/session-health.ts.html +240 -240
  53. package/coverage/lcov-report/lib/providers/walletconnect/core/walletconnect-client-manager.ts.html +559 -559
  54. package/coverage/lcov-report/lib/providers/walletconnect/core/walletconnect-provider.ts.html +1108 -1105
  55. package/coverage/lcov-report/lib/providers/walletconnect/core/walletconnect-session-store.ts.html +493 -493
  56. package/coverage/lcov-report/lib/providers/walletconnect/core/walletconnect-signing-orchestrator.ts.html +366 -366
  57. package/coverage/lcov-report/lib/providers/walletconnect/signers/hedera-signer.ts.html +730 -730
  58. package/coverage/lcov-report/lib/providers/walletconnect/signers/index.html +43 -43
  59. package/coverage/lcov-report/lib/providers/walletconnect/signers/signer-factory.ts.html +234 -234
  60. package/coverage/lcov-report/lib/providers/walletconnect/signers/xrpl-signer.ts.html +650 -650
  61. package/coverage/lcov-report/lib/services/hsuite-auth.interceptor.ts.html +568 -0
  62. package/coverage/lcov-report/lib/services/index.html +50 -20
  63. package/coverage/lcov-report/lib/services/logger.service.ts.html +1 -1
  64. package/coverage/lcov-report/lib/services/smart-session.service.ts.html +1264 -0
  65. package/coverage/lcov-report/lib/services/transaction-builders/active-account-source.ts.html +250 -0
  66. package/coverage/lcov-report/lib/services/transaction-builders/base-transaction-builder.service.ts.html +1 -1
  67. package/coverage/lcov-report/lib/services/transaction-builders/hedera-amount-utils.ts.html +155 -155
  68. package/coverage/lcov-report/lib/services/transaction-builders/hedera-transaction-builder.service.ts.html +2156 -2156
  69. package/coverage/lcov-report/lib/services/transaction-builders/index.html +58 -43
  70. package/coverage/lcov-report/lib/services/transaction-builders/xrpl-transaction-builder.service.ts.html +1674 -1674
  71. package/coverage/lcov-report/lib/services/transaction.service.ts.html +4 -4
  72. package/coverage/lcov-report/lib/services/unified-wallet.service.ts.html +3 -3
  73. package/coverage/lcov-report/lib/services/wallet-context.service.ts.html +1 -1
  74. package/coverage/lcov-report/lib/services/wallet-event-bus.service.ts.html +249 -249
  75. package/coverage/lcov-report/lib/services/wallet-providers.service.ts.html +1 -1
  76. package/coverage/lcov-report/lib/transports/chrome-extension-transport.ts.html +1 -1
  77. package/coverage/lcov-report/lib/transports/index.html +1 -1
  78. package/coverage/lcov-report/lib/utils/index.html +36 -21
  79. package/coverage/lcov-report/lib/utils/ledger-icons.util.ts.html +254 -161
  80. package/coverage/lcov-report/lib/utils/ledger-ui-registry.ts.html +676 -0
  81. package/coverage/lcov.info +8567 -6896
  82. package/coverage/lib/components/account-selector/account-actions/account-actions.component.ts.html +1 -1
  83. package/coverage/lib/components/account-selector/account-actions/index.html +1 -1
  84. package/coverage/lib/components/account-selector/account-filter/account-filter.component.ts.html +1 -1
  85. package/coverage/lib/components/account-selector/account-filter/index.html +1 -1
  86. package/coverage/lib/components/account-selector/account-formatting.service.ts.html +13 -19
  87. package/coverage/lib/components/account-selector/account-grouping.service.ts.html +1 -1
  88. package/coverage/lib/components/account-selector/account-list/account-list.component.ts.html +1 -1
  89. package/coverage/lib/components/account-selector/account-list/index.html +1 -1
  90. package/coverage/lib/components/account-selector/account-selector.component.ts.html +1 -1
  91. package/coverage/lib/components/account-selector/account-selector.service.ts.html +1 -1
  92. package/coverage/lib/components/account-selector/index.html +5 -5
  93. package/coverage/lib/components/wallet-account-display/index.html +1 -1
  94. package/coverage/lib/components/wallet-account-display/wallet-account-display.component.ts.html +10 -10
  95. package/coverage/lib/components/wallet-connect-button/index.html +1 -1
  96. package/coverage/lib/components/wallet-connect-button/wallet-connect-button.component.ts.html +1 -1
  97. package/coverage/lib/components/wallet-connect-prompt/index.html +1 -1
  98. package/coverage/lib/components/wallet-connect-prompt/wallet-connect-prompt.component.ts.html +1 -1
  99. package/coverage/lib/components/wallet-connected-guard/index.html +1 -1
  100. package/coverage/lib/components/wallet-connected-guard/wallet-connected-guard.component.ts.html +1 -1
  101. package/coverage/lib/components/wallet-connection-modal/connection-method-step/connection-method-step.component.ts.html +1 -1
  102. package/coverage/lib/components/wallet-connection-modal/connection-method-step/index.html +1 -1
  103. package/coverage/lib/components/wallet-connection-modal/index.html +15 -15
  104. package/coverage/lib/components/wallet-connection-modal/qr-pairing-step/index.html +1 -1
  105. package/coverage/lib/components/wallet-connection-modal/qr-pairing-step/qr-pairing-step.component.ts.html +1 -1
  106. package/coverage/lib/components/wallet-connection-modal/wallet-connection-modal.component.ts.html +84 -36
  107. package/coverage/lib/components/wallet-session-display/index.html +1 -1
  108. package/coverage/lib/components/wallet-session-display/wallet-session-display.component.ts.html +1 -1
  109. package/coverage/lib/components/wallet-transaction-status/index.html +1 -1
  110. package/coverage/lib/components/wallet-transaction-status/wallet-transaction-status.component.ts.html +1 -1
  111. package/coverage/lib/directives/index.html +1 -1
  112. package/coverage/lib/directives/wallet-connected.directive.ts.html +1 -1
  113. package/coverage/lib/directives/wallet-context.directive.ts.html +1 -1
  114. package/coverage/lib/directives/wallet-events.directive.ts.html +1 -1
  115. package/coverage/lib/hsuite-wallet.module.ts.html +1 -1
  116. package/coverage/lib/index.html +1 -1
  117. package/coverage/lib/models/connection-config.model.ts.html +1 -1
  118. package/coverage/lib/models/index.html +7 -7
  119. package/coverage/lib/models/provider-types.ts.html +11 -5
  120. package/coverage/lib/providers/base-wallet-provider.ts.html +20 -20
  121. package/coverage/lib/providers/hsuite-native/channel-client.service.ts.html +639 -636
  122. package/coverage/lib/providers/hsuite-native/index.html +19 -19
  123. package/coverage/lib/providers/hsuite-native-provider.ts.html +1 -1
  124. package/coverage/lib/providers/index.html +18 -18
  125. package/coverage/lib/providers/p2p-native/index.html +22 -22
  126. package/coverage/lib/providers/p2p-native/p2p-native.provider.ts.html +993 -993
  127. package/coverage/lib/providers/p2p-native/p2p-session-manager.ts.html +7 -4
  128. package/coverage/lib/providers/wallet-error-handler.ts.html +1 -1
  129. package/coverage/lib/providers/walletconnect/core/index.html +65 -65
  130. package/coverage/lib/providers/walletconnect/core/session-health.ts.html +240 -240
  131. package/coverage/lib/providers/walletconnect/core/walletconnect-client-manager.ts.html +559 -559
  132. package/coverage/lib/providers/walletconnect/core/walletconnect-provider.ts.html +1108 -1105
  133. package/coverage/lib/providers/walletconnect/core/walletconnect-session-store.ts.html +493 -493
  134. package/coverage/lib/providers/walletconnect/core/walletconnect-signing-orchestrator.ts.html +366 -366
  135. package/coverage/lib/providers/walletconnect/signers/hedera-signer.ts.html +730 -730
  136. package/coverage/lib/providers/walletconnect/signers/index.html +43 -43
  137. package/coverage/lib/providers/walletconnect/signers/signer-factory.ts.html +234 -234
  138. package/coverage/lib/providers/walletconnect/signers/xrpl-signer.ts.html +650 -650
  139. package/coverage/lib/services/hsuite-auth.interceptor.ts.html +568 -0
  140. package/coverage/lib/services/index.html +50 -20
  141. package/coverage/lib/services/logger.service.ts.html +1 -1
  142. package/coverage/lib/services/smart-session.service.ts.html +1264 -0
  143. package/coverage/lib/services/transaction-builders/active-account-source.ts.html +250 -0
  144. package/coverage/lib/services/transaction-builders/base-transaction-builder.service.ts.html +1 -1
  145. package/coverage/lib/services/transaction-builders/hedera-amount-utils.ts.html +155 -155
  146. package/coverage/lib/services/transaction-builders/hedera-transaction-builder.service.ts.html +2156 -2156
  147. package/coverage/lib/services/transaction-builders/index.html +58 -43
  148. package/coverage/lib/services/transaction-builders/xrpl-transaction-builder.service.ts.html +1674 -1674
  149. package/coverage/lib/services/transaction.service.ts.html +4 -4
  150. package/coverage/lib/services/unified-wallet.service.ts.html +3 -3
  151. package/coverage/lib/services/wallet-context.service.ts.html +1 -1
  152. package/coverage/lib/services/wallet-event-bus.service.ts.html +249 -249
  153. package/coverage/lib/services/wallet-providers.service.ts.html +1 -1
  154. package/coverage/lib/transports/chrome-extension-transport.ts.html +1 -1
  155. package/coverage/lib/transports/index.html +1 -1
  156. package/coverage/lib/utils/index.html +36 -21
  157. package/coverage/lib/utils/ledger-icons.util.ts.html +254 -161
  158. package/coverage/lib/utils/ledger-ui-registry.ts.html +676 -0
  159. package/dist/fesm2022/hsuite-native-connect-angular.mjs +854 -308
  160. package/dist/fesm2022/hsuite-native-connect-angular.mjs.map +1 -1
  161. package/dist/index.d.ts +456 -30
  162. package/package.json +4 -4
  163. package/src/index.ts +26 -0
  164. package/src/lib/components/account-selector/account-formatting.service.ts +8 -10
  165. package/src/lib/components/wallet-account-display/wallet-account-display.component.ts +9 -9
  166. package/src/lib/components/wallet-connection-modal/wallet-connection-modal.component.ts +34 -18
  167. package/src/lib/models/provider-types.ts +3 -1
  168. package/src/lib/models/unified-account.model.ts +4 -1
  169. package/src/lib/providers/hsuite-native/channel-client.service.ts +1 -0
  170. package/src/lib/providers/p2p-native/p2p-session-manager.ts +1 -0
  171. package/src/lib/providers/walletconnect/core/walletconnect-provider.ts +2 -1
  172. package/src/lib/services/hsuite-auth.interceptor.ts +159 -0
  173. package/src/lib/services/smart-session.service.ts +378 -0
  174. package/src/lib/services/transaction-builders/active-account-source.spec.ts +75 -0
  175. package/src/lib/services/transaction-builders/active-account-source.ts +55 -0
  176. package/src/lib/services/transaction-builders/hedera-transaction-builder.service.ts +4 -4
  177. package/src/lib/services/transaction-builders/index.ts +1 -0
  178. package/src/lib/services/transaction.service.ts +7 -3
  179. package/src/lib/services/unified-wallet.service.spec.ts +1 -1
  180. package/src/lib/services/unified-wallet.service.ts +2 -2
  181. package/src/lib/utils/index.ts +1 -0
  182. package/src/lib/utils/ledger-icons.util.ts +61 -30
  183. package/src/lib/utils/ledger-ui-registry.ts +197 -0
@@ -14,7 +14,8 @@ import SignClient from '@walletconnect/sign-client';
14
14
  import { toObservable } from '@angular/core/rxjs-interop';
15
15
  import { copyToClipboard } from '@hsuite/native-connect-ui';
16
16
  import * as QRCode from 'qrcode';
17
- import { Subscription } from 'rxjs';
17
+ import { Subscription, firstValueFrom, catchError, from, switchMap, throwError } from 'rxjs';
18
+ import { HttpClient, HttpErrorResponse } from '@angular/common/http';
18
19
  import { PublicKey, KeyList, TransferTransaction, AccountId, Hbar, TokenId, NftId, TokenAssociateTransaction, TokenDissociateTransaction, ScheduleCreateTransaction, TokenCreateTransaction, TokenType, TokenSupplyType, TokenMintTransaction, TokenBurnTransaction, TopicCreateTransaction, TopicMessageSubmitTransaction, AccountCreateTransaction, PrivateKey, AccountUpdateTransaction, TransactionId, BatchTransaction, Client } from '@hashgraph/sdk';
19
20
 
20
21
  /**
@@ -197,6 +198,120 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.19", ngImpo
197
198
  type: Output
198
199
  }] } });
199
200
 
201
+ /**
202
+ * HSuite Native Connect
203
+ * Copyright 2024-2025 HSuite (https://hsuite.finance)
204
+ *
205
+ * SPDX-License-Identifier: PolyForm-Noncommercial-1.0.0
206
+ *
207
+ * This file is part of HSuite Native Connect. For commercial licensing,
208
+ * visit https://hsuite.finance/licensing
209
+ */
210
+ /**
211
+ * Open, string-keyed registry of {@link LedgerUiDescriptor}s.
212
+ *
213
+ * A static registry (like `AccountLabelManager`) because ledger presentation is
214
+ * process-global — Ionicons' own icon table is global too. Mirrors the core
215
+ * `LedgerRegistry` shape (`register` / `get` / `has` / `list`) so the two read
216
+ * the same way.
217
+ */
218
+ class LedgerUIRegistry {
219
+ static descriptors = new Map();
220
+ /** Whether {@link registerIcons} has already flushed SVGs to Ionicons. */
221
+ static iconsFlushed = false;
222
+ /**
223
+ * Register (or replace) the presentation descriptor for a ledger.
224
+ *
225
+ * If icons were already flushed to Ionicons (i.e. {@link registerIcons} ran),
226
+ * the new ledger's SVG is registered immediately so late registrations still
227
+ * render.
228
+ *
229
+ * @param descriptor - The ledger's presentation contract.
230
+ */
231
+ static register(descriptor) {
232
+ LedgerUIRegistry.descriptors.set(descriptor.id, descriptor);
233
+ if (LedgerUIRegistry.iconsFlushed) {
234
+ addIcons({ [descriptor.iconName]: descriptor.iconSvg });
235
+ }
236
+ }
237
+ /**
238
+ * Look up a ledger's presentation descriptor.
239
+ *
240
+ * @param ledgerId - Canonical ledger id (case-sensitive; callers normalise).
241
+ * @returns The descriptor, or `undefined` if the ledger is not registered.
242
+ */
243
+ static get(ledgerId) {
244
+ return LedgerUIRegistry.descriptors.get(ledgerId);
245
+ }
246
+ /**
247
+ * @param ledgerId - Canonical ledger id.
248
+ * @returns `true` if a descriptor is registered for `ledgerId`.
249
+ */
250
+ static has(ledgerId) {
251
+ return LedgerUIRegistry.descriptors.has(ledgerId);
252
+ }
253
+ /**
254
+ * @returns All registered descriptors, in registration order.
255
+ */
256
+ static list() {
257
+ return Array.from(LedgerUIRegistry.descriptors.values());
258
+ }
259
+ /**
260
+ * Flush every registered ledger's brand SVG to Ionicons so the icons resolve
261
+ * by name from `<ion-icon>`. Idempotent and cheap to call repeatedly — call it
262
+ * before the icons are first rendered (e.g. from a component constructor or
263
+ * once at app bootstrap).
264
+ */
265
+ static registerIcons() {
266
+ if (LedgerUIRegistry.iconsFlushed) {
267
+ return;
268
+ }
269
+ const icons = {};
270
+ for (const descriptor of LedgerUIRegistry.descriptors.values()) {
271
+ icons[descriptor.iconName] = descriptor.iconSvg;
272
+ }
273
+ addIcons(icons);
274
+ LedgerUIRegistry.iconsFlushed = true;
275
+ }
276
+ }
277
+ // ---------------------------------------------------------------------------
278
+ // Built-in ledgers
279
+ //
280
+ // The only place the first-party ledger set is enumerated. Adding a new
281
+ // first-party chain is one more `register(...)` here; everything downstream
282
+ // (icons, colours, names, the connection modal's "Choose Blockchain" step)
283
+ // derives from these descriptors.
284
+ // ---------------------------------------------------------------------------
285
+ LedgerUIRegistry.register({
286
+ id: 'hedera',
287
+ displayName: 'Hedera',
288
+ shortName: 'Hedera',
289
+ currencySymbol: 'HBAR',
290
+ currencyDecimals: 8,
291
+ brandColor: '#8259ef',
292
+ badgeColor: 'success',
293
+ iconName: 'ledger-hedera',
294
+ // Brand disc themed with `brandColor` (#8259ef) + a white "H" so the mark stays
295
+ // brand-correct and legible on any background (incl. the dark modal card).
296
+ iconSvg: `<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><g fill="none"><path fill="#8259ef" d="M12 4a8 8 0 1 0 0 16a8 8 0 0 0 0-16"/><path fill="#fff" d="M15.252 15.46h-1.016V13.3H9.764v2.16H8.748V8.456h1.016v2.108h4.472V8.456h1.016zm-5.44-2.968h4.472v-1.116H9.812z"/></g></svg>`,
297
+ tokenIconUrl: 'https://assets.coingecko.com/coins/images/3688/standard/hbar.png?1696504364',
298
+ });
299
+ LedgerUIRegistry.register({
300
+ id: 'xrpl',
301
+ displayName: 'XRP Ledger',
302
+ shortName: 'XRPL',
303
+ currencySymbol: 'XRP',
304
+ currencyDecimals: 6,
305
+ brandColor: '#23292f',
306
+ badgeColor: 'tertiary',
307
+ iconName: 'ledger-xrpl',
308
+ // `currentColor` so the mark adopts the host `<ion-icon>` colour — the XRPL
309
+ // brand black (#23292f) is invisible on the dark modal card, so the icon
310
+ // inherits the theme colour while `brandColor` stays the canonical accent.
311
+ iconSvg: `<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><path fill="currentColor" d="M21.778 4h-2.837l-4.49 4.371a3.52 3.52 0 0 1-2.451.99a3.52 3.52 0 0 1-2.452-.99L5.062 4h-2.84L8.13 9.754c2.14 2.083 5.607 2.083 7.745 0zM2.223 20H5.05l4.508-4.385a3.5 3.5 0 0 1 2.443-.985c.914 0 1.792.354 2.443.985L18.952 20h2.826l-5.92-5.761c-2.132-2.073-5.585-2.073-7.715 0z"/></svg>`,
312
+ tokenIconUrl: 'https://assets.coingecko.com/coins/images/44/standard/xrp-symbol-white-128.png?1696501442',
313
+ });
314
+
200
315
  /**
201
316
  * HSuite Native Connect
202
317
  * Copyright 2024-2025 HSuite (https://hsuite.finance)
@@ -241,11 +356,9 @@ class AccountFormattingService {
241
356
  * @returns Display name
242
357
  */
243
358
  getLedgerName(ledgerId) {
244
- const names = {
245
- hedera: 'Hedera',
246
- xrpl: 'XRPL',
247
- };
248
- return names[ledgerId?.toLowerCase()] || ledgerId?.toUpperCase() || 'Unknown';
359
+ return (LedgerUIRegistry.get(ledgerId?.toLowerCase())?.shortName ||
360
+ ledgerId?.toUpperCase() ||
361
+ 'Unknown');
249
362
  }
250
363
  /**
251
364
  * Get color for a ledger badge.
@@ -254,11 +367,7 @@ class AccountFormattingService {
254
367
  * @returns Ionic color name
255
368
  */
256
369
  getLedgerColor(ledgerId) {
257
- const colors = {
258
- hedera: 'success',
259
- xrpl: 'tertiary',
260
- };
261
- return colors[ledgerId?.toLowerCase()] || 'medium';
370
+ return LedgerUIRegistry.get(ledgerId?.toLowerCase())?.badgeColor || 'medium';
262
371
  }
263
372
  /**
264
373
  * Format network display name with proper casing.
@@ -651,61 +760,80 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.19", ngImpo
651
760
  */
652
761
  /**
653
762
  * @module LedgerIconsUtil
654
- * Utilities for getting default icon URLs for ledgers and their native tokens.
655
763
  *
656
- * Uses CoinGecko's public CDN for reliable, high-quality token icons.
657
- * Shared across wallet and dApp for consistency.
764
+ * Backward-compatible facade over {@link LedgerUIRegistry}.
765
+ *
766
+ * Every value here is **derived from the registry** so there is exactly one
767
+ * source of truth for ledger presentation. New code should prefer
768
+ * {@link LedgerUIRegistry} directly (it is open/extensible and richer); these
769
+ * getters and constant maps remain for the existing public API surface.
770
+ *
771
+ * The constant maps below are snapshots taken at module load — they include the
772
+ * built-in ledgers (Hedera, XRPL). Ledgers registered later at runtime are
773
+ * always reachable through the getters and {@link LedgerUIRegistry}, but will
774
+ * not retroactively appear in these legacy snapshots; prefer the registry when
775
+ * extensibility matters.
658
776
  */
659
777
  /**
660
- * Default icon URLs for native ledger tokens
778
+ * Default raster icon URLs for native ledger tokens, keyed by ledger id.
779
+ * Derived from {@link LedgerUiDescriptor.tokenIconUrl}.
661
780
  */
662
- const DEFAULT_LEDGER_ICONS = {
663
- hedera: 'https://assets.coingecko.com/coins/images/3688/standard/hbar.png?1696504364',
664
- xrpl: 'https://assets.coingecko.com/coins/images/44/standard/xrp-symbol-white-128.png?1696501442',
665
- };
781
+ const DEFAULT_LEDGER_ICONS = Object.fromEntries(LedgerUIRegistry.list()
782
+ .filter((descriptor) => descriptor.tokenIconUrl)
783
+ .map((descriptor) => [descriptor.id, descriptor.tokenIconUrl]));
666
784
  /**
667
- * Brand colors for each ledger
785
+ * Brand colours (hex) for each ledger, keyed by ledger id.
786
+ * Derived from {@link LedgerUiDescriptor.brandColor}.
668
787
  */
669
- const LEDGER_COLORS = {
670
- hedera: '#8259ef',
671
- xrpl: '#23292f',
672
- };
788
+ const LEDGER_COLORS = Object.fromEntries(LedgerUIRegistry.list().map((descriptor) => [descriptor.id, descriptor.brandColor]));
673
789
  /**
674
- * Display names for each ledger
790
+ * Display names for each ledger, keyed by ledger id.
791
+ * Derived from {@link LedgerUiDescriptor.displayName}.
675
792
  */
676
- const LEDGER_NAMES = {
677
- hedera: 'Hedera',
678
- xrpl: 'XRP Ledger',
679
- };
793
+ const LEDGER_NAMES = Object.fromEntries(LedgerUIRegistry.list().map((descriptor) => [descriptor.id, descriptor.displayName]));
794
+ /**
795
+ * Ionicons names under which each ledger's brand SVG is registered, keyed by
796
+ * ledger id. Reference these from `<ion-icon [name]="...">`.
797
+ * Derived from {@link LedgerUiDescriptor.iconName}.
798
+ */
799
+ const LEDGER_ICON_NAMES = Object.fromEntries(LedgerUIRegistry.list().map((descriptor) => [descriptor.id, descriptor.iconName]));
680
800
  /**
681
- * Get the default icon URL for a ledger
682
- * @param ledgerId - Ledger identifier (e.g., 'hedera', 'xrpl')
683
- * @returns Icon URL or empty string if not found
801
+ * Register the ledger brand SVGs with Ionicons so they can be referenced by name
802
+ * (see {@link LEDGER_ICON_NAMES}). Idempotent; safe to call from multiple
803
+ * consumers. Delegates to {@link LedgerUIRegistry.registerIcons}.
804
+ */
805
+ function registerLedgerIcons() {
806
+ LedgerUIRegistry.registerIcons();
807
+ }
808
+ /**
809
+ * Get the default raster token icon URL for a ledger.
810
+ * @param ledgerId - Ledger identifier (e.g. `'hedera'`, `'xrpl'`)
811
+ * @returns Icon URL, or empty string if the ledger has none.
684
812
  */
685
813
  function getLedgerIcon(ledgerId) {
686
- return DEFAULT_LEDGER_ICONS[ledgerId?.toLowerCase()] || '';
814
+ return LedgerUIRegistry.get(ledgerId?.toLowerCase())?.tokenIconUrl ?? '';
687
815
  }
688
816
  /**
689
- * Get the brand color for a ledger
817
+ * Get the brand colour (hex) for a ledger.
690
818
  * @param ledgerId - Ledger identifier
691
- * @returns Hex color string or primary color fallback
819
+ * @returns Hex colour string, or the Ionic primary CSS variable as fallback.
692
820
  */
693
821
  function getLedgerColor(ledgerId) {
694
- return LEDGER_COLORS[ledgerId?.toLowerCase()] || 'var(--ion-color-primary)';
822
+ return LedgerUIRegistry.get(ledgerId?.toLowerCase())?.brandColor ?? 'var(--ion-color-primary)';
695
823
  }
696
824
  /**
697
- * Get the display name for a ledger
825
+ * Get the display name for a ledger.
698
826
  * @param ledgerId - Ledger identifier
699
- * @returns Human-readable ledger name
827
+ * @returns Human-readable ledger name, or the raw id if unknown.
700
828
  */
701
829
  function getLedgerName(ledgerId) {
702
- return LEDGER_NAMES[ledgerId?.toLowerCase()] || ledgerId;
830
+ return LedgerUIRegistry.get(ledgerId?.toLowerCase())?.displayName ?? ledgerId;
703
831
  }
704
832
  /**
705
- * Get token icon URL, falling back to ledger default if not provided
833
+ * Get a token icon URL, falling back to the ledger default if not provided.
706
834
  * @param tokenIconUrl - Specific token icon URL (optional)
707
835
  * @param ledgerId - Ledger identifier for fallback
708
- * @returns Icon URL or empty string
836
+ * @returns Icon URL, or empty string.
709
837
  */
710
838
  function getTokenIcon(tokenIconUrl, ledgerId) {
711
839
  return tokenIconUrl || getLedgerIcon(ledgerId);
@@ -1301,7 +1429,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.19", ngImpo
1301
1429
  * Each event is available as both an Angular EventEmitter (for template bindings)
1302
1430
  * and an RxJS Observable (for advanced composition with operators).
1303
1431
  */
1304
- const logger$j = getLogger().scoped?.('WalletEventBus') ?? getLogger();
1432
+ const logger$k = getLogger().scoped?.('WalletEventBus') ?? getLogger();
1305
1433
  /**
1306
1434
  * Centralized event bus for wallet events.
1307
1435
  *
@@ -1413,7 +1541,7 @@ class WalletEventBus {
1413
1541
  *
1414
1542
  */
1415
1543
  constructor() {
1416
- logger$j.debug('Event bus initialized');
1544
+ logger$k.debug('Event bus initialized');
1417
1545
  }
1418
1546
  static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.19", ngImport: i0, type: WalletEventBus, deps: [], target: i0.ɵɵFactoryTarget.Injectable });
1419
1547
  static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "20.3.19", ngImport: i0, type: WalletEventBus, providedIn: 'root' });
@@ -1600,7 +1728,7 @@ class BaseWalletProvider {
1600
1728
  * }
1601
1729
  * ```
1602
1730
  */
1603
- const logger$i = getLogger().scoped?.('ChannelClientService') ?? getLogger();
1731
+ const logger$j = getLogger().scoped?.('ChannelClientService') ?? getLogger();
1604
1732
  /**
1605
1733
  * ChannelClientService
1606
1734
  *
@@ -1650,6 +1778,7 @@ class ChannelClientService {
1650
1778
  return {
1651
1779
  id: `channel-${account.address}`,
1652
1780
  address: account.address,
1781
+ publicKey: account.publicKey,
1653
1782
  label: account.alias ?? `Account ${index + 1}`,
1654
1783
  ledgerId: account.ledgerId,
1655
1784
  networkId: account.networkId,
@@ -1688,7 +1817,7 @@ class ChannelClientService {
1688
1817
  */
1689
1818
  async connect(config) {
1690
1819
  if (this._state() === 'connecting' || this._state() === 'pending') {
1691
- logger$i.warn('Connection already in progress');
1820
+ logger$j.warn('Connection already in progress');
1692
1821
  const existing = this._currentInvite();
1693
1822
  if (existing)
1694
1823
  return existing;
@@ -1730,7 +1859,7 @@ class ChannelClientService {
1730
1859
  this.runInZone(() => {
1731
1860
  const previousState = this._state();
1732
1861
  if (state !== previousState) {
1733
- logger$i.debug('State change via callback', { from: previousState, to: state });
1862
+ logger$j.debug('State change via callback', { from: previousState, to: state });
1734
1863
  this._state.set(state);
1735
1864
  // Handle error state - this is triggered on rejection
1736
1865
  if (state === 'error') {
@@ -1755,7 +1884,7 @@ class ChannelClientService {
1755
1884
  },
1756
1885
  onAccountsChange: (accounts) => {
1757
1886
  this.runInZone(() => {
1758
- logger$i.debug('Accounts change via callback', { count: accounts.length });
1887
+ logger$j.debug('Accounts change via callback', { count: accounts.length });
1759
1888
  this._accounts.set(accounts);
1760
1889
  // Re-persist when accounts change
1761
1890
  if (this._state() === 'active') {
@@ -1766,7 +1895,7 @@ class ChannelClientService {
1766
1895
  onTransportChange: (transport) => {
1767
1896
  this.runInZone(() => {
1768
1897
  if (transport !== this._transportState()) {
1769
- logger$i.debug('Transport change via callback', { state: transport });
1898
+ logger$j.debug('Transport change via callback', { state: transport });
1770
1899
  this._transportState.set(transport);
1771
1900
  }
1772
1901
  });
@@ -1801,7 +1930,7 @@ class ChannelClientService {
1801
1930
  });
1802
1931
  // Store invite for reconnection
1803
1932
  this.storeInvite(invite);
1804
- logger$i.info('Channel connection initiated', {
1933
+ logger$j.info('Channel connection initiated', {
1805
1934
  channelId: invite.id.slice(0, 8),
1806
1935
  type: invite.type,
1807
1936
  });
@@ -1809,7 +1938,7 @@ class ChannelClientService {
1809
1938
  }
1810
1939
  catch (error) {
1811
1940
  const message = error instanceof Error ? error.message : String(error);
1812
- logger$i.error('Connection failed', { error: message });
1941
+ logger$j.error('Connection failed', { error: message });
1813
1942
  // Reset connecting flag on error
1814
1943
  this.connectingNewSession = false;
1815
1944
  this.runInZone(() => {
@@ -1850,7 +1979,7 @@ class ChannelClientService {
1850
1979
  if (state !== 'active' && state !== 'approved') {
1851
1980
  throw new Error(`Not connected - channel state is '${state}'. Please reconnect to the wallet.`);
1852
1981
  }
1853
- logger$i.debug('Sending RPC request', { method, state });
1982
+ logger$j.debug('Sending RPC request', { method, state });
1854
1983
  return this.client.request(method, params, timeoutMs);
1855
1984
  }
1856
1985
  /**
@@ -1927,7 +2056,7 @@ class ChannelClientService {
1927
2056
  await this.client.disconnect();
1928
2057
  }
1929
2058
  catch (error) {
1930
- logger$i.warn('Disconnect error', { error });
2059
+ logger$j.warn('Disconnect error', { error });
1931
2060
  }
1932
2061
  this.client = null;
1933
2062
  }
@@ -1939,7 +2068,7 @@ class ChannelClientService {
1939
2068
  this._currentInvite.set(null);
1940
2069
  this._error.set(null);
1941
2070
  });
1942
- logger$i.info('Disconnected from channel');
2071
+ logger$j.info('Disconnected from channel');
1943
2072
  }
1944
2073
  /**
1945
2074
  * Attempt to restore a previous session.
@@ -1952,7 +2081,7 @@ class ChannelClientService {
1952
2081
  async attemptRestore() {
1953
2082
  // Skip restore if a new connection is being initiated
1954
2083
  if (this.connectingNewSession) {
1955
- logger$i.debug('Skipping restore - new connection in progress');
2084
+ logger$j.debug('Skipping restore - new connection in progress');
1956
2085
  return false;
1957
2086
  }
1958
2087
  const stored = this.getStoredChannel();
@@ -1968,11 +2097,11 @@ class ChannelClientService {
1968
2097
  // Safe to do unconditionally at this point in the project's lifecycle:
1969
2098
  // no dApp sessions are live in production yet.
1970
2099
  if (stored.localContext === undefined) {
1971
- logger$i.warn('Clearing legacy persisted channel without localContext — user must re-approve the dApp connection (§21.1)', { channelId: stored.id.slice(0, 8) });
2100
+ logger$j.warn('Clearing legacy persisted channel without localContext — user must re-approve the dApp connection (§21.1)', { channelId: stored.id.slice(0, 8) });
1972
2101
  this.clearStoredChannel();
1973
2102
  return false;
1974
2103
  }
1975
- logger$i.info('Attempting session restore', {
2104
+ logger$j.info('Attempting session restore', {
1976
2105
  channelId: stored.id.slice(0, 8),
1977
2106
  });
1978
2107
  this.runInZone(() => {
@@ -1985,7 +2114,7 @@ class ChannelClientService {
1985
2114
  this.runInZone(() => {
1986
2115
  const previousState = this._state();
1987
2116
  if (state !== previousState) {
1988
- logger$i.debug('State change via callback (reconnect)', {
2117
+ logger$j.debug('State change via callback (reconnect)', {
1989
2118
  from: previousState,
1990
2119
  to: state,
1991
2120
  });
@@ -2005,7 +2134,7 @@ class ChannelClientService {
2005
2134
  },
2006
2135
  onAccountsChange: (accounts) => {
2007
2136
  this.runInZone(() => {
2008
- logger$i.debug('Accounts change via callback (reconnect)', { count: accounts.length });
2137
+ logger$j.debug('Accounts change via callback (reconnect)', { count: accounts.length });
2009
2138
  this._accounts.set(accounts);
2010
2139
  if (this._state() === 'active') {
2011
2140
  this.persistCurrentState();
@@ -2015,7 +2144,7 @@ class ChannelClientService {
2015
2144
  onTransportChange: (transport) => {
2016
2145
  this.runInZone(() => {
2017
2146
  if (transport !== this._transportState()) {
2018
- logger$i.debug('Transport change via callback (reconnect)', { state: transport });
2147
+ logger$j.debug('Transport change via callback (reconnect)', { state: transport });
2019
2148
  this._transportState.set(transport);
2020
2149
  }
2021
2150
  });
@@ -2038,14 +2167,14 @@ class ChannelClientService {
2038
2167
  }
2039
2168
  this._state.set('active');
2040
2169
  });
2041
- logger$i.info('Session restored successfully', {
2170
+ logger$j.info('Session restored successfully', {
2042
2171
  channelId: stored.id.slice(0, 8),
2043
2172
  accounts: restoredAccounts.length,
2044
2173
  });
2045
2174
  return true;
2046
2175
  }
2047
2176
  catch (error) {
2048
- logger$i.warn('Session restore failed', {
2177
+ logger$j.warn('Session restore failed', {
2049
2178
  error: error instanceof Error ? error.message : String(error),
2050
2179
  });
2051
2180
  // Clean up the partially initialized client
@@ -2121,7 +2250,7 @@ class ChannelClientService {
2121
2250
  }
2122
2251
  if (clientTransport !== this._transportState()) {
2123
2252
  this._transportState.set(clientTransport);
2124
- logger$i.debug('Transport state updated', { state: clientTransport });
2253
+ logger$j.debug('Transport state updated', { state: clientTransport });
2125
2254
  }
2126
2255
  });
2127
2256
  // Continue polling as long as client exists
@@ -2164,14 +2293,14 @@ class ChannelClientService {
2164
2293
  const persisted = this.client.exportState();
2165
2294
  if (persisted) {
2166
2295
  localStorage.setItem(ChannelClientService.STORAGE_KEY, JSON.stringify(persisted));
2167
- logger$i.debug('Channel state persisted', {
2296
+ logger$j.debug('Channel state persisted', {
2168
2297
  channelId: persisted.id.slice(0, 8),
2169
2298
  accounts: persisted.accounts?.length ?? 0,
2170
2299
  });
2171
2300
  }
2172
2301
  }
2173
2302
  catch (error) {
2174
- logger$i.warn('Failed to persist channel state', { error });
2303
+ logger$j.warn('Failed to persist channel state', { error });
2175
2304
  }
2176
2305
  }
2177
2306
  /**
@@ -2212,7 +2341,7 @@ class ChannelClientService {
2212
2341
  }
2213
2342
  }
2214
2343
  catch {
2215
- logger$i.warn('Failed to store channel');
2344
+ logger$j.warn('Failed to store channel');
2216
2345
  }
2217
2346
  }
2218
2347
  /**
@@ -2226,7 +2355,7 @@ class ChannelClientService {
2226
2355
  }
2227
2356
  }
2228
2357
  catch {
2229
- logger$i.warn('Failed to retrieve stored channel');
2358
+ logger$j.warn('Failed to retrieve stored channel');
2230
2359
  }
2231
2360
  return null;
2232
2361
  }
@@ -2278,7 +2407,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.19", ngImpo
2278
2407
  * 8. P2P upgrade happens automatically in background
2279
2408
  * ```
2280
2409
  */
2281
- const logger$h = getLogger().scoped?.('HsuiteNativeProvider') ?? getLogger();
2410
+ const logger$i = getLogger().scoped?.('HsuiteNativeProvider') ?? getLogger();
2282
2411
  /**
2283
2412
  * HSuite Native Connect Provider.
2284
2413
  *
@@ -2364,7 +2493,7 @@ class HsuiteNativeProvider extends BaseWalletProvider {
2364
2493
  const isConnected = this.channelService.isConnected();
2365
2494
  // If we were connected but now disconnected, emit disconnect event
2366
2495
  if (this.previouslyConnected && !isConnected && status === 'disconnected') {
2367
- logger$h.info('[HsuiteNativeProvider] Channel terminated');
2496
+ logger$i.info('[HsuiteNativeProvider] Channel terminated');
2368
2497
  this.eventBus.disconnected.emit({
2369
2498
  providerId: this.id,
2370
2499
  providerType: 'hsuite-native',
@@ -2377,7 +2506,7 @@ class HsuiteNativeProvider extends BaseWalletProvider {
2377
2506
  });
2378
2507
  // Attempt automatic reconnect when session exists after reload
2379
2508
  void this.attemptReconnect().catch((error) => {
2380
- logger$h.debug('[HsuiteNativeProvider] Auto-reconnect skipped', { error });
2509
+ logger$i.debug('[HsuiteNativeProvider] Auto-reconnect skipped', { error });
2381
2510
  });
2382
2511
  }
2383
2512
  /**
@@ -2471,10 +2600,10 @@ class HsuiteNativeProvider extends BaseWalletProvider {
2471
2600
  // Guard: Don't start a new connection if already connecting
2472
2601
  const currentStatus = this.status();
2473
2602
  if (currentStatus === 'connecting') {
2474
- logger$h.warn('Connection already in progress, ignoring duplicate request');
2603
+ logger$i.warn('Connection already in progress, ignoring duplicate request');
2475
2604
  return;
2476
2605
  }
2477
- logger$h.info('Connecting to HSuite Wallet via unified channel protocol', { config });
2606
+ logger$i.info('Connecting to HSuite Wallet via unified channel protocol', { config });
2478
2607
  try {
2479
2608
  const invite = await this.channelService.connect({
2480
2609
  type: 'session',
@@ -2500,14 +2629,14 @@ class HsuiteNativeProvider extends BaseWalletProvider {
2500
2629
  accounts,
2501
2630
  timestamp: Date.now(),
2502
2631
  });
2503
- logger$h.info('Connected successfully via unified channel', {
2632
+ logger$i.info('Connected successfully via unified channel', {
2504
2633
  channelId: invite.id.slice(0, 8),
2505
2634
  accountCount: accounts.length,
2506
2635
  });
2507
2636
  });
2508
2637
  }
2509
2638
  catch (error) {
2510
- logger$h.error('Connection failed', { error });
2639
+ logger$i.error('Connection failed', { error });
2511
2640
  throw error;
2512
2641
  }
2513
2642
  }
@@ -2540,7 +2669,7 @@ class HsuiteNativeProvider extends BaseWalletProvider {
2540
2669
  if (wallet) {
2541
2670
  // Send invite directly via BroadcastChannel - instant, no network!
2542
2671
  this.localDiscoveryService.sendInvite(wallet.fingerprint, inviteUrl, config?.appId, config?.appName);
2543
- logger$h.info('[HsuiteNativeProvider] Sent invite via local discovery', {
2672
+ logger$i.info('[HsuiteNativeProvider] Sent invite via local discovery', {
2544
2673
  wallet: wallet.fingerprint.slice(0, 8),
2545
2674
  });
2546
2675
  return;
@@ -2632,7 +2761,7 @@ class HsuiteNativeProvider extends BaseWalletProvider {
2632
2761
  * @throws {Error} If disconnection fails (event still emitted)
2633
2762
  */
2634
2763
  async disconnect() {
2635
- logger$h.info('Disconnecting from HSuite Wallet');
2764
+ logger$i.info('Disconnecting from HSuite Wallet');
2636
2765
  try {
2637
2766
  await this.channelService.disconnect();
2638
2767
  // Emit disconnection event
@@ -2642,10 +2771,10 @@ class HsuiteNativeProvider extends BaseWalletProvider {
2642
2771
  reason: 'user_initiated',
2643
2772
  timestamp: Date.now(),
2644
2773
  });
2645
- logger$h.info('Disconnected successfully');
2774
+ logger$i.info('Disconnected successfully');
2646
2775
  }
2647
2776
  catch (error) {
2648
- logger$h.error('Disconnection failed', { error });
2777
+ logger$i.error('Disconnection failed', { error });
2649
2778
  // Still emit event even if disconnect fails
2650
2779
  this.eventBus.disconnected.emit({
2651
2780
  providerId: this.id,
@@ -2673,7 +2802,7 @@ class HsuiteNativeProvider extends BaseWalletProvider {
2673
2802
  * @throws {Error} If channel communication fails
2674
2803
  */
2675
2804
  async signTransaction(options) {
2676
- logger$h.info('Signing transaction', { options });
2805
+ logger$i.info('Signing transaction', { options });
2677
2806
  try {
2678
2807
  const response = await this.channelService.signTransaction({
2679
2808
  accountAddress: options.accountAddress,
@@ -2681,7 +2810,7 @@ class HsuiteNativeProvider extends BaseWalletProvider {
2681
2810
  ledgerId: options.ledgerId,
2682
2811
  networkId: options.networkId,
2683
2812
  });
2684
- logger$h.info('Transaction signed');
2813
+ logger$i.info('Transaction signed');
2685
2814
  return {
2686
2815
  signedPayload: response.signedPayload || '',
2687
2816
  signature: response.signature,
@@ -2689,7 +2818,7 @@ class HsuiteNativeProvider extends BaseWalletProvider {
2689
2818
  };
2690
2819
  }
2691
2820
  catch (error) {
2692
- logger$h.error('Transaction signing failed', { error });
2821
+ logger$i.error('Transaction signing failed', { error });
2693
2822
  throw error;
2694
2823
  }
2695
2824
  }
@@ -2713,7 +2842,7 @@ class HsuiteNativeProvider extends BaseWalletProvider {
2713
2842
  * @throws {Error} If transaction submission fails
2714
2843
  */
2715
2844
  async signAndExecuteTransaction(options) {
2716
- logger$h.info('signAndExecuteTransaction called (single prompt)', {
2845
+ logger$i.info('signAndExecuteTransaction called (single prompt)', {
2717
2846
  accountAddress: options.accountAddress,
2718
2847
  ledgerId: options.ledgerId,
2719
2848
  networkId: options.networkId,
@@ -2750,7 +2879,7 @@ class HsuiteNativeProvider extends BaseWalletProvider {
2750
2879
  * @param options
2751
2880
  */
2752
2881
  async submitTransactionInternal(options) {
2753
- logger$h.info('Signing and submitting transaction (single prompt)', {
2882
+ logger$i.info('Signing and submitting transaction (single prompt)', {
2754
2883
  accountAddress: options.accountAddress,
2755
2884
  ledgerId: options.ledgerId,
2756
2885
  networkId: options.networkId,
@@ -2768,7 +2897,7 @@ class HsuiteNativeProvider extends BaseWalletProvider {
2768
2897
  innerTransactions: options.innerTransactions,
2769
2898
  }),
2770
2899
  });
2771
- logger$h.info('Transaction signed and submitted successfully', {
2900
+ logger$i.info('Transaction signed and submitted successfully', {
2772
2901
  transactionId: response.transactionId,
2773
2902
  transactionHash: response.transactionHash?.substring(0, 16),
2774
2903
  });
@@ -2779,7 +2908,7 @@ class HsuiteNativeProvider extends BaseWalletProvider {
2779
2908
  };
2780
2909
  }
2781
2910
  catch (error) {
2782
- logger$h.error('Transaction sign+submit failed', { error });
2911
+ logger$i.error('Transaction sign+submit failed', { error });
2783
2912
  throw error;
2784
2913
  }
2785
2914
  }
@@ -2801,7 +2930,7 @@ class HsuiteNativeProvider extends BaseWalletProvider {
2801
2930
  * @throws {Error} If wallet is not connected
2802
2931
  */
2803
2932
  async signMessage(options) {
2804
- logger$h.info('Signing message', {
2933
+ logger$i.info('Signing message', {
2805
2934
  accountAddress: options.accountAddress,
2806
2935
  encoding: options.encoding,
2807
2936
  messageLength: options.message?.length,
@@ -2814,7 +2943,7 @@ class HsuiteNativeProvider extends BaseWalletProvider {
2814
2943
  ledgerId: options.ledgerId,
2815
2944
  networkId: options.networkId,
2816
2945
  });
2817
- logger$h.info('Message signed successfully', {
2946
+ logger$i.info('Message signed successfully', {
2818
2947
  algorithm: response.algorithm,
2819
2948
  caipChainId: response.caipChainId,
2820
2949
  });
@@ -2831,7 +2960,7 @@ class HsuiteNativeProvider extends BaseWalletProvider {
2831
2960
  };
2832
2961
  }
2833
2962
  catch (error) {
2834
- logger$h.error('Message signing failed', { error });
2963
+ logger$i.error('Message signing failed', { error });
2835
2964
  throw error;
2836
2965
  }
2837
2966
  }
@@ -2863,7 +2992,7 @@ class HsuiteNativeProvider extends BaseWalletProvider {
2863
2992
  * @returns Promise resolving to true if reconnection succeeded, false otherwise
2864
2993
  */
2865
2994
  async attemptReconnect() {
2866
- logger$h.info('Attempting reconnect via unified channel');
2995
+ logger$i.info('Attempting reconnect via unified channel');
2867
2996
  try {
2868
2997
  const success = await this.channelService.attemptRestore();
2869
2998
  if (success) {
@@ -2876,15 +3005,15 @@ class HsuiteNativeProvider extends BaseWalletProvider {
2876
3005
  metadata: { autoReconnected: true },
2877
3006
  timestamp: Date.now(),
2878
3007
  });
2879
- logger$h.info('Reconnect successful');
3008
+ logger$i.info('Reconnect successful');
2880
3009
  }
2881
3010
  else {
2882
- logger$h.warn('Reconnect failed - no session or unable to connect');
3011
+ logger$i.warn('Reconnect failed - no session or unable to connect');
2883
3012
  }
2884
3013
  return success;
2885
3014
  }
2886
3015
  catch (error) {
2887
- logger$h.error('Reconnect failed', { error });
3016
+ logger$i.error('Reconnect failed', { error });
2888
3017
  return false;
2889
3018
  }
2890
3019
  }
@@ -2919,7 +3048,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.19", ngImpo
2919
3048
  * Implements the IWalletConnectSigner interface for Hedera ledger.
2920
3049
  * Handles Hedera-specific JSON-RPC methods and transaction formats.
2921
3050
  */
2922
- const logger$g = getLogger().scoped?.('HederaSigner') ?? getLogger();
3051
+ const logger$h = getLogger().scoped?.('HederaSigner') ?? getLogger();
2923
3052
  /**
2924
3053
  * Extract a meaningful error message from various error shapes.
2925
3054
  * WalletConnect SDK throws errors that are not standard Error instances.
@@ -2937,7 +3066,7 @@ const logger$g = getLogger().scoped?.('HederaSigner') ?? getLogger();
2937
3066
  */
2938
3067
  function extractErrorMessage$1(error) {
2939
3068
  // Log the raw error for debugging
2940
- logger$g.debug('Extracting error message', {
3069
+ logger$h.debug('Extracting error message', {
2941
3070
  errorType: typeof error,
2942
3071
  isError: error instanceof Error,
2943
3072
  constructorName: error?.constructor?.name,
@@ -2975,7 +3104,7 @@ function extractErrorMessage$1(error) {
2975
3104
  propDebug[prop] = '[err]';
2976
3105
  }
2977
3106
  }
2978
- logger$g.error('WC Error object dump', propDebug);
3107
+ logger$h.error('WC Error object dump', propDebug);
2979
3108
  // Check for code property first (common in SDK errors like PIN_REQUIRED)
2980
3109
  if (typeof errorObj['code'] === 'string') {
2981
3110
  const codeMsg = errorObj['message']
@@ -3056,7 +3185,7 @@ function extractErrorMessage$1(error) {
3056
3185
  }
3057
3186
  // Try getting own property names (includes non-enumerable)
3058
3187
  const ownProps = Object.getOwnPropertyNames(errorObj);
3059
- logger$g.debug('Error object properties', { props: ownProps });
3188
+ logger$h.debug('Error object properties', { props: ownProps });
3060
3189
  if (ownProps.length > 0) {
3061
3190
  // Try to read ALL properties for better debugging
3062
3191
  const propValues = [];
@@ -3077,7 +3206,7 @@ function extractErrorMessage$1(error) {
3077
3206
  propValues.push(k);
3078
3207
  }
3079
3208
  }
3080
- logger$g.debug('Error property values', { values: propValues });
3209
+ logger$h.debug('Error property values', { values: propValues });
3081
3210
  // Return a more informative error
3082
3211
  return `Error with properties: ${propValues.slice(0, 5).join(', ')}`;
3083
3212
  }
@@ -3090,7 +3219,7 @@ function extractErrorMessage$1(error) {
3090
3219
  }
3091
3220
  }
3092
3221
  // Last resort - log what we know about the object
3093
- logger$g.warn('Could not extract error message', {
3222
+ logger$h.warn('Could not extract error message', {
3094
3223
  constructor: error?.constructor?.name,
3095
3224
  prototype: Object.getPrototypeOf(error)?.constructor?.name,
3096
3225
  });
@@ -3189,13 +3318,13 @@ class HederaSigner {
3189
3318
  Object.keys(error).length === 0 &&
3190
3319
  !(error instanceof Error);
3191
3320
  if (isEmptyError) {
3192
- logger$g.warn('WalletConnect SDK empty error - relay subscription may have been stale', {
3321
+ logger$h.warn('WalletConnect SDK empty error - relay subscription may have been stale', {
3193
3322
  topic: params.topic?.substring(0, 16) + '...',
3194
3323
  });
3195
3324
  throw new Error('WalletConnect connection issue - please try again');
3196
3325
  }
3197
3326
  const errorMsg = extractErrorMessage$1(error);
3198
- logger$g.error('Sign failed', { error: errorMsg });
3327
+ logger$h.error('Sign failed', { error: errorMsg });
3199
3328
  throw new Error(`Hedera sign failed: ${errorMsg}`);
3200
3329
  }
3201
3330
  }
@@ -3211,7 +3340,7 @@ class HederaSigner {
3211
3340
  const network = params.networkId.includes('mainnet') ? 'mainnet' : 'testnet';
3212
3341
  // Format account ID in HIP-30 format
3213
3342
  const signerAccountId = `hedera:${network}:${params.accountAddress}`;
3214
- logger$g.debug('Sending hedera_signAndExecuteTransaction request', {
3343
+ logger$h.debug('Sending hedera_signAndExecuteTransaction request', {
3215
3344
  topic: params.topic?.substring(0, 16) + '...',
3216
3345
  chainId: `hedera:${network}`,
3217
3346
  signerAccountId,
@@ -3239,7 +3368,7 @@ class HederaSigner {
3239
3368
  try {
3240
3369
  // Race between the request and our timeout
3241
3370
  const result = await Promise.race([requestPromise, timeoutPromise]);
3242
- logger$g.debug('Received hedera_signAndExecuteTransaction response', {
3371
+ logger$h.debug('Received hedera_signAndExecuteTransaction response', {
3243
3372
  hasResult: !!result,
3244
3373
  resultKeys: result ? Object.keys(result) : [],
3245
3374
  });
@@ -3272,7 +3401,7 @@ class HederaSigner {
3272
3401
  // Get all own property names
3273
3402
  ownProps: error && typeof error === 'object' ? Object.getOwnPropertyNames(error) : [],
3274
3403
  };
3275
- logger$g.error('Submit failed - full error analysis', errorInfo);
3404
+ logger$h.error('Submit failed - full error analysis', errorInfo);
3276
3405
  // Check if this is an empty error object (WalletConnect SDK bug)
3277
3406
  // This typically happens when relay subscription is stale
3278
3407
  const isEmptyError = typeof error === 'object' &&
@@ -3284,7 +3413,7 @@ class HederaSigner {
3284
3413
  // It usually means the relay subscription was stale
3285
3414
  // The SessionHealthManager should have pinged before the request,
3286
3415
  // but if we still get this error, the subscription dropped after the ping
3287
- logger$g.warn('WalletConnect SDK empty error - relay subscription may have been stale', {
3416
+ logger$h.warn('WalletConnect SDK empty error - relay subscription may have been stale', {
3288
3417
  topic: params.topic?.substring(0, 16) + '...',
3289
3418
  hint: 'This can happen when the relay WebSocket connection drops',
3290
3419
  });
@@ -3294,7 +3423,7 @@ class HederaSigner {
3294
3423
  'please check your transaction history as it may have been executed successfully.');
3295
3424
  }
3296
3425
  const errorMsg = extractErrorMessage$1(error);
3297
- logger$g.error('Submit failed', { error: errorMsg });
3426
+ logger$h.error('Submit failed', { error: errorMsg });
3298
3427
  throw new Error(`Hedera submit failed: ${errorMsg}`);
3299
3428
  }
3300
3429
  }
@@ -3351,13 +3480,13 @@ class HederaSigner {
3351
3480
  Object.keys(error).length === 0 &&
3352
3481
  !(error instanceof Error);
3353
3482
  if (isEmptyError) {
3354
- logger$g.warn('WalletConnect SDK empty error - relay subscription may have been stale', {
3483
+ logger$h.warn('WalletConnect SDK empty error - relay subscription may have been stale', {
3355
3484
  topic: params.topic?.substring(0, 16) + '...',
3356
3485
  });
3357
3486
  throw new Error('WalletConnect connection issue - please try again');
3358
3487
  }
3359
3488
  const errorMsg = extractErrorMessage$1(error);
3360
- logger$g.error('Sign message failed', { error: errorMsg });
3489
+ logger$h.error('Sign message failed', { error: errorMsg });
3361
3490
  throw new Error(`Hedera sign message failed: ${errorMsg}`);
3362
3491
  }
3363
3492
  }
@@ -3375,15 +3504,15 @@ class HederaSigner {
3375
3504
  */
3376
3505
  parseAccounts(namespace, targetNetworkId) {
3377
3506
  if (!namespace) {
3378
- logger$g.warn('Namespace is null or undefined');
3507
+ logger$h.warn('Namespace is null or undefined');
3379
3508
  return [];
3380
3509
  }
3381
3510
  if (!namespace.accounts) {
3382
- logger$g.warn('Namespace has no accounts property');
3511
+ logger$h.warn('Namespace has no accounts property');
3383
3512
  return [];
3384
3513
  }
3385
3514
  if (!Array.isArray(namespace.accounts)) {
3386
- logger$g.warn('Namespace accounts is not an array', {
3515
+ logger$h.warn('Namespace accounts is not an array', {
3387
3516
  type: typeof namespace.accounts,
3388
3517
  });
3389
3518
  return [];
@@ -3393,7 +3522,7 @@ class HederaSigner {
3393
3522
  // HIP-30 format: hedera:testnet:0.0.12345
3394
3523
  const parts = account.split(':');
3395
3524
  if (parts.length < 3) {
3396
- logger$g.warn('Invalid account format', { account, partsLength: parts.length });
3525
+ logger$h.warn('Invalid account format', { account, partsLength: parts.length });
3397
3526
  return { address: account, chainId: 'hedera:testnet' };
3398
3527
  }
3399
3528
  return {
@@ -3406,7 +3535,7 @@ class HederaSigner {
3406
3535
  const targetNetwork = targetNetworkId.split(':')[1]?.toLowerCase(); // e.g., 'mainnet'
3407
3536
  if (targetNetwork) {
3408
3537
  const filteredAccounts = allAccounts.filter((acc) => acc.chainId.toLowerCase().includes(targetNetwork));
3409
- logger$g.debug('Filtered accounts by target network', {
3538
+ logger$h.debug('Filtered accounts by target network', {
3410
3539
  targetNetworkId,
3411
3540
  targetNetwork,
3412
3541
  totalAccounts: allAccounts.length,
@@ -3414,7 +3543,7 @@ class HederaSigner {
3414
3543
  });
3415
3544
  // If no accounts match the target network, log a warning
3416
3545
  if (filteredAccounts.length === 0 && allAccounts.length > 0) {
3417
- logger$g.warn('No accounts found for target network', {
3546
+ logger$h.warn('No accounts found for target network', {
3418
3547
  targetNetwork,
3419
3548
  availableNetworks: [...new Set(allAccounts.map((a) => a.chainId))],
3420
3549
  });
@@ -3442,7 +3571,7 @@ class HederaSigner {
3442
3571
  * Implements the IWalletConnectSigner interface for XRPL ledger.
3443
3572
  * Handles XRPL-specific JSON-RPC methods and transaction formats.
3444
3573
  */
3445
- const logger$f = getLogger().scoped?.('XrplSigner') ?? getLogger();
3574
+ const logger$g = getLogger().scoped?.('XrplSigner') ?? getLogger();
3446
3575
  /**
3447
3576
  * Extract a meaningful error message from various error shapes.
3448
3577
  * WalletConnect SDK throws errors that are not standard Error instances.
@@ -3460,7 +3589,7 @@ const logger$f = getLogger().scoped?.('XrplSigner') ?? getLogger();
3460
3589
  */
3461
3590
  function extractErrorMessage(error) {
3462
3591
  // Log raw error for debugging
3463
- logger$f.debug('Raw error object', {
3592
+ logger$g.debug('Raw error object', {
3464
3593
  errorType: typeof error,
3465
3594
  isError: error instanceof Error,
3466
3595
  errorKeys: typeof error === 'object' && error !== null ? Object.keys(error) : [],
@@ -3596,7 +3725,7 @@ class XrplSigner {
3596
3725
  */
3597
3726
  async signTransaction(params) {
3598
3727
  // Decode base64 payload to JSON transaction
3599
- logger$f.debug('Decoding XRPL transaction payload', {
3728
+ logger$g.debug('Decoding XRPL transaction payload', {
3600
3729
  payloadLength: params.payload?.length,
3601
3730
  networkId: params.networkId,
3602
3731
  topic: params.topic?.substring(0, 16) + '...',
@@ -3604,19 +3733,19 @@ class XrplSigner {
3604
3733
  let transaction;
3605
3734
  try {
3606
3735
  transaction = XrplTransactionEncoder.decodeTransaction(params.payload);
3607
- logger$f.debug('Transaction decoded successfully', {
3736
+ logger$g.debug('Transaction decoded successfully', {
3608
3737
  transactionType: transaction?.TransactionType,
3609
3738
  account: transaction?.Account,
3610
3739
  });
3611
3740
  }
3612
3741
  catch (decodeError) {
3613
- logger$f.error('Failed to decode transaction payload', {
3742
+ logger$g.error('Failed to decode transaction payload', {
3614
3743
  error: decodeError instanceof Error ? decodeError.message : String(decodeError),
3615
3744
  });
3616
3745
  throw decodeError;
3617
3746
  }
3618
3747
  try {
3619
- logger$f.debug('Sending xrpl_signTransaction request to wallet', {
3748
+ logger$g.debug('Sending xrpl_signTransaction request to wallet', {
3620
3749
  method: 'xrpl_signTransaction',
3621
3750
  chainId: params.networkId,
3622
3751
  topic: params.topic?.substring(0, 16) + '...',
@@ -3633,7 +3762,7 @@ class XrplSigner {
3633
3762
  },
3634
3763
  expiry: 300, // 5 minutes in seconds
3635
3764
  });
3636
- logger$f.debug('Received response from wallet', {
3765
+ logger$g.debug('Received response from wallet', {
3637
3766
  hasResult: !!result,
3638
3767
  resultKeys: result ? Object.keys(result) : [],
3639
3768
  });
@@ -3649,13 +3778,13 @@ class XrplSigner {
3649
3778
  Object.keys(error).length === 0 &&
3650
3779
  !(error instanceof Error);
3651
3780
  if (isEmptyError) {
3652
- logger$f.warn('WalletConnect SDK empty error - relay subscription may have been stale', {
3781
+ logger$g.warn('WalletConnect SDK empty error - relay subscription may have been stale', {
3653
3782
  topic: params.topic?.substring(0, 16) + '...',
3654
3783
  });
3655
3784
  throw new Error('WalletConnect connection issue - please try again');
3656
3785
  }
3657
3786
  const errorMsg = extractErrorMessage(error);
3658
- logger$f.error('Sign failed', { error: errorMsg });
3787
+ logger$g.error('Sign failed', { error: errorMsg });
3659
3788
  throw new Error(`XRPL sign failed: ${errorMsg}`);
3660
3789
  }
3661
3790
  }
@@ -3670,7 +3799,7 @@ class XrplSigner {
3670
3799
  // Decode base64 payload to JSON transaction
3671
3800
  const transaction = XrplTransactionEncoder.decodeTransaction(params.payload);
3672
3801
  try {
3673
- logger$f.debug('Sending xrpl_signAndSubmit request to wallet', {
3802
+ logger$g.debug('Sending xrpl_signAndSubmit request to wallet', {
3674
3803
  method: 'xrpl_signAndSubmit',
3675
3804
  chainId: params.networkId,
3676
3805
  topic: params.topic?.substring(0, 16) + '...',
@@ -3687,7 +3816,7 @@ class XrplSigner {
3687
3816
  },
3688
3817
  expiry: 300, // 5 minutes in seconds
3689
3818
  });
3690
- logger$f.debug('Received xrpl_signAndSubmit response', {
3819
+ logger$g.debug('Received xrpl_signAndSubmit response', {
3691
3820
  hasResult: !!result,
3692
3821
  resultKeys: result ? Object.keys(result) : [],
3693
3822
  });
@@ -3709,14 +3838,14 @@ class XrplSigner {
3709
3838
  if (isEmptyError) {
3710
3839
  // Empty error object is a known WalletConnect SDK issue
3711
3840
  // It usually means the relay subscription was stale
3712
- logger$f.warn('WalletConnect SDK empty error - relay subscription may have been stale', {
3841
+ logger$g.warn('WalletConnect SDK empty error - relay subscription may have been stale', {
3713
3842
  topic: params.topic?.substring(0, 16) + '...',
3714
3843
  hint: 'This can happen when the relay WebSocket connection drops',
3715
3844
  });
3716
3845
  throw new Error('WalletConnect connection issue - please try again');
3717
3846
  }
3718
3847
  const errorMsg = extractErrorMessage(error);
3719
- logger$f.error('Submit failed', { error: errorMsg });
3848
+ logger$g.error('Submit failed', { error: errorMsg });
3720
3849
  throw new Error(`XRPL submit failed: ${errorMsg}`);
3721
3850
  }
3722
3851
  }
@@ -3766,13 +3895,13 @@ class XrplSigner {
3766
3895
  Object.keys(error).length === 0 &&
3767
3896
  !(error instanceof Error);
3768
3897
  if (isEmptyError) {
3769
- logger$f.warn('WalletConnect SDK empty error - relay subscription may have been stale', {
3898
+ logger$g.warn('WalletConnect SDK empty error - relay subscription may have been stale', {
3770
3899
  topic: params.topic?.substring(0, 16) + '...',
3771
3900
  });
3772
3901
  throw new Error('WalletConnect connection issue - please try again');
3773
3902
  }
3774
3903
  const errorMsg = extractErrorMessage(error);
3775
- logger$f.error('Sign message failed', { error: errorMsg });
3904
+ logger$g.error('Sign message failed', { error: errorMsg });
3776
3905
  throw new Error(`XRPL sign message failed: ${errorMsg}`);
3777
3906
  }
3778
3907
  }
@@ -3797,7 +3926,7 @@ class XrplSigner {
3797
3926
  // XRPL format: xrpl:testnet:rN7n7otQDd6FczFgLdlqtyMVrn3WnFBrDB
3798
3927
  const parts = account.split(':');
3799
3928
  if (parts.length < 3) {
3800
- logger$f.warn('Invalid account format', { account });
3929
+ logger$g.warn('Invalid account format', { account });
3801
3930
  return { address: account, chainId: 'xrpl:testnet' };
3802
3931
  }
3803
3932
  return {
@@ -3810,7 +3939,7 @@ class XrplSigner {
3810
3939
  const targetNetwork = targetNetworkId.split(':')[1]?.toLowerCase(); // e.g., 'mainnet'
3811
3940
  if (targetNetwork) {
3812
3941
  const filteredAccounts = allAccounts.filter((acc) => acc.chainId.toLowerCase().includes(targetNetwork));
3813
- logger$f.debug('Filtered accounts by target network', {
3942
+ logger$g.debug('Filtered accounts by target network', {
3814
3943
  targetNetworkId,
3815
3944
  targetNetwork,
3816
3945
  totalAccounts: allAccounts.length,
@@ -3818,7 +3947,7 @@ class XrplSigner {
3818
3947
  });
3819
3948
  // If no accounts match the target network, log a warning
3820
3949
  if (filteredAccounts.length === 0 && allAccounts.length > 0) {
3821
- logger$f.warn('No accounts found for target network', {
3950
+ logger$g.warn('No accounts found for target network', {
3822
3951
  targetNetwork,
3823
3952
  availableNetworks: [...new Set(allAccounts.map((a) => a.chainId))],
3824
3953
  });
@@ -3850,7 +3979,7 @@ class XrplSigner {
3850
3979
  * 1. Implementing IWalletConnectSigner interface
3851
3980
  * 2. Registering the signer with SignerFactory
3852
3981
  */
3853
- const logger$e = getLogger().scoped?.('SignerFactory') ?? getLogger();
3982
+ const logger$f = getLogger().scoped?.('SignerFactory') ?? getLogger();
3854
3983
  /**
3855
3984
  * Factory class for creating and managing WalletConnect signers.
3856
3985
  *
@@ -3892,13 +4021,13 @@ class SignerFactory {
3892
4021
  */
3893
4022
  static registerSigner(ledgerId, signer) {
3894
4023
  if (signer.ledgerId !== ledgerId) {
3895
- logger$e.warn('Signer ledgerId does not match registration key', {
4024
+ logger$f.warn('Signer ledgerId does not match registration key', {
3896
4025
  signerLedgerId: signer.ledgerId,
3897
4026
  registrationKey: ledgerId,
3898
4027
  });
3899
4028
  }
3900
4029
  this.signers.set(ledgerId, signer);
3901
- logger$e.debug('Registered signer for ledger', { ledgerId });
4030
+ logger$f.debug('Registered signer for ledger', { ledgerId });
3902
4031
  }
3903
4032
  /**
3904
4033
  * Check if a signer is registered for a ledger.
@@ -3927,7 +4056,7 @@ class SignerFactory {
3927
4056
  static unregisterSigner(ledgerId) {
3928
4057
  const removed = this.signers.delete(ledgerId);
3929
4058
  if (removed) {
3930
- logger$e.debug('Unregistered signer for ledger', { ledgerId });
4059
+ logger$f.debug('Unregistered signer for ledger', { ledgerId });
3931
4060
  }
3932
4061
  return removed;
3933
4062
  }
@@ -3956,7 +4085,7 @@ class SignerFactory {
3956
4085
  * - Automatic ping cache management
3957
4086
  * - Subscription refresh capability
3958
4087
  */
3959
- const logger$d = getLogger().scoped?.('WCSessionHealth') ?? getLogger();
4088
+ const logger$e = getLogger().scoped?.('WCSessionHealth') ?? getLogger();
3960
4089
  /**
3961
4090
  * Manages WalletConnect session health to prevent stale relay subscription issues.
3962
4091
  *
@@ -3987,7 +4116,7 @@ class SessionHealthManager {
3987
4116
  constructor(client) {
3988
4117
  this.client = client;
3989
4118
  this.setupRelayMonitoring();
3990
- logger$d.info('SessionHealthManager initialized');
4119
+ logger$e.info('SessionHealthManager initialized');
3991
4120
  }
3992
4121
  /**
3993
4122
  * Ensure session is healthy before making a request.
@@ -4005,14 +4134,14 @@ class SessionHealthManager {
4005
4134
  const now = Date.now();
4006
4135
  // Skip if we pinged recently
4007
4136
  if (now - lastPing <= this.PING_INTERVAL_MS) {
4008
- logger$d.debug('Skipping ping - recent ping exists', {
4137
+ logger$e.debug('Skipping ping - recent ping exists', {
4009
4138
  topic: topic.substring(0, 16) + '...',
4010
4139
  lastPingAge: now - lastPing,
4011
4140
  });
4012
4141
  return;
4013
4142
  }
4014
4143
  try {
4015
- logger$d.debug('Pinging session to ensure relay subscription', {
4144
+ logger$e.debug('Pinging session to ensure relay subscription', {
4016
4145
  topic: topic.substring(0, 16) + '...',
4017
4146
  });
4018
4147
  // Race ping against timeout
@@ -4021,14 +4150,14 @@ class SessionHealthManager {
4021
4150
  new Promise((_, reject) => setTimeout(() => reject(new Error('Ping timeout')), this.PING_TIMEOUT_MS)),
4022
4151
  ]);
4023
4152
  this.lastPingTime.set(topic, now);
4024
- logger$d.debug('Session ping successful', {
4153
+ logger$e.debug('Session ping successful', {
4025
4154
  topic: topic.substring(0, 16) + '...',
4026
4155
  });
4027
4156
  }
4028
4157
  catch (err) {
4029
4158
  // Log warning but don't throw - let the request attempt proceed
4030
4159
  // The request might still succeed if the subscription is actually active
4031
- logger$d.warn('Session ping failed - relay subscription may be stale', {
4160
+ logger$e.warn('Session ping failed - relay subscription may be stale', {
4032
4161
  topic: topic.substring(0, 16) + '...',
4033
4162
  error: err instanceof Error ? err.message : String(err),
4034
4163
  });
@@ -4050,16 +4179,16 @@ class SessionHealthManager {
4050
4179
  await relayer.subscribe(topic);
4051
4180
  // Clear ping cache so next ensureSessionHealth will ping
4052
4181
  this.lastPingTime.delete(topic);
4053
- logger$d.info('Refreshed relay subscription', {
4182
+ logger$e.info('Refreshed relay subscription', {
4054
4183
  topic: topic.substring(0, 16) + '...',
4055
4184
  });
4056
4185
  }
4057
4186
  else {
4058
- logger$d.warn('Relayer.subscribe not available');
4187
+ logger$e.warn('Relayer.subscribe not available');
4059
4188
  }
4060
4189
  }
4061
4190
  catch (err) {
4062
- logger$d.warn('Failed to refresh subscription', {
4191
+ logger$e.warn('Failed to refresh subscription', {
4063
4192
  topic: topic.substring(0, 16) + '...',
4064
4193
  error: err instanceof Error ? err.message : String(err),
4065
4194
  });
@@ -4092,22 +4221,22 @@ class SessionHealthManager {
4092
4221
  // eslint-disable-next-line @typescript-eslint/no-explicit-any -- WalletConnect internal API not typed
4093
4222
  const relayer = this.client.core?.relayer;
4094
4223
  if (!relayer) {
4095
- logger$d.warn('Could not access relayer for monitoring');
4224
+ logger$e.warn('Could not access relayer for monitoring');
4096
4225
  return;
4097
4226
  }
4098
4227
  relayer.on('connect', () => {
4099
- logger$d.info('Relay WebSocket connected');
4228
+ logger$e.info('Relay WebSocket connected');
4100
4229
  });
4101
4230
  relayer.on('disconnect', () => {
4102
- logger$d.warn('Relay WebSocket disconnected - clearing ping cache');
4231
+ logger$e.warn('Relay WebSocket disconnected - clearing ping cache');
4103
4232
  this.lastPingTime.clear();
4104
4233
  });
4105
4234
  relayer.on('error', (err) => {
4106
- logger$d.error('Relay error', {
4235
+ logger$e.error('Relay error', {
4107
4236
  error: err?.message || String(err),
4108
4237
  });
4109
4238
  });
4110
- logger$d.debug('Relay monitoring setup complete');
4239
+ logger$e.debug('Relay monitoring setup complete');
4111
4240
  }
4112
4241
  }
4113
4242
 
@@ -4132,7 +4261,7 @@ class SessionHealthManager {
4132
4261
  *
4133
4262
  * Extracted from WalletConnectV2Provider to reduce file size.
4134
4263
  */
4135
- const logger$c = getLogger().scoped?.('WCClientManager') ?? getLogger();
4264
+ const logger$d = getLogger().scoped?.('WCClientManager') ?? getLogger();
4136
4265
  /**
4137
4266
  * Storage key for persisted projectId
4138
4267
  */
@@ -4159,7 +4288,7 @@ class WalletConnectClientManager {
4159
4288
  if (this.client && this.projectId === projectId) {
4160
4289
  return this.client;
4161
4290
  }
4162
- logger$c.debug('Initializing SignClient', { projectId: projectId.substring(0, 8) });
4291
+ logger$d.debug('Initializing SignClient', { projectId: projectId.substring(0, 8) });
4163
4292
  // Store projectId for session restoration
4164
4293
  this.projectId = projectId;
4165
4294
  this.persistProjectId(projectId);
@@ -4171,7 +4300,7 @@ class WalletConnectClientManager {
4171
4300
  });
4172
4301
  // Initialize session health manager for relay subscription management
4173
4302
  this.sessionHealth = new SessionHealthManager(this.client);
4174
- logger$c.info('SignClient initialized with session health manager');
4303
+ logger$d.info('SignClient initialized with session health manager');
4175
4304
  return this.client;
4176
4305
  }
4177
4306
  /**
@@ -4200,14 +4329,14 @@ class WalletConnectClientManager {
4200
4329
  async restoreClient(metadata) {
4201
4330
  const storedProjectId = this.getStoredProjectId();
4202
4331
  if (!storedProjectId) {
4203
- logger$c.debug('No stored projectId, skipping client restoration');
4332
+ logger$d.debug('No stored projectId, skipping client restoration');
4204
4333
  return undefined;
4205
4334
  }
4206
4335
  try {
4207
4336
  return await this.initialize(storedProjectId, metadata);
4208
4337
  }
4209
4338
  catch (error) {
4210
- logger$c.error('Failed to restore client', {
4339
+ logger$d.error('Failed to restore client', {
4211
4340
  error: error instanceof Error ? error.message : String(error),
4212
4341
  });
4213
4342
  return undefined;
@@ -4274,7 +4403,7 @@ class WalletConnectClientManager {
4274
4403
  if (sessionProperties) {
4275
4404
  connectParams.sessionProperties = sessionProperties;
4276
4405
  }
4277
- logger$c.debug('Connecting with params', {
4406
+ logger$d.debug('Connecting with params', {
4278
4407
  namespaces: Object.keys(optionalNamespaces),
4279
4408
  hasSessionProperties: !!sessionProperties,
4280
4409
  });
@@ -4340,7 +4469,7 @@ class WalletConnectClientManager {
4340
4469
  const startKeepAlive = () => {
4341
4470
  keepAliveInterval = setInterval(async () => {
4342
4471
  try {
4343
- logger$c.debug('Keep-alive ping during request', {
4472
+ logger$d.debug('Keep-alive ping during request', {
4344
4473
  topic: params.topic?.substring(0, 16) + '...',
4345
4474
  method: params.request.method,
4346
4475
  });
@@ -4353,7 +4482,7 @@ class WalletConnectClientManager {
4353
4482
  }
4354
4483
  catch (err) {
4355
4484
  // Log but don't throw - ping failure during wait is not critical
4356
- logger$c.debug('Keep-alive ping failed (non-critical)', {
4485
+ logger$d.debug('Keep-alive ping failed (non-critical)', {
4357
4486
  error: err instanceof Error ? err.message : String(err),
4358
4487
  });
4359
4488
  }
@@ -4395,7 +4524,7 @@ class WalletConnectClientManager {
4395
4524
  window.localStorage?.setItem(STORAGE_KEY_PROJECT_ID, projectId);
4396
4525
  }
4397
4526
  catch {
4398
- logger$c.warn('Failed to persist projectId');
4527
+ logger$d.warn('Failed to persist projectId');
4399
4528
  }
4400
4529
  }
4401
4530
  getStoredProjectId() {
@@ -4440,7 +4569,7 @@ class WalletConnectClientManager {
4440
4569
  * - Aggregate accounts across sessions
4441
4570
  * - Find sessions by account address
4442
4571
  */
4443
- const logger$b = getLogger().scoped?.('WCSessionStore') ?? getLogger();
4572
+ const logger$c = getLogger().scoped?.('WCSessionStore') ?? getLogger();
4444
4573
  /**
4445
4574
  * WalletConnect Session Store
4446
4575
  *
@@ -4478,7 +4607,7 @@ class WalletConnectSessionStore {
4478
4607
  */
4479
4608
  setSession(sessionKey, data) {
4480
4609
  this.sessions.set(sessionKey, data);
4481
- logger$b.debug('Session stored', { sessionKey, accountCount: data.accounts.length });
4610
+ logger$c.debug('Session stored', { sessionKey, accountCount: data.accounts.length });
4482
4611
  }
4483
4612
  /**
4484
4613
  * Delete a session by key.
@@ -4489,7 +4618,7 @@ class WalletConnectSessionStore {
4489
4618
  deleteSession(sessionKey) {
4490
4619
  const deleted = this.sessions.delete(sessionKey);
4491
4620
  if (deleted) {
4492
- logger$b.debug('Session deleted', { sessionKey });
4621
+ logger$c.debug('Session deleted', { sessionKey });
4493
4622
  }
4494
4623
  return deleted;
4495
4624
  }
@@ -4513,7 +4642,7 @@ class WalletConnectSessionStore {
4513
4642
  clear() {
4514
4643
  this.sessions.clear();
4515
4644
  this._accounts.set([]);
4516
- logger$b.debug('All sessions cleared');
4645
+ logger$c.debug('All sessions cleared');
4517
4646
  }
4518
4647
  /**
4519
4648
  * Get all session entries.
@@ -4554,7 +4683,7 @@ class WalletConnectSessionStore {
4554
4683
  for (const sessionData of this.sessions.values()) {
4555
4684
  allAccounts.push(...sessionData.accounts);
4556
4685
  }
4557
- logger$b.debug('Aggregated accounts', {
4686
+ logger$c.debug('Aggregated accounts', {
4558
4687
  sessionCount: this.sessions.size,
4559
4688
  totalAccounts: allAccounts.length,
4560
4689
  });
@@ -4590,7 +4719,7 @@ class WalletConnectSessionStore {
4590
4719
  for (const [sessionKey, sessionData] of this.sessions.entries()) {
4591
4720
  if (sessionData.session.topic === topic) {
4592
4721
  this.sessions.delete(sessionKey);
4593
- logger$b.info('Session removed by topic', { sessionKey, topic: topic.substring(0, 16) });
4722
+ logger$c.info('Session removed by topic', { sessionKey, topic: topic.substring(0, 16) });
4594
4723
  return { sessionKey, data: sessionData };
4595
4724
  }
4596
4725
  }
@@ -4638,7 +4767,7 @@ class WalletConnectSessionStore {
4638
4767
  *
4639
4768
  * Extracted from WalletConnectV2Provider to reduce file size.
4640
4769
  */
4641
- const logger$a = getLogger().scoped?.('WCSigningOrchestrator') ?? getLogger();
4770
+ const logger$b = getLogger().scoped?.('WCSigningOrchestrator') ?? getLogger();
4642
4771
  /**
4643
4772
  * Signing Orchestrator
4644
4773
  *
@@ -4669,7 +4798,7 @@ class WalletConnectSigningOrchestrator {
4669
4798
  const sessionInfo = this.findAndValidateSession(options.accountAddress, 'signTransaction');
4670
4799
  // Use user's selected network from session, with fallback to options.networkId
4671
4800
  const networkId = this.resolveNetworkId(sessionInfo, options.networkId);
4672
- logger$a.debug('Routing sign to signer', {
4801
+ logger$b.debug('Routing sign to signer', {
4673
4802
  ledgerId: sessionInfo.signer.ledgerId,
4674
4803
  topic: sessionInfo.session.topic.substring(0, 16) + '...',
4675
4804
  networkId,
@@ -4692,7 +4821,7 @@ class WalletConnectSigningOrchestrator {
4692
4821
  const sessionInfo = this.findAndValidateSession(options.accountAddress, 'submitTransaction');
4693
4822
  // Use user's selected network from session, with fallback to options.networkId
4694
4823
  const networkId = this.resolveNetworkId(sessionInfo, options.networkId);
4695
- logger$a.debug('Routing submit to signer', {
4824
+ logger$b.debug('Routing submit to signer', {
4696
4825
  ledgerId: sessionInfo.signer.ledgerId,
4697
4826
  topic: sessionInfo.session.topic.substring(0, 16) + '...',
4698
4827
  networkId,
@@ -4715,7 +4844,7 @@ class WalletConnectSigningOrchestrator {
4715
4844
  const sessionInfo = this.findAndValidateSession(options.accountAddress, 'signAndExecuteTransaction');
4716
4845
  // Use user's selected network from session, with fallback to options.networkId
4717
4846
  const networkId = this.resolveNetworkId(sessionInfo, options.networkId);
4718
- logger$a.debug('Routing signAndExecute to signer', {
4847
+ logger$b.debug('Routing signAndExecute to signer', {
4719
4848
  ledgerId: sessionInfo.signer.ledgerId,
4720
4849
  topic: sessionInfo.session.topic.substring(0, 16) + '...',
4721
4850
  networkId,
@@ -4756,7 +4885,7 @@ class WalletConnectSigningOrchestrator {
4756
4885
  const sessionInfo = this.findAndValidateSession(options.accountAddress, 'signMessage');
4757
4886
  // Use user's selected network from session, with fallback to options.networkId
4758
4887
  const networkId = this.resolveNetworkId(sessionInfo, options.networkId);
4759
- logger$a.debug('Routing signMessage to signer', {
4888
+ logger$b.debug('Routing signMessage to signer', {
4760
4889
  ledgerId: sessionInfo.signer.ledgerId,
4761
4890
  topic: sessionInfo.session.topic.substring(0, 16) + '...',
4762
4891
  networkId,
@@ -4797,7 +4926,7 @@ class WalletConnectSigningOrchestrator {
4797
4926
  if (optionsNetworkId &&
4798
4927
  sessionInfo.userSelectedNetwork &&
4799
4928
  optionsNetworkId !== sessionInfo.userSelectedNetwork) {
4800
- logger$a.warn('Network mismatch: using session network over caller-provided network', {
4929
+ logger$b.warn('Network mismatch: using session network over caller-provided network', {
4801
4930
  callerNetwork: optionsNetworkId,
4802
4931
  sessionNetwork: sessionInfo.userSelectedNetwork,
4803
4932
  using: resolvedNetwork,
@@ -4817,7 +4946,7 @@ class WalletConnectSigningOrchestrator {
4817
4946
  }
4818
4947
  // Validate session exists in WC SDK
4819
4948
  if (!this.validateSessionInSdk(sessionInfo.session.topic)) {
4820
- logger$a.error('Session not found in WC SDK', {
4949
+ logger$b.error('Session not found in WC SDK', {
4821
4950
  topic: sessionInfo.session.topic.substring(0, 16) + '...',
4822
4951
  account: accountAddress,
4823
4952
  });
@@ -4844,7 +4973,7 @@ class WalletConnectSigningOrchestrator {
4844
4973
  return !!session;
4845
4974
  }
4846
4975
  catch (error) {
4847
- logger$a.warn('Session validation failed', {
4976
+ logger$b.warn('Session validation failed', {
4848
4977
  topic: topic.substring(0, 16) + '...',
4849
4978
  error: error instanceof Error ? error.message : String(error),
4850
4979
  });
@@ -4880,7 +5009,7 @@ class WalletConnectSigningOrchestrator {
4880
5009
  * - Testable (mock signers for unit tests)
4881
5010
  * - Maintainable (ledger logic is isolated)
4882
5011
  */
4883
- const logger$9 = getLogger().scoped?.('WalletConnectV2Provider') ?? getLogger();
5012
+ const logger$a = getLogger().scoped?.('WalletConnectV2Provider') ?? getLogger();
4884
5013
  /**
4885
5014
  * Storage key prefix for persisting user's network selection per session topic.
4886
5015
  * This is critical for proper session restoration after page reload.
@@ -4944,7 +5073,7 @@ class WalletConnectV2Provider extends BaseWalletProvider {
4944
5073
  clientManager: this.clientManager,
4945
5074
  eventBus: this.eventBus,
4946
5075
  });
4947
- logger$9.info('Initializing - will attempt session restoration');
5076
+ logger$a.info('Initializing - will attempt session restoration');
4948
5077
  void this.restoreSession();
4949
5078
  }
4950
5079
  /**
@@ -4971,7 +5100,7 @@ class WalletConnectV2Provider extends BaseWalletProvider {
4971
5100
  */
4972
5101
  async restoreSession() {
4973
5102
  try {
4974
- logger$9.debug('Attempting to restore sessions...');
5103
+ logger$a.debug('Attempting to restore sessions...');
4975
5104
  // Restore client from stored projectId
4976
5105
  const client = await this.clientManager.restoreClient({
4977
5106
  name: 'HSuite Demo',
@@ -4986,7 +5115,7 @@ class WalletConnectV2Provider extends BaseWalletProvider {
4986
5115
  this.registerSessionDeleteListener();
4987
5116
  // Get all active sessions
4988
5117
  const activeSessions = this.clientManager.getActiveSessions();
4989
- logger$9.info('Found active sessions', { count: activeSessions.length });
5118
+ logger$a.info('Found active sessions', { count: activeSessions.length });
4990
5119
  if (activeSessions.length === 0) {
4991
5120
  return;
4992
5121
  }
@@ -4996,7 +5125,7 @@ class WalletConnectV2Provider extends BaseWalletProvider {
4996
5125
  await this.restoreSingleSession(session);
4997
5126
  }
4998
5127
  catch (error) {
4999
- logger$9.error('Failed to restore session', {
5128
+ logger$a.error('Failed to restore session', {
5000
5129
  topic: session.topic,
5001
5130
  error: error instanceof Error ? error.message : String(error),
5002
5131
  });
@@ -5006,11 +5135,11 @@ class WalletConnectV2Provider extends BaseWalletProvider {
5006
5135
  this.sessionStore.updateAggregatedAccounts();
5007
5136
  if (this.sessionStore.size > 0) {
5008
5137
  this._status.set('connected');
5009
- logger$9.info('Restored sessions', { count: this.sessionStore.size });
5138
+ logger$a.info('Restored sessions', { count: this.sessionStore.size });
5010
5139
  }
5011
5140
  }
5012
5141
  catch (error) {
5013
- logger$9.error('Failed to restore sessions', {
5142
+ logger$a.error('Failed to restore sessions', {
5014
5143
  error: error instanceof Error ? error.message : String(error),
5015
5144
  });
5016
5145
  }
@@ -5025,23 +5154,23 @@ class WalletConnectV2Provider extends BaseWalletProvider {
5025
5154
  * @param session - WalletConnect session object from IndexedDB
5026
5155
  */
5027
5156
  async restoreSingleSession(session) {
5028
- logger$9.debug('Restoring session', { topic: session.topic });
5029
- logger$9.debug('Session namespaces', { namespaces: Object.keys(session.namespaces) });
5157
+ logger$a.debug('Restoring session', { topic: session.topic });
5158
+ logger$a.debug('Session namespaces', { namespaces: Object.keys(session.namespaces) });
5030
5159
  // Determine ledger from session namespaces
5031
5160
  let ledgerId;
5032
5161
  let walletReportedNetwork;
5033
5162
  if (session.namespaces.hedera) {
5034
5163
  ledgerId = 'hedera';
5035
5164
  walletReportedNetwork = session.namespaces.hedera.chains?.[0] || 'hedera:testnet';
5036
- logger$9.debug('Found Hedera namespace', { chains: session.namespaces.hedera.chains });
5165
+ logger$a.debug('Found Hedera namespace', { chains: session.namespaces.hedera.chains });
5037
5166
  }
5038
5167
  else if (session.namespaces.xrpl) {
5039
5168
  ledgerId = 'xrpl';
5040
5169
  walletReportedNetwork = session.namespaces.xrpl.chains?.[0] || 'xrpl:testnet';
5041
- logger$9.debug('Found XRPL namespace', { chains: session.namespaces.xrpl.chains });
5170
+ logger$a.debug('Found XRPL namespace', { chains: session.namespaces.xrpl.chains });
5042
5171
  }
5043
5172
  if (!ledgerId || !walletReportedNetwork) {
5044
- logger$9.warn('Could not determine ledger for session', {
5173
+ logger$a.warn('Could not determine ledger for session', {
5045
5174
  topic: session.topic,
5046
5175
  availableNamespaces: Object.keys(session.namespaces),
5047
5176
  });
@@ -5052,14 +5181,14 @@ class WalletConnectV2Provider extends BaseWalletProvider {
5052
5181
  const userSelectedNetwork = this.getUserNetworkSelection(session.topic);
5053
5182
  const networkId = userSelectedNetwork || walletReportedNetwork;
5054
5183
  if (userSelectedNetwork) {
5055
- logger$9.debug('Restored user network selection', {
5184
+ logger$a.debug('Restored user network selection', {
5056
5185
  userSelectedNetwork,
5057
5186
  walletReportedNetwork,
5058
5187
  topic: session.topic.substring(0, 16),
5059
5188
  });
5060
5189
  }
5061
5190
  else {
5062
- logger$9.warn('No stored network selection found, using wallet-reported network', {
5191
+ logger$a.warn('No stored network selection found, using wallet-reported network', {
5063
5192
  walletReportedNetwork,
5064
5193
  topic: session.topic.substring(0, 16),
5065
5194
  });
@@ -5070,18 +5199,18 @@ class WalletConnectV2Provider extends BaseWalletProvider {
5070
5199
  const sessionKey = this.sessionStore.generateSessionKey(ledgerId, networkId, session.topic);
5071
5200
  // Parse accounts from session, filtering by user's selected network
5072
5201
  const namespace = session.namespaces[ledgerId];
5073
- logger$9.debug('Namespace for restoration', {
5202
+ logger$a.debug('Namespace for restoration', {
5074
5203
  ledgerId,
5075
5204
  accountCount: namespace?.accounts?.length || 0,
5076
5205
  });
5077
5206
  // Pass the user's selected network to filter accounts appropriately
5078
5207
  const parsedAccounts = signer.parseAccounts(namespace, userSelectedNetwork);
5079
- logger$9.debug('Parsed accounts from restored session', {
5208
+ logger$a.debug('Parsed accounts from restored session', {
5080
5209
  count: parsedAccounts.length,
5081
5210
  userSelectedNetwork,
5082
5211
  });
5083
5212
  if (parsedAccounts.length === 0) {
5084
- logger$9.warn('Restored session has no accounts for selected network', {
5213
+ logger$a.warn('Restored session has no accounts for selected network', {
5085
5214
  userSelectedNetwork,
5086
5215
  walletReportedNetwork,
5087
5216
  });
@@ -5113,7 +5242,7 @@ class WalletConnectV2Provider extends BaseWalletProvider {
5113
5242
  signer,
5114
5243
  accounts,
5115
5244
  });
5116
- logger$9.info('Restored session', {
5245
+ logger$a.info('Restored session', {
5117
5246
  sessionKey,
5118
5247
  ledgerId,
5119
5248
  networkId,
@@ -5140,13 +5269,13 @@ class WalletConnectV2Provider extends BaseWalletProvider {
5140
5269
  storeUserNetworkSelection(sessionTopic, networkId) {
5141
5270
  try {
5142
5271
  localStorage.setItem(`${NETWORK_SELECTION_STORAGE_KEY}${sessionTopic}`, networkId);
5143
- logger$9.debug('Stored user network selection', {
5272
+ logger$a.debug('Stored user network selection', {
5144
5273
  topic: sessionTopic.substring(0, 16),
5145
5274
  networkId,
5146
5275
  });
5147
5276
  }
5148
5277
  catch (e) {
5149
- logger$9.warn('Failed to store network selection', { error: e.message });
5278
+ logger$a.warn('Failed to store network selection', { error: e.message });
5150
5279
  }
5151
5280
  }
5152
5281
  /**
@@ -5160,7 +5289,7 @@ class WalletConnectV2Provider extends BaseWalletProvider {
5160
5289
  return localStorage.getItem(`${NETWORK_SELECTION_STORAGE_KEY}${sessionTopic}`) || undefined;
5161
5290
  }
5162
5291
  catch (e) {
5163
- logger$9.warn('Failed to retrieve network selection', { error: e.message });
5292
+ logger$a.warn('Failed to retrieve network selection', { error: e.message });
5164
5293
  return undefined;
5165
5294
  }
5166
5295
  }
@@ -5206,7 +5335,7 @@ class WalletConnectV2Provider extends BaseWalletProvider {
5206
5335
  }
5207
5336
  // Get the appropriate signer for this ledger (Strategy Pattern)
5208
5337
  const signer = SignerFactory.getSigner(wcConfig.ledgerId);
5209
- logger$9.debug('Using signer for ledger', { ledgerId: wcConfig.ledgerId });
5338
+ logger$a.debug('Using signer for ledger', { ledgerId: wcConfig.ledgerId });
5210
5339
  // Initialize client via manager
5211
5340
  await this.clientManager.initialize(projectId, {
5212
5341
  name: wcConfig.appName || 'HSuite Demo',
@@ -5220,14 +5349,14 @@ class WalletConnectV2Provider extends BaseWalletProvider {
5220
5349
  // Build namespace configuration using signer
5221
5350
  const namespaceConfig = signer.buildNamespace(wcConfig.networkId);
5222
5351
  const optionalNamespaces = { [wcConfig.ledgerId]: namespaceConfig };
5223
- logger$9.debug('Namespace config', { ledgerId: wcConfig.ledgerId });
5352
+ logger$a.debug('Namespace config', { ledgerId: wcConfig.ledgerId });
5224
5353
  // Build session properties to pass user's preferred network to wallet
5225
5354
  // This tells the wallet which network accounts to show in the picker
5226
5355
  const sessionProperties = {
5227
5356
  preferredNetwork: wcConfig.networkId,
5228
5357
  preferredLedger: wcConfig.ledgerId,
5229
5358
  };
5230
- logger$9.info('Connecting with preferred network', {
5359
+ logger$a.info('Connecting with preferred network', {
5231
5360
  preferredNetwork: wcConfig.networkId,
5232
5361
  preferredLedger: wcConfig.ledgerId,
5233
5362
  });
@@ -5237,10 +5366,10 @@ class WalletConnectV2Provider extends BaseWalletProvider {
5237
5366
  await modal.openModal({ uri });
5238
5367
  }
5239
5368
  // Wait for wallet approval
5240
- logger$9.info('Waiting for wallet approval...');
5369
+ logger$a.info('Waiting for wallet approval...');
5241
5370
  const session = await approval();
5242
5371
  this.clientManager.closeModal();
5243
- logger$9.info('[WC:DAPP:APPROVED] Session approved by wallet', {
5372
+ logger$a.info('[WC:DAPP:APPROVED] Session approved by wallet', {
5244
5373
  topic: session.topic.substring(0, 16) + '...',
5245
5374
  fullTopic: session.topic,
5246
5375
  namespaces: Object.keys(session.namespaces),
@@ -5250,12 +5379,12 @@ class WalletConnectV2Provider extends BaseWalletProvider {
5250
5379
  const sessionKey = this.sessionStore.generateSessionKey(wcConfig.ledgerId, wcConfig.networkId, session.topic);
5251
5380
  // Parse accounts from session
5252
5381
  const sessionNamespace = session.namespaces[wcConfig.ledgerId];
5253
- logger$9.debug('Session namespace for ledger', {
5382
+ logger$a.debug('Session namespace for ledger', {
5254
5383
  ledgerId: wcConfig.ledgerId,
5255
5384
  accountCount: sessionNamespace?.accounts?.length || 0,
5256
5385
  });
5257
5386
  if (!sessionNamespace) {
5258
- logger$9.error('No namespace found for ledger', {
5387
+ logger$a.error('No namespace found for ledger', {
5259
5388
  ledgerId: wcConfig.ledgerId,
5260
5389
  availableNamespaces: Object.keys(session.namespaces),
5261
5390
  });
@@ -5264,12 +5393,12 @@ class WalletConnectV2Provider extends BaseWalletProvider {
5264
5393
  // Parse accounts from session namespace, filtering by user's selected network
5265
5394
  // This ensures we only show accounts that match the network the user selected
5266
5395
  const parsedAccounts = signer.parseAccounts(sessionNamespace, wcConfig.networkId);
5267
- logger$9.debug('Parsed accounts', {
5396
+ logger$a.debug('Parsed accounts', {
5268
5397
  count: parsedAccounts.length,
5269
5398
  userSelectedNetwork: wcConfig.networkId,
5270
5399
  });
5271
5400
  if (parsedAccounts.length === 0) {
5272
- logger$9.warn('No accounts returned from wallet - possible causes:', {
5401
+ logger$a.warn('No accounts returned from wallet - possible causes:', {
5273
5402
  reason1: 'Wallet has no accounts for the requested network',
5274
5403
  reason2: 'Wallet denied account sharing',
5275
5404
  reason3: 'Wallet returned accounts in unexpected format',
@@ -5308,7 +5437,7 @@ class WalletConnectV2Provider extends BaseWalletProvider {
5308
5437
  this.storeUserNetworkSelection(session.topic, wcConfig.networkId);
5309
5438
  // Verify session exists in WC SDK after storing
5310
5439
  const sdkSession = this.clientManager.getSession(session.topic);
5311
- logger$9.info('[WC:DAPP:STORED] Session stored locally', {
5440
+ logger$a.info('[WC:DAPP:STORED] Session stored locally', {
5312
5441
  sessionKey,
5313
5442
  topic: session.topic.substring(0, 16) + '...',
5314
5443
  fullTopic: session.topic,
@@ -5337,7 +5466,7 @@ class WalletConnectV2Provider extends BaseWalletProvider {
5337
5466
  catch (error) {
5338
5467
  this._status.set('error');
5339
5468
  this._error.set(error instanceof Error ? error.message : 'Connection failed');
5340
- logger$9.error('Connection failed', {
5469
+ logger$a.error('Connection failed', {
5341
5470
  error: error instanceof Error ? error.message : String(error),
5342
5471
  });
5343
5472
  // Emit provider error event
@@ -5402,14 +5531,14 @@ class WalletConnectV2Provider extends BaseWalletProvider {
5402
5531
  // WalletConnect events arrive outside Angular's zone
5403
5532
  this.clientManager.on('session_delete', (event) => {
5404
5533
  this.zone.run(() => {
5405
- logger$9.info('� Session deleted by wallet (session_delete event)', {
5534
+ logger$a.info('� Session deleted by wallet (session_delete event)', {
5406
5535
  topic: event.topic,
5407
5536
  });
5408
5537
  this.removeSessionByTopic(event.topic);
5409
5538
  });
5410
5539
  });
5411
5540
  this.sessionDeleteListenerRegistered = true;
5412
- logger$9.debug('session_delete listener registered');
5541
+ logger$a.debug('session_delete listener registered');
5413
5542
  }
5414
5543
  /**
5415
5544
  * Disconnect from WalletConnect sessions.
@@ -5419,7 +5548,7 @@ class WalletConnectV2Provider extends BaseWalletProvider {
5419
5548
  */
5420
5549
  async disconnect(sessionKey) {
5421
5550
  if (!this.clientManager.isInitialized()) {
5422
- logger$9.warn('No client to disconnect');
5551
+ logger$a.warn('No client to disconnect');
5423
5552
  return;
5424
5553
  }
5425
5554
  if (sessionKey) {
@@ -5431,10 +5560,10 @@ class WalletConnectV2Provider extends BaseWalletProvider {
5431
5560
  code: 6000,
5432
5561
  message: 'User disconnected session',
5433
5562
  });
5434
- logger$9.info('Disconnected session', { sessionKey });
5563
+ logger$a.info('Disconnected session', { sessionKey });
5435
5564
  }
5436
5565
  catch (e) {
5437
- logger$9.error('Disconnect error for session', {
5566
+ logger$a.error('Disconnect error for session', {
5438
5567
  sessionKey,
5439
5568
  error: e instanceof Error ? e.message : String(e),
5440
5569
  });
@@ -5459,14 +5588,14 @@ class WalletConnectV2Provider extends BaseWalletProvider {
5459
5588
  code: 6000,
5460
5589
  message: 'User disconnected all sessions',
5461
5590
  })
5462
- .catch((err) => logger$9.error('Disconnect error', {
5591
+ .catch((err) => logger$a.error('Disconnect error', {
5463
5592
  error: err.message,
5464
5593
  })));
5465
5594
  }
5466
5595
  await Promise.all(disconnectPromises);
5467
5596
  this.sessionStore.clear();
5468
5597
  this._status.set('disconnected');
5469
- logger$9.info('Disconnected all sessions');
5598
+ logger$a.info('Disconnected all sessions');
5470
5599
  }
5471
5600
  this.clientManager.closeModal();
5472
5601
  }
@@ -5569,7 +5698,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.19", ngImpo
5569
5698
  * - RPC communication over best available transport
5570
5699
  * - Session ownership remains with the wallet
5571
5700
  */
5572
- const logger$8 = getLogger().scoped?.('P2PSessionManager') ?? getLogger();
5701
+ const logger$9 = getLogger().scoped?.('P2PSessionManager') ?? getLogger();
5573
5702
  /**
5574
5703
  * Mobile Native Session Manager
5575
5704
  *
@@ -5638,7 +5767,7 @@ class P2PSessionManager {
5638
5767
  * @returns Promise resolving to offer result with QR data
5639
5768
  */
5640
5769
  async createPairingOffer(options) {
5641
- logger$8.info('Creating pairing offer (Nostr-first)', { options });
5770
+ logger$9.info('Creating pairing offer (Nostr-first)', { options });
5642
5771
  try {
5643
5772
  this.runInZone(() => this._connectionState.set('creating_offer'));
5644
5773
  // Clean up any existing client
@@ -5651,12 +5780,12 @@ class P2PSessionManager {
5651
5780
  this.client = new ChannelClient({
5652
5781
  p2p: { enabled: true },
5653
5782
  onStateChange: (state) => {
5654
- logger$8.debug('ChannelClient state callback', { state });
5783
+ logger$9.debug('ChannelClient state callback', { state });
5655
5784
  const accounts = this.client?.accounts ?? [];
5656
5785
  this.handleStateChange(state, accounts);
5657
5786
  },
5658
5787
  onAccountsChange: (accounts) => {
5659
- logger$8.debug('ChannelClient accounts callback', { count: accounts.length });
5788
+ logger$9.debug('ChannelClient accounts callback', { count: accounts.length });
5660
5789
  const state = this.client?.state ?? 'idle';
5661
5790
  this.handleStateChange(state, accounts);
5662
5791
  },
@@ -5681,7 +5810,7 @@ class P2PSessionManager {
5681
5810
  // Encode invite for QR code
5682
5811
  const qrData = encodeChannelInvite(invite);
5683
5812
  this.runInZone(() => this._connectionState.set('awaiting_connection'));
5684
- logger$8.info('Pairing offer created', {
5813
+ logger$9.info('Pairing offer created', {
5685
5814
  sessionId: invite.id.slice(0, 8),
5686
5815
  qrDataLength: qrData.length,
5687
5816
  });
@@ -5690,7 +5819,7 @@ class P2PSessionManager {
5690
5819
  return { qrData, sessionId: invite.id };
5691
5820
  }
5692
5821
  catch (error) {
5693
- logger$8.error('Failed to create pairing offer', { error });
5822
+ logger$9.error('Failed to create pairing offer', { error });
5694
5823
  this.runInZone(() => this._connectionState.set('error'));
5695
5824
  this.notifyError(error instanceof Error ? error : new Error('Failed to create offer'));
5696
5825
  throw error;
@@ -5708,7 +5837,7 @@ class P2PSessionManager {
5708
5837
  if (!this.client || !this.currentInvite) {
5709
5838
  throw new Error('No active pairing offer - call createPairingOffer first');
5710
5839
  }
5711
- logger$8.info('Waiting for wallet to connect and approve session...');
5840
+ logger$9.info('Waiting for wallet to connect and approve session...');
5712
5841
  return new Promise((resolve, reject) => {
5713
5842
  this.sessionApprovalPromise = { resolve, reject };
5714
5843
  });
@@ -5719,7 +5848,7 @@ class P2PSessionManager {
5719
5848
  * Cleans up the transport without fully disconnecting.
5720
5849
  */
5721
5850
  async cancelPairingOffer() {
5722
- logger$8.debug('Cancelling pairing offer');
5851
+ logger$9.debug('Cancelling pairing offer');
5723
5852
  if (this.sessionApprovalPromise) {
5724
5853
  this.sessionApprovalPromise.reject(new Error('Pairing cancelled'));
5725
5854
  this.sessionApprovalPromise = undefined;
@@ -5761,7 +5890,7 @@ class P2PSessionManager {
5761
5890
  */
5762
5891
  async signTransaction(options) {
5763
5892
  this.requireSession();
5764
- logger$8.info('Signing transaction', { account: options.accountAddress });
5893
+ logger$9.info('Signing transaction', { account: options.accountAddress });
5765
5894
  if (!this.client) {
5766
5895
  throw new Error('Not connected');
5767
5896
  }
@@ -5783,7 +5912,7 @@ class P2PSessionManager {
5783
5912
  */
5784
5913
  async submitTransaction(options) {
5785
5914
  this.requireSession();
5786
- logger$8.info('Submitting transaction', { account: options.accountAddress });
5915
+ logger$9.info('Submitting transaction', { account: options.accountAddress });
5787
5916
  if (!this.client) {
5788
5917
  throw new Error('Not connected');
5789
5918
  }
@@ -5808,7 +5937,7 @@ class P2PSessionManager {
5808
5937
  */
5809
5938
  async signMessage(options) {
5810
5939
  this.requireSession();
5811
- logger$8.info('Signing message', { account: options.accountAddress });
5940
+ logger$9.info('Signing message', { account: options.accountAddress });
5812
5941
  if (!this.client) {
5813
5942
  throw new Error('Not connected');
5814
5943
  }
@@ -5833,7 +5962,7 @@ class P2PSessionManager {
5833
5962
  * Terminate the current session
5834
5963
  */
5835
5964
  async terminateSession() {
5836
- logger$8.info('Terminating session');
5965
+ logger$9.info('Terminating session');
5837
5966
  if (this.client) {
5838
5967
  await this.client.disconnect();
5839
5968
  }
@@ -5934,6 +6063,7 @@ class P2PSessionManager {
5934
6063
  accounts: accounts.map((acc, index) => ({
5935
6064
  id: `p2p-${acc.address}`,
5936
6065
  address: acc.address,
6066
+ publicKey: acc.publicKey,
5937
6067
  label: acc.alias || `Account ${index + 1}`,
5938
6068
  ledgerId: acc.ledgerId,
5939
6069
  networkId: acc.networkId,
@@ -5952,7 +6082,7 @@ class P2PSessionManager {
5952
6082
  * @param reason
5953
6083
  */
5954
6084
  handleDisconnection(reason) {
5955
- logger$8.info('Handling disconnection', { reason });
6085
+ logger$9.info('Handling disconnection', { reason });
5956
6086
  this.cleanup();
5957
6087
  this.runInZone(() => {
5958
6088
  this._currentSession.set(null);
@@ -6004,7 +6134,7 @@ class P2PSessionManager {
6004
6134
  callback(session);
6005
6135
  }
6006
6136
  catch (error) {
6007
- logger$8.error('Connected callback error', { error });
6137
+ logger$9.error('Connected callback error', { error });
6008
6138
  }
6009
6139
  }
6010
6140
  }
@@ -6017,7 +6147,7 @@ class P2PSessionManager {
6017
6147
  callback();
6018
6148
  }
6019
6149
  catch (error) {
6020
- logger$8.error('Disconnected callback error', { error });
6150
+ logger$9.error('Disconnected callback error', { error });
6021
6151
  }
6022
6152
  }
6023
6153
  }
@@ -6031,7 +6161,7 @@ class P2PSessionManager {
6031
6161
  callback(error);
6032
6162
  }
6033
6163
  catch (err) {
6034
- logger$8.error('Error callback error', { err });
6164
+ logger$9.error('Error callback error', { err });
6035
6165
  }
6036
6166
  }
6037
6167
  }
@@ -6073,7 +6203,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.19", ngImpo
6073
6203
  * 4. User approves session in wallet
6074
6204
  * 5. P2P upgrade happens automatically in background
6075
6205
  */
6076
- const logger$7 = getLogger().scoped?.('P2PNativeProvider') ?? getLogger();
6206
+ const logger$8 = getLogger().scoped?.('P2PNativeProvider') ?? getLogger();
6077
6207
  /**
6078
6208
  * Storage key for mobile session metadata (separate from hsuite-native)
6079
6209
  */
@@ -6098,10 +6228,10 @@ class P2PSessionPersistence {
6098
6228
  timestamp: Date.now(),
6099
6229
  };
6100
6230
  window.localStorage.setItem(P2P_SESSION_STORAGE_KEY, JSON.stringify(payload));
6101
- logger$7.debug('Mobile session persisted', { sessionId: session.sessionId });
6231
+ logger$8.debug('Mobile session persisted', { sessionId: session.sessionId });
6102
6232
  }
6103
6233
  catch (error) {
6104
- logger$7.warn('Failed to persist mobile session', { error });
6234
+ logger$8.warn('Failed to persist mobile session', { error });
6105
6235
  }
6106
6236
  }
6107
6237
  /**
@@ -6119,11 +6249,11 @@ class P2PSessionPersistence {
6119
6249
  this.clear();
6120
6250
  return null;
6121
6251
  }
6122
- logger$7.info('Restored mobile session metadata', { sessionId: stored.sessionId });
6252
+ logger$8.info('Restored mobile session metadata', { sessionId: stored.sessionId });
6123
6253
  return stored;
6124
6254
  }
6125
6255
  catch (error) {
6126
- logger$7.warn('Failed to restore mobile session', { error });
6256
+ logger$8.warn('Failed to restore mobile session', { error });
6127
6257
  return null;
6128
6258
  }
6129
6259
  }
@@ -6135,10 +6265,10 @@ class P2PSessionPersistence {
6135
6265
  if (typeof window === 'undefined')
6136
6266
  return;
6137
6267
  window.localStorage.removeItem(P2P_SESSION_STORAGE_KEY);
6138
- logger$7.debug('Mobile session cleared');
6268
+ logger$8.debug('Mobile session cleared');
6139
6269
  }
6140
6270
  catch (error) {
6141
- logger$7.warn('Failed to clear mobile session', { error });
6271
+ logger$8.warn('Failed to clear mobile session', { error });
6142
6272
  }
6143
6273
  }
6144
6274
  /**
@@ -6258,7 +6388,7 @@ class P2PNativeProvider extends BaseWalletProvider {
6258
6388
  restorePersistedSession() {
6259
6389
  const stored = this.sessionPersistence.restore();
6260
6390
  if (stored) {
6261
- logger$7.info('Restoring persisted mobile session', {
6391
+ logger$8.info('Restoring persisted mobile session', {
6262
6392
  sessionId: stored.sessionId,
6263
6393
  accountCount: stored.accounts?.length ?? 0,
6264
6394
  });
@@ -6269,7 +6399,7 @@ class P2PNativeProvider extends BaseWalletProvider {
6269
6399
  }
6270
6400
  // Note: We don't set connected status because WebRTC needs re-pairing
6271
6401
  // The persisted data is for account info only
6272
- logger$7.debug('Mobile session metadata restored (requires re-pairing for connection)');
6402
+ logger$8.debug('Mobile session metadata restored (requires re-pairing for connection)');
6273
6403
  }
6274
6404
  }
6275
6405
  /**
@@ -6292,7 +6422,7 @@ class P2PNativeProvider extends BaseWalletProvider {
6292
6422
  * @throws {Error} If offer generation fails
6293
6423
  */
6294
6424
  async createPairingOffer(config) {
6295
- logger$7.info('Creating pairing offer', { config });
6425
+ logger$8.info('Creating pairing offer', { config });
6296
6426
  try {
6297
6427
  this._connectionState.set('generating_offer');
6298
6428
  this._error.set(null);
@@ -6315,14 +6445,14 @@ class P2PNativeProvider extends BaseWalletProvider {
6315
6445
  this._pairingOffer.set(offerResult);
6316
6446
  this._connectionState.set('awaiting_scan');
6317
6447
  this._status.set('connecting');
6318
- logger$7.info('Pairing offer created', {
6448
+ logger$8.info('Pairing offer created', {
6319
6449
  qrDataLength: result.qrData.length,
6320
6450
  expiresAt: offerResult.expiresAt,
6321
6451
  });
6322
6452
  return offerResult;
6323
6453
  }
6324
6454
  catch (error) {
6325
- logger$7.error('Failed to create pairing offer', { error });
6455
+ logger$8.error('Failed to create pairing offer', { error });
6326
6456
  this._connectionState.set('error');
6327
6457
  this._status.set('error');
6328
6458
  this._error.set(error instanceof Error ? error.message : 'Failed to create pairing offer');
@@ -6336,7 +6466,7 @@ class P2PNativeProvider extends BaseWalletProvider {
6336
6466
  * @returns Promise resolving to new pairing offer
6337
6467
  */
6338
6468
  async refreshPairingOffer(config) {
6339
- logger$7.debug('Refreshing pairing offer');
6469
+ logger$8.debug('Refreshing pairing offer');
6340
6470
  // Cancel any existing offer
6341
6471
  await this.sessionManager.cancelPairingOffer();
6342
6472
  return this.createPairingOffer(config);
@@ -6372,7 +6502,7 @@ class P2PNativeProvider extends BaseWalletProvider {
6372
6502
  * @throws {Error} If no pairing offer was created
6373
6503
  */
6374
6504
  async waitForSessionApproval() {
6375
- logger$7.info('Waiting for wallet to connect and approve session');
6505
+ logger$8.info('Waiting for wallet to connect and approve session');
6376
6506
  this._connectionState.set('pending_approval');
6377
6507
  try {
6378
6508
  // This blocks until wallet connects via Nostr and user approves
@@ -6390,7 +6520,7 @@ class P2PNativeProvider extends BaseWalletProvider {
6390
6520
  return session;
6391
6521
  }
6392
6522
  catch (error) {
6393
- logger$7.error('Session approval failed', { error });
6523
+ logger$8.error('Session approval failed', { error });
6394
6524
  this._connectionState.set('error');
6395
6525
  throw error;
6396
6526
  }
@@ -6415,10 +6545,10 @@ class P2PNativeProvider extends BaseWalletProvider {
6415
6545
  * @throws {Error} If connection times out (2 minutes)
6416
6546
  */
6417
6547
  async connect(config) {
6418
- logger$7.info('Connect called', { config });
6548
+ logger$8.info('Connect called', { config });
6419
6549
  // If already connected, no-op
6420
6550
  if (this._status() === 'connected') {
6421
- logger$7.debug('Already connected');
6551
+ logger$8.debug('Already connected');
6422
6552
  return;
6423
6553
  }
6424
6554
  // Create pairing offer and wait for connection
@@ -6446,7 +6576,7 @@ class P2PNativeProvider extends BaseWalletProvider {
6446
6576
  * persisted session data. The wallet is notified of the disconnection.
6447
6577
  */
6448
6578
  async disconnect() {
6449
- logger$7.info('Disconnecting');
6579
+ logger$8.info('Disconnecting');
6450
6580
  try {
6451
6581
  await this.sessionManager.terminateSession();
6452
6582
  }
@@ -6478,7 +6608,7 @@ class P2PNativeProvider extends BaseWalletProvider {
6478
6608
  if (this._status() !== 'connected') {
6479
6609
  throw new Error('Not connected to wallet');
6480
6610
  }
6481
- logger$7.info('Signing transaction', { account: options.accountAddress });
6611
+ logger$8.info('Signing transaction', { account: options.accountAddress });
6482
6612
  const result = await this.sessionManager.signTransaction({
6483
6613
  accountAddress: options.accountAddress,
6484
6614
  payload: options.payload,
@@ -6509,7 +6639,7 @@ class P2PNativeProvider extends BaseWalletProvider {
6509
6639
  if (this._status() !== 'connected') {
6510
6640
  throw new Error('Not connected to wallet');
6511
6641
  }
6512
- logger$7.info('Submitting transaction', { account: options.accountAddress });
6642
+ logger$8.info('Submitting transaction', { account: options.accountAddress });
6513
6643
  const result = await this.sessionManager.submitTransaction({
6514
6644
  accountAddress: options.accountAddress,
6515
6645
  payload: options.payload,
@@ -6561,7 +6691,7 @@ class P2PNativeProvider extends BaseWalletProvider {
6561
6691
  if (this._status() !== 'connected') {
6562
6692
  throw new Error('Not connected to wallet');
6563
6693
  }
6564
- logger$7.info('Signing message', { account: options.accountAddress });
6694
+ logger$8.info('Signing message', { account: options.accountAddress });
6565
6695
  const result = await this.sessionManager.signMessage({
6566
6696
  accountAddress: options.accountAddress,
6567
6697
  message: options.message,
@@ -6596,7 +6726,7 @@ class P2PNativeProvider extends BaseWalletProvider {
6596
6726
  // Connection established — wrap in NgZone to ensure Angular change
6597
6727
  // detection picks up signal updates from Nostr/WebSocket callbacks
6598
6728
  this.sessionManager.onConnected((session) => {
6599
- logger$7.info('Session connected', { sessionId: session?.id });
6729
+ logger$8.info('Session connected', { sessionId: session?.id });
6600
6730
  this.ngZone.run(() => {
6601
6731
  this._connectionState.set('connected');
6602
6732
  this._status.set('connected');
@@ -6614,7 +6744,7 @@ class P2PNativeProvider extends BaseWalletProvider {
6614
6744
  });
6615
6745
  // Session terminated
6616
6746
  this.sessionManager.onDisconnected(() => {
6617
- logger$7.info('Session disconnected');
6747
+ logger$8.info('Session disconnected');
6618
6748
  this.ngZone.run(() => {
6619
6749
  this._connectionState.set('disconnected');
6620
6750
  this._status.set('disconnected');
@@ -6625,7 +6755,7 @@ class P2PNativeProvider extends BaseWalletProvider {
6625
6755
  });
6626
6756
  // Error occurred
6627
6757
  this.sessionManager.onError((error) => {
6628
- logger$7.error('Session error', { error });
6758
+ logger$8.error('Session error', { error });
6629
6759
  this.ngZone.run(() => {
6630
6760
  this._connectionState.set('error');
6631
6761
  this._status.set('error');
@@ -6634,7 +6764,7 @@ class P2PNativeProvider extends BaseWalletProvider {
6634
6764
  });
6635
6765
  // Accounts updated
6636
6766
  this.sessionManager.onAccountsChanged((accounts) => {
6637
- logger$7.debug('Accounts updated', { count: accounts.length });
6767
+ logger$8.debug('Accounts updated', { count: accounts.length });
6638
6768
  this.ngZone.run(() => {
6639
6769
  const accountsWithProvider = this.ensureProviderIdOnAccounts(accounts);
6640
6770
  this._accounts.set(accountsWithProvider);
@@ -6704,7 +6834,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.19", ngImpo
6704
6834
  * +-------------------------------------------------------------------+
6705
6835
  * ```
6706
6836
  */
6707
- const logger$6 = getLogger().scoped?.('UnifiedWalletService') ?? getLogger();
6837
+ const logger$7 = getLogger().scoped?.('UnifiedWalletService') ?? getLogger();
6708
6838
  /**
6709
6839
  * Central service for managing wallet connections across multiple protocols.
6710
6840
  *
@@ -6842,7 +6972,7 @@ class UnifiedWalletService {
6842
6972
  return await reconnect.call(provider);
6843
6973
  }
6844
6974
  catch (error) {
6845
- logger$6.warn('Provider reconnect failed', { providerId, error });
6975
+ logger$7.warn('Provider reconnect failed', { providerId, error });
6846
6976
  return false;
6847
6977
  }
6848
6978
  }
@@ -6906,7 +7036,7 @@ class UnifiedWalletService {
6906
7036
  */
6907
7037
  registerProvider(provider) {
6908
7038
  if (this.providers.has(provider.id)) {
6909
- logger$6.warn('Provider already registered', { providerId: provider.id });
7039
+ logger$7.warn('Provider already registered', { providerId: provider.id });
6910
7040
  return;
6911
7041
  }
6912
7042
  this.providers.set(provider.id, provider);
@@ -7361,7 +7491,7 @@ class UnifiedWalletService {
7361
7491
  switchAccount(accountId) {
7362
7492
  const account = this.getAccountById(accountId);
7363
7493
  if (!account) {
7364
- logger$6.warn('Account not found', { accountId });
7494
+ logger$7.warn('Account not found', { accountId });
7365
7495
  return false;
7366
7496
  }
7367
7497
  this.setActiveAccount(account);
@@ -7416,7 +7546,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.19", ngImpo
7416
7546
  * - Keyboard navigation support
7417
7547
  * - Toast/alert integration
7418
7548
  */
7419
- const logger$5 = getLogger().scoped?.('AccountSelectorService') ?? getLogger();
7549
+ const logger$6 = getLogger().scoped?.('AccountSelectorService') ?? getLogger();
7420
7550
  /**
7421
7551
  * @service AccountSelectorService
7422
7552
  * Business logic service for account selector component.
@@ -7505,7 +7635,7 @@ class AccountSelectorService {
7505
7635
  return null;
7506
7636
  }
7507
7637
  catch (error) {
7508
- logger$5.error('Error getting currently connected account', { error });
7638
+ logger$6.error('Error getting currently connected account', { error });
7509
7639
  return null;
7510
7640
  }
7511
7641
  }, ...(ngDevMode ? [{ debugName: "currentlyConnectedAccount" }] : []));
@@ -7533,7 +7663,7 @@ class AccountSelectorService {
7533
7663
  return others;
7534
7664
  }
7535
7665
  catch (error) {
7536
- logger$5.error('Error getting other accounts', { error });
7666
+ logger$6.error('Error getting other accounts', { error });
7537
7667
  return [];
7538
7668
  }
7539
7669
  }, ...(ngDevMode ? [{ debugName: "otherAccounts" }] : []));
@@ -7562,10 +7692,10 @@ class AccountSelectorService {
7562
7692
  // Modal mode: show toast and dismiss
7563
7693
  if (mode === 'modal') {
7564
7694
  await this.showSuccessToast(`Switched to ${account.label || 'Account'}`);
7565
- logger$5.info('[Modal] Account changed and modal dismissed', { ...accountData });
7695
+ logger$6.info('[Modal] Account changed and modal dismissed', { ...accountData });
7566
7696
  }
7567
7697
  else {
7568
- logger$5.info('[Inline] Account changed', { ...accountData });
7698
+ logger$6.info('[Inline] Account changed', { ...accountData });
7569
7699
  }
7570
7700
  return accountData;
7571
7701
  }
@@ -7617,7 +7747,7 @@ class AccountSelectorService {
7617
7747
  */
7618
7748
  async disconnectAll(_mode) {
7619
7749
  if (!this.alertController) {
7620
- logger$5.warn('AlertController not available for disconnect confirmation');
7750
+ logger$6.warn('AlertController not available for disconnect confirmation');
7621
7751
  return false;
7622
7752
  }
7623
7753
  return new Promise((resolve) => {
@@ -7642,7 +7772,7 @@ class AccountSelectorService {
7642
7772
  await this.wallet.disconnectSession(session.providerId, session.metadata?.sessionKey);
7643
7773
  }
7644
7774
  catch (error) {
7645
- logger$5.error('Failed to disconnect session', {
7775
+ logger$6.error('Failed to disconnect session', {
7646
7776
  providerId: session.providerId,
7647
7777
  error,
7648
7778
  });
@@ -7652,7 +7782,7 @@ class AccountSelectorService {
7652
7782
  resolve(true);
7653
7783
  }
7654
7784
  catch (error) {
7655
- logger$5.error('Failed to disconnect all sessions', { error });
7785
+ logger$6.error('Failed to disconnect all sessions', { error });
7656
7786
  this.error.set('Failed to disconnect all wallets');
7657
7787
  resolve(false);
7658
7788
  }
@@ -7737,11 +7867,11 @@ class AccountSelectorService {
7737
7867
  if (mode === 'modal') {
7738
7868
  await this.showSuccessToast('Wallet disconnected successfully');
7739
7869
  }
7740
- logger$5.info('Session disconnected', { providerId, sessionKey, mode });
7870
+ logger$6.info('Session disconnected', { providerId, sessionKey, mode });
7741
7871
  return true;
7742
7872
  }
7743
7873
  catch (error) {
7744
- logger$5.error('Failed to disconnect session', { providerId, error });
7874
+ logger$6.error('Failed to disconnect session', { providerId, error });
7745
7875
  if (mode === 'modal') {
7746
7876
  await this.showErrorToast('Failed to disconnect wallet. Please try again.');
7747
7877
  }
@@ -8439,24 +8569,22 @@ class WalletAccountDisplayComponent {
8439
8569
  }
8440
8570
  return null;
8441
8571
  }, ...(ngDevMode ? [{ debugName: "multisigInfo" }] : []));
8572
+ /**
8573
+ *
8574
+ */
8442
8575
  constructor() {
8443
8576
  addIcons({ walletOutline, personOutline, peopleOutline });
8444
8577
  }
8445
8578
  /**
8446
8579
  * Get color for ledger badge
8580
+ * @param ledgerId
8447
8581
  */
8448
8582
  getLedgerColor(ledgerId) {
8449
- switch (ledgerId.toLowerCase()) {
8450
- case 'hedera':
8451
- return 'success';
8452
- case 'xrpl':
8453
- return 'tertiary';
8454
- default:
8455
- return 'primary';
8456
- }
8583
+ return LedgerUIRegistry.get(ledgerId.toLowerCase())?.badgeColor ?? 'primary';
8457
8584
  }
8458
8585
  /**
8459
8586
  * Format network ID for display
8587
+ * @param networkId
8460
8588
  */
8461
8589
  formatNetwork(networkId) {
8462
8590
  const parts = networkId.split(':');
@@ -9290,7 +9418,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.19", ngImpo
9290
9418
  * - HSuite Native + Mobile QR: Network → Protocol → Method → QR Pairing (4 steps)
9291
9419
  * - WalletConnect: Network → Protocol → Ledger → Connect (4 steps)
9292
9420
  */
9293
- const logger$4 = getLogger().scoped?.('WalletConnectionModal') ?? getLogger();
9421
+ const logger$5 = getLogger().scoped?.('WalletConnectionModal') ?? getLogger();
9294
9422
  /**
9295
9423
  * Connection step enumeration for the wizard flow
9296
9424
  */
@@ -9303,6 +9431,18 @@ var ConnectionStep;
9303
9431
  ConnectionStep[ConnectionStep["QrPairing"] = 5] = "QrPairing";
9304
9432
  ConnectionStep[ConnectionStep["ConnectionProgress"] = 6] = "ConnectionProgress";
9305
9433
  })(ConnectionStep || (ConnectionStep = {}));
9434
+ /**
9435
+ * Per-ledger copy for the WalletConnect "Choose Blockchain" step.
9436
+ *
9437
+ * Keyed by {@link SupportedLedger} (the closed set of ledgers the WalletConnect
9438
+ * provider brokers) via `satisfies`, so widening that union forces a description
9439
+ * here. Display name and icon come from {@link LedgerUIRegistry}; this map holds
9440
+ * only the connection-flow copy specific to this surface.
9441
+ */
9442
+ const LEDGER_DESCRIPTIONS = {
9443
+ hedera: 'Hedera Hashgraph network',
9444
+ xrpl: 'XRP Ledger network',
9445
+ };
9306
9446
  /**
9307
9447
  * Main wallet connection modal component.
9308
9448
  * Orchestrates the multi-step connection flow.
@@ -9416,20 +9556,15 @@ class WalletConnectionModalComponent {
9416
9556
  }
9417
9557
  return options;
9418
9558
  }, ...(ngDevMode ? [{ debugName: "protocolOptions" }] : []));
9419
- ledgerOptions = [
9420
- {
9421
- id: 'hedera',
9422
- name: 'Hedera',
9423
- description: 'Hedera Hashgraph network',
9424
- icon: 'logo-bitcoin', // Placeholder, use actual Hedera icon
9425
- },
9426
- {
9427
- id: 'xrpl',
9428
- name: 'XRP Ledger',
9429
- description: 'XRP Ledger network',
9430
- icon: 'logo-usd', // Placeholder, use actual XRPL icon
9431
- },
9432
- ];
9559
+ ledgerOptions = Object.keys(LEDGER_DESCRIPTIONS).map((id) => {
9560
+ const ui = LedgerUIRegistry.get(id);
9561
+ return {
9562
+ id,
9563
+ name: ui?.displayName ?? id,
9564
+ description: LEDGER_DESCRIPTIONS[id],
9565
+ icon: ui?.iconName ?? '',
9566
+ };
9567
+ });
9433
9568
  /**
9434
9569
  * Connection method options for HSuite Native.
9435
9570
  * Simplified to two options:
@@ -9593,6 +9728,8 @@ class WalletConnectionModalComponent {
9593
9728
  this.p2pNativeProvider.onPeerConnected(() => {
9594
9729
  this.onMobileConnected();
9595
9730
  });
9731
+ // Register the shared ledger brand logos so <ion-icon> can resolve them by name.
9732
+ registerLedgerIcons();
9596
9733
  }
9597
9734
  /**
9598
9735
  * Apply the pinned network (if any) before the first render.
@@ -9806,7 +9943,7 @@ class WalletConnectionModalComponent {
9806
9943
  await this.modalController.dismiss({ connected: true });
9807
9944
  }
9808
9945
  catch (error) {
9809
- logger$4.error('Connection failed', {
9946
+ logger$5.error('Connection failed', {
9810
9947
  error: error instanceof Error ? error.message : String(error),
9811
9948
  });
9812
9949
  this.connectionError.set(error instanceof Error ? error.message : 'Connection failed. Please try again.');
@@ -9851,7 +9988,7 @@ class WalletConnectionModalComponent {
9851
9988
  this.waitForWalletApproval();
9852
9989
  }
9853
9990
  catch (error) {
9854
- logger$4.error('Failed to create pairing offer', { error });
9991
+ logger$5.error('Failed to create pairing offer', { error });
9855
9992
  this.connectionError.set(error instanceof Error ? error.message : 'Failed to generate QR code');
9856
9993
  this.isGeneratingOffer.set(false);
9857
9994
  }
@@ -9864,7 +10001,7 @@ class WalletConnectionModalComponent {
9864
10001
  try {
9865
10002
  // This blocks until wallet scans QR, connects via Nostr, and user approves
9866
10003
  const session = await this.p2pNativeProvider.waitForSessionApproval();
9867
- logger$4.info('Session approved by wallet', {
10004
+ logger$5.info('Session approved by wallet', {
9868
10005
  sessionId: session?.sessionId,
9869
10006
  accounts: session?.accounts?.length,
9870
10007
  });
@@ -9873,7 +10010,7 @@ class WalletConnectionModalComponent {
9873
10010
  catch (error) {
9874
10011
  // Only show error if we're still on the QR pairing step (not cancelled)
9875
10012
  if (this.currentStep() === ConnectionStep.QrPairing) {
9876
- logger$4.error('Session approval failed', { error });
10013
+ logger$5.error('Session approval failed', { error });
9877
10014
  this.connectionError.set(error instanceof Error ? error.message : 'Session approval failed or rejected');
9878
10015
  }
9879
10016
  this.isWaitingForWallet.set(false);
@@ -9884,7 +10021,7 @@ class WalletConnectionModalComponent {
9884
10021
  * Handle QR code expiry
9885
10022
  */
9886
10023
  onQrExpired() {
9887
- logger$4.debug('QR code expired');
10024
+ logger$5.debug('QR code expired');
9888
10025
  this.pairingOffer.set('');
9889
10026
  this.isWaitingForWallet.set(false);
9890
10027
  }
@@ -9900,7 +10037,7 @@ class WalletConnectionModalComponent {
9900
10037
  * Handle successful mobile connection
9901
10038
  */
9902
10039
  onMobileConnected() {
9903
- logger$4.info('Mobile wallet connected');
10040
+ logger$5.info('Mobile wallet connected');
9904
10041
  this.connected.emit({ protocol: 'mobile-native', method: 'qr' });
9905
10042
  void this.modalController.dismiss({ connected: true });
9906
10043
  }
@@ -9951,7 +10088,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.19", ngImpo
9951
10088
  * This file is part of HSuite Native Connect. For commercial licensing,
9952
10089
  * visit https://hsuite.finance/licensing
9953
10090
  */
9954
- const logger$3 = getLogger().scoped?.('WalletConnectButton') ?? getLogger();
10091
+ const logger$4 = getLogger().scoped?.('WalletConnectButton') ?? getLogger();
9955
10092
  /**
9956
10093
  * @component WalletConnectButtonComponent
9957
10094
  * Ready-to-use wallet connection button for dApps with multi-protocol support.
@@ -10056,7 +10193,7 @@ class WalletConnectButtonComponent {
10056
10193
  catch (err) {
10057
10194
  const error = err instanceof Error ? err : new Error(String(err));
10058
10195
  this.error.emit(error);
10059
- logger$3.error('Connection failed', { error: error.message });
10196
+ logger$4.error('Connection failed', { error: error.message });
10060
10197
  }
10061
10198
  finally {
10062
10199
  this.isConnecting = false;
@@ -10102,7 +10239,7 @@ class WalletConnectButtonComponent {
10102
10239
  catch (err) {
10103
10240
  const error = err instanceof Error ? err : new Error(String(err));
10104
10241
  this.error.emit(error);
10105
- logger$3.error('Disconnect failed', { error: error.message });
10242
+ logger$4.error('Disconnect failed', { error: error.message });
10106
10243
  }
10107
10244
  }
10108
10245
  /**
@@ -11497,7 +11634,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.19", ngImpo
11497
11634
  * }
11498
11635
  * ```
11499
11636
  */
11500
- const logger$2 = getLogger().scoped?.('TransactionService') ?? getLogger();
11637
+ const logger$3 = getLogger().scoped?.('TransactionService') ?? getLogger();
11501
11638
  /**
11502
11639
  * High-level transaction service with automatic state management.
11503
11640
  *
@@ -11549,7 +11686,7 @@ class TransactionService {
11549
11686
  async signTransaction(payload) {
11550
11687
  return this.executeTransaction(async () => {
11551
11688
  const result = (await this.walletService.signTransaction(payload));
11552
- logger$2.info('Transaction signed', {
11689
+ logger$3.info('Transaction signed', {
11553
11690
  hasSignature: !!result.signedTransaction,
11554
11691
  });
11555
11692
  await this.showSuccessToast('Transaction Signed', 'Your transaction has been signed successfully.');
@@ -11570,7 +11707,7 @@ class TransactionService {
11570
11707
  async submitTransaction(payload) {
11571
11708
  return this.executeTransaction(async () => {
11572
11709
  const result = (await this.walletService.submitTransaction(payload));
11573
- logger$2.info('Transaction submitted', { transactionId: result.transactionId });
11710
+ logger$3.info('Transaction submitted', { transactionId: result.transactionId });
11574
11711
  await this.showSuccessToast('Transaction Submitted', `Transaction ID: ${result.transactionId || 'Success'}`);
11575
11712
  return result;
11576
11713
  });
@@ -11589,7 +11726,7 @@ class TransactionService {
11589
11726
  // Use the wallet's signAndExecuteTransaction method directly
11590
11727
  // This uses hedera_signAndExecuteTransaction for WalletConnect (one prompt!)
11591
11728
  const result = (await this.walletService.signAndExecuteTransaction(payload));
11592
- logger$2.info('Transaction signed and submitted', { transactionId: result.transactionId });
11729
+ logger$3.info('Transaction signed and submitted', { transactionId: result.transactionId });
11593
11730
  await this.showSuccessToast('Transaction Complete', `Transaction ID: ${result.transactionId || 'Success'}`);
11594
11731
  return result;
11595
11732
  });
@@ -11613,7 +11750,7 @@ class TransactionService {
11613
11750
  batchKey: options.batchKey,
11614
11751
  innerTransactions: options.innerTransactions,
11615
11752
  }));
11616
- logger$2.info('Batch transaction submitted', { transactionId: result.transactionId });
11753
+ logger$3.info('Batch transaction submitted', { transactionId: result.transactionId });
11617
11754
  await this.showSuccessToast('Batch Transaction Complete', `Transaction ID: ${result.transactionId || 'Success'}`);
11618
11755
  return result;
11619
11756
  });
@@ -11626,8 +11763,8 @@ class TransactionService {
11626
11763
  */
11627
11764
  async signMessage(message) {
11628
11765
  return this.executeTransaction(async () => {
11629
- const result = (await this.walletService.signMessage(message));
11630
- logger$2.info('Message signed', { hasSignature: !!result.signature });
11766
+ const result = await this.walletService.signMessage(message);
11767
+ logger$3.info('Message signed', { hasSignature: !!result.signature });
11631
11768
  await this.showSuccessToast('Message Signed', 'Your message has been signed successfully.');
11632
11769
  return result;
11633
11770
  });
@@ -11750,6 +11887,378 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.19", ngImpo
11750
11887
  args: [{ providedIn: 'root' }]
11751
11888
  }] });
11752
11889
 
11890
+ /**
11891
+ * HSuite Native Connect
11892
+ * Copyright 2024-2025 HSuite (https://hsuite.finance)
11893
+ *
11894
+ * SPDX-License-Identifier: PolyForm-Noncommercial-1.0.0
11895
+ *
11896
+ * This file is part of HSuite Native Connect. For commercial licensing,
11897
+ * visit https://hsuite.finance/licensing
11898
+ */
11899
+ /**
11900
+ * @file Smart-host customer session helper.
11901
+ *
11902
+ * @module services/smart-session
11903
+ *
11904
+ * @description
11905
+ * SmartSessionService automates the smart-host authentication handshake for
11906
+ * HSuite dApps. It discovers the host's `appId`, requests a challenge, signs it
11907
+ * with the active wallet account, and exchanges the signed challenge for a
11908
+ * short-lived bearer token.
11909
+ *
11910
+ * **Typical flow:**
11911
+ * ```typescript
11912
+ * const session = inject(SmartSessionService);
11913
+ * await session.login();
11914
+ * const bearer = session.getBearer();
11915
+ * ```
11916
+ *
11917
+ * The service also exposes {@link withSession} for automatic 401 recovery:
11918
+ * operations that fail with HTTP 401 are retried once after a fresh login.
11919
+ */
11920
+ const logger$2 = getLogger().scoped?.('SmartSessionService') ?? getLogger();
11921
+ /**
11922
+ * Configuration token for {@link SmartSessionService}.
11923
+ */
11924
+ const SMART_SESSION_CONFIG = new InjectionToken('SMART_SESSION_CONFIG', {
11925
+ factory: () => ({}),
11926
+ });
11927
+ /**
11928
+ * Smart-host customer session helper.
11929
+ *
11930
+ * @service SmartSessionService
11931
+ *
11932
+ * @description
11933
+ * Encapsulates the full challenge → sign → verify → store JWT flow required by
11934
+ * HSuite smart hosts. The service is intentionally thin: it delegates signing to
11935
+ * {@link TransactionService} and relies on standard Angular `HttpClient` for the
11936
+ * host HTTP calls.
11937
+ *
11938
+ * @providedIn root
11939
+ */
11940
+ class SmartSessionService {
11941
+ http = inject(HttpClient);
11942
+ walletService = inject(UnifiedWalletService);
11943
+ transactionService = inject(TransactionService);
11944
+ config = inject(SMART_SESSION_CONFIG);
11945
+ get baseUrl() {
11946
+ return this.config.baseUrl ?? '';
11947
+ }
11948
+ get healthEndpoint() {
11949
+ return this.config.healthEndpoint ?? '/api/health';
11950
+ }
11951
+ get challengeEndpoint() {
11952
+ return this.config.challengeEndpoint ?? '/api/auth/challenge';
11953
+ }
11954
+ get verifyEndpoint() {
11955
+ return this.config.verifyEndpoint ?? '/api/auth/verify';
11956
+ }
11957
+ get storageKey() {
11958
+ return this.config.storageKey ?? 'hsuite.smart-session';
11959
+ }
11960
+ /**
11961
+ * Returns the currently stored bearer token, or `null` if there is no session.
11962
+ *
11963
+ * @returns Bearer token string or null
11964
+ */
11965
+ getBearer() {
11966
+ const stored = this.readStoredSession();
11967
+ return stored && stored.expiresAt > Date.now() ? stored.bearer : null;
11968
+ }
11969
+ /**
11970
+ * Checks whether a non-expired session is available.
11971
+ *
11972
+ * @returns true if logged in and the bearer has not expired
11973
+ */
11974
+ isLoggedIn() {
11975
+ return this.getBearer() !== null;
11976
+ }
11977
+ /**
11978
+ * Performs the full smart-host login handshake.
11979
+ *
11980
+ * @description
11981
+ * 1. Discovers `appId` from the health endpoint.
11982
+ * 2. Fetches a challenge from the challenge endpoint.
11983
+ * 3. Signs the challenge with the active wallet account.
11984
+ * 4. Exchanges the signed challenge for a bearer token.
11985
+ * 5. Stores the bearer and expiry in `sessionStorage`.
11986
+ *
11987
+ * @returns The verify response from the host
11988
+ *
11989
+ * @throws {Error} If no active account is available
11990
+ * @throws {Error} If the health endpoint does not return an `appId`
11991
+ * @throws {Error} If the challenge endpoint does not return a `challenge`
11992
+ * @throws {Error} If the verify call fails
11993
+ */
11994
+ async login() {
11995
+ const account = this.walletService.activeAccount();
11996
+ if (!account) {
11997
+ throw new Error('No active account');
11998
+ }
11999
+ logger$2.info('Starting smart-host login handshake', {
12000
+ accountAddress: account.address,
12001
+ });
12002
+ const health = await this.fetchHealth();
12003
+ if (!health.appId) {
12004
+ throw new Error('Smart host health endpoint did not return appId');
12005
+ }
12006
+ const challengeResponse = await this.fetchChallenge(health.appId);
12007
+ if (!challengeResponse.challenge) {
12008
+ throw new Error('Smart host challenge endpoint did not return challenge');
12009
+ }
12010
+ const signResult = await this.transactionService.signMessage(challengeResponse.challenge);
12011
+ const verifyResponse = await this.verifyChallenge(health.appId, account, challengeResponse.challenge, signResult);
12012
+ if (!verifyResponse.bearer) {
12013
+ throw new Error('Smart host verify endpoint did not return bearer');
12014
+ }
12015
+ const expiresAt = this.resolveExpiry(verifyResponse);
12016
+ this.storeSession({ bearer: verifyResponse.bearer, expiresAt });
12017
+ logger$2.info('Smart-host login successful', {
12018
+ appId: health.appId,
12019
+ expiresAt,
12020
+ });
12021
+ return verifyResponse;
12022
+ }
12023
+ /**
12024
+ * Clears the stored session.
12025
+ */
12026
+ logout() {
12027
+ this.clearStoredSession();
12028
+ logger$2.info('Smart-host session cleared');
12029
+ }
12030
+ /**
12031
+ * Runs an HTTP operation with automatic 401 recovery.
12032
+ *
12033
+ * @description
12034
+ * Executes the provided operation. If it rejects with an HTTP 401 error,
12035
+ * the service clears the current bearer, performs a fresh login, and retries
12036
+ * the operation once. Any other error is propagated immediately.
12037
+ *
12038
+ * @param operation - Async operation that needs a valid session
12039
+ * @returns The result of the operation
12040
+ *
12041
+ * @throws {Error} The original error if retry is not possible or fails
12042
+ */
12043
+ async withSession(operation) {
12044
+ try {
12045
+ return await operation();
12046
+ }
12047
+ catch (error) {
12048
+ if (this.isUnauthorizedError(error)) {
12049
+ logger$2.warn('Operation received 401; attempting single session refresh');
12050
+ this.logout();
12051
+ await this.login();
12052
+ return await operation();
12053
+ }
12054
+ throw error;
12055
+ }
12056
+ }
12057
+ async fetchHealth() {
12058
+ return firstValueFrom(this.http.get(`${this.baseUrl}${this.healthEndpoint}`));
12059
+ }
12060
+ async fetchChallenge(appId) {
12061
+ return firstValueFrom(this.http.post(`${this.baseUrl}${this.challengeEndpoint}`, { appId }));
12062
+ }
12063
+ async verifyChallenge(appId, account, challenge, signResult) {
12064
+ const payload = {
12065
+ appId,
12066
+ accountAddress: account.address,
12067
+ publicKey: signResult.publicKey ?? account.publicKey,
12068
+ signature: signResult.signature,
12069
+ algorithm: signResult.algorithm,
12070
+ message: challenge,
12071
+ caipChainId: signResult.caipChainId,
12072
+ ledgerId: account.ledgerId,
12073
+ networkId: account.networkId,
12074
+ };
12075
+ return firstValueFrom(this.http.post(`${this.baseUrl}${this.verifyEndpoint}`, payload));
12076
+ }
12077
+ resolveExpiry(response) {
12078
+ if (response.expiresAt) {
12079
+ return response.expiresAt;
12080
+ }
12081
+ if (response.expiresIn) {
12082
+ return Date.now() + response.expiresIn * 1000;
12083
+ }
12084
+ // Default to 5 minutes if no expiry is provided
12085
+ return Date.now() + 5 * 60 * 1000;
12086
+ }
12087
+ readStoredSession() {
12088
+ try {
12089
+ const raw = sessionStorage.getItem(this.storageKey);
12090
+ if (!raw) {
12091
+ return null;
12092
+ }
12093
+ const parsed = JSON.parse(raw);
12094
+ if (!parsed.bearer || typeof parsed.expiresAt !== 'number') {
12095
+ return null;
12096
+ }
12097
+ return parsed;
12098
+ }
12099
+ catch {
12100
+ return null;
12101
+ }
12102
+ }
12103
+ storeSession(session) {
12104
+ try {
12105
+ sessionStorage.setItem(this.storageKey, JSON.stringify(session));
12106
+ }
12107
+ catch (error) {
12108
+ logger$2.warn('Failed to store smart session', { error });
12109
+ }
12110
+ }
12111
+ clearStoredSession() {
12112
+ try {
12113
+ sessionStorage.removeItem(this.storageKey);
12114
+ }
12115
+ catch (error) {
12116
+ logger$2.warn('Failed to clear smart session', { error });
12117
+ }
12118
+ }
12119
+ isUnauthorizedError(error) {
12120
+ if (!error || typeof error !== 'object') {
12121
+ return false;
12122
+ }
12123
+ const status = error.status;
12124
+ if (typeof status === 'number') {
12125
+ return status === 401;
12126
+ }
12127
+ const message = String(error.message ?? '');
12128
+ return /\b401\b|unauthorized/i.test(message);
12129
+ }
12130
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.19", ngImport: i0, type: SmartSessionService, deps: [], target: i0.ɵɵFactoryTarget.Injectable });
12131
+ static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "20.3.19", ngImport: i0, type: SmartSessionService, providedIn: 'root' });
12132
+ }
12133
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.19", ngImport: i0, type: SmartSessionService, decorators: [{
12134
+ type: Injectable,
12135
+ args: [{ providedIn: 'root' }]
12136
+ }] });
12137
+
12138
+ /**
12139
+ * HSuite Native Connect
12140
+ * Copyright 2024-2025 HSuite (https://hsuite.finance)
12141
+ *
12142
+ * SPDX-License-Identifier: PolyForm-Noncommercial-1.0.0
12143
+ *
12144
+ * This file is part of HSuite Native Connect. For commercial licensing,
12145
+ * visit https://hsuite.finance/licensing
12146
+ */
12147
+ /**
12148
+ * @file HTTP interceptor that attaches wallet-attributed auth headers.
12149
+ *
12150
+ * @module services/hsuite-auth-interceptor
12151
+ *
12152
+ * @description
12153
+ * `HsuiteAuthInterceptor` automatically adds the active smart-host bearer token
12154
+ * and wallet ledger identifier to outgoing HTTP requests. When a request fails
12155
+ * with HTTP 401, it delegates recovery to {@link SmartSessionService} for a
12156
+ * single re-login and retry.
12157
+ *
12158
+ * **Registration (standalone apps):**
12159
+ * ```typescript
12160
+ * provideHttpClient(withInterceptors([provideHsuiteAuthInterceptor()]))
12161
+ * ```
12162
+ *
12163
+ * **Registration (module-based apps):**
12164
+ * ```typescript
12165
+ * { provide: HTTP_INTERCEPTORS, useClass: HsuiteAuthInterceptor, multi: true }
12166
+ * ```
12167
+ */
12168
+ /**
12169
+ * Headers injected by the interceptor.
12170
+ */
12171
+ const HSUITE_AUTH_HEADER = 'Authorization';
12172
+ const HSUITE_LEDGER_HEADER = 'X-Ledger-Id';
12173
+ /**
12174
+ * Functional HTTP interceptor that attaches wallet-attributed auth headers.
12175
+ *
12176
+ * @description
12177
+ * Adds:
12178
+ * - `Authorization: Bearer <token>` when {@link SmartSessionService.getBearer} returns a token
12179
+ * - `X-Ledger-Id: <ledgerId>` when a wallet account is active
12180
+ *
12181
+ * On 401 responses, clears the stale bearer and retries once after re-login.
12182
+ *
12183
+ * @param req - The outgoing HTTP request
12184
+ * @param next - The downstream request handler
12185
+ * @returns Observable of HTTP events
12186
+ */
12187
+ const hsuiteAuthInterceptor = (req, next) => {
12188
+ const session = inject(SmartSessionService);
12189
+ const wallet = inject(UnifiedWalletService);
12190
+ const authenticated = appendAuthHeaders(req, session, wallet);
12191
+ return next(authenticated).pipe(catchError((error) => {
12192
+ if (error instanceof HttpErrorResponse && error.status === 401) {
12193
+ session.logout();
12194
+ return from(session.login()).pipe(switchMap(() => next(appendAuthHeaders(req, session, wallet))), catchError((loginError) => throwError(() => loginError)));
12195
+ }
12196
+ return throwError(() => error);
12197
+ }));
12198
+ };
12199
+ /**
12200
+ * Class-based HTTP interceptor for module-based Angular apps.
12201
+ *
12202
+ * @description
12203
+ * Provides the same behavior as {@link hsuiteAuthInterceptor} in a class form
12204
+ * suitable for registration via `HTTP_INTERCEPTORS`.
12205
+ */
12206
+ class HsuiteAuthInterceptor {
12207
+ session = inject(SmartSessionService);
12208
+ wallet = inject(UnifiedWalletService);
12209
+ /**
12210
+ * Intercepts outgoing HTTP requests to attach wallet-attributed auth headers.
12211
+ *
12212
+ * @param req - The outgoing HTTP request
12213
+ * @param next - The downstream request handler
12214
+ * @returns Observable of HTTP events
12215
+ */
12216
+ intercept(req, next) {
12217
+ const authenticated = appendAuthHeaders(req, this.session, this.wallet);
12218
+ return next.handle(authenticated).pipe(catchError((error) => {
12219
+ if (error instanceof HttpErrorResponse && error.status === 401) {
12220
+ this.session.logout();
12221
+ return from(this.session.login()).pipe(switchMap(() => next.handle(appendAuthHeaders(req, this.session, this.wallet))), catchError((loginError) => throwError(() => loginError)));
12222
+ }
12223
+ return throwError(() => error);
12224
+ }));
12225
+ }
12226
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.19", ngImport: i0, type: HsuiteAuthInterceptor, deps: [], target: i0.ɵɵFactoryTarget.Injectable });
12227
+ static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "20.3.19", ngImport: i0, type: HsuiteAuthInterceptor, providedIn: 'root' });
12228
+ }
12229
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.19", ngImport: i0, type: HsuiteAuthInterceptor, decorators: [{
12230
+ type: Injectable,
12231
+ args: [{ providedIn: 'root' }]
12232
+ }] });
12233
+ /**
12234
+ * Helper that clones a request with the active auth headers attached.
12235
+ *
12236
+ * @param req - The outgoing HTTP request
12237
+ * @param session - Smart session service for bearer lookup
12238
+ * @param wallet - Unified wallet service for ledger ID lookup
12239
+ * @returns The request cloned with Authorization and/or X-Ledger-Id headers
12240
+ */
12241
+ function appendAuthHeaders(req, session, wallet) {
12242
+ const bearer = session.getBearer();
12243
+ const activeAccount = wallet.activeAccount();
12244
+ const ledgerId = activeAccount?.ledgerId;
12245
+ // Avoid mutating requests that already carry an Authorization header
12246
+ if (!bearer && !ledgerId) {
12247
+ return req;
12248
+ }
12249
+ const headers = {};
12250
+ if (bearer && !req.headers.has(HSUITE_AUTH_HEADER)) {
12251
+ headers[HSUITE_AUTH_HEADER] = `Bearer ${bearer}`;
12252
+ }
12253
+ if (ledgerId && !req.headers.has(HSUITE_LEDGER_HEADER)) {
12254
+ headers[HSUITE_LEDGER_HEADER] = ledgerId;
12255
+ }
12256
+ if (Object.keys(headers).length === 0) {
12257
+ return req;
12258
+ }
12259
+ return req.clone({ setHeaders: headers });
12260
+ }
12261
+
11753
12262
  /**
11754
12263
  * HSuite Native Connect
11755
12264
  * Copyright 2024-2025 HSuite (https://hsuite.finance)
@@ -12190,6 +12699,43 @@ class BaseTransactionBuilderService {
12190
12699
  }
12191
12700
  }
12192
12701
 
12702
+ /**
12703
+ * HSuite Native Connect
12704
+ * Copyright 2024-2025 HSuite (https://hsuite.finance)
12705
+ *
12706
+ * SPDX-License-Identifier: PolyForm-Noncommercial-1.0.0
12707
+ *
12708
+ * This file is part of HSuite Native Connect. For commercial licensing,
12709
+ * visit https://hsuite.finance/licensing
12710
+ */
12711
+ /**
12712
+ * @file ACTIVE_ACCOUNT_SOURCE: the minimal active-account read surface the
12713
+ * transaction builders need.
12714
+ *
12715
+ * @description
12716
+ * The Hedera transaction builder only reads `activeAccount()` from the wallet
12717
+ * (to pick the network and the entity key config). Injecting the whole
12718
+ * {@link UnifiedWalletService} couples the builder to a heavy root service that
12719
+ * also runs the dApp connect stack on construction. This token narrows that
12720
+ * dependency to a single member.
12721
+ *
12722
+ * The default provider points at {@link UnifiedWalletService}, so existing SDK
12723
+ * consumers that already provide it need NO wiring change (backward
12724
+ * compatible). The embedded widget shell overrides this token with a one-member
12725
+ * account context, which keeps the heavy root service from ever being
12726
+ * constructed inside the wallet.
12727
+ */
12728
+ /**
12729
+ * Injection token for the active-account read surface. Defaults to
12730
+ * {@link UnifiedWalletService} so consumers that already provide it need no
12731
+ * extra wiring; override it to supply a narrower source (the embedded shell
12732
+ * does this to avoid constructing the root service inside the wallet).
12733
+ */
12734
+ const ACTIVE_ACCOUNT_SOURCE = new InjectionToken('ACTIVE_ACCOUNT_SOURCE', {
12735
+ providedIn: 'root',
12736
+ factory: () => inject(UnifiedWalletService),
12737
+ });
12738
+
12193
12739
  /**
12194
12740
  * HSuite Native Connect
12195
12741
  * Copyright 2024-2025 HSuite (https://hsuite.finance)
@@ -12333,7 +12879,7 @@ function assertSafeInteger(value, context) {
12333
12879
  * ```
12334
12880
  */
12335
12881
  class HederaTransactionBuilderService {
12336
- wallet = inject(UnifiedWalletService);
12882
+ accountSource = inject(ACTIVE_ACCOUNT_SOURCE);
12337
12883
  logger = inject(LoggerService).scoped('HederaTransactionBuilder');
12338
12884
  /**
12339
12885
  * Gets the network ID from the active wallet account.
@@ -12348,7 +12894,7 @@ class HederaTransactionBuilderService {
12348
12894
  * @throws {Error} When used in methods that require a network, if no account is active
12349
12895
  */
12350
12896
  getNetworkId() {
12351
- const activeAccount = this.wallet.activeAccount();
12897
+ const activeAccount = this.accountSource.activeAccount();
12352
12898
  return activeAccount?.networkId;
12353
12899
  }
12354
12900
  /**
@@ -12394,7 +12940,7 @@ class HederaTransactionBuilderService {
12394
12940
  * @returns Key configuration or undefined if no active account
12395
12941
  */
12396
12942
  getActiveAccountKeyConfig() {
12397
- const activeAccount = this.wallet.activeAccount();
12943
+ const activeAccount = this.accountSource.activeAccount();
12398
12944
  if (!activeAccount) {
12399
12945
  this.logger.debug('No active account for key config');
12400
12946
  return undefined;
@@ -14653,5 +15199,5 @@ function provideWalletErrorHandler(config) {
14653
15199
  * Generated bundle index. Do not edit.
14654
15200
  */
14655
15201
 
14656
- export { AccountActionsComponent, AccountFilterComponent, AccountFormattingService, AccountGroupingService, AccountListComponent, AccountSelectorComponent, AccountSelectorService, BaseWalletProvider, ChannelClientService, ChromeExtensionTransport, DEFAULT_LEDGER_ICONS, DEFAULT_WALLET_URL, HederaSigner, HederaTransactionBuilderService, HsuiteNativeProvider, HsuiteWalletModule, LEDGER_COLORS, LEDGER_NAMES, LoggerService, P2PNativeProvider, P2PSessionManager, SignerFactory, TransactionService, UnifiedWalletService, WalletAccountDisplayComponent, WalletConnectButtonComponent, WalletConnectClientManager, WalletConnectPromptComponent, WalletConnectSessionStore, WalletConnectSigningOrchestrator, WalletConnectV2Provider, WalletConnectedDirective, WalletConnectedGuardComponent, WalletConnectionModalComponent, WalletContextDirective, WalletContextService, WalletErrorHandler, WalletEventBus, WalletEventsDirective, WalletSessionDisplayComponent, WalletTransactionStatusComponent, XrplSigner, XrplTransactionBuilderService, getExtensionVersion, getLedgerColor, getLedgerIcon, getLedgerName, getTokenIcon, isExtensionInstalled, isHsuiteNativeConfig, isWalletConnectV2Config, provideWalletErrorHandler, scaleHederaAmountToBaseUnits };
15202
+ export { ACTIVE_ACCOUNT_SOURCE, AccountActionsComponent, AccountFilterComponent, AccountFormattingService, AccountGroupingService, AccountListComponent, AccountSelectorComponent, AccountSelectorService, BaseWalletProvider, ChannelClientService, ChromeExtensionTransport, DEFAULT_LEDGER_ICONS, DEFAULT_WALLET_URL, HSUITE_AUTH_HEADER, HSUITE_LEDGER_HEADER, HederaSigner, HederaTransactionBuilderService, HsuiteAuthInterceptor, HsuiteNativeProvider, HsuiteWalletModule, LEDGER_COLORS, LEDGER_ICON_NAMES, LEDGER_NAMES, LedgerUIRegistry, LoggerService, P2PNativeProvider, P2PSessionManager, SMART_SESSION_CONFIG, SignerFactory, SmartSessionService, TransactionService, UnifiedWalletService, WalletAccountDisplayComponent, WalletConnectButtonComponent, WalletConnectClientManager, WalletConnectPromptComponent, WalletConnectSessionStore, WalletConnectSigningOrchestrator, WalletConnectV2Provider, WalletConnectedDirective, WalletConnectedGuardComponent, WalletConnectionModalComponent, WalletContextDirective, WalletContextService, WalletErrorHandler, WalletEventBus, WalletEventsDirective, WalletSessionDisplayComponent, WalletTransactionStatusComponent, XrplSigner, XrplTransactionBuilderService, getExtensionVersion, getLedgerColor, getLedgerIcon, getLedgerName, getTokenIcon, hsuiteAuthInterceptor, isExtensionInstalled, isHsuiteNativeConfig, isWalletConnectV2Config, provideWalletErrorHandler, registerLedgerIcons, scaleHederaAmountToBaseUnits };
14657
15203
  //# sourceMappingURL=hsuite-native-connect-angular.mjs.map