@ledgerhq/live-common 21.24.0 → 21.26.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 (76) hide show
  1. package/lib/account/support.d.ts.map +1 -1
  2. package/lib/account/support.js +1 -25
  3. package/lib/account/support.js.map +1 -1
  4. package/lib/api/explorerConfig/index.d.ts.map +1 -1
  5. package/lib/api/explorerConfig/index.js +0 -4
  6. package/lib/api/explorerConfig/index.js.map +1 -1
  7. package/lib/errors.d.ts +3 -0
  8. package/lib/errors.d.ts.map +1 -1
  9. package/lib/errors.js +3 -2
  10. package/lib/errors.js.map +1 -1
  11. package/lib/families/bitcoin/test-dataset.js +1 -1
  12. package/lib/families/bitcoin/test-dataset.js.map +1 -1
  13. package/lib/families/crypto_org/deviceTransactionConfig.d.ts +11 -0
  14. package/lib/families/crypto_org/deviceTransactionConfig.d.ts.map +1 -0
  15. package/lib/families/crypto_org/deviceTransactionConfig.js +40 -0
  16. package/lib/families/crypto_org/deviceTransactionConfig.js.map +1 -0
  17. package/lib/families/ethereum/modules/compound.d.ts.map +1 -1
  18. package/lib/families/ethereum/modules/compound.js +2 -1
  19. package/lib/families/ethereum/modules/compound.js.map +1 -1
  20. package/lib/families/ethereum/modules/erc1155.d.ts.map +1 -1
  21. package/lib/families/ethereum/modules/erc1155.js +2 -1
  22. package/lib/families/ethereum/modules/erc1155.js.map +1 -1
  23. package/lib/families/ethereum/modules/erc20.d.ts.map +1 -1
  24. package/lib/families/ethereum/modules/erc20.js +2 -1
  25. package/lib/families/ethereum/modules/erc20.js.map +1 -1
  26. package/lib/families/ethereum/modules/erc721.d.ts.map +1 -1
  27. package/lib/families/ethereum/modules/erc721.js +2 -1
  28. package/lib/families/ethereum/modules/erc721.js.map +1 -1
  29. package/lib/families/ethereum/modules/index.d.ts +5 -0
  30. package/lib/families/ethereum/modules/index.d.ts.map +1 -1
  31. package/lib/families/ethereum/modules/index.js.map +1 -1
  32. package/lib/families/ethereum/signOperation.d.ts.map +1 -1
  33. package/lib/families/ethereum/signOperation.js +33 -24
  34. package/lib/families/ethereum/signOperation.js.map +1 -1
  35. package/lib/families/polkadot/address.d.ts.map +1 -1
  36. package/lib/families/polkadot/address.js +5 -1
  37. package/lib/families/polkadot/address.js.map +1 -1
  38. package/lib/families/polkadot/js-getTransactionStatus.d.ts.map +1 -1
  39. package/lib/families/polkadot/js-getTransactionStatus.js +6 -2
  40. package/lib/families/polkadot/js-getTransactionStatus.js.map +1 -1
  41. package/lib/families/tezos/bridge/js.d.ts.map +1 -1
  42. package/lib/families/tezos/bridge/js.js +19 -20
  43. package/lib/families/tezos/bridge/js.js.map +1 -1
  44. package/lib/families/tezos/hw-getAddress.d.ts.map +1 -1
  45. package/lib/families/tezos/hw-getAddress.js +1 -3
  46. package/lib/families/tezos/hw-getAddress.js.map +1 -1
  47. package/lib/families/tezos/synchronisation.d.ts.map +1 -1
  48. package/lib/families/tezos/synchronisation.js +1 -1
  49. package/lib/families/tezos/synchronisation.js.map +1 -1
  50. package/lib/generated/deviceTransactionConfig.d.ts +2 -0
  51. package/lib/generated/deviceTransactionConfig.d.ts.map +1 -1
  52. package/lib/generated/deviceTransactionConfig.js +18 -16
  53. package/lib/generated/deviceTransactionConfig.js.map +1 -1
  54. package/lib/hw/actions/transaction.d.ts +3 -1
  55. package/lib/hw/actions/transaction.d.ts.map +1 -1
  56. package/lib/hw/actions/transaction.js +4 -2
  57. package/lib/hw/actions/transaction.js.map +1 -1
  58. package/package.json +8 -8
  59. package/src/account/support.ts +1 -25
  60. package/src/api/explorerConfig/index.ts +0 -4
  61. package/src/errors.ts +3 -0
  62. package/src/families/bitcoin/test-dataset.ts +1 -1
  63. package/src/families/crypto_org/deviceTransactionConfig.ts +52 -0
  64. package/src/families/ethereum/modules/compound.ts +2 -0
  65. package/src/families/ethereum/modules/erc1155.ts +2 -0
  66. package/src/families/ethereum/modules/erc20.ts +2 -0
  67. package/src/families/ethereum/modules/erc721.ts +2 -0
  68. package/src/families/ethereum/modules/index.ts +10 -0
  69. package/src/families/ethereum/signOperation.ts +27 -8
  70. package/src/families/polkadot/address.ts +8 -2
  71. package/src/families/polkadot/js-getTransactionStatus.ts +6 -2
  72. package/src/families/tezos/bridge/js.ts +41 -40
  73. package/src/families/tezos/hw-getAddress.ts +1 -3
  74. package/src/families/tezos/synchronisation.ts +4 -3
  75. package/src/generated/deviceTransactionConfig.ts +3 -0
  76. package/src/hw/actions/transaction.ts +7 -2
