@@ -41,6 +41,8 @@ export class Ledger {
4141 private _getWalletConnectProvider ?: ( ) => Promise < any > ;
4242 private _walletConnectAccount ?: Account ;
4343 private _sessionDeleteHandler ?: ( ) => void ;
44+ /** 由 provider 注入,用于 signMessage/signTypedData 根据连接类型分支 */
45+ private _getConnectType ?: ( ) => 'USB' | 'WalletConnect' | undefined ;
4446
4547 constructor ( name ?: string , derivationPath ?: string ) {
4648 this . wallet . name = name || 'Ledger' ;
@@ -57,7 +59,10 @@ export class Ledger {
5759 this . ethereumSigner = new EthereumSigner ( ) ;
5860 }
5961
60- public connect = async ( returnWhenNoDevice ?: boolean ) => {
62+ /**
63+ * USB 连接:发现设备、建立 session、检查 Ethereum app。
64+ */
65+ public connectUSB = async ( returnWhenNoDevice ?: boolean ) => {
6166 if ( this . availableDevices . devices . length === 0 ) {
6267 if ( returnWhenNoDevice ) {
6368 throw new LedgerError ( 'NO_DEVICE' , 'No available devices to connect' ) ;
@@ -172,54 +177,92 @@ export class Ledger {
172177 }
173178 } ;
174179
175- public signMessage = async ( message : string ) => {
176- // Check if using WalletConnect
177- if ( this . _walletConnectAccount ) {
178- return this . _signMessageWithWalletConnect ( message ) ;
179- }
180-
181- // Use hardware wallet signing
180+ /**
181+ * USB 签名:仅走 USB 通道(personal_sign 或 EIP-712)。
182+ * 与 WalletConnect 签名完全独立。
183+ */
184+ public signWithUSB = async (
185+ params : { type : 'message' ; message : string } | { type : 'typedData' ; typedData : any } ,
186+ ) : Promise < any > => {
182187 if ( ! this . sessionId ) {
183188 throw new LedgerError (
184189 'NO_SESSION' ,
185- 'No session ID available . Please connect to Ledger device first.' ,
190+ 'No session. Please connect to Ledger device via USB first.' ,
186191 ) ;
187192 }
188- try {
189- return await this . ethereumSigner . signMessage ( this . sessionId , this . derivationPath , message ) ;
190- } catch {
191- throw new LedgerError ( 'SIGN_MESSAGE_FAILED' , 'Failed to sign message' ) ;
192- }
193- } ;
194-
195- public signTypedData = async ( typedData : any ) => {
196- // Check if using WalletConnect
197- if ( this . _walletConnectAccount ) {
198- return this . _signTypedDataWithWalletConnect ( typedData ) ;
199- }
200-
201- // Use hardware wallet signing
202- if ( ! this . sessionId ) {
203- throw new LedgerError (
204- 'NO_SESSION' ,
205- 'No session ID available. Please connect to Ledger device first.' ,
206- ) ;
193+ if ( params . type === 'message' ) {
194+ try {
195+ return await this . ethereumSigner . signMessage (
196+ this . sessionId ,
197+ this . derivationPath ,
198+ params . message ,
199+ ) ;
200+ } catch {
201+ throw new LedgerError ( 'SIGN_MESSAGE_FAILED' , 'Failed to sign message' ) ;
202+ }
207203 }
208204 try {
209205 return await this . ethereumSigner . signTypedData (
210206 this . sessionId ,
211207 this . derivationPath ,
212- typedData ,
208+ params . typedData ,
213209 ) ;
214210 } catch {
215211 throw new LedgerError ( 'SIGN_TYPED_DATA_FAILED' , 'Failed to sign typed data' ) ;
216212 }
217213 } ;
218214
215+ /**
216+ * WalletConnect 签名:仅走 WalletConnect 通道(personal_sign 或 EIP-712)。
217+ * 与 USB 签名完全独立。
218+ */
219+ public signWithWalletConnect = async (
220+ params : { type : 'message' ; message : string } | { type : 'typedData' ; typedData : any } ,
221+ ) : Promise < any > => {
222+ if ( params . type === 'message' ) {
223+ return this . _signMessageWithWalletConnect ( params . message ) ;
224+ }
225+ return this . _signTypedDataWithWalletConnect ( params . typedData ) ;
226+ } ;
227+
228+ /**
229+ * 统一签名入口:优先根据 connectType(由 provider 通过 setConnectTypeGetter 注入 latestConnectTypeRef)委托;
230+ * 未注入时回退为根据 _walletConnectAccount 判断。
231+ */
232+ public signMessage = async ( message : string ) => {
233+ const connectType = this . _getConnectType ?.( ) ;
234+ const useWalletConnect = connectType === 'WalletConnect' && this . _walletConnectAccount ;
235+ if ( useWalletConnect ) {
236+ return this . signWithWalletConnect ( { type : 'message' , message } ) ;
237+ }
238+ return this . signWithUSB ( { type : 'message' , message } ) ;
239+ } ;
240+
241+ /**
242+ * 统一签名入口:优先根据 connectType(由 provider 通过 setConnectTypeGetter 注入 latestConnectTypeRef)委托;
243+ * 未注入时回退为根据 _walletConnectAccount 判断。
244+ */
245+ public signTypedData = async ( typedData : any ) => {
246+ const connectType = this . _getConnectType ?.( ) ;
247+ const useWalletConnect = connectType === 'WalletConnect' && this . _walletConnectAccount ;
248+ if ( useWalletConnect ) {
249+ return this . signWithWalletConnect ( { type : 'typedData' , typedData } ) ;
250+ }
251+ return this . signWithUSB ( { type : 'typedData' , typedData } ) ;
252+ } ;
253+
254+ /** 由 provider 注入 latestConnectTypeRef 的 getter,用于签名分支判断 */
255+ public setConnectTypeGetter = ( getter : ( ) => 'USB' | 'WalletConnect' | undefined ) => {
256+ this . _getConnectType = getter ;
257+ } ;
258+
219259 public setWalletConnectProviderGetter = ( providerGetter : ( ) => Promise < any > ) => {
220260 this . _getWalletConnectProvider = providerGetter ;
221261 } ;
222262
263+ /**
264+ * WalletConnect 连接:配对/复用 session、解析账户。
265+ */
223266 public connectWalletConnect = async ( ) => {
224267 if ( ! this . _getWalletConnectProvider ) {
225268 throw new LedgerError ( 'WALLETCONNECT_NOT_CONFIGURED' , 'WalletConnect is not configured' ) ;
0 commit comments