@@ -3,7 +3,8 @@ import type {
3
3
Account ,
4
4
Asset ,
5
5
Chain ,
6
- WalletInit
6
+ WalletInit ,
7
+ EIP1193Provider
7
8
} from '@web3-onboard/common'
8
9
9
10
import type { StaticJsonRpcProvider } from '@ethersproject/providers'
@@ -239,161 +240,193 @@ function keepkey(): WalletInit {
239
240
return accounts
240
241
}
241
242
242
- const provider = createEIP1193Provider (
243
- { } ,
244
- {
245
- eth_requestAccounts : async ( ) => {
246
- if ( keepKeyWallet && typeof keepKeyWallet . cancel === 'function' ) {
247
- // cancel any current actions on device
248
- keepKeyWallet . cancel ( )
249
- }
243
+ const request : EIP1193Provider [ 'request' ] = async ( {
244
+ method,
245
+ params
246
+ } ) => {
247
+ const response = await fetch ( currentChain . rpcUrl , {
248
+ method : 'POST' ,
249
+ body : JSON . stringify ( {
250
+ id : '42' ,
251
+ method,
252
+ params
253
+ } )
254
+ } ) . then ( res => res . json ( ) )
250
255
251
- try {
252
- keepKeyWallet =
253
- ( await keepKeyAdapter . pairDevice ( ) ) as KeepKeyHDWallet
254
- } catch ( error ) {
255
- const { name } = error as { name : string }
256
- // This error indicates that the keepkey is paired with another app
257
- if ( name === HDWalletErrorType . ConflictingApp ) {
258
- throw new ProviderRpcError ( {
259
- code : 4001 ,
260
- message : errorMessages [ ERROR_BUSY ]
261
- } )
262
-
263
- // This error indicates that for some reason we can't claim the usb device
264
- } else if ( name === HDWalletErrorType . WebUSBCouldNotPair ) {
265
- throw new ProviderRpcError ( {
266
- code : 4001 ,
267
- message : errorMessages [ ERROR_PAIRING ]
268
- } )
269
- }
270
- }
256
+ if ( response . result ) {
257
+ return response . result
258
+ } else {
259
+ throw response . error
260
+ }
261
+ }
271
262
272
- // Triggers the account select modal if no accounts have been selected
273
- const accounts = await getAccounts ( )
263
+ const keepKeyProvider = { request }
274
264
275
- if ( ! accounts || ! Array . isArray ( accounts ) ) {
276
- throw new Error ( 'No accounts were returned from Keepkey device' )
277
- }
278
- if ( ! accounts . length ) {
265
+ const provider = createEIP1193Provider ( keepKeyProvider , {
266
+ eth_requestAccounts : async ( ) => {
267
+ if ( keepKeyWallet && typeof keepKeyWallet . cancel === 'function' ) {
268
+ // cancel any current actions on device
269
+ keepKeyWallet . cancel ( )
270
+ }
271
+
272
+ try {
273
+ keepKeyWallet =
274
+ ( await keepKeyAdapter . pairDevice ( ) ) as KeepKeyHDWallet
275
+ } catch ( error ) {
276
+ const { name } = error as { name : string }
277
+ // This error indicates that the keepkey is paired with another app
278
+ if ( name === HDWalletErrorType . ConflictingApp ) {
279
279
throw new ProviderRpcError ( {
280
280
code : 4001 ,
281
- message : 'User rejected the request.'
281
+ message : errorMessages [ ERROR_BUSY ]
282
282
} )
283
- }
284
- if ( ! accounts [ 0 ] . hasOwnProperty ( 'address' ) ) {
285
- throw new Error (
286
- 'The account returned does not have a required address field'
287
- )
288
- }
289
283
290
- return [ accounts [ 0 ] . address ]
291
- } ,
292
- eth_selectAccounts : async ( ) => {
293
- const accounts = await getAccounts ( )
294
- return accounts . map ( ( { address } ) => address )
295
- } ,
296
- eth_accounts : async ( ) => {
297
- if ( ! accounts || ! Array . isArray ( accounts ) ) {
298
- throw new Error ( 'No accounts were returned from Keepkey device' )
284
+ // This error indicates that for some reason we can't claim the usb device
285
+ } else if ( name === HDWalletErrorType . WebUSBCouldNotPair ) {
286
+ throw new ProviderRpcError ( {
287
+ code : 4001 ,
288
+ message : errorMessages [ ERROR_PAIRING ]
289
+ } )
299
290
}
300
- return accounts [ 0 ] . hasOwnProperty ( 'address' )
301
- ? [ accounts [ 0 ] . address ]
302
- : [ ]
303
- } ,
304
- eth_chainId : async ( ) => {
305
- return currentChain && currentChain . id != undefined
306
- ? currentChain . id
307
- : '0x0'
308
- } ,
309
- eth_signTransaction : async ( { params : [ transactionObject ] } ) => {
310
- if ( ! accounts || ! Array . isArray ( accounts ) || ! accounts . length )
311
- throw new Error (
312
- 'No account selected. Must call eth_requestAccounts first.'
313
- )
314
-
315
- const account =
316
- ! transactionObject || ! transactionObject . hasOwnProperty ( 'from' )
317
- ? accounts [ 0 ]
318
- : accounts . find (
319
- account => account . address === transactionObject . from
320
- )
321
-
322
- const { derivationPath } = account || accounts [ 0 ]
323
- const addressNList = bip32ToAddressNList ( derivationPath )
324
-
325
- const {
326
- nonce,
327
- gasPrice,
328
- gas,
329
- gasLimit,
330
- to,
331
- value,
332
- data,
333
- maxFeePerGas,
334
- maxPriorityFeePerGas
335
- } = transactionObject
336
-
337
- const { serialized } = await keepKeyWallet . ethSignTx ( {
338
- addressNList,
339
- nonce : nonce || '0x0' ,
340
- gasPrice,
341
- gasLimit : gasLimit || gas || '0x5208' ,
342
- to,
343
- value : value || '0x0' ,
344
- data : data || '' ,
345
- maxFeePerGas,
346
- maxPriorityFeePerGas,
347
- chainId : parseInt ( currentChain . id )
291
+ }
292
+
293
+ // Triggers the account select modal if no accounts have been selected
294
+ const accounts = await getAccounts ( )
295
+
296
+ if ( ! accounts || ! Array . isArray ( accounts ) ) {
297
+ throw new Error ( 'No accounts were returned from Keepkey device' )
298
+ }
299
+ if ( ! accounts . length ) {
300
+ throw new ProviderRpcError ( {
301
+ code : 4001 ,
302
+ message : 'User rejected the request.'
348
303
} )
304
+ }
305
+ if ( ! accounts [ 0 ] . hasOwnProperty ( 'address' ) ) {
306
+ throw new Error (
307
+ 'The account returned does not have a required address field'
308
+ )
309
+ }
349
310
350
- return serialized
351
- } ,
352
- eth_sign : async ( { params : [ address , message ] } ) => {
353
- if (
354
- ! accounts ||
355
- ! Array . isArray ( accounts ) ||
356
- ! ( accounts . length && accounts . length > 0 )
311
+ return [ accounts [ 0 ] . address ]
312
+ } ,
313
+ eth_selectAccounts : async ( ) => {
314
+ const accounts = await getAccounts ( )
315
+ return accounts . map ( ( { address } ) => address )
316
+ } ,
317
+ eth_accounts : async ( ) => {
318
+ if ( ! accounts || ! Array . isArray ( accounts ) ) {
319
+ throw new Error ( 'No accounts were returned from Keepkey device' )
320
+ }
321
+ return accounts [ 0 ] . hasOwnProperty ( 'address' )
322
+ ? [ accounts [ 0 ] . address ]
323
+ : [ ]
324
+ } ,
325
+ eth_chainId : async ( ) => {
326
+ return currentChain && currentChain . id != undefined
327
+ ? currentChain . id
328
+ : '0x0'
329
+ } ,
330
+ eth_signTransaction : async ( { params : [ transactionObject ] } ) => {
331
+ if ( ! accounts || ! Array . isArray ( accounts ) || ! accounts . length )
332
+ throw new Error (
333
+ 'No account selected. Must call eth_requestAccounts first.'
357
334
)
358
- throw new Error (
359
- 'No account selected. Must call eth_requestAccounts first.'
360
- )
361
335
362
- const account =
363
- accounts . find ( account => account . address === address ) ||
364
- accounts [ 0 ]
336
+ const account =
337
+ ! transactionObject || ! transactionObject . hasOwnProperty ( 'from' )
338
+ ? accounts [ 0 ]
339
+ : accounts . find (
340
+ account => account . address === transactionObject . from
341
+ )
342
+
343
+ const { derivationPath } = account || accounts [ 0 ]
344
+ const addressNList = bip32ToAddressNList ( derivationPath )
345
+
346
+ const {
347
+ nonce,
348
+ gasPrice,
349
+ gas,
350
+ gasLimit,
351
+ to,
352
+ value,
353
+ data,
354
+ maxFeePerGas,
355
+ maxPriorityFeePerGas
356
+ } = transactionObject
357
+
358
+ const { serialized } = await keepKeyWallet . ethSignTx ( {
359
+ addressNList,
360
+ nonce : nonce || '0x0' ,
361
+ gasPrice,
362
+ gasLimit : gasLimit || gas || '0x5208' ,
363
+ to,
364
+ value : value || '0x0' ,
365
+ data : data || '' ,
366
+ maxFeePerGas,
367
+ maxPriorityFeePerGas,
368
+ chainId : parseInt ( currentChain . id )
369
+ } )
365
370
366
- const { derivationPath } = account
367
- const accountIdx = getAccountIdx ( derivationPath )
368
- const { addressNList } = getPaths ( accountIdx )
369
-
370
- const { signature } = await keepKeyWallet . ethSignMessage ( {
371
- addressNList,
372
- message :
373
- message . slice ( 0 , 2 ) === '0x'
374
- ? // @ts -ignore - commonjs weirdness
375
- ( ethUtil . default || ethUtil )
376
- . toBuffer ( message )
377
- . toString ( 'utf8' )
378
- : message
379
- } )
371
+ return serialized
372
+ } ,
373
+ eth_sendTransaction : async ( { baseRequest, params } ) => {
374
+ const signedTx = await provider . request ( {
375
+ method : 'eth_signTransaction' ,
376
+ params
377
+ } )
380
378
381
- return signature
382
- } ,
383
- eth_signTypedData : null ,
384
- wallet_switchEthereumChain : async ( { params : [ { chainId } ] } ) => {
385
- currentChain =
386
- chains . find ( ( { id } ) => id === chainId ) || currentChain
379
+ const transactionHash = await baseRequest ( {
380
+ method : 'eth_sendRawTransaction' ,
381
+ params : [ signedTx ]
382
+ } )
387
383
388
- if ( ! currentChain )
389
- throw new Error ( 'chain must be set before switching' )
384
+ return transactionHash as string
385
+ } ,
386
+ eth_sign : async ( { params : [ address , message ] } ) => {
387
+ if (
388
+ ! accounts ||
389
+ ! Array . isArray ( accounts ) ||
390
+ ! ( accounts . length && accounts . length > 0 )
391
+ )
392
+ throw new Error (
393
+ 'No account selected. Must call eth_requestAccounts first.'
394
+ )
390
395
391
- eventEmitter . emit ( 'chainChanged' , currentChain . id )
392
- return null
393
- } ,
394
- wallet_addEthereumChain : null
395
- }
396
- )
396
+ const account =
397
+ accounts . find ( account => account . address === address ) ||
398
+ accounts [ 0 ]
399
+
400
+ const { derivationPath } = account
401
+ const accountIdx = getAccountIdx ( derivationPath )
402
+ const { addressNList } = getPaths ( accountIdx )
403
+
404
+ const { signature } = await keepKeyWallet . ethSignMessage ( {
405
+ addressNList,
406
+ message :
407
+ message . slice ( 0 , 2 ) === '0x'
408
+ ? // @ts -ignore - commonjs weirdness
409
+ ( ethUtil . default || ethUtil )
410
+ . toBuffer ( message )
411
+ . toString ( 'utf8' )
412
+ : message
413
+ } )
414
+
415
+ return signature
416
+ } ,
417
+ eth_signTypedData : null ,
418
+ wallet_switchEthereumChain : async ( { params : [ { chainId } ] } ) => {
419
+ currentChain =
420
+ chains . find ( ( { id } ) => id === chainId ) || currentChain
421
+
422
+ if ( ! currentChain )
423
+ throw new Error ( 'chain must be set before switching' )
424
+
425
+ eventEmitter . emit ( 'chainChanged' , currentChain . id )
426
+ return null
427
+ } ,
428
+ wallet_addEthereumChain : null
429
+ } )
397
430
398
431
provider . on = eventEmitter . on . bind ( eventEmitter )
399
432
0 commit comments