package/package.json CHANGED
@@ -8,7 +8,7 @@
8
8
  "type": "git",
9
9
  "url": "https://github.com/LedgerHQ/ledger-live-common"
10
10
  },
11
- "version": "21.24.0",
11
+ "version": "21.26.0",
12
12
  "main": "lib/index.js",
13
13
  "types": "lib/index.d.ts",
14
14
  "license": "Apache-2.0",
@@ -44,13 +44,13 @@
44
44
  "dependencies": {
45
45
  "@crypto-com/chain-jslib": "0.0.19",
46
46
  "@ledgerhq/compressjs": "1.3.2",
47
- "@ledgerhq/cryptoassets": "6.22.0",
47
+ "@ledgerhq/cryptoassets": "6.22.3",
48
48
  "@ledgerhq/devices": "6.20.0",
49
49
  "@ledgerhq/errors": "6.10.0",
50
50
  "@ledgerhq/hw-app-algorand": "6.20.0",
51
51
  "@ledgerhq/hw-app-btc": "6.21.0",
52
52
  "@ledgerhq/hw-app-cosmos": "6.20.0",
53
- "@ledgerhq/hw-app-eth": "6.22.0",
53
+ "@ledgerhq/hw-app-eth": "6.22.3",
54
54
  "@ledgerhq/hw-app-polkadot": "6.20.0",
55
55
  "@ledgerhq/hw-app-solana": "^6.20.0",
56
56
  "@ledgerhq/hw-app-str": "6.20.0",
@@ -101,7 +101,7 @@
101
101
  "ethereumjs-common": "^1.5.2",
102
102
  "ethereumjs-tx": "^2.1.2",
103
103
  "ethereumjs-util": "^7.1.3",
104
- "expect": "^27.4.2",
104
+ "expect": "^27.4.6",
105
105
  "generic-pool": "^3.8.2",
106
106
  "invariant": "^2.2.2",
107
107
  "isomorphic-ws": "^4.0.1",
@@ -127,7 +127,7 @@
127
127
  "stellar-sdk": "^9.1.0",
128
128
  "triple-beam": "^1.3.0",
129
129
  "winston": "^3.3.3",
130
- "xstate": "^4.26.1",
130
+ "xstate": "^4.27.0",
131
131
  "zcash-bitcore-lib": "^0.13.20-rc3"
132
132
  },
