@ledgerhq/live-common 21.17.2 → 21.19.1

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 (119) hide show
  1. package/lib/__tests__/test-helpers/setup.js +1 -0
  2. package/lib/__tests__/test-helpers/setup.js.map +1 -1
  3. package/lib/account/addAccounts.d.ts.map +1 -1
  4. package/lib/account/addAccounts.js +3 -2
  5. package/lib/account/addAccounts.js.map +1 -1
  6. package/lib/account/helpers.d.ts.map +1 -1
  7. package/lib/account/helpers.js +1 -0
  8. package/lib/account/helpers.js.map +1 -1
  9. package/lib/api/Ethereum.d.ts.map +1 -1
  10. package/lib/api/Ethereum.js +2 -1
  11. package/lib/api/Ethereum.js.map +1 -1
  12. package/lib/api/explorerConfig/index.d.ts.map +1 -1
  13. package/lib/api/explorerConfig/index.js +0 -4
  14. package/lib/api/explorerConfig/index.js.map +1 -1
  15. package/lib/bridge/jsHelpers.d.ts.map +1 -1
  16. package/lib/bridge/jsHelpers.js +9 -8
  17. package/lib/bridge/jsHelpers.js.map +1 -1
  18. package/lib/env.d.ts +10 -5
  19. package/lib/env.d.ts.map +1 -1
  20. package/lib/env.js +5 -0
  21. package/lib/env.js.map +1 -1
  22. package/lib/env.react.d.ts +1 -1
  23. package/lib/env.react.d.ts.map +1 -1
  24. package/lib/families/bitcoin/getAccountNetworkInfo.d.ts.map +1 -1
  25. package/lib/families/bitcoin/getAccountNetworkInfo.js +12 -2
  26. package/lib/families/bitcoin/getAccountNetworkInfo.js.map +1 -1
  27. package/lib/families/bitcoin/test-dataset.js +2 -2
  28. package/lib/families/bitcoin/test-dataset.js.map +1 -1
  29. package/lib/families/bitcoin/types.d.ts +1 -0
  30. package/lib/families/bitcoin/types.d.ts.map +1 -1
  31. package/lib/families/bitcoin/types.js.map +1 -1
  32. package/lib/families/bitcoin/wallet-btc/explorer/index.d.ts +1 -0
  33. package/lib/families/bitcoin/wallet-btc/explorer/index.d.ts.map +1 -1
  34. package/lib/families/bitcoin/wallet-btc/explorer/index.js +19 -0
  35. package/lib/families/bitcoin/wallet-btc/explorer/index.js.map +1 -1
  36. package/lib/families/bitcoin/wallet-btc/explorer/types.d.ts +1 -0
  37. package/lib/families/bitcoin/wallet-btc/explorer/types.d.ts.map +1 -1
  38. package/lib/families/ethereum/bridge/js.d.ts.map +1 -1
  39. package/lib/families/ethereum/bridge/js.js +3 -0
  40. package/lib/families/ethereum/bridge/js.js.map +1 -1
  41. package/lib/families/ethereum/cli-transaction.d.ts.map +1 -1
  42. package/lib/families/ethereum/cli-transaction.js +10 -0
  43. package/lib/families/ethereum/cli-transaction.js.map +1 -1
  44. package/lib/families/ethereum/modules/erc1155.d.ts +4 -0
  45. package/lib/families/ethereum/modules/erc1155.d.ts.map +1 -0
  46. package/lib/families/ethereum/modules/erc1155.js +129 -0
  47. package/lib/families/ethereum/modules/erc1155.js.map +1 -0
  48. package/lib/families/ethereum/modules/erc721.d.ts +6 -0
  49. package/lib/families/ethereum/modules/erc721.d.ts.map +1 -0
  50. package/lib/families/ethereum/modules/erc721.js +189 -0
  51. package/lib/families/ethereum/modules/erc721.js.map +1 -0
  52. package/lib/families/ethereum/modules/index.d.ts +8 -1
  53. package/lib/families/ethereum/modules/index.d.ts.map +1 -1
  54. package/lib/families/ethereum/modules/index.js +14 -2
  55. package/lib/families/ethereum/modules/index.js.map +1 -1
  56. package/lib/families/ethereum/nft.test.d.ts +2 -0
  57. package/lib/families/ethereum/nft.test.d.ts.map +1 -0
  58. package/lib/families/ethereum/nft.test.js +353 -0
  59. package/lib/families/ethereum/nft.test.js.map +1 -0
  60. package/lib/families/ethereum/signOperation.d.ts.map +1 -1
  61. package/lib/families/ethereum/signOperation.js +3 -12
  62. package/lib/families/ethereum/signOperation.js.map +1 -1
  63. package/lib/families/ethereum/synchronisation.d.ts.map +1 -1
  64. package/lib/families/ethereum/synchronisation.js +21 -38
  65. package/lib/families/ethereum/synchronisation.js.map +1 -1
  66. package/lib/families/ethereum/synchronisation.test.js.map +1 -1
  67. package/lib/families/ethereum/transaction.d.ts.map +1 -1
  68. package/lib/families/ethereum/transaction.js +25 -8
  69. package/lib/families/ethereum/transaction.js.map +1 -1
  70. package/lib/families/ethereum/types.d.ts +8 -0
  71. package/lib/families/ethereum/types.d.ts.map +1 -1
  72. package/lib/families/ethereum/types.js.map +1 -1
  73. package/lib/hw/uninstallApp.d.ts.map +1 -1
  74. package/lib/hw/uninstallApp.js +1 -1
  75. package/lib/hw/uninstallApp.js.map +1 -1
  76. package/lib/nft/helpers.js +1 -2
  77. package/lib/nft/helpers.js.map +1 -1
  78. package/lib/nft/index.d.ts +1 -0
  79. package/lib/nft/index.d.ts.map +1 -1
  80. package/lib/nft/index.js +1 -0
  81. package/lib/nft/index.js.map +1 -1
  82. package/lib/nft/support.d.ts +4 -0
  83. package/lib/nft/support.d.ts.map +1 -0
  84. package/lib/nft/support.js +16 -0
  85. package/lib/nft/support.js.map +1 -0
  86. package/package.json +4 -4
  87. package/src/.DS_Store +0 -0
  88. package/src/__tests__/.DS_Store +0 -0
  89. package/src/__tests__/__snapshots__/all.libcore.ts.snap +10 -49
  90. package/src/__tests__/test-helpers/setup.ts +1 -0
  91. package/src/account/addAccounts.ts +3 -2
  92. package/src/account/helpers.ts +1 -0
  93. package/src/api/Ethereum.ts +4 -4
  94. package/src/api/explorerConfig/index.ts +0 -4
  95. package/src/bridge/jsHelpers.ts +9 -8
  96. package/src/currencies/{.DS_Store → __snapshots__/.DS_Store} +0 -0
  97. package/src/env.ts +5 -0
  98. package/src/families/bitcoin/getAccountNetworkInfo.ts +8 -1
  99. package/src/families/bitcoin/test-dataset.ts +2 -2
  100. package/src/families/bitcoin/types.ts +1 -0
  101. package/src/families/bitcoin/wallet-btc/explorer/index.ts +7 -0
  102. package/src/families/bitcoin/wallet-btc/explorer/types.ts +1 -0
  103. package/src/families/ethereum/bridge/js.ts +8 -1
  104. package/src/families/ethereum/cli-transaction.ts +10 -0
  105. package/src/families/ethereum/modules/erc1155.ts +157 -0
  106. package/src/families/ethereum/modules/erc721.ts +146 -0
  107. package/src/families/ethereum/modules/index.ts +32 -1
  108. package/src/families/ethereum/nft.test.ts +259 -0
  109. package/src/families/ethereum/signOperation.ts +3 -16
  110. package/src/families/ethereum/synchronisation.test.ts +1 -0
  111. package/src/families/ethereum/synchronisation.ts +104 -113
  112. package/src/families/ethereum/transaction.ts +42 -8
  113. package/src/families/ethereum/types.ts +8 -0
  114. package/src/hw/uninstallApp.ts +13 -8
  115. package/src/nft/helpers.ts +1 -1
  116. package/src/nft/index.ts +1 -0
  117. package/src/nft/support.ts +16 -0
  118. package/src/types/account.ts +1 -1
  119. package/src/currencies/__snapshots__/sortByMarketcap.test.ts.snap +0 -6150
