@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,349 @@
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 wallet-error-handler.ts
13
+ * @description Configurable error handler with automatic toast notifications
14
+ *
15
+ * Provides automatic error handling for wallet operations with beautiful
16
+ * Ionic toast notifications. Fully customizable per error type.
17
+ */
18
+
19
+ import { Injectable, Provider, inject, InjectionToken } from '@angular/core';
20
+ import { getLogger } from '@hsuite/native-connect-sdk';
21
+ import { ToastController } from '@ionic/angular/standalone';
22
+
23
+ import { WalletEventBus } from '../services/wallet-event-bus.service';
24
+
25
+ const logger = getLogger().scoped?.('WalletErrorHandler') ?? getLogger();
26
+
27
+ /**
28
+ * Error category for categorizing wallet errors
29
+ */
30
+ export type WalletErrorCategory =
31
+ | 'network' // Network connectivity issues
32
+ | 'auth' // Authentication failures (PIN, biometric)
33
+ | 'user_cancelled' // User cancelled the operation
34
+ | 'provider' // Provider-specific errors
35
+ | 'transaction' // Transaction failures
36
+ | 'validation' // Input validation errors
37
+ | 'unknown'; // Uncategorized errors
38
+
39
+ /**
40
+ * Categorized wallet error with user-friendly message
41
+ */
42
+ export interface CategorizedError {
43
+ /** Original error */
44
+ original: Error;
45
+ /** Error category */
46
+ category: WalletErrorCategory;
47
+ /** User-friendly message */
48
+ userMessage: string;
49
+ /** Whether this error is recoverable */
50
+ recoverable: boolean;
51
+ }
52
+
53
+ /**
54
+ * Configuration for the wallet error handler
55
+ */
56
+ export interface WalletErrorHandlerConfig {
57
+ /**
58
+ * Whether to show toast notifications for errors (default: true)
59
+ */
60
+ showToasts?: boolean;
61
+
62
+ /**
63
+ * Custom handler for connection errors
64
+ */
65
+ onConnectionError?: (error: Error) => void;
66
+
67
+ /**
68
+ * Custom handler for transaction errors
69
+ */
70
+ onTransactionError?: (error: Error) => void;
71
+
72
+ /**
73
+ * Custom handler for provider errors
74
+ */
75
+ onProviderError?: (error: Error) => void;
76
+
77
+ /**
78
+ * Toast duration in milliseconds (default: 4000)
79
+ */
80
+ toastDuration?: number;
81
+
82
+ /**
83
+ * Toast position (default: 'top')
84
+ */
85
+ toastPosition?: 'top' | 'bottom' | 'middle';
86
+ }
87
+
88
+ /**
89
+ * Injection token for error handler config
90
+ */
91
+ export const WALLET_ERROR_HANDLER_CONFIG = new InjectionToken<WalletErrorHandlerConfig>(
92
+ 'WALLET_ERROR_HANDLER_CONFIG',
93
+ );
94
+
95
+ /**
96
+ * Wallet error handler service
97
+ *
98
+ * Automatically subscribes to wallet events and shows error toasts.
99
+ * Can be customized via configuration.
100
+ */
101
+ @Injectable()
102
+ export class WalletErrorHandler {
103
+ private readonly config = inject(WALLET_ERROR_HANDLER_CONFIG, { optional: true });
104
+ private readonly eventBus = inject(WalletEventBus);
105
+ private readonly toastController = inject(ToastController);
106
+
107
+ /**
108
+ *
109
+ */
110
+ constructor() {
111
+ // Setup error listeners
112
+ this.setupErrorListeners();
113
+ logger.debug('Initialized with config', { config: this.config });
114
+ }
115
+
116
+ /**
117
+ * Setup listeners for wallet errors
118
+ */
119
+ private setupErrorListeners(): void {
120
+ // Listen to provider errors
121
+ this.eventBus.providerError.subscribe((event) => {
122
+ logger.error('Provider error', { event });
123
+
124
+ // Custom handler
125
+ if (this.config?.onProviderError) {
126
+ this.config.onProviderError(
127
+ event.error instanceof Error ? event.error : new Error(String(event.error)),
128
+ );
129
+ }
130
+
131
+ // Show toast if enabled (default: true)
132
+ if (this.config?.showToasts !== false) {
133
+ void this.showErrorToast(
134
+ 'Wallet Error',
135
+ event.error instanceof Error ? event.error.message : String(event.error),
136
+ );
137
+ }
138
+ });
139
+
140
+ // Listen to disconnections for unexpected disconnects
141
+ this.eventBus.disconnected.subscribe((event) => {
142
+ if (event.reason === 'wallet_initiated_disconnect' || event.reason === 'session_terminated') {
143
+ logger.warn('Unexpected disconnect', { event });
144
+
145
+ // Show toast if enabled
146
+ if (this.config?.showToasts !== false) {
147
+ void this.showWarningToast(
148
+ 'Wallet Disconnected',
149
+ `${event.providerType === 'hsuite-native' ? 'HSuite Wallet' : 'WalletConnect'} session ended`,
150
+ );
151
+ }
152
+ }
153
+ });
154
+ }
155
+
156
+ /**
157
+ * Show error toast
158
+ * Uses cssClass-only styling (no Ionic color property) for theme compatibility.
159
+ * @param header
160
+ * @param message
161
+ */
162
+ private async showErrorToast(header: string, message: string): Promise<void> {
163
+ const toast = await this.toastController.create({
164
+ header,
165
+ message,
166
+ duration: this.config?.toastDuration || 4000,
167
+ position: this.config?.toastPosition || 'top',
168
+ cssClass: 'toast-danger toast-compact',
169
+ buttons: [{ icon: 'close', role: 'cancel' }],
170
+ });
171
+
172
+ await toast.present();
173
+ }
174
+
175
+ /**
176
+ * Show warning toast
177
+ * Uses cssClass-only styling (no Ionic color property) for theme compatibility.
178
+ * @param header
179
+ * @param message
180
+ */
181
+ private async showWarningToast(header: string, message: string): Promise<void> {
182
+ const toast = await this.toastController.create({
183
+ header,
184
+ message,
185
+ duration: this.config?.toastDuration || 4000,
186
+ position: this.config?.toastPosition || 'top',
187
+ cssClass: 'toast-warning toast-compact',
188
+ buttons: [{ icon: 'close', role: 'cancel' }],
189
+ });
190
+
191
+ await toast.present();
192
+ }
193
+
194
+ /**
195
+ * Manually handle an error (for use in components)
196
+ * @param title
197
+ * @param error
198
+ */
199
+ async handleError(title: string, error: Error | string): Promise<void> {
200
+ const message = error instanceof Error ? error.message : String(error);
201
+
202
+ if (this.config?.showToasts !== false) {
203
+ await this.showErrorToast(title, message);
204
+ }
205
+ }
206
+
207
+ /**
208
+ * Manually show success toast (convenience method)
209
+ * Uses cssClass-only styling (no Ionic color property) for theme compatibility.
210
+ * @param header
211
+ * @param message
212
+ */
213
+ async showSuccess(header: string, message: string): Promise<void> {
214
+ const toast = await this.toastController.create({
215
+ header,
216
+ message,
217
+ duration: this.config?.toastDuration || 3000,
218
+ position: this.config?.toastPosition || 'top',
219
+ cssClass: 'toast-success toast-compact',
220
+ buttons: [{ icon: 'close', role: 'cancel' }],
221
+ });
222
+
223
+ await toast.present();
224
+ }
225
+
226
+ /**
227
+ * Categorize an error for better handling
228
+ * @param error - The error to categorize
229
+ * @returns Categorized error with user-friendly message
230
+ */
231
+ categorizeError(error: Error | string): CategorizedError {
232
+ const errorMessage = error instanceof Error ? error.message : String(error);
233
+ const lowerMessage = errorMessage.toLowerCase();
234
+
235
+ // Network errors
236
+ if (
237
+ lowerMessage.includes('network') ||
238
+ lowerMessage.includes('timeout') ||
239
+ lowerMessage.includes('fetch') ||
240
+ lowerMessage.includes('connection')
241
+ ) {
242
+ return {
243
+ original: error instanceof Error ? error : new Error(errorMessage),
244
+ category: 'network',
245
+ userMessage: 'Network connection issue. Please check your internet connection.',
246
+ recoverable: true,
247
+ };
248
+ }
249
+
250
+ // User cancelled
251
+ if (
252
+ lowerMessage.includes('cancel') ||
253
+ lowerMessage.includes('rejected') ||
254
+ lowerMessage.includes('denied') ||
255
+ lowerMessage.includes('user rejected')
256
+ ) {
257
+ return {
258
+ original: error instanceof Error ? error : new Error(errorMessage),
259
+ category: 'user_cancelled',
260
+ userMessage: 'Operation cancelled.',
261
+ recoverable: true,
262
+ };
263
+ }
264
+
265
+ // Authentication errors
266
+ if (
267
+ lowerMessage.includes('pin') ||
268
+ lowerMessage.includes('biometric') ||
269
+ lowerMessage.includes('auth') ||
270
+ lowerMessage.includes('unlock')
271
+ ) {
272
+ return {
273
+ original: error instanceof Error ? error : new Error(errorMessage),
274
+ category: 'auth',
275
+ userMessage: 'Authentication failed. Please try again.',
276
+ recoverable: true,
277
+ };
278
+ }
279
+
280
+ // Transaction errors
281
+ if (
282
+ lowerMessage.includes('transaction') ||
283
+ lowerMessage.includes('insufficient') ||
284
+ lowerMessage.includes('balance') ||
285
+ lowerMessage.includes('sign')
286
+ ) {
287
+ return {
288
+ original: error instanceof Error ? error : new Error(errorMessage),
289
+ category: 'transaction',
290
+ userMessage: 'Transaction failed. Please check the details and try again.',
291
+ recoverable: true,
292
+ };
293
+ }
294
+
295
+ // Validation errors
296
+ if (
297
+ lowerMessage.includes('invalid') ||
298
+ lowerMessage.includes('required') ||
299
+ lowerMessage.includes('format')
300
+ ) {
301
+ return {
302
+ original: error instanceof Error ? error : new Error(errorMessage),
303
+ category: 'validation',
304
+ userMessage: errorMessage,
305
+ recoverable: true,
306
+ };
307
+ }
308
+
309
+ // Provider errors
310
+ if (
311
+ lowerMessage.includes('provider') ||
312
+ lowerMessage.includes('wallet') ||
313
+ lowerMessage.includes('session')
314
+ ) {
315
+ return {
316
+ original: error instanceof Error ? error : new Error(errorMessage),
317
+ category: 'provider',
318
+ userMessage: 'Wallet connection issue. Please reconnect.',
319
+ recoverable: true,
320
+ };
321
+ }
322
+
323
+ // Unknown
324
+ return {
325
+ original: error instanceof Error ? error : new Error(errorMessage),
326
+ category: 'unknown',
327
+ userMessage: 'An unexpected error occurred.',
328
+ recoverable: false,
329
+ };
330
+ }
331
+ }
332
+
333
+ /**
334
+ * Provider function for WalletErrorHandler
335
+ *
336
+ * Call this in your app configuration to enable automatic error handling.
337
+ *
338
+ * @param config - Optional configuration
339
+ * @returns Angular providers
340
+ */
341
+ export function provideWalletErrorHandler(config?: WalletErrorHandlerConfig): Provider[] {
342
+ return [
343
+ {
344
+ provide: WALLET_ERROR_HANDLER_CONFIG,
345
+ useValue: config || { showToasts: true },
346
+ },
347
+ WalletErrorHandler,
348
+ ];
349
+ }
@@ -0,0 +1,122 @@
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 base-signer.interface.ts
13
+ * @description Abstract signer interface for WalletConnect multi-chain support
14
+ *
15
+ * Defines the contract that all ledger-specific signers must implement.
16
+ * This enables the Strategy Pattern for clean separation of ledger logic.
17
+ */
18
+
19
+ import type { SignResult, SubmitResult, SignMessageResult } from '../../base-wallet-provider';
20
+ import type SignClient from '@walletconnect/sign-client';
21
+
22
+ /**
23
+ * Configuration for initializing a WalletConnect signer
24
+ */
25
+ export interface WalletConnectSignerConfig {
26
+ ledgerId: string;
27
+ networkId: string;
28
+ chainId: string; // e.g., 'hedera:testnet', 'xrpl:testnet'
29
+ }
30
+
31
+ /**
32
+ * Parameters for signing operations
33
+ */
34
+ export interface SignerOperationParams {
35
+ client: SignClient;
36
+ topic: string;
37
+ accountAddress: string;
38
+ payload: string;
39
+ networkId: string;
40
+ }
41
+
42
+ /**
43
+ * Interface that all WalletConnect signers must implement.
44
+ * Each ledger (Hedera, XRPL, etc.) provides its own implementation.
45
+ *
46
+ * This follows the Strategy Pattern, allowing the WalletConnect provider
47
+ * to delegate ledger-specific logic to the appropriate signer.
48
+ */
49
+ export interface IWalletConnectSigner {
50
+ /**
51
+ * Unique identifier for this ledger (e.g., 'hedera', 'xrpl')
52
+ */
53
+ readonly ledgerId: string;
54
+
55
+ /**
56
+ * Build WalletConnect namespace configuration for this ledger.
57
+ * Defines the JSON-RPC methods, chains, and events supported.
58
+ *
59
+ * @param networkId - The network identifier (e.g., 'hedera:testnet')
60
+ * @returns Namespace configuration object
61
+ */
62
+ buildNamespace(networkId: string): {
63
+ methods: string[];
64
+ chains: string[];
65
+ events: string[];
66
+ };
67
+
68
+ /**
69
+ * Sign a transaction without submitting to the network.
70
+ * Used for multi-sig workflows or when the dApp handles submission.
71
+ *
72
+ * @param params - Signing parameters including client, topic, account, and payload
73
+ * @returns Promise resolving to signed transaction data
74
+ */
75
+ signTransaction(params: SignerOperationParams): Promise<SignResult>;
76
+
77
+ /**
78
+ * Sign and submit a transaction to the network.
79
+ * The wallet handles both signing and network submission.
80
+ *
81
+ * @param params - Submission parameters including client, topic, account, and payload
82
+ * @returns Promise resolving to transaction ID and metadata
83
+ */
84
+ submitTransaction(params: SignerOperationParams): Promise<SubmitResult>;
85
+
86
+ /**
87
+ * Sign and execute a transaction in one call (preferred method to avoid double prompts).
88
+ * This uses the wallet's native sign+execute method when available (e.g., hedera_signAndExecuteTransaction).
89
+ * Falls back to sign then submit for wallets that don't support it.
90
+ *
91
+ * @param params - Transaction parameters including client, topic, account, and payload
92
+ * @returns Promise resolving to transaction ID and metadata
93
+ */
94
+ signAndExecuteTransaction?(params: SignerOperationParams): Promise<SubmitResult>;
95
+
96
+ /**
97
+ * Sign an arbitrary message (e.g., for DAO votes, authentication, proofs).
98
+ * The message can be plain text or base64 encoded.
99
+ *
100
+ * @param params - Signing parameters with message string
101
+ * @returns Promise resolving to signature and optional public key
102
+ */
103
+ signMessage(
104
+ params: SignerOperationParams & { message: string; encoding?: 'utf-8' | 'base64' },
105
+ ): Promise<SignMessageResult>;
106
+
107
+ /**
108
+ * Parse accounts from WalletConnect session namespace.
109
+ * Extracts account addresses and chain IDs from the session data.
110
+ *
111
+ * Optionally filters accounts to only include those matching a target network.
112
+ * This is important for respecting the user's network selection in the dApp.
113
+ *
114
+ * @param namespace - The WalletConnect namespace object for this ledger
115
+ * @param targetNetworkId - Optional network ID to filter accounts (e.g., 'hedera:mainnet')
116
+ * @returns Array of parsed account objects, filtered by target network if specified
117
+ */
118
+ parseAccounts(
119
+ namespace: any,
120
+ targetNetworkId?: string,
121
+ ): Array<{ address: string; chainId: string }>;
122
+ }
@@ -0,0 +1,196 @@
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 session-health.ts
13
+ * @description Manages WalletConnect session health - ensures relay subscriptions
14
+ * are active before making requests. Transparent to dApp developers.
15
+ *
16
+ * This class handles the common WalletConnect issue where relay subscriptions
17
+ * become stale, causing requests to fail with empty error objects.
18
+ *
19
+ * Features:
20
+ * - Pre-request session ping to ensure relay subscription is active
21
+ * - Relay connection monitoring (connect/disconnect/error events)
22
+ * - Automatic ping cache management
23
+ * - Subscription refresh capability
24
+ */
25
+
26
+ import { getLogger } from '@hsuite/native-connect-sdk';
27
+ import type SignClient from '@walletconnect/sign-client';
28
+
29
+ const logger = getLogger().scoped?.('WCSessionHealth') ?? getLogger();
30
+
31
+ /**
32
+ * Manages WalletConnect session health to prevent stale relay subscription issues.
33
+ *
34
+ * The WalletConnect relay uses WebSocket connections that can become stale,
35
+ * causing push events to stop arriving. This manager:
36
+ * - Pings sessions before requests to ensure subscriptions are active
37
+ * - Monitors relay connection state
38
+ * - Clears ping cache on disconnect to force re-ping
39
+ */
40
+ export class SessionHealthManager {
41
+ private client: SignClient;
42
+ private lastPingTime = new Map<string, number>();
43
+
44
+ /**
45
+ * Minimum interval between pings for the same topic (30 seconds).
46
+ * Pinging too frequently is unnecessary and adds latency.
47
+ */
48
+ private readonly PING_INTERVAL_MS = 30000;
49
+
50
+ /**
51
+ * Maximum time to wait for a ping response (5 seconds).
52
+ * If ping times out, we proceed anyway but log a warning.
53
+ */
54
+ private readonly PING_TIMEOUT_MS = 5000;
55
+
56
+ /**
57
+ * Create a new SessionHealthManager.
58
+ *
59
+ * @param client - Initialized WalletConnect SignClient instance
60
+ */
61
+ constructor(client: SignClient) {
62
+ this.client = client;
63
+ this.setupRelayMonitoring();
64
+ logger.info('SessionHealthManager initialized');
65
+ }
66
+
67
+ /**
68
+ * Ensure session is healthy before making a request.
69
+ *
70
+ * Pings the session if the last ping was more than 30 seconds ago.
71
+ * This refreshes the relay subscription and helps prevent the
72
+ * empty error object issue.
73
+ *
74
+ * Called automatically by WalletConnectClientManager before requests.
75
+ *
76
+ * @param topic - Session topic to verify
77
+ */
78
+ async ensureSessionHealth(topic: string): Promise<void> {
79
+ const lastPing = this.lastPingTime.get(topic) || 0;
80
+ const now = Date.now();
81
+
82
+ // Skip if we pinged recently
83
+ if (now - lastPing <= this.PING_INTERVAL_MS) {
84
+ logger.debug('Skipping ping - recent ping exists', {
85
+ topic: topic.substring(0, 16) + '...',
86
+ lastPingAge: now - lastPing,
87
+ });
88
+ return;
89
+ }
90
+
91
+ try {
92
+ logger.debug('Pinging session to ensure relay subscription', {
93
+ topic: topic.substring(0, 16) + '...',
94
+ });
95
+
96
+ // Race ping against timeout
97
+ await Promise.race([
98
+ this.client.ping({ topic }),
99
+ new Promise<never>((_, reject) =>
100
+ setTimeout(() => reject(new Error('Ping timeout')), this.PING_TIMEOUT_MS),
101
+ ),
102
+ ]);
103
+
104
+ this.lastPingTime.set(topic, now);
105
+ logger.debug('Session ping successful', {
106
+ topic: topic.substring(0, 16) + '...',
107
+ });
108
+ } catch (err) {
109
+ // Log warning but don't throw - let the request attempt proceed
110
+ // The request might still succeed if the subscription is actually active
111
+ logger.warn('Session ping failed - relay subscription may be stale', {
112
+ topic: topic.substring(0, 16) + '...',
113
+ error: err instanceof Error ? err.message : String(err),
114
+ });
115
+ }
116
+ }
117
+
118
+ /**
119
+ * Force refresh relay subscription for a topic.
120
+ *
121
+ * Use this when you suspect the subscription is stale and want
122
+ * to explicitly re-subscribe rather than relying on ping.
123
+ *
124
+ * @param topic - Session topic to refresh subscription for
125
+ */
126
+ async refreshSubscription(topic: string): Promise<void> {
127
+ try {
128
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any -- WalletConnect internal API not typed
129
+ const relayer = (this.client as any).core?.relayer;
130
+ if (relayer?.subscribe) {
131
+ await relayer.subscribe(topic);
132
+ // Clear ping cache so next ensureSessionHealth will ping
133
+ this.lastPingTime.delete(topic);
134
+ logger.info('Refreshed relay subscription', {
135
+ topic: topic.substring(0, 16) + '...',
136
+ });
137
+ } else {
138
+ logger.warn('Relayer.subscribe not available');
139
+ }
140
+ } catch (err) {
141
+ logger.warn('Failed to refresh subscription', {
142
+ topic: topic.substring(0, 16) + '...',
143
+ error: err instanceof Error ? err.message : String(err),
144
+ });
145
+ }
146
+ }
147
+
148
+ /**
149
+ * Clear ping cache for a specific topic or all topics.
150
+ *
151
+ * @param topic - Optional topic to clear. If not provided, clears all.
152
+ */
153
+ clearPingCache(topic?: string): void {
154
+ if (topic) {
155
+ this.lastPingTime.delete(topic);
156
+ } else {
157
+ this.lastPingTime.clear();
158
+ }
159
+ }
160
+
161
+ /**
162
+ * Setup relay connection monitoring.
163
+ *
164
+ * Listens for:
165
+ * - connect: Logs when WebSocket connects
166
+ * - disconnect: Clears ping cache to force re-ping on next request
167
+ * - error: Logs relay errors
168
+ *
169
+ * @private
170
+ */
171
+ private setupRelayMonitoring(): void {
172
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any -- WalletConnect internal API not typed
173
+ const relayer = (this.client as any).core?.relayer;
174
+ if (!relayer) {
175
+ logger.warn('Could not access relayer for monitoring');
176
+ return;
177
+ }
178
+
179
+ relayer.on('connect', () => {
180
+ logger.info('Relay WebSocket connected');
181
+ });
182
+
183
+ relayer.on('disconnect', () => {
184
+ logger.warn('Relay WebSocket disconnected - clearing ping cache');
185
+ this.lastPingTime.clear();
186
+ });
187
+
188
+ relayer.on('error', (err: Error) => {
189
+ logger.error('Relay error', {
190
+ error: err?.message || String(err),
191
+ });
192
+ });
193
+
194
+ logger.debug('Relay monitoring setup complete');
195
+ }
196
+ }