133
133
  "devDependencies": {
@@ -149,15 +149,15 @@
149
149
  "eslint-config-prettier": "^8.3.0",
150
150
  "eslint-config-typescript": "^3.0.0",
151
151
  "eslint-formatter-pretty": "^3.0.1",
152
- "eslint-plugin-import": "^2.25.3",
152
+ "eslint-plugin-import": "^2.25.4",
153
153
  "eslint-plugin-jsx-a11y": "^6.5.1",
154
154
  "eslint-plugin-prettier": "^3.4.0",
155
- "eslint-plugin-react": "^7.27.1",
155
+ "eslint-plugin-react": "^7.28.0",
156
156
  "eslint-plugin-react-hooks": "^4.3.0",
157
157
  "eslint-plugin-typescript": "^0.14.0",
158
158
  "fs": "^0.0.1-security",
159
159
  "glob": "^7.2.0",
160
- "jest": "^27.4.5",
160
+ "jest": "^27.4.7",
161
161
  "jest-file-snapshot": "^0.5.0",
162
162
  "prettier": "2.3.2",
163
163
  "react": "17.0.2",
@@ -20,31 +20,7 @@ import { getMainAccount } from "../account";
20
20
  import { getAccountBridge } from "../bridge";
21
21
  import jsBridges from "../generated/bridge/js";
22
22
 
23
- const experimentalIntegrations = [
24
- "algorand",
25
- "bitcoin",
26
- "bsc",
27
- "bitcoin_cash",
28
- "litecoin",
29
- "dash",
30
- "qtum",
31
- "zcash",
32
- "bitcoin_gold",
33
- "stratis",
34
- "dogecoin",
35
- "digibyte",
36
- "komodo",
37
- "pivx",
38
- "zencash",
39
- "vertcoin",
40
- "peercoin",
41
- "viacoin",
42
- "stakenet",
43
- "stealthcoin",
44
- "decred",
45
- "bitcoin_testnet",
46
- "tezos",
47
- ];
23
+ const experimentalIntegrations = ["algorand", "tezos"];
48
24
  export function shouldUseJS(currency: CryptoCurrency) {
49
25
  const jsBridge = jsBridges[currency.family];
50
26
  if (!jsBridge) return false;
@@ -14,10 +14,6 @@ const initialExplorerConfig: FullConfig = {
14
14
  bitcoin_cash: {
15
15
  id: "bch",
16
16
  stable: {
17
- base: "EXPLORER",
18
- version: "v2",
19
- },
20
- experimental: {
21
17
  base: "EXPLORER",
22
18
  version: "v3",
23
19
  },
package/src/errors.ts CHANGED
@@ -23,6 +23,9 @@ export const LowerThanMinimumRelayFee = createCustomErrorClass(
23
23
  export const TransactionRefusedOnDevice = createCustomErrorClass(
24
24
  "TransactionRefusedOnDevice"
25
25
  );
26
+ export const InvalidAddressBecauseAlreadyDelegated = createCustomErrorClass(
27
+ "InvalidAddressBecauseAlreadyDelegated"
28
+ );
26
29
  export const TronNoFrozenForBandwidth = createCustomErrorClass(
27
30
  "TronNoFrozenForBandwidth"
28
31
  );
@@ -18,7 +18,7 @@ import vertcoin from "./datasets/vertcoin";
18
18
  import viacoin from "./datasets/viacoin";
19
19
  // import zcash from "./datasets/zcash";
20
20
  const dataset: DatasetTest<Transaction> = {
21
- implementations: ["js", "libcore", "mock"],
21
+ implementations: ["js", "mock"],
22
22
  currencies: {
23
23
  bitcoin,
24
24
  // bitcoin_cash,
@@ -0,0 +1,52 @@
1
+ import type { AccountLike, Account, TransactionStatus } from "../../types";
2
+ import type { Transaction } from "./types";
3
+ import type { DeviceTransactionField } from "../../transaction";
4
+
5
+ function getDeviceTransactionConfig({
6
+ transaction,
7
+ status: { estimatedFees },
8
+ }: {
9
+ account: AccountLike;
10
+ parentAccount?: Account;
11
+ transaction: Transaction;
12
+ status: TransactionStatus;
13
+ }): Array<DeviceTransactionField> {
14
+ const fields: Array<DeviceTransactionField> = [];
15
+
16
+ if (transaction.useAllAmount) {
17
+ fields.push({
18
+ type: "text",
19
+ label: "Method",
20
+ value: "Send all",
21
+ });
22
+ } else {
23
+ fields.push({
24
+ type: "text",
25
+ label: "Method",
26
+ value: "Send",
27
+ });
28
+ fields.push({
29
+ type: "amount",
30
+ label: "Amount",
31
+ });
32
+ }
33
+
34
+ if (!estimatedFees.isZero()) {
35
+ fields.push({
36
+ type: "fees",
37
+ label: "Fees",
38
+ });
39
+ }
40
+
41
+ if (transaction.memo) {
42
+ fields.push({
43
+ type: "text",
44
+ label: "Memo",
45
+ value: transaction.memo,
46
+ });
47
+ }
48
+
49
+ return fields;
50
+ }
51
+
52
+ export default getDeviceTransactionConfig;
@@ -160,6 +160,8 @@ const compoundSupply: ModeModule = {
160
160
  ];
161
161
  }
162
162
  },
163
+
164
+ getResolutionConfig: () => ({ erc20: true, externalPlugins: true }),
163
165
  };
164
166
 
165
167
  /**
@@ -122,6 +122,8 @@ const erc1155Transfer: ModeModule = {
122
122
  },
123
123
 
124
124
  prepareTransaction,
125
+
126
+ getResolutionConfig: () => ({ nft: true }),
125
127
  };
126
128
 
127
129
  function serializeTransactionData(
@@ -138,6 +138,8 @@ const erc20approve: ModeModule = {
138
138
  fillOptimisticOperation(_account, _transaction, operation) {
139
139
  operation.type = "FEES";
140
140
  },
141
+
142
+ getResolutionConfig: () => ({ erc20: true, externalPlugins: true }),
141
143
  };
142
144
  export const modes: Record<Modes, ModeModule> = {
143
145
  "erc20.approve": erc20approve,
@@ -119,6 +119,8 @@ const erc721Transfer: ModeModule = {
119
119
  fillOptimisticOperation(a, t, op) {
120
120
  op.type = "FEES";
121
121
  },
122
+
123
+ getResolutionConfig: () => ({ nft: true }),
122
124
  };
123
125
 
124
126
  function serializeTransactionData(
@@ -20,6 +20,8 @@ import type { Modes as ERC20Modes } from "./erc20";
20
20
  import type { Modes as SendModes } from "./send";
21
21
  import type { Modes as ERC721Modes } from "./erc721";
22
22
  import type { Modes as ERC1155Modes } from "./erc1155";
23
+ import { ResolutionConfig } from "@ledgerhq/hw-app-eth/lib/services/types";
24
+
23
25
  const modules = {
24
26
  erc20,
25
27
  compound,
@@ -98,6 +100,14 @@ export type ModeModule = {
98
100
  account: Account,
99
101
  transaction: Transaction
100
102
  ) => Promise<Transaction>;
103
+
104
+ /**
105
+ * tells what needs to be resolved in the transaction
106
+ */
107
+ getResolutionConfig?: (
108
+ account: Account,
109
+ transaction: Transaction
110
+ ) => ResolutionConfig;
101
111
  };
102
112
  export const modes: Record<TransactionMode, ModeModule> = {} as Record<
103
113
  TransactionMode,
@@ -7,6 +7,7 @@ import { log } from "@ledgerhq/logs";
7
7
  import { FeeNotLoaded } from "@ledgerhq/errors";
8
8
  import Eth from "@ledgerhq/hw-app-eth";
9
9
  import { byContractAddressAndChainId } from "@ledgerhq/hw-app-eth/erc20";
10
+ import ethLedgerServices from "@ledgerhq/hw-app-eth/lib/services/ledger";
10
11
  import type { Transaction } from "./types";
11
12
  import type { Operation, Account, SignOperationEvent } from "../../types";
12
13
  import { getGasLimit, buildEthereumTx } from "./transaction";
@@ -15,6 +16,7 @@ import { withDevice } from "../../hw/deviceAccess";
15
16
  import { modes } from "./modules";
16
17
  import { isNFTActive } from "../../nft";
17
18
  import { getEnv } from "../../env";
19
+ import { LoadConfig } from "@ledgerhq/hw-app-eth/lib/services/types";
18
20
  export const signOperation = ({
19
21
  account,
20
22
  deviceId,
@@ -61,13 +63,31 @@ export const signOperation = ({
61
63
  const value = new BigNumber(
62
64
  "0x" + (tx.value.toString("hex") || "0")
63
65
  );
64
- const eth = new Eth(transport);
66
+
67
+ const txHex = tx.serialize().toString("hex");
68
+
69
+ const loadConfig: LoadConfig = {};
65
70
  if (isNFTActive(account.currency)) {
66
- eth.setLoadConfig({
67
- nftExplorerBaseURL:
68
- getEnv("NFT_ETH_METADATA_SERVICE") + "/v1/ethereum",
69
- });
71
+ loadConfig.nftExplorerBaseURL =
72
+ getEnv("NFT_ETH_METADATA_SERVICE") + "/v1/ethereum";
70
73
  }
74
+
75
+ const m = modes[transaction.mode];
76
+ invariant(m, "missing module for mode=" + transaction.mode);
77
+
78
+ const resolutionConfig = m.getResolutionConfig
79
+ ? m.getResolutionConfig(account, transaction)
80
+ : {};
81
+
82
+ const resolution = await ethLedgerServices.resolveTransaction(
83
+ txHex,
84
+ loadConfig,
85
+ resolutionConfig
86
+ );
87
+
88
+ const eth = new Eth(transport);
89
+ eth.setLoadConfig(loadConfig);
90
+
71
91
  // FIXME this part is still required for compound to correctly display info on the device
72
92
  const addrs =
73
93
  (fillTransactionDataResult &&
@@ -91,7 +111,8 @@ export const signOperation = ({
91
111
  });
92
112
  const result = await eth.signTransaction(
93
113
  freshAddressPath,
94
- tx.serialize().toString("hex")
114
+ txHex,
115
+ resolution
95
116
  );
96
117
  if (cancelled) return;
97
118
  o.next({
@@ -131,8 +152,6 @@ export const signOperation = ({
131
152
  date: new Date(),
132
153
  extra: {},
133
154
  };
134
- const m = modes[transaction.mode];
135
- invariant(m, "missing module for mode=" + transaction.mode);
136
155
  m.fillOptimisticOperation(account, transaction, operation);
137
156
  o.next({
138
157
  type: "signed",
@@ -1,4 +1,5 @@
1
- import { decodeAddress } from "@polkadot/util-crypto";
1
+ import { encodeAddress, decodeAddress } from "@polkadot/util-crypto";
2
+ import { hexToU8a, isHex } from "@polkadot/util";
2
3
 
3
4
  const POLKADOT_SS58_PREFIX = 0;
4
5
 
@@ -7,6 +8,7 @@ const POLKADOT_SS58_PREFIX = 0;
7
8
  *
8
9
  * @param {*} address
9
10
  */
11
+ // TODO Cache this to improve perf
10
12
  export const isValidAddress = (
11
13
  address: string,
12
14
  ss58Format: number = POLKADOT_SS58_PREFIX
@@ -14,7 +16,11 @@ export const isValidAddress = (
14
16
  if (!address) return false;
15
17
 
16
18
  try {
17
- decodeAddress(address, false, ss58Format);
19
+ encodeAddress(
20
+ isHex(address)
21
+ ? hexToU8a(address)
22
+ : decodeAddress(address, false, ss58Format)
23
+ );
18
24
  return true;
19
25
  } catch (err) {
20
26
  return false;
@@ -58,7 +58,9 @@ const getSendTransactionStatus = async (
58
58
  } else if (a.freshAddress === t.recipient) {
59
59
  errors.recipient = new InvalidAddressBecauseDestinationIsAlsoSource();
60
60
  } else if (!isValidAddress(t.recipient)) {
61
- errors.recipient = new InvalidAddress("");
61
+ errors.recipient = new InvalidAddress("", {
62
+ currencyName: a.currency.name,
63
+ });
62
64
  }
63
65
 
64
66
  const estimatedFees = t.fees || new BigNumber(0);
@@ -181,7 +183,9 @@ const getTransactionStatus = async (a: Account, t: Transaction) => {
181
183
  if (!t.recipient) {
182
184
  errors.recipient = new RecipientRequired("");
183
185
  } else if (!isValidAddress(t.recipient)) {
184
- errors.recipient = new InvalidAddress("");
186
+ errors.recipient = new InvalidAddress("", {
187
+ currencyName: a.currency.name,
188
+ });
185
189
  } else if (await isControllerAddress(t.recipient)) {
186
190
  errors.recipient = new PolkadotUnauthorizedOperation(
187
191
  "Recipient is already a controller"
@@ -30,6 +30,7 @@ import { getEnv } from "../../../env";
30
30
  import { signOperation } from "../signOperation";
31
31
  import { patchOperationWithHash } from "../../../operation";
32
32
  import { log } from "@ledgerhq/logs";
33
+ import { InvalidAddressBecauseAlreadyDelegated } from "../../../errors";
33
34
 
34
35
  const receive = makeAccountBridgeReceive();
35
36
 
@@ -70,54 +71,52 @@ const getTransactionStatus = async (
70
71
  const { tezosResources } = account;
71
72
  if (!tezosResources) throw new Error("tezosResources is missing");
72
73
 
73
- if (!t.taquitoError) {
74
- if (t.mode !== "undelegate") {
75
- if (account.freshAddress === t.recipient) {
76
- errors.recipient = new InvalidAddressBecauseDestinationIsAlsoSource();
77
- } else {
78
- const { recipientError, recipientWarning } = await validateRecipient(
79
- account.currency,
80
- t.recipient
81
- );
74
+ if (t.mode !== "undelegate") {
75
+ if (account.freshAddress === t.recipient) {
76
+ errors.recipient = new InvalidAddressBecauseDestinationIsAlsoSource();
77
+ } else {
78
+ const { recipientError, recipientWarning } = await validateRecipient(
79
+ account.currency,
80
+ t.recipient
81
+ );
82
82
 
83
- if (recipientError) {
84
- errors.recipient = recipientError;
85
- }
83
+ if (recipientError) {
84
+ errors.recipient = recipientError;
85
+ }
86
86
 
87
- if (recipientWarning) {
88
- warnings.recipient = recipientWarning;
89
- }
87
+ if (recipientWarning) {
88
+ warnings.recipient = recipientWarning;
90
89
  }
91
90
  }
91
+ }
92
92
 
93
- if (t.mode === "send") {
94
- if (!errors.amount && t.amount.eq(0)) {
95
- errors.amount = new AmountRequired();
96
- } else if (!errors.amount && t.amount.lt(0)) {
97
- errors.amount = new NotEnoughBalance();
98
- } else if (t.amount.gt(0) && estimatedFees.times(10).gt(t.amount)) {
99
- warnings.feeTooHigh = new FeeTooHigh();
100
- }
93
+ if (t.mode === "send") {
94
+ if (!errors.amount && t.amount.eq(0)) {
95
+ errors.amount = new AmountRequired();
96
+ } else if (!errors.amount && t.amount.lt(0)) {
97
+ errors.amount = new NotEnoughBalance();
98
+ } else if (t.amount.gt(0) && estimatedFees.times(10).gt(t.amount)) {
99
+ warnings.feeTooHigh = new FeeTooHigh();
100
+ }
101
101
 
102
- const thresholdWarning = 0.5 * 10 ** account.currency.units[0].magnitude;
103
-
104
- if (
105
- !errors.amount &&
106
- account.balance
107
- .minus(t.amount)
108
- .minus(estimatedFees)
109
- .lt(thresholdWarning)
110
- ) {
111
- if (isAccountDelegating(account)) {
112
- if (t.useAllAmount) {
113
- errors.amount = new RecommendUndelegation();
114
- } else {
115
- warnings.amount = new RecommendUndelegation();
116
- }
102
+ const thresholdWarning = 0.5 * 10 ** account.currency.units[0].magnitude;
103
+
104
+ if (
105
+ !errors.amount &&
106
+ account.balance.minus(t.amount).minus(estimatedFees).lt(thresholdWarning)
107
+ ) {
108
+ if (isAccountDelegating(account)) {
109
+ if (t.useAllAmount) {
110
+ errors.amount = new RecommendUndelegation();
111
+ } else {
112
+ warnings.amount = new RecommendUndelegation();
117
113
  }
118
114
  }
119
115
  }
120
- } else {
116
+ }
117
+
118
+ // if we also have taquitoError, we interprete them and they override the previously inferred errors
119
+ if (t.taquitoError) {
121
120
  log("taquitoerror", String(t.taquitoError));
122
121
 
123
122
  // remap taquito errors
@@ -127,7 +126,9 @@ const getTransactionStatus = async (
127
126
  } else {
128
127
  errors.amount = new NotEnoughBalanceToDelegate();
129
128
  }
130
- } else {
129
+ } else if (t.taquitoError.endsWith("delegate.unchanged")) {
130
+ errors.recipient = new InvalidAddressBecauseAlreadyDelegated();
131
+ } else if (!errors.amount) {
131
132
  // unidentified error case
132
133
  errors.amount = new Error(t.taquitoError);
133
134
  }
@@ -3,9 +3,7 @@ import type { Resolver } from "../../hw/getAddress/types";
3
3
 
4
4
  const resolver: Resolver = async (transport, { path, verify }) => {
5
5
  const xtz = new Xtz(transport);
6
- const r = await xtz.getAddress(path, {
7
- verify,
8
- });
6
+ const r = await xtz.getAddress(path, { verify });
9
7
  return { ...r, path };
10
8
  };
11
9
 
@@ -48,9 +48,10 @@ export const getAccountShape: GetAccountShape = async (infoInput) => {
48
48
  derivationMode,
49
49
  });
50
50
 
51
- const initialStableOperations = initialAccount
52
- ? initialAccount.operations
53
- : [];
51
+ const initialStableOperations =
52
+ initialAccount && initialAccount.id === accountId
53
+ ? initialAccount.operations
54
+ : [];
54
55
 
55
56
  // fetch transactions, incrementally if possible
56
57
  const mostRecentStableOperation = initialStableOperations[0];
@@ -4,6 +4,8 @@ import bitcoin from "../families/bitcoin/deviceTransactionConfig";
4
4
 
5
5
  import cosmos from "../families/cosmos/deviceTransactionConfig";
6
6
 
7
+ import crypto_org from "../families/crypto_org/deviceTransactionConfig";
8
+
7
9
  import elrond from "../families/elrond/deviceTransactionConfig";
8
10
 
9
11
  import ethereum from "../families/ethereum/deviceTransactionConfig";
@@ -25,6 +27,7 @@ export default {
25
27
  algorand,
26
28
  bitcoin,
27
29
  cosmos,
30
+ crypto_org,
28
31
  elrond,
29
32
  ethereum,
30
33
  polkadot,
@@ -17,7 +17,7 @@ import { getMainAccount } from "../../account";
17
17
  import { getAccountBridge } from "../../bridge";
18
18
  import type { ConnectAppEvent, Input as ConnectAppInput } from "../connectApp";
19
19
  import type { Action, Device } from "./types";
20
- import type { AppState } from "./app";
20
+ import type { AppRequest, AppState } from "./app";
21
21
  import { createAction as createAppAction } from "./app";
22
22
  type State = {
23
23
  signedOperation: SignedOperation | null | undefined;
@@ -33,6 +33,8 @@ type TransactionRequest = {
33
33
  transaction: Transaction;
34
34
  status: TransactionStatus;
35
35
  appName?: string;
36
+ dependencies?: AppRequest[];
37
+ requireLatestFirmware?: boolean;
36
38
  };
37
39
  type TransactionResult =
38
40
  | {
@@ -112,7 +114,8 @@ export const createAction = (
112
114
  reduxDevice: Device | null | undefined,
113
115
  txRequest: TransactionRequest
114
116
  ): TransactionState => {
115
- const { transaction, appName } = txRequest;
117
+ const { transaction, appName, dependencies, requireLatestFirmware } =
118
+ txRequest;
116
119
  const mainAccount = getMainAccount(
117
120
  txRequest.account,
118
121
  txRequest.parentAccount
@@ -120,6 +123,8 @@ export const createAction = (
120
123
  const appState = createAppAction(connectAppExec).useHook(reduxDevice, {
121
124
  account: mainAccount,
122
125
  appName,
126
+ dependencies,
127
+ requireLatestFirmware,
123
128
  });
124
129
  const { device, opened, inWrongDeviceForAccount, error } = appState;
125
130
  const [state, setState] = useState(initialState);