@ledgerhq/live-common 34.37.0 → 34.38.0-nightly.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (121) hide show
  1. package/lib/e2e/enum/Provider.d.ts +1 -1
  2. package/lib/e2e/enum/Provider.d.ts.map +1 -1
  3. package/lib/e2e/enum/Provider.js +1 -1
  4. package/lib/e2e/enum/Provider.js.map +1 -1
  5. package/lib/e2e/index.d.ts +6 -0
  6. package/lib/e2e/index.d.ts.map +1 -1
  7. package/lib/e2e/speculos.d.ts.map +1 -1
  8. package/lib/e2e/speculos.js +3 -0
  9. package/lib/e2e/speculos.js.map +1 -1
  10. package/lib/e2e/speculosCI.js +1 -1
  11. package/lib/e2e/swap.d.ts.map +1 -1
  12. package/lib/e2e/swap.js +7 -7
  13. package/lib/e2e/swap.js.map +1 -1
  14. package/lib/exchange/providers/swap.d.ts +1 -0
  15. package/lib/exchange/providers/swap.d.ts.map +1 -1
  16. package/lib/exchange/providers/swap.integration.test.js +26 -12
  17. package/lib/exchange/providers/swap.integration.test.js.map +1 -1
  18. package/lib/exchange/providers/swap.js +25 -0
  19. package/lib/exchange/providers/swap.js.map +1 -1
  20. package/lib/families/evm/config.js +2 -2
  21. package/lib/families/evm/config.js.map +1 -1
  22. package/lib/featureFlags/defaultFeatures.d.ts.map +1 -1
  23. package/lib/featureFlags/defaultFeatures.js +34 -0
  24. package/lib/featureFlags/defaultFeatures.js.map +1 -1
  25. package/lib/featureFlags/stakePrograms/index.d.ts +8 -2
  26. package/lib/featureFlags/stakePrograms/index.d.ts.map +1 -1
  27. package/lib/featureFlags/stakePrograms/index.js +3 -2
  28. package/lib/featureFlags/stakePrograms/index.js.map +1 -1
  29. package/lib/featureFlags/stakePrograms/index.test.js +4 -4
  30. package/lib/featureFlags/stakePrograms/index.test.js.map +1 -1
  31. package/lib/featureFlags/useFeature.d.ts +1 -1
  32. package/lib/featureFlags/useFeature.d.ts.map +1 -1
  33. package/lib/hooks/useOFACGeoBlockCheck.js +1 -1
  34. package/lib/hooks/useOFACGeoBlockCheck.js.map +1 -1
  35. package/lib/hooks/useShowProviderLoadingTransition.d.ts +9 -0
  36. package/lib/hooks/useShowProviderLoadingTransition.d.ts.map +1 -0
  37. package/lib/hooks/useShowProviderLoadingTransition.js +46 -0
  38. package/lib/hooks/useShowProviderLoadingTransition.js.map +1 -0
  39. package/lib/hooks/useShowProviderLoadingTransition.test.d.ts +5 -0
  40. package/lib/hooks/useShowProviderLoadingTransition.test.d.ts.map +1 -0
  41. package/lib/hooks/useShowProviderLoadingTransition.test.js +83 -0
  42. package/lib/hooks/useShowProviderLoadingTransition.test.js.map +1 -0
  43. package/lib/wallet-api/Exchange/server.d.ts +2 -0
  44. package/lib/wallet-api/Exchange/server.d.ts.map +1 -1
  45. package/lib/wallet-api/Exchange/server.js +6 -0
  46. package/lib/wallet-api/Exchange/server.js.map +1 -1
  47. package/lib/wallet-api/ModularDrawer/types.d.ts +30 -25
  48. package/lib/wallet-api/ModularDrawer/types.d.ts.map +1 -1
  49. package/lib/wallet-api/ModularDrawer/types.js +15 -11
  50. package/lib/wallet-api/ModularDrawer/types.js.map +1 -1
  51. package/lib/wallet-api/ModularDrawer/utils.js +1 -1
  52. package/lib/wallet-api/ModularDrawer/utils.js.map +1 -1
  53. package/lib-es/e2e/enum/Provider.d.ts +1 -1
  54. package/lib-es/e2e/enum/Provider.d.ts.map +1 -1
  55. package/lib-es/e2e/enum/Provider.js +1 -1
  56. package/lib-es/e2e/enum/Provider.js.map +1 -1
  57. package/lib-es/e2e/index.d.ts +6 -0
  58. package/lib-es/e2e/index.d.ts.map +1 -1
  59. package/lib-es/e2e/speculos.d.ts.map +1 -1
  60. package/lib-es/e2e/speculos.js +3 -0
  61. package/lib-es/e2e/speculos.js.map +1 -1
  62. package/lib-es/e2e/speculosCI.js +1 -1
  63. package/lib-es/e2e/swap.d.ts.map +1 -1
  64. package/lib-es/e2e/swap.js +7 -7
  65. package/lib-es/e2e/swap.js.map +1 -1
  66. package/lib-es/exchange/providers/swap.d.ts +1 -0
  67. package/lib-es/exchange/providers/swap.d.ts.map +1 -1
  68. package/lib-es/exchange/providers/swap.integration.test.js +27 -13
  69. package/lib-es/exchange/providers/swap.integration.test.js.map +1 -1
  70. package/lib-es/exchange/providers/swap.js +25 -0
  71. package/lib-es/exchange/providers/swap.js.map +1 -1
  72. package/lib-es/families/evm/config.js +2 -2
  73. package/lib-es/families/evm/config.js.map +1 -1
  74. package/lib-es/featureFlags/defaultFeatures.d.ts.map +1 -1
  75. package/lib-es/featureFlags/defaultFeatures.js +34 -0
  76. package/lib-es/featureFlags/defaultFeatures.js.map +1 -1
  77. package/lib-es/featureFlags/stakePrograms/index.d.ts +8 -2
  78. package/lib-es/featureFlags/stakePrograms/index.d.ts.map +1 -1
  79. package/lib-es/featureFlags/stakePrograms/index.js +3 -2
  80. package/lib-es/featureFlags/stakePrograms/index.js.map +1 -1
  81. package/lib-es/featureFlags/stakePrograms/index.test.js +4 -4
  82. package/lib-es/featureFlags/stakePrograms/index.test.js.map +1 -1
  83. package/lib-es/featureFlags/useFeature.d.ts +1 -1
  84. package/lib-es/featureFlags/useFeature.d.ts.map +1 -1
  85. package/lib-es/hooks/useOFACGeoBlockCheck.js +1 -1
  86. package/lib-es/hooks/useOFACGeoBlockCheck.js.map +1 -1
  87. package/lib-es/hooks/useShowProviderLoadingTransition.d.ts +9 -0
  88. package/lib-es/hooks/useShowProviderLoadingTransition.d.ts.map +1 -0
  89. package/lib-es/hooks/useShowProviderLoadingTransition.js +41 -0
  90. package/lib-es/hooks/useShowProviderLoadingTransition.js.map +1 -0
  91. package/lib-es/hooks/useShowProviderLoadingTransition.test.d.ts +5 -0
  92. package/lib-es/hooks/useShowProviderLoadingTransition.test.d.ts.map +1 -0
  93. package/lib-es/hooks/useShowProviderLoadingTransition.test.js +81 -0
  94. package/lib-es/hooks/useShowProviderLoadingTransition.test.js.map +1 -0
  95. package/lib-es/wallet-api/Exchange/server.d.ts +2 -0
  96. package/lib-es/wallet-api/Exchange/server.d.ts.map +1 -1
  97. package/lib-es/wallet-api/Exchange/server.js +6 -0
  98. package/lib-es/wallet-api/Exchange/server.js.map +1 -1
  99. package/lib-es/wallet-api/ModularDrawer/types.d.ts +30 -25
  100. package/lib-es/wallet-api/ModularDrawer/types.d.ts.map +1 -1
  101. package/lib-es/wallet-api/ModularDrawer/types.js +9 -5
  102. package/lib-es/wallet-api/ModularDrawer/types.js.map +1 -1
  103. package/lib-es/wallet-api/ModularDrawer/utils.js +1 -1
  104. package/lib-es/wallet-api/ModularDrawer/utils.js.map +1 -1
  105. package/package.json +61 -61
  106. package/src/e2e/enum/Provider.ts +1 -1
  107. package/src/e2e/speculos.ts +3 -0
  108. package/src/e2e/speculosCI.ts +1 -1
  109. package/src/e2e/swap.ts +8 -7
  110. package/src/exchange/providers/swap.integration.test.ts +33 -16
  111. package/src/exchange/providers/swap.ts +32 -0
  112. package/src/families/evm/config.ts +2 -2
  113. package/src/featureFlags/defaultFeatures.ts +36 -0
  114. package/src/featureFlags/stakePrograms/index.test.ts +4 -4
  115. package/src/featureFlags/stakePrograms/index.ts +5 -6
  116. package/src/hooks/useOFACGeoBlockCheck.ts +1 -1
  117. package/src/hooks/useShowProviderLoadingTransition.test.ts +112 -0
  118. package/src/hooks/useShowProviderLoadingTransition.ts +57 -0
  119. package/src/wallet-api/Exchange/server.ts +8 -0
  120. package/src/wallet-api/ModularDrawer/types.ts +9 -5
  121. package/src/wallet-api/ModularDrawer/utils.ts +1 -1
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@ledgerhq/live-common",
3
3
  "description": "Common ground for the Ledger Live apps",
