@ledgerhq/live-common 21.19.0 → 21.19.4
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/__tests__/test-helpers/setup.js +1 -0
- package/lib/__tests__/test-helpers/setup.js.map +1 -1
- package/lib/account/helpers.d.ts.map +1 -1
- package/lib/account/helpers.js +1 -0
- package/lib/account/helpers.js.map +1 -1
- package/lib/api/Ethereum.d.ts.map +1 -1
- package/lib/api/Ethereum.js +3 -1
- package/lib/api/Ethereum.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/bridge/jsHelpers.d.ts.map +1 -1
- package/lib/bridge/jsHelpers.js +7 -6
- package/lib/bridge/jsHelpers.js.map +1 -1
- package/lib/env.d.ts +10 -5
- package/lib/env.d.ts.map +1 -1
- package/lib/env.js +5 -0
- package/lib/env.js.map +1 -1
- package/lib/env.react.d.ts +1 -1
- package/lib/env.react.d.ts.map +1 -1
- package/lib/families/bitcoin/test-dataset.js +2 -2
- package/lib/families/bitcoin/test-dataset.js.map +1 -1
- package/lib/families/ethereum/bridge/js.d.ts.map +1 -1
- package/lib/families/ethereum/bridge/js.js +3 -0
- package/lib/families/ethereum/bridge/js.js.map +1 -1
- package/lib/families/ethereum/modules/erc1155.d.ts.map +1 -1
- package/lib/families/ethereum/modules/erc1155.js +21 -9
- package/lib/families/ethereum/modules/erc1155.js.map +1 -1
- package/lib/families/ethereum/modules/erc721.d.ts +3 -1
- package/lib/families/ethereum/modules/erc721.d.ts.map +1 -1
- package/lib/families/ethereum/modules/erc721.js +101 -7
- 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 +9 -1
- package/lib/families/ethereum/modules/index.js.map +1 -1
- package/lib/families/ethereum/nft.test.js +227 -34
- package/lib/families/ethereum/nft.test.js.map +1 -1
- package/lib/families/ethereum/signOperation.d.ts.map +1 -1
- package/lib/families/ethereum/signOperation.js +3 -4
- package/lib/families/ethereum/signOperation.js.map +1 -1
- package/lib/families/ethereum/synchronisation.d.ts.map +1 -1
- package/lib/families/ethereum/synchronisation.js +21 -38
- package/lib/families/ethereum/synchronisation.js.map +1 -1
- package/lib/families/ethereum/transaction.d.ts.map +1 -1
- package/lib/families/ethereum/transaction.js +4 -4
- package/lib/families/ethereum/transaction.js.map +1 -1
- package/lib/families/ethereum/types.d.ts +2 -0
- package/lib/families/ethereum/types.d.ts.map +1 -1
- package/lib/families/ethereum/types.js.map +1 -1
- package/lib/nft/helpers.d.ts +1 -2
- package/lib/nft/helpers.d.ts.map +1 -1
- package/lib/nft/helpers.js +13 -20
- package/lib/nft/helpers.js.map +1 -1
- package/lib/nft/index.d.ts +1 -0
- package/lib/nft/index.d.ts.map +1 -1
- package/lib/nft/index.js +1 -0
- package/lib/nft/index.js.map +1 -1
- package/lib/nft/support.d.ts +4 -0
- package/lib/nft/support.d.ts.map +1 -0
- package/lib/nft/support.js +16 -0
- package/lib/nft/support.js.map +1 -0
- package/lib/reconciliation.d.ts.map +1 -1
- package/lib/reconciliation.js +5 -1
- package/lib/reconciliation.js.map +1 -1
- package/package.json +1 -1
- package/src/.DS_Store +0 -0
- package/src/__tests__/.DS_Store +0 -0
- package/src/__tests__/__snapshots__/all.libcore.ts.snap +10 -49
- package/src/__tests__/test-helpers/setup.ts +1 -0
- package/src/account/helpers.ts +1 -0
- package/src/api/Ethereum.ts +5 -4
- package/src/api/explorerConfig/index.ts +0 -4
- package/src/bridge/jsHelpers.ts +7 -6
- package/src/currencies/__snapshots__/.DS_Store +0 -0
- package/src/env.ts +5 -0
- package/src/families/bitcoin/test-dataset.ts +2 -2
- package/src/families/ethereum/bridge/js.ts +8 -1
- package/src/families/ethereum/modules/erc1155.ts +22 -7
- package/src/families/ethereum/modules/erc721.ts +42 -4
- package/src/families/ethereum/modules/index.ts +20 -0
- package/src/families/ethereum/nft.test.ts +199 -26
- package/src/families/ethereum/signOperation.ts +2 -3
- package/src/families/ethereum/synchronisation.ts +104 -113
- package/src/families/ethereum/transaction.ts +8 -4
- package/src/families/ethereum/types.ts +2 -0
- package/src/nft/helpers.ts +13 -21
- package/src/nft/index.ts +1 -0
- package/src/nft/support.ts +16 -0
- package/src/reconciliation.ts +4 -1
- package/src/currencies/__snapshots__/sortByMarketcap.test.ts.snap +0 -6152
package/src/env.ts
CHANGED
|
@@ -381,6 +381,11 @@ const envDefinitions = {
|
|
|
381
381
|
parser: boolParser,
|
|
382
382
|
desc: "synchronizing nfts",
|
|
383
383
|
},
|
|
384
|
+
NFT_CURRENCIES: {
|
|
385
|
+
def: "ethereum",
|
|
386
|
+
parser: stringParser,
|
|
387
|
+
desc: "set the currencies where NFT is active",
|
|
388
|
+
},
|
|
384
389
|
NFT_ETH_METADATA_SERVICE: {
|
|
385
390
|
// FIXME LL-8001
|
|
386
391
|
def: "https://nft.staging.aws.ledger.fr/v1/ethereum/1/contracts/tokens/infos",
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import type { DatasetTest } from "../../types";
|
|
2
2
|
import type { Transaction } from "./types";
|
|
3
|
-
import bitcoin_cash from "./datasets/bitcoin_cash";
|
|
3
|
+
// import bitcoin_cash from "./datasets/bitcoin_cash";
|
|
4
4
|
// import bitcoin_gold from "./datasets/bitcoin_gold";
|
|
5
5
|
import bitcoin from "./datasets/bitcoin";
|
|
6
6
|
import dash from "./datasets/dash";
|
|
@@ -21,7 +21,7 @@ const dataset: DatasetTest<Transaction> = {
|
|
|
21
21
|
implementations: ["js", "libcore", "mock"],
|
|
22
22
|
currencies: {
|
|
23
23
|
bitcoin,
|
|
24
|
-
bitcoin_cash,
|
|
24
|
+
// bitcoin_cash,
|
|
25
25
|
// bitcoin_gold,
|
|
26
26
|
dash,
|
|
27
27
|
// decred, // BACK-2443
|
|
@@ -24,11 +24,16 @@ import {
|
|
|
24
24
|
estimateGasLimit,
|
|
25
25
|
} from "../transaction";
|
|
26
26
|
import { getAccountShape } from "../synchronisation";
|
|
27
|
-
import {
|
|
27
|
+
import {
|
|
28
|
+
preload,
|
|
29
|
+
hydrate,
|
|
30
|
+
prepareTransaction as prepareTransactionModules,
|
|
31
|
+
} from "../modules";
|
|
28
32
|
import { signOperation } from "../signOperation";
|
|
29
33
|
import { modes } from "../modules";
|
|
30
34
|
import postSyncPatch from "../postSyncPatch";
|
|
31
35
|
import { inferDynamicRange } from "../../../range";
|
|
36
|
+
|
|
32
37
|
const receive = makeAccountBridgeReceive();
|
|
33
38
|
|
|
34
39
|
const broadcast = async ({
|
|
@@ -173,6 +178,8 @@ const prepareTransaction = async (a, t: Transaction): Promise<Transaction> => {
|
|
|
173
178
|
t.estimatedGasLimit = estimatedGasLimit;
|
|
174
179
|
}
|
|
175
180
|
|
|
181
|
+
t = await prepareTransactionModules(a, t);
|
|
182
|
+
|
|
176
183
|
return t;
|
|
177
184
|
};
|
|
178
185
|
|
|
@@ -9,6 +9,7 @@ import {
|
|
|
9
9
|
import { validateRecipient } from "../transaction";
|
|
10
10
|
import type { ModeModule, Transaction } from "../types";
|
|
11
11
|
import type { Account } from "../../../types";
|
|
12
|
+
import { prepareTransaction } from "./erc721";
|
|
12
13
|
|
|
13
14
|
const notOwnedNft = createCustomErrorClass("NotOwnedNft");
|
|
14
15
|
const notEnoughNftOwned = createCustomErrorClass("NotEnoughNftOwned");
|
|
@@ -75,25 +76,37 @@ const erc1155Transfer: ModeModule = {
|
|
|
75
76
|
fields.push({
|
|
76
77
|
type: "text",
|
|
77
78
|
label: "Type",
|
|
78
|
-
value: `
|
|
79
|
+
value: `NFT Transfer`,
|
|
79
80
|
});
|
|
80
81
|
|
|
81
82
|
fields.push({
|
|
82
83
|
type: "text",
|
|
83
|
-
label: "
|
|
84
|
-
value: input.transaction.
|
|
84
|
+
label: "To",
|
|
85
|
+
value: input.transaction.recipient ?? "",
|
|
85
86
|
});
|
|
86
87
|
|
|
87
88
|
fields.push({
|
|
88
89
|
type: "text",
|
|
89
|
-
label: "
|
|
90
|
-
value: input.transaction.
|
|
90
|
+
label: "Collection Name",
|
|
91
|
+
value: input.transaction.collectionName || "",
|
|
91
92
|
});
|
|
92
93
|
|
|
93
94
|
fields.push({
|
|
94
95
|
type: "text",
|
|
95
|
-
label: "
|
|
96
|
-
value: input.transaction.quantities?.
|
|
96
|
+
label: "Quantity",
|
|
97
|
+
value: input.transaction.quantities?.[0]?.toFixed() ?? "",
|
|
98
|
+
});
|
|
99
|
+
|
|
100
|
+
fields.push({
|
|
101
|
+
type: "address",
|
|
102
|
+
label: "NFT Address",
|
|
103
|
+
address: input.transaction.collection ?? "",
|
|
104
|
+
});
|
|
105
|
+
|
|
106
|
+
fields.push({
|
|
107
|
+
type: "text",
|
|
108
|
+
label: "NFT ID",
|
|
109
|
+
value: input.transaction.tokenIds?.[0] ?? "",
|
|
97
110
|
});
|
|
98
111
|
},
|
|
99
112
|
|
|
@@ -107,6 +120,8 @@ const erc1155Transfer: ModeModule = {
|
|
|
107
120
|
approving: true, // workaround to track the status ENABLING
|
|
108
121
|
};
|
|
109
122
|
},
|
|
123
|
+
|
|
124
|
+
prepareTransaction,
|
|
110
125
|
};
|
|
111
126
|
|
|
112
127
|
function serializeTransactionData(
|
|
@@ -9,11 +9,35 @@ import {
|
|
|
9
9
|
import { validateRecipient } from "../transaction";
|
|
10
10
|
import type { ModeModule, Transaction } from "../types";
|
|
11
11
|
import type { Account } from "../../../types";
|
|
12
|
+
import { apiForCurrency } from "../../../api/Ethereum";
|
|
12
13
|
|
|
13
14
|
const notOwnedNft = createCustomErrorClass("NotOwnedNft");
|
|
14
15
|
|
|
15
16
|
export type Modes = "erc721.transfer";
|
|
16
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
|
+
|
|
17
41
|
const erc721Transfer: ModeModule = {
|
|
18
42
|
/**
|
|
19
43
|
* Tx data is filled during the buildEthereumTx
|
|
@@ -52,6 +76,8 @@ const erc721Transfer: ModeModule = {
|
|
|
52
76
|
}
|
|
53
77
|
},
|
|
54
78
|
|
|
79
|
+
prepareTransaction,
|
|
80
|
+
|
|
55
81
|
/**
|
|
56
82
|
* This will only be used by LLM & LLD, not the HW.
|
|
57
83
|
*/
|
|
@@ -59,18 +85,30 @@ const erc721Transfer: ModeModule = {
|
|
|
59
85
|
fields.push({
|
|
60
86
|
type: "text",
|
|
61
87
|
label: "Type",
|
|
62
|
-
value: `
|
|
88
|
+
value: `NFT Transfer`,
|
|
63
89
|
});
|
|
64
90
|
|
|
65
91
|
fields.push({
|
|
66
92
|
type: "text",
|
|
67
|
-
label: "
|
|
68
|
-
value: input.transaction.
|
|
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 ?? "",
|
|
69
107
|
});
|
|
70
108
|
|
|
71
109
|
fields.push({
|
|
72
110
|
type: "text",
|
|
73
|
-
label: "
|
|
111
|
+
label: "NFT ID",
|
|
74
112
|
value: input.transaction.tokenIds?.[0] ?? "",
|
|
75
113
|
});
|
|
76
114
|
},
|
|
@@ -90,6 +90,14 @@ export type ModeModule = {
|
|
|
90
90
|
arg1: Transaction,
|
|
91
91
|
arg2: Operation
|
|
92
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>;
|
|
93
101
|
};
|
|
94
102
|
export const modes: Record<TransactionMode, ModeModule> = {} as Record<
|
|
95
103
|
TransactionMode,
|
|
@@ -137,6 +145,18 @@ export function hydrate(value: unknown, currency: CryptoCurrency): void {
|
|
|
137
145
|
}
|
|
138
146
|
}
|
|
139
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
|
+
);
|
|
140
160
|
export const prepareTokenAccounts = (
|
|
141
161
|
currency: CryptoCurrency,
|
|
142
162
|
subAccounts: TokenAccount[],
|
|
@@ -1,11 +1,16 @@
|
|
|
1
1
|
import "../../__tests__/test-helpers/setup";
|
|
2
|
+
import BigNumber from "bignumber.js";
|
|
2
3
|
import { reduce } from "rxjs/operators";
|
|
3
|
-
import { fromAccountRaw, toAccountRaw } from "../../account";
|
|
4
|
-
import type { Account, AccountRaw } from "../../types";
|
|
4
|
+
import { fromAccountRaw, toAccountRaw, toNFTRaw } from "../../account";
|
|
5
|
+
import type { Account, AccountRaw, NFT } from "../../types";
|
|
5
6
|
import { getAccountBridge } from "../../bridge";
|
|
6
7
|
import { makeBridgeCacheSystem } from "../../bridge/cache";
|
|
7
8
|
import { patchAccount } from "../../reconciliation";
|
|
8
9
|
import { setEnv } from "../../env";
|
|
10
|
+
import { mergeNfts } from "../../bridge/jsHelpers";
|
|
11
|
+
import { encodeNftId } from "../../nft";
|
|
12
|
+
|
|
13
|
+
jest.setTimeout(120000);
|
|
9
14
|
|
|
10
15
|
const gaspardAccount: AccountRaw = {
|
|
11
16
|
id: "js:1:ethereum:0xb98d10d9f6d07ba283bfd21b2dfec050f9ae282a:",
|
|
@@ -26,32 +31,146 @@ const gaspardAccount: AccountRaw = {
|
|
|
26
31
|
xpub: "",
|
|
27
32
|
};
|
|
28
33
|
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
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",
|
|
39
108
|
},
|
|
40
109
|
});
|
|
41
|
-
const
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
}
|
|
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);
|
|
55
174
|
|
|
56
175
|
test("first sync & have nfts", async () => {
|
|
57
176
|
await cache.prepareCurrency(account.currency);
|
|
@@ -78,6 +197,17 @@ describe("nft reconciliation", () => {
|
|
|
78
197
|
expect(resync.nfts).toEqual(account.nfts);
|
|
79
198
|
});
|
|
80
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
|
+
|
|
81
211
|
test("patchAccount restore new NFTs correctly", async () => {
|
|
82
212
|
const copy = {
|
|
83
213
|
...account,
|
|
@@ -87,4 +217,47 @@ describe("nft reconciliation", () => {
|
|
|
87
217
|
const newAccount = patchAccount(copy, toAccountRaw(account));
|
|
88
218
|
expect(newAccount.nfts).toEqual(account.nfts);
|
|
89
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
|
+
test("no nft should be on quantity 0 or negative", async () => {
|
|
236
|
+
expect(account.nfts?.find((n) => !n.amount.gt(0))).toEqual(undefined);
|
|
237
|
+
});
|
|
238
|
+
});
|
|
239
|
+
|
|
240
|
+
/*
|
|
241
|
+
// this is never ending here... have to disable this test... (backend issue)
|
|
242
|
+
describe("gaspard NFT on polygon", () => {
|
|
243
|
+
let account = fromAccountRaw(gaspardPolygonAccount);
|
|
244
|
+
test("first sync", async () => {
|
|
245
|
+
await cache.prepareCurrency(account.currency);
|
|
246
|
+
account = await sync(account);
|
|
247
|
+
});
|
|
248
|
+
test(".nfts shouldn't be visible", () => {
|
|
249
|
+
expect(account.nfts).toBeFalsy();
|
|
250
|
+
});
|
|
251
|
+
});
|
|
252
|
+
*/
|
|
253
|
+
|
|
254
|
+
describe("gaspard NFT on bsc", () => {
|
|
255
|
+
let account = fromAccountRaw(gaspardBscAccount);
|
|
256
|
+
test("first sync", async () => {
|
|
257
|
+
await cache.prepareCurrency(account.currency);
|
|
258
|
+
account = await sync(account);
|
|
259
|
+
});
|
|
260
|
+
test(".nfts shouldn't be visible", () => {
|
|
261
|
+
expect(account.nfts).toBeFalsy();
|
|
262
|
+
});
|
|
90
263
|
});
|
|
@@ -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 {
|
|
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 (
|
|
64
|
+
if (isNFTActive(account.currency)) {
|
|
66
65
|
eth.setLoadConfig({
|
|
67
66
|
// FIXME drop this after LL-8001
|
|
68
67
|
nftExplorerBaseURL:
|