@@ -0,0 +1,146 @@
1
+ import eip55 from "eip55";
2
+ import abi from "ethereumjs-abi";
3
+ import invariant from "invariant";
4
+ import BigNumber from "bignumber.js";
5
+ import {
6
+ createCustomErrorClass,
7
+ NotEnoughBalanceInParentAccount,
8
+ } from "@ledgerhq/errors";
9
+ import { validateRecipient } from "../transaction";
10
+ import type { ModeModule, Transaction } from "../types";
11
+ import type { Account } from "../../../types";
12
+ import { apiForCurrency } from "../../../api/Ethereum";
13
+
14
+ const notOwnedNft = createCustomErrorClass("NotOwnedNft");
15
+
16
+ export type Modes = "erc721.transfer";
17
+
18
+ export async function prepareTransaction(
19
+ account: Account,
20
+ transaction: Transaction
21
+ ): Promise<Transaction> {
22
+ let t = transaction;
23
+ const { collection, collectionName, tokenIds } = transaction;
24
+ if (collection && tokenIds && typeof collectionName === "undefined") {
25
+ const api = apiForCurrency(account.currency);
26
+ const [{ status, result }] = await api.getNFTMetadata([
27
+ {
28
+ contract: collection,
29
+ tokenId: tokenIds[0],
30
+ },
31
+ ]);
32
+ let collectionName = ""; // default value fallback if issue
33
+ if (status === 200) {
34
+ collectionName = result?.tokenName || "";
35
+ }
36
+ t = { ...t, collectionName };
37
+ }
38
+ return Promise.resolve(t);
39
+ }
40
+
41
+ const erc721Transfer: ModeModule = {
42
+ /**
43
+ * Tx data is filled during the buildEthereumTx
44
+ */
45
+ fillTransactionData(a, t, tx) {
46
+ const data = serializeTransactionData(a, t);
47
+ invariant(data, "serializeTransactionData provided no data");
48
+ tx.data = "0x" + (data as Buffer).toString("hex");
49
+ tx.to = t.collection;
50
+ tx.value = "0x00";
51
+ },
52
+
53
+ /**
54
+ * Tx status is filled after the buildEthereumTx
55
+ */
56
+ fillTransactionStatus: (a, t, result) => {
57
+ validateRecipient(a.currency, t.recipient, result);
58
+
59
+ if (!result.errors.recipient) {
60
+ result.totalSpent = result.estimatedFees;
61
+ result.amount = new BigNumber(t.amount);
62
+
63
+ if (result.estimatedFees.gt(a.spendableBalance)) {
64
+ result.errors.amount = new NotEnoughBalanceInParentAccount();
65
+ }
66
+
67
+ if (
68
+ !a.nfts?.find?.(
69
+ (n) =>
70
+ n.tokenId === t.tokenIds?.[0] &&
71
+ n.collection.contract === t.collection
72
+ )
73
+ ) {
74
+ result.errors.amount = new notOwnedNft();
75
+ }
76
+ }
77
+ },
78
+
79
+ prepareTransaction,
80
+
81
+ /**
82
+ * This will only be used by LLM & LLD, not the HW.
83
+ */
84
+ fillDeviceTransactionConfig(input, fields) {
85
+ fields.push({
86
+ type: "text",
87
+ label: "Type",
88
+ value: `NFT Transfer`,
89
+ });
90
+
91
+ fields.push({
92
+ type: "text",
93
+ label: "To",
94
+ value: input.transaction.recipient ?? "",
95
+ });
96
+
97
+ fields.push({
98
+ type: "text",
99
+ label: "Collection Name",
100
+ value: input.transaction.collectionName || "",
101
+ });
102
+
103
+ fields.push({
104
+ type: "address",
105
+ label: "NFT Address",
106
+ address: input.transaction.collection ?? "",
107
+ });
108
+
109
+ fields.push({
110
+ type: "text",
111
+ label: "NFT ID",
112
+ value: input.transaction.tokenIds?.[0] ?? "",
113
+ });
114
+ },
115
+
116
+ /**
117
+ * Optimistic Operation is filled post signing
118
+ */
119
+ fillOptimisticOperation(a, t, op) {
120
+ op.type = "FEES";
121
+ op.extra = {
122
+ ...op.extra,
123
+ approving: true, // workaround to track the status ENABLING
124
+ };
125
+ },
126
+ };
127
+
128
+ function serializeTransactionData(
129
+ account: Account,
130
+ transaction: Transaction
131
+ ): Buffer | null | undefined {
132
+ const from = eip55.encode(account.freshAddress);
133
+ const to = eip55.encode(transaction.recipient);
134
+
135
+ return abi.simpleEncode(
136
+ "safeTransferFrom(address,address,uint256,bytes)",
137
+ from,
138
+ to,
139
+ transaction.tokenIds?.[0],
140
+ "0x00"
141
+ );
142
+ }
143
+
144
+ export const modes: Record<Modes, ModeModule> = {
145
+ "erc721.transfer": erc721Transfer,
146
+ };
@@ -13,15 +13,26 @@ import type { DeviceTransactionField } from "../../../transaction";
13
13
  import * as compound from "./compound";