4
- "version": "34.37.0",
4
+ "version": "34.38.0-nightly.0",
5
5
  "repository": {
6
6
  "type": "git",
7
7
  "url": "https://github.com/LedgerHQ/ledger-live.git"
@@ -139,7 +139,7 @@
139
139
  "fuse.js": "^6.6.2",
140
140
  "invariant": "^2.2.2",
141
141
  "isomorphic-ws": "^4.0.1",
142
- "jotai": "^2.10.1",
142
+ "jotai": "2.12.4",
143
143
  "json-rpc-2.0": "^0.2.19",
144
144
  "lodash": "^4.17.21",
145
145
  "minimatch": "^5.1.0",
@@ -162,70 +162,70 @@
162
162
  "xstate": "^5.19.2",
163
163
  "yargs": "^17.0.0",
164
164
  "zod": "^3.22.4",
165
- "@ledgerhq/coin-algorand": "^0.9.9",
166
- "@ledgerhq/coin-aptos": "^2.2.0",
167
- "@ledgerhq/coin-bitcoin": "^0.16.0",
168
- "@ledgerhq/coin-cardano": "^0.8.9",
169
- "@ledgerhq/coin-casper": "^2.0.0",
170
- "@ledgerhq/coin-celo": "^1.1.7",
171
- "@ledgerhq/coin-evm": "^2.22.3",
172
- "@ledgerhq/coin-cosmos": "^0.15.1",
173
- "@ledgerhq/coin-filecoin": "^1.9.9",
174
- "@ledgerhq/coin-framework": "^5.3.0",
175
- "@ledgerhq/coin-hedera": "^1.7.1",
176
- "@ledgerhq/coin-icon": "^0.10.9",
177
- "@ledgerhq/coin-internet_computer": "^1.7.9",
178
- "@ledgerhq/coin-mina": "^1.1.8",
179
- "@ledgerhq/coin-multiversx": "^0.4.9",
180
- "@ledgerhq/coin-polkadot": "^6.2.0",
181
- "@ledgerhq/coin-near": "^0.11.9",
182
- "@ledgerhq/coin-solana": "^0.25.1",
183
- "@ledgerhq/coin-stacks": "^0.8.9",
184
- "@ledgerhq/coin-stellar": "^5.2.0",
185
- "@ledgerhq/coin-sui": "^0.5.0",
186
- "@ledgerhq/coin-tezos": "^5.3.0",
187
- "@ledgerhq/coin-ton": "^0.12.1",
188
- "@ledgerhq/coin-tron": "^4.2.0",
189
- "@ledgerhq/coin-vechain": "^2.7.9",
190
- "@ledgerhq/coin-xrp": "^6.2.0",
191
- "@ledgerhq/crypto-icons-ui": "^1.14.0",
165
+ "@ledgerhq/coin-algorand": "^0.9.10-nightly.0",
166
+ "@ledgerhq/coin-aptos": "^2.2.1-nightly.0",
167
+ "@ledgerhq/coin-bitcoin": "^0.16.1-nightly.0",
168
+ "@ledgerhq/coin-cardano": "^0.8.10-nightly.0",
169
+ "@ledgerhq/coin-casper": "^2.0.1-nightly.0",
170
+ "@ledgerhq/coin-celo": "^1.1.8-nightly.0",
171
+ "@ledgerhq/coin-cosmos": "^0.15.2-nightly.0",
172
+ "@ledgerhq/coin-evm": "^2.22.4-nightly.0",
173
+ "@ledgerhq/coin-filecoin": "^1.9.10-nightly.0",
174
+ "@ledgerhq/coin-framework": "^5.3.1-nightly.0",
175
+ "@ledgerhq/coin-hedera": "^1.7.2-nightly.0",
176
+ "@ledgerhq/coin-icon": "^0.10.10-nightly.0",
177
+ "@ledgerhq/coin-internet_computer": "^1.7.10-nightly.0",
178
+ "@ledgerhq/coin-mina": "^1.1.9-nightly.0",
179
+ "@ledgerhq/coin-multiversx": "^0.4.10-nightly.0",
180
+ "@ledgerhq/coin-near": "^0.11.10-nightly.0",
181
+ "@ledgerhq/coin-polkadot": "^6.2.1-nightly.0",
182
+ "@ledgerhq/coin-solana": "^0.26.0-nightly.0",
183
+ "@ledgerhq/coin-stacks": "^0.8.10-nightly.0",
184
+ "@ledgerhq/coin-stellar": "^5.2.1-nightly.0",
185
+ "@ledgerhq/coin-sui": "^0.5.1-nightly.0",
186
+ "@ledgerhq/coin-tezos": "^5.3.1-nightly.0",
187
+ "@ledgerhq/coin-ton": "^0.12.2-nightly.0",
188
+ "@ledgerhq/coin-tron": "^4.2.1-nightly.0",
189
+ "@ledgerhq/coin-vechain": "^2.7.10-nightly.0",
190
+ "@ledgerhq/coin-xrp": "^6.2.1-nightly.0",
191
+ "@ledgerhq/crypto-icons-ui": "^1.15.0-nightly.0",
192
192
  "@ledgerhq/cryptoassets": "^13.18.1",
193
- "@ledgerhq/device-core": "^0.4.27",
194
- "@ledgerhq/devices": "8.4.6",
195
- "@ledgerhq/hw-app-algorand": "^6.31.2",
196
- "@ledgerhq/hw-app-aptos": "^6.34.2",
197
- "@ledgerhq/errors": "^6.21.0",
198
- "@ledgerhq/hw-app-btc": "^10.9.2",
199
- "@ledgerhq/hw-app-celo": "^6.33.5",
200
- "@ledgerhq/hw-app-cosmos": "^6.32.2",
201
- "@ledgerhq/hw-app-exchange": "^0.10.2",
202
- "@ledgerhq/hw-app-eth": "^6.45.7",
203
- "@ledgerhq/hw-app-hedera": "^1.2.2",
204
- "@ledgerhq/hw-app-icon": "^1.3.2",
205
- "@ledgerhq/hw-app-multiversx": "^6.24.2",
206
- "@ledgerhq/hw-app-near": "^6.31.2",
207
- "@ledgerhq/hw-app-str": "^7.2.2",
193
+ "@ledgerhq/device-core": "^0.4.28-nightly.0",
194
+ "@ledgerhq/devices": "8.4.7-nightly.0",
195
+ "@ledgerhq/errors": "^6.22.0-nightly.0",
196
+ "@ledgerhq/hw-app-algorand": "^6.31.3-nightly.0",
197
+ "@ledgerhq/hw-app-aptos": "^6.34.3-nightly.0",
198
+ "@ledgerhq/hw-app-btc": "^10.9.3-nightly.0",
199
+ "@ledgerhq/hw-app-celo": "^6.33.6-nightly.0",
200
+ "@ledgerhq/hw-app-cosmos": "^6.32.3-nightly.0",
201
+ "@ledgerhq/hw-app-eth": "^6.45.8-nightly.0",
202
+ "@ledgerhq/hw-app-exchange": "^0.10.3-nightly.0",
203
+ "@ledgerhq/hw-app-hedera": "^1.2.3-nightly.0",
204
+ "@ledgerhq/hw-app-icon": "^1.3.3-nightly.0",
205
+ "@ledgerhq/hw-app-multiversx": "^6.24.3-nightly.0",
206
+ "@ledgerhq/hw-app-near": "^6.31.3-nightly.0",
207
+ "@ledgerhq/hw-app-polkadot": "^6.34.3-nightly.0",
208
+ "@ledgerhq/hw-app-str": "^7.2.3-nightly.0",
208
209
  "@ledgerhq/hw-app-sui": "^1.1.0",
209
- "@ledgerhq/hw-app-polkadot": "^6.34.2",
210
- "@ledgerhq/hw-app-tezos": "^6.31.2",
211
- "@ledgerhq/hw-app-trx": "^6.31.2",
210
+ "@ledgerhq/hw-app-tezos": "^6.31.3-nightly.0",
211
+ "@ledgerhq/hw-app-trx": "^6.31.3-nightly.0",
212
212
  "@ledgerhq/hw-app-vet": "^0.5.6",
213
213
  "@ledgerhq/hw-app-xrp": "^6.32.0",
214
- "@ledgerhq/hw-transport": "^6.31.6",
214
+ "@ledgerhq/hw-transport": "^6.31.7-nightly.0",
215
+ "@ledgerhq/hw-transport-mocker": "^6.29.7-nightly.0",
215
216
  "@ledgerhq/ledger-cal-service": "^0.5.1",
216
- "@ledgerhq/hw-transport-mocker": "^6.29.6",
217
217
  "@ledgerhq/live-config": "^3.1.0",
218
- "@ledgerhq/live-countervalues": "^0.5.9",
219
- "@ledgerhq/live-dmk-shared": "^0.9.0",
220
- "@ledgerhq/live-countervalues-react": "^0.2.38",
218
+ "@ledgerhq/live-countervalues": "^0.5.10-nightly.0",
219
+ "@ledgerhq/live-dmk-shared": "^0.9.1-nightly.0",
220
+ "@ledgerhq/live-countervalues-react": "^0.2.39-nightly.0",
221
221
  "@ledgerhq/live-env": "^2.10.0",
222
222
  "@ledgerhq/live-hooks": "0.1.0",
223
223
  "@ledgerhq/live-network": "^2.0.10",
224
- "@ledgerhq/live-nft": "^0.8.9",
224
+ "@ledgerhq/live-nft": "^0.8.10-nightly.0",
225
225
  "@ledgerhq/live-promise": "^0.1.1",
226
- "@ledgerhq/live-signer-evm": "^0.5.2",
227
- "@ledgerhq/live-signer-solana": "^0.2.1",
228
- "@ledgerhq/live-wallet": "^0.11.0",
226
+ "@ledgerhq/live-signer-evm": "^0.5.3-nightly.0",
227
+ "@ledgerhq/live-signer-solana": "^0.3.0-nightly.0",
228
+ "@ledgerhq/live-wallet": "^0.11.1-nightly.0",
229
229
  "@ledgerhq/logs": "^6.13.0",
230
230
  "@ledgerhq/speculos-transport": "^0.2.3",
231
231
  "@ledgerhq/wallet-api-acre-module": "^0.5.0",
@@ -239,7 +239,7 @@
239
239
  "@tanstack/react-query": "^5.28.9",
240
240
  "@testing-library/react": "^14.1.2",
241
241
  "@types/bs58": "^4.0.1",
242
- "@types/cbor": "^6.0.0",
242
+ "@types/cbor": "6.0.0",
243
243
  "@types/invariant": "^2.2.36",
244
244
  "@types/jest": "^29.5.10",
245
245
  "@types/lodash": "^4.14.179",
@@ -265,8 +265,8 @@
265
265
  "nock": "^13.0.5",
266
266
  "react": "18.3.1",
267
267
  "react-dom": "18.3.1",
268
- "react-native": "0.74.5",
269
- "react-native-svg": "13.14.0",
268
+ "react-native": "0.77.2",
269
+ "react-native-svg": "15.11.2",
270
270
  "react-redux": "^7.2.9",
271
271
  "react-test-renderer": "^18.2.0",
272
272
  "redux-actions": "2.6.5",
@@ -277,10 +277,10 @@
277
277
  "undici": "6.19.2",
278
278
  "uuid": "^8.3.2",
279
279
  "ws": "7",
280
+ "@ledgerhq/device-react": "^0.2.34-nightly.0",
280
281
  "@ledgerhq/types-cryptoassets": "^7.23.0",
281
282
  "@ledgerhq/types-devices": "^6.25.3",
282
- "@ledgerhq/types-live": "^6.73.0",
283
- "@ledgerhq/device-react": "^0.2.33"
283
+ "@ledgerhq/types-live": "^6.74.0-nightly.0"
284
284
  },
