1
1
import { nopLogger } from '@chorus-one/utils'
2
- import type { Logger } from '@chorus-one/utils'
2
+ import type { Logger , sortObjectByKeys } from '@chorus-one/utils'
3
3
import type { LedgerCosmosSignerConfig } from './types'
4
4
import type { Signature , SignerData } from '@chorus-one/signer'
5
- import Cosmos from '@ledgerhq/hw-app-cosmos'
5
+ import { secp256k1 } from '@noble/curves/secp256k1'
6
+ import CosmosApp from '@zondax/ledger-cosmos-js'
6
7
import Transport from '@ledgerhq/hw-transport'
7
8
8
9
/**
@@ -16,7 +17,7 @@ export class LedgerCosmosSigner {
16
17
private readonly config : LedgerCosmosSignerConfig
17
18
private readonly transport : Transport
18
19
private accounts : Map < string , { hdPath : string ; publicKey : Uint8Array } >
19
- private app ?: Cosmos
20
+ private app ?: CosmosApp
20
21
private logger : Logger
21
22
22
23
/**
@@ -43,15 +44,15 @@ export class LedgerCosmosSigner {
43
44
* @returns A promise that resolves once the initialization is complete.
44
45
*/
45
46
async init ( ) : Promise < void > {
46
- const app = new Cosmos ( this . transport )
47
+ const app = new CosmosApp ( this . transport )
47
48
this . app = app
48
49
49
50
this . config . accounts . forEach ( async ( account : { hdPath : string } ) => {
50
- const response = await app . getAddress ( account . hdPath , this . config . bechPrefix )
51
+ const response = await app . getAddressAndPubKey ( account . hdPath , this . config . bechPrefix )
51
52
52
- this . accounts . set ( response . address . toLowerCase ( ) , {
53
+ this . accounts . set ( response . bech32_address . toLowerCase ( ) , {
53
54
hdPath : account . hdPath ,
54
- publicKey : Buffer . from ( response . publicKey , 'hex' )
55
+ publicKey : response . compressed_pk
55
56
} )
56
57
} )
57
58
}
@@ -75,16 +76,23 @@ export class LedgerCosmosSigner {
75
76
}
76
77
77
78
const account = this . getAccount ( signerAddress )
78
- const { signature, return_code } = await this . app . sign ( account . hdPath , signerData . message )
79
79
80
- if ( signature === null ) {
81
- throw new Error ( `failed to sign message: ${ return_code } ` )
80
+ const { signature } = await this . app . sign (
81
+ account . hdPath ,
82
+ Buffer . from ( JSON . stringify ( sortObjectByKeys ( signerData . data . signDoc ) ) , 'utf-8' ) ,
83
+ this . config . bechPrefix ,
84
+ 0 // 0 for JSON, 1 for TEXTUAL
85
+ )
86
+
87
+ if ( signature . length === 0 ) {
88
+ throw new Error ( `failed to sign message` )
82
89
}
83
90
91
+ const secpsig = secp256k1 . Signature . fromDER ( signature )
84
92
const sig = {
85
- fullSig : Buffer . from ( signature ) . toString ( 'hex' ) ,
86
- r : Buffer . from ( signature . subarray ( 0 , 32 ) ) . toString ( 'hex' ) ,
87
- s : Buffer . from ( signature . subarray ( 32 , 64 ) ) . toString ( 'hex' ) ,
93
+ fullSig : secpsig . toCompactHex ( ) ,
94
+ r : Buffer . from ( secpsig . toCompactRawBytes ( ) . subarray ( 0 , 32 ) ) . toString ( 'hex' ) ,
95
+ s : Buffer . from ( secpsig . toCompactRawBytes ( ) . subarray ( 32 , 64 ) ) . toString ( 'hex' ) ,
88
96
v : 0
89
97
}
90
98
0 commit comments