@ledgerhq/live-common 34.52.0-nightly.20251031094135 → 34.52.0-nightly.20251101023821
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/bridge/generic-alpaca/signOperation.d.ts.map +1 -1
- package/lib/bridge/generic-alpaca/signOperation.js +5 -3
- package/lib/bridge/generic-alpaca/signOperation.js.map +1 -1
- package/lib/bridge/generic-alpaca/types.d.ts +56 -2
- package/lib/bridge/generic-alpaca/types.d.ts.map +1 -1
- package/lib/bridge/generic-alpaca/utils.d.ts.map +1 -1
- package/lib/bridge/generic-alpaca/utils.js +97 -1
- package/lib/bridge/generic-alpaca/utils.js.map +1 -1
- package/lib/e2e/speculosAppVersion.d.ts.map +1 -1
- package/lib/e2e/speculosAppVersion.js +1 -0
- package/lib/e2e/speculosAppVersion.js.map +1 -1
- package/lib/featureFlags/defaultFeatures.d.ts.map +1 -1
- package/lib/featureFlags/defaultFeatures.js +1 -0
- package/lib/featureFlags/defaultFeatures.js.map +1 -1
- package/lib/market/hooks/useLargeMoverCurrencies.d.ts +1 -1
- package/lib/market/hooks/useMarketDataProvider.d.ts +2 -2
- package/lib/market/hooks/useMarketDataProvider.d.ts.map +1 -1
- package/lib/market/utils/currencyFormatter.d.ts +3 -3
- package/lib/market/utils/currencyFormatter.d.ts.map +1 -1
- package/lib/market/utils/currencyFormatter.js.map +1 -1
- package/lib/market/utils/queryKeys.d.ts +0 -1
- package/lib/market/utils/queryKeys.d.ts.map +1 -1
- package/lib/market/utils/queryKeys.js +0 -1
- package/lib/market/utils/queryKeys.js.map +1 -1
- package/lib/market/utils/types.d.ts +6 -6
- package/lib/market/utils/types.d.ts.map +1 -1
- package/lib/postOnboarding/hooks/usePostOnboardingHubState.d.ts.map +1 -1
- package/lib/postOnboarding/hooks/usePostOnboardingHubState.js +13 -4
- package/lib/postOnboarding/hooks/usePostOnboardingHubState.js.map +1 -1
- package/lib/postOnboarding/mock.d.ts +1 -0
- package/lib/postOnboarding/mock.d.ts.map +1 -1
- package/lib/postOnboarding/mock.js +3 -1
- package/lib/postOnboarding/mock.js.map +1 -1
- package/lib/postOnboarding/reducer.d.ts +16 -14
- package/lib/postOnboarding/reducer.d.ts.map +1 -1
- package/lib-es/bridge/generic-alpaca/signOperation.d.ts.map +1 -1
- package/lib-es/bridge/generic-alpaca/signOperation.js +5 -3
- package/lib-es/bridge/generic-alpaca/signOperation.js.map +1 -1
- package/lib-es/bridge/generic-alpaca/types.d.ts +56 -2
- package/lib-es/bridge/generic-alpaca/types.d.ts.map +1 -1
- package/lib-es/bridge/generic-alpaca/utils.d.ts.map +1 -1
- package/lib-es/bridge/generic-alpaca/utils.js +97 -1
- package/lib-es/bridge/generic-alpaca/utils.js.map +1 -1
- package/lib-es/e2e/speculosAppVersion.d.ts.map +1 -1
- package/lib-es/e2e/speculosAppVersion.js +1 -0
- package/lib-es/e2e/speculosAppVersion.js.map +1 -1
- package/lib-es/featureFlags/defaultFeatures.d.ts.map +1 -1
- package/lib-es/featureFlags/defaultFeatures.js +1 -0
- package/lib-es/featureFlags/defaultFeatures.js.map +1 -1
- package/lib-es/market/hooks/useLargeMoverCurrencies.d.ts +1 -1
- package/lib-es/market/hooks/useMarketDataProvider.d.ts +2 -2
- package/lib-es/market/hooks/useMarketDataProvider.d.ts.map +1 -1
- package/lib-es/market/utils/currencyFormatter.d.ts +3 -3
- package/lib-es/market/utils/currencyFormatter.d.ts.map +1 -1
- package/lib-es/market/utils/currencyFormatter.js.map +1 -1
- package/lib-es/market/utils/queryKeys.d.ts +0 -1
- package/lib-es/market/utils/queryKeys.d.ts.map +1 -1
- package/lib-es/market/utils/queryKeys.js +0 -1
- package/lib-es/market/utils/queryKeys.js.map +1 -1
- package/lib-es/market/utils/types.d.ts +6 -6
- package/lib-es/market/utils/types.d.ts.map +1 -1
- package/lib-es/postOnboarding/hooks/usePostOnboardingHubState.d.ts.map +1 -1
- package/lib-es/postOnboarding/hooks/usePostOnboardingHubState.js +13 -4
- package/lib-es/postOnboarding/hooks/usePostOnboardingHubState.js.map +1 -1
- package/lib-es/postOnboarding/mock.d.ts +1 -0
- package/lib-es/postOnboarding/mock.d.ts.map +1 -1
- package/lib-es/postOnboarding/mock.js +2 -0
- package/lib-es/postOnboarding/mock.js.map +1 -1
- package/lib-es/postOnboarding/reducer.d.ts +16 -14
- package/lib-es/postOnboarding/reducer.d.ts.map +1 -1
- package/package.json +74 -74
- package/src/bridge/generic-alpaca/signOperation.ts +5 -3
- package/src/bridge/generic-alpaca/types.ts +75 -2
- package/src/bridge/generic-alpaca/utils.test.ts +28 -2
- package/src/bridge/generic-alpaca/utils.ts +121 -2
- package/src/e2e/speculosAppVersion.ts +1 -0
- package/src/featureFlags/defaultFeatures.ts +1 -0
- package/src/market/hooks/useMarketDataProvider.ts +2 -2
- package/src/market/utils/currencyFormatter.ts +3 -3
- package/src/market/utils/queryKeys.ts +0 -1
- package/src/market/utils/types.ts +6 -6
- package/src/postOnboarding/hooks/usePostOnboardingHubState.test.ts +30 -3
- package/src/postOnboarding/hooks/usePostOnboardingHubState.ts +20 -6
- package/src/postOnboarding/mock.ts +2 -0
|
@@ -1,4 +1,9 @@
|
|
|
1
|
-
import type {
|
|
1
|
+
import type {
|
|
2
|
+
Operation,
|
|
3
|
+
OperationRaw,
|
|
4
|
+
TransactionCommon,
|
|
5
|
+
TransactionCommonRaw,
|
|
6
|
+
} from "@ledgerhq/types-live";
|
|
2
7
|
import BigNumber from "bignumber.js";
|
|
3
8
|
import type { Unit } from "@ledgerhq/types-cryptoassets";
|
|
4
9
|
|
|
@@ -6,6 +11,34 @@ type NetworkInfo = {
|
|
|
6
11
|
fees: BigNumber;
|
|
7
12
|
};
|
|
8
13
|
|
|
14
|
+
type NetworkInfoRaw = {
|
|
15
|
+
fees: string;
|
|
16
|
+
};
|
|
17
|
+
|
|
18
|
+
type Strategy = "slow" | "medium" | "fast";
|
|
19
|
+
|
|
20
|
+
export type FeeData = {
|
|
21
|
+
maxFeePerGas: BigNumber | null;
|
|
22
|
+
maxPriorityFeePerGas: BigNumber | null;
|
|
23
|
+
gasPrice: BigNumber | null;
|
|
24
|
+
nextBaseFee: BigNumber | null;
|
|
25
|
+
};
|
|
26
|
+
|
|
27
|
+
export type FeeDataRaw = {
|
|
28
|
+
maxFeePerGas: string | null;
|
|
29
|
+
maxPriorityFeePerGas: string | null;
|
|
30
|
+
gasPrice: string | null;
|
|
31
|
+
nextBaseFee: string | null;
|
|
32
|
+
};
|
|
33
|
+
|
|
34
|
+
export type GasOptions = {
|
|
35
|
+
[key in Strategy]: FeeData;
|
|
36
|
+
};
|
|
37
|
+
|
|
38
|
+
export type GasOptionsRaw = {
|
|
39
|
+
[key in Strategy]: FeeDataRaw;
|
|
40
|
+
};
|
|
41
|
+
|
|
9
42
|
export type GenericTransaction = TransactionCommon & {
|
|
10
43
|
family: string;
|
|
11
44
|
fees?: BigNumber | null;
|
|
@@ -14,6 +47,7 @@ export type GenericTransaction = TransactionCommon & {
|
|
|
14
47
|
parameters: { fees?: BigNumber | null };
|
|
15
48
|
};
|
|
16
49
|
tag?: number | null | undefined;
|
|
50
|
+
nonce?: number | null | undefined;
|
|
17
51
|
feeCustomUnit?: Unit | null | undefined;
|
|
18
52
|
memoType?: string | null;
|
|
19
53
|
memoValue?: string | null;
|
|
@@ -31,13 +65,52 @@ export type GenericTransaction = TransactionCommon & {
|
|
|
31
65
|
assetReference?: string;
|
|
32
66
|
assetOwner?: string;
|
|
33
67
|
networkInfo?: NetworkInfo | null;
|
|
34
|
-
chainId?: number;
|
|
68
|
+
chainId?: number | null;
|
|
35
69
|
gasLimit?: BigNumber | null;
|
|
36
70
|
gasPrice?: BigNumber | null;
|
|
37
71
|
maxFeePerGas?: BigNumber | null;
|
|
38
72
|
maxPriorityFeePerGas?: BigNumber | null;
|
|
73
|
+
gasOptions?: GasOptions;
|
|
74
|
+
};
|
|
75
|
+
|
|
76
|
+
export type GenericTransactionRaw = TransactionCommonRaw & {
|
|
77
|
+
family: string;
|
|
78
|
+
fees?: string | null;
|
|
79
|
+
storageLimit?: string | null;
|
|
80
|
+
customFees?: {
|
|
81
|
+
parameters: { fees?: string | null };
|
|
82
|
+
};
|
|
83
|
+
tag?: number | null | undefined;
|
|
84
|
+
nonce?: number | null | undefined;
|
|
85
|
+
feeCustomUnit?: Unit | null | undefined;
|
|
86
|
+
memoType?: string | null;
|
|
87
|
+
memoValue?: string | null;
|
|
88
|
+
data?: string;
|
|
89
|
+
mode?:
|
|
90
|
+
| "send"
|
|
91
|
+
| "changeTrust"
|
|
92
|
+
| "send-legacy"
|
|
93
|
+
| "send-eip1559"
|
|
94
|
+
| "delegate"
|
|
95
|
+
| "stake"
|
|
96
|
+
| "undelegate"
|
|
97
|
+
| "unstake";
|
|
98
|
+
type?: number | null;
|
|
99
|
+
assetReference?: string | null;
|
|
100
|
+
assetOwner?: string | null;
|
|
101
|
+
networkInfo?: NetworkInfoRaw | null;
|
|
102
|
+
chainId?: number | null;
|
|
103
|
+
gasLimit?: string | null;
|
|
104
|
+
gasPrice?: string | null;
|
|
105
|
+
maxFeePerGas?: string | null;
|
|
106
|
+
maxPriorityFeePerGas?: string | null;
|
|
107
|
+
gasOptions?: GasOptionsRaw;
|
|
39
108
|
};
|
|
40
109
|
|
|
41
110
|
export interface OperationCommon extends Operation {
|
|
42
111
|
extra: Record<string, any>;
|
|
43
112
|
}
|
|
113
|
+
|
|
114
|
+
export interface OperationCommonRaw extends OperationRaw {
|
|
115
|
+
extra: Record<string, any>;
|
|
116
|
+
}
|
|
@@ -22,6 +22,7 @@ describe("Alpaca utils", () => {
|
|
|
22
22
|
parentType: "OPT_IN",
|
|
23
23
|
subType: undefined,
|
|
24
24
|
parentValue: new BigNumber(50),
|
|
25
|
+
parentRecipient: "recipient-address",
|
|
25
26
|
},
|
|
26
27
|
],
|
|
27
28
|
[
|
|
@@ -32,6 +33,7 @@ describe("Alpaca utils", () => {
|
|
|
32
33
|
parentType: "DELEGATE",
|
|
33
34
|
subType: undefined,
|
|
34
35
|
parentValue: new BigNumber(50),
|
|
36
|
+
parentRecipient: "recipient-address",
|
|
35
37
|
},
|
|
36
38
|
],
|
|
37
39
|
[
|
|
@@ -42,6 +44,7 @@ describe("Alpaca utils", () => {
|
|
|
42
44
|
parentType: "DELEGATE",
|
|
43
45
|
subType: undefined,
|
|
44
46
|
parentValue: new BigNumber(50),
|
|
47
|
+
parentRecipient: "recipient-address",
|
|
45
48
|
},
|
|
46
49
|
],
|
|
47
50
|
[
|
|
@@ -52,6 +55,7 @@ describe("Alpaca utils", () => {
|
|
|
52
55
|
parentType: "UNDELEGATE",
|
|
53
56
|
subType: undefined,
|
|
54
57
|
parentValue: new BigNumber(50),
|
|
58
|
+
parentRecipient: "recipient-address",
|
|
55
59
|
},
|
|
56
60
|
],
|
|
57
61
|
[
|
|
@@ -62,6 +66,7 @@ describe("Alpaca utils", () => {
|
|
|
62
66
|
parentType: "UNDELEGATE",
|
|
63
67
|
subType: undefined,
|
|
64
68
|
parentValue: new BigNumber(50),
|
|
69
|
+
parentRecipient: "recipient-address",
|
|
65
70
|
},
|
|
66
71
|
],
|
|
67
72
|
[
|
|
@@ -72,6 +77,7 @@ describe("Alpaca utils", () => {
|
|
|
72
77
|
parentType: "OUT",
|
|
73
78
|
subType: undefined,
|
|
74
79
|
parentValue: new BigNumber(50),
|
|
80
|
+
parentRecipient: "recipient-address",
|
|
75
81
|
},
|
|
76
82
|
],
|
|
77
83
|
[
|
|
@@ -82,6 +88,7 @@ describe("Alpaca utils", () => {
|
|
|
82
88
|
parentType: "FEES",
|
|
83
89
|
subType: "OPT_IN",
|
|
84
90
|
parentValue: new BigNumber(12),
|
|
91
|
+
parentRecipient: "contract-address",
|
|
85
92
|
},
|
|
86
93
|
],
|
|
87
94
|
[
|
|
@@ -92,6 +99,7 @@ describe("Alpaca utils", () => {
|
|
|
92
99
|
parentType: "FEES",
|
|
93
100
|
subType: "DELEGATE",
|
|
94
101
|
parentValue: new BigNumber(12),
|
|
102
|
+
parentRecipient: "contract-address",
|
|
95
103
|
},
|
|
96
104
|
],
|
|
97
105
|
[
|
|
@@ -102,6 +110,7 @@ describe("Alpaca utils", () => {
|
|
|
102
110
|
parentType: "FEES",
|
|
103
111
|
subType: "DELEGATE",
|
|
104
112
|
parentValue: new BigNumber(12),
|
|
113
|
+
parentRecipient: "contract-address",
|
|
105
114
|
},
|
|
106
115
|
],
|
|
107
116
|
[
|
|
@@ -112,6 +121,7 @@ describe("Alpaca utils", () => {
|
|
|
112
121
|
parentType: "FEES",
|
|
113
122
|
subType: "UNDELEGATE",
|
|
114
123
|
parentValue: new BigNumber(12),
|
|
124
|
+
parentRecipient: "contract-address",
|
|
115
125
|
},
|
|
116
126
|
],
|
|
117
127
|
[
|
|
@@ -122,20 +132,26 @@ describe("Alpaca utils", () => {
|
|
|
122
132
|
parentType: "FEES",
|
|
123
133
|
subType: "UNDELEGATE",
|
|
124
134
|
parentValue: new BigNumber(12),
|
|
135
|
+
parentRecipient: "contract-address",
|
|
125
136
|
},
|
|
126
137
|
],
|
|
127
138
|
[
|
|
128
139
|
"token",
|
|
129
140
|
"send",
|
|
130
141
|
{ subAccountId: "sub-account-id" },
|
|
131
|
-
{
|
|
142
|
+
{
|
|
143
|
+
parentType: "FEES",
|
|
144
|
+
subType: "OUT",
|
|
145
|
+
parentValue: new BigNumber(12),
|
|
146
|
+
parentRecipient: "contract-address",
|
|
147
|
+
},
|
|
132
148
|
],
|
|
133
149
|
])("builds an optimistic %s operation with %s mode ", (_s, mode, params, expected) => {
|
|
134
150
|
const operation = buildOptimisticOperation(
|
|
135
151
|
{
|
|
136
152
|
id: "parent-account-id",
|
|
137
153
|
freshAddress: "account-address",
|
|
138
|
-
subAccounts: [{ id: "sub-account-id" }],
|
|
154
|
+
subAccounts: [{ id: "sub-account-id", token: { contractAddress: "contract-address" } }],
|
|
139
155
|
} as Account,
|
|
140
156
|
{
|
|
141
157
|
mode,
|
|
@@ -156,6 +172,11 @@ describe("Alpaca utils", () => {
|
|
|
156
172
|
fee: new BigNumber(12),
|
|
157
173
|
blockHash: null,
|
|
158
174
|
blockHeight: null,
|
|
175
|
+
transactionRaw: {
|
|
176
|
+
amount: expected.subType ? "0" : expected.parentValue.toFixed(),
|
|
177
|
+
fees: "12",
|
|
178
|
+
recipient: expected.parentRecipient,
|
|
179
|
+
},
|
|
159
180
|
...(expected.subType
|
|
160
181
|
? {
|
|
161
182
|
subOperations: [
|
|
@@ -168,6 +189,11 @@ describe("Alpaca utils", () => {
|
|
|
168
189
|
value: new BigNumber(50),
|
|
169
190
|
blockHash: null,
|
|
170
191
|
blockHeight: null,
|
|
192
|
+
transactionRaw: {
|
|
193
|
+
amount: "50",
|
|
194
|
+
fees: "12",
|
|
195
|
+
recipient: "recipient-address",
|
|
196
|
+
},
|
|
171
197
|
},
|
|
172
198
|
],
|
|
173
199
|
}
|
|
@@ -9,7 +9,15 @@ import {
|
|
|
9
9
|
} from "@ledgerhq/coin-framework/api/types";
|
|
10
10
|
import { findCryptoCurrencyById } from "@ledgerhq/cryptoassets/currencies";
|
|
11
11
|
import { CryptoCurrency } from "@ledgerhq/types-cryptoassets";
|
|
12
|
-
import {
|
|
12
|
+
import {
|
|
13
|
+
FeeData,
|
|
14
|
+
FeeDataRaw,
|
|
15
|
+
GasOptions,
|
|
16
|
+
GasOptionsRaw,
|
|
17
|
+
GenericTransaction,
|
|
18
|
+
GenericTransactionRaw,
|
|
19
|
+
OperationCommon,
|
|
20
|
+
} from "./types";
|
|
13
21
|
|
|
14
22
|
export function findCryptoCurrencyByNetwork(network: string): CryptoCurrency | undefined {
|
|
15
23
|
const networksRemap = {
|
|
@@ -189,6 +197,7 @@ export function transactionToIntent(
|
|
|
189
197
|
data: Buffer.isBuffer(transaction.data)
|
|
190
198
|
? { type: "buffer", value: transaction.data }
|
|
191
199
|
: { type: "none" },
|
|
200
|
+
sequence: transaction.nonce ?? undefined,
|
|
192
201
|
};
|
|
193
202
|
if (transaction.assetReference && transaction.assetOwner) {
|
|
194
203
|
const { subAccountId } = transaction;
|
|
@@ -216,6 +225,105 @@ export function transactionToIntent(
|
|
|
216
225
|
return res;
|
|
217
226
|
}
|
|
218
227
|
|
|
228
|
+
function toFeeDataRaw(data: FeeData): FeeDataRaw {
|
|
229
|
+
return {
|
|
230
|
+
gasPrice: data.gasPrice?.toFixed() ?? null,
|
|
231
|
+
maxFeePerGas: data.maxFeePerGas?.toFixed() ?? null,
|
|
232
|
+
maxPriorityFeePerGas: data.maxPriorityFeePerGas?.toFixed() ?? null,
|
|
233
|
+
nextBaseFee: data.nextBaseFee?.toFixed() ?? null,
|
|
234
|
+
};
|
|
235
|
+
}
|
|
236
|
+
|
|
237
|
+
function toGasOptionRaw(options: GasOptions): GasOptionsRaw {
|
|
238
|
+
return {
|
|
239
|
+
fast: toFeeDataRaw(options.fast),
|
|
240
|
+
medium: toFeeDataRaw(options.medium),
|
|
241
|
+
slow: toFeeDataRaw(options.slow),
|
|
242
|
+
};
|
|
243
|
+
}
|
|
244
|
+
|
|
245
|
+
function toGenericTransactionRaw(transaction: GenericTransaction): GenericTransactionRaw {
|
|
246
|
+
const raw: GenericTransactionRaw = {
|
|
247
|
+
amount: transaction.amount.toString(),
|
|
248
|
+
recipient: transaction.recipient,
|
|
249
|
+
family: transaction.family,
|
|
250
|
+
};
|
|
251
|
+
|
|
252
|
+
if ("useAllAmount" in transaction) {
|
|
253
|
+
raw.useAllAmount = transaction.useAllAmount;
|
|
254
|
+
}
|
|
255
|
+
|
|
256
|
+
const stringFieldsToPropagate = [
|
|
257
|
+
"memoType",
|
|
258
|
+
"memoValue",
|
|
259
|
+
"assetReference",
|
|
260
|
+
"assetOwner",
|
|
261
|
+
] as const;
|
|
262
|
+
for (const field of stringFieldsToPropagate) {
|
|
263
|
+
if (field in transaction) {
|
|
264
|
+
raw[field] = transaction[field];
|
|
265
|
+
}
|
|
266
|
+
}
|
|
267
|
+
|
|
268
|
+
const numberFieldsToPropagate = ["tag", "nonce", "type", "chainId"] as const;
|
|
269
|
+
for (const field of numberFieldsToPropagate) {
|
|
270
|
+
if (field in transaction) {
|
|
271
|
+
raw[field] = transaction[field];
|
|
272
|
+
}
|
|
273
|
+
}
|
|
274
|
+
|
|
275
|
+
const bigNumberFieldsToPropagate = [
|
|
276
|
+
"fees",
|
|
277
|
+
"storageLimit",
|
|
278
|
+
"gasLimit",
|
|
279
|
+
"gasPrice",
|
|
280
|
+
"maxFeePerGas",
|
|
281
|
+
"maxPriorityFeePerGas",
|
|
282
|
+
] as const;
|
|
283
|
+
for (const field of bigNumberFieldsToPropagate) {
|
|
284
|
+
if (field in transaction) {
|
|
285
|
+
raw[field] = transaction[field]?.toFixed();
|
|
286
|
+
}
|
|
287
|
+
}
|
|
288
|
+
|
|
289
|
+
if ("customFees" in transaction) {
|
|
290
|
+
raw.customFees =
|
|
291
|
+
transaction.customFees && "fees" in transaction.customFees.parameters
|
|
292
|
+
? {
|
|
293
|
+
parameters: { fees: transaction.customFees.parameters.fees?.toFixed() },
|
|
294
|
+
}
|
|
295
|
+
: { parameters: {} };
|
|
296
|
+
}
|
|
297
|
+
|
|
298
|
+
if ("feesStrategy" in transaction) {
|
|
299
|
+
raw.feesStrategy = transaction.feesStrategy;
|
|
300
|
+
}
|
|
301
|
+
|
|
302
|
+
if ("mode" in transaction) {
|
|
303
|
+
raw.mode = transaction.mode;
|
|
304
|
+
}
|
|
305
|
+
|
|
306
|
+
if ("feeCustomUnit" in transaction) {
|
|
307
|
+
raw.feeCustomUnit = transaction.feeCustomUnit;
|
|
308
|
+
}
|
|
309
|
+
|
|
310
|
+
if ("data" in transaction) {
|
|
311
|
+
raw.data = transaction.data?.toString("hex");
|
|
312
|
+
}
|
|
313
|
+
|
|
314
|
+
if ("networkInfo" in transaction) {
|
|
315
|
+
raw.networkInfo = transaction.networkInfo && {
|
|
316
|
+
fees: transaction.networkInfo.fees.toFixed(),
|
|
317
|
+
};
|
|
318
|
+
}
|
|
319
|
+
|
|
320
|
+
if ("gasOptions" in transaction) {
|
|
321
|
+
raw.gasOptions = transaction.gasOptions && toGasOptionRaw(transaction.gasOptions);
|
|
322
|
+
}
|
|
323
|
+
|
|
324
|
+
return raw;
|
|
325
|
+
}
|
|
326
|
+
|
|
219
327
|
export const buildOptimisticOperation = (
|
|
220
328
|
account: Account,
|
|
221
329
|
transaction: GenericTransaction,
|
|
@@ -242,6 +350,7 @@ export const buildOptimisticOperation = (
|
|
|
242
350
|
const { subAccountId } = transaction;
|
|
243
351
|
const { subAccounts } = account;
|
|
244
352
|
const parentType = subAccountId ? "FEES" : type;
|
|
353
|
+
const tokenAccount = subAccountId ? subAccounts?.find(ta => ta.id === subAccountId) : null;
|
|
245
354
|
|
|
246
355
|
const operation: Operation = {
|
|
247
356
|
id: encodeOperationId(account.id, "", parentType),
|
|
@@ -256,6 +365,13 @@ export const buildOptimisticOperation = (
|
|
|
256
365
|
transactionSequenceNumber: sequenceNumber ?? 0,
|
|
257
366
|
accountId: account.id,
|
|
258
367
|
date: new Date(),
|
|
368
|
+
transactionRaw: toGenericTransactionRaw({
|
|
369
|
+
...transaction,
|
|
370
|
+
nonce: sequenceNumber,
|
|
371
|
+
...(tokenAccount
|
|
372
|
+
? { recipient: tokenAccount.token.contractAddress, amount: new BigNumber(0) }
|
|
373
|
+
: {}),
|
|
374
|
+
}),
|
|
259
375
|
extra: {
|
|
260
376
|
ledgerOpType: type,
|
|
261
377
|
blockTime: new Date(),
|
|
@@ -263,7 +379,6 @@ export const buildOptimisticOperation = (
|
|
|
263
379
|
},
|
|
264
380
|
};
|
|
265
381
|
|
|
266
|
-
const tokenAccount = subAccountId ? subAccounts?.find(ta => ta.id === subAccountId) : null;
|
|
267
382
|
if (tokenAccount && subAccountId) {
|
|
268
383
|
operation.subOperations = [
|
|
269
384
|
{
|
|
@@ -278,6 +393,10 @@ export const buildOptimisticOperation = (
|
|
|
278
393
|
recipients: [transaction.recipient],
|
|
279
394
|
accountId: subAccountId,
|
|
280
395
|
date: new Date(),
|
|
396
|
+
transactionRaw: toGenericTransactionRaw({
|
|
397
|
+
...transaction,
|
|
398
|
+
nonce: sequenceNumber,
|
|
399
|
+
}),
|
|
281
400
|
extra: {
|
|
282
401
|
ledgerOpType: type,
|
|
283
402
|
},
|
|
@@ -18,7 +18,7 @@ import { REFETCH_TIME_ONE_MINUTE, BASIC_REFETCH, ONE_DAY } from "../utils/timers
|
|
|
18
18
|
import {
|
|
19
19
|
MarketCurrencyRequestParams,
|
|
20
20
|
MarketListRequestParams,
|
|
21
|
-
|
|
21
|
+
MarketCurrencyData,
|
|
22
22
|
HashMapBody,
|
|
23
23
|
MarketItemResponse,
|
|
24
24
|
MarketListRequestResult,
|
|
@@ -118,7 +118,7 @@ export function useMarketData(props: MarketListRequestParams): MarketListRequest
|
|
|
118
118
|
function combineMarketData(
|
|
119
119
|
results: UseQueryResult<
|
|
120
120
|
{
|
|
121
|
-
formattedData:
|
|
121
|
+
formattedData: MarketCurrencyData[];
|
|
122
122
|
page: number;
|
|
123
123
|
},
|
|
124
124
|
Error
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { CryptoCurrency, TokenCurrency } from "@ledgerhq/types-cryptoassets";
|
|
2
2
|
import {
|
|
3
|
-
|
|
3
|
+
MarketCurrencyData,
|
|
4
4
|
KeysPriceChange,
|
|
5
5
|
MarketItemPerformer,
|
|
6
6
|
MarketItemResponse,
|
|
@@ -48,14 +48,14 @@ function sparklineAsSvgData(points: number[]): SparklineSvgData {
|
|
|
48
48
|
export function currencyFormatter(
|
|
49
49
|
data: MarketItemResponse[],
|
|
50
50
|
cryptoCurrenciesList: (CryptoCurrency | TokenCurrency)[],
|
|
51
|
-
):
|
|
51
|
+
): MarketCurrencyData[] {
|
|
52
52
|
return data.map((currency: MarketItemResponse) => format(currency, cryptoCurrenciesList));
|
|
53
53
|
}
|
|
54
54
|
|
|
55
55
|
export const format = (
|
|
56
56
|
currency: MarketItemResponse,
|
|
57
57
|
cryptoCurrenciesList?: (CryptoCurrency | TokenCurrency)[],
|
|
58
|
-
):
|
|
58
|
+
): MarketCurrencyData => {
|
|
59
59
|
const ledgerIdsSet = new Set(currency.ledgerIds.map(id => id.toLowerCase()));
|
|
60
60
|
|
|
61
61
|
const internalCurrency = cryptoCurrenciesList?.find(({ id }) =>
|
|
@@ -33,7 +33,7 @@ export type MarketListRequestParams = {
|
|
|
33
33
|
};
|
|
34
34
|
|
|
35
35
|
export type MarketListRequestResult = {
|
|
36
|
-
data:
|
|
36
|
+
data: MarketCurrencyData[];
|
|
37
37
|
isPending: boolean;
|
|
38
38
|
isLoading: boolean;
|
|
39
39
|
isError: boolean;
|
|
@@ -45,7 +45,7 @@ export type HashMapBody = {
|
|
|
45
45
|
refetch: (options?: RefetchOptions | undefined) => Promise<
|
|
46
46
|
QueryObserverResult<
|
|
47
47
|
{
|
|
48
|
-
formattedData:
|
|
48
|
+
formattedData: MarketCurrencyData[];
|
|
49
49
|
page: number;
|
|
50
50
|
},
|
|
51
51
|
Error
|
|
@@ -80,7 +80,7 @@ export enum KeysPriceChange {
|
|
|
80
80
|
year = "1y",
|
|
81
81
|
}
|
|
82
82
|
|
|
83
|
-
export type
|
|
83
|
+
export type MarketCurrencyData = {
|
|
84
84
|
id: string;
|
|
85
85
|
ledgerIds: string[];
|
|
86
86
|
name: string;
|
|
@@ -113,13 +113,13 @@ export type SingleCoinState = {
|
|
|
113
113
|
loadingChart: boolean;
|
|
114
114
|
error?: Error;
|
|
115
115
|
supportedCounterCurrencies: string[];
|
|
116
|
-
selectedCoinData?:
|
|
116
|
+
selectedCoinData?: MarketCurrencyData;
|
|
117
117
|
counterCurrency?: string;
|
|
118
118
|
};
|
|
119
119
|
|
|
120
120
|
export type State = SingleCoinState & {
|
|
121
121
|
ready: boolean;
|
|
122
|
-
marketData?:
|
|
122
|
+
marketData?: MarketCurrencyData[];
|
|
123
123
|
requestParams: MarketListRequestParams;
|
|
124
124
|
page: number;
|
|
125
125
|
endOfList: boolean;
|
|
@@ -187,7 +187,7 @@ export type MarketItemPerformer = {
|
|
|
187
187
|
|
|
188
188
|
export type MarketDataApi = {
|
|
189
189
|
setSupportedCoinsList: () => Promise<SupportedCoins>;
|
|
190
|
-
listPaginated: (params: MarketListRequestParams) => Promise<
|
|
190
|
+
listPaginated: (params: MarketListRequestParams) => Promise<MarketCurrencyData[]>;
|
|
191
191
|
supportedCounterCurrencies: () => Promise<string[]>;
|
|
192
192
|
currencyChartData: (
|
|
193
193
|
params: MarketCurrencyChartDataRequestParams,
|
|
@@ -4,7 +4,11 @@
|
|
|
4
4
|
import { useFeatureFlags } from "../../featureFlags";
|
|
5
5
|
import { hubStateSelector } from "../reducer";
|
|
6
6
|
import { usePostOnboardingContext } from "./usePostOnboardingContext";
|
|
7
|
-
import {
|
|
7
|
+
import {
|
|
8
|
+
getPostOnboardingAction,
|
|
9
|
+
mockedFeatureIdToTest,
|
|
10
|
+
mockedFeatureParamIdToTest,
|
|
11
|
+
} from "../mock";
|
|
8
12
|
import { renderHook } from "@testing-library/react";
|
|
9
13
|
import { DeviceModelId } from "@ledgerhq/types-devices";
|
|
10
14
|
import { PostOnboardingActionId } from "@ledgerhq/types-live";
|
|
@@ -19,10 +23,16 @@ jest.mock("../reducer");
|
|
|
19
23
|
|
|
20
24
|
const mockedUseFeatureFlags = jest.mocked(useFeatureFlags);
|
|
21
25
|
|
|
22
|
-
const mockedGetFeatureWithMockFeatureEnabled = enabled => ({
|
|
26
|
+
const mockedGetFeatureWithMockFeatureEnabled = (enabled, paramEnabled = true) => ({
|
|
23
27
|
isFeature: () => true,
|
|
24
28
|
getFeature: id => {
|
|
25
|
-
if (id === mockedFeatureIdToTest)
|
|
29
|
+
if (id === mockedFeatureIdToTest)
|
|
30
|
+
return {
|
|
31
|
+
enabled,
|
|
32
|
+
params: {
|
|
33
|
+
[mockedFeatureParamIdToTest]: paramEnabled,
|
|
34
|
+
},
|
|
35
|
+
};
|
|
26
36
|
return { enabled: true };
|
|
27
37
|
},
|
|
28
38
|
overrideFeature: () => {},
|
|
@@ -134,6 +144,23 @@ describe("usePostOnboardingHubState", () => {
|
|
|
134
144
|
expect(lastActionCompleted).toBe(null);
|
|
135
145
|
});
|
|
136
146
|
|
|
147
|
+
it("should not return actions that have a disabled feature param flag ", () => {
|
|
148
|
+
const state = stateAllCompleted;
|
|
149
|
+
mockedHubStateSelector.mockReturnValue(state);
|
|
150
|
+
mockedUseFeatureFlags.mockReturnValue(mockedGetFeatureWithMockFeatureEnabled(true, false));
|
|
151
|
+
|
|
152
|
+
const {
|
|
153
|
+
result: {
|
|
154
|
+
current: { actionsState, lastActionCompleted },
|
|
155
|
+
},
|
|
156
|
+
} = renderHook(() => usePostOnboardingHubState());
|
|
157
|
+
|
|
158
|
+
expect(actionsState.find(action => action.featureFlagId === mockedFeatureIdToTest)).toBe(
|
|
159
|
+
undefined,
|
|
160
|
+
);
|
|
161
|
+
expect(lastActionCompleted).toBe(null);
|
|
162
|
+
});
|
|
163
|
+
|
|
137
164
|
it("should return actions that have a feature flag enabled", () => {
|
|
138
165
|
const state = stateAllCompleted;
|
|
139
166
|
mockedHubStateSelector.mockReturnValue(state);
|
|
@@ -1,10 +1,23 @@
|
|
|
1
1
|
import { useSelector } from "react-redux";
|
|
2
2
|
import { useMemo } from "react";
|
|
3
|
-
import { PostOnboardingHubState } from "@ledgerhq/types-live";
|
|
4
|
-
import { useFeatureFlags } from "../../featureFlags";
|
|
3
|
+
import { PostOnboardingAction, PostOnboardingHubState } from "@ledgerhq/types-live";
|
|
4
|
+
import { FeatureFlagsContextValue, useFeatureFlags } from "../../featureFlags";
|
|
5
5
|
import { hubStateSelector } from "../reducer";
|
|
6
6
|
import { usePostOnboardingContext } from "./usePostOnboardingContext";
|
|
7
7
|
|
|
8
|
+
const getIsFeatureEnabled = (
|
|
9
|
+
action: PostOnboardingAction | undefined,
|
|
10
|
+
getFeature: FeatureFlagsContextValue["getFeature"],
|
|
11
|
+
) => {
|
|
12
|
+
if (!action) return false;
|
|
13
|
+
if (!action.featureFlagId) return true;
|
|
14
|
+
|
|
15
|
+
const flag = getFeature(action.featureFlagId);
|
|
16
|
+
if (!flag?.enabled) return false;
|
|
17
|
+
|
|
18
|
+
return !action.featureFlagParamId || !!flag.params?.[action.featureFlagParamId];
|
|
19
|
+
};
|
|
20
|
+
|
|
8
21
|
/**
|
|
9
22
|
* @returns an object representing the state that should be rendered on the post
|
|
10
23
|
* onboarding hub screen.
|
|
@@ -26,9 +39,12 @@ export function usePostOnboardingHubState(): PostOnboardingHubState {
|
|
|
26
39
|
actionsState: [],
|
|
27
40
|
postOnboardingInProgress: hubState.postOnboardingInProgress,
|
|
28
41
|
};
|
|
42
|
+
|
|
29
43
|
const actionsState = hubState.actionsToComplete.flatMap(actionId => {
|
|
30
44
|
const action = getPostOnboardingAction(actionId);
|
|
31
|
-
|
|
45
|
+
const isFeatureEnabled = getIsFeatureEnabled(action, getFeature);
|
|
46
|
+
|
|
47
|
+
if (!action || !isFeatureEnabled) {
|
|
32
48
|
return [];
|
|
33
49
|
}
|
|
34
50
|
return [{ ...action, completed: !!hubState.actionsCompleted[actionId] }];
|
|
@@ -38,9 +54,7 @@ export function usePostOnboardingHubState(): PostOnboardingHubState {
|
|
|
38
54
|
: null;
|
|
39
55
|
|
|
40
56
|
const isLastActionCompletedEnabled =
|
|
41
|
-
lastActionCompleted &&
|
|
42
|
-
(!lastActionCompleted.featureFlagId ||
|
|
43
|
-
getFeature(lastActionCompleted.featureFlagId)?.enabled);
|
|
57
|
+
lastActionCompleted && getIsFeatureEnabled(lastActionCompleted, getFeature);
|
|
44
58
|
|
|
45
59
|
return {
|
|
46
60
|
deviceModelId: hubState.deviceModelId,
|
|
@@ -5,6 +5,7 @@ import { FeatureId, PostOnboardingAction, PostOnboardingActionId } from "@ledger
|
|
|
5
5
|
const MockIcon = () => null;
|
|
6
6
|
|
|
7
7
|
export const mockedFeatureIdToTest: FeatureId = "mockFeature";
|
|
8
|
+
export const mockedFeatureParamIdToTest: string = "mockFeatureParam";
|
|
8
9
|
|
|
9
10
|
export const claimTestMock: PostOnboardingAction = {
|
|
10
11
|
id: PostOnboardingActionId.claimMock,
|
|
@@ -21,6 +22,7 @@ export const personalizeTestMock: PostOnboardingAction = {
|
|
|
21
22
|
id: PostOnboardingActionId.personalizeMock,
|
|
22
23
|
Icon: MockIcon,
|
|
23
24
|
featureFlagId: mockedFeatureIdToTest,
|
|
25
|
+
featureFlagParamId: mockedFeatureParamIdToTest,
|
|
24
26
|
title: `Personalize my device`,
|
|
25
27
|
titleCompleted: `Personalize my device`,
|
|
26
28
|
description: "By customizing the screen.",
|