@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.
- package/lib/account/support.d.ts.map +1 -1
- package/lib/account/support.js +1 -25
- package/lib/account/support.js.map +1 -1
- package/lib/api/explorerConfig/index.d.ts.map +1 -1
- package/lib/api/explorerConfig/index.js +0 -4
- package/lib/api/explorerConfig/index.js.map +1 -1
- package/lib/errors.d.ts +3 -0
- package/lib/errors.d.ts.map +1 -1
- package/lib/errors.js +3 -2
- package/lib/errors.js.map +1 -1
- package/lib/families/bitcoin/test-dataset.js +1 -1
- package/lib/families/bitcoin/test-dataset.js.map +1 -1
- package/lib/families/crypto_org/deviceTransactionConfig.d.ts +11 -0
- package/lib/families/crypto_org/deviceTransactionConfig.d.ts.map +1 -0
- package/lib/families/crypto_org/deviceTransactionConfig.js +40 -0
- package/lib/families/crypto_org/deviceTransactionConfig.js.map +1 -0
- package/lib/families/ethereum/modules/compound.d.ts.map +1 -1
- package/lib/families/ethereum/modules/compound.js +2 -1
- package/lib/families/ethereum/modules/compound.js.map +1 -1
- package/lib/families/ethereum/modules/erc1155.d.ts.map +1 -1
- package/lib/families/ethereum/modules/erc1155.js +2 -1
- package/lib/families/ethereum/modules/erc1155.js.map +1 -1
- package/lib/families/ethereum/modules/erc20.d.ts.map +1 -1
- package/lib/families/ethereum/modules/erc20.js +2 -1
- package/lib/families/ethereum/modules/erc20.js.map +1 -1
- package/lib/families/ethereum/modules/erc721.d.ts.map +1 -1
- package/lib/families/ethereum/modules/erc721.js +2 -1
- package/lib/families/ethereum/modules/erc721.js.map +1 -1
- package/lib/families/ethereum/modules/index.d.ts +5 -0
- package/lib/families/ethereum/modules/index.d.ts.map +1 -1
- package/lib/families/ethereum/modules/index.js.map +1 -1
- package/lib/families/ethereum/signOperation.d.ts.map +1 -1
- package/lib/families/ethereum/signOperation.js +33 -24
- package/lib/families/ethereum/signOperation.js.map +1 -1
- package/lib/families/polkadot/address.d.ts.map +1 -1
- package/lib/families/polkadot/address.js +5 -1
- package/lib/families/polkadot/address.js.map +1 -1
- package/lib/families/polkadot/js-getTransactionStatus.d.ts.map +1 -1
- package/lib/families/polkadot/js-getTransactionStatus.js +6 -2
- package/lib/families/polkadot/js-getTransactionStatus.js.map +1 -1
- package/lib/families/tezos/bridge/js.d.ts.map +1 -1
- package/lib/families/tezos/bridge/js.js +19 -20
- package/lib/families/tezos/bridge/js.js.map +1 -1
- package/lib/families/tezos/hw-getAddress.d.ts.map +1 -1
- package/lib/families/tezos/hw-getAddress.js +1 -3
- package/lib/families/tezos/hw-getAddress.js.map +1 -1
- package/lib/families/tezos/synchronisation.d.ts.map +1 -1
- package/lib/families/tezos/synchronisation.js +1 -1
- package/lib/families/tezos/synchronisation.js.map +1 -1
- package/lib/generated/deviceTransactionConfig.d.ts +2 -0
- package/lib/generated/deviceTransactionConfig.d.ts.map +1 -1
- package/lib/generated/deviceTransactionConfig.js +18 -16
- package/lib/generated/deviceTransactionConfig.js.map +1 -1
- package/lib/hw/actions/transaction.d.ts +3 -1
- package/lib/hw/actions/transaction.d.ts.map +1 -1
- package/lib/hw/actions/transaction.js +4 -2
- package/lib/hw/actions/transaction.js.map +1 -1
- package/package.json +8 -8
- package/src/account/support.ts +1 -25
- package/src/api/explorerConfig/index.ts +0 -4
- package/src/errors.ts +3 -0
- package/src/families/bitcoin/test-dataset.ts +1 -1
- package/src/families/crypto_org/deviceTransactionConfig.ts +52 -0
- package/src/families/ethereum/modules/compound.ts +2 -0
- package/src/families/ethereum/modules/erc1155.ts +2 -0
- package/src/families/ethereum/modules/erc20.ts +2 -0
- package/src/families/ethereum/modules/erc721.ts +2 -0
- package/src/families/ethereum/modules/index.ts +10 -0
- package/src/families/ethereum/signOperation.ts +27 -8
- package/src/families/polkadot/address.ts +8 -2
- package/src/families/polkadot/js-getTransactionStatus.ts +6 -2
- package/src/families/tezos/bridge/js.ts +41 -40
- package/src/families/tezos/hw-getAddress.ts +1 -3
- package/src/families/tezos/synchronisation.ts +4 -3
- package/src/generated/deviceTransactionConfig.ts +3 -0
- 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.
|
|
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.
|
|
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.
|
|
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.
|
|
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.
|
|
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.
|
|
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.
|
|
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.
|
|
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",
|
package/src/account/support.ts
CHANGED
|
@@ -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;
|
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", "
|
|
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;
|
|
@@ -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,
|
|
@@ -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
|
-
|
|
66
|
+
|
|
67
|
+
const txHex = tx.serialize().toString("hex");
|
|
68
|
+
|
|
69
|
+
const loadConfig: LoadConfig = {};
|
|
65
70
|
if (isNFTActive(account.currency)) {
|
|
66
|
-
|
|
67
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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 (
|
|
74
|
-
if (
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
}
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
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
|
-
|
|
84
|
-
|
|
85
|
-
|
|
83
|
+
if (recipientError) {
|
|
84
|
+
errors.recipient = recipientError;
|
|
85
|
+
}
|
|
86
86
|
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
}
|
|
87
|
+
if (recipientWarning) {
|
|
88
|
+
warnings.recipient = recipientWarning;
|
|
90
89
|
}
|
|
91
90
|
}
|
|
91
|
+
}
|
|
92
92
|
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
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
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
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
|
-
}
|
|
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 =
|
|
52
|
-
|
|
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 } =
|
|
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);
|