14
14
  import * as erc20 from "./erc20";
15
15
  import * as send from "./send";
16
+ import * as erc721 from "./erc721";
17
+ import * as erc1155 from "./erc1155";
16
18
  import type { Modes as CompoundModes } from "./compound";
17
19
  import type { Modes as ERC20Modes } from "./erc20";
18
20
  import type { Modes as SendModes } from "./send";
21
+ import type { Modes as ERC721Modes } from "./erc721";
22
+ import type { Modes as ERC1155Modes } from "./erc1155";
19
23
  const modules = {
20
24
  erc20,
21
25
  compound,
22
26
  send,
27
+ erc721,
28
+ erc1155,
23
29
  };
24
- export type TransactionMode = CompoundModes | ERC20Modes | SendModes;
30
+ export type TransactionMode =
31
+ | CompoundModes
32
+ | ERC20Modes
33
+ | SendModes
34
+ | ERC721Modes
35
+ | ERC1155Modes;
25
36
 
26
37
  /**
27
38
  * A ModeModule enable a new transaction mode in Ethereum family
@@ -79,6 +90,14 @@ export type ModeModule = {
79
90
  arg1: Transaction,
80
91
  arg2: Operation
81
92
  ) => void;
93
+
94
+ /**
95
+ * hook to resolve a transaction like the prepareTransaction of the bridge
96
+ */
97
+ prepareTransaction?: (
98
+ account: Account,
99
+ transaction: Transaction
100
+ ) => Promise<Transaction>;
82
101
  };
