@hsuite/native-connect-angular 1.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (276) hide show
  1. package/README.md +48 -0
  2. package/USAGE_EXAMPLES.md +476 -0
  3. package/assets/wallets/extension.svg +7 -0
  4. package/assets/wallets/hashpack.svg +6 -0
  5. package/assets/wallets/hsuite.svg +11 -0
  6. package/assets/wallets/kabila.svg +11 -0
  7. package/assets/wallets/walletconnect.svg +13 -0
  8. package/coverage/base.css +224 -0
  9. package/coverage/block-navigation.js +87 -0
  10. package/coverage/coverage-summary.json +50 -0
  11. package/coverage/favicon.png +0 -0
  12. package/coverage/index.html +476 -0
  13. package/coverage/lcov-report/base.css +224 -0
  14. package/coverage/lcov-report/block-navigation.js +87 -0
  15. package/coverage/lcov-report/favicon.png +0 -0
  16. package/coverage/lcov-report/index.html +476 -0
  17. package/coverage/lcov-report/lib/components/account-selector/account-actions/account-actions.component.ts.html +868 -0
  18. package/coverage/lcov-report/lib/components/account-selector/account-actions/index.html +116 -0
  19. package/coverage/lcov-report/lib/components/account-selector/account-filter/account-filter.component.ts.html +1288 -0
  20. package/coverage/lcov-report/lib/components/account-selector/account-filter/index.html +116 -0
  21. package/coverage/lcov-report/lib/components/account-selector/account-formatting.service.ts.html +685 -0
  22. package/coverage/lcov-report/lib/components/account-selector/account-grouping.service.ts.html +766 -0
  23. package/coverage/lcov-report/lib/components/account-selector/account-list/account-list.component.ts.html +1495 -0
  24. package/coverage/lcov-report/lib/components/account-selector/account-list/index.html +116 -0
  25. package/coverage/lcov-report/lib/components/account-selector/account-selector.component.ts.html +1495 -0
  26. package/coverage/lcov-report/lib/components/account-selector/account-selector.service.ts.html +1588 -0
  27. package/coverage/lcov-report/lib/components/account-selector/index.html +161 -0
  28. package/coverage/lcov-report/lib/components/wallet-account-display/index.html +116 -0
  29. package/coverage/lcov-report/lib/components/wallet-account-display/wallet-account-display.component.ts.html +505 -0
  30. package/coverage/lcov-report/lib/components/wallet-connect-button/index.html +116 -0
  31. package/coverage/lcov-report/lib/components/wallet-connect-button/wallet-connect-button.component.ts.html +805 -0
  32. package/coverage/lcov-report/lib/components/wallet-connect-prompt/index.html +116 -0
  33. package/coverage/lcov-report/lib/components/wallet-connect-prompt/wallet-connect-prompt.component.ts.html +409 -0
  34. package/coverage/lcov-report/lib/components/wallet-connected-guard/index.html +116 -0
  35. package/coverage/lcov-report/lib/components/wallet-connected-guard/wallet-connected-guard.component.ts.html +304 -0
  36. package/coverage/lcov-report/lib/components/wallet-connection-modal/connection-method-step/connection-method-step.component.ts.html +436 -0
  37. package/coverage/lcov-report/lib/components/wallet-connection-modal/connection-method-step/index.html +116 -0
  38. package/coverage/lcov-report/lib/components/wallet-connection-modal/index.html +116 -0
  39. package/coverage/lcov-report/lib/components/wallet-connection-modal/qr-pairing-step/index.html +116 -0
  40. package/coverage/lcov-report/lib/components/wallet-connection-modal/qr-pairing-step/qr-pairing-step.component.ts.html +2287 -0
  41. package/coverage/lcov-report/lib/components/wallet-connection-modal/wallet-connection-modal.component.ts.html +2275 -0
  42. package/coverage/lcov-report/lib/components/wallet-session-display/index.html +116 -0
  43. package/coverage/lcov-report/lib/components/wallet-session-display/wallet-session-display.component.ts.html +676 -0
  44. package/coverage/lcov-report/lib/components/wallet-transaction-status/index.html +116 -0
  45. package/coverage/lcov-report/lib/components/wallet-transaction-status/wallet-transaction-status.component.ts.html +703 -0
  46. package/coverage/lcov-report/lib/directives/index.html +146 -0
  47. package/coverage/lcov-report/lib/directives/wallet-connected.directive.ts.html +670 -0
  48. package/coverage/lcov-report/lib/directives/wallet-context.directive.ts.html +547 -0
  49. package/coverage/lcov-report/lib/directives/wallet-events.directive.ts.html +781 -0
  50. package/coverage/lcov-report/lib/hsuite-wallet.module.ts.html +715 -0
  51. package/coverage/lcov-report/lib/index.html +116 -0
  52. package/coverage/lcov-report/lib/models/connection-config.model.ts.html +280 -0
  53. package/coverage/lcov-report/lib/models/index.html +131 -0
  54. package/coverage/lcov-report/lib/models/provider-types.ts.html +577 -0
  55. package/coverage/lcov-report/lib/providers/base-wallet-provider.ts.html +1138 -0
  56. package/coverage/lcov-report/lib/providers/hsuite-native/channel-client.service.ts.html +2671 -0
  57. package/coverage/lcov-report/lib/providers/hsuite-native/index.html +116 -0
  58. package/coverage/lcov-report/lib/providers/hsuite-native-provider.ts.html +2347 -0
  59. package/coverage/lcov-report/lib/providers/index.html +146 -0
  60. package/coverage/lcov-report/lib/providers/p2p-native/index.html +131 -0
  61. package/coverage/lcov-report/lib/providers/p2p-native/p2p-native.provider.ts.html +2254 -0
  62. package/coverage/lcov-report/lib/providers/p2p-native/p2p-session-manager.ts.html +2170 -0
  63. package/coverage/lcov-report/lib/providers/wallet-error-handler.ts.html +1132 -0
  64. package/coverage/lcov-report/lib/providers/walletconnect/core/index.html +176 -0
  65. package/coverage/lcov-report/lib/providers/walletconnect/core/session-health.ts.html +673 -0
  66. package/coverage/lcov-report/lib/providers/walletconnect/core/walletconnect-client-manager.ts.html +1177 -0
  67. package/coverage/lcov-report/lib/providers/walletconnect/core/walletconnect-provider.ts.html +2563 -0
  68. package/coverage/lcov-report/lib/providers/walletconnect/core/walletconnect-session-store.ts.html +904 -0
  69. package/coverage/lcov-report/lib/providers/walletconnect/core/walletconnect-signing-orchestrator.ts.html +982 -0
  70. package/coverage/lcov-report/lib/providers/walletconnect/signers/hedera-signer.ts.html +1915 -0
  71. package/coverage/lcov-report/lib/providers/walletconnect/signers/index.html +146 -0
  72. package/coverage/lcov-report/lib/providers/walletconnect/signers/signer-factory.ts.html +445 -0
  73. package/coverage/lcov-report/lib/providers/walletconnect/signers/xrpl-signer.ts.html +1519 -0
  74. package/coverage/lcov-report/lib/services/index.html +191 -0
  75. package/coverage/lcov-report/lib/services/logger.service.ts.html +463 -0
  76. package/coverage/lcov-report/lib/services/transaction-builders/base-transaction-builder.service.ts.html +1840 -0
  77. package/coverage/lcov-report/lib/services/transaction-builders/hedera-amount-utils.ts.html +337 -0
  78. package/coverage/lcov-report/lib/services/transaction-builders/hedera-transaction-builder.service.ts.html +3940 -0
  79. package/coverage/lcov-report/lib/services/transaction-builders/index.html +161 -0
  80. package/coverage/lcov-report/lib/services/transaction-builders/xrpl-transaction-builder.service.ts.html +2581 -0
  81. package/coverage/lcov-report/lib/services/transaction.service.ts.html +1123 -0
  82. package/coverage/lcov-report/lib/services/unified-wallet.service.ts.html +2641 -0
  83. package/coverage/lcov-report/lib/services/wallet-context.service.ts.html +637 -0
  84. package/coverage/lcov-report/lib/services/wallet-event-bus.service.ts.html +643 -0
  85. package/coverage/lcov-report/lib/services/wallet-providers.service.ts.html +496 -0
  86. package/coverage/lcov-report/lib/transports/chrome-extension-transport.ts.html +823 -0
  87. package/coverage/lcov-report/lib/transports/index.html +116 -0
  88. package/coverage/lcov-report/lib/utils/index.html +116 -0
  89. package/coverage/lcov-report/lib/utils/ledger-icons.util.ts.html +319 -0
  90. package/coverage/lcov-report/prettify.css +1 -0
  91. package/coverage/lcov-report/prettify.js +2 -0
  92. package/coverage/lcov-report/sort-arrow-sprite.png +0 -0
  93. package/coverage/lcov-report/sorter.js +210 -0
  94. package/coverage/lcov.info +19252 -0
  95. package/coverage/lib/components/account-selector/account-actions/account-actions.component.ts.html +868 -0
  96. package/coverage/lib/components/account-selector/account-actions/index.html +116 -0
  97. package/coverage/lib/components/account-selector/account-filter/account-filter.component.ts.html +1288 -0
  98. package/coverage/lib/components/account-selector/account-filter/index.html +116 -0
  99. package/coverage/lib/components/account-selector/account-formatting.service.ts.html +685 -0
  100. package/coverage/lib/components/account-selector/account-grouping.service.ts.html +766 -0
  101. package/coverage/lib/components/account-selector/account-list/account-list.component.ts.html +1495 -0
  102. package/coverage/lib/components/account-selector/account-list/index.html +116 -0
  103. package/coverage/lib/components/account-selector/account-selector.component.ts.html +1495 -0
  104. package/coverage/lib/components/account-selector/account-selector.service.ts.html +1588 -0
  105. package/coverage/lib/components/account-selector/index.html +161 -0
  106. package/coverage/lib/components/wallet-account-display/index.html +116 -0
  107. package/coverage/lib/components/wallet-account-display/wallet-account-display.component.ts.html +505 -0
  108. package/coverage/lib/components/wallet-connect-button/index.html +116 -0
  109. package/coverage/lib/components/wallet-connect-button/wallet-connect-button.component.ts.html +805 -0
  110. package/coverage/lib/components/wallet-connect-prompt/index.html +116 -0
  111. package/coverage/lib/components/wallet-connect-prompt/wallet-connect-prompt.component.ts.html +409 -0
  112. package/coverage/lib/components/wallet-connected-guard/index.html +116 -0
  113. package/coverage/lib/components/wallet-connected-guard/wallet-connected-guard.component.ts.html +304 -0
  114. package/coverage/lib/components/wallet-connection-modal/connection-method-step/connection-method-step.component.ts.html +436 -0
  115. package/coverage/lib/components/wallet-connection-modal/connection-method-step/index.html +116 -0
  116. package/coverage/lib/components/wallet-connection-modal/index.html +116 -0
  117. package/coverage/lib/components/wallet-connection-modal/qr-pairing-step/index.html +116 -0
  118. package/coverage/lib/components/wallet-connection-modal/qr-pairing-step/qr-pairing-step.component.ts.html +2287 -0
  119. package/coverage/lib/components/wallet-connection-modal/wallet-connection-modal.component.ts.html +2275 -0
  120. package/coverage/lib/components/wallet-session-display/index.html +116 -0
  121. package/coverage/lib/components/wallet-session-display/wallet-session-display.component.ts.html +676 -0
  122. package/coverage/lib/components/wallet-transaction-status/index.html +116 -0
  123. package/coverage/lib/components/wallet-transaction-status/wallet-transaction-status.component.ts.html +703 -0
  124. package/coverage/lib/directives/index.html +146 -0
  125. package/coverage/lib/directives/wallet-connected.directive.ts.html +670 -0
  126. package/coverage/lib/directives/wallet-context.directive.ts.html +547 -0
  127. package/coverage/lib/directives/wallet-events.directive.ts.html +781 -0
  128. package/coverage/lib/hsuite-wallet.module.ts.html +715 -0
  129. package/coverage/lib/index.html +116 -0
  130. package/coverage/lib/models/connection-config.model.ts.html +280 -0
  131. package/coverage/lib/models/index.html +131 -0
  132. package/coverage/lib/models/provider-types.ts.html +577 -0
  133. package/coverage/lib/providers/base-wallet-provider.ts.html +1138 -0
  134. package/coverage/lib/providers/hsuite-native/channel-client.service.ts.html +2671 -0
  135. package/coverage/lib/providers/hsuite-native/index.html +116 -0
  136. package/coverage/lib/providers/hsuite-native-provider.ts.html +2347 -0
  137. package/coverage/lib/providers/index.html +146 -0
  138. package/coverage/lib/providers/p2p-native/index.html +131 -0
  139. package/coverage/lib/providers/p2p-native/p2p-native.provider.ts.html +2254 -0
  140. package/coverage/lib/providers/p2p-native/p2p-session-manager.ts.html +2170 -0
  141. package/coverage/lib/providers/wallet-error-handler.ts.html +1132 -0
  142. package/coverage/lib/providers/walletconnect/core/index.html +176 -0
  143. package/coverage/lib/providers/walletconnect/core/session-health.ts.html +673 -0
  144. package/coverage/lib/providers/walletconnect/core/walletconnect-client-manager.ts.html +1177 -0
  145. package/coverage/lib/providers/walletconnect/core/walletconnect-provider.ts.html +2563 -0
  146. package/coverage/lib/providers/walletconnect/core/walletconnect-session-store.ts.html +904 -0
  147. package/coverage/lib/providers/walletconnect/core/walletconnect-signing-orchestrator.ts.html +982 -0
  148. package/coverage/lib/providers/walletconnect/signers/hedera-signer.ts.html +1915 -0
  149. package/coverage/lib/providers/walletconnect/signers/index.html +146 -0
  150. package/coverage/lib/providers/walletconnect/signers/signer-factory.ts.html +445 -0
  151. package/coverage/lib/providers/walletconnect/signers/xrpl-signer.ts.html +1519 -0
  152. package/coverage/lib/services/index.html +191 -0
  153. package/coverage/lib/services/logger.service.ts.html +463 -0
  154. package/coverage/lib/services/transaction-builders/base-transaction-builder.service.ts.html +1840 -0
  155. package/coverage/lib/services/transaction-builders/hedera-amount-utils.ts.html +337 -0
  156. package/coverage/lib/services/transaction-builders/hedera-transaction-builder.service.ts.html +3940 -0
  157. package/coverage/lib/services/transaction-builders/index.html +161 -0
  158. package/coverage/lib/services/transaction-builders/xrpl-transaction-builder.service.ts.html +2581 -0
  159. package/coverage/lib/services/transaction.service.ts.html +1123 -0
  160. package/coverage/lib/services/unified-wallet.service.ts.html +2641 -0
  161. package/coverage/lib/services/wallet-context.service.ts.html +637 -0
  162. package/coverage/lib/services/wallet-event-bus.service.ts.html +643 -0
  163. package/coverage/lib/services/wallet-providers.service.ts.html +496 -0
  164. package/coverage/lib/transports/chrome-extension-transport.ts.html +823 -0
  165. package/coverage/lib/transports/index.html +116 -0
  166. package/coverage/lib/utils/index.html +116 -0
  167. package/coverage/lib/utils/ledger-icons.util.ts.html +319 -0
  168. package/coverage/prettify.css +1 -0
  169. package/coverage/prettify.js +2 -0
  170. package/coverage/sort-arrow-sprite.png +0 -0
  171. package/coverage/sorter.js +210 -0
  172. package/dist/README.md +48 -0
  173. package/dist/fesm2022/hsuite-native-connect-angular.mjs +14592 -0
  174. package/dist/fesm2022/hsuite-native-connect-angular.mjs.map +1 -0
  175. package/dist/index.d.ts +6949 -0
  176. package/examples/minimal-connect.ts +178 -0
  177. package/examples/multi-protocol.ts +495 -0
  178. package/examples/transaction-signing.ts +361 -0
  179. package/jest.config.json +45 -0
  180. package/karma.conf.js +42 -0
  181. package/ng-package.json +20 -0
  182. package/package.json +60 -0
  183. package/src/index.ts +203 -0
  184. package/src/lib/components/account-selector/account-actions/account-actions.component.ts +261 -0
  185. package/src/lib/components/account-selector/account-filter/account-filter.component.ts +401 -0
  186. package/src/lib/components/account-selector/account-formatting.service.ts +200 -0
  187. package/src/lib/components/account-selector/account-grouping.service.ts +227 -0
  188. package/src/lib/components/account-selector/account-list/account-list.component.ts +470 -0
  189. package/src/lib/components/account-selector/account-selector.component.html +135 -0
  190. package/src/lib/components/account-selector/account-selector.component.scss +2039 -0
  191. package/src/lib/components/account-selector/account-selector.component.ts +470 -0
  192. package/src/lib/components/account-selector/account-selector.service.ts +501 -0
  193. package/src/lib/components/wallet-account-display/wallet-account-display.component.html +34 -0
  194. package/src/lib/components/wallet-account-display/wallet-account-display.component.scss +99 -0
  195. package/src/lib/components/wallet-account-display/wallet-account-display.component.ts +140 -0
  196. package/src/lib/components/wallet-connect-button/wallet-connect-button.component.html +14 -0
  197. package/src/lib/components/wallet-connect-button/wallet-connect-button.component.scss +272 -0
  198. package/src/lib/components/wallet-connect-button/wallet-connect-button.component.ts +240 -0
  199. package/src/lib/components/wallet-connect-prompt/wallet-connect-prompt.component.html +24 -0
  200. package/src/lib/components/wallet-connect-prompt/wallet-connect-prompt.component.scss +50 -0
  201. package/src/lib/components/wallet-connect-prompt/wallet-connect-prompt.component.ts +108 -0
  202. package/src/lib/components/wallet-connected-guard/wallet-connected-guard.component.html +24 -0
  203. package/src/lib/components/wallet-connected-guard/wallet-connected-guard.component.ts +73 -0
  204. package/src/lib/components/wallet-connection-modal/connection-method-step/connection-method-step.component.html +56 -0
  205. package/src/lib/components/wallet-connection-modal/connection-method-step/connection-method-step.component.scss +218 -0
  206. package/src/lib/components/wallet-connection-modal/connection-method-step/connection-method-step.component.ts +117 -0
  207. package/src/lib/components/wallet-connection-modal/qr-pairing-step/qr-pairing-step.component.html +94 -0
  208. package/src/lib/components/wallet-connection-modal/qr-pairing-step/qr-pairing-step.component.scss +272 -0
  209. package/src/lib/components/wallet-connection-modal/qr-pairing-step/qr-pairing-step.component.ts +734 -0
  210. package/src/lib/components/wallet-connection-modal/wallet-connection-modal.component.html +197 -0
  211. package/src/lib/components/wallet-connection-modal/wallet-connection-modal.component.scss +678 -0
  212. package/src/lib/components/wallet-connection-modal/wallet-connection-modal.component.ts +730 -0
  213. package/src/lib/components/wallet-session-display/wallet-session-display.component.html +110 -0
  214. package/src/lib/components/wallet-session-display/wallet-session-display.component.scss +179 -0
  215. package/src/lib/components/wallet-session-display/wallet-session-display.component.ts +197 -0
  216. package/src/lib/components/wallet-transaction-status/wallet-transaction-status.component.html +65 -0
  217. package/src/lib/components/wallet-transaction-status/wallet-transaction-status.component.scss +254 -0
  218. package/src/lib/components/wallet-transaction-status/wallet-transaction-status.component.ts +206 -0
  219. package/src/lib/directives/wallet-connected.directive.ts +195 -0
  220. package/src/lib/directives/wallet-context.directive.ts +154 -0
  221. package/src/lib/directives/wallet-events.directive.ts +232 -0
  222. package/src/lib/hsuite-wallet.module.ts +210 -0
  223. package/src/lib/models/connection-config.model.ts +65 -0
  224. package/src/lib/models/provider-types.ts +164 -0
  225. package/src/lib/models/unified-account.model.ts +76 -0
  226. package/src/lib/models/wallet-context.model.ts +121 -0
  227. package/src/lib/models/wallet-events.model.ts +158 -0
  228. package/src/lib/providers/base-wallet-provider.ts +351 -0
  229. package/src/lib/providers/hsuite-native/channel-client.service.spec.ts +73 -0
  230. package/src/lib/providers/hsuite-native/channel-client.service.ts +862 -0
  231. package/src/lib/providers/hsuite-native/index.ts +8 -0
  232. package/src/lib/providers/hsuite-native-provider.ts +754 -0
  233. package/src/lib/providers/mobile-native/mobile-native.provider.spec.ts +19 -0
  234. package/src/lib/providers/p2p-native/index.ts +30 -0
  235. package/src/lib/providers/p2p-native/p2p-native.provider.spec.ts +523 -0
  236. package/src/lib/providers/p2p-native/p2p-native.provider.ts +723 -0
  237. package/src/lib/providers/p2p-native/p2p-session-manager.ts +695 -0
  238. package/src/lib/providers/wallet-error-handler.ts +349 -0
  239. package/src/lib/providers/walletconnect/core/base-signer.interface.ts +122 -0
  240. package/src/lib/providers/walletconnect/core/session-health.ts +196 -0
  241. package/src/lib/providers/walletconnect/core/walletconnect-client-manager.ts +364 -0
  242. package/src/lib/providers/walletconnect/core/walletconnect-provider.integration.spec.ts +348 -0
  243. package/src/lib/providers/walletconnect/core/walletconnect-provider.ts +826 -0
  244. package/src/lib/providers/walletconnect/core/walletconnect-session-store.ts +273 -0
  245. package/src/lib/providers/walletconnect/core/walletconnect-signing-orchestrator.ts +299 -0
  246. package/src/lib/providers/walletconnect/core/walletconnect-types.ts +48 -0
  247. package/src/lib/providers/walletconnect/index.ts +33 -0
  248. package/src/lib/providers/walletconnect/signers/hedera-signer.spec.ts +367 -0
  249. package/src/lib/providers/walletconnect/signers/hedera-signer.ts +610 -0
  250. package/src/lib/providers/walletconnect/signers/signer-factory.spec.ts +62 -0
  251. package/src/lib/providers/walletconnect/signers/signer-factory.ts +120 -0
  252. package/src/lib/providers/walletconnect/signers/xrpl-signer.spec.ts +296 -0
  253. package/src/lib/providers/walletconnect/signers/xrpl-signer.ts +478 -0
  254. package/src/lib/services/logger.service.ts +126 -0
  255. package/src/lib/services/transaction-builders/base-transaction-builder.service.ts +585 -0
  256. package/src/lib/services/transaction-builders/hedera-amount-utils.ts +84 -0
  257. package/src/lib/services/transaction-builders/hedera-transaction-builder.service.spec.ts +741 -0
  258. package/src/lib/services/transaction-builders/hedera-transaction-builder.service.ts +1285 -0
  259. package/src/lib/services/transaction-builders/index.ts +54 -0
  260. package/src/lib/services/transaction-builders/xrpl-transaction-builder.service.spec.ts +937 -0
  261. package/src/lib/services/transaction-builders/xrpl-transaction-builder.service.ts +832 -0
  262. package/src/lib/services/transaction.service.ts +346 -0
  263. package/src/lib/services/unified-wallet.service.spec.ts +1382 -0
  264. package/src/lib/services/unified-wallet.service.ts +852 -0
  265. package/src/lib/services/wallet-context.service.ts +184 -0
  266. package/src/lib/services/wallet-event-bus.service.ts +186 -0
  267. package/src/lib/services/wallet-providers.service.ts +137 -0
  268. package/src/lib/transports/chrome-extension-transport.ts +246 -0
  269. package/src/lib/utils/index.ts +14 -0
  270. package/src/lib/utils/ledger-icons.util.ts +78 -0
  271. package/test/test-setup.ts +21 -0
  272. package/test-setup.ts +63 -0
  273. package/tsconfig.build.json +11 -0
  274. package/tsconfig.json +29 -0
  275. package/tsconfig.spec.json +15 -0
  276. package/vitest.config.ts +48 -0
