Skip to content

Commit 3aa97ed

Browse files
author
Yuejian
committed
chore: 版本问题修复
1 parent dd075af commit 3aa97ed

File tree

7 files changed

+520
-124
lines changed

7 files changed

+520
-124
lines changed

packages/ledger/package.json

Lines changed: 7 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -45,11 +45,13 @@
4545
"dependencies": {
4646
"@ant-design/web3-common": "workspace:*",
4747
"@ant-design/web3-icons": "workspace:*",
48-
"@ledgerhq/device-management-kit": "^0.9.1",
49-
"@ledgerhq/device-signer-kit-ethereum": "^1.8.0",
50-
"@ledgerhq/device-transport-kit-web-hid": "^1.2.0",
51-
"@walletconnect/universal-provider": "^2.14.0",
52-
"rxjs": "^7.8.1"
48+
"@ledgerhq/device-management-kit": "^1.0.0",
49+
"@ledgerhq/device-signer-kit-ethereum": "^1.11.0",
50+
"@ledgerhq/device-transport-kit-web-hid": "^1.2.3",
51+
"@ledgerhq/context-module": "^1.14.1",
52+
"@walletconnect/core": "^2.23.4",
53+
"@walletconnect/universal-provider": "^2.23.4",
54+
"rxjs": "^7.8.2"
5355
},
5456
"devDependencies": {
5557
"father": "^4.6.2",

packages/ledger/src/ledger/index.tsx

Lines changed: 72 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -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');

packages/ledger/src/provider/LedgerAddressIndexModal.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -94,7 +94,7 @@ export const LedgerAddressIndexModal: FC<LedgerAddressIndexModalProps> = ({
9494
Confirm
9595
</Button>,
9696
]}
97-
destroyOnClose
97+
destroyOnHidden
9898
maskClosable={false}
9999
>
100100
<div style={{ marginBottom: 16 }}>

packages/ledger/src/provider/index.tsx

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -61,7 +61,11 @@ export const LedgerWeb3ConfigProvider: FC<PropsWithChildren<LedgerWeb3ConfigProv
6161
const accountRef = useRef(account);
6262
accountRef.current = account;
6363

64-
// Set WalletConnect provider getter on ledger instance
64+
// Set WalletConnect provider getter and connect type getter on ledger instance
65+
useEffect(() => {
66+
ledger.setConnectTypeGetter(() => latestConnectTypeRef.current);
67+
}, [ledger, latestConnectTypeRef]);
68+
6569
useEffect(() => {
6670
if (!hasWalletConnect) return;
6771
ledger.setWalletConnectProviderGetter(getWalletConnectProvider);
@@ -86,7 +90,7 @@ export const LedgerWeb3ConfigProvider: FC<PropsWithChildren<LedgerWeb3ConfigProv
8690
} else {
8791
// USB: connect device then show address-index modal (ConnectModal will close)
8892
await ledger.disconnect();
89-
await ledger.connect();
93+
await ledger.connectUSB();
9094
cacheSelectedWallet({ walletName: selected.name, latestConnectType: 'USB' });
9195
setAwaitingAddressIndex(true);
9296
return undefined;
@@ -233,7 +237,7 @@ export const LedgerWeb3ConfigProvider: FC<PropsWithChildren<LedgerWeb3ConfigProv
233237
const addressIndex = savedIndex ?? '0';
234238
try {
235239
await ledger.disconnect();
236-
await ledger.connect(true);
240+
await ledger.connectUSB(true);
237241
await ledger.setAddressIndex(addressIndex);
238242
setAccount(ledger.accounts[0]);
239243
} catch (e: any) {

packages/web3/src/connect-modal/__tests__/basic.test.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -138,7 +138,7 @@ describe('ConnectModal with guide', () => {
138138
}}
139139
walletList={walletList}
140140
guide={guide}
141-
destroyOnClose={true}
141+
destroyOnHidden
142142
onCancel={() => setOpen(false)}
143143
/>
144144
);

packages/web3/src/ledger/demos/basic.tsx

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -81,6 +81,7 @@ const AccountSelector: React.FC = () => {
8181

8282
const handleSignTypedData = async () => {
8383
try {
84+
// 格式需符合 @ledgerhq/device-signer-kit-ethereum 的 TypedData:domain.chainId 为 number
8485
const typedData = {
8586
types: {
8687
EIP712Domain: [
@@ -115,6 +116,8 @@ const AccountSelector: React.FC = () => {
115116
const signature = await ledger.signTypedData(typedData);
116117
messageApi.success(`Typed data signed! ${String(signature).slice(0, 20)}...`);
117118
} catch (error: any) {
119+
// 便于排查「无法唤起设备」:若为解析/SDK 错误会在此打出
120+
console.error('[handleSignTypedData]', error);
118121
messageApi.error(`Sign failed: ${error?.message || error}`);
119122
}
120123
};

0 commit comments

Comments
 (0)