1
1
import { WalletCheckModal , StateAndHelpers } from '../../interfaces'
2
+ import { usbIcon } from './icons'
2
3
3
4
interface DerivationPaths {
4
5
[ key : string ] : Array < { path ?: string ; label : string } >
5
6
}
6
7
7
8
const derivationPaths : DerivationPaths = {
8
9
Ledger : [
9
- { path : `m/44'/60'` , label : 'Ethereum' } ,
10
- { path : `m/44'/60'/0' ` , label : 'Ethereum Legacy ' }
10
+ { path : `m/44'/60'/0' ` , label : 'Ethereum' } ,
11
+ { path : `m/44'/60'` , label : 'Ethereum Ledger Live ' }
11
12
] ,
12
13
Trezor : [ { path : `m/44'/60'/0'/0` , label : 'Ethereum' } ]
13
14
}
14
15
15
16
const styles = `
16
17
display: flex;
17
18
flex-direction: column;
19
+ align-items: center;
20
+ justify-content: center;
18
21
`
19
22
20
- // color: #4a90e2;
21
-
22
23
const baseStyles = `
23
24
background: inherit;
24
25
font-size: 0.889em;
@@ -44,26 +45,43 @@ const selectedStyles = `
44
45
border: 1px solid #4a90e2;
45
46
`
46
47
47
- const customInputHtmlString = `
48
- <input
49
- id="custom-derivation-input"
50
- style="${ baseStyles + selectedStyles } "
51
- type="text"
52
- placeholder="custom derivation path"
53
- onchange="window.handleCustomInput(this.value)" />
48
+ const errorStyles = `
49
+ border: 1px solid #e2504a;
54
50
`
55
51
56
- function derivationPath ( ) {
52
+ const errorMsgStyles = `
53
+ font-size: 0.889em;
54
+ font-family: inherit;
55
+ color: #e2504a;
56
+ `
57
+
58
+ const customInputHtmlString = ( error ?: string ) => {
59
+ return `
60
+ <input
61
+ id="custom-derivation-input"
62
+ style="${ baseStyles + selectedStyles + ( error ? errorStyles : '' ) } "
63
+ type="text"
64
+ placeholder="custom derivation path"
65
+ onchange="window.handleCustomInput(this.value)" />
66
+ `
67
+ }
68
+
69
+ function derivationPath ( options : {
70
+ heading : string
71
+ description : string
72
+ icon : string
73
+ } ) {
74
+ const { heading, description, icon } = options
75
+
57
76
let state = {
58
77
completed : false ,
59
78
showCustomInput : false ,
60
- dPath : ''
79
+ dPath : '' ,
80
+ loading : false ,
81
+ error : ''
61
82
}
62
83
63
- function derivationSelectHtmlString (
64
- walletName : string ,
65
- showCustomInput : boolean
66
- ) {
84
+ function derivationSelectHtmlString ( walletName : string ) {
67
85
return `
68
86
<div id="derivation-select" style="${ styles } ">
69
87
${ derivationPaths [ walletName ]
@@ -81,11 +99,22 @@ function derivationPath() {
81
99
} )
82
100
. join ( ' ' ) }
83
101
${
84
- showCustomInput
85
- ? customInputHtmlString
102
+ state . showCustomInput
103
+ ? customInputHtmlString ( state . error )
86
104
: `<button style="${ baseStyles +
87
105
buttonStyles } " onclick="window.handleDerivationClick(this)" data-path="custom">Custom Path</button>`
88
106
}
107
+ ${
108
+ state . loading
109
+ ? `<div class="bn-onboard-custom bn-onboard-loading" style="margin-top: 1rem">
110
+ <div class="bn-onboard-loading-first"></div>
111
+ <div class="bn-onboard-loading-second"></div>
112
+ <div class="bn-onboard-loading-third"</div>
113
+ </div>`
114
+ : state . error
115
+ ? `<span style="${ errorMsgStyles } ">${ state . error } </span>`
116
+ : ''
117
+ }
89
118
</div>
90
119
`
91
120
}
@@ -94,20 +123,23 @@ function derivationPath() {
94
123
state . completed = false
95
124
state . showCustomInput = false
96
125
state . dPath = ''
126
+ state . loading = false
127
+ state . error = ''
97
128
}
98
129
99
130
function checkModule (
100
131
stateAndHelpers : StateAndHelpers
101
132
) : WalletCheckModal | undefined {
102
- const { wallet, address } = stateAndHelpers
133
+ const { wallet } = stateAndHelpers
103
134
104
- if ( ! address && wallet && wallet . type === 'hardware' && ! state . completed ) {
135
+ if ( wallet && wallet . type === 'hardware' && ! state . completed ) {
105
136
const handleCustomInput = ( ) => {
106
137
const input = < HTMLInputElement > (
107
138
document . getElementById ( 'custom-derivation-input' )
108
139
)
109
140
110
141
state . dPath = input && input . value
142
+ state . error = ''
111
143
}
112
144
113
145
const handleDerivationClick = ( button : any ) => {
@@ -121,6 +153,7 @@ function derivationPath() {
121
153
input && input . focus ( )
122
154
} , 100 )
123
155
} else {
156
+ state . error = ''
124
157
state . showCustomInput = false
125
158
state . dPath = selectedPath
126
159
}
@@ -134,29 +167,42 @@ function derivationPath() {
134
167
; ( window as any ) . handleDerivationClick = handleDerivationClick
135
168
136
169
return {
137
- heading : 'Hardware Wallet Connect' ,
138
- description : `Please select a derivation path to connect your ${ wallet . name } accounts, or select custom to input a custom path:` ,
170
+ heading : heading || 'Hardware Wallet Connect' ,
171
+ description :
172
+ description ||
173
+ `Please select a derivation path to connect your ${ wallet . name } accounts, or select custom to input a custom path:` ,
139
174
eventCode : 'derivationPath' ,
140
- html : derivationSelectHtmlString ( wallet . name , state . showCustomInput ) ,
175
+ html : derivationSelectHtmlString ( wallet . name ) ,
141
176
button : {
142
177
text : 'Connect' ,
143
- onclick : ( ) => {
144
- wallet . provider . setPath (
145
- state . dPath || derivationPaths [ wallet . name ] [ 0 ] . path
178
+ onclick : async ( ) => {
179
+ state . loading = true
180
+ const path = state . dPath || derivationPaths [ wallet . name ] [ 0 ] . path
181
+ const validPath = await wallet . provider . setPath (
182
+ path ,
183
+ state . showCustomInput
146
184
)
185
+
186
+ if ( ! validPath ) {
187
+ state . error = `${ path } is not a valid derivation path`
188
+ state . loading = false
189
+ return
190
+ }
191
+
192
+ state . error = ''
193
+
147
194
wallet . connect &&
148
195
wallet . connect ( ) . then ( ( ) => {
149
196
// @TODO add path to local store
150
197
151
198
deleteWindowProperties ( )
199
+ state . loading = false
152
200
state . completed = true
153
201
} )
154
202
}
155
203
} ,
156
204
157
- icon : `
158
- <svg height="14" viewBox="0 0 18 14" width="18" xmlns="http://www.w3.org/2000/svg"><g fill="currentColor"><path d="m10.29375 4.05351563c0-.04921875 0-.09140625 0-.13007813 0-1.0546875 0-2.109375 0-3.1640625 0-.43945312.3480469-.76992188.7804688-.7453125.2003906.01054688.3585937.10546875.4992187.24609375.5800781.58359375 1.1566406 1.16367188 1.7367187 1.74023438 1.4695313 1.46953125 2.9390625 2.93906249 4.4050782 4.40859375.1335937.13359375.2425781.27421875.2707031.46757812.0351562.20742188-.0246094.421875-.1652344.58007813-.0246094.028125-.0492187.05273437-.0738281.08085937-2.0601563 2.06367188-4.1203125 4.1238281-6.1804688 6.1875-.2109375.2109375-.4570312.3023438-.7453125.2179688-.2707031-.0808594-.4464843-.2707032-.5132812-.5484375-.0140625-.0738282-.0175781-.1441407-.0140625-.2179688 0-1.0335937 0-2.0707031 0-3.1042969 0-.0386719 0-.08085935 0-.13359372h-5.06953125c-.49570313 0-.80507813-.309375-.80507813-.80859375 0-1.42382813 0-2.84414063 0-4.26796875 0-.49570313.30585938-.8015625.8015625-.8015625h4.93593748z"/><path d="m5.69882812 13.978125h-4.01132812c-.928125 0-1.6875-.8753906-1.6875-1.9511719v-10.06171872c0-1.07578125.75585938-1.95117188 1.6875-1.95117188h4.01132812c.34101563 0 .61523438.31992188.61523438.71015625 0 .39023438-.27421875.71015625-.61523438.71015625h-4.01132812c-.253125 0-.45703125.23554688-.45703125.52734375v10.06171875c0 .2917969.20390625.5273437.45703125.5273437h4.01132812c.34101563 0 .61523438.3199219.61523438.7101563s-.27773438.7171875-.61523438.7171875z"/></g></svg>
159
- `
205
+ icon : icon || usbIcon
160
206
}
161
207
}
162
208
}
0 commit comments