@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.
- package/README.md +48 -0
- package/USAGE_EXAMPLES.md +476 -0
- package/assets/wallets/extension.svg +7 -0
- package/assets/wallets/hashpack.svg +6 -0
- package/assets/wallets/hsuite.svg +11 -0
- package/assets/wallets/kabila.svg +11 -0
- package/assets/wallets/walletconnect.svg +13 -0
- package/coverage/base.css +224 -0
- package/coverage/block-navigation.js +87 -0
- package/coverage/coverage-summary.json +50 -0
- package/coverage/favicon.png +0 -0
- package/coverage/index.html +476 -0
- package/coverage/lcov-report/base.css +224 -0
- package/coverage/lcov-report/block-navigation.js +87 -0
- package/coverage/lcov-report/favicon.png +0 -0
- package/coverage/lcov-report/index.html +476 -0
- package/coverage/lcov-report/lib/components/account-selector/account-actions/account-actions.component.ts.html +868 -0
- package/coverage/lcov-report/lib/components/account-selector/account-actions/index.html +116 -0
- package/coverage/lcov-report/lib/components/account-selector/account-filter/account-filter.component.ts.html +1288 -0
- package/coverage/lcov-report/lib/components/account-selector/account-filter/index.html +116 -0
- package/coverage/lcov-report/lib/components/account-selector/account-formatting.service.ts.html +685 -0
- package/coverage/lcov-report/lib/components/account-selector/account-grouping.service.ts.html +766 -0
- package/coverage/lcov-report/lib/components/account-selector/account-list/account-list.component.ts.html +1495 -0
- package/coverage/lcov-report/lib/components/account-selector/account-list/index.html +116 -0
- package/coverage/lcov-report/lib/components/account-selector/account-selector.component.ts.html +1495 -0
- package/coverage/lcov-report/lib/components/account-selector/account-selector.service.ts.html +1588 -0
- package/coverage/lcov-report/lib/components/account-selector/index.html +161 -0
- package/coverage/lcov-report/lib/components/wallet-account-display/index.html +116 -0
- package/coverage/lcov-report/lib/components/wallet-account-display/wallet-account-display.component.ts.html +505 -0
- package/coverage/lcov-report/lib/components/wallet-connect-button/index.html +116 -0
- package/coverage/lcov-report/lib/components/wallet-connect-button/wallet-connect-button.component.ts.html +805 -0
- package/coverage/lcov-report/lib/components/wallet-connect-prompt/index.html +116 -0
- package/coverage/lcov-report/lib/components/wallet-connect-prompt/wallet-connect-prompt.component.ts.html +409 -0
- package/coverage/lcov-report/lib/components/wallet-connected-guard/index.html +116 -0
- package/coverage/lcov-report/lib/components/wallet-connected-guard/wallet-connected-guard.component.ts.html +304 -0
- package/coverage/lcov-report/lib/components/wallet-connection-modal/connection-method-step/connection-method-step.component.ts.html +436 -0
- package/coverage/lcov-report/lib/components/wallet-connection-modal/connection-method-step/index.html +116 -0
- package/coverage/lcov-report/lib/components/wallet-connection-modal/index.html +116 -0
- package/coverage/lcov-report/lib/components/wallet-connection-modal/qr-pairing-step/index.html +116 -0
- package/coverage/lcov-report/lib/components/wallet-connection-modal/qr-pairing-step/qr-pairing-step.component.ts.html +2287 -0
- package/coverage/lcov-report/lib/components/wallet-connection-modal/wallet-connection-modal.component.ts.html +2275 -0
- package/coverage/lcov-report/lib/components/wallet-session-display/index.html +116 -0
- package/coverage/lcov-report/lib/components/wallet-session-display/wallet-session-display.component.ts.html +676 -0
- package/coverage/lcov-report/lib/components/wallet-transaction-status/index.html +116 -0
- package/coverage/lcov-report/lib/components/wallet-transaction-status/wallet-transaction-status.component.ts.html +703 -0
- package/coverage/lcov-report/lib/directives/index.html +146 -0
- package/coverage/lcov-report/lib/directives/wallet-connected.directive.ts.html +670 -0
- package/coverage/lcov-report/lib/directives/wallet-context.directive.ts.html +547 -0
- package/coverage/lcov-report/lib/directives/wallet-events.directive.ts.html +781 -0
- package/coverage/lcov-report/lib/hsuite-wallet.module.ts.html +715 -0
- package/coverage/lcov-report/lib/index.html +116 -0
- package/coverage/lcov-report/lib/models/connection-config.model.ts.html +280 -0
- package/coverage/lcov-report/lib/models/index.html +131 -0
- package/coverage/lcov-report/lib/models/provider-types.ts.html +577 -0
- package/coverage/lcov-report/lib/providers/base-wallet-provider.ts.html +1138 -0
- package/coverage/lcov-report/lib/providers/hsuite-native/channel-client.service.ts.html +2671 -0
- package/coverage/lcov-report/lib/providers/hsuite-native/index.html +116 -0
- package/coverage/lcov-report/lib/providers/hsuite-native-provider.ts.html +2347 -0
- package/coverage/lcov-report/lib/providers/index.html +146 -0
- package/coverage/lcov-report/lib/providers/p2p-native/index.html +131 -0
- package/coverage/lcov-report/lib/providers/p2p-native/p2p-native.provider.ts.html +2254 -0
- package/coverage/lcov-report/lib/providers/p2p-native/p2p-session-manager.ts.html +2170 -0
- package/coverage/lcov-report/lib/providers/wallet-error-handler.ts.html +1132 -0
- package/coverage/lcov-report/lib/providers/walletconnect/core/index.html +176 -0
- package/coverage/lcov-report/lib/providers/walletconnect/core/session-health.ts.html +673 -0
- package/coverage/lcov-report/lib/providers/walletconnect/core/walletconnect-client-manager.ts.html +1177 -0
- package/coverage/lcov-report/lib/providers/walletconnect/core/walletconnect-provider.ts.html +2563 -0
- package/coverage/lcov-report/lib/providers/walletconnect/core/walletconnect-session-store.ts.html +904 -0
- package/coverage/lcov-report/lib/providers/walletconnect/core/walletconnect-signing-orchestrator.ts.html +982 -0
- package/coverage/lcov-report/lib/providers/walletconnect/signers/hedera-signer.ts.html +1915 -0
- package/coverage/lcov-report/lib/providers/walletconnect/signers/index.html +146 -0
- package/coverage/lcov-report/lib/providers/walletconnect/signers/signer-factory.ts.html +445 -0
- package/coverage/lcov-report/lib/providers/walletconnect/signers/xrpl-signer.ts.html +1519 -0
- package/coverage/lcov-report/lib/services/index.html +191 -0
- package/coverage/lcov-report/lib/services/logger.service.ts.html +463 -0
- package/coverage/lcov-report/lib/services/transaction-builders/base-transaction-builder.service.ts.html +1840 -0
- package/coverage/lcov-report/lib/services/transaction-builders/hedera-amount-utils.ts.html +337 -0
- package/coverage/lcov-report/lib/services/transaction-builders/hedera-transaction-builder.service.ts.html +3940 -0
- package/coverage/lcov-report/lib/services/transaction-builders/index.html +161 -0
- package/coverage/lcov-report/lib/services/transaction-builders/xrpl-transaction-builder.service.ts.html +2581 -0
- package/coverage/lcov-report/lib/services/transaction.service.ts.html +1123 -0
- package/coverage/lcov-report/lib/services/unified-wallet.service.ts.html +2641 -0
- package/coverage/lcov-report/lib/services/wallet-context.service.ts.html +637 -0
- package/coverage/lcov-report/lib/services/wallet-event-bus.service.ts.html +643 -0
- package/coverage/lcov-report/lib/services/wallet-providers.service.ts.html +496 -0
- package/coverage/lcov-report/lib/transports/chrome-extension-transport.ts.html +823 -0
- package/coverage/lcov-report/lib/transports/index.html +116 -0
- package/coverage/lcov-report/lib/utils/index.html +116 -0
- package/coverage/lcov-report/lib/utils/ledger-icons.util.ts.html +319 -0
- package/coverage/lcov-report/prettify.css +1 -0
- package/coverage/lcov-report/prettify.js +2 -0
- package/coverage/lcov-report/sort-arrow-sprite.png +0 -0
- package/coverage/lcov-report/sorter.js +210 -0
- package/coverage/lcov.info +19252 -0
- package/coverage/lib/components/account-selector/account-actions/account-actions.component.ts.html +868 -0
- package/coverage/lib/components/account-selector/account-actions/index.html +116 -0
- package/coverage/lib/components/account-selector/account-filter/account-filter.component.ts.html +1288 -0
- package/coverage/lib/components/account-selector/account-filter/index.html +116 -0
- package/coverage/lib/components/account-selector/account-formatting.service.ts.html +685 -0
- package/coverage/lib/components/account-selector/account-grouping.service.ts.html +766 -0
- package/coverage/lib/components/account-selector/account-list/account-list.component.ts.html +1495 -0
- package/coverage/lib/components/account-selector/account-list/index.html +116 -0
- package/coverage/lib/components/account-selector/account-selector.component.ts.html +1495 -0
- package/coverage/lib/components/account-selector/account-selector.service.ts.html +1588 -0
- package/coverage/lib/components/account-selector/index.html +161 -0
- package/coverage/lib/components/wallet-account-display/index.html +116 -0
- package/coverage/lib/components/wallet-account-display/wallet-account-display.component.ts.html +505 -0
- package/coverage/lib/components/wallet-connect-button/index.html +116 -0
- package/coverage/lib/components/wallet-connect-button/wallet-connect-button.component.ts.html +805 -0
- package/coverage/lib/components/wallet-connect-prompt/index.html +116 -0
- package/coverage/lib/components/wallet-connect-prompt/wallet-connect-prompt.component.ts.html +409 -0
- package/coverage/lib/components/wallet-connected-guard/index.html +116 -0
- package/coverage/lib/components/wallet-connected-guard/wallet-connected-guard.component.ts.html +304 -0
- package/coverage/lib/components/wallet-connection-modal/connection-method-step/connection-method-step.component.ts.html +436 -0
- package/coverage/lib/components/wallet-connection-modal/connection-method-step/index.html +116 -0
- package/coverage/lib/components/wallet-connection-modal/index.html +116 -0
- package/coverage/lib/components/wallet-connection-modal/qr-pairing-step/index.html +116 -0
- package/coverage/lib/components/wallet-connection-modal/qr-pairing-step/qr-pairing-step.component.ts.html +2287 -0
- package/coverage/lib/components/wallet-connection-modal/wallet-connection-modal.component.ts.html +2275 -0
- package/coverage/lib/components/wallet-session-display/index.html +116 -0
- package/coverage/lib/components/wallet-session-display/wallet-session-display.component.ts.html +676 -0
- package/coverage/lib/components/wallet-transaction-status/index.html +116 -0
- package/coverage/lib/components/wallet-transaction-status/wallet-transaction-status.component.ts.html +703 -0
- package/coverage/lib/directives/index.html +146 -0
- package/coverage/lib/directives/wallet-connected.directive.ts.html +670 -0
- package/coverage/lib/directives/wallet-context.directive.ts.html +547 -0
- package/coverage/lib/directives/wallet-events.directive.ts.html +781 -0
- package/coverage/lib/hsuite-wallet.module.ts.html +715 -0
- package/coverage/lib/index.html +116 -0
- package/coverage/lib/models/connection-config.model.ts.html +280 -0
- package/coverage/lib/models/index.html +131 -0
- package/coverage/lib/models/provider-types.ts.html +577 -0
- package/coverage/lib/providers/base-wallet-provider.ts.html +1138 -0
- package/coverage/lib/providers/hsuite-native/channel-client.service.ts.html +2671 -0
- package/coverage/lib/providers/hsuite-native/index.html +116 -0
- package/coverage/lib/providers/hsuite-native-provider.ts.html +2347 -0
- package/coverage/lib/providers/index.html +146 -0
- package/coverage/lib/providers/p2p-native/index.html +131 -0
- package/coverage/lib/providers/p2p-native/p2p-native.provider.ts.html +2254 -0
- package/coverage/lib/providers/p2p-native/p2p-session-manager.ts.html +2170 -0
- package/coverage/lib/providers/wallet-error-handler.ts.html +1132 -0
- package/coverage/lib/providers/walletconnect/core/index.html +176 -0
- package/coverage/lib/providers/walletconnect/core/session-health.ts.html +673 -0
- package/coverage/lib/providers/walletconnect/core/walletconnect-client-manager.ts.html +1177 -0
- package/coverage/lib/providers/walletconnect/core/walletconnect-provider.ts.html +2563 -0
- package/coverage/lib/providers/walletconnect/core/walletconnect-session-store.ts.html +904 -0
- package/coverage/lib/providers/walletconnect/core/walletconnect-signing-orchestrator.ts.html +982 -0
- package/coverage/lib/providers/walletconnect/signers/hedera-signer.ts.html +1915 -0
- package/coverage/lib/providers/walletconnect/signers/index.html +146 -0
- package/coverage/lib/providers/walletconnect/signers/signer-factory.ts.html +445 -0
- package/coverage/lib/providers/walletconnect/signers/xrpl-signer.ts.html +1519 -0
- package/coverage/lib/services/index.html +191 -0
- package/coverage/lib/services/logger.service.ts.html +463 -0
- package/coverage/lib/services/transaction-builders/base-transaction-builder.service.ts.html +1840 -0
- package/coverage/lib/services/transaction-builders/hedera-amount-utils.ts.html +337 -0
- package/coverage/lib/services/transaction-builders/hedera-transaction-builder.service.ts.html +3940 -0
- package/coverage/lib/services/transaction-builders/index.html +161 -0
- package/coverage/lib/services/transaction-builders/xrpl-transaction-builder.service.ts.html +2581 -0
- package/coverage/lib/services/transaction.service.ts.html +1123 -0
- package/coverage/lib/services/unified-wallet.service.ts.html +2641 -0
- package/coverage/lib/services/wallet-context.service.ts.html +637 -0
- package/coverage/lib/services/wallet-event-bus.service.ts.html +643 -0
- package/coverage/lib/services/wallet-providers.service.ts.html +496 -0
- package/coverage/lib/transports/chrome-extension-transport.ts.html +823 -0
- package/coverage/lib/transports/index.html +116 -0
- package/coverage/lib/utils/index.html +116 -0
- package/coverage/lib/utils/ledger-icons.util.ts.html +319 -0
- package/coverage/prettify.css +1 -0
- package/coverage/prettify.js +2 -0
- package/coverage/sort-arrow-sprite.png +0 -0
- package/coverage/sorter.js +210 -0
- package/dist/README.md +48 -0
- package/dist/fesm2022/hsuite-native-connect-angular.mjs +14592 -0
- package/dist/fesm2022/hsuite-native-connect-angular.mjs.map +1 -0
- package/dist/index.d.ts +6949 -0
- package/examples/minimal-connect.ts +178 -0
- package/examples/multi-protocol.ts +495 -0
- package/examples/transaction-signing.ts +361 -0
- package/jest.config.json +45 -0
- package/karma.conf.js +42 -0
- package/ng-package.json +20 -0
- package/package.json +60 -0
- package/src/index.ts +203 -0
- package/src/lib/components/account-selector/account-actions/account-actions.component.ts +261 -0
- package/src/lib/components/account-selector/account-filter/account-filter.component.ts +401 -0
- package/src/lib/components/account-selector/account-formatting.service.ts +200 -0
- package/src/lib/components/account-selector/account-grouping.service.ts +227 -0
- package/src/lib/components/account-selector/account-list/account-list.component.ts +470 -0
- package/src/lib/components/account-selector/account-selector.component.html +135 -0
- package/src/lib/components/account-selector/account-selector.component.scss +2039 -0
- package/src/lib/components/account-selector/account-selector.component.ts +470 -0
- package/src/lib/components/account-selector/account-selector.service.ts +501 -0
- package/src/lib/components/wallet-account-display/wallet-account-display.component.html +34 -0
- package/src/lib/components/wallet-account-display/wallet-account-display.component.scss +99 -0
- package/src/lib/components/wallet-account-display/wallet-account-display.component.ts +140 -0
- package/src/lib/components/wallet-connect-button/wallet-connect-button.component.html +14 -0
- package/src/lib/components/wallet-connect-button/wallet-connect-button.component.scss +272 -0
- package/src/lib/components/wallet-connect-button/wallet-connect-button.component.ts +240 -0
- package/src/lib/components/wallet-connect-prompt/wallet-connect-prompt.component.html +24 -0
- package/src/lib/components/wallet-connect-prompt/wallet-connect-prompt.component.scss +50 -0
- package/src/lib/components/wallet-connect-prompt/wallet-connect-prompt.component.ts +108 -0
- package/src/lib/components/wallet-connected-guard/wallet-connected-guard.component.html +24 -0
- package/src/lib/components/wallet-connected-guard/wallet-connected-guard.component.ts +73 -0
- package/src/lib/components/wallet-connection-modal/connection-method-step/connection-method-step.component.html +56 -0
- package/src/lib/components/wallet-connection-modal/connection-method-step/connection-method-step.component.scss +218 -0
- package/src/lib/components/wallet-connection-modal/connection-method-step/connection-method-step.component.ts +117 -0
- package/src/lib/components/wallet-connection-modal/qr-pairing-step/qr-pairing-step.component.html +94 -0
- package/src/lib/components/wallet-connection-modal/qr-pairing-step/qr-pairing-step.component.scss +272 -0
- package/src/lib/components/wallet-connection-modal/qr-pairing-step/qr-pairing-step.component.ts +734 -0
- package/src/lib/components/wallet-connection-modal/wallet-connection-modal.component.html +197 -0
- package/src/lib/components/wallet-connection-modal/wallet-connection-modal.component.scss +678 -0
- package/src/lib/components/wallet-connection-modal/wallet-connection-modal.component.ts +730 -0
- package/src/lib/components/wallet-session-display/wallet-session-display.component.html +110 -0
- package/src/lib/components/wallet-session-display/wallet-session-display.component.scss +179 -0
- package/src/lib/components/wallet-session-display/wallet-session-display.component.ts +197 -0
- package/src/lib/components/wallet-transaction-status/wallet-transaction-status.component.html +65 -0
- package/src/lib/components/wallet-transaction-status/wallet-transaction-status.component.scss +254 -0
- package/src/lib/components/wallet-transaction-status/wallet-transaction-status.component.ts +206 -0
- package/src/lib/directives/wallet-connected.directive.ts +195 -0
- package/src/lib/directives/wallet-context.directive.ts +154 -0
- package/src/lib/directives/wallet-events.directive.ts +232 -0
- package/src/lib/hsuite-wallet.module.ts +210 -0
- package/src/lib/models/connection-config.model.ts +65 -0
- package/src/lib/models/provider-types.ts +164 -0
- package/src/lib/models/unified-account.model.ts +76 -0
- package/src/lib/models/wallet-context.model.ts +121 -0
- package/src/lib/models/wallet-events.model.ts +158 -0
- package/src/lib/providers/base-wallet-provider.ts +351 -0
- package/src/lib/providers/hsuite-native/channel-client.service.spec.ts +73 -0
- package/src/lib/providers/hsuite-native/channel-client.service.ts +862 -0
- package/src/lib/providers/hsuite-native/index.ts +8 -0
- package/src/lib/providers/hsuite-native-provider.ts +754 -0
- package/src/lib/providers/mobile-native/mobile-native.provider.spec.ts +19 -0
- package/src/lib/providers/p2p-native/index.ts +30 -0
- package/src/lib/providers/p2p-native/p2p-native.provider.spec.ts +523 -0
- package/src/lib/providers/p2p-native/p2p-native.provider.ts +723 -0
- package/src/lib/providers/p2p-native/p2p-session-manager.ts +695 -0
- package/src/lib/providers/wallet-error-handler.ts +349 -0
- package/src/lib/providers/walletconnect/core/base-signer.interface.ts +122 -0
- package/src/lib/providers/walletconnect/core/session-health.ts +196 -0
- package/src/lib/providers/walletconnect/core/walletconnect-client-manager.ts +364 -0
- package/src/lib/providers/walletconnect/core/walletconnect-provider.integration.spec.ts +348 -0
- package/src/lib/providers/walletconnect/core/walletconnect-provider.ts +826 -0
- package/src/lib/providers/walletconnect/core/walletconnect-session-store.ts +273 -0
- package/src/lib/providers/walletconnect/core/walletconnect-signing-orchestrator.ts +299 -0
- package/src/lib/providers/walletconnect/core/walletconnect-types.ts +48 -0
- package/src/lib/providers/walletconnect/index.ts +33 -0
- package/src/lib/providers/walletconnect/signers/hedera-signer.spec.ts +367 -0
- package/src/lib/providers/walletconnect/signers/hedera-signer.ts +610 -0
- package/src/lib/providers/walletconnect/signers/signer-factory.spec.ts +62 -0
- package/src/lib/providers/walletconnect/signers/signer-factory.ts +120 -0
- package/src/lib/providers/walletconnect/signers/xrpl-signer.spec.ts +296 -0
- package/src/lib/providers/walletconnect/signers/xrpl-signer.ts +478 -0
- package/src/lib/services/logger.service.ts +126 -0
- package/src/lib/services/transaction-builders/base-transaction-builder.service.ts +585 -0
- package/src/lib/services/transaction-builders/hedera-amount-utils.ts +84 -0
- package/src/lib/services/transaction-builders/hedera-transaction-builder.service.spec.ts +741 -0
- package/src/lib/services/transaction-builders/hedera-transaction-builder.service.ts +1285 -0
- package/src/lib/services/transaction-builders/index.ts +54 -0
- package/src/lib/services/transaction-builders/xrpl-transaction-builder.service.spec.ts +937 -0
- package/src/lib/services/transaction-builders/xrpl-transaction-builder.service.ts +832 -0
- package/src/lib/services/transaction.service.ts +346 -0
- package/src/lib/services/unified-wallet.service.spec.ts +1382 -0
- package/src/lib/services/unified-wallet.service.ts +852 -0
- package/src/lib/services/wallet-context.service.ts +184 -0
- package/src/lib/services/wallet-event-bus.service.ts +186 -0
- package/src/lib/services/wallet-providers.service.ts +137 -0
- package/src/lib/transports/chrome-extension-transport.ts +246 -0
- package/src/lib/utils/index.ts +14 -0
- package/src/lib/utils/ledger-icons.util.ts +78 -0
- package/test/test-setup.ts +21 -0
- package/test-setup.ts +63 -0
- package/tsconfig.build.json +11 -0
- package/tsconfig.json +29 -0
- package/tsconfig.spec.json +15 -0
- package/vitest.config.ts +48 -0
|
@@ -0,0 +1,730 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @file wallet-connection-modal.component.ts
|
|
3
|
+
* @description Multi-protocol wallet connection modal with step-by-step flow
|
|
4
|
+
*
|
|
5
|
+
* Provides a beautiful, user-friendly interface for connecting wallets across
|
|
6
|
+
* multiple protocols (HSuite Native, WalletConnect) and ledgers (Hedera, XRPL).
|
|
7
|
+
*
|
|
8
|
+
* Features:
|
|
9
|
+
* - Step-by-step connection wizard with direct selection (no Next button)
|
|
10
|
+
* - Dynamic step indicator showing only relevant steps per protocol path
|
|
11
|
+
* - Network selection (Mainnet, Testnet)
|
|
12
|
+
* - Protocol selection (HSuite Native vs WalletConnect)
|
|
13
|
+
* - Connection method selection (Desktop or Mobile QR)
|
|
14
|
+
* - Ledger selection (Hedera, XRPL) for WalletConnect
|
|
15
|
+
* - QR code display for mobile P2P connections
|
|
16
|
+
* - Beautiful animations and loading states
|
|
17
|
+
*
|
|
18
|
+
* Step Paths:
|
|
19
|
+
* - HSuite Native + Desktop: Network → Protocol → Method (3 steps)
|
|
20
|
+
* - HSuite Native + Mobile QR: Network → Protocol → Method → QR Pairing (4 steps)
|
|
21
|
+
* - WalletConnect: Network → Protocol → Ledger → Connect (4 steps)
|
|
22
|
+
*/
|
|
23
|
+
|
|
24
|
+
import { CommonModule } from '@angular/common';
|
|
25
|
+
import { Component, Input, Output, EventEmitter, signal, computed, inject } from '@angular/core';
|
|
26
|
+
import { getLogger } from '@hsuite/native-connect-sdk';
|
|
27
|
+
import { IonicModule, ModalController, Platform } from '@ionic/angular';
|
|
28
|
+
|
|
29
|
+
import type { WalletConnectV2Config } from '../../models/provider-types';
|
|
30
|
+
import { DEFAULT_WALLET_URL } from '../../models/provider-types';
|
|
31
|
+
import { P2PNativeProvider } from '../../providers/p2p-native/p2p-native.provider';
|
|
32
|
+
import { UnifiedWalletService } from '../../services/unified-wallet.service';
|
|
33
|
+
|
|
34
|
+
import {
|
|
35
|
+
ConnectionMethodStepComponent,
|
|
36
|
+
type ConnectionMethodOption,
|
|
37
|
+
} from './connection-method-step/connection-method-step.component';
|
|
38
|
+
import { QrPairingStepComponent } from './qr-pairing-step/qr-pairing-step.component';
|
|
39
|
+
|
|
40
|
+
const logger = getLogger().scoped?.('WalletConnectionModal') ?? getLogger();
|
|
41
|
+
|
|
42
|
+
/**
|
|
43
|
+
* Connection step enumeration for the wizard flow
|
|
44
|
+
*/
|
|
45
|
+
enum ConnectionStep {
|
|
46
|
+
NetworkSelection = 1,
|
|
47
|
+
ProtocolSelection = 2,
|
|
48
|
+
ConnectionMethodSelection = 3,
|
|
49
|
+
LedgerSelection = 4,
|
|
50
|
+
QrPairing = 5,
|
|
51
|
+
ConnectionProgress = 6,
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
/**
|
|
55
|
+
* Connection method type.
|
|
56
|
+
* - desktop: Uses extension if available, otherwise opens PWA in new tab (SDK auto-selects)
|
|
57
|
+
* - mobile-qr: Two-way QR scan for cross-device P2P connection
|
|
58
|
+
*/
|
|
59
|
+
type ConnectionMethod = 'desktop' | 'mobile-qr';
|
|
60
|
+
|
|
61
|
+
/**
|
|
62
|
+
* Network configuration options
|
|
63
|
+
*/
|
|
64
|
+
interface NetworkOption {
|
|
65
|
+
id: string;
|
|
66
|
+
name: string;
|
|
67
|
+
description: string;
|
|
68
|
+
icon?: string;
|
|
69
|
+
recommended?: boolean;
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
/**
|
|
73
|
+
* Protocol configuration options
|
|
74
|
+
*/
|
|
75
|
+
interface ProtocolOption {
|
|
76
|
+
id: 'hsuite-native' | 'walletconnect';
|
|
77
|
+
name: string;
|
|
78
|
+
description: string;
|
|
79
|
+
icon: string;
|
|
80
|
+
features: string[];
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
/**
|
|
84
|
+
* Ledger configuration options
|
|
85
|
+
*/
|
|
86
|
+
interface LedgerOption {
|
|
87
|
+
id: 'hedera' | 'xrpl';
|
|
88
|
+
name: string;
|
|
89
|
+
description: string;
|
|
90
|
+
icon: string;
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
/**
|
|
94
|
+
* Step configuration for dynamic step indicator.
|
|
95
|
+
* Defines the total steps and labels based on selected protocol path.
|
|
96
|
+
*/
|
|
97
|
+
interface StepConfig {
|
|
98
|
+
/** Total number of steps in the current path */
|
|
99
|
+
total: number;
|
|
100
|
+
/** Labels for each step in the progress indicator */
|
|
101
|
+
labels: string[];
|
|
102
|
+
}
|
|
103
|
+
|
|
104
|
+
/**
|
|
105
|
+
* Main wallet connection modal component.
|
|
106
|
+
* Orchestrates the multi-step connection flow.
|
|
107
|
+
*/
|
|
108
|
+
@Component({
|
|
109
|
+
selector: 'hsuite-wallet-connection-modal',
|
|
110
|
+
standalone: true,
|
|
111
|
+
imports: [CommonModule, IonicModule, ConnectionMethodStepComponent, QrPairingStepComponent],
|
|
112
|
+
templateUrl: './wallet-connection-modal.component.html',
|
|
113
|
+
styleUrls: ['./wallet-connection-modal.component.scss'],
|
|
114
|
+
})
|
|
115
|
+
export class WalletConnectionModalComponent {
|
|
116
|
+
/**
|
|
117
|
+
* WalletConnect project ID (required for WalletConnect)
|
|
118
|
+
*/
|
|
119
|
+
@Input() projectId?: string;
|
|
120
|
+
|
|
121
|
+
/**
|
|
122
|
+
* App name for WalletConnect metadata
|
|
123
|
+
*/
|
|
124
|
+
@Input() appName: string = 'HSuite Demo';
|
|
125
|
+
|
|
126
|
+
/**
|
|
127
|
+
* App description for WalletConnect metadata
|
|
128
|
+
*/
|
|
129
|
+
@Input() appDescription: string = 'Multi-chain wallet connection';
|
|
130
|
+
|
|
131
|
+
/**
|
|
132
|
+
* Wallet URL for HSuite Native connection
|
|
133
|
+
*/
|
|
134
|
+
@Input() walletUrl: string = DEFAULT_WALLET_URL;
|
|
135
|
+
|
|
136
|
+
/**
|
|
137
|
+
* Event emitted when connection is successful
|
|
138
|
+
*/
|
|
139
|
+
@Output() connected = new EventEmitter<unknown>();
|
|
140
|
+
|
|
141
|
+
// Note: answerScannerRequested removed - new Nostr-first flow doesn't need answer scanning
|
|
142
|
+
|
|
143
|
+
private readonly platform = inject(Platform);
|
|
144
|
+
private readonly p2pNativeProvider = inject(P2PNativeProvider);
|
|
145
|
+
|
|
146
|
+
// Step management
|
|
147
|
+
readonly currentStep = signal<ConnectionStep>(ConnectionStep.NetworkSelection);
|
|
148
|
+
readonly ConnectionStep = ConnectionStep;
|
|
149
|
+
|
|
150
|
+
// Selection state
|
|
151
|
+
readonly selectedNetwork = signal<string>('testnet');
|
|
152
|
+
readonly selectedProtocol = signal<'hsuite-native' | 'walletconnect' | null>(null);
|
|
153
|
+
readonly selectedConnectionMethod = signal<ConnectionMethod | null>(null);
|
|
154
|
+
readonly selectedLedger = signal<'hedera' | 'xrpl' | null>(null);
|
|
155
|
+
|
|
156
|
+
// Loading state
|
|
157
|
+
readonly isConnecting = signal<boolean>(false);
|
|
158
|
+
readonly connectionError = signal<string | null>(null);
|
|
159
|
+
|
|
160
|
+
// QR Pairing state
|
|
161
|
+
readonly pairingOffer = signal<string>('');
|
|
162
|
+
readonly isGeneratingOffer = signal<boolean>(false);
|
|
163
|
+
|
|
164
|
+
/**
|
|
165
|
+
* Indicates we're waiting for the wallet to scan the QR and connect via Nostr.
|
|
166
|
+
*/
|
|
167
|
+
readonly isWaitingForWallet = signal<boolean>(false);
|
|
168
|
+
|
|
169
|
+
/**
|
|
170
|
+
* Indicates we're waiting for the wallet user to approve the session.
|
|
171
|
+
* Nostr connection is established, but session approval is pending.
|
|
172
|
+
*/
|
|
173
|
+
readonly isWaitingForApproval = signal<boolean>(false);
|
|
174
|
+
|
|
175
|
+
// Platform detection
|
|
176
|
+
readonly isMobile = signal<boolean>(this.detectMobile());
|
|
177
|
+
readonly isExtensionAvailable = signal<boolean>(this.detectExtension());
|
|
178
|
+
|
|
179
|
+
// Configuration options
|
|
180
|
+
readonly networkOptions: NetworkOption[] = [
|
|
181
|
+
{
|
|
182
|
+
id: 'mainnet',
|
|
183
|
+
name: 'Mainnet',
|
|
184
|
+
description: 'Production network with real assets',
|
|
185
|
+
icon: 'shield-checkmark',
|
|
186
|
+
},
|
|
187
|
+
{
|
|
188
|
+
id: 'testnet',
|
|
189
|
+
name: 'Testnet',
|
|
190
|
+
description: 'Test network for development',
|
|
191
|
+
icon: 'flask',
|
|
192
|
+
recommended: true,
|
|
193
|
+
},
|
|
194
|
+
];
|
|
195
|
+
|
|
196
|
+
readonly protocolOptions = computed<ProtocolOption[]>(() => {
|
|
197
|
+
const options: ProtocolOption[] = [
|
|
198
|
+
{
|
|
199
|
+
id: 'hsuite-native',
|
|
200
|
+
name: 'HSuite Native Connect',
|
|
201
|
+
description: 'Direct connection to HSuite Wallet',
|
|
202
|
+
icon: 'link',
|
|
203
|
+
features: [
|
|
204
|
+
'Multiple chains in one session',
|
|
205
|
+
'Multiple wallets per session',
|
|
206
|
+
'Seamless multi-chain operations',
|
|
207
|
+
'Best for HSuite Wallet users',
|
|
208
|
+
],
|
|
209
|
+
},
|
|
210
|
+
];
|
|
211
|
+
|
|
212
|
+
// Only show WalletConnect if projectId is provided
|
|
213
|
+
if (this.projectId) {
|
|
214
|
+
options.push({
|
|
215
|
+
id: 'walletconnect',
|
|
216
|
+
name: 'WalletConnect',
|
|
217
|
+
description: 'Universal wallet connection protocol',
|
|
218
|
+
icon: 'scan',
|
|
219
|
+
features: [
|
|
220
|
+
'Connect via QR code or extension',
|
|
221
|
+
'Compatible with HashPack, Kabila, and more',
|
|
222
|
+
'Industry-standard protocol',
|
|
223
|
+
'One wallet per session',
|
|
224
|
+
],
|
|
225
|
+
});
|
|
226
|
+
}
|
|
227
|
+
|
|
228
|
+
return options;
|
|
229
|
+
});
|
|
230
|
+
|
|
231
|
+
readonly ledgerOptions: LedgerOption[] = [
|
|
232
|
+
{
|
|
233
|
+
id: 'hedera',
|
|
234
|
+
name: 'Hedera',
|
|
235
|
+
description: 'Hedera Hashgraph network',
|
|
236
|
+
icon: 'logo-bitcoin', // Placeholder, use actual Hedera icon
|
|
237
|
+
},
|
|
238
|
+
{
|
|
239
|
+
id: 'xrpl',
|
|
240
|
+
name: 'XRP Ledger',
|
|
241
|
+
description: 'XRP Ledger network',
|
|
242
|
+
icon: 'logo-usd', // Placeholder, use actual XRPL icon
|
|
243
|
+
},
|
|
244
|
+
];
|
|
245
|
+
|
|
246
|
+
/**
|
|
247
|
+
* Connection method options for HSuite Native.
|
|
248
|
+
* Simplified to two options:
|
|
249
|
+
* - HSuite Wallet (desktop): SDK auto-selects extension or PWA
|
|
250
|
+
* - Mobile Wallet (QR): Cross-device P2P connection
|
|
251
|
+
*/
|
|
252
|
+
readonly connectionMethodOptions = computed<ConnectionMethodOption[]>(() => [
|
|
253
|
+
{
|
|
254
|
+
id: 'desktop',
|
|
255
|
+
name: 'HSuite Wallet',
|
|
256
|
+
description: this.isExtensionAvailable()
|
|
257
|
+
? 'Connect via browser extension'
|
|
258
|
+
: 'Open HSuite Wallet in new tab',
|
|
259
|
+
icon: this.isExtensionAvailable() ? 'extension-puzzle-outline' : 'open-outline',
|
|
260
|
+
available: true,
|
|
261
|
+
recommended: !this.isMobile(),
|
|
262
|
+
features: this.isExtensionAvailable()
|
|
263
|
+
? ['Extension detected', 'Fastest connection']
|
|
264
|
+
: ['Opens in new tab', 'Works everywhere'],
|
|
265
|
+
},
|
|
266
|
+
{
|
|
267
|
+
id: 'mobile-qr',
|
|
268
|
+
name: 'Mobile Wallet (QR)',
|
|
269
|
+
description: 'Two-way QR scan for cross-device connection',
|
|
270
|
+
icon: 'qr-code-outline',
|
|
271
|
+
available: true,
|
|
272
|
+
recommended: this.isMobile(),
|
|
273
|
+
features: ['Cross-device', 'P2P', 'No server needed'],
|
|
274
|
+
},
|
|
275
|
+
]);
|
|
276
|
+
|
|
277
|
+
// Computed properties
|
|
278
|
+
readonly canProceed = computed(() => {
|
|
279
|
+
const step = this.currentStep();
|
|
280
|
+
switch (step) {
|
|
281
|
+
case ConnectionStep.NetworkSelection:
|
|
282
|
+
return !!this.selectedNetwork();
|
|
283
|
+
case ConnectionStep.ProtocolSelection:
|
|
284
|
+
return !!this.selectedProtocol();
|
|
285
|
+
case ConnectionStep.ConnectionMethodSelection:
|
|
286
|
+
return !!this.selectedConnectionMethod();
|
|
287
|
+
case ConnectionStep.LedgerSelection:
|
|
288
|
+
return !!this.selectedLedger();
|
|
289
|
+
default:
|
|
290
|
+
return false;
|
|
291
|
+
}
|
|
292
|
+
});
|
|
293
|
+
|
|
294
|
+
readonly stepTitle = computed(() => {
|
|
295
|
+
const step = this.currentStep();
|
|
296
|
+
switch (step) {
|
|
297
|
+
case ConnectionStep.NetworkSelection:
|
|
298
|
+
return 'Select Network';
|
|
299
|
+
case ConnectionStep.ProtocolSelection:
|
|
300
|
+
return 'Choose Connection Protocol';
|
|
301
|
+
case ConnectionStep.ConnectionMethodSelection:
|
|
302
|
+
return 'Choose Connection Method';
|
|
303
|
+
case ConnectionStep.LedgerSelection:
|
|
304
|
+
return 'Select Ledger';
|
|
305
|
+
case ConnectionStep.QrPairing:
|
|
306
|
+
return 'Connect Mobile Wallet';
|
|
307
|
+
case ConnectionStep.ConnectionProgress:
|
|
308
|
+
return 'Connecting...';
|
|
309
|
+
default:
|
|
310
|
+
return '';
|
|
311
|
+
}
|
|
312
|
+
});
|
|
313
|
+
|
|
314
|
+
/**
|
|
315
|
+
* Dynamic step configuration based on selected protocol and connection method.
|
|
316
|
+
* Returns the total number of steps and labels for the progress indicator.
|
|
317
|
+
*
|
|
318
|
+
* Step Paths:
|
|
319
|
+
* - Initial (no protocol): 3 placeholder steps
|
|
320
|
+
* - HSuite Native + Desktop: 3 steps (Network, Protocol, Method)
|
|
321
|
+
* - HSuite Native + Mobile QR: 4 steps (Network, Protocol, Method, Pair)
|
|
322
|
+
* - WalletConnect: 4 steps (Network, Protocol, Ledger, Connect)
|
|
323
|
+
*/
|
|
324
|
+
readonly stepConfig = computed<StepConfig>(() => {
|
|
325
|
+
const protocol = this.selectedProtocol();
|
|
326
|
+
const method = this.selectedConnectionMethod();
|
|
327
|
+
|
|
328
|
+
// Initial state: show 3 placeholder steps until protocol is selected
|
|
329
|
+
if (!protocol) {
|
|
330
|
+
return { total: 3, labels: ['Network', 'Protocol', '...'] };
|
|
331
|
+
}
|
|
332
|
+
|
|
333
|
+
// HSuite Native path
|
|
334
|
+
if (protocol === 'hsuite-native') {
|
|
335
|
+
// If mobile QR is selected, we need 4 steps
|
|
336
|
+
if (method === 'mobile-qr') {
|
|
337
|
+
return { total: 4, labels: ['Network', 'Protocol', 'Method', 'Pair'] };
|
|
338
|
+
}
|
|
339
|
+
// Desktop connection is 3 steps (connects immediately after method selection)
|
|
340
|
+
return { total: 3, labels: ['Network', 'Protocol', 'Method'] };
|
|
341
|
+
}
|
|
342
|
+
|
|
343
|
+
// WalletConnect path: 4 steps
|
|
344
|
+
return { total: 4, labels: ['Network', 'Protocol', 'Ledger', 'Connect'] };
|
|
345
|
+
});
|
|
346
|
+
|
|
347
|
+
/**
|
|
348
|
+
* Maps the internal ConnectionStep enum to display position (1-based).
|
|
349
|
+
* Different protocol paths have different step mappings.
|
|
350
|
+
*/
|
|
351
|
+
readonly displayStep = computed<number>(() => {
|
|
352
|
+
const step = this.currentStep();
|
|
353
|
+
// Protocol could be used for protocol-specific step mapping in the future
|
|
354
|
+
const _protocol = this.selectedProtocol();
|
|
355
|
+
|
|
356
|
+
// Map internal step to display position based on protocol path
|
|
357
|
+
switch (step) {
|
|
358
|
+
case ConnectionStep.NetworkSelection:
|
|
359
|
+
return 1;
|
|
360
|
+
case ConnectionStep.ProtocolSelection:
|
|
361
|
+
return 2;
|
|
362
|
+
case ConnectionStep.ConnectionMethodSelection:
|
|
363
|
+
return 3;
|
|
364
|
+
case ConnectionStep.LedgerSelection:
|
|
365
|
+
// WalletConnect ledger selection is step 3
|
|
366
|
+
return 3;
|
|
367
|
+
case ConnectionStep.QrPairing:
|
|
368
|
+
// QR pairing is step 4 for both paths that use it
|
|
369
|
+
return 4;
|
|
370
|
+
case ConnectionStep.ConnectionProgress:
|
|
371
|
+
// Connection progress is always the last step
|
|
372
|
+
return this.stepConfig().total;
|
|
373
|
+
default:
|
|
374
|
+
return 1;
|
|
375
|
+
}
|
|
376
|
+
});
|
|
377
|
+
|
|
378
|
+
/**
|
|
379
|
+
*
|
|
380
|
+
* @param modalController
|
|
381
|
+
* @param unifiedWalletService
|
|
382
|
+
*/
|
|
383
|
+
constructor(
|
|
384
|
+
private modalController: ModalController,
|
|
385
|
+
private unifiedWalletService: UnifiedWalletService,
|
|
386
|
+
) {
|
|
387
|
+
// Set up mobile provider connection callback
|
|
388
|
+
this.p2pNativeProvider.onPeerConnected(() => {
|
|
389
|
+
this.onMobileConnected();
|
|
390
|
+
});
|
|
391
|
+
}
|
|
392
|
+
|
|
393
|
+
/**
|
|
394
|
+
* Select a network option (internal, use selectNetworkAndProceed for UI)
|
|
395
|
+
* @param networkId
|
|
396
|
+
*/
|
|
397
|
+
selectNetwork(networkId: string): void {
|
|
398
|
+
this.selectedNetwork.set(networkId);
|
|
399
|
+
}
|
|
400
|
+
|
|
401
|
+
/**
|
|
402
|
+
* Select a network and automatically proceed to the next step.
|
|
403
|
+
* This enables direct selection behavior without requiring a "Next" button.
|
|
404
|
+
* @param networkId - The network ID to select ('mainnet' or 'testnet')
|
|
405
|
+
*/
|
|
406
|
+
selectNetworkAndProceed(networkId: string): void {
|
|
407
|
+
this.selectedNetwork.set(networkId);
|
|
408
|
+
// Auto-advance to protocol selection
|
|
409
|
+
this.currentStep.set(ConnectionStep.ProtocolSelection);
|
|
410
|
+
}
|
|
411
|
+
|
|
412
|
+
/**
|
|
413
|
+
* Select a protocol option (internal, use selectProtocolAndProceed for UI)
|
|
414
|
+
* @param protocolId
|
|
415
|
+
*/
|
|
416
|
+
selectProtocol(protocolId: 'hsuite-native' | 'walletconnect'): void {
|
|
417
|
+
this.selectedProtocol.set(protocolId);
|
|
418
|
+
}
|
|
419
|
+
|
|
420
|
+
/**
|
|
421
|
+
* Select a protocol and automatically proceed to the appropriate next step.
|
|
422
|
+
* - HSuite Native → Connection Method Selection
|
|
423
|
+
* - WalletConnect → Ledger Selection
|
|
424
|
+
* @param protocolId - The protocol ID to select
|
|
425
|
+
*/
|
|
426
|
+
selectProtocolAndProceed(protocolId: 'hsuite-native' | 'walletconnect'): void {
|
|
427
|
+
this.selectedProtocol.set(protocolId);
|
|
428
|
+
|
|
429
|
+
if (protocolId === 'hsuite-native') {
|
|
430
|
+
// HSuite Native: Go to connection method selection
|
|
431
|
+
this.currentStep.set(ConnectionStep.ConnectionMethodSelection);
|
|
432
|
+
} else {
|
|
433
|
+
// WalletConnect: Go to ledger selection
|
|
434
|
+
this.currentStep.set(ConnectionStep.LedgerSelection);
|
|
435
|
+
}
|
|
436
|
+
}
|
|
437
|
+
|
|
438
|
+
/**
|
|
439
|
+
* Select a connection method (internal)
|
|
440
|
+
* @param methodId
|
|
441
|
+
*/
|
|
442
|
+
selectConnectionMethod(methodId: string): void {
|
|
443
|
+
this.selectedConnectionMethod.set(methodId as ConnectionMethod);
|
|
444
|
+
}
|
|
445
|
+
|
|
446
|
+
/**
|
|
447
|
+
* Handle connection method selection from step component.
|
|
448
|
+
* Automatically proceeds to connect or QR pairing based on method.
|
|
449
|
+
* @param methodId
|
|
450
|
+
*/
|
|
451
|
+
onConnectionMethodSelected(methodId: string): void {
|
|
452
|
+
this.selectConnectionMethod(methodId);
|
|
453
|
+
void this.next();
|
|
454
|
+
}
|
|
455
|
+
|
|
456
|
+
/**
|
|
457
|
+
* Select a ledger option (internal, use selectLedgerAndConnect for UI)
|
|
458
|
+
* @param ledgerId
|
|
459
|
+
*/
|
|
460
|
+
selectLedger(ledgerId: 'hedera' | 'xrpl'): void {
|
|
461
|
+
this.selectedLedger.set(ledgerId);
|
|
462
|
+
}
|
|
463
|
+
|
|
464
|
+
/**
|
|
465
|
+
* Select a ledger and automatically initiate connection.
|
|
466
|
+
* This enables direct selection behavior for WalletConnect ledger step.
|
|
467
|
+
* @param ledgerId - The ledger ID to select ('hedera' or 'xrpl')
|
|
468
|
+
*/
|
|
469
|
+
selectLedgerAndConnect(ledgerId: 'hedera' | 'xrpl'): void {
|
|
470
|
+
this.selectedLedger.set(ledgerId);
|
|
471
|
+
// Auto-connect with the selected ledger
|
|
472
|
+
void this.connect();
|
|
473
|
+
}
|
|
474
|
+
|
|
475
|
+
/**
|
|
476
|
+
* Proceed to the next step in the wizard
|
|
477
|
+
*/
|
|
478
|
+
async next(): Promise<void> {
|
|
479
|
+
const currentStep = this.currentStep();
|
|
480
|
+
|
|
481
|
+
if (currentStep === ConnectionStep.NetworkSelection) {
|
|
482
|
+
this.currentStep.set(ConnectionStep.ProtocolSelection);
|
|
483
|
+
} else if (currentStep === ConnectionStep.ProtocolSelection) {
|
|
484
|
+
const protocol = this.selectedProtocol();
|
|
485
|
+
if (protocol === 'hsuite-native') {
|
|
486
|
+
// HSuite Native: Show connection method selection
|
|
487
|
+
this.currentStep.set(ConnectionStep.ConnectionMethodSelection);
|
|
488
|
+
} else {
|
|
489
|
+
// WalletConnect: Show ledger selection
|
|
490
|
+
this.currentStep.set(ConnectionStep.LedgerSelection);
|
|
491
|
+
}
|
|
492
|
+
} else if (currentStep === ConnectionStep.ConnectionMethodSelection) {
|
|
493
|
+
const method = this.selectedConnectionMethod();
|
|
494
|
+
if (method === 'mobile-qr') {
|
|
495
|
+
// Mobile QR: Show QR pairing step
|
|
496
|
+
await this.initiateQrPairing();
|
|
497
|
+
} else {
|
|
498
|
+
// Desktop: Connect directly (SDK auto-selects extension or PWA)
|
|
499
|
+
await this.connect();
|
|
500
|
+
}
|
|
501
|
+
} else if (currentStep === ConnectionStep.LedgerSelection) {
|
|
502
|
+
// Connect with selected ledger
|
|
503
|
+
await this.connect();
|
|
504
|
+
}
|
|
505
|
+
}
|
|
506
|
+
|
|
507
|
+
/**
|
|
508
|
+
* Go back to the previous step
|
|
509
|
+
*/
|
|
510
|
+
back(): void {
|
|
511
|
+
const currentStep = this.currentStep();
|
|
512
|
+
if (currentStep === ConnectionStep.ProtocolSelection) {
|
|
513
|
+
this.currentStep.set(ConnectionStep.NetworkSelection);
|
|
514
|
+
} else if (currentStep === ConnectionStep.ConnectionMethodSelection) {
|
|
515
|
+
this.currentStep.set(ConnectionStep.ProtocolSelection);
|
|
516
|
+
} else if (currentStep === ConnectionStep.LedgerSelection) {
|
|
517
|
+
this.currentStep.set(ConnectionStep.ProtocolSelection);
|
|
518
|
+
} else if (currentStep === ConnectionStep.QrPairing) {
|
|
519
|
+
this.currentStep.set(ConnectionStep.ConnectionMethodSelection);
|
|
520
|
+
this.pairingOffer.set('');
|
|
521
|
+
this.connectionError.set(null);
|
|
522
|
+
} else if (currentStep === ConnectionStep.ConnectionProgress) {
|
|
523
|
+
// Go back to appropriate step based on protocol and method
|
|
524
|
+
const protocol = this.selectedProtocol();
|
|
525
|
+
const method = this.selectedConnectionMethod();
|
|
526
|
+
if (protocol === 'walletconnect') {
|
|
527
|
+
this.currentStep.set(ConnectionStep.LedgerSelection);
|
|
528
|
+
} else if (method === 'mobile-qr') {
|
|
529
|
+
this.currentStep.set(ConnectionStep.QrPairing);
|
|
530
|
+
} else {
|
|
531
|
+
this.currentStep.set(ConnectionStep.ConnectionMethodSelection);
|
|
532
|
+
}
|
|
533
|
+
// Clear error state
|
|
534
|
+
this.connectionError.set(null);
|
|
535
|
+
this.isConnecting.set(false);
|
|
536
|
+
}
|
|
537
|
+
}
|
|
538
|
+
|
|
539
|
+
/**
|
|
540
|
+
* Connect to the selected protocol and ledger
|
|
541
|
+
*/
|
|
542
|
+
private async connect(): Promise<void> {
|
|
543
|
+
this.currentStep.set(ConnectionStep.ConnectionProgress);
|
|
544
|
+
this.isConnecting.set(true);
|
|
545
|
+
this.connectionError.set(null);
|
|
546
|
+
|
|
547
|
+
try {
|
|
548
|
+
const protocol = this.selectedProtocol();
|
|
549
|
+
const network = this.selectedNetwork();
|
|
550
|
+
|
|
551
|
+
if (protocol === 'hsuite-native') {
|
|
552
|
+
// Connect to HSuite Native (multi-chain by default)
|
|
553
|
+
// Use the input walletUrl and pass targetWindow metadata for consistent window naming
|
|
554
|
+
await this.unifiedWalletService.connect('hsuite-native', {
|
|
555
|
+
type: 'hsuite-native',
|
|
556
|
+
appId: 'hsuite-demo',
|
|
557
|
+
appName: this.appName,
|
|
558
|
+
ledgerId: 'multi-chain',
|
|
559
|
+
networkId: network || 'testnet',
|
|
560
|
+
walletUrl: this.walletUrl,
|
|
561
|
+
metadata: {
|
|
562
|
+
targetWindow: 'hsuite-wallet',
|
|
563
|
+
},
|
|
564
|
+
});
|
|
565
|
+
} else if (protocol === 'walletconnect') {
|
|
566
|
+
// Connect to WalletConnect (ledger-specific)
|
|
567
|
+
const ledger = this.selectedLedger();
|
|
568
|
+
if (!ledger) {
|
|
569
|
+
throw new Error('No ledger selected');
|
|
570
|
+
}
|
|
571
|
+
|
|
572
|
+
if (!this.projectId) {
|
|
573
|
+
throw new Error(
|
|
574
|
+
'WalletConnect projectId is required. Get one from https://cloud.walletconnect.com',
|
|
575
|
+
);
|
|
576
|
+
}
|
|
577
|
+
|
|
578
|
+
const config: WalletConnectV2Config = {
|
|
579
|
+
type: 'walletconnect-v2',
|
|
580
|
+
projectId: this.projectId,
|
|
581
|
+
ledgerId: ledger,
|
|
582
|
+
networkId: `${ledger}:${network}`,
|
|
583
|
+
appName: this.appName,
|
|
584
|
+
appDescription: this.appDescription,
|
|
585
|
+
};
|
|
586
|
+
|
|
587
|
+
await this.unifiedWalletService.connect('walletconnect-v2', config);
|
|
588
|
+
}
|
|
589
|
+
|
|
590
|
+
// Success! Emit event and close modal
|
|
591
|
+
this.connected.emit({ protocol, network });
|
|
592
|
+
await this.modalController.dismiss({ connected: true });
|
|
593
|
+
} catch (error) {
|
|
594
|
+
logger.error('Connection failed', {
|
|
595
|
+
error: error instanceof Error ? error.message : String(error),
|
|
596
|
+
});
|
|
597
|
+
this.connectionError.set(
|
|
598
|
+
error instanceof Error ? error.message : 'Connection failed. Please try again.',
|
|
599
|
+
);
|
|
600
|
+
this.isConnecting.set(false);
|
|
601
|
+
// Stay on ConnectionProgress to show the error and "Try Again" button
|
|
602
|
+
// Don't auto-navigate away - let user click "Try Again" which calls back()
|
|
603
|
+
}
|
|
604
|
+
}
|
|
605
|
+
|
|
606
|
+
/**
|
|
607
|
+
* Close the modal without connecting
|
|
608
|
+
*/
|
|
609
|
+
async dismiss(): Promise<void> {
|
|
610
|
+
await this.modalController.dismiss({ connected: false });
|
|
611
|
+
}
|
|
612
|
+
|
|
613
|
+
// ========== QR Pairing Methods ==========
|
|
614
|
+
|
|
615
|
+
/**
|
|
616
|
+
* Initiate QR pairing flow for mobile connection (Nostr-first protocol).
|
|
617
|
+
*
|
|
618
|
+
* Flow:
|
|
619
|
+
* 1. Generate session invite QR code
|
|
620
|
+
* 2. Wait for wallet to scan and connect via Nostr
|
|
621
|
+
* 3. Wait for wallet user to approve session
|
|
622
|
+
* 4. P2P upgrade happens automatically in background
|
|
623
|
+
*/
|
|
624
|
+
private async initiateQrPairing(): Promise<void> {
|
|
625
|
+
this.currentStep.set(ConnectionStep.QrPairing);
|
|
626
|
+
this.isGeneratingOffer.set(true);
|
|
627
|
+
this.connectionError.set(null);
|
|
628
|
+
|
|
629
|
+
try {
|
|
630
|
+
const network = this.selectedNetwork();
|
|
631
|
+
const result = await this.p2pNativeProvider.createPairingOffer({
|
|
632
|
+
type: 'mobile-native',
|
|
633
|
+
appId: 'hsuite-dapp',
|
|
634
|
+
appName: this.appName,
|
|
635
|
+
ledgerId: 'multi-chain',
|
|
636
|
+
networkId: network || 'testnet',
|
|
637
|
+
});
|
|
638
|
+
|
|
639
|
+
this.pairingOffer.set(result.qrData);
|
|
640
|
+
this.isGeneratingOffer.set(false);
|
|
641
|
+
this.isWaitingForWallet.set(true);
|
|
642
|
+
|
|
643
|
+
// Start waiting for wallet to connect and approve
|
|
644
|
+
this.waitForWalletApproval();
|
|
645
|
+
} catch (error) {
|
|
646
|
+
logger.error('Failed to create pairing offer', { error });
|
|
647
|
+
this.connectionError.set(
|
|
648
|
+
error instanceof Error ? error.message : 'Failed to generate QR code',
|
|
649
|
+
);
|
|
650
|
+
this.isGeneratingOffer.set(false);
|
|
651
|
+
}
|
|
652
|
+
}
|
|
653
|
+
|
|
654
|
+
/**
|
|
655
|
+
* Wait for wallet to connect via Nostr and approve the session.
|
|
656
|
+
* This is the new single-QR flow - no answer scanning needed.
|
|
657
|
+
*/
|
|
658
|
+
private async waitForWalletApproval(): Promise<void> {
|
|
659
|
+
try {
|
|
660
|
+
// This blocks until wallet scans QR, connects via Nostr, and user approves
|
|
661
|
+
const session = await this.p2pNativeProvider.waitForSessionApproval();
|
|
662
|
+
|
|
663
|
+
logger.info('Session approved by wallet', {
|
|
664
|
+
sessionId: session?.sessionId,
|
|
665
|
+
accounts: session?.accounts?.length,
|
|
666
|
+
});
|
|
667
|
+
|
|
668
|
+
this.onMobileConnected();
|
|
669
|
+
} catch (error) {
|
|
670
|
+
// Only show error if we're still on the QR pairing step (not cancelled)
|
|
671
|
+
if (this.currentStep() === ConnectionStep.QrPairing) {
|
|
672
|
+
logger.error('Session approval failed', { error });
|
|
673
|
+
this.connectionError.set(
|
|
674
|
+
error instanceof Error ? error.message : 'Session approval failed or rejected',
|
|
675
|
+
);
|
|
676
|
+
}
|
|
677
|
+
this.isWaitingForWallet.set(false);
|
|
678
|
+
this.isWaitingForApproval.set(false);
|
|
679
|
+
}
|
|
680
|
+
}
|
|
681
|
+
|
|
682
|
+
/**
|
|
683
|
+
* Handle QR code expiry
|
|
684
|
+
*/
|
|
685
|
+
onQrExpired(): void {
|
|
686
|
+
logger.debug('QR code expired');
|
|
687
|
+
this.pairingOffer.set('');
|
|
688
|
+
this.isWaitingForWallet.set(false);
|
|
689
|
+
}
|
|
690
|
+
|
|
691
|
+
/**
|
|
692
|
+
* Refresh the QR pairing offer
|
|
693
|
+
*/
|
|
694
|
+
async onQrRefresh(): Promise<void> {
|
|
695
|
+
this.isWaitingForWallet.set(false);
|
|
696
|
+
this.isWaitingForApproval.set(false);
|
|
697
|
+
await this.initiateQrPairing();
|
|
698
|
+
}
|
|
699
|
+
|
|
700
|
+
/**
|
|
701
|
+
* Handle successful mobile connection
|
|
702
|
+
*/
|
|
703
|
+
private onMobileConnected(): void {
|
|
704
|
+
logger.info('Mobile wallet connected');
|
|
705
|
+
this.connected.emit({ protocol: 'mobile-native', method: 'qr' });
|
|
706
|
+
void this.modalController.dismiss({ connected: true });
|
|
707
|
+
}
|
|
708
|
+
|
|
709
|
+
// ========== Platform Detection ==========
|
|
710
|
+
|
|
711
|
+
/**
|
|
712
|
+
* Detect if running on mobile device
|
|
713
|
+
*/
|
|
714
|
+
private detectMobile(): boolean {
|
|
715
|
+
return this.platform.is('mobile') || this.platform.is('android') || this.platform.is('ios');
|
|
716
|
+
}
|
|
717
|
+
|
|
718
|
+
/**
|
|
719
|
+
* Detect if HSuite extension is available.
|
|
720
|
+
* Checks for the flag injected by the extension's content script.
|
|
721
|
+
*/
|
|
722
|
+
private detectExtension(): boolean {
|
|
723
|
+
if (typeof window === 'undefined') return false;
|
|
724
|
+
// Check for HSuite extension marker (injected by extension's inject-flags.ts)
|
|
725
|
+
return (
|
|
726
|
+
(window as unknown as { __HSUITE_WALLET_EXTENSION__?: boolean })
|
|
727
|
+
.__HSUITE_WALLET_EXTENSION__ === true
|
|
728
|
+
);
|
|
729
|
+
}
|
|
730
|
+
}
|