@ledgerhq/live-common 27.1.0 → 27.2.0-next.0

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.
Files changed (120) hide show
  1. package/lib/api/socket.js.map +1 -1
  2. package/lib/bot/index.d.ts.map +1 -1
  3. package/lib/bot/index.js +90 -81
  4. package/lib/bot/index.js.map +1 -1
  5. package/lib/bot/specs.d.ts.map +1 -1
  6. package/lib/bot/specs.js +11 -2
  7. package/lib/bot/specs.js.map +1 -1
  8. package/lib/errors.d.ts +306 -102
  9. package/lib/errors.d.ts.map +1 -1
  10. package/lib/exchange/swap/getKYCStatus.d.ts.map +1 -1
  11. package/lib/exchange/swap/getKYCStatus.js +1 -1
  12. package/lib/exchange/swap/getKYCStatus.js.map +1 -1
  13. package/lib/families/bitcoin/cache.js +3 -3
  14. package/lib/families/bitcoin/cache.js.map +1 -1
  15. package/lib/families/bitcoin/errors.d.ts +3 -1
  16. package/lib/families/bitcoin/errors.d.ts.map +1 -1
  17. package/lib/families/bitcoin/hw-signMessage.d.ts +5 -3
  18. package/lib/families/bitcoin/hw-signMessage.d.ts.map +1 -1
  19. package/lib/families/bitcoin/hw-signMessage.js +2 -2
  20. package/lib/families/bitcoin/hw-signMessage.js.map +1 -1
  21. package/lib/families/cardano/errors.d.ts +6 -2
  22. package/lib/families/cardano/errors.d.ts.map +1 -1
  23. package/lib/families/celo/errors.d.ts +3 -1
  24. package/lib/families/celo/errors.d.ts.map +1 -1
  25. package/lib/families/cosmos/specs.d.ts.map +1 -1
  26. package/lib/families/cosmos/specs.js +12 -8
  27. package/lib/families/cosmos/specs.js.map +1 -1
  28. package/lib/families/crypto_org/errors.d.ts +9 -3
  29. package/lib/families/crypto_org/errors.d.ts.map +1 -1
  30. package/lib/families/ethereum/hw-signMessage.d.ts +7 -3
  31. package/lib/families/ethereum/hw-signMessage.d.ts.map +1 -1
  32. package/lib/families/ethereum/hw-signMessage.js +73 -14
  33. package/lib/families/ethereum/hw-signMessage.js.map +1 -1
  34. package/lib/families/ethereum/hw-signMessage.test.js +99 -23
  35. package/lib/families/ethereum/hw-signMessage.test.js.map +1 -1
  36. package/lib/families/ethereum/transaction.d.ts +1 -1
  37. package/lib/families/ethereum/transaction.d.ts.map +1 -1
  38. package/lib/families/ethereum/types.d.ts +6 -8
  39. package/lib/families/ethereum/types.d.ts.map +1 -1
  40. package/lib/families/filecoin/bridge.integration.test.js +1 -1
  41. package/lib/families/filecoin/bridge.integration.test.js.map +1 -1
  42. package/lib/families/filecoin/hw-signMessage.d.ts +5 -3
  43. package/lib/families/filecoin/hw-signMessage.d.ts.map +1 -1
  44. package/lib/families/filecoin/hw-signMessage.js +2 -2
  45. package/lib/families/filecoin/hw-signMessage.js.map +1 -1
  46. package/lib/families/osmosis/errors.d.ts +9 -3
  47. package/lib/families/osmosis/errors.d.ts.map +1 -1
  48. package/lib/families/osmosis/specs.d.ts.map +1 -1
  49. package/lib/families/osmosis/specs.js +32 -22
  50. package/lib/families/osmosis/specs.js.map +1 -1
  51. package/lib/families/polkadot/errors.d.ts +36 -12
  52. package/lib/families/polkadot/errors.d.ts.map +1 -1
  53. package/lib/families/solana/errors.d.ts +60 -20
  54. package/lib/families/solana/errors.d.ts.map +1 -1
  55. package/lib/families/stellar/api/horizon.js +3 -3
  56. package/lib/families/stellar/api/horizon.js.map +1 -1
  57. package/lib/families/stellar/errors.d.ts +33 -11
  58. package/lib/families/stellar/errors.d.ts.map +1 -1
  59. package/lib/families/tezos/bridge/js.js.map +1 -1
  60. package/lib/families/tron/specs.js +1 -1
  61. package/lib/families/tron/specs.js.map +1 -1
  62. package/lib/featureFlags/defaultFeatures.d.ts.map +1 -1
  63. package/lib/featureFlags/defaultFeatures.js +9 -3
  64. package/lib/featureFlags/defaultFeatures.js.map +1 -1
  65. package/lib/generated/hw-signMessage.d.ts +10 -3
  66. package/lib/generated/hw-signMessage.d.ts.map +1 -1
  67. package/lib/hw/connectApp.js.map +1 -1
  68. package/lib/hw/connectManager.js.map +1 -1
  69. package/lib/hw/deviceAccess.d.ts +1 -1
  70. package/lib/hw/deviceAccess.d.ts.map +1 -1
  71. package/lib/hw/deviceAccess.js.map +1 -1
  72. package/lib/hw/getOnboardingStatePolling.d.ts +1 -1
  73. package/lib/hw/getOnboardingStatePolling.d.ts.map +1 -1
  74. package/lib/hw/getOnboardingStatePolling.js +1 -0
  75. package/lib/hw/getOnboardingStatePolling.js.map +1 -1
  76. package/lib/hw/installLanguage.js.map +1 -1
  77. package/lib/hw/signMessage/index.d.ts +5 -5
  78. package/lib/hw/signMessage/index.d.ts.map +1 -1
  79. package/lib/hw/signMessage/index.js +10 -6
  80. package/lib/hw/signMessage/index.js.map +1 -1
  81. package/lib/hw/signMessage/index.test.js +42 -43
  82. package/lib/hw/signMessage/index.test.js.map +1 -1
  83. package/lib/hw/signMessage/types.d.ts +1 -1
  84. package/lib/hw/signMessage/types.d.ts.map +1 -1
  85. package/lib/hw/uninstallLanguage.js.map +1 -1
  86. package/lib/walletconnect/index.d.ts +1 -1
  87. package/lib/walletconnect/index.d.ts.map +1 -1
  88. package/lib/walletconnect/index.js +1 -9
  89. package/lib/walletconnect/index.js.map +1 -1
  90. package/lib/walletconnect/walletconnect.test.js.map +1 -1
  91. package/package.json +17 -17
  92. package/src/api/socket.ts +1 -1
  93. package/src/bot/index.ts +174 -113
  94. package/src/bot/specs.ts +16 -2
  95. package/src/exchange/swap/getKYCStatus.ts +3 -1
  96. package/src/families/bitcoin/cache.ts +2 -2
  97. package/src/families/bitcoin/hw-signMessage.ts +3 -3
  98. package/src/families/cosmos/specs.ts +14 -10
  99. package/src/families/ethereum/hw-signMessage.test.ts +105 -21
  100. package/src/families/ethereum/hw-signMessage.ts +68 -16
  101. package/src/families/ethereum/types.ts +6 -8
  102. package/src/families/filecoin/__snapshots__/bridge.integration.test.ts.snap +27 -0
  103. package/src/families/filecoin/bridge.integration.test.ts +6 -2
  104. package/src/families/filecoin/hw-signMessage.ts +3 -3
  105. package/src/families/osmosis/specs.ts +35 -25
  106. package/src/families/stellar/api/horizon.ts +4 -4
  107. package/src/families/tezos/bridge/js.ts +1 -1
  108. package/src/families/tron/specs.ts +1 -1
  109. package/src/featureFlags/defaultFeatures.ts +9 -3
  110. package/src/hw/connectApp.ts +1 -1
  111. package/src/hw/connectManager.ts +1 -1
  112. package/src/hw/deviceAccess.ts +2 -2
  113. package/src/hw/getOnboardingStatePolling.ts +5 -1
  114. package/src/hw/installLanguage.ts +1 -1
  115. package/src/hw/signMessage/index.test.ts +48 -45
  116. package/src/hw/signMessage/index.ts +23 -9
  117. package/src/hw/signMessage/types.ts +4 -1
  118. package/src/hw/uninstallLanguage.ts +1 -1
  119. package/src/walletconnect/index.ts +3 -11
  120. package/src/walletconnect/walletconnect.test.ts +2 -0