@@ -0,0 +1,852 @@
1
+ /**
2
+ * HSuite Native Connect
3
+ * Copyright 2024-2025 HSuite (https://hsuite.finance)
4
+ *
5
+ * SPDX-License-Identifier: PolyForm-Noncommercial-1.0.0
6
+ *
7
+ * This file is part of HSuite Native Connect. For commercial licensing,
8
+ * visit https://hsuite.finance/licensing
9
+ */
10
+
11
+ /**
12
+ * @file Central service for managing multiple wallet providers in Angular applications.
13
+ * @module services/unified-wallet
14
+ *
15
+ * @description
16
+ * UnifiedWalletService is the primary entry point for dApp developers to interact with
17
+ * blockchain wallets. It provides a unified API that abstracts the differences between
18
+ * various wallet connection protocols (HSuite Native, WalletConnect, P2P).
19
+ *
20
+ * Key Capabilities:
21
+ * - **Multi-Provider Management**: Register and manage multiple wallet providers
22
+ * - **Unified Account Access**: Aggregate accounts from all connected providers
23
+ * - **Active Account Tracking**: Maintain and switch the currently active account
24
+ * - **Transaction Operations**: Sign and submit transactions through any connected wallet
25
+ * - **Session Management**: Handle wallet sessions with automatic reconnection
26
+ *
27
+ * Architecture:
28
+ * ```
29
+ * +-------------------------------------------------------------------+
30
+ * | UnifiedWalletService |
31
+ * +-------------------------------------------------------------------+
32
+ * | |
33
+ * | +-------------------+ +-------------------+ +----------------+ |
34
+ * | | HsuiteNative | | WalletConnect | | P2PNative | |
35
+ * | | Provider | | V2Provider | | Provider | |
36
+ * | +-------------------+ +-------------------+ +----------------+ |
37
+ * | | | | |
38
+ * | +----------------------+----------------------+ |
39
+ * | | |
40
+ * | BaseWalletProvider |
41
+ * | (common interface) |
42
+ * +-------------------------------------------------------------------+
43
+ * ```
44
+ */
45
+
46
+ import { Injectable, signal, computed, inject, effect } from '@angular/core';
47
+ import { getLogger } from '@hsuite/native-connect-sdk';
48
+
49
+ import type { ConnectionConfig } from '../models/connection-config.model';
50
+ import type { ProviderType, ConnectionStatus } from '../models/provider-types';
51
+ import type { UnifiedAccount } from '../models/unified-account.model';
52
+ import { BaseWalletProvider } from '../providers/base-wallet-provider';
53
+ import { HsuiteNativeProvider } from '../providers/hsuite-native-provider';
54
+ import { P2PNativeProvider } from '../providers/p2p-native/p2p-native.provider';
55
+ import { WalletConnectV2Provider } from '../providers/walletconnect/core/walletconnect-provider';
56
+
57
+ import { WalletEventBus } from './wallet-event-bus.service';
58
+
59
+
60
+ const logger = getLogger().scoped?.('UnifiedWalletService') ?? getLogger();
61
+
62
+ interface ProviderSummary {
63
+ id: string;
64
+ name: string;
65
+ providerType: string;
66
+ status: ConnectionStatus;
67
+ accounts: UnifiedAccount[];
68
+ supportsReconnect: boolean;
69
+ }
70
+
71
+ /**
72
+ * Central service for managing wallet connections across multiple protocols.
73
+ *
74
+ * @description
75
+ * UnifiedWalletService provides a unified interface for interacting with blockchain wallets
76
+ * regardless of the underlying connection protocol. It manages multiple provider instances,
77
+ * aggregates accounts, and provides transaction signing/submission capabilities.
78
+ *
79
+ * The service automatically registers built-in providers (HSuite Native, WalletConnect, P2P)
80
+ * and supports session restoration across page reloads.
81
+ *
82
+ * @Component({
83
+ * template: `
84
+ * <div *ngIf="wallet.activeAccount() as account">
85
+ * Connected: {{ account.address }}
86
+ * </div>
87
+ * <button (click)="connectWallet()">Connect</button>
88
+ * `
89
+ * })
90
+ * export class MyComponent {
91
+ * wallet = inject(UnifiedWalletService);
92
+ *
93
+ * async connectWallet() {
94
+ * await this.wallet.connect('hsuite-native', {
95
+ * type: 'hsuite-native',
96
+ * appId: 'my-dapp',
97
+ * appName: 'My dApp',
98
+ * ledgerId: 'hedera',
99
+ * networkId: 'testnet',
100
+ * });
101
+ * }
102
+ * }
103
+ * ```
104
+ *
105
+ * @publicApi
106
+ */
107
+ @Injectable({ providedIn: 'root' })
108
+ export class UnifiedWalletService {
109
+ /**
110
+ * Map of registered providers
111
+ */
112
+ private readonly providers = new Map<string, BaseWalletProvider>();
113
+
114
+ /**
115
+ * Signal tracking all registered provider IDs
116
+ */
117
+ private readonly _providerIds = signal<string[]>([]);
118
+
119
+ /**
120
+ * Signal for the active account (across all providers)
121
+ */
122
+ private readonly _activeAccount = signal<UnifiedAccount | null>(null);
123
+
124
+ /**
125
+ * Event bus for emitting wallet events
126
+ */
127
+ private readonly eventBus = inject(WalletEventBus);
128
+
129
+ /**
130
+ *
131
+ * @param hsuiteProvider
132
+ * @param walletConnectProvider
133
+ * @param p2pNativeProvider
134
+ */
135
+ constructor(
136
+ hsuiteProvider: HsuiteNativeProvider,
137
+ walletConnectProvider: WalletConnectV2Provider,
138
+ p2pNativeProvider: P2PNativeProvider,
139
+ ) {
140
+ // Auto-register built-in providers (injected as constructor params)
141
+ this.registerProvider(hsuiteProvider);
142
+ this.registerProvider(walletConnectProvider);
143
+ this.registerProvider(p2pNativeProvider);
144
+
145
+ // Auto-select first account from unknown restored session (after a delay to let providers restore)
146
+ setTimeout(() => {
147
+ const allAccounts = this.allAccounts();
148
+ if (!this._activeAccount() && allAccounts.length > 0) {
149
+ this.setActiveAccount(allAccounts[0]);
150
+
151
+ // Emit session restored event
152
+ this.eventBus.sessionRestored.emit({
153
+ providerId: allAccounts[0].providerId,
154
+ sessionKey: allAccounts[0].id,
155
+ accounts: allAccounts,
156
+ metadata: { autoRestored: true },
157
+ timestamp: Date.now(),
158
+ });
159
+ }
160
+ }, 100);
161
+
162
+ effect(() => {
163
+ const accounts = this.allAccounts();
164
+ const active = this._activeAccount();
165
+
166
+ if (accounts.length === 0) {
167
+ if (active) {
168
+ this.setActiveAccount(null);
169
+ }
170
+ return;
171
+ }
172
+
173
+ const activeStillPresent = active ? accounts.some((acct) => acct.id === active.id) : false;
174
+ if (!activeStillPresent) {
175
+ this.setActiveAccount(accounts[0]);
176
+ }
177
+ });
178
+ }
179
+
180
+ /**
181
+ * Gets summaries of all registered providers including status and accounts.
182
+ *
183
+ * @description
184
+ * Returns metadata about each registered provider, useful for building
185
+ * wallet selection UI or debugging connection states.
186
+ *
187
+ * @returns Array of provider summaries with status and account information
188
+ */
189
+ getProviderSummaries(): ProviderSummary[] {
190
+ return Array.from(this.providers.values()).map((provider) => ({
191
+ id: provider.id,
192
+ name: provider.metadata.name,
193
+ providerType: provider.metadata.type,
194
+ status: provider.status(),
195
+ accounts: provider.accounts(),
196
+ supportsReconnect: typeof (provider as any).attemptReconnect === 'function',
197
+ }));
198
+ }
199
+
200
+ /**
201
+ * Attempts to reconnect a provider using stored session data.
202
+ *
203
+ * @description
204
+ * Some providers (like HSuite Native) support session persistence and can
205
+ * automatically reconnect after page reload without user interaction.
206
+ * This method triggers the reconnection attempt.
207
+ *
208
+ * @param providerId - The provider ID to reconnect (e.g., 'hsuite-native')
209
+ *
210
+ * @returns Promise resolving to true if reconnection succeeded, false otherwise
211
+ */
212
+ async reconnectProvider(providerId: string): Promise<boolean> {
213
+ const provider = this.providers.get(providerId);
214
+ if (!provider) {
215
+ return false;
216
+ }
217
+ const reconnect = (provider as unknown as { attemptReconnect?: () => Promise<boolean> })
218
+ .attemptReconnect;
219
+ if (typeof reconnect === 'function') {
220
+ try {
221
+ return await reconnect.call(provider);
222
+ } catch (error) {
223
+ logger.warn('Provider reconnect failed', { providerId, error });
224
+ return false;
225
+ }
226
+ }
227
+ return false;
228
+ }
229
+
230
+ /**
231
+ * All accounts from all connected providers (reactive)
232
+ */
233
+ readonly allAccounts = computed<UnifiedAccount[]>(() => {
234
+ const providers = Array.from(this.providers.values());
235
+ return providers.flatMap((p) => p.accounts());
236
+ });
237
+
238
+ /**
239
+ * Currently active account (reactive)
240
+ */
241
+ readonly activeAccount = computed(() => this._activeAccount());
242
+
243
+ /**
244
+ * List of connected providers (reactive)
245
+ */
246
+ readonly connectedProviders = computed<BaseWalletProvider[]>(() => {
247
+ return Array.from(this.providers.values()).filter((p) => p.isConnected());
248
+ });
249
+
250
+ /**
251
+ * Transport state for HSuite Native and P2P Native connections.
252
+ * Values: 'idle' | 'nostr-only' | 'upgrading' | 'p2p-connected' | 'p2p-failed'
253
+ *
254
+ * Checks both HSuite Native and P2P Native providers.
255
+ * Returns 'idle' for non-HSuite connections (WalletConnect, etc.)
256
+ */
257
+ readonly transportState = computed<string>(() => {
258
+ // Check HSuite Native provider first
259
+ const hsuiteProvider = this.providers.get('hsuite-native') as HsuiteNativeProvider | undefined;
260
+ if (hsuiteProvider) {
261
+ const status = hsuiteProvider.status();
262
+ if (status === 'connecting' || status === 'connected') {
263
+ return hsuiteProvider.transportState();
264
+ }
265
+ }
266
+
267
+ // Check P2P Native provider (mobile-native)
268
+ const p2pProvider = this.providers.get('mobile-native') as P2PNativeProvider | undefined;
269
+ if (p2pProvider) {
270
+ const status = p2pProvider.status();
271
+ if (status === 'connecting' || status === 'connected') {
272
+ return p2pProvider.transportState();
273
+ }
274
+ }
275
+
276
+ return 'idle';
277
+ });
278
+
279
+ /**
280
+ * Registers a wallet provider instance.
281
+ *
282
+ * @description
283
+ * Adds a provider to the service's internal registry. Once registered,
284
+ * the provider's accounts will be included in {@link allAccounts} and
285
+ * can be used for wallet operations.
286
+ *
287
+ * Built-in providers (HSuite Native, WalletConnect, P2P) are auto-registered.
288
+ * Use this method only for custom provider implementations.
289
+ *
290
+ * @param provider - The provider instance to register
291
+ */
292
+ registerProvider(provider: BaseWalletProvider): void {
293
+ if (this.providers.has(provider.id)) {
294
+ logger.warn('Provider already registered', { providerId: provider.id });
295
+ return;
296
+ }
297
+
298
+ this.providers.set(provider.id, provider);
299
+ this._providerIds.set(Array.from(this.providers.keys()));
300
+ }
301
+
302
+ /**
303
+ * Unregisters a wallet provider.
304
+ *
305
+ * @description
306
+ * Removes a provider from the service's registry. The provider's accounts
307
+ * will no longer be included in {@link allAccounts}.
308
+ *
309
+ * @param providerId - The provider ID to unregister
310
+ */
311
+ unregisterProvider(providerId: string): void {
312
+ this.providers.delete(providerId);
313
+ this._providerIds.set(Array.from(this.providers.keys()));
314
+ }
315
+
316
+ /**
317
+ * Gets a specific provider by ID.
318
+ *
319
+ * @description
320
+ * Retrieves a registered provider instance for direct interaction.
321
+ * Useful for accessing provider-specific features not exposed through
322
+ * the unified interface.
323
+ *
324
+ * @param providerId - The provider ID (e.g., 'hsuite-native', 'walletconnect-v2')
325
+ *
326
+ * @returns The provider instance or undefined if not found
327
+ */
328
+ getProvider(providerId: string): BaseWalletProvider | undefined {
329
+ return this.providers.get(providerId);
330
+ }
331
+
332
+ /**
333
+ * Gets all providers of a specific type.
334
+ *
335
+ * @description
336
+ * Filters providers by their type, useful when you need to work with
337
+ * a specific category of wallets.
338
+ *
339
+ * @param type - Provider type to filter by (e.g., 'hsuite-native', 'walletconnect-v2')
340
+ *
341
+ * @returns Array of providers matching the specified type
342
+ */
343
+ getProvidersByType(type: ProviderType): BaseWalletProvider[] {
344
+ return Array.from(this.providers.values()).filter((p) => p.metadata.type === type);
345
+ }
346
+
347
+ /**
348
+ * Connects to a wallet using a specific provider.
349
+ *
350
+ * @description
351
+ * Initiates a wallet connection through the specified provider. The connection
352
+ * flow varies by provider type:
353
+ * - **HSuite Native**: Opens wallet window/tab or uses Nostr discovery
354
+ * - **WalletConnect**: Displays QR code for mobile wallet scanning
355
+ * - **P2P Native**: Displays QR code for direct P2P connection
356
+ *
357
+ * Upon successful connection, emits 'connected' and 'accountsUpdated' events
358
+ * via WalletEventBus.
359
+ *
360
+ * @param providerId - The provider ID to use for connection
361
+ * @param config - Connection configuration (varies by provider type)
362
+ *
363
+ * @throws {Error} If provider is not found
364
+ * @throws {Error} If connection fails or times out
365
+ */
366
+ async connect(providerId: string, config: ConnectionConfig): Promise<void> {
367
+ const provider = this.providers.get(providerId);
368
+ if (!provider) {
369
+ throw new Error(`Provider ${providerId} not found`);
370
+ }
371
+
372
+ await provider.connect(config);
373
+
374
+ const accounts = provider.accounts();
375
+
376
+ // Emit connection event
377
+ this.eventBus.connected.emit({
378
+ providerId,
379
+ providerType: provider.metadata.type as 'hsuite-native' | 'walletconnect-v2',
380
+ accounts,
381
+ timestamp: Date.now(),
382
+ });
383
+
384
+ // Emit accounts updated
385
+ this.eventBus.accountsUpdated.emit({
386
+ providerId,
387
+ accounts,
388
+ totalAccounts: this.allAccounts().length,
389
+ timestamp: Date.now(),
390
+ });
391
+
392
+ // Auto-select first account if none is active
393
+ if (!this._activeAccount() && provider.accounts().length > 0) {
394
+ this.setActiveAccount(provider.accounts()[0]);
395
+ }
396
+ }
397
+
398
+ /**
399
+ * Disconnects a specific provider.
400
+ *
401
+ * @description
402
+ * Terminates the wallet connection for the specified provider. If the active
403
+ * account belonged to this provider, automatically selects another available
404
+ * account or clears the active account.
405
+ *
406
+ * @param providerId - The provider ID to disconnect
407
+ *
408
+ * @throws {Error} If provider is not found
409
+ */
410
+ async disconnect(providerId: string): Promise<void> {
411
+ const provider = this.providers.get(providerId);
412
+ if (!provider) {
413
+ throw new Error(`Provider ${providerId} not found`);
414
+ }
415
+
416
+ await provider.disconnect();
417
+
418
+ // If the active account belonged to this provider, clear it
419
+ const active = this._activeAccount();
420
+ if (active && active.providerId === providerId) {
421
+ // Try to select another account from a different provider
422
+ const accounts = this.allAccounts();
423
+ const nextAccount = accounts.find((a) => a.providerId !== providerId);
424
+ this.setActiveAccount(nextAccount || null);
425
+ }
426
+ }
427
+
428
+ /**
429
+ * Disconnects all connected providers.
430
+ *
431
+ * @description
432
+ * Terminates all wallet connections and clears the active account.
433
+ * Useful for logout flows or cleanup operations.
434
+ */
435
+ async disconnectAll(): Promise<void> {
436
+ const disconnectPromises = Array.from(this.providers.values())
437
+ .filter((p) => p.isConnected())
438
+ .map((p) => p.disconnect());
439
+
440
+ await Promise.all(disconnectPromises);
441
+ this.setActiveAccount(null);
442
+ }
443
+
444
+ /**
445
+ * Sets the active account for wallet operations.
446
+ *
447
+ * @description
448
+ * Changes the currently active account. All subsequent signing and transaction
449
+ * operations will use this account. Emits an 'accountChanged' event via
450
+ * WalletEventBus.
451
+ *
452
+ * @param account - The account to set as active, or null to clear
453
+ */
454
+ setActiveAccount(account: UnifiedAccount | null): void {
455
+ const previous = this._activeAccount();
456
+ this._activeAccount.set(account);
457
+
458
+ // Emit account change event
459
+ this.eventBus.accountChanged.emit({
460
+ previousAccount: previous,
461
+ newAccount: account,
462
+ timestamp: Date.now(),
463
+ });
464
+ }
465
+
466
+ /**
467
+ * Signs a transaction using the active account.
468
+ *
469
+ * @description
470
+ * Requests the wallet to sign the provided transaction payload using the
471
+ * active account's private key. The transaction is not submitted to the
472
+ * network.
473
+ *
474
+ * @param payload - Serialized transaction payload to sign (format depends on ledger)
475
+ *
476
+ * @returns Promise resolving to sign result with signed payload and signature
477
+ *
478
+ * @throws {Error} If no active account is set
479
+ * @throws {Error} If provider is not found
480
+ * @throws {Error} If user rejects the signing request
481
+ */
482
+ async signTransaction(payload: string): Promise<unknown> {
483
+ const account = this._activeAccount();
484
+ if (!account) {
485
+ throw new Error('No active account');
486
+ }
487
+
488
+ const provider = this.providers.get(account.providerId);
489
+ if (!provider) {
490
+ throw new Error(`Provider ${account.providerId} not found`);
491
+ }
492
+
493
+ return await provider.signTransaction({
494
+ accountAddress: account.address,
495
+ payload,
496
+ ledgerId: account.ledgerId,
497
+ networkId: account.networkId,
498
+ });
499
+ }
500
+
501
+ /**
502
+ * Submits a transaction using the active account.
503
+ *
504
+ * @description
505
+ * Signs and submits a transaction to the blockchain network. This is a two-step
506
+ * operation: sign then submit. For a single-prompt flow, use
507
+ * {@link signAndExecuteTransaction} instead.
508
+ *
509
+ * Supports batch transactions when isBatch is true.
510
+ *
511
+ * @param payload - Serialized transaction payload to submit
512
+ * @param options - Optional submission options
513
+ * @param options.isBatch - Whether this is a batch transaction
514
+ * @param options.batchKey - Unique key for batch grouping
515
+ * @param options.innerTransactions - Individual transactions within the batch
516
+ *
517
+ * @returns Promise resolving to submit result with transaction ID and hash
518
+ *
519
+ * @throws {Error} If no active account is set
520
+ * @throws {Error} If provider is not found
521
+ * @throws {Error} If user rejects or transaction fails
522
+ */
523
+ async submitTransaction(
524
+ payload: string,
525
+ options?: {
526
+ isBatch?: boolean;
527
+ batchKey?: string;
528
+ innerTransactions?: Array<{ payload: string; description?: string }>;
529
+ },
530
+ ): Promise<unknown> {
531
+ const account = this._activeAccount();
532
+ if (!account) {
533
+ throw new Error('No active account');
534
+ }
535
+
536
+ const provider = this.providers.get(account.providerId);
537
+ if (!provider) {
538
+ throw new Error(`Provider ${account.providerId} not found`);
539
+ }
540
+
541
+ return await provider.submitTransaction({
542
+ accountAddress: account.address,
543
+ payload,
544
+ ledgerId: account.ledgerId,
545
+ networkId: account.networkId,
546
+ ...options,
547
+ });
548
+ }
549
+
550
+ /**
551
+ * Signs an arbitrary message using the active account.
552
+ *
553
+ * @description
554
+ * Requests the wallet to sign a message for authentication or verification
555
+ * purposes (e.g., DAO votes, login challenges). The message is not a
556
+ * blockchain transaction.
557
+ *
558
+ * @param message - The message to sign (plain text or base64 encoded)
559
+ * @param encoding - Message encoding: 'utf-8' (default) or 'base64'
560
+ *
561
+ * @returns Promise resolving to sign result with signature and public key
562
+ *
563
+ * @throws {Error} If no active account is set
564
+ * @throws {Error} If provider is not found
565
+ * @throws {Error} If user rejects the signing request
566
+ */
567
+ async signMessage(message: string, encoding?: 'utf-8' | 'base64'): Promise<unknown> {
568
+ const account = this._activeAccount();
569
+ if (!account) {
570
+ throw new Error('No active account');
571
+ }
572
+
573
+ const provider = this.providers.get(account.providerId);
574
+ if (!provider) {
575
+ throw new Error(`Provider ${account.providerId} not found`);
576
+ }
577
+
578
+ return await provider.signMessage({
579
+ accountAddress: account.address,
580
+ message,
581
+ encoding,
582
+ ledgerId: account.ledgerId,
583
+ networkId: account.networkId,
584
+ });
585
+ }
586
+
587
+ /**
588
+ * Signs and executes a transaction in a single prompt.
589
+ *
590
+ * @description
591
+ * Performs atomic sign-and-submit in a single wallet prompt. This is the
592
+ * **recommended method** for most transaction submissions as it:
593
+ * - Only requires one user approval (better UX)
594
+ * - Matches WalletConnect's `hedera_signAndExecuteTransaction` behavior
595
+ * - Provides atomic operation (sign+submit happen together)
596
+ *
597
+ * For providers that don't support native signAndExecute, this method
598
+ * falls back to separate sign and submit calls.
599
+ *
600
+ * @param payload - Serialized transaction payload
601
+ * @param options - Optional provider-specific options
602
+ *
603
+ * @returns Promise resolving to execution result with transaction ID and hash
604
+ *
605
+ * @throws {Error} If no active account is set
606
+ * @throws {Error} If provider is not found
607
+ * @throws {Error} If user rejects or transaction fails
608
+ */
609
+ async signAndExecuteTransaction(
610
+ payload: string,
611
+ options?: Record<string, unknown>,
612
+ ): Promise<unknown> {
613
+ const account = this._activeAccount();
614
+ if (!account) {
615
+ throw new Error('No active account');
616
+ }
617
+
618
+ const provider = this.providers.get(account.providerId);
619
+ if (!provider) {
620
+ throw new Error(`Provider ${account.providerId} not found`);
621
+ }
622
+
623
+ // Check if provider has native signAndExecute support
624
+ if (
625
+ typeof (provider as any as { signAndExecuteTransaction: (payload: any) => Promise<any> })
626
+ .signAndExecuteTransaction === 'function'
627
+ ) {
628
+ return await (
629
+ provider as any as { signAndExecuteTransaction: (payload: any) => Promise<any> }
630
+ ).signAndExecuteTransaction({
631
+ accountAddress: account.address,
632
+ payload,
633
+ ledgerId: account.ledgerId,
634
+ networkId: account.networkId,
635
+ ...options,
636
+ });
637
+ }
638
+
639
+ // Fallback: sign then submit
640
+ const signResult = await provider.signTransaction({
641
+ accountAddress: account.address,
642
+ payload,
643
+ ledgerId: account.ledgerId,
644
+ networkId: account.networkId,
645
+ ...options,
646
+ });
647
+
648
+ return await provider.submitTransaction({
649
+ accountAddress: account.address,
650
+ payload: signResult.signedPayload || payload,
651
+ ledgerId: account.ledgerId,
652
+ networkId: account.networkId,
653
+ ...options,
654
+ });
655
+ }
656
+
657
+ /**
658
+ * Gets all active sessions across all providers.
659
+ *
660
+ * @description
661
+ * Returns detailed session information for all connected providers. For
662
+ * WalletConnect, each session is returned separately. For other providers,
663
+ * a single session entry represents the connection.
664
+ *
665
+ * @returns Array of session objects with provider and account information
666
+ */
667
+ getActiveSessions(): Array<{
668
+ providerId: string;
669
+ providerType: string;
670
+ providerName: string;
671
+ accounts: import('../models/unified-account.model').UnifiedAccount[];
672
+ metadata: any;
673
+ }> {
674
+ const sessions: Array<{
675
+ providerId: string;
676
+ providerType: string;
677
+ providerName: string;
678
+ accounts: import('../models/unified-account.model').UnifiedAccount[];
679
+ metadata: any;
680
+ }> = [];
681
+
682
+ for (const provider of this.providers.values()) {
683
+ const accounts = provider.accounts();
684
+
685
+ if (accounts.length > 0) {
686
+ // For WalletConnect, get detailed session info
687
+ if (provider.id === 'walletconnect-v2' && 'getActiveSessions' in provider) {
688
+ const wcProvider = provider as any;
689
+ const wcSessions = (
690
+ wcProvider as { getActiveSessions: () => unknown[] }
691
+ ).getActiveSessions();
692
+
693
+ for (const wcSession of wcSessions) {
694
+ sessions.push({
695
+ providerId: provider.id,
696
+ providerType: provider.metadata.type,
697
+ providerName: provider.metadata.name,
698
+ accounts: (wcSession as { accounts?: any[] }).accounts || [],
699
+ metadata: {
700
+ sessionKey: (wcSession as { sessionKey?: string }).sessionKey,
701
+ ledgerId: (wcSession as { ledgerId?: string }).ledgerId,
702
+ networkId: (wcSession as { networkId?: string }).networkId,
703
+ topic: (wcSession as { topic?: string }).topic,
704
+ },
705
+ });
706
+ }
707
+ } else {
708
+ // For HSuite Native and other providers, create a single session entry
709
+ sessions.push({
710
+ providerId: provider.id,
711
+ providerType: provider.metadata.type,
712
+ providerName: provider.metadata.name,
713
+ accounts,
714
+ metadata: {
715
+ type: provider.metadata.type,
716
+ },
717
+ });
718
+ }
719
+ }
720
+ }
721
+
722
+ return sessions;
723
+ }
724
+
725
+ /**
726
+ * Disconnects a specific session from a provider.
727
+ *
728
+ * @description
729
+ * For WalletConnect which supports multiple concurrent sessions, this allows
730
+ * disconnecting a specific session without affecting others. For other
731
+ * providers, this is equivalent to calling {@link disconnect}.
732
+ *
733
+ * @param providerId - The provider ID
734
+ * @param sessionKey - Optional session key (required for WalletConnect multi-session)
735
+ *
736
+ * @throws {Error} If provider is not found
737
+ */
738
+ async disconnectSession(providerId: string, sessionKey?: string): Promise<void> {
739
+ const provider = this.providers.get(providerId);
740
+ if (!provider) {
741
+ throw new Error(`Provider ${providerId} not found`);
742
+ }
743
+
744
+ // If provider supports session-level disconnect (WalletConnect), use it
745
+ if ('disconnectSession' in provider && sessionKey) {
746
+ const wcProvider = provider as any;
747
+ await (wcProvider as { disconnectSession: (key: string) => Promise<void> }).disconnectSession(
748
+ sessionKey,
749
+ );
750
+ } else {
751
+ // Otherwise, disconnect the entire provider
752
+ await provider.disconnect();
753
+ }
754
+
755
+ // Emit disconnection event
756
+ this.eventBus.disconnected.emit({
757
+ providerId,
758
+ providerType: provider.metadata.type,
759
+ sessionKey,
760
+ reason: 'user_initiated',
761
+ timestamp: Date.now(),
762
+ });
763
+
764
+ // Update active account if needed
765
+ const active = this._activeAccount();
766
+ if (active && active.providerId === providerId) {
767
+ const accounts = this.allAccounts();
768
+ const nextAccount = accounts.find(
769
+ (a) =>
770
+ a.providerId !== providerId ||
771
+ (sessionKey && (a.metadata as { sessionKey?: string })?.sessionKey !== sessionKey),
772
+ );
773
+ this.setActiveAccount(nextAccount || null);
774
+ }
775
+ }
776
+
777
+ /**
778
+ * Check if any provider is connected
779
+ */
780
+ isAnyConnected(): boolean {
781
+ return this.connectedProviders().length > 0;
782
+ }
783
+
784
+ /**
785
+ * Alias for isAnyConnected() - convenience method
786
+ */
787
+ isConnected(): boolean {
788
+ return this.isAnyConnected();
789
+ }
790
+
791
+ /**
792
+ * Get account by ID
793
+ * @param accountId
794
+ */
795
+ getAccountById(accountId: string): UnifiedAccount | undefined {
796
+ return this.allAccounts().find((a) => a.id === accountId);
797
+ }
798
+
799
+ /**
800
+ * Get list of unique ledger IDs from connected accounts
801
+ * @returns Array of ledger IDs (e.g., ['hedera', 'xrpl'])
802
+ */
803
+ getConnectedLedgers(): string[] {
804
+ const accounts = this.allAccounts();
805
+ const ledgerIds = new Set(accounts.map((a) => a.ledgerId).filter(Boolean));
806
+ return Array.from(ledgerIds);
807
+ }
808
+
809
+ /**
810
+ * Get accounts filtered by ledger ID
811
+ * @param ledgerId - Ledger identifier (e.g., 'hedera', 'xrpl')
812
+ * @returns Array of accounts for the specified ledger
813
+ */
814
+ getAccountsByLedger(ledgerId: string): UnifiedAccount[] {
815
+ return this.allAccounts().filter((a) => a.ledgerId === ledgerId);
816
+ }
817
+
818
+ /**
819
+ * Switch to an account by its ID
820
+ * @param accountId - The account ID to switch to
821
+ * @returns true if account was found and switched, false otherwise
822
+ */
823
+ switchAccount(accountId: string): boolean {
824
+ const account = this.getAccountById(accountId);
825
+ if (!account) {
826
+ logger.warn('Account not found', { accountId });
827
+ return false;
828
+ }
829
+
830
+ this.setActiveAccount(account);
831
+ return true;
832
+ }
833
+
834
+ /**
835
+ * Get the primary account for a specific ledger
836
+ * Returns the first account found for the specified ledger
837
+ * @param ledgerId - Ledger identifier (e.g., 'hedera', 'xrpl')
838
+ * @returns The first account for the ledger, or undefined
839
+ */
840
+ getPrimaryAccountForLedger(ledgerId: string): UnifiedAccount | undefined {
841
+ return this.allAccounts().find((a) => a.ledgerId === ledgerId);
842
+ }
843
+
844
+ /**
845
+ * Check if a specific ledger has connected accounts
846
+ * @param ledgerId - Ledger identifier (e.g., 'hedera', 'xrpl')
847
+ * @returns true if at least one account exists for the ledger
848
+ */
849
+ hasAccountsForLedger(ledgerId: string): boolean {
850
+ return this.getAccountsByLedger(ledgerId).length > 0;
851
+ }
852
+ }