83
102
  export const modes: Record<TransactionMode, ModeModule> = {} as Record<
84
103
  TransactionMode,
@@ -126,6 +145,18 @@ export function hydrate(value: unknown, currency: CryptoCurrency): void {
126
145
  }
127
146
  }
128
147
  }
148
+ export const prepareTransaction = (
149
+ account: Account,
150
+ transaction: Transaction
151
+ ): Promise<Transaction> =>
152
+ values(modules)
153
+ // @ts-expect-error some module implement it
154
+ .map((m) => m.prepareTransaction)
155
+ .filter(Boolean)
156
+ .reduce(
157
+ (p, fn) => p.then((t) => fn(account, t)),
158
+ Promise.resolve(transaction)
159
+ );
129
160
  export const prepareTokenAccounts = (
130
161
  currency: CryptoCurrency,
131
162
  subAccounts: TokenAccount[],
@@ -0,0 +1,259 @@
1
+ import "../../__tests__/test-helpers/setup";
2
+ import BigNumber from "bignumber.js";
3
+ import { reduce } from "rxjs/operators";
4
+ import { fromAccountRaw, toAccountRaw, toNFTRaw } from "../../account";
5
+ import type { Account, AccountRaw, NFT } from "../../types";
6
+ import { getAccountBridge } from "../../bridge";
7
+ import { makeBridgeCacheSystem } from "../../bridge/cache";
8
+ import { patchAccount } from "../../reconciliation";
9
+ import { setEnv } from "../../env";
10
+ import { mergeNfts } from "../../bridge/jsHelpers";
11
+ import { encodeNftId } from "../../nft";
12
+
13
+ jest.setTimeout(120000);
14
+
15
+ const gaspardAccount: AccountRaw = {
16
+ id: "js:1:ethereum:0xb98d10d9f6d07ba283bfd21b2dfec050f9ae282a:",
17
+ seedIdentifier: "0xb98d10d9f6d07ba283bfd21b2dfec050f9ae282a",
18
+ name: "G4sp4rd",
19
+ derivationMode: "",
20
+ index: 0,
21
+ freshAddress: "0xb98d10d9f6d07ba283bfd21b2dfec050f9ae282a",
22
+ freshAddressPath: "44'/60'/0'/0/0",
23
+ freshAddresses: [],
24
+ pendingOperations: [],
25
+ operations: [],
26
+ currencyId: "ethereum",
27
+ unitMagnitude: 18,
28
+ balance: "",
29
+ blockHeight: 0,
30
+ lastSyncDate: "",
31
+ xpub: "",
32
+ };
33
+
34
+ /*
35
+ const gaspardPolygonAccount: AccountRaw = {
36
+ id: "js:1:polygon:0xb98d10d9f6d07ba283bfd21b2dfec050f9ae282a:",
37
+ seedIdentifier: "0xb98d10d9f6d07ba283bfd21b2dfec050f9ae282a",
38
+ name: "G4sp4rd",
39
+ derivationMode: "",
40
+ index: 0,
41
+ freshAddress: "0xb98d10d9f6d07ba283bfd21b2dfec050f9ae282a",
42
+ freshAddressPath: "44'/60'/0'/0/0",
43
+ freshAddresses: [],
44
+ pendingOperations: [],
45
+ operations: [],
46
+ currencyId: "polygon",
47
+ unitMagnitude: 18,
48
+ balance: "",
49
+ blockHeight: 0,
50
+ lastSyncDate: "",
51
+ xpub: "",
52
+ };
53
+ */
54
+
55
+ const gaspardBscAccount: AccountRaw = {
56
+ id: "js:1:bsc:0xb98d10d9f6d07ba283bfd21b2dfec050f9ae282a:",
57
+ seedIdentifier: "0xb98d10d9f6d07ba283bfd21b2dfec050f9ae282a",
58
+ name: "G4sp4rd",
59
+ derivationMode: "",
60
+ index: 0,
61
+ freshAddress: "0xb98d10d9f6d07ba283bfd21b2dfec050f9ae282a",
62
+ freshAddressPath: "44'/60'/0'/0/0",
63
+ freshAddresses: [],
64
+ pendingOperations: [],
65
+ operations: [],
66
+ currencyId: "bsc",
67
+ unitMagnitude: 18,
68
+ balance: "",
69
+ blockHeight: 0,
70
+ lastSyncDate: "",
71
+ xpub: "",
72
+ };
73
+
74
+ async function sync(account, withNFT = true) {
75
+ const bridge = getAccountBridge(account);
76
+ const blacklistedTokenIds = [];
77
+ setEnv("NFT", withNFT);
78
+ const r = await bridge
79
+ .sync(account, {
80
+ paginationConfig: {},
81
+ blacklistedTokenIds,
82
+ })
83
+ .pipe(reduce((a, f: (arg0: Account) => Account) => f(a), account))
84
+ .toPromise();
85
+ setEnv("NFT", false);
86
+ return r;
87
+ }
88
+
89
+ const localCache = {};
90
+ const cache = makeBridgeCacheSystem({
91
+ saveData(c, d) {
92
+ localCache[c.id] = d;
93
+ return Promise.resolve();
94
+ },
95
+ getData(c) {
96
+ return Promise.resolve(localCache[c.id]);
97
+ },
98
+ });
99
+
100
+ describe("nft merging", () => {
101
+ const makeNFT = (tokenId: string, contract: string, amount: number): NFT => ({
102
+ id: encodeNftId("test", contract, tokenId),
103
+ tokenId,
104
+ amount: new BigNumber(amount),
105
+ collection: {
106
+ contract,
107
+ standard: "erc721",
108
+ },
109
+ });
110
+ const oldNfts = [
111
+ makeNFT("1", "contract1", 10),
112
+ makeNFT("2", "contract1", 1),
113
+ makeNFT("3", "contract2", 6),
114
+ ];
115
+
116
+ test("should remove first NFT and return new array with same refs", () => {
117
+ const nfts = [makeNFT("2", "contract1", 1), makeNFT("3", "contract2", 6)];
118
+ const newNfts = mergeNfts(oldNfts, nfts);
119
+
120
+ expect(newNfts.map(toNFTRaw)).toEqual(nfts.map(toNFTRaw));
121
+ expect(oldNfts[1]).toBe(newNfts[0]);
122
+ expect(oldNfts[2]).toBe(newNfts[1]);
123
+ });
124
+
125
+ test("should remove any NFT and return new array with same refs", () => {
126
+ const nfts = [makeNFT("1", "contract1", 10), makeNFT("3", "contract2", 6)];
127
+ const newNfts = mergeNfts(oldNfts, nfts);
128
+
129
+ expect(newNfts.map(toNFTRaw)).toEqual(nfts.map(toNFTRaw));
130
+ expect(oldNfts[0]).toBe(newNfts[0]);
131
+ expect(oldNfts[2]).toBe(newNfts[1]);
132
+ });
133
+
134
+ test("should change NFT amount and return new array with new ref", () => {
135
+ const nfts = [
136
+ makeNFT("1", "contract1", 10),
137
+ makeNFT("2", "contract1", 5),
138
+ makeNFT("3", "contract2", 6),
139
+ ];
140
+ const addToNft1 = mergeNfts(oldNfts, nfts);
141
+
142
+ expect(addToNft1.map(toNFTRaw)).toEqual(nfts.map(toNFTRaw));
143
+ expect(oldNfts[0]).toBe(addToNft1[0]);
144
+ expect(oldNfts[1]).not.toBe(addToNft1[1]);
145
+ expect(oldNfts[2]).toBe(addToNft1[2]);
146
+ });
147
+
148
+ test("should add NFT and return new array with new ref", () => {
149
+ const nfts = [
150
+ makeNFT("1", "contract1", 10),
151
+ makeNFT("2", "contract1", 1),
152
+ makeNFT("3", "contract2", 6),
153
+ makeNFT("4", "contract2", 4),
154
+ ];
155
+ const addToNft1 = mergeNfts(oldNfts, nfts);
156
+
157
+ expect(addToNft1.map(toNFTRaw)).toEqual(
158
+ [
159
+ makeNFT("4", "contract2", 4),
160
+ makeNFT("1", "contract1", 10),
161
+ makeNFT("2", "contract1", 1),
162
+ makeNFT("3", "contract2", 6),
163
+ ].map(toNFTRaw)
164
+ );
165
+ expect(oldNfts[0]).toBe(addToNft1[1]);
166
+ expect(oldNfts[1]).toBe(addToNft1[2]);
167
+ expect(oldNfts[2]).toBe(addToNft1[3]);
168
+ expect(addToNft1[0]).toBe(nfts[3]);
169
+ });
170
+ });
171
+
172
+ describe("gaspard NFT on ethereum", () => {
173
+ let account = fromAccountRaw(gaspardAccount);
174
+
175
+ test("first sync & have nfts", async () => {
176
+ await cache.prepareCurrency(account.currency);
177
+ account = await sync(account);
178
+ expect(account.nfts?.length || 0).not.toBe(0);
179
+ });
180
+
181
+ test("remove half NFTs will restore them with operations still here", async () => {
182
+ const copy = {
183
+ ...account,
184
+ nfts: account.nfts?.slice(Math.ceil((account.nfts?.length || 0) / 2)),
185
+ };
186
+ const resync = await sync(copy);
187
+ expect(resync.nfts).toEqual(account.nfts);
188
+ });
189
+
190
+ test("remove half NFTs will restore them with missing operations too", async () => {
191
+ const copy = {
192
+ ...account,
193
+ operations: [],
194
+ nfts: account.nfts?.slice(Math.ceil((account.nfts?.length || 0) / 2)),
195
+ };
196
+ const resync = await sync(copy);
197
+ expect(resync.nfts).toEqual(account.nfts);
198
+ });
199
+
200
+ test("remove half NFTs will restore them with half operations", async () => {
201
+ const halfOps = Math.ceil(account.operations.length / 2);
202
+ const copy = {
203
+ ...account,
204
+ operations: account.operations.slice(halfOps),
205
+ nfts: account.nfts?.slice(Math.ceil((account.nfts?.length || 0) / 2)),
206
+ };
207
+ const resync = await sync(copy);
208
+ expect(resync.nfts).toEqual(account.nfts);
209
+ });
210
+
211
+ test("patchAccount restore new NFTs correctly", async () => {
212
+ const copy = {
213
+ ...account,
214
+ operations: [],
215
+ nfts: account.nfts?.slice(Math.ceil((account.nfts?.length || 0) / 2)),
216
+ };
217
+ const newAccount = patchAccount(copy, toAccountRaw(account));
218
+ expect(newAccount.nfts).toEqual(account.nfts);
219
+ });
220
+
221
+ test("start account with .nfts and disable the NFT flag should make it disappear", async () => {
222
+ expect(account.nfts).not.toBeFalsy();
223
+ const resync = await sync(account, false);
224
+ expect(resync.nfts).toBeFalsy();
225
+ });
226
+
227
+ test("start account without .nfts and enable the NFT flag should make it appear", async () => {
228
+ const first = await sync(account, false);
229
+ expect(first.nfts).toBeFalsy();
230
+ const second = await sync(first, true);
231
+ expect(second.nfts).not.toBeFalsy();
232
+ expect(second.nfts).toEqual(account.nfts);
233
+ });
234
+ });
235
+
236
+ /*
237
+ // this is never ending here... have to disable this test... (backend issue)
238
+ describe("gaspard NFT on polygon", () => {
239
+ let account = fromAccountRaw(gaspardPolygonAccount);
240
+ test("first sync", async () => {
241
+ await cache.prepareCurrency(account.currency);
242
+ account = await sync(account);
243
+ });
244
+ test(".nfts shouldn't be visible", () => {
245
+ expect(account.nfts).toBeFalsy();
246
+ });
247
+ });
248
+ */
249
+
250
+ describe("gaspard NFT on bsc", () => {
251
+ let account = fromAccountRaw(gaspardBscAccount);
252
+ test("first sync", async () => {
253
+ await cache.prepareCurrency(account.currency);
254
+ account = await sync(account);
255
+ });
256
+ test(".nfts shouldn't be visible", () => {
257
+ expect(account.nfts).toBeFalsy();
258
+ });
259
+ });
@@ -13,7 +13,7 @@ import { getGasLimit, buildEthereumTx } from "./transaction";
13
13
  import { apiForCurrency } from "../../api/Ethereum";
14
14
  import { withDevice } from "../../hw/deviceAccess";
15
15
  import { modes } from "./modules";
16
- import { getEnv } from "../../env";
16
+ import { isNFTActive } from "../../nft";
17
17
  export const signOperation = ({
18
18
  account,
19
19
  deviceId,
@@ -57,12 +57,11 @@ export const signOperation = ({
57
57
  nonce
58
58
  );
59
59
  const to = eip55.encode("0x" + tx.to.toString("hex"));
60
- const chainId = tx.getChainId();
61
60
  const value = new BigNumber(
62
61
  "0x" + (tx.value.toString("hex") || "0")
63
62
  );
64
63
  const eth = new Eth(transport);
65
- if (getEnv("NFT")) {
64
+ if (isNFTActive(account.currency)) {
66
65
  eth.setLoadConfig({
67
66
  // FIXME drop this after LL-8001
68
67
  nftExplorerBaseURL:
@@ -99,19 +98,7 @@ export const signOperation = ({
99
98
  type: "device-signature-granted",
100
99
  });
101
100
  // Second, we re-set some tx fields from the device signature
102
- let v = result.v;
103
-
104
- if (chainId > 0) {
105
- // EIP155 support. check/recalc signature v value.
106
- const rv = parseInt(v, 16);
107
- let cv = chainId * 2 + 35;
108
-
109
- if (rv !== cv && (rv & cv) !== rv) {
110
- cv += 1; // add signature v bit.
111
- }
112
-
113
- v = cv.toString(16);
114
- }
101
+ const v = result.v;
115
102
 
116
103
  tx.v = Buffer.from(v, "hex");
117
104
  tx.r = Buffer.from(result.r, "hex");
@@ -6,6 +6,7 @@ import type { Account, SubAccount } from "../../types";
6
6
  import { getAccountBridge } from "../../bridge";
7
7
  import { makeBridgeCacheSystem } from "../../bridge/cache";
8
8
  import { ethereum1 } from "./test-dataset";
9
+
9
10
  describe("blacklistedTokenIds functionality", () => {
10
11
  const account = fromAccountRaw(ethereum1);
11
12
  const localCache = {};