@@ -76,7 +76,7 @@ const identifyTransport = (t) => (typeof t.id === "string" ? t.id : "");
76
76
  const needsCleanup = {};
77
77
  // when a series of APDUs are interrupted, this is called
78
78
  // so we don't forget to cleanup on the next withDevice
79
- export const cancelDeviceAction = (transport: Transport) => {
79
+ export const cancelDeviceAction = (transport: Transport): void => {
80
80
  needsCleanup[identifyTransport(transport)] = true;
81
81
  };
82
82
  const deviceQueues = {};
@@ -158,7 +158,7 @@ export const withDevice =
158
158
  if (sub) sub.unsubscribe();
159
159
  };
160
160
  });
161
- export const genericCanRetryOnError = (err: Error | null | undefined) => {
161
+ export const genericCanRetryOnError = (err: unknown): boolean => {
162
162
  if (err instanceof WrongAppForCurrency) return false;
163
163
  if (err instanceof WrongDeviceForAccount) return false;
164
164
  if (err instanceof CantOpenDevice) return false;
@@ -16,6 +16,7 @@ import {
16
16
  DeviceExtractOnboardingStateError,
17
17
  DisconnectedDevice,
18
18
  CantOpenDevice,
19
+ TransportRaceCondition,
19
20
  } from "@ledgerhq/errors";
20
21
  import { FirmwareInfo } from "@ledgerhq/types-live";
21
22
  import {
@@ -142,13 +143,16 @@ export const getOnboardingStatePolling = ({
142
143
  return delayedOnceOnboardingStateObservable.pipe(repeat());
143
144
  };
144
145
 
145
- export const isAllowedOnboardingStatePollingError = (error: Error): boolean => {
146
+ export const isAllowedOnboardingStatePollingError = (
147
+ error: unknown
148
+ ): boolean => {
146
149
  if (
147
150
  error &&
148
151
  // Timeout error is thrown by rxjs's timeout
149
152
  (error instanceof TimeoutError ||
150
153
  error instanceof DisconnectedDevice ||
151
154
  error instanceof CantOpenDevice ||
155
+ error instanceof TransportRaceCondition ||
152
156
  error instanceof TransportStatusError)
153
157
  ) {
154
158
  return true;
@@ -125,7 +125,7 @@ export default function installLanguage({
125
125
 
126
126
  subscriber.complete();
127
127
  }),
128
- catchError((e: Error) => {
128
+ catchError((e: unknown) => {
129
129
  if (
130
130
  e instanceof DeviceOnDashboardExpected ||
131
131
  (e &&
@@ -1,19 +1,38 @@
1
+ import BigNumber from "bignumber.js";
1
2
  import type { CryptoCurrency } from "@ledgerhq/types-cryptoassets";
2
3
  import type { Account } from "@ledgerhq/types-live";
3
- import BigNumber from "bignumber.js";
4
+ import { createFixtureCryptoCurrency } from "../../mock/fixtures/cryptoCurrencies";
5
+ import { TypedMessageData } from "../../families/ethereum/types";
4
6
  import { prepareMessageToSign } from "./index";
5
7
  import { MessageData } from "./types";
6
8
 
9
+ const signResult = {
10
+ message: "Sign results",
11
+ rawMessage: "Sign raw results",
12
+ };
13
+ const signFunction = jest.fn(() => signResult);
14
+ jest.mock("../../generated/hw-signMessage", () => {
15
+ return {
16
+ signExistFamily: {
17
+ prepareMessageToSign: function () {
18
+ return signFunction();
19
+ },
20
+ },
21
+ bitcoin: {
22
+ otherMethod: function () {},
23
+ },
24
+ };
25
+ });
26
+
7
27
  describe("prepareMessageToSign", () => {
8
- it("returns the prepared data from a simple string", () => {
28
+ it("calls the perFamily function if it's exist and returns this function results", () => {
9
29
  // Given
10
- const crypto = createCryptoCurrency("ethereum");
30
+ const crypto = createFixtureCryptoCurrency("signExistFamily");
11
31
  const account = createAccount(crypto);
12
- const message = "4d6573736167652064652074657374";
13
- const expectedRawMessage = "0x4d6573736167652064652074657374";
32
+ const message = "whatever";
14
33
 
15
34
  // When
16
- let result: MessageData | null = null;
35
+ let result: MessageData | TypedMessageData | undefined;
17
36
  let error: unknown = null;
18
37
  try {
19
38
  result = prepareMessageToSign(account, message);
@@ -23,10 +42,26 @@ describe("prepareMessageToSign", () => {
23
42
 
24
43
  // Then
25
44
  expect(error).toBeNull();
45
+ expect(signFunction).toBeCalledTimes(1);
46
+ expect(result).toEqual(signResult);
47
+ });
48
+
49
+ it("returns a default implementation if account is linked to a crypto able to sign but with no prepareMessageToSign function", () => {
50
+ // Given
51
+ const currency = createFixtureCryptoCurrency("bitcoin");
52
+ const account = createAccount(currency);
53
+ const message = "4d6573736167652064652074657374";
54
+ const expectedPath = "44'/60'/0'/0/0";
55
+ const expectedRawMessage = "0x4d6573736167652064652074657374";
56
+
57
+ // // When
58
+ const result = prepareMessageToSign(account, message);
59
+
60
+ // // Then
26
61
  expect(result).toEqual({
27
- currency: crypto,
28
- path: "44'/60'/0'/0/0",
29
- derivationMode: "ethM",
62
+ currency,
63
+ path: expectedPath,
64
+ derivationMode: account.derivationMode,
30
65
  message: "Message de test",
31
66
  rawMessage: expectedRawMessage,
32
67
  });
@@ -34,12 +69,12 @@ describe("prepareMessageToSign", () => {
34
69
 
35
70
  it("returns an error if account is not linked to a crypto able to sign a message", () => {
36
71
  // Given
37
- const crypto = createCryptoCurrency("mycoin");
72
+ const crypto = createFixtureCryptoCurrency("mycoin");
38
73
  const account = createAccount(crypto);
39
- const message = "4d6573736167652064652074657374";
74
+ const message = "whatever";
40
75
 
41
76
  // When
42
- let result: MessageData | null = null;
77
+ let result: MessageData | TypedMessageData | undefined;
43
78
  let error: Error | null = null;
44
79
  try {
45
80
  result = prepareMessageToSign(account, message);
@@ -48,43 +83,11 @@ describe("prepareMessageToSign", () => {
48
83
  }
49
84
 
50
85
  // Then
51
- expect(result).toBeNull();
86
+ expect(result).toBeUndefined();
52
87
  expect(error).toEqual(Error("Crypto does not support signMessage"));
53
88
  });
54
89
  });
55
90
 
56
- const createCryptoCurrency = (family: string): CryptoCurrency => ({
57
- type: "CryptoCurrency",
58
- id: "testCoinId",
59
- coinType: 8008,
60
- name: "MyCoin",
61
- managerAppName: "MyCoin",
62
- ticker: "MYC",
63
- countervalueTicker: "MYC",
64
- scheme: "mycoin",
65
- color: "#ff0000",
66
- family,
67
- units: [
68
- {
69
- name: "MYC",
70
- code: "MYC",
71
- magnitude: 8,
72
- },
73
- {
74
- name: "SmallestUnit",
75
- code: "SMALLESTUNIT",
76
- magnitude: 0,
77
- },
78
- ],
79
- explorerViews: [
80
- {
81
- address: "https://mycoinexplorer.com/account/$address",
82
- tx: "https://mycoinexplorer.com/transaction/$hash",
83
- token: "https://mycoinexplorer.com/token/$contractAddress/?a=$address",
84
- },
85
- ],
86
- });
87
-
88
91
  const createAccount = (crypto: CryptoCurrency): Account => ({
89
92
  type: "Account",
90
93
  id: "ethereumjs:2:ethereum:0x01:",
@@ -13,17 +13,29 @@ import { createAction as createAppAction } from "../actions/app";
13
13
  import type { Device } from "../actions/types";
14
14
  import type { ConnectAppEvent, Input as ConnectAppInput } from "../connectApp";
15
15
  import { withDevice } from "../deviceAccess";
16
- import type { MessageData, Resolver, Result } from "./types";
16
+ import type { MessageData, SignMessage, Result } from "./types";
17
17
  import { DerivationMode } from "../../derivation";
18
18
 
19
19
  export const prepareMessageToSign = (
20
- { currency, freshAddressPath, derivationMode }: Account,
20
+ account: Account,
21
21
  message: string
22
- ): MessageData | null => {
22
+ ): MessageData => {
23
+ const { currency, freshAddressPath, derivationMode } = account;
24
+
23
25
  if (!perFamily[currency.family]) {
24
26
  throw new Error("Crypto does not support signMessage");
25
27
  }
26
28
 
29
+ if ("prepareMessageToSign" in perFamily[currency.family]) {
30
+ return perFamily[currency.family].prepareMessageToSign(
31
+ currency,
32
+ freshAddressPath,
33
+ derivationMode,
34
+ message
35
+ );
36
+ }
37
+
38
+ // Default implementation
27
39
  return {
28
40
  currency: currency,
29
41
  path: freshAddressPath,
@@ -33,9 +45,9 @@ export const prepareMessageToSign = (
33
45
  };
34
46
  };
35
47
 
36
- const dispatch: Resolver = (transport, opts) => {
48
+ const signMessage: SignMessage = (transport, opts) => {
37
49
  const { currency, verify } = opts;
38
- const signMessage = perFamily[currency.family];
50
+ const signMessage = perFamily[currency.family].signMessage;
39
51
  invariant(signMessage, `signMessage is not implemented for ${currency.id}`);
40
52
  return signMessage(transport, opts)
41
53
  .then((result) => {
@@ -87,7 +99,7 @@ export const signMessageExec = ({
87
99
  deviceId,
88
100
  }: Input): Observable<Result> => {
89
101
  const result: Observable<Result> = withDevice(deviceId)((transport) =>
90
- from(dispatch(transport, request.message))
102
+ from(signMessage(transport, request.message))
91
103
  );
92
104
  return result;
93
105
  };
@@ -99,8 +111,10 @@ const initialState: BaseState = {
99
111
  };
100
112
 
101
113
  export const createAction = (
102
- connectAppExec: (arg0: ConnectAppInput) => Observable<ConnectAppEvent>,
103
- signMessage: (arg0: Input) => Observable<Result> = signMessageExec
114
+ connectAppExec: (
115
+ connectAppInput: ConnectAppInput
116
+ ) => Observable<ConnectAppEvent>,
117
+ signMessage: (input: Input) => Observable<Result> = signMessageExec
104
118
  ) => {
105
119
  const useHook = (
106
120
  reduxDevice: Device | null | undefined,
@@ -175,4 +189,4 @@ export const createAction = (
175
189
  }),
176
190
  };
177
191
  };
178
- export default dispatch;
192
+ export default signMessage;
@@ -17,4 +17,7 @@ export type MessageData = {
17
17
  message: string;
18
18
  rawMessage: string;
19
19
  };
20
- export type Resolver = (arg0: Transport, arg1: MessageData) => Promise<Result>;
20
+ export type SignMessage = (
21
+ transport: Transport,
22
+ message: MessageData
23
+ ) => Promise<Result>;
@@ -82,7 +82,7 @@ export default function unistallLanguage({
82
82
 
83
83
  subscriber.complete();
84
84
  }),
85
- catchError((e: Error) => {
85
+ catchError((e: unknown) => {
86
86
  if (
87
87
  e instanceof DeviceOnDashboardExpected ||
88
88
  (e &&
@@ -39,7 +39,7 @@ export type WCCallRequest =
39
39
  method: "send" | "sign";
40
40
  data: Transaction;
41
41
  };
42
- type Parser = (arg0: Account, arg1: WCPayload) => Promise<WCCallRequest>;
42
+ type Parser = (account: Account, payload: WCPayload) => Promise<WCCallRequest>;
43
43
  export const parseCallRequest: Parser = async (account, payload) => {
44
44
  let wcTransactionData, bridge, transaction, message, rawMessage, hashes;
45
45
 
@@ -52,12 +52,11 @@ export const parseCallRequest: Parser = async (account, payload) => {
52
52
 
53
53
  // @dev: Today, `eth_signTypedData` is versionned. We can't only check `eth_signTypedData`
54
54
  // This regex matches `eth_signTypedData` and `eth_signTypedData_v[0-9]`
55
+ // https://docs.metamask.io/guide/signing-data.html
55
56
  case payload.method.match(/eth_signTypedData(_v.)?$/)?.input:
56
57
  message = JSON.parse(payload.params[1]);
57
58
  hashes = {
58
- // $FlowFixMe
59
59
  domainHash: bufferToHex(domainHash(message)),
60
- // $FlowFixMe
61
60
  messageHash: bufferToHex(messageHash(message)),
62
61
  };
63
62
  case "eth_sign":
@@ -67,7 +66,6 @@ export const parseCallRequest: Parser = async (account, payload) => {
67
66
  stringHash:
68
67
  "0x" +
69
68
  sha("sha256")
70
- // $FlowFixMe
71
69
  .update(Buffer.from(payload.params[1].slice(2), "hex"))
72
70
  .digest("hex"),
73
71
  };
@@ -76,16 +74,10 @@ export const parseCallRequest: Parser = async (account, payload) => {
76
74
  message || Buffer.from(payload.params[0].slice(2), "hex").toString();
77
75
  rawMessage = rawMessage || payload.params[0];
78
76
  hashes = hashes || {
79
- stringHash:
80
- "0x" +
81
- sha("sha256")
82
- // $FlowFixMe
83
- .update(message)
84
- .digest("hex"),
77
+ stringHash: "0x" + sha("sha256").update(message).digest("hex"),
85
78
  };
86
79
  return {
87
80
  type: "message",
88
- // $FlowFixMe (can't figure out MessageData | TypedMessageData)
89
81
  data: {
90
82
  path: account.freshAddressPath,
91
83
  message,
@@ -51,6 +51,7 @@ describe("walletconnect", () => {
51
51
  })
52
52
  ).rejects.toThrow("wrong payload");
53
53
  });
54
+
54
55
  test("should parse personal_sign payloads", async () => {
55
56
  expect(
56
57
  await parseCallRequest(account, {
@@ -132,6 +133,7 @@ describe("walletconnect", () => {
132
133
  type: "message",
133
134
  });
134
135
  });
136
+
135
137
  test("should parse eth_sendTransaction payloads", async () => {
136
138
  const raw: WCPayloadTransaction = {
137
139
  data: "0x",