1- import React , { useCallback , useEffect , useState } from 'react'
1+ import React , { useCallback , useState } from 'react'
22import { useRouter } from 'expo-router'
33import { Alert } from 'react-native'
4- import { useTheme , View } from '@avalabs/k2-alpine'
5- import Animated , { useAnimatedStyle , withTiming } from 'react-native-reanimated'
64import { ScrollScreen } from 'common/components/ScrollScreen'
5+ import { ProgressDots } from 'common/components/ProgressDots'
76import { LedgerAppConnection } from 'new/features/ledger/components/LedgerAppConnection'
87import { useLedgerSetupContext } from 'new/features/ledger/contexts/LedgerSetupContext'
9- import { LedgerDerivationPathType } from 'services/ledger/types'
10-
11- // Animated dot component - moved outside to prevent recreation on every render
12- const AnimatedDot = ( {
13- isActive,
14- dotSize,
15- colors
16- } : {
17- isActive : boolean
18- dotSize : number
19- colors : Record < string , string >
20- } ) : JSX . Element => {
21- const animatedStyle = useAnimatedStyle ( ( ) => {
22- return {
23- width : withTiming ( isActive ? dotSize * 2 : dotSize , { duration : 200 } ) ,
24- opacity : withTiming ( isActive ? 1 : 0.4 , { duration : 200 } )
25- }
26- } )
27-
28- return (
29- < Animated . View
30- style = { [
31- {
32- height : dotSize ,
33- borderRadius : dotSize / 2 ,
34- backgroundColor : colors . $textPrimary
35- } ,
36- animatedStyle
37- ] }
38- />
39- )
40- }
41-
42- // Header-compatible progress dots using k2-alpine components
43- const HeaderProgressDots = ( {
44- totalSteps,
45- currentStep
46- } : {
47- totalSteps : number
48- currentStep : number
49- } ) : JSX . Element => {
50- const {
51- theme : { colors }
52- } = useTheme ( )
53- const dotSize = 6
54- const gap = 6
55-
56- return (
57- < View
58- style = { {
59- flexDirection : 'row' ,
60- alignItems : 'center' ,
61- gap,
62- justifyContent : 'center'
63- } } >
64- { Array . from ( { length : totalSteps } ) . map ( ( _ , index ) => (
65- < AnimatedDot
66- key = { index }
67- isActive = { index === currentStep }
68- dotSize = { dotSize }
69- colors = { colors }
70- />
71- ) ) }
72- </ View >
73- )
74- }
758
769export default function AppConnectionScreen ( ) : JSX . Element {
7710 const { push, back } = useRouter ( )
@@ -82,69 +15,62 @@ export default function AppConnectionScreen(): JSX.Element {
8215 connectedDeviceId,
8316 connectedDeviceName,
8417 selectedDerivationPath,
85- setSelectedDerivationPath,
8618 resetSetup,
8719 disconnectDevice,
8820 createLedgerWallet
8921 } = useLedgerSetupContext ( )
9022
91- // Set up default values for the Ledger setup
92- useEffect ( ( ) => {
93- // Set default derivation path if not set
94- if ( ! selectedDerivationPath ) {
95- setSelectedDerivationPath ( LedgerDerivationPathType . BIP44 )
96- }
97- } , [ selectedDerivationPath , setSelectedDerivationPath ] )
98-
99- const handleComplete = useCallback ( async ( keys : {
100- solanaKeys : Array < { key : string ; derivationPath : string ; curve : string } >
101- avalancheKeys : { evm : string ; avalanche : string ; pvm : string } | null
102- bitcoinAddress : string
103- xpAddress : string
104- } ) => {
105- // If wallet hasn't been created yet, create it now
106- if (
107- keys . avalancheKeys &&
108- connectedDeviceId &&
109- selectedDerivationPath &&
110- ! isCreatingWallet
111- ) {
112- setIsCreatingWallet ( true )
23+ const handleComplete = useCallback (
24+ async ( keys : {
25+ solanaKeys : Array < { key : string ; derivationPath : string ; curve : string } >
26+ avalancheKeys : { evm : string ; avalanche : string ; pvm : string } | null
27+ bitcoinAddress : string
28+ xpAddress : string
29+ } ) => {
30+ // If wallet hasn't been created yet, create it now
31+ if (
32+ keys . avalancheKeys &&
33+ connectedDeviceId &&
34+ selectedDerivationPath &&
35+ ! isCreatingWallet
36+ ) {
37+ setIsCreatingWallet ( true )
11338
114- try {
115- await createLedgerWallet ( {
116- deviceId : connectedDeviceId ,
117- deviceName : connectedDeviceName ,
118- derivationPathType : selectedDerivationPath ,
119- // Pass the keys directly to the wallet creation
120- avalancheKeys : keys . avalancheKeys ,
121- solanaKeys : keys . solanaKeys
122- } )
39+ try {
40+ await createLedgerWallet ( {
41+ deviceId : connectedDeviceId ,
42+ deviceName : connectedDeviceName ,
43+ derivationPathType : selectedDerivationPath ,
44+ avalancheKeys : keys . avalancheKeys ,
45+ solanaKeys : keys . solanaKeys
46+ } )
12347
48+ // @ts -ignore TODO: make routes typesafe
49+ push ( '/accountSettings/ledger/complete' )
50+ } catch ( error ) {
51+ Alert . alert (
52+ 'Wallet Creation Failed' ,
53+ error instanceof Error
54+ ? error . message
55+ : 'Failed to create Ledger wallet. Please try again.' ,
56+ [ { text : 'OK' } ]
57+ )
58+ setIsCreatingWallet ( false )
59+ }
60+ } else {
12461 // @ts -ignore TODO: make routes typesafe
12562 push ( '/accountSettings/ledger/complete' )
126- } catch ( error ) {
127- Alert . alert (
128- 'Wallet Creation Failed' ,
129- error instanceof Error
130- ? error . message
131- : 'Failed to create Ledger wallet. Please try again.' ,
132- [ { text : 'OK' } ]
133- )
134- setIsCreatingWallet ( false )
13563 }
136- } else {
137- // @ts -ignore TODO: make routes typesafe
138- push ( '/accountSettings/ledger/complete' )
139- }
140- } , [
141- connectedDeviceId ,
142- connectedDeviceName ,
143- selectedDerivationPath ,
144- createLedgerWallet ,
145- push ,
146- isCreatingWallet
147- ] )
64+ } ,
65+ [
66+ connectedDeviceId ,
67+ connectedDeviceName ,
68+ selectedDerivationPath ,
69+ createLedgerWallet ,
70+ push ,
71+ isCreatingWallet
72+ ]
73+ )
14874
14975 const handleCancel = useCallback ( async ( ) => {
15076 await disconnectDevice ( )
@@ -153,14 +79,14 @@ export default function AppConnectionScreen(): JSX.Element {
15379 } , [ disconnectDevice , resetSetup , back ] )
15480
15581 const renderHeaderCenterComponent = useCallback ( ( ) => {
156- return < HeaderProgressDots totalSteps = { 3 } currentStep = { currentStep } />
82+ return < ProgressDots totalSteps = { 3 } currentStep = { currentStep } />
15783 } , [ currentStep ] )
15884
15985 return (
16086 < ScrollScreen
16187 renderHeaderCenterComponent = { renderHeaderCenterComponent }
162- showNavigationHeaderTitle = { false } // Hide navigation title since we have progress dots
163- hasParent = { true } // Modal screens need hasParent={true}
88+ showNavigationHeaderTitle = { false }
89+ hasParent = { true }
16490 isModal = { true }
16591 scrollEnabled = { false }
16692 contentContainerStyle = { { flex : 1 } } >
0 commit comments