285
285
  "scripts": {
286
286
  "build": "zx ./scripts/build-ts.mjs",
@@ -9,7 +9,7 @@ export class Provider {
9
9
  static readonly CHANGELLY = new Provider("changelly", "Changelly", false, true, true);
10
10
  static readonly EXODUS = new Provider("exodus", "Exodus", false, true, true);
11
11
  static readonly ONE_INCH = new Provider("oneinch", "1inch", false, false, true);
12
- static readonly PARASWAP = new Provider("paraswap", "Paraswap", false, false, true);
12
+ static readonly VELORA = new Provider("velora", "Velora", false, false, true);
13
13
  static readonly MOONPAY = new Provider("moonpay", "MoonPay", true, false, true);
14
14
  static readonly THORCHAIN = new Provider("thorswap", "THORChain", false, true, false);
15
15
  static readonly UNISWAP = new Provider("uniswap", "Uniswap", false, false, false);
@@ -569,6 +569,9 @@ export async function expectValidAddressDevice(account: Account, addressDisplaye
569
569
  case Currency.ATOM:
570
570
  deviceLabels = [DeviceLabels.ADDRESS, DeviceLabels.CAPS_APPROVE, DeviceLabels.CAPS_REJECT];
571
571
  break;
572
+ case Currency.BTC:
573
+ deviceLabels = [DeviceLabels.ADDRESS, DeviceLabels.CONFIRM, DeviceLabels.CANCEL];
574
+ break;
572
575
  default:
573
576
  deviceLabels = [DeviceLabels.ADDRESS, DeviceLabels.APPROVE, DeviceLabels.REJECT];
574
577
  break;
@@ -58,7 +58,7 @@ async function githubApiRequest<T = unknown>({
58
58
  }
59
59
  }
60
60
 
61
- function waitForSpeculosReady(url: string, { interval = 2000, timeout = 120_000 } = {}) {
61
+ function waitForSpeculosReady(url: string, { interval = 2000, timeout = 300_000 } = {}) {
62
62
  return new Promise((resolve, reject) => {
63
63
  const startTime = Date.now();
64
64
 
package/src/e2e/swap.ts CHANGED
@@ -3,7 +3,7 @@ import axios from "axios";
3
3
 
4
4
  export async function getMinimumSwapAmount(AccountFrom: Account, AccountTo: Account) {
5
5
  try {
6
- const { data } = await axios({
6
+ const requestConfig = {
7
7
  method: "GET",
8
8
  url: `https://swap-stg.ledger-test.com/v5/quote`,
9
9
  params: {
@@ -24,16 +24,17 @@ export async function getMinimumSwapAmount(AccountFrom: Account, AccountTo: Acco
24
24
  headers: {
25
25
  accept: "application/json",
26
26
  },
27
- });
27
+ };
28
28
 
29
- const minimumAmounts = data.map((item: any) => {
30
- return parseFloat(item.parameter.minAmount);
31
- });
29
+ const { data } = await axios(requestConfig);
30
+
31
+ const minimumAmounts = data
32
+ .filter((item: any) => item.parameter?.minAmount !== undefined)
33
+ .map((item: any) => parseFloat(item.parameter.minAmount));
32
34
 
33
35
  const validMinimumAmounts = minimumAmounts.filter((amount: number) => !isNaN(amount));
34
36
 
35
- const maxMinAmount = Math.max(...validMinimumAmounts);
36
- return maxMinAmount;
37
+ return Math.max(...validMinimumAmounts);
37
38
  } catch (error) {
38
39
  console.error(error);
39
40
  }
@@ -1,19 +1,4 @@
1
- import { fetchAndMergeProviderData, findExchangeCurrencyData } from "./swap";
2
-
3
- describe("findExchangeCurrencyData", () => {
4
- it("returns all data in expected format", async () => {
5
- // When
6
- const currencies = await findExchangeCurrencyData("arbitrum");
7
-
8
- // Then
9
- expect(currencies).toEqual({
10
- config: "0345544808457468657265756d0d0345544812000000000000a4b1",
11
- id: "arbitrum",
12
- signature:
13
- "30450221008ca557e4acc2fa290a6a44c2b0eb5232712ba69b23df93645a320bcff9789fd9022017e6e05582806a9d4b7b2aaaedbcc3471bd26e10ad686e4f313fc0b1068b5d64",
14
- });
15
- });
16
- });
1
+ import { fetchAndMergeProviderData } from "./swap";
17
2
 
18
3
  describe("fetchAndMergeProviderData", () => {
19
4
  it("returns all data in expected format", async () => {
@@ -31,6 +16,11 @@ describe("fetchAndMergeProviderData", () => {
31
16
  mainUrl: "https://changelly.com/",
32
17
  name: "Changelly",
33
18
  needsKYC: false,
19
+ usefulUrls: [
20
+ "https://changelly.com/terms-of-use",
21
+ "https://changelly.com/aml-kyc",
22
+ "https://support.changelly.com/en/support/tickets/new",
23
+ ],
34
24
  publicKey: {
35
25
  curve: "secp256k1",
36
26
  data: Buffer.from(
@@ -47,6 +37,33 @@ describe("fetchAndMergeProviderData", () => {
47
37
  type: "CEX",
48
38
  version: 1,
49
39
  },
40
+ changelly_v2: {
41
+ displayName: "Changelly",
42
+ name: "Changelly",
43
+ useInExchangeApp: true,
44
+ publicKey: {
45
+ curve: "secp256k1",
46
+ data: Buffer.from(
47
+ "0480d7c0d3a9183597395f58dda05999328da6f18fabd5cda0aff8e8e3fc633436a2dbf48ecb23d40df7c3c7d3e774b77b4b5df0e9f7e08cf1cdf2dba788eb085b",
48
+ "hex",
49
+ ),
50
+ },
51
+ signature: Buffer.from(
52
+ "3045022100c2db00da651cfcc84702f75ab5f131a3f037592080ea750a6f665a8cb36797c802200e594938cdf2c836b34717f57487002a0588f2088f64f00a6c4d320fd37db6fa",
53
+ "hex",
54
+ ),
55
+ needsKYC: false,
56
+ type: "CEX",
57
+ usefulUrls: [
58
+ "https://changelly.com/terms-of-use",
59
+ "https://changelly.com/aml-kyc",
60
+ "https://support.changelly.com/en/support/tickets/new",
61
+ ],
62
+ termsOfUseUrl: "https://changelly.com/terms-of-use",
63
+ supportUrl: "https://support.changelly.com/en/support/home",
64
+ mainUrl: "https://changelly.com/",
65
+ version: 2,
66
+ },
50
67
  changenow: {
51
68
  name: "ChangeNOW",
52
69
  publicKey: {
@@ -15,6 +15,7 @@ export type AdditionalProviderConfig = SwapProviderConfig & { type: "DEX" | "CEX
15
15
  version?: number;
16
16
  termsOfUseUrl: string;
17
17
  supportUrl: string;
18
+ usefulUrls?: string[];
18
19
  mainUrl: string;
19
20
  useInExchangeApp: boolean;
20
21
  displayName: string;
@@ -39,10 +40,41 @@ const DEFAULT_SWAP_PROVIDERS: Record<string, ProviderConfig & Partial<Additional
39
40
  needsKYC: false,
40
41
  needsBearerToken: false,
41
42
  type: "CEX",
43
+ usefulUrls: [
44
+ "https://changelly.com/terms-of-use",
45
+ "https://changelly.com/aml-kyc",
46
+ "https://support.changelly.com/en/support/tickets/new",
47
+ ],
42
48
  termsOfUseUrl: "https://changelly.com/terms-of-use",
43
49
  supportUrl: "https://support.changelly.com/en/support/home",
44
50
  mainUrl: "https://changelly.com/",
45
51
  },
52
+ changelly_v2: {
53
+ name: "Changelly",
54
+ publicKey: {
55
+ curve: "secp256k1",
56
+ data: Buffer.from(
57
+ "0480d7c0d3a9183597395f58dda05999328da6f18fabd5cda0aff8e8e3fc633436a2dbf48ecb23d40df7c3c7d3e774b77b4b5df0e9f7e08cf1cdf2dba788eb085b",
58
+ "hex",
59
+ ),
60
+ },
61
+ signature: Buffer.from(
62
+ "3045022100c2db00da651cfcc84702f75ab5f131a3f037592080ea750a6f665a8cb36797c802200e594938cdf2c836b34717f57487002a0588f2088f64f00a6c4d320fd37db6fa",
63
+ "hex",
64
+ ),
65
+ needsKYC: false,
66
+ needsBearerToken: false,
67
+ type: "CEX",
68
+ usefulUrls: [
69
+ "https://changelly.com/terms-of-use",
70
+ "https://changelly.com/aml-kyc",
71
+ "https://support.changelly.com/en/support/tickets/new",
72
+ ],
73
+ termsOfUseUrl: "https://changelly.com/terms-of-use",
74
+ supportUrl: "https://support.changelly.com/en/support/home",
75
+ mainUrl: "https://changelly.com/",
76
+ version: 2,
77
+ },
46
78
  exodus: {
47
79
  name: "exodus",
48
80
  publicKey: {
@@ -104,7 +104,7 @@ const evmConfig: CurrencyLiveConfigDefinition = {
104
104
  type: "ledger",
105
105
  explorerId: "eth",
106
106
  },
107
- showNfts: true,
107
+ showNfts: false,
108
108
  },
109
109
  },
110
110
  config_currency_sonic: {
@@ -266,7 +266,7 @@ const evmConfig: CurrencyLiveConfigDefinition = {
266
266
  type: "ledger",
267
267
  explorerId: "matic",
268
268
  },
269
- showNfts: true,
269
+ showNfts: false,
270
270
  },
271
271
  },
272
272
  config_currency_reosc: {
@@ -396,6 +396,13 @@ export const DEFAULT_FEATURES: Features = {
396
396
  },
397
397
  },
398
398
 
399
+ buySellLoader: {
400
+ enabled: false,
401
+ params: {
402
+ durationMs: 0,
403
+ },
404
+ },
405
+
399
406
  buySellShortcut: {
400
407
  enabled: false,
401
408
  },
@@ -422,6 +429,10 @@ export const DEFAULT_FEATURES: Features = {
422
429
  },
423
430
  },
424
431
 
432
+ ptxSwapLiveAppKycWarning: {
433
+ enabled: false,
434
+ },
435
+
425
436
  llmAnalyticsOptInPrompt: {
426
437
  enabled: false,
427
438
  params: {
@@ -605,6 +616,7 @@ export const DEFAULT_FEATURES: Features = {
605
616
  live_app: true,
606
617
  receive_flow: true,
607
618
  send_flow: true,
619
+ enableModularization: false,
608
620
  },
609
621
  },
610
622
  llNftSupport: DEFAULT_FEATURE,
@@ -620,6 +632,30 @@ export const DEFAULT_FEATURES: Features = {
620
632
  lldNetworkBasedAddAccount: DEFAULT_FEATURE,
621
633
  llmOfacGeoBlocking: DEFAULT_FEATURE,
622
634
  lldOfacGeoBlocking: DEFAULT_FEATURE,
635
+ llmDatadog: {
636
+ ...DEFAULT_FEATURE,
637
+ params: {
638
+ batchProcessingLevel: "MEDIUM",
639
+ batchSize: "MEDIUM",
640
+ bundleLogsWithRum: true,
641
+ bundleLogsWithTraces: true,
642
+ longTaskThresholdMs: 0,
643
+ nativeInteractionTracking: false,
644
+ nativeLongTaskThresholdMs: 0,
645
+ nativeViewTracking: false,
646
+ resourceTracingSamplingRate: 0,
647
+ serviceName: "Ledger Live Mobile (default)",
648
+ sessionSamplingRate: 0,
649
+ trackBackgroundEvents: false,
650
+ trackFrustrations: true,
651
+ trackErrors: false,
652
+ trackResources: false,
653
+ trackInteractions: false,
654
+ trackWatchdogTerminations: false,
655
+ uploadFrequency: "AVERAGE",
656
+ vitalsUpdateFrequency: "AVERAGE",
657
+ },
658
+ },
623
659
  };
624
660
 
625
661
  // Firebase SDK treat JSON values as strings
@@ -35,13 +35,13 @@ const feature_stake_programs_json: Feature_StakePrograms = {
35
35
 
36
36
  describe("stakeProgramsToEarnParam", () => {
37
37
  it("should return `undefined` when there are no redirects", () => {
38
- const result = stakeProgramsToEarnParam(feature_stake_programs_empty_json);
39
- expect(result).toEqual(undefined);
38
+ const { stakeProgramsParam } = stakeProgramsToEarnParam(feature_stake_programs_empty_json);
39
+ expect(stakeProgramsParam).toEqual(undefined);
40
40
  });
41
41
 
42
42
  it("should return a record of stake earn params", () => {
43
- const result = stakeProgramsToEarnParam(feature_stake_programs_json);
44
- expect(result).toEqual({
43
+ const { stakeProgramsParam } = stakeProgramsToEarnParam(feature_stake_programs_json);
44
+ expect(stakeProgramsParam).toEqual({
45
45
  "ethereum/erc20/usd__coin": "kiln-widget",
46
46
  "ethereum/erc20/usd_tether__erc20_": "earn",
47
47
  tron: "stakekit",
@@ -1,19 +1,18 @@
1
- import type { Feature_StakePrograms, PlatformManifestId } from "@ledgerhq/types-live";
1
+ import type { Feature_StakePrograms } from "@ledgerhq/types-live";
2
2
 
3
- export const stakeProgramsToEarnParam = (
4
- stakePrograms: Feature_StakePrograms | null,
5
- ): Record<PlatformManifestId, string> | undefined => {
3
+ export const stakeProgramsToEarnParam = (stakePrograms: Feature_StakePrograms | null) => {
4
+ const list = stakePrograms?.params?.list ?? [];
6
5
  const redirects = stakePrograms?.params?.redirects ?? {};
7
6
  const result: Record<string, string> = {};
8
7
  const keys = Object.keys(redirects);
9
8
  if (keys.length === 0) {
10
- return undefined;
9
+ return { stakeProgramsParam: undefined, stakeCurrenciesParam: [] };
11
10
  }
12
11
  keys.forEach(key => {
13
12
  result[key] = redirects[key].platform;
14
13
  });
15
14
 
16
- return result;
15
+ return { stakeProgramsParam: result, stakeCurrenciesParam: list };
17
16
  };
18
17
 
19
18
  type StablecoinYield = "dapp" | "api" | "inactive";
@@ -20,7 +20,7 @@ export const useOFACGeoBlockCheck = ({
20
20
  queryKey: ["ofac-geo-block", geoBlockingFeatureFlagKey],
21
21
  queryFn: async () => {
22
22
  if (!platformOfacGeoBlocking?.enabled) return false;
23
- const res = await fetch(`${baseURL()}/v3/market`);
23
+ const res = await fetch(`${baseURL()}/v3/markets`);
24
24
  return res.status === 451;
25
25
  },
26
26
  });
@@ -0,0 +1,112 @@
1
+ /**
2
+ * @jest-environment jsdom
3
+ */
4
+
5
+ import { renderHook } from "@testing-library/react";
6
+ import { LiveAppManifest } from "../platform/types";
7
+ import { INTERNAL_APP_IDS } from "../wallet-api/constants";
8
+ import { useFeature } from "../featureFlags";
9
+ import { useInternalAppIds } from "./useInternalAppIds";
10
+
11
+ import { useShowProviderLoadingTransition } from "./useShowProviderLoadingTransition";
12
+
13
+ jest.mock("../featureFlags", () => ({
14
+ useFeature: jest.fn(),
15
+ }));
16
+ jest.mock("../wallet-api/constants", () => ({
17
+ INTERNAL_APP_IDS: ["internal-app-id-1", "internal-app-id-2"],
18
+ }));
19
+ jest.mock("./useInternalAppIds", () => ({
20
+ useInternalAppIds: jest.fn(),
21
+ }));
22
+
23
+ describe("useShowProviderLoadingTransition", () => {
24
+ const mockUseFeature = useFeature as jest.Mock;
25
+ const mockUseInternalAppIds = useInternalAppIds as jest.Mock;
26
+
27
+ beforeEach(() => {
28
+ jest.clearAllMocks();
29
+ });
30
+
31
+ it("should return false when feature is disabled", () => {
32
+ mockUseFeature.mockReturnValue({ enabled: false, params: {} });
33
+ const { result } = renderHook(() =>
34
+ useShowProviderLoadingTransition({
35
+ manifest: { id: "test-app-id" } as LiveAppManifest,
36
+ isLoading: true,
37
+ }),
38
+ );
39
+ expect(result.current).toBe(false);
40
+ });
41
+
42
+ it("should return false for internal apps", () => {
43
+ mockUseFeature.mockReturnValue({ enabled: true, params: {} });
44
+ mockUseInternalAppIds.mockReturnValue(INTERNAL_APP_IDS);
45
+ const { result } = renderHook(() =>
46
+ useShowProviderLoadingTransition({
47
+ manifest: { id: "internal-app-id-1" } as LiveAppManifest,
48
+ isLoading: true,
49
+ }),
50
+ );
51
+ expect(result.current).toBe(false);
52
+ });
53
+
54
+ it("should return true when loading and feature is enabled", () => {
55
+ mockUseFeature.mockReturnValue({ enabled: true, params: {} });
56
+ mockUseInternalAppIds.mockReturnValue([]);
57
+ const { result } = renderHook(() =>
58
+ useShowProviderLoadingTransition({
59
+ manifest: { id: "test-app-id" } as LiveAppManifest,
60
+ isLoading: true,
61
+ }),
62
+ );
63
+ expect(result.current).toBe(true);
64
+ });
65
+
66
+ it("should handle extended loading state", () => {
67
+ jest.useFakeTimers();
68
+ mockUseFeature.mockReturnValue({ enabled: true, params: { durationMs: 1000 } });
69
+ mockUseInternalAppIds.mockReturnValue([]);
70
+
71
+ const { result, rerender } = renderHook(
72
+ ({ isLoading }) =>
73
+ useShowProviderLoadingTransition({
74
+ manifest: { id: "test-app-id" } as LiveAppManifest,
75
+ isLoading,
76
+ }),
77
+ {
78
+ initialProps: { isLoading: true },
79
+ },
80
+ );
81
+
82
+ expect(result.current).toBe(true);
83
+
84
+ // Simulate the timeout
85
+ jest.advanceTimersByTime(1000);
86
+
87
+ rerender({ isLoading: false });
88
+
89
+ expect(result.current).toBe(false);
90
+
91
+ jest.useRealTimers();
92
+ });
93
+ it("should clear timeout on unmount", () => {
94
+ jest.useFakeTimers();
95
+ mockUseFeature.mockReturnValue({ enabled: true, params: { durationMs: 1000 } });
96
+ mockUseInternalAppIds.mockReturnValue([]);
97
+
98
+ const { unmount } = renderHook(() =>
99
+ useShowProviderLoadingTransition({
100
+ manifest: { id: "test-app-id" } as LiveAppManifest,
101
+ isLoading: true,
102
+ }),
103
+ );
104
+
105
+ unmount();
106
+
107
+ // Advance timers to ensure no memory leaks
108
+ jest.advanceTimersByTime(1000);
109
+
110
+ jest.useRealTimers();
111
+ });
112
+ });
@@ -0,0 +1,57 @@
1
+ import { useEffect, useRef, useState } from "react";
2
+
3
+ import { useFeature } from "../featureFlags/index";
4
+ import { INTERNAL_APP_IDS } from "../wallet-api/constants";
5
+ import { useInternalAppIds } from "./useInternalAppIds";
6
+ import { LiveAppManifest } from "../platform/types";
7
+
8
+ export function useShowProviderLoadingTransition({
9
+ isLoading,
10
+ manifest,
11
+ }: {
12
+ manifest: LiveAppManifest;
13
+ isLoading: boolean;
14
+ }) {
15
+ const isEnabled = useProviderInterstitalEnabled({ manifest });
16
+ const [extendedInitialLoading, setExtendedInitialLoading] = useState(false);
17
+
18
+ const timeoutRef = useRef<NodeJS.Timeout | null>(null);
19
+ const buySellLoaderFF = useFeature("buySellLoader");
20
+ const durationMs = buySellLoaderFF?.params?.durationMs ?? 0;
21
+ const internalAppIds = useInternalAppIds() || INTERNAL_APP_IDS;
22
+ const isAppInternal = internalAppIds.includes(manifest.id);
23
+
24
+ useEffect(() => {
25
+ if (isEnabled && isLoading && !extendedInitialLoading) {
26
+ setExtendedInitialLoading(true);
27
+
28
+ if (timeoutRef.current) clearTimeout(timeoutRef.current);
29
+
30
+ timeoutRef.current = setTimeout(() => {
31
+ setExtendedInitialLoading(false);
32
+ }, durationMs);
33
+ }
34
+ }, [durationMs, extendedInitialLoading, isAppInternal, isEnabled, isLoading]);
35
+
36
+ useEffect(() => {
37
+ return () => {
38
+ if (timeoutRef.current) clearTimeout(timeoutRef.current);
39
+ };
40
+ }, []);
41
+
42
+ return isEnabled && (isLoading || extendedInitialLoading);
43
+ }
44
+
45
+ export function useProviderInterstitalEnabled({ manifest }: { manifest?: LiveAppManifest }) {
46
+ const buySellLoaderFF = useFeature("buySellLoader");
47
+ const internalAppIds = useInternalAppIds() || INTERNAL_APP_IDS;
48
+
49
+ if (!manifest) {
50
+ return false;
51
+ }
52
+
53
+ const isAppInternal = internalAppIds.includes(manifest.id);
54
+ const isEnabled = buySellLoaderFF?.enabled && !isAppInternal;
55
+
56
+ return isEnabled;
57
+ }