11import { AccountData , DirectSignResponse , OfflineDirectSigner } from '@cosmjs/proto-signing' ;
22
33import { SignDoc } from '../src/codec/cosmos/tx/v1beta1/tx' ;
4- import { LumWallet , LumWalletFactory , LumUtils , LumConstants , LumMessages } from '../src' ;
5- import { encodeSecp256k1Signature } from '@cosmjs/amino' ;
4+ import { LumWallet , LumWalletFactory , LumUtils , LumConstants , LumMessages , LumRegistry , LumAminoRegistry } from '../src' ;
5+ import { AminoSignResponse , encodeSecp256k1Signature , OfflineAminoSigner , StdSignDoc } from '@cosmjs/amino' ;
6+ import { SignMode } from '../src/codec/cosmos/tx/signing/v1beta1/signing' ;
67
7- class FakeOfflineSigner implements OfflineDirectSigner {
8+ class FakeOfflineDirectSigner implements OfflineDirectSigner {
89 private readonly privateKey : Uint8Array ;
910
1011 constructor ( privateKey : Uint8Array ) {
@@ -35,6 +36,48 @@ class FakeOfflineSigner implements OfflineDirectSigner {
3536 } ;
3637}
3738
39+ class FakeOfflineAminoSigner implements OfflineAminoSigner {
40+ private readonly privateKey : Uint8Array ;
41+
42+ constructor ( privateKey : Uint8Array ) {
43+ this . privateKey = privateKey ;
44+ }
45+
46+ getAccounts = async ( ) : Promise < AccountData [ ] > => {
47+ const publicKey = await LumUtils . getPublicKeyFromPrivateKey ( this . privateKey ) ;
48+ return [
49+ {
50+ pubkey : publicKey ,
51+ address : LumUtils . getAddressFromPublicKey ( publicKey ) ,
52+ algo : 'secp256k1' ,
53+ } ,
54+ ] ;
55+ } ;
56+
57+ signAmino = async ( signerAddress : string , stdSignDoc : StdSignDoc ) : Promise < AminoSignResponse > => {
58+ const publicKey = await LumUtils . getPublicKeyFromPrivateKey ( this . privateKey ) ;
59+ const signDoc = LumUtils . generateSignDoc (
60+ {
61+ chainId : stdSignDoc . chain_id ,
62+ fee : stdSignDoc . fee ,
63+ memo : stdSignDoc . memo ,
64+ messages : stdSignDoc . msgs . map ( ( aminoMsg ) => LumAminoRegistry . fromAmino ( aminoMsg ) ) ,
65+ signers : [ { accountNumber : parseInt ( stdSignDoc . account_number ) , sequence : parseInt ( stdSignDoc . sequence ) , publicKey : publicKey } ] ,
66+ } ,
67+ 0 ,
68+ SignMode . SIGN_MODE_DIRECT , // Simulated to enable signature comparison during tests
69+ ) ;
70+ const signBytes = LumUtils . generateSignDocBytes ( signDoc ) ;
71+ const hashedMessage = LumUtils . sha256 ( signBytes ) ;
72+ const signature = await LumUtils . generateSignature ( hashedMessage , this . privateKey ) ;
73+ const stdSig = encodeSecp256k1Signature ( publicKey , signature ) ;
74+ return {
75+ signed : stdSignDoc ,
76+ signature : stdSig ,
77+ } ;
78+ } ;
79+ }
80+
3881describe ( 'LumWallet' , ( ) => {
3982 it ( 'Should be identical from mnemonic, privatekey and keystore recovery' , async ( ) => {
4083 const mnemonic = 'surround miss nominee dream gap cross assault thank captain prosper drop duty group candy wealth weather scale put' ;
@@ -45,7 +88,8 @@ describe('LumWallet', () => {
4588 const w1 = await LumWalletFactory . fromMnemonic ( mnemonic , `m/44'/837'/0'/0/0` ) ;
4689 const w2 = await LumWalletFactory . fromPrivateKey ( LumUtils . keyFromHex ( privateKey ) ) ;
4790 const w3 = await LumWalletFactory . fromKeyStore ( keystore , 'lumiere' ) ;
48- const w4 = await LumWalletFactory . fromOfflineSigner ( new FakeOfflineSigner ( LumUtils . keyFromHex ( privateKey ) ) ) ;
91+ const w4 = await LumWalletFactory . fromOfflineSigner ( new FakeOfflineDirectSigner ( LumUtils . keyFromHex ( privateKey ) ) ) ;
92+ const w5 = await LumWalletFactory . fromOfflineSigner ( new FakeOfflineAminoSigner ( LumUtils . keyFromHex ( privateKey ) ) ) ;
4993
5094 expect ( LumUtils . isAddressValid ( w1 . getAddress ( ) ) ) . toBe ( true ) ;
5195 expect ( LumUtils . isAddressValid ( w1 . getAddress ( ) , LumConstants . LumBech32PrefixAccAddr ) ) . toBe ( true ) ;
@@ -71,17 +115,27 @@ describe('LumWallet', () => {
71115 ] ,
72116 } ;
73117
118+ const w1Response = await w1 . signTransaction ( doc ) ;
119+ expect ( LumUtils . verifySignature ( w1Response [ 1 ] , LumUtils . sha256 ( LumUtils . generateSignDocBytes ( w1Response [ 0 ] ) ) , w5 . getPublicKey ( ) ) ) ;
120+
74121 expect ( w1 . getAddress ( ) ) . toEqual ( w2 . getAddress ( ) ) ;
75122 expect ( w1 . getPublicKey ( ) ) . toEqual ( w2 . getPublicKey ( ) ) ;
76- expect ( await w1 . signTransaction ( doc ) ) . toEqual ( await w2 . signTransaction ( doc ) ) ;
123+ expect ( w1Response ) . toEqual ( await w2 . signTransaction ( doc ) ) ;
77124
78125 expect ( w1 . getAddress ( ) ) . toEqual ( w3 . getAddress ( ) ) ;
79126 expect ( w1 . getPublicKey ( ) ) . toEqual ( w3 . getPublicKey ( ) ) ;
80- expect ( await w1 . signTransaction ( doc ) ) . toEqual ( await w3 . signTransaction ( doc ) ) ;
127+ expect ( w1Response ) . toEqual ( await w3 . signTransaction ( doc ) ) ;
81128
82129 expect ( w1 . getAddress ( ) ) . toEqual ( w4 . getAddress ( ) ) ;
83130 expect ( w1 . getPublicKey ( ) ) . toEqual ( w4 . getPublicKey ( ) ) ;
84- expect ( await w1 . signTransaction ( doc ) ) . toEqual ( await w4 . signTransaction ( doc ) ) ;
131+ expect ( w1Response ) . toEqual ( await w4 . signTransaction ( doc ) ) ;
132+
133+ expect ( w1 . getAddress ( ) ) . toEqual ( w5 . getAddress ( ) ) ;
134+ expect ( w1 . getPublicKey ( ) ) . toEqual ( w5 . getPublicKey ( ) ) ;
135+ // Signature will differ due to the SignMode use but should still be valid
136+ const w5Response = await w5 . signTransaction ( doc ) ;
137+ expect ( w1Response ) . not . toEqual ( w5Response ) ;
138+ expect ( LumUtils . verifySignature ( w5Response [ 1 ] , LumUtils . sha256 ( LumUtils . generateSignDocBytes ( w5Response [ 0 ] ) ) , w5 . getPublicKey ( ) ) ) ;
85139
86140 const randomPrivateKey = LumUtils . generatePrivateKey ( ) ;
87141 expect ( randomPrivateKey ) . toHaveLength ( LumConstants . PrivateKeyLength ) ;
@@ -101,7 +155,7 @@ describe('LumWallet', () => {
101155
102156 const w1 = await LumWalletFactory . fromMnemonic ( mnemonic ) ;
103157 const w2 = await LumWalletFactory . fromMnemonic ( LumUtils . generateMnemonic ( ) ) ;
104- const w3 = await LumWalletFactory . fromOfflineSigner ( new FakeOfflineSigner ( LumUtils . keyFromHex ( privateKey ) ) ) ;
158+ const w3 = await LumWalletFactory . fromOfflineSigner ( new FakeOfflineDirectSigner ( LumUtils . keyFromHex ( privateKey ) ) ) ;
105159
106160 const signedW1 = await w1 . signMessage ( message ) ;
107161 expect ( signedW1 . signer ) . toEqual ( LumConstants . LumMessageSigner . PAPER ) ;
0 commit comments