1- import { useCallback } from "react"
1+ import { useCallback , useMemo } from "react"
22import { atom , useRecoilState } from "recoil"
33import { encode } from "js-base64"
4- import { CreateTxOptions , RawKey } from "@terra-money/terra.js"
4+ import { AccAddress , CreateTxOptions } from "@terra-money/terra.js"
5+ import { PublicKey , RawKey , SignatureV2 } from "@terra-money/terra.js"
6+ import { useChainID } from "data/wallet"
57import { useLCDClient } from "data/Terra/lcdClient"
68import { PasswordError } from "../scripts/keystore"
79import { getDecryptedKey , testPassword } from "../scripts/keystore"
810import { getWallet , storeWallet , clearWallet } from "../scripts/keystore"
911import { getStoredWallet , getStoredWallets } from "../scripts/keystore"
1012import encrypt from "../scripts/encrypt"
13+ import * as ledger from "../ledger/ledger"
14+ import LedgerKey from "../ledger/LedgerKey"
1115import useAvailable from "./useAvailable"
1216
1317const walletState = atom ( {
@@ -33,22 +37,49 @@ const useAuth = () => {
3337 [ setWallet ]
3438 )
3539
40+ const connectLedger = useCallback (
41+ ( address : AccAddress ) => {
42+ const wallet = { address, ledger : true as const }
43+ storeWallet ( wallet )
44+ setWallet ( wallet )
45+ } ,
46+ [ setWallet ]
47+ )
48+
3649 const disconnect = useCallback ( ( ) => {
3750 clearWallet ( )
3851 setWallet ( undefined )
3952 } , [ setWallet ] )
4053
4154 /* helpers */
42- const getConnectedWallet = ( ) => {
43- if ( ! wallet ) throw new Error ( "Wallet is not connected" )
55+ const connectedWallet = useMemo ( ( ) => {
56+ if ( ! ( wallet && "name" in wallet ) ) return
4457 return wallet
58+ } , [ wallet ] )
59+
60+ const getConnectedWallet = ( ) => {
61+ if ( ! connectedWallet ) throw new Error ( "Wallet is not defined" )
62+ return connectedWallet
4563 }
4664
4765 const getKey = ( password : string ) => {
4866 const { name } = getConnectedWallet ( )
4967 return getDecryptedKey ( { name, password } )
5068 }
5169
70+ const getLedgerKey = async ( ) => {
71+ const pk = await ledger . getPubKey ( )
72+ if ( ! pk ) throw new Error ( "Public key is not defined" )
73+
74+ const publicKey = PublicKey . fromAmino ( {
75+ type : "tendermint/PubKeySecp256k1" ,
76+ value : pk . toString ( "base64" ) ,
77+ } )
78+
79+ const key = new LedgerKey ( publicKey )
80+ return key
81+ }
82+
5283 /* manage: export */
5384 const encodeEncryptedWallet = ( password : string ) => {
5485 const { name, address } = getConnectedWallet ( )
@@ -68,19 +99,38 @@ const useAuth = () => {
6899 }
69100
70101 /* tx */
71- const post = async ( txOptions : CreateTxOptions , password : string ) => {
72- const pk = getKey ( password )
73- if ( ! pk ) throw new PasswordError ( "Incorrect password" )
74- const rk = new RawKey ( Buffer . from ( pk , "hex" ) )
75- const wallet = lcd . wallet ( rk )
76- const signedTx = await wallet . createAndSignTx ( txOptions )
77- return { result : await lcd . tx . broadcastSync ( signedTx ) }
102+ const chainID = useChainID ( )
103+ const post = async ( txOptions : CreateTxOptions , password = "" ) => {
104+ if ( ! wallet ) throw new Error ( "Wallet is not defined" )
105+ const { address } = wallet
106+
107+ if ( "ledger" in wallet ) {
108+ const key = await getLedgerKey ( )
109+ const wallet = lcd . wallet ( key )
110+ const { account_number : accountNumber , sequence } =
111+ await wallet . accountNumberAndSequence ( )
112+ const signMode = SignatureV2 . SignMode . SIGN_MODE_LEGACY_AMINO_JSON
113+ const unsignedTx = await lcd . tx . create ( [ { address } ] , txOptions )
114+ const options = { chainID, accountNumber, sequence, signMode }
115+ const signedTx = await key . signTx ( unsignedTx , options )
116+ return { result : await lcd . tx . broadcastSync ( signedTx ) }
117+ } else {
118+ const pk = getKey ( password )
119+ if ( ! pk ) throw new PasswordError ( "Incorrect password" )
120+ const key = new RawKey ( Buffer . from ( pk , "hex" ) )
121+ const wallet = lcd . wallet ( key )
122+ const signedTx = await wallet . createAndSignTx ( txOptions )
123+ return { result : await lcd . tx . broadcastSync ( signedTx ) }
124+ }
78125 }
79126
80127 return {
81128 wallet,
82129 wallets,
130+ getConnectedWallet,
131+ connectedWallet,
83132 connect,
133+ connectLedger,
84134 disconnect,
85135 available,
86136 encodeEncryptedWallet,
0 commit comments