@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,501 @@
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 account-selector.service.ts
13
+ * @description Business logic service for account selector
14
+ *
15
+ * Encapsulates the core business logic for the AccountSelectorComponent.
16
+ * Handles account selection, session management, and data transformations.
17
+ * Extracted from AccountSelectorComponent for better testability and maintainability.
18
+ *
19
+ * **Features:**
20
+ * - Account selection and switching
21
+ * - Session disconnect logic
22
+ * - Account grouping by ledger
23
+ * - Keyboard navigation support
24
+ * - Toast/alert integration
25
+ */
26
+
27
+ import { Injectable, inject, signal, computed } from '@angular/core';
28
+ import { getLogger } from '@hsuite/native-connect-sdk';
29
+ import { AlertController, ToastController, ModalController } from '@ionic/angular/standalone';
30
+
31
+ import { UnifiedWalletService } from '../../services/unified-wallet.service';
32
+
33
+ import { AccountFormattingService } from './account-formatting.service';
34
+ import type { LedgerGroup, AccountItem } from './account-list/account-list.component';
35
+
36
+ const logger = getLogger().scoped?.('AccountSelectorService') ?? getLogger();
37
+
38
+ /**
39
+ * Account data emitted on selection change
40
+ */
41
+ export interface SelectedAccountData {
42
+ id: string;
43
+ address: string;
44
+ ledgerId: string;
45
+ networkId: string;
46
+ label?: string;
47
+ providerId?: string;
48
+ providerType?: string;
49
+ }
50
+
51
+ /**
52
+ * @service AccountSelectorService
53
+ * Business logic service for account selector component.
54
+ */
55
+ @Injectable({ providedIn: 'root' })
56
+ export class AccountSelectorService {
57
+ protected readonly wallet = inject(UnifiedWalletService);
58
+ protected readonly formatting = inject(AccountFormattingService);
59
+
60
+ // Controllers - optional for different contexts
61
+ protected alertController = inject(AlertController, { optional: true });
62
+ protected toastController = inject(ToastController, { optional: true });
63
+ protected modalController = inject(ModalController, { optional: true });
64
+
65
+ /**
66
+ * Loading state signal
67
+ */
68
+ readonly isLoading = signal<boolean>(false);
69
+
70
+ /**
71
+ * Error state signal
72
+ */
73
+ readonly error = signal<string | null>(null);
74
+
75
+ /**
76
+ * Get all active sessions from wallet
77
+ */
78
+ get activeSessions() {
79
+ return this.wallet.getActiveSessions();
80
+ }
81
+
82
+ /**
83
+ * Get all accounts as a computed value
84
+ */
85
+ readonly allAccounts = computed(() => {
86
+ const accounts = this.wallet.allAccounts();
87
+ return accounts.map((acc) => ({
88
+ id: acc.id,
89
+ address: acc.address,
90
+ ledgerId: acc.ledgerId,
91
+ networkId: acc.networkId,
92
+ label: acc.label,
93
+ publicKey: (acc.metadata as any)?.publicKey,
94
+ providerId: acc.providerId,
95
+ providerType: acc.providerType,
96
+ sessionKey: (acc.metadata as any)?.sessionKey,
97
+ }));
98
+ });
99
+
100
+ /**
101
+ * Get currently active account
102
+ */
103
+ readonly activeAccount = computed(() => this.wallet.activeAccount());
104
+
105
+ /**
106
+ * Get total account count
107
+ */
108
+ readonly totalAccountCount = computed(() => this.wallet.allAccounts().length);
109
+
110
+ /**
111
+ * Get all accounts grouped by ledger
112
+ */
113
+ readonly groupedByLedger = computed<LedgerGroup[]>(() => {
114
+ const sessions = this.wallet.getActiveSessions();
115
+ const items: Array<{ account: any; session: any }> = [];
116
+
117
+ for (const session of sessions) {
118
+ if (!session.accounts || !Array.isArray(session.accounts)) continue;
119
+ for (const account of session.accounts) {
120
+ if (account) items.push({ account, session });
121
+ }
122
+ }
123
+
124
+ return this.groupAccountsByLedger(items);
125
+ });
126
+
127
+ /**
128
+ * Get currently connected account with session
129
+ */
130
+ readonly currentlyConnectedAccount = computed<{
131
+ session: any;
132
+ account: any;
133
+ } | null>(() => {
134
+ try {
135
+ const activeAccount = this.wallet.activeAccount();
136
+ if (!activeAccount) return null;
137
+
138
+ const sessions = this.wallet.getActiveSessions();
139
+ if (!sessions || !Array.isArray(sessions)) return null;
140
+
141
+ for (const session of sessions) {
142
+ if (!session || !session.accounts || !Array.isArray(session.accounts)) continue;
143
+
144
+ const account = session.accounts.find((a) => a && a.address === activeAccount.address);
145
+ if (account) {
146
+ return { session, account };
147
+ }
148
+ }
149
+ return null;
150
+ } catch (error) {
151
+ logger.error('Error getting currently connected account', { error });
152
+ return null;
153
+ }
154
+ });
155
+
156
+ /**
157
+ * Get other accounts (not currently connected)
158
+ */
159
+ readonly otherAccounts = computed<
160
+ Array<{
161
+ session: any;
162
+ account: any;
163
+ }>
164
+ >(() => {
165
+ try {
166
+ const activeAccount = this.wallet.activeAccount();
167
+ const sessions = this.wallet.getActiveSessions();
168
+ const others: Array<{ session: any; account: any }> = [];
169
+
170
+ if (!sessions || !Array.isArray(sessions)) return others;
171
+
172
+ for (const session of sessions) {
173
+ if (!session || !session.accounts || !Array.isArray(session.accounts)) continue;
174
+
175
+ for (const account of session.accounts) {
176
+ if (!account) continue;
177
+
178
+ if (!activeAccount || account.address !== activeAccount.address) {
179
+ others.push({ session, account });
180
+ }
181
+ }
182
+ }
183
+
184
+ return others;
185
+ } catch (error) {
186
+ logger.error('Error getting other accounts', { error });
187
+ return [];
188
+ }
189
+ });
190
+
191
+ /**
192
+ * Select an account
193
+ * @param accountItem
194
+ * @param mode
195
+ */
196
+ async selectAccount(
197
+ accountItem: AccountItem,
198
+ mode: 'inline' | 'modal',
199
+ ): Promise<SelectedAccountData | null> {
200
+ const account = accountItem.account;
201
+ const selectedId = account.id;
202
+
203
+ // Update UnifiedWalletService active account
204
+ const unifiedAccount = this.wallet.allAccounts().find((a) => a.id === selectedId);
205
+ if (unifiedAccount) {
206
+ this.wallet.setActiveAccount(unifiedAccount);
207
+ }
208
+
209
+ const accountData: SelectedAccountData = {
210
+ id: account.id || '',
211
+ address: account.address || '',
212
+ ledgerId: account.ledgerId || '',
213
+ networkId: account.networkId || '',
214
+ label: account.label,
215
+ providerId: accountItem.session.providerId,
216
+ providerType: accountItem.session.providerType,
217
+ };
218
+
219
+ // Modal mode: show toast and dismiss
220
+ if (mode === 'modal') {
221
+ await this.showSuccessToast(`Switched to ${account.label || 'Account'}`);
222
+ logger.info('[Modal] Account changed and modal dismissed', { ...accountData });
223
+ } else {
224
+ logger.info('[Inline] Account changed', { ...accountData });
225
+ }
226
+
227
+ return accountData;
228
+ }
229
+
230
+ /**
231
+ * Disconnect a session with confirmation
232
+ * @param providerId
233
+ * @param sessionKey
234
+ * @param mode
235
+ * @param skipConfirmation
236
+ */
237
+ async disconnectSession(
238
+ providerId: string,
239
+ sessionKey: string | undefined,
240
+ mode: 'inline' | 'modal',
241
+ skipConfirmation = false,
242
+ ): Promise<boolean> {
243
+ // Modal mode: use AlertController for confirmation
244
+ if (!skipConfirmation) {
245
+ if (mode === 'modal' && this.alertController) {
246
+ return new Promise((resolve) => {
247
+ this.alertController!.create({
248
+ header: 'Disconnect Session',
249
+ message: 'Are you sure you want to disconnect this wallet session?',
250
+ buttons: [
251
+ {
252
+ text: 'Cancel',
253
+ role: 'cancel',
254
+ handler: () => resolve(false),
255
+ },
256
+ {
257
+ text: 'Disconnect',
258
+ role: 'destructive',
259
+ handler: async () => {
260
+ const success = await this.performDisconnect(providerId, sessionKey, mode);
261
+ resolve(success);
262
+ },
263
+ },
264
+ ],
265
+ }).then((alert) => alert.present());
266
+ });
267
+ }
268
+
269
+ // Inline mode: use browser confirm
270
+ if (mode === 'inline') {
271
+ const confirmed = confirm('Are you sure you want to disconnect this wallet session?');
272
+ if (!confirmed) return false;
273
+ }
274
+ }
275
+
276
+ return this.performDisconnect(providerId, sessionKey, mode);
277
+ }
278
+
279
+ /**
280
+ * Disconnect all sessions with confirmation
281
+ * @param _mode
282
+ */
283
+ async disconnectAll(_mode: 'inline' | 'modal'): Promise<boolean> {
284
+ if (!this.alertController) {
285
+ logger.warn('AlertController not available for disconnect confirmation');
286
+ return false;
287
+ }
288
+
289
+ return new Promise((resolve) => {
290
+ this.alertController!.create({
291
+ header: 'Disconnect All Wallets',
292
+ message: 'Are you sure you want to disconnect all connected wallets?',
293
+ buttons: [
294
+ {
295
+ text: 'Cancel',
296
+ role: 'cancel',
297
+ handler: () => resolve(false),
298
+ },
299
+ {
300
+ text: 'Disconnect All',
301
+ role: 'destructive',
302
+ handler: async () => {
303
+ this.isLoading.set(true);
304
+ try {
305
+ const sessions = this.wallet.getActiveSessions();
306
+ for (const session of sessions) {
307
+ try {
308
+ await this.wallet.disconnectSession(
309
+ session.providerId,
310
+ session.metadata?.sessionKey,
311
+ );
312
+ } catch (error) {
313
+ logger.error('Failed to disconnect session', {
314
+ providerId: session.providerId,
315
+ error,
316
+ });
317
+ }
318
+ }
319
+
320
+ await this.showSuccessToast('All wallets disconnected');
321
+ resolve(true);
322
+ } catch (error) {
323
+ logger.error('Failed to disconnect all sessions', { error });
324
+ this.error.set('Failed to disconnect all wallets');
325
+ resolve(false);
326
+ } finally {
327
+ this.isLoading.set(false);
328
+ }
329
+ },
330
+ },
331
+ ],
332
+ }).then((alert) => alert.present());
333
+ });
334
+ }
335
+
336
+ /**
337
+ * Navigate accounts using keyboard
338
+ * @param direction
339
+ * @param selectedId
340
+ */
341
+ navigateAccounts(direction: 1 | -1, selectedId?: string): string | null {
342
+ const accounts = this.allAccounts();
343
+ if (accounts.length === 0) return null;
344
+
345
+ const currentIndex = accounts.findIndex((acc) => acc.id === selectedId);
346
+ let nextIndex = currentIndex + direction;
347
+
348
+ // Wrap around
349
+ if (nextIndex < 0) {
350
+ nextIndex = accounts.length - 1;
351
+ } else if (nextIndex >= accounts.length) {
352
+ nextIndex = 0;
353
+ }
354
+
355
+ const nextAccount = accounts[nextIndex];
356
+ return nextAccount?.id ?? null;
357
+ }
358
+
359
+ /**
360
+ * Navigate to first or last account
361
+ * @param toFirst
362
+ */
363
+ navigateToEdge(toFirst: boolean): string | null {
364
+ const accounts = this.allAccounts();
365
+ if (accounts.length === 0) return null;
366
+
367
+ const targetAccount = toFirst ? accounts[0] : accounts[accounts.length - 1];
368
+ return targetAccount?.id ?? null;
369
+ }
370
+
371
+ /**
372
+ * Get wallet logo for active account
373
+ */
374
+ getActiveWalletLogo(): string {
375
+ const sessions = this.wallet.getActiveSessions();
376
+ const activeAccount = this.wallet.activeAccount();
377
+
378
+ if (!activeAccount) return 'assets/wallets/hsuite.svg';
379
+
380
+ const session = sessions.find((s) =>
381
+ s.accounts?.some((acc) => acc.address === activeAccount.address),
382
+ );
383
+
384
+ if (!session) return 'assets/wallets/hsuite.svg';
385
+
386
+ return this.formatting.getWalletLogo(session.providerType);
387
+ }
388
+
389
+ /**
390
+ * Clear error state
391
+ */
392
+ clearError(): void {
393
+ this.error.set(null);
394
+ }
395
+
396
+ /**
397
+ * Set modal controller instance (for modal context)
398
+ * @param controller
399
+ */
400
+ setModalController(controller: ModalController): void {
401
+ this.modalController = controller;
402
+ }
403
+
404
+ /**
405
+ * Perform the actual disconnect operation
406
+ * @param providerId
407
+ * @param sessionKey
408
+ * @param mode
409
+ */
410
+ private async performDisconnect(
411
+ providerId: string,
412
+ sessionKey: string | undefined,
413
+ mode: 'inline' | 'modal',
414
+ ): Promise<boolean> {
415
+ this.isLoading.set(true);
416
+ this.error.set(null);
417
+
418
+ try {
419
+ await this.wallet.disconnectSession(providerId, sessionKey);
420
+
421
+ if (mode === 'modal') {
422
+ await this.showSuccessToast('Wallet disconnected successfully');
423
+ }
424
+
425
+ logger.info('Session disconnected', { providerId, sessionKey, mode });
426
+ return true;
427
+ } catch (error) {
428
+ logger.error('Failed to disconnect session', { providerId, error });
429
+
430
+ if (mode === 'modal') {
431
+ await this.showErrorToast('Failed to disconnect wallet. Please try again.');
432
+ }
433
+
434
+ this.error.set(error instanceof Error ? error.message : 'Failed to disconnect');
435
+ return false;
436
+ } finally {
437
+ this.isLoading.set(false);
438
+ }
439
+ }
440
+
441
+ /**
442
+ * Group accounts by ledger
443
+ * @param items
444
+ */
445
+ private groupAccountsByLedger(items: Array<{ account: any; session: any }>): LedgerGroup[] {
446
+ const ledgerMap = new Map<string, Array<{ account: any; session: any }>>();
447
+
448
+ for (const item of items) {
449
+ const { account } = item;
450
+ if (!account?.ledgerId) continue;
451
+
452
+ const ledgerId = account.ledgerId;
453
+ if (!ledgerMap.has(ledgerId)) {
454
+ ledgerMap.set(ledgerId, []);
455
+ }
456
+ ledgerMap.get(ledgerId)!.push(item);
457
+ }
458
+
459
+ return Array.from(ledgerMap.entries()).map(([ledgerId, accounts]) => ({
460
+ ledgerName: this.formatting.getLedgerName(ledgerId),
461
+ ledgerId,
462
+ accounts,
463
+ }));
464
+ }
465
+
466
+ /**
467
+ * Show success toast
468
+ * @param message
469
+ */
470
+ private async showSuccessToast(message: string): Promise<void> {
471
+ if (this.toastController) {
472
+ const toast = await this.toastController.create({
473
+ message,
474
+ duration: 2000,
475
+ cssClass: 'toast-success toast-compact',
476
+ position: 'top',
477
+ icon: 'checkmark-circle',
478
+ buttons: [{ icon: 'close', role: 'cancel' }],
479
+ });
480
+ await toast.present();
481
+ }
482
+ }
483
+
484
+ /**
485
+ * Show error toast
486
+ * @param message
487
+ */
488
+ private async showErrorToast(message: string): Promise<void> {
489
+ if (this.toastController) {
490
+ const toast = await this.toastController.create({
491
+ message,
492
+ duration: 3000,
493
+ cssClass: 'toast-danger toast-compact',
494
+ position: 'top',
495
+ icon: 'alert-circle-outline',
496
+ buttons: [{ icon: 'close', role: 'cancel' }],
497
+ });
498
+ await toast.present();
499
+ }
500
+ }
501
+ }
@@ -0,0 +1,34 @@
1
+ <div class="wallet-account-display" *ngIf="account()">
2
+ <div class="account-header">
3
+ <ion-icon [name]="showLabel ? 'person-outline' : 'wallet-outline'"></ion-icon>
4
+ <div class="account-info">
5
+ <div class="account-label" *ngIf="showLabel">
6
+ <strong>{{ account()!.label || 'Account' }}</strong>
7
+ </div>
8
+ <div class="account-address">
9
+ <ion-text [color]="addressColor">
10
+ <small>{{ displayAddress() }}</small>
11
+ </ion-text>
12
+ </div>
13
+ </div>
14
+ </div>
15
+
16
+ <div class="account-badges" *ngIf="showBadges">
17
+ <ion-badge *ngIf="isMultisig()" color="tertiary" class="multisig-badge">
18
+ <ion-icon name="people-outline"></ion-icon>
19
+ Multisig{{ multisigInfo() ? ' (' + multisigInfo() + ')' : '' }}
20
+ </ion-badge>
21
+ <ion-badge [color]="getLedgerColor(account()!.ledgerId)">
22
+ {{ account()!.ledgerId.toUpperCase() }}
23
+ </ion-badge>
24
+ <ion-badge>
25
+ {{ formatNetwork(account()!.networkId) }}
26
+ </ion-badge>
27
+ </div>
28
+ </div>
29
+
30
+ <div class="wallet-account-display empty" *ngIf="!account()">
31
+ <ion-text>
32
+ <small>{{ emptyText }}</small>
33
+ </ion-text>
34
+ </div>
@@ -0,0 +1,99 @@
1
+ /**
2
+ * Wallet Account Display Component Styles
3
+ * @compodoc
4
+ * Styles for the wallet account display component
5
+ */
6
+
7
+ .wallet-account-display {
8
+ display: flex;
9
+ align-items: center;
10
+ justify-content: space-between;
11
+ gap: var(--space-lg, 16px);
12
+ padding: var(--space-lg, 16px) var(--space-xl, 20px);
13
+ background: var(--surface-flat);
14
+ border: var(--border-width-thin, 1px) solid var(--border-flat);
15
+ border-radius: var(--border-radius-lg, 12px);
16
+ min-height: 72px;
17
+
18
+ &.empty {
19
+ justify-content: center;
20
+ padding: var(--space-md, 14px) var(--space-lg, 16px);
21
+ min-height: 56px;
22
+ }
23
+ }
24
+
25
+ .account-header {
26
+ display: flex;
27
+ align-items: center;
28
+ gap: var(--space-md, 12px);
29
+ flex: 1;
30
+ min-width: 0;
31
+
32
+ ion-icon {
33
+ font-size: var(--font-size-2xl, 24px);
34
+ color: var(--ion-color-primary);
35
+ flex-shrink: 0;
36
+ }
37
+ }
38
+
39
+ .account-info {
40
+ display: flex;
41
+ flex-direction: column;
42
+ gap: var(--space-xs, 6px);
43
+ min-width: 0;
44
+ flex: 1;
45
+ }
46
+
47
+ .account-label {
48
+ font-size: var(--font-size-lg, 16px);
49
+ font-weight: var(--font-weight-semibold, 600);
50
+ color: var(--ion-text-color);
51
+ line-height: 1.3;
52
+ }
53
+
54
+ .account-address {
55
+ font-family: var(--font-family-mono, monospace);
56
+ font-size: var(--font-size-md, 14px);
57
+ color: var(--ion-color-medium);
58
+ overflow: hidden;
59
+ text-overflow: ellipsis;
60
+ white-space: nowrap;
61
+ line-height: 1.4;
62
+ }
63
+
64
+ .account-badges {
65
+ display: flex;
66
+ gap: var(--space-sm, 8px);
67
+ flex-shrink: 0;
68
+ flex-wrap: wrap;
69
+
70
+ ion-badge {
71
+ padding: var(--space-xs, 6px) var(--space-sm, 10px);
72
+ font-size: var(--font-size-xs, 12px);
73
+ font-weight: var(--font-weight-medium, 500);
74
+ }
75
+
76
+ .multisig-badge {
77
+ display: inline-flex;
78
+ align-items: center;
79
+ gap: 4px;
80
+
81
+ ion-icon {
82
+ font-size: 14px;
83
+ }
84
+ }
85
+ }
86
+
87
+ @media (max-width: 576px) {
88
+ .wallet-account-display {
89
+ flex-direction: column;
90
+ align-items: flex-start;
91
+ padding: var(--space-md, 14px) var(--space-lg, 16px);
92
+ gap: var(--space-md, 12px);
93
+ }
94
+
95
+ .account-badges {
96
+ width: 100%;
97
+ justify-content: flex-start;
98
+ }
99
+ }