@reef-knot/ledger-connector 5.2.0-alpha.1 → 5.2.0-alpha.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1 +1 @@
1
- {"version":3,"file":"account.d.ts","sourceRoot":"","sources":["../../src/hid/account.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,GAAG,MAAM,sBAAsB,CAAC;AAE5C,OAAO,EAOL,KAAK,OAAO,EACZ,KAAK,YAAY,EAGlB,MAAM,MAAM,CAAC;AAId,MAAM,MAAM,UAAU,GAAG,CAAC,CAAC,EACzB,QAAQ,EAAE,CAAC,GAAG,EAAE,GAAG,KAAK,CAAC,GAAG,OAAO,CAAC,CAAC,CAAC,KACnC,OAAO,CAAC,CAAC,CAAC,CAAC;AAiBhB,eAAO,MAAM,mBAAmB,YACrB,OAAO,QACV,MAAM,cACA,UAAU,KACrB,YAiFC,CAAC"}
1
+ {"version":3,"file":"account.d.ts","sourceRoot":"","sources":["../../src/hid/account.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,GAAG,MAAM,sBAAsB,CAAC;AAE5C,OAAO,EAOL,KAAK,OAAO,EACZ,KAAK,YAAY,EAGlB,MAAM,MAAM,CAAC;AAId,MAAM,MAAM,UAAU,GAAG,CAAC,CAAC,EACzB,QAAQ,EAAE,CAAC,GAAG,EAAE,GAAG,KAAK,CAAC,GAAG,OAAO,CAAC,CAAC,CAAC,KACnC,OAAO,CAAC,CAAC,CAAC,CAAC;AAiBhB,eAAO,MAAM,mBAAmB,GAC9B,SAAS,OAAO,EAChB,MAAM,MAAM,EACZ,YAAY,UAAU,KACrB,YAiFC,CAAC"}
@@ -1,6 +1,5 @@
1
1
  import { bytesToHex, getTypesForEIP712Domain, hashStruct, serializeSignature, serializeTransaction, stringToHex } from "viem";
2
2
  import { toAccount } from "viem/accounts";
3
-
4
3
  //#region src/hid/account.ts
5
4
  const RESOLUTION_CONFIG = {
6
5
  erc20: true,
@@ -26,11 +25,12 @@ const createLedgerAccount = (address, path, withEthApp) => toAccount({
26
25
  },
27
26
  async signMessage({ message }) {
28
27
  const messageHex = typeof message === "string" ? stringToHex(message) : typeof message.raw === "string" ? message.raw : bytesToHex(message.raw);
29
- return toSignatureHex(await withEthApp((eth) => eth.signPersonalMessage(path, messageHex.slice(2))));
28
+ const signature = await withEthApp((eth) => eth.signPersonalMessage(path, messageHex.slice(2)));
29
+ return toSignatureHex(signature);
30
30
  },
31
31
  async signTypedData(parameters) {
32
32
  const { domain = {}, types, primaryType, message } = parameters;
33
- return toSignatureHex(await withEthApp(async (eth) => {
33
+ const signature = await withEthApp(async (eth) => {
34
34
  try {
35
35
  return await eth.signEIP712Message(path, parameters);
36
36
  } catch (error) {
@@ -48,9 +48,9 @@ const createLedgerAccount = (address, path, withEthApp) => toAccount({
48
48
  });
49
49
  return eth.signEIP712HashedMessage(path, domainSeparator.slice(2), messageHash.slice(2));
50
50
  }
51
- }));
51
+ });
52
+ return toSignatureHex(signature);
52
53
  }
53
54
  });
54
-
55
55
  //#endregion
56
- export { createLedgerAccount };
56
+ export { createLedgerAccount };
@@ -1 +1 @@
1
- {"version":3,"file":"connector.d.ts","sourceRoot":"","sources":["../../src/hid/connector.ts"],"names":[],"mappings":"AAKA,OAAO,EAAE,KAAK,EAAE,MAAM,cAAc,CAAC;AAGrC,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,YAAY,CAAC;AACnD,eAAO,MAAM,WAAW,cAAc,CAAC;AACvC,eAAO,MAAM,IAAI,WAAW,CAAC;AAG7B,wBAAgB,kBAAkB,CAAC,EACjC,GAAG,EACH,YAAY,GACb,EAAE;IACD,GAAG,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IAC5B,YAAY,EAAE,KAAK,CAAC;CACrB,yGAuHA;yBA7He,kBAAkB"}
1
+ {"version":3,"file":"connector.d.ts","sourceRoot":"","sources":["../../src/hid/connector.ts"],"names":[],"mappings":"AAKA,OAAO,EAAE,KAAK,EAAE,MAAM,cAAc,CAAC;AAUrC,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,YAAY,CAAC;AACnD,eAAO,MAAM,WAAW,cAAc,CAAC;AACvC,eAAO,MAAM,IAAI,WAAW,CAAC;AAG7B,wBAAgB,kBAAkB,CAAC,EACjC,GAAG,EACH,YAAY,GACb,EAAE;IACD,GAAG,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IAC5B,YAAY,EAAE,KAAK,CAAC;CACrB,yGAgIA;yBAtIe,kBAAkB"}
@@ -1,14 +1,13 @@
1
- import { checkError, clearLedgerDerivationPath } from "./helpers.js";
1
+ import { checkError, clearLedgerAccount, clearLedgerChainId, clearLedgerDerivationPath, restoreLedgerChainId, saveLedgerChainId } from "./helpers.js";
2
2
  import { ChainNotConfiguredError, ConnectorNotFoundError, createConnector } from "wagmi";
3
3
  import { SwitchChainError } from "viem";
4
-
5
4
  //#region src/hid/connector.ts
6
5
  const idLedgerHid = "ledgerHID";
7
6
  const name = "Ledger";
8
7
  ledgerHIDConnector.type = "ledgerHID";
9
8
  function ledgerHIDConnector({ rpc, defaultChain }) {
10
9
  const providers = {};
11
- let currentChainId;
10
+ let currentChainId = restoreLedgerChainId();
12
11
  return createConnector(({ chains, emitter }) => ({
13
12
  id: idLedgerHid,
14
13
  name,
@@ -26,12 +25,13 @@ function ledgerHIDConnector({ rpc, defaultChain }) {
26
25
  },
27
26
  async connect({ chainId, withCapabilities = false } = {}) {
28
27
  try {
29
- currentChainId = chainId;
30
- const provider = await this.getProvider({ chainId });
28
+ currentChainId = chainId ?? currentChainId;
29
+ const provider = await this.getProvider({ chainId: currentChainId });
31
30
  provider.on("disconnect", this.onDisconnect);
32
31
  const account = await provider.enable();
33
32
  const connectedChainId = await this.getChainId();
34
33
  currentChainId = connectedChainId;
34
+ saveLedgerChainId(connectedChainId);
35
35
  return {
36
36
  accounts: withCapabilities ? [{
37
37
  address: account,
@@ -40,7 +40,7 @@ function ledgerHIDConnector({ rpc, defaultChain }) {
40
40
  chainId: connectedChainId
41
41
  };
42
42
  } catch (error) {
43
- currentChainId = void 0;
43
+ currentChainId = restoreLedgerChainId();
44
44
  return checkError(error);
45
45
  }
46
46
  },
@@ -51,6 +51,8 @@ function ledgerHIDConnector({ rpc, defaultChain }) {
51
51
  });
52
52
  currentChainId = void 0;
53
53
  clearLedgerDerivationPath();
54
+ clearLedgerChainId();
55
+ clearLedgerAccount();
54
56
  },
55
57
  async getAccounts() {
56
58
  return [await (await this.getProvider()).getAddress()];
@@ -72,6 +74,7 @@ function ledgerHIDConnector({ rpc, defaultChain }) {
72
74
  const chain = chains.find((x) => x.id === chainId);
73
75
  if (!chain) throw new SwitchChainError(new ChainNotConfiguredError());
74
76
  currentChainId = chainId;
77
+ saveLedgerChainId(chainId);
75
78
  emitter.emit("change", { chainId });
76
79
  return chain;
77
80
  },
@@ -82,6 +85,5 @@ function ledgerHIDConnector({ rpc, defaultChain }) {
82
85
  onChainChanged() {}
83
86
  }));
84
87
  }
85
-
86
88
  //#endregion
87
- export { idLedgerHid, ledgerHIDConnector };
89
+ export { idLedgerHid, ledgerHIDConnector, name };
@@ -1,2 +1,4 @@
1
1
  export declare const LS_KEY_DERIVATION_PATH = "reef-knot_ledger-derivation-path";
2
+ export declare const LS_KEY_CHAIN_ID = "reef-knot_ledger-chain-id";
3
+ export declare const LS_KEY_ACCOUNT = "reef-knot_ledger-account";
2
4
  //# sourceMappingURL=constants.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"constants.d.ts","sourceRoot":"","sources":["../../src/hid/constants.ts"],"names":[],"mappings":"AAAA,eAAO,MAAM,sBAAsB,qCAAqC,CAAC"}
1
+ {"version":3,"file":"constants.d.ts","sourceRoot":"","sources":["../../src/hid/constants.ts"],"names":[],"mappings":"AAAA,eAAO,MAAM,sBAAsB,qCAAqC,CAAC;AACzE,eAAO,MAAM,eAAe,8BAA8B,CAAC;AAC3D,eAAO,MAAM,cAAc,6BAA6B,CAAC"}
@@ -1,5 +1,6 @@
1
1
  //#region src/hid/constants.ts
2
2
  const LS_KEY_DERIVATION_PATH = "reef-knot_ledger-derivation-path";
3
-
3
+ const LS_KEY_CHAIN_ID = "reef-knot_ledger-chain-id";
4
+ const LS_KEY_ACCOUNT = "reef-knot_ledger-account";
4
5
  //#endregion
5
- export { LS_KEY_DERIVATION_PATH };
6
+ export { LS_KEY_ACCOUNT, LS_KEY_CHAIN_ID, LS_KEY_DERIVATION_PATH };
@@ -1,3 +1,15 @@
1
+ import { type Address } from 'viem';
2
+ export type PersistedLedgerAccount = {
3
+ address: Address;
4
+ path: string;
5
+ };
6
+ export declare const isLockedDeviceError: (error: unknown) => boolean;
1
7
  export declare const checkError: (error: any) => never;
2
8
  export declare const clearLedgerDerivationPath: () => void;
9
+ export declare const saveLedgerChainId: (chainId: number) => void;
10
+ export declare const restoreLedgerChainId: () => number | undefined;
11
+ export declare const clearLedgerChainId: () => void;
12
+ export declare const saveLedgerAccount: (account: PersistedLedgerAccount) => void;
13
+ export declare const restoreLedgerAccount: () => PersistedLedgerAccount | undefined;
14
+ export declare const clearLedgerAccount: () => void;
3
15
  //# sourceMappingURL=helpers.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"helpers.d.ts","sourceRoot":"","sources":["../../src/hid/helpers.ts"],"names":[],"mappings":"AAEA,eAAO,MAAM,UAAU,UAAW,GAAG,KAAG,KAmBvC,CAAC;AAEF,eAAO,MAAM,yBAAyB,YAErC,CAAC"}
1
+ {"version":3,"file":"helpers.d.ts","sourceRoot":"","sources":["../../src/hid/helpers.ts"],"names":[],"mappings":"AAAA,OAAO,EAAa,KAAK,OAAO,EAAE,MAAM,MAAM,CAAC;AAO/C,MAAM,MAAM,sBAAsB,GAAG;IACnC,OAAO,EAAE,OAAO,CAAC;IACjB,IAAI,EAAE,MAAM,CAAC;CACd,CAAC;AAEF,eAAO,MAAM,mBAAmB,GAAI,OAAO,OAAO,KAAG,OACc,CAAC;AAEpE,eAAO,MAAM,UAAU,GAAI,OAAO,GAAG,KAAG,KAmBvC,CAAC;AAEF,eAAO,MAAM,yBAAyB,YAErC,CAAC;AAEF,eAAO,MAAM,iBAAiB,GAAI,SAAS,MAAM,SAGhD,CAAC;AAEF,eAAO,MAAM,oBAAoB,QAAO,MAAM,GAAG,SAMhD,CAAC;AAEF,eAAO,MAAM,kBAAkB,YAG9B,CAAC;AAEF,eAAO,MAAM,iBAAiB,GAAI,SAAS,sBAAsB,SAGhE,CAAC;AAEF,eAAO,MAAM,oBAAoB,QAAO,sBAAsB,GAAG,SAchE,CAAC;AAEF,eAAO,MAAM,kBAAkB,YAG9B,CAAC"}
@@ -1,6 +1,7 @@
1
- import { LS_KEY_DERIVATION_PATH } from "./constants.js";
2
-
1
+ import { LS_KEY_ACCOUNT, LS_KEY_CHAIN_ID, LS_KEY_DERIVATION_PATH } from "./constants.js";
2
+ import { isAddress } from "viem";
3
3
  //#region src/hid/helpers.ts
4
+ const isLockedDeviceError = (error) => error?.name === "LockedDeviceError";
4
5
  const checkError = (error) => {
5
6
  if (error.statusText === "INS_NOT_SUPPORTED") error.message = "Device is not supported. Make sure the Ethereum app is open on the device.";
6
7
  if (error.statusText === "UNKNOWN_ERROR") error.message = "Unknown error. Make sure the device is connected and the Ethereum app is open on the device.";
@@ -10,6 +11,40 @@ const checkError = (error) => {
10
11
  const clearLedgerDerivationPath = () => {
11
12
  window?.localStorage.removeItem(LS_KEY_DERIVATION_PATH);
12
13
  };
13
-
14
+ const saveLedgerChainId = (chainId) => {
15
+ if (typeof window === "undefined") return;
16
+ window.localStorage.setItem(LS_KEY_CHAIN_ID, String(chainId));
17
+ };
18
+ const restoreLedgerChainId = () => {
19
+ if (typeof window === "undefined") return void 0;
20
+ const stored = window.localStorage.getItem(LS_KEY_CHAIN_ID);
21
+ if (!stored) return void 0;
22
+ const chainId = Number(stored);
23
+ return Number.isInteger(chainId) && chainId > 0 ? chainId : void 0;
24
+ };
25
+ const clearLedgerChainId = () => {
26
+ if (typeof window === "undefined") return;
27
+ window.localStorage.removeItem(LS_KEY_CHAIN_ID);
28
+ };
29
+ const saveLedgerAccount = (account) => {
30
+ if (typeof window === "undefined") return;
31
+ window.localStorage.setItem(LS_KEY_ACCOUNT, JSON.stringify(account));
32
+ };
33
+ const restoreLedgerAccount = () => {
34
+ if (typeof window === "undefined") return void 0;
35
+ const stored = window.localStorage.getItem(LS_KEY_ACCOUNT);
36
+ if (!stored) return void 0;
37
+ try {
38
+ const { address, path } = JSON.parse(stored);
39
+ if (address && isAddress(address) && typeof path === "string") return {
40
+ address,
41
+ path
42
+ };
43
+ } catch {}
44
+ };
45
+ const clearLedgerAccount = () => {
46
+ if (typeof window === "undefined") return;
47
+ window.localStorage.removeItem(LS_KEY_ACCOUNT);
48
+ };
14
49
  //#endregion
15
- export { checkError, clearLedgerDerivationPath };
50
+ export { checkError, clearLedgerAccount, clearLedgerChainId, clearLedgerDerivationPath, isLockedDeviceError, restoreLedgerAccount, restoreLedgerChainId, saveLedgerAccount, saveLedgerChainId };
package/dist/hid/index.js CHANGED
@@ -1,2 +1,3 @@
1
1
  import { LS_KEY_DERIVATION_PATH } from "./constants.js";
2
2
  import { idLedgerHid, ledgerHIDConnector } from "./connector.js";
3
+ export { LS_KEY_DERIVATION_PATH, idLedgerHid, ledgerHIDConnector };
@@ -31,6 +31,7 @@ export declare class LedgerHQProvider {
31
31
  enable(): Promise<Address>;
32
32
  resetAccount(): void;
33
33
  getAccount(): Promise<LocalAccount>;
34
+ private readAddress;
34
35
  getAddress(): Promise<Address>;
35
36
  private getPublicClient;
36
37
  private getWalletClient;
@@ -1 +1 @@
1
- {"version":3,"file":"provider.d.ts","sourceRoot":"","sources":["../../src/hid/provider.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,GAAG,MAAM,sBAAsB,CAAC;AAC5C,OAAO,KAAK,eAAe,MAAM,+BAA+B,CAAC;AACjE,OAAO,EAWL,KAAK,OAAO,EACZ,KAAK,KAAK,EAEV,KAAK,YAAY,EAIlB,MAAM,MAAM,CAAC;AA0Bd,KAAK,gBAAgB,GAAG;IACtB,MAAM,EAAE,MAAM,CAAC;IACf,MAAM,CAAC,EAAE,OAAO,EAAE,CAAC;CACpB,CAAC;AAEF,KAAK,aAAa,GAAG,YAAY,CAAC;AAClC,KAAK,QAAQ,GAAG,MAAM,IAAI,CAAC;AAE3B,qBAAa,gBAAgB;IAC3B,QAAQ,CAAC,KAAK,EAAE,KAAK,CAAC;IAEf,MAAM,CAAC,EAAE,SAAS,CAAC;IAEnB,SAAS,CAAC,EAAE,OAAO,eAAe,CAAC;IAE1C,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAC,CAAS;IAEjC,OAAO,CAAC,OAAO,CAAC,CAAe;IAE/B,OAAO,CAAC,WAAW,CAAC,CAAS;IAE7B,OAAO,CAAC,YAAY,CAAC,CAAe;IAEpC,OAAO,CAAC,YAAY,CAAC,CAAe;IAEpC,OAAO,CAAC,SAAS,CAAqD;gBAE1D,EAAE,KAAK,EAAE,MAAM,EAAE,EAAE;QAAE,KAAK,EAAE,KAAK,CAAC;QAAC,MAAM,CAAC,EAAE,MAAM,CAAA;KAAE;IAehE,EAAE,CAAC,KAAK,EAAE,aAAa,EAAE,QAAQ,EAAE,QAAQ;IAI3C,cAAc,CAAC,KAAK,EAAE,aAAa,EAAE,QAAQ,EAAE,QAAQ;IAIvD,IAAI,CAAC,KAAK,EAAE,aAAa;IAMzB,IAAI,cAAc,WAQjB;IAEK,aAAa;IASb,YAAY,IAAI,OAAO,CAAC,eAAe,CAAC;IAc9C,UAAU,CAAC,CAAC,EAAE,QAAQ,EAAE,CAAC,GAAG,EAAE,GAAG,KAAK,CAAC,GAAG,OAAO,CAAC,CAAC,CAAC,GAAG,OAAO,CAAC,CAAC,CAAC;IAoB3D,MAAM,IAAI,OAAO,CAAC,OAAO,CAAC;IAyBhC,YAAY;IAMN,UAAU,IAAI,OAAO,CAAC,YAAY,CAAC;IAiBnC,UAAU,IAAI,OAAO,CAAC,OAAO,CAAC;IAOpC,OAAO,CAAC,eAAe;YAQT,eAAe;YAUf,eAAe;IAuEvB,OAAO,CAAC,EAAE,MAAM,EAAE,MAAW,EAAE,EAAE,gBAAgB,GAAG,OAAO,CAAC,OAAO,CAAC;CA2C3E"}
1
+ {"version":3,"file":"provider.d.ts","sourceRoot":"","sources":["../../src/hid/provider.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,GAAG,MAAM,sBAAsB,CAAC;AAC5C,OAAO,KAAK,eAAe,MAAM,+BAA+B,CAAC;AACjE,OAAO,EAYL,KAAK,OAAO,EACZ,KAAK,KAAK,EAEV,KAAK,YAAY,EAIlB,MAAM,MAAM,CAAC;AA6Cd,KAAK,gBAAgB,GAAG;IACtB,MAAM,EAAE,MAAM,CAAC;IACf,MAAM,CAAC,EAAE,OAAO,EAAE,CAAC;CACpB,CAAC;AAEF,KAAK,aAAa,GAAG,YAAY,CAAC;AAClC,KAAK,QAAQ,GAAG,MAAM,IAAI,CAAC;AAE3B,qBAAa,gBAAgB;IAC3B,QAAQ,CAAC,KAAK,EAAE,KAAK,CAAC;IAEf,MAAM,CAAC,EAAE,SAAS,CAAC;IAEnB,SAAS,CAAC,EAAE,OAAO,eAAe,CAAC;IAE1C,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAC,CAAS;IAEjC,OAAO,CAAC,OAAO,CAAC,CAAe;IAE/B,OAAO,CAAC,WAAW,CAAC,CAAS;IAE7B,OAAO,CAAC,YAAY,CAAC,CAAe;IAEpC,OAAO,CAAC,YAAY,CAAC,CAAe;IAEpC,OAAO,CAAC,SAAS,CAAqD;gBAE1D,EAAE,KAAK,EAAE,MAAM,EAAE,EAAE;QAAE,KAAK,EAAE,KAAK,CAAC;QAAC,MAAM,CAAC,EAAE,MAAM,CAAA;KAAE;IAehE,EAAE,CAAC,KAAK,EAAE,aAAa,EAAE,QAAQ,EAAE,QAAQ;IAI3C,cAAc,CAAC,KAAK,EAAE,aAAa,EAAE,QAAQ,EAAE,QAAQ;IAIvD,IAAI,CAAC,KAAK,EAAE,aAAa;IAMzB,IAAI,cAAc,WAQjB;IAEK,aAAa;IAQb,YAAY,IAAI,OAAO,CAAC,eAAe,CAAC;IAc9C,UAAU,CAAC,CAAC,EAAE,QAAQ,EAAE,CAAC,GAAG,EAAE,GAAG,KAAK,CAAC,GAAG,OAAO,CAAC,CAAC,CAAC,GAAG,OAAO,CAAC,CAAC,CAAC;IAoB3D,MAAM,IAAI,OAAO,CAAC,OAAO,CAAC;IAyBhC,YAAY;IAMN,UAAU,IAAI,OAAO,CAAC,YAAY,CAAC;YAqC3B,WAAW;IAoBnB,UAAU,IAAI,OAAO,CAAC,OAAO,CAAC;IAOpC,OAAO,CAAC,eAAe;YAQT,eAAe;YAUf,eAAe;IAuEvB,OAAO,CAAC,EAAE,MAAM,EAAE,MAAW,EAAE,EAAE,gBAAgB,GAAG,OAAO,CAAC,OAAO,CAAC;CA0D3E"}
@@ -1,8 +1,7 @@
1
- import { LS_KEY_DERIVATION_PATH } from "./constants.js";
2
- import { checkError } from "./helpers.js";
1
+ import "./constants.js";
2
+ import { checkError, clearLedgerAccount, isLockedDeviceError, restoreLedgerAccount, saveLedgerAccount } from "./helpers.js";
3
3
  import { createLedgerAccount } from "./account.js";
4
- import { createPublicClient, createWalletClient, getAddress, hexToBigInt, hexToNumber, http, isAddress, isAddressEqual, isHex, numberToHex } from "viem";
5
-
4
+ import { MethodNotSupportedRpcError, createPublicClient, createWalletClient, getAddress, hexToBigInt, hexToNumber, http, isAddress, isAddressEqual, isHex, numberToHex } from "viem";
6
5
  //#region src/hid/provider.ts
7
6
  const NOOP = () => {};
8
7
  const DEFAULT_DERIVATION_PATH = "m/44'/60'/0'/0/0";
@@ -11,6 +10,15 @@ const TX_TYPES = {
11
10
  "0x1": "eip2930",
12
11
  "0x2": "eip1559"
13
12
  };
13
+ const UNSUPPORTED_WALLET_METHODS = /* @__PURE__ */ new Set([
14
+ "eth_signTransaction",
15
+ "eth_signTypedData",
16
+ "eth_signTypedData_v1",
17
+ "eth_signTypedData_v3",
18
+ "eth_decrypt",
19
+ "eth_getEncryptionPublicKey",
20
+ "personal_ecRecover"
21
+ ]);
14
22
  let deviceSessionLock = Promise.resolve();
15
23
  const withDeviceSession = (fn) => {
16
24
  const result = deviceSessionLock.then(fn);
@@ -35,7 +43,7 @@ var LedgerHQProvider = class {
35
43
  this.listeners[event]?.forEach((listener) => listener());
36
44
  }
37
45
  get derivationPath() {
38
- if (typeof window !== "undefined") return window.localStorage.getItem(LS_KEY_DERIVATION_PATH) || DEFAULT_DERIVATION_PATH;
46
+ if (typeof window !== "undefined") return window.localStorage.getItem("reef-knot_ledger-derivation-path") || DEFAULT_DERIVATION_PATH;
39
47
  return DEFAULT_DERIVATION_PATH;
40
48
  }
41
49
  async loadTransport() {
@@ -94,13 +102,48 @@ var LedgerHQProvider = class {
94
102
  async getAccount() {
95
103
  const path = this.derivationPath;
96
104
  if (!this.account || this.accountPath !== path) {
97
- const { address } = await this.withEthApp((eth) => eth.getAddress(path));
98
- this.account = createLedgerAccount(getAddress(address), path, (cb) => this.withEthApp(cb));
105
+ const { address, verifiedByDevice } = await this.readAddress(path);
106
+ let verified = verifiedByDevice;
107
+ const withVerifyingEthApp = (cb) => this.withEthApp(async (eth) => {
108
+ if (!verified) {
109
+ const actual = await eth.getAddress(path);
110
+ if (!isAddressEqual(getAddress(actual.address), address)) {
111
+ clearLedgerAccount();
112
+ this.resetAccount();
113
+ this.emit("disconnect");
114
+ throw new Error("The connected account does not match the device. Please reconnect.");
115
+ }
116
+ verified = true;
117
+ }
118
+ return cb(eth);
119
+ });
120
+ this.account = createLedgerAccount(address, path, withVerifyingEthApp);
99
121
  this.accountPath = path;
100
122
  this.walletClient = void 0;
101
123
  }
102
124
  return this.account;
103
125
  }
126
+ async readAddress(path) {
127
+ try {
128
+ const { address } = await this.withEthApp((eth) => eth.getAddress(path));
129
+ const checksummed = getAddress(address);
130
+ saveLedgerAccount({
131
+ address: checksummed,
132
+ path
133
+ });
134
+ return {
135
+ address: checksummed,
136
+ verifiedByDevice: true
137
+ };
138
+ } catch (error) {
139
+ const persisted = restoreLedgerAccount();
140
+ if (isLockedDeviceError(error) && persisted?.path === path) return {
141
+ address: persisted.address,
142
+ verifiedByDevice: false
143
+ };
144
+ return checkError(error);
145
+ }
146
+ }
104
147
  async getAddress() {
105
148
  const { address } = await this.getAccount();
106
149
  return address;
@@ -181,6 +224,7 @@ var LedgerHQProvider = class {
181
224
  if (typeof params[1] !== "string") throw new Error("eth_signTypedData_v4 arg 1 is not a string");
182
225
  return (await this.getAccount()).signTypedData(JSON.parse(params[1]));
183
226
  default: {
227
+ if (method.startsWith("wallet_") || UNSUPPORTED_WALLET_METHODS.has(method)) throw new MethodNotSupportedRpcError(/* @__PURE__ */ new Error(`The method ${method} is not supported`), { method });
184
228
  const rpcRequest = this.getPublicClient().request;
185
229
  return rpcRequest({
186
230
  method,
@@ -190,6 +234,5 @@ var LedgerHQProvider = class {
190
234
  }
191
235
  }
192
236
  };
193
-
194
237
  //#endregion
195
- export { LedgerHQProvider };
238
+ export { LedgerHQProvider };
@@ -1,6 +1,5 @@
1
1
  import { SwitchChainNotSupportedError, createConnector } from "wagmi";
2
2
  import { ResourceUnavailableRpcError, UserRejectedRequestError, getAddress, numberToHex } from "viem";
3
-
4
3
  //#region src/iframe/connector.ts
5
4
  const idLedgerLive = "ledgerLive";
6
5
  const name = "Ledger Live";
@@ -101,6 +100,5 @@ function ledgerLiveConnector({ options, defaultChain }) {
101
100
  }
102
101
  }));
103
102
  }
104
-
105
103
  //#endregion
106
- export { idLedgerLive, ledgerLiveConnector, name };
104
+ export { idLedgerLive, ledgerLiveConnector, name };
@@ -9,6 +9,5 @@ const isLedgerLive = () => {
9
9
  return false;
10
10
  }
11
11
  };
12
-
13
12
  //#endregion
14
- export { isIframe, isLedgerLive };
13
+ export { isIframe, isLedgerLive };
@@ -1,2 +1,3 @@
1
1
  import { idLedgerLive, ledgerLiveConnector, name } from "./connector.js";
2
2
  import { isIframe, isLedgerLive } from "./helpers.js";
3
+ export { idLedgerLive, isIframe, isLedgerLive, ledgerLiveConnector, name };
@@ -1,11 +1,9 @@
1
1
  import { IFrameEthereumProvider } from "@ledgerhq/iframe-provider";
2
-
3
2
  //#region src/iframe/provider.ts
4
3
  var LedgerIFrameProvider = class extends IFrameEthereumProvider {
5
4
  request({ method, params }) {
6
5
  return this.send(method, params);
7
6
  }
8
7
  };
9
-
10
8
  //#endregion
11
- export { LedgerIFrameProvider };
9
+ export { LedgerIFrameProvider };
package/dist/index.js CHANGED
@@ -4,5 +4,4 @@ import "./iframe/index.js";
4
4
  import { LS_KEY_DERIVATION_PATH } from "./hid/constants.js";
5
5
  import { idLedgerHid, ledgerHIDConnector } from "./hid/connector.js";
6
6
  import "./hid/index.js";
7
-
8
- export { LS_KEY_DERIVATION_PATH, idLedgerHid, idLedgerLive, isIframe, isLedgerLive, ledgerHIDConnector, ledgerLiveConnector, name };
7
+ export { LS_KEY_DERIVATION_PATH, idLedgerHid, idLedgerLive, isIframe, isLedgerLive, ledgerHIDConnector, ledgerLiveConnector, name };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@reef-knot/ledger-connector",
3
- "version": "5.2.0-alpha.1",
3
+ "version": "5.2.0-alpha.2",
4
4
  "main": "dist/index.js",
5
5
  "types": "dist/index.d.ts",
6
6
  "exports": {
@@ -38,7 +38,7 @@
38
38
  "typecheck": "tsc --noEmit"
39
39
  },
40
40
  "devDependencies": {
41
- "@types/w3c-web-hid": "^1.0.2",
41
+ "@types/w3c-web-hid": "^1.0.7",
42
42
  "build-config": "*",
43
43
  "eslint-config-custom": "*",
44
44
  "viem": ">=2.50",