@ledgerhq/live-common 27.2.0 → 27.3.0-next.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 (371) hide show
  1. package/lib/apps/logic.test.js +1 -1
  2. package/lib/apps/logic.test.js.map +1 -1
  3. package/lib/apps/polyfill.d.ts +1 -1
  4. package/lib/apps/polyfill.d.ts.map +1 -1
  5. package/lib/apps/polyfill.js +6 -3
  6. package/lib/apps/polyfill.js.map +1 -1
  7. package/lib/apps/polyfill.test.d.ts +2 -0
  8. package/lib/apps/polyfill.test.d.ts.map +1 -0
  9. package/lib/apps/polyfill.test.js +25 -0
  10. package/lib/apps/polyfill.test.js.map +1 -0
  11. package/lib/apps/support.d.ts.map +1 -1
  12. package/lib/apps/support.js +3 -2
  13. package/lib/apps/support.js.map +1 -1
  14. package/lib/bot/engine.d.ts.map +1 -1
  15. package/lib/bot/engine.js +154 -45
  16. package/lib/bot/engine.js.map +1 -1
  17. package/lib/bot/formatters.d.ts +1 -1
  18. package/lib/bot/formatters.d.ts.map +1 -1
  19. package/lib/bot/formatters.js +9 -3
  20. package/lib/bot/formatters.js.map +1 -1
  21. package/lib/bot/index.d.ts.map +1 -1
  22. package/lib/bot/index.js +29 -11
  23. package/lib/bot/index.js.map +1 -1
  24. package/lib/bot/specs.d.ts +12 -1
  25. package/lib/bot/specs.d.ts.map +1 -1
  26. package/lib/bot/specs.js +75 -1
  27. package/lib/bot/specs.js.map +1 -1
  28. package/lib/bot/types.d.ts +18 -1
  29. package/lib/bot/types.d.ts.map +1 -1
  30. package/lib/currencies/sortByMarketcap.d.ts.map +1 -1
  31. package/lib/currencies/sortByMarketcap.js +5 -1
  32. package/lib/currencies/sortByMarketcap.js.map +1 -1
  33. package/lib/currencies/support.d.ts.map +1 -1
  34. package/lib/currencies/support.js +2 -1
  35. package/lib/currencies/support.js.map +1 -1
  36. package/lib/derivation.d.ts.map +1 -1
  37. package/lib/derivation.js +2 -4
  38. package/lib/derivation.js.map +1 -1
  39. package/lib/env.js +1 -1
  40. package/lib/exchange/swap/getExchangeRates.d.ts.map +1 -1
  41. package/lib/exchange/swap/getExchangeRates.js +6 -3
  42. package/lib/exchange/swap/getExchangeRates.js.map +1 -1
  43. package/lib/exchange/swap/getProviders.d.ts.map +1 -1
  44. package/lib/exchange/swap/getProviders.js +45 -5
  45. package/lib/exchange/swap/getProviders.js.map +1 -1
  46. package/lib/exchange/swap/getProviders.test.d.ts +2 -0
  47. package/lib/exchange/swap/getProviders.test.d.ts.map +1 -0
  48. package/lib/exchange/swap/getProviders.test.js +519 -0
  49. package/lib/exchange/swap/getProviders.test.js.map +1 -0
  50. package/lib/exchange/swap/hooks/useProviderRates.d.ts +1 -0
  51. package/lib/exchange/swap/hooks/useProviderRates.d.ts.map +1 -1
  52. package/lib/exchange/swap/hooks/useProviderRates.js +19 -4
  53. package/lib/exchange/swap/hooks/useProviderRates.js.map +1 -1
  54. package/lib/exchange/swap/hooks/useProviderRates.test.js +42 -0
  55. package/lib/exchange/swap/hooks/useProviderRates.test.js.map +1 -1
  56. package/lib/exchange/swap/hooks/useSwapTransaction.d.ts +1 -0
  57. package/lib/exchange/swap/hooks/useSwapTransaction.d.ts.map +1 -1
  58. package/lib/exchange/swap/hooks/useSwapTransaction.js +2 -1
  59. package/lib/exchange/swap/hooks/useSwapTransaction.js.map +1 -1
  60. package/lib/exchange/swap/index.d.ts +2 -1
  61. package/lib/exchange/swap/index.d.ts.map +1 -1
  62. package/lib/exchange/swap/index.js +11 -1
  63. package/lib/exchange/swap/index.js.map +1 -1
  64. package/lib/exchange/swap/index.test.js +22 -0
  65. package/lib/exchange/swap/index.test.js.map +1 -1
  66. package/lib/exchange/swap/mock.js +1 -1
  67. package/lib/exchange/swap/mock.js.map +1 -1
  68. package/lib/exchange/swap/types.d.ts +14 -0
  69. package/lib/exchange/swap/types.d.ts.map +1 -1
  70. package/lib/exchange/swap/utils/index.d.ts +1 -0
  71. package/lib/exchange/swap/utils/index.d.ts.map +1 -1
  72. package/lib/exchange/swap/utils/index.js +6 -1
  73. package/lib/exchange/swap/utils/index.js.map +1 -1
  74. package/lib/exchange/swap/utils/index.test.js +12 -0
  75. package/lib/exchange/swap/utils/index.test.js.map +1 -1
  76. package/lib/families/algorand/specs.d.ts.map +1 -1
  77. package/lib/families/algorand/specs.js +2 -0
  78. package/lib/families/algorand/specs.js.map +1 -1
  79. package/lib/families/algorand/speculos-deviceActions.d.ts.map +1 -1
  80. package/lib/families/algorand/speculos-deviceActions.js +2 -29
  81. package/lib/families/algorand/speculos-deviceActions.js.map +1 -1
  82. package/lib/families/bitcoin/specs.d.ts +0 -1
  83. package/lib/families/bitcoin/specs.d.ts.map +1 -1
  84. package/lib/families/bitcoin/specs.js +65 -48
  85. package/lib/families/bitcoin/specs.js.map +1 -1
  86. package/lib/families/bitcoin/speculos-deviceActions.d.ts.map +1 -1
  87. package/lib/families/bitcoin/speculos-deviceActions.js +2 -22
  88. package/lib/families/bitcoin/speculos-deviceActions.js.map +1 -1
  89. package/lib/families/cardano/specs.d.ts.map +1 -1
  90. package/lib/families/cardano/specs.js +9 -4
  91. package/lib/families/cardano/specs.js.map +1 -1
  92. package/lib/families/cardano/speculos-deviceActions.d.ts.map +1 -1
  93. package/lib/families/cardano/speculos-deviceActions.js +2 -10
  94. package/lib/families/cardano/speculos-deviceActions.js.map +1 -1
  95. package/lib/families/celo/specs/createSendMutation.d.ts +1 -0
  96. package/lib/families/celo/specs/createSendMutation.d.ts.map +1 -1
  97. package/lib/families/celo/specs/createSendMutation.js +7 -5
  98. package/lib/families/celo/specs/createSendMutation.js.map +1 -1
  99. package/lib/families/celo/specs.d.ts.map +1 -1
  100. package/lib/families/celo/specs.js +1 -0
  101. package/lib/families/celo/specs.js.map +1 -1
  102. package/lib/families/celo/speculos-deviceActions.d.ts.map +1 -1
  103. package/lib/families/celo/speculos-deviceActions.js +3 -10
  104. package/lib/families/celo/speculos-deviceActions.js.map +1 -1
  105. package/lib/families/cosmos/helpers.d.ts +9 -0
  106. package/lib/families/cosmos/helpers.d.ts.map +1 -0
  107. package/lib/families/cosmos/helpers.js +20 -0
  108. package/lib/families/cosmos/helpers.js.map +1 -0
  109. package/lib/families/cosmos/helpers.unit.test.d.ts +2 -0
  110. package/lib/families/cosmos/helpers.unit.test.d.ts.map +1 -0
  111. package/lib/families/cosmos/helpers.unit.test.js +56 -0
  112. package/lib/families/cosmos/helpers.unit.test.js.map +1 -0
  113. package/lib/families/cosmos/js-signOperation.d.ts.map +1 -1
  114. package/lib/families/cosmos/js-signOperation.js +5 -3
  115. package/lib/families/cosmos/js-signOperation.js.map +1 -1
  116. package/lib/families/cosmos/js-synchronisation.d.ts.map +1 -1
  117. package/lib/families/cosmos/js-synchronisation.js +99 -95
  118. package/lib/families/cosmos/js-synchronisation.js.map +1 -1
  119. package/lib/families/cosmos/specs.d.ts.map +1 -1
  120. package/lib/families/cosmos/specs.js +5 -1
  121. package/lib/families/cosmos/specs.js.map +1 -1
  122. package/lib/families/crypto_org/specs.d.ts.map +1 -1
  123. package/lib/families/crypto_org/specs.js +9 -8
  124. package/lib/families/crypto_org/specs.js.map +1 -1
  125. package/lib/families/elrond/specs.d.ts.map +1 -1
  126. package/lib/families/elrond/specs.js +1 -0
  127. package/lib/families/elrond/specs.js.map +1 -1
  128. package/lib/families/elrond/speculos-deviceActions.d.ts.map +1 -1
  129. package/lib/families/elrond/speculos-deviceActions.js +3 -8
  130. package/lib/families/elrond/speculos-deviceActions.js.map +1 -1
  131. package/lib/families/ethereum/specs.d.ts.map +1 -1
  132. package/lib/families/ethereum/specs.js +20 -8
  133. package/lib/families/ethereum/specs.js.map +1 -1
  134. package/lib/families/ethereum/speculos-deviceActions.d.ts.map +1 -1
  135. package/lib/families/ethereum/speculos-deviceActions.js +10 -33
  136. package/lib/families/ethereum/speculos-deviceActions.js.map +1 -1
  137. package/lib/families/evm/specs.d.ts.map +1 -1
  138. package/lib/families/evm/specs.js +20 -10
  139. package/lib/families/evm/specs.js.map +1 -1
  140. package/lib/families/evm/speculos-deviceActions.d.ts.map +1 -1
  141. package/lib/families/evm/speculos-deviceActions.js +5 -25
  142. package/lib/families/evm/speculos-deviceActions.js.map +1 -1
  143. package/lib/families/filecoin/specs.d.ts.map +1 -1
  144. package/lib/families/filecoin/specs.js +3 -0
  145. package/lib/families/filecoin/specs.js.map +1 -1
  146. package/lib/families/filecoin/speculos-deviceActions.d.ts.map +1 -1
  147. package/lib/families/filecoin/speculos-deviceActions.js +6 -7
  148. package/lib/families/filecoin/speculos-deviceActions.js.map +1 -1
  149. package/lib/families/hedera/specs.d.ts.map +1 -1
  150. package/lib/families/hedera/specs.js +2 -0
  151. package/lib/families/hedera/specs.js.map +1 -1
  152. package/lib/families/osmosis/specs.d.ts.map +1 -1
  153. package/lib/families/osmosis/specs.js +3 -0
  154. package/lib/families/osmosis/specs.js.map +1 -1
  155. package/lib/families/polkadot/specs.d.ts.map +1 -1
  156. package/lib/families/polkadot/specs.js +4 -1
  157. package/lib/families/polkadot/specs.js.map +1 -1
  158. package/lib/families/polkadot/speculos-deviceActions.d.ts.map +1 -1
  159. package/lib/families/polkadot/speculos-deviceActions.js +3 -10
  160. package/lib/families/polkadot/speculos-deviceActions.js.map +1 -1
  161. package/lib/families/ripple/specs.d.ts.map +1 -1
  162. package/lib/families/ripple/specs.js +2 -0
  163. package/lib/families/ripple/specs.js.map +1 -1
  164. package/lib/families/ripple/speculos-deviceActions.d.ts.map +1 -1
  165. package/lib/families/ripple/speculos-deviceActions.js +2 -22
  166. package/lib/families/ripple/speculos-deviceActions.js.map +1 -1
  167. package/lib/families/solana/specs.d.ts.map +1 -1
  168. package/lib/families/solana/specs.js +7 -3
  169. package/lib/families/solana/specs.js.map +1 -1
  170. package/lib/families/solana/speculos-deviceActions.d.ts.map +1 -1
  171. package/lib/families/solana/speculos-deviceActions.js +5 -7
  172. package/lib/families/solana/speculos-deviceActions.js.map +1 -1
  173. package/lib/families/stellar/specs.d.ts.map +1 -1
  174. package/lib/families/stellar/specs.js +1 -0
  175. package/lib/families/stellar/specs.js.map +1 -1
  176. package/lib/families/stellar/speculos-deviceActions.d.ts.map +1 -1
  177. package/lib/families/stellar/speculos-deviceActions.js +4 -8
  178. package/lib/families/stellar/speculos-deviceActions.js.map +1 -1
  179. package/lib/families/tezos/specs.d.ts.map +1 -1
  180. package/lib/families/tezos/specs.js +6 -1
  181. package/lib/families/tezos/specs.js.map +1 -1
  182. package/lib/families/tezos/speculos-deviceActions.d.ts.map +1 -1
  183. package/lib/families/tezos/speculos-deviceActions.js +6 -11
  184. package/lib/families/tezos/speculos-deviceActions.js.map +1 -1
  185. package/lib/families/tron/specs.d.ts.map +1 -1
  186. package/lib/families/tron/specs.js +16 -1
  187. package/lib/families/tron/specs.js.map +1 -1
  188. package/lib/families/tron/speculos-deviceActions.d.ts.map +1 -1
  189. package/lib/families/tron/speculos-deviceActions.js +2 -14
  190. package/lib/families/tron/speculos-deviceActions.js.map +1 -1
  191. package/lib/families/tron/synchronisation.integration.test.d.ts +2 -0
  192. package/lib/families/tron/synchronisation.integration.test.d.ts.map +1 -0
  193. package/lib/families/tron/{synchronisation.test.js → synchronisation.integration.test.js} +1 -1
  194. package/lib/families/tron/synchronisation.integration.test.js.map +1 -0
  195. package/lib/featureFlags/defaultFeatures.d.ts.map +1 -1
  196. package/lib/featureFlags/defaultFeatures.js +6 -0
  197. package/lib/featureFlags/defaultFeatures.js.map +1 -1
  198. package/lib/generated/specs.d.ts +0 -1
  199. package/lib/generated/specs.d.ts.map +1 -1
  200. package/lib/hw/actions/installLanguage.js +1 -1
  201. package/lib/hw/extractOnboardingState.d.ts +5 -1
  202. package/lib/hw/extractOnboardingState.d.ts.map +1 -1
  203. package/lib/hw/extractOnboardingState.js +17 -9
  204. package/lib/hw/extractOnboardingState.js.map +1 -1
  205. package/lib/hw/extractOnboardingState.test.js +21 -11
  206. package/lib/hw/extractOnboardingState.test.js.map +1 -1
  207. package/lib/load/speculos.d.ts.map +1 -1
  208. package/lib/load/speculos.js +39 -15
  209. package/lib/load/speculos.js.map +1 -1
  210. package/lib/manager/hooks.d.ts +4 -1
  211. package/lib/manager/hooks.d.ts.map +1 -1
  212. package/lib/manager/hooks.js +4 -3
  213. package/lib/manager/hooks.js.map +1 -1
  214. package/lib/manager/localization.js +2 -2
  215. package/lib/manager/localization.js.map +1 -1
  216. package/lib/mock/account.d.ts.map +1 -1
  217. package/lib/mock/account.js +17 -19
  218. package/lib/mock/account.js.map +1 -1
  219. package/lib/notifications/ServiceStatusProvider/index.d.ts.map +1 -1
  220. package/lib/notifications/ServiceStatusProvider/index.js +5 -1
  221. package/lib/notifications/ServiceStatusProvider/index.js.map +1 -1
  222. package/lib/postOnboarding/PostOnboardingProvider.d.ts +20 -0
  223. package/lib/postOnboarding/PostOnboardingProvider.d.ts.map +1 -0
  224. package/lib/postOnboarding/PostOnboardingProvider.js +33 -0
  225. package/lib/postOnboarding/PostOnboardingProvider.js.map +1 -0
  226. package/lib/postOnboarding/actions.d.ts +20 -0
  227. package/lib/postOnboarding/actions.d.ts.map +1 -0
  228. package/lib/postOnboarding/actions.js +37 -0
  229. package/lib/postOnboarding/actions.js.map +1 -0
  230. package/lib/postOnboarding/hooks/index.d.ts +6 -0
  231. package/lib/postOnboarding/hooks/index.d.ts.map +1 -0
  232. package/lib/postOnboarding/hooks/index.js +22 -0
  233. package/lib/postOnboarding/hooks/index.js.map +1 -0
  234. package/lib/postOnboarding/hooks/useAllPostOnboardingActionsCompleted.d.ts +8 -0
  235. package/lib/postOnboarding/hooks/useAllPostOnboardingActionsCompleted.d.ts.map +1 -0
  236. package/lib/postOnboarding/hooks/useAllPostOnboardingActionsCompleted.js +16 -0
  237. package/lib/postOnboarding/hooks/useAllPostOnboardingActionsCompleted.js.map +1 -0
  238. package/lib/postOnboarding/hooks/useAllPostOnboardingActionsCompleted.test.d.ts +2 -0
  239. package/lib/postOnboarding/hooks/useAllPostOnboardingActionsCompleted.test.d.ts.map +1 -0
  240. package/lib/postOnboarding/hooks/useAllPostOnboardingActionsCompleted.test.js +75 -0
  241. package/lib/postOnboarding/hooks/useAllPostOnboardingActionsCompleted.test.js.map +1 -0
  242. package/lib/postOnboarding/hooks/usePostOnboardingContext.d.ts +3 -0
  243. package/lib/postOnboarding/hooks/usePostOnboardingContext.d.ts.map +1 -0
  244. package/lib/postOnboarding/hooks/usePostOnboardingContext.js +10 -0
  245. package/lib/postOnboarding/hooks/usePostOnboardingContext.js.map +1 -0
  246. package/lib/postOnboarding/hooks/usePostOnboardingEntryPointVisibleOnWallet.d.ts +8 -0
  247. package/lib/postOnboarding/hooks/usePostOnboardingEntryPointVisibleOnWallet.d.ts.map +1 -0
  248. package/lib/postOnboarding/hooks/usePostOnboardingEntryPointVisibleOnWallet.js +20 -0
  249. package/lib/postOnboarding/hooks/usePostOnboardingEntryPointVisibleOnWallet.js.map +1 -0
  250. package/lib/postOnboarding/hooks/usePostOnboardingEntryPointVisibleOnWallet.test.d.ts +2 -0
  251. package/lib/postOnboarding/hooks/usePostOnboardingEntryPointVisibleOnWallet.test.d.ts.map +1 -0
  252. package/lib/postOnboarding/hooks/usePostOnboardingEntryPointVisibleOnWallet.test.js +64 -0
  253. package/lib/postOnboarding/hooks/usePostOnboardingEntryPointVisibleOnWallet.test.js.map +1 -0
  254. package/lib/postOnboarding/hooks/usePostOnboardingHubState.d.ts +12 -0
  255. package/lib/postOnboarding/hooks/usePostOnboardingHubState.d.ts.map +1 -0
  256. package/lib/postOnboarding/hooks/usePostOnboardingHubState.js +65 -0
  257. package/lib/postOnboarding/hooks/usePostOnboardingHubState.js.map +1 -0
  258. package/lib/postOnboarding/hooks/usePostOnboardingHubState.test.d.ts +2 -0
  259. package/lib/postOnboarding/hooks/usePostOnboardingHubState.test.d.ts.map +1 -0
  260. package/lib/postOnboarding/hooks/usePostOnboardingHubState.test.js +129 -0
  261. package/lib/postOnboarding/hooks/usePostOnboardingHubState.test.js.map +1 -0
  262. package/lib/postOnboarding/hooks/useStartPostOnboardingCallback.d.ts +13 -0
  263. package/lib/postOnboarding/hooks/useStartPostOnboardingCallback.d.ts.map +1 -0
  264. package/lib/postOnboarding/hooks/useStartPostOnboardingCallback.js +34 -0
  265. package/lib/postOnboarding/hooks/useStartPostOnboardingCallback.js.map +1 -0
  266. package/lib/postOnboarding/mock.d.ts +8 -0
  267. package/lib/postOnboarding/mock.d.ts.map +1 -0
  268. package/lib/postOnboarding/mock.js +46 -0
  269. package/lib/postOnboarding/mock.js.map +1 -0
  270. package/lib/postOnboarding/reducer.d.ts +22 -0
  271. package/lib/postOnboarding/reducer.d.ts.map +1 -0
  272. package/lib/postOnboarding/reducer.js +71 -0
  273. package/lib/postOnboarding/reducer.js.map +1 -0
  274. package/lib/postOnboarding/reducer.test.d.ts +2 -0
  275. package/lib/postOnboarding/reducer.test.d.ts.map +1 -0
  276. package/lib/postOnboarding/reducer.test.js +251 -0
  277. package/lib/postOnboarding/reducer.test.js.map +1 -0
  278. package/package.json +24 -20
  279. package/src/__tests__/__snapshots__/portfolio.v2.ts.snap +16 -0
  280. package/src/apps/__snapshots__/logic.test.ts.snap +18 -11
  281. package/src/apps/logic.test.ts +1 -2
  282. package/src/apps/polyfill.test.ts +24 -0
  283. package/src/apps/polyfill.ts +7 -2
  284. package/src/apps/support.ts +2 -1
  285. package/src/bot/engine.ts +178 -35
  286. package/src/bot/formatters.ts +15 -2
  287. package/src/bot/index.ts +48 -19
  288. package/src/bot/specs.ts +95 -1
  289. package/src/bot/types.ts +23 -1
  290. package/src/currencies/__snapshots__/sortByMarketcap.test.ts.snap +55 -6
  291. package/src/currencies/sortByMarketcap.ts +6 -1
  292. package/src/currencies/support.ts +2 -1
  293. package/src/derivation.ts +2 -4
  294. package/src/env.ts +1 -1
  295. package/src/exchange/swap/getExchangeRates.ts +12 -5
  296. package/src/exchange/swap/getProviders.test.ts +450 -0
  297. package/src/exchange/swap/getProviders.ts +31 -8
  298. package/src/exchange/swap/hooks/useProviderRates.test.ts +43 -0
  299. package/src/exchange/swap/hooks/useProviderRates.ts +22 -3
  300. package/src/exchange/swap/hooks/useSwapTransaction.ts +3 -1
  301. package/src/exchange/swap/index.test.ts +36 -1
  302. package/src/exchange/swap/index.ts +15 -0
  303. package/src/exchange/swap/mock.ts +2 -2
  304. package/src/exchange/swap/types.ts +11 -0
  305. package/src/exchange/swap/utils/index.test.ts +19 -0
  306. package/src/exchange/swap/utils/index.ts +5 -0
  307. package/src/families/algorand/specs.ts +3 -1
  308. package/src/families/algorand/speculos-deviceActions.ts +4 -35
  309. package/src/families/bitcoin/specs.ts +72 -56
  310. package/src/families/bitcoin/speculos-deviceActions.ts +3 -26
  311. package/src/families/cardano/specs.ts +9 -4
  312. package/src/families/cardano/speculos-deviceActions.ts +3 -14
  313. package/src/families/celo/specs/createSendMutation.ts +5 -3
  314. package/src/families/celo/specs.ts +2 -0
  315. package/src/families/celo/speculos-deviceActions.ts +6 -14
  316. package/src/families/cosmos/__snapshots__/bridge.integration.test.ts.snap +24 -44
  317. package/src/families/cosmos/helpers.ts +21 -0
  318. package/src/families/cosmos/helpers.unit.test.ts +63 -0
  319. package/src/families/cosmos/js-signOperation.ts +6 -3
  320. package/src/families/cosmos/js-synchronisation.ts +120 -119
  321. package/src/families/cosmos/specs.ts +11 -2
  322. package/src/families/crypto_org/specs.ts +12 -19
  323. package/src/families/elrond/specs.ts +1 -0
  324. package/src/families/elrond/speculos-deviceActions.ts +4 -9
  325. package/src/families/ethereum/specs.ts +34 -38
  326. package/src/families/ethereum/speculos-deviceActions.ts +16 -46
  327. package/src/families/evm/specs.ts +18 -8
  328. package/src/families/evm/speculos-deviceActions.ts +7 -35
  329. package/src/families/filecoin/specs.ts +4 -1
  330. package/src/families/filecoin/speculos-deviceActions.ts +7 -8
  331. package/src/families/hedera/specs.ts +3 -1
  332. package/src/families/osmosis/specs.ts +4 -1
  333. package/src/families/polkadot/specs.ts +11 -2
  334. package/src/families/polkadot/speculos-deviceActions.ts +5 -16
  335. package/src/families/ripple/specs.ts +3 -1
  336. package/src/families/ripple/speculos-deviceActions.ts +3 -28
  337. package/src/families/solana/specs.ts +15 -4
  338. package/src/families/solana/speculos-deviceActions.ts +6 -8
  339. package/src/families/stellar/specs.ts +1 -0
  340. package/src/families/stellar/speculos-deviceActions.ts +5 -11
  341. package/src/families/tezos/specs.ts +7 -5
  342. package/src/families/tezos/speculos-deviceActions.ts +9 -16
  343. package/src/families/tron/specs.ts +31 -3
  344. package/src/families/tron/speculos-deviceActions.ts +4 -12
  345. package/src/families/tron/{synchronisation.test.ts → synchronisation.integration.test.ts} +0 -0
  346. package/src/featureFlags/defaultFeatures.ts +6 -0
  347. package/src/hw/actions/installLanguage.ts +1 -1
  348. package/src/hw/extractOnboardingState.test.ts +29 -12
  349. package/src/hw/extractOnboardingState.ts +17 -9
  350. package/src/load/speculos.ts +42 -21
  351. package/src/manager/hooks.ts +6 -6
  352. package/src/manager/localization.ts +2 -2
  353. package/src/mock/account.ts +18 -20
  354. package/src/notifications/ServiceStatusProvider/index.tsx +8 -1
  355. package/src/postOnboarding/PostOnboardingProvider.tsx +49 -0
  356. package/src/postOnboarding/actions.ts +40 -0
  357. package/src/postOnboarding/hooks/index.ts +5 -0
  358. package/src/postOnboarding/hooks/useAllPostOnboardingActionsCompleted.test.ts +82 -0
  359. package/src/postOnboarding/hooks/useAllPostOnboardingActionsCompleted.ts +12 -0
  360. package/src/postOnboarding/hooks/usePostOnboardingContext.ts +9 -0
  361. package/src/postOnboarding/hooks/usePostOnboardingEntryPointVisibleOnWallet.test.ts +83 -0
  362. package/src/postOnboarding/hooks/usePostOnboardingEntryPointVisibleOnWallet.ts +22 -0
  363. package/src/postOnboarding/hooks/usePostOnboardingHubState.test.ts +184 -0
  364. package/src/postOnboarding/hooks/usePostOnboardingHubState.ts +56 -0
  365. package/src/postOnboarding/hooks/useStartPostOnboardingCallback.ts +38 -0
  366. package/src/postOnboarding/mock.ts +53 -0
  367. package/src/postOnboarding/reducer.test.ts +247 -0
  368. package/src/postOnboarding/reducer.ts +105 -0
  369. package/lib/families/tron/synchronisation.test.d.ts +0 -2
  370. package/lib/families/tron/synchronisation.test.d.ts.map +0 -1
  371. package/lib/families/tron/synchronisation.test.js.map +0 -1
@@ -368,21 +368,21 @@ Object {
368
368
  "name": "Dogecoin",
369
369
  },
370
370
  Object {
371
- "blocks": 1,
372
- "bytes": 4096,
371
+ "blocks": 10,
372
+ "bytes": 40960,
373
373
  "currencyId": "zcash",
374
374
  "name": "Zcash",
375
375
  },
376
376
  ],
377
377
  "appsSpaceBlocks": 60,
378
378
  "appsSpaceBytes": 245760,
379
- "freeSpaceBlocks": 27,
380
- "freeSpaceBytes": 110592,
379
+ "freeSpaceBlocks": 18,
380
+ "freeSpaceBytes": 73728,
381
381
  "osBlocks": 20,
382
382
  "osBytes": 81920,
383
383
  "shouldWarnMemory": false,
384
- "totalAppsBlocks": 33,
385
- "totalAppsBytes": 135168,
384
+ "totalAppsBlocks": 42,
385
+ "totalAppsBytes": 172032,
386
386
  "totalBlocks": 80,
387
387
  "totalBytes": 327680,
388
388
  }
@@ -390,16 +390,23 @@ Object {
390
390
 
391
391
  exports[`Scenario: order is preserved in uninstall action plan 1`] = `
392
392
  Object {
393
- "apps": Array [],
393
+ "apps": Array [
394
+ Object {
395
+ "blocks": 1,
396
+ "bytes": 4096,
397
+ "currencyId": "zcash",
398
+ "name": "Zcash",
399
+ },
400
+ ],
394
401
  "appsSpaceBlocks": 60,
395
402
  "appsSpaceBytes": 245760,
396
- "freeSpaceBlocks": 60,
397
- "freeSpaceBytes": 245760,
403
+ "freeSpaceBlocks": 59,
404
+ "freeSpaceBytes": 241664,
398
405
  "osBlocks": 20,
399
406
  "osBytes": 81920,
400
407
  "shouldWarnMemory": false,
401
- "totalAppsBlocks": 0,
402
- "totalAppsBytes": 0,
408
+ "totalAppsBlocks": 1,
409
+ "totalAppsBytes": 4096,
403
410
  "totalBlocks": 80,
404
411
  "totalBytes": 327680,
405
412
  }
@@ -313,8 +313,7 @@ const scenarios = [
313
313
  name: "Bitcoin",
314
314
  },
315
315
  ],
316
- expectPlan:
317
- "-XRP, -Ethereum Classic, -Ethereum, -Dogecoin, -Zcash, -Bitcoin",
316
+ expectPlan: "-XRP, -Ethereum Classic, -Ethereum, -Dogecoin, -Bitcoin",
318
317
  expectInstalled: "",
319
318
  },
320
319
  ],
@@ -0,0 +1,24 @@
1
+ import { Application } from "@ledgerhq/types-live";
2
+ import { polyfillApplication } from "./polyfill";
3
+
4
+ test("polyfillApplication set ethereum currency for ethereum app", () => {
5
+ const app: Application = {
6
+ id: 1,
7
+ name: "Ethereum",
8
+ description: undefined,
9
+ application_versions: [],
10
+ providers: [],
11
+ category: 0,
12
+ date_creation: "",
13
+ date_last_modified: "",
14
+ publisher: undefined,
15
+ currencyId: undefined,
16
+ authorName: undefined,
17
+ supportURL: undefined,
18
+ contactURL: undefined,
19
+ sourceURL: undefined,
20
+ compatibleWalletsJSON: undefined,
21
+ };
22
+ const polyfilled = polyfillApplication(app);
23
+ expect(polyfilled.currencyId).toEqual("ethereum");
24
+ });
@@ -7,7 +7,14 @@ import {
7
7
  import { App, Application } from "@ledgerhq/types-live";
8
8
  const directDep = {};
9
9
  const reverseDep = {};
10
+
11
+ // whitelist dependencies
12
+ export const whitelistDependencies = ["Decred", "Decred Test", "Zcash"];
13
+
10
14
  export function declareDep(name: string, dep: string) {
15
+ if (whitelistDependencies.includes(name)) {
16
+ return;
17
+ }
11
18
  directDep[name] = (directDep[name] || []).concat(dep);
12
19
  reverseDep[dep] = (reverseDep[dep] || []).concat(name);
13
20
  }
@@ -25,8 +32,6 @@ listCryptoCurrencies(true, true).forEach((a) => {
25
32
  declareDep(a.managerAppName + " Test", dep.managerAppName);
26
33
  }
27
34
  });
28
- // whitelist dependencies
29
- export const whitelistDependencies = ["Decred", "Decred Testnet"];
30
35
 
31
36
  // extra dependencies
32
37
  [
@@ -33,10 +33,11 @@ const appVersionsRequired = {
33
33
  Algorand: ">= 1.2.9",
34
34
  Polkadot: ">= 13.9250.0",
35
35
  Elrond: ">= 1.0.11",
36
- Ethereum: ">= 1.9.17",
36
+ Ethereum: ">= 1.9.20 || 1.9.20-dev",
37
37
  Solana: ">= 1.2.0",
38
38
  Celo: ">= 1.1.8",
39
39
  "Cardano ADA": ">= 4.1.0",
40
+ Zcash: "> 2.0.6",
40
41
  };
41
42
  export function mustUpgrade(
42
43
  deviceModel: DeviceModelId,
package/src/bot/engine.ts CHANGED
@@ -41,6 +41,7 @@ import type {
41
41
  TransactionTestInput,
42
42
  TransactionArg,
43
43
  TransactionRes,
44
+ TransactionDestinationTestInput,
44
45
  } from "./types";
45
46
  import { makeBridgeCacheSystem } from "../bridge/cache";
46
47
  import { accountDataToAccount, accountToAccountData } from "../cross";
@@ -91,7 +92,9 @@ export async function runWithAppSpec<T extends Transaction>(
91
92
  const { appQuery, currency, dependency } = spec;
92
93
  const appCandidate = findAppCandidate(appCandidates, appQuery);
93
94
  if (!appCandidate) {
94
- console.warn("no app found for " + spec.name, { appQuery, appCandidates });
95
+ console.warn("no app found for " + spec.name);
96
+ console.warn(appQuery);
97
+ console.warn(JSON.stringify(appCandidates, undefined, 2));
95
98
  }
96
99
  invariant(
97
100
  appCandidate,
@@ -113,9 +116,24 @@ export async function runWithAppSpec<T extends Transaction>(
113
116
  coinapps,
114
117
  };
115
118
  let device;
116
- const appReport: SpecReport<T> = {
117
- spec,
118
- };
119
+ const hintWarnings: string[] = [];
120
+ const appReport: SpecReport<T> = { spec, hintWarnings };
121
+
122
+ // staticly check that all mutations declared a test too (if no generic spec test)
123
+ if (!spec.test) {
124
+ const list = spec.mutations.filter((m) => !m.test);
125
+ if (list.length > 0) {
126
+ hintWarnings.push(
127
+ "mutations should define a test(): " +
128
+ list.map((m) => m.name).join(", ")
129
+ );
130
+ }
131
+ }
132
+
133
+ // staticly assess if testDestination is necessary
134
+ const mutationThatProducedDestinationsWithoutTests: MutationSpec<any>[] = [];
135
+ const mutationWithDestinationTestsWithoutDestination: MutationSpec<any>[] =
136
+ [];
119
137
 
120
138
  try {
121
139
  device = await createSpeculosDevice(deviceParams);
@@ -150,6 +168,16 @@ export async function runWithAppSpec<T extends Transaction>(
150
168
  )
151
169
  .toPromise();
152
170
  appReport.scanDuration = now() - beforeScanTime;
171
+
172
+ // check if there are more accounts than mutation declared as a hint for the dev
173
+ if (accounts.length <= spec.mutations.length) {
174
+ hintWarnings.push(
175
+ "There are not enough accounts to cover all mutations. Please increase the account target to at least " +
176
+ (spec.mutations.length + 1) +
177
+ " accounts"
178
+ );
179
+ }
180
+
153
181
  // "Migrate" the FIRST and every {crossAccountFrequency} account to simulate an export/import (same logic as export to mobile) – default to every 10
154
182
  // this is made a subset of the accounts to help identify problem that would be specific to the "cross" or not.
155
183
  for (
@@ -239,6 +267,33 @@ export async function runWithAppSpec<T extends Transaction>(
239
267
  a.id === finalAccount.id ? finalAccount : a
240
268
  );
241
269
  }
270
+ if (report.finalDestination) {
271
+ // optim: no need to resync if all went well with finalDestination
272
+ const finalDestination: Account = report.finalDestination;
273
+ accountIdsNeedResync = accountIdsNeedResync.filter(
274
+ (id) => id !== finalDestination.id
275
+ );
276
+ accounts = accounts.map((a: Account) =>
277
+ a.id === finalDestination.id ? finalDestination : a
278
+ );
279
+ } else if (report.mutation) {
280
+ const { mutation } = report;
281
+ if (report.destination) {
282
+ if (
283
+ !mutation.testDestination &&
284
+ !mutationThatProducedDestinationsWithoutTests.includes(mutation)
285
+ ) {
286
+ mutationThatProducedDestinationsWithoutTests.push(mutation);
287
+ }
288
+ } else {
289
+ if (
290
+ mutation.testDestination &&
291
+ !mutationWithDestinationTestsWithoutDestination.includes(mutation)
292
+ ) {
293
+ mutationWithDestinationTestsWithoutDestination.push(mutation);
294
+ }
295
+ }
296
+ }
242
297
  // eslint-disable-next-line no-console
243
298
  console.log(formatReportForConsole(report));
244
299
  mutationReports.push(report);
@@ -261,11 +316,32 @@ export async function runWithAppSpec<T extends Transaction>(
261
316
  mutationsCount = {};
262
317
  }
263
318
 
264
- accounts = await promiseAllBatched(
265
- getEnv("SYNC_MAX_CONCURRENT"),
266
- accounts,
267
- syncAccount
268
- );
319
+ if (
320
+ mutationReports.every((r) => !r.mutation) &&
321
+ accounts.some((a) => a.spendableBalance.gt(spec.minViableAmount || 0))
322
+ ) {
323
+ hintWarnings.push(
324
+ "No mutation were found possible. Yet there are funds in the accounts, please investigate."
325
+ );
326
+ }
327
+
328
+ if (mutationThatProducedDestinationsWithoutTests.length) {
329
+ hintWarnings.push(
330
+ "mutations should define a testDestination(): " +
331
+ mutationThatProducedDestinationsWithoutTests
332
+ .map((m) => m.name)
333
+ .join(", ")
334
+ );
335
+ }
336
+ if (mutationWithDestinationTestsWithoutDestination.length) {
337
+ hintWarnings.push(
338
+ "mutations should NOT define a testDestination() because there are no 'destination' sibling account found: " +
339
+ mutationWithDestinationTestsWithoutDestination
340
+ .map((m) => m.name)
341
+ .join(", ")
342
+ );
343
+ }
344
+
269
345
  appReport.mutations = mutationReports;
270
346
  appReport.accountsAfter = accounts;
271
347
  } catch (e: any) {
@@ -327,6 +403,7 @@ export async function runOnAccount<T extends Transaction>({
327
403
  mutation: MutationSpec<T>;
328
404
  tx: T;
329
405
  updates: Array<Partial<T> | null | undefined>;
406
+ destination: Account | undefined;
330
407
  }> = [];
331
408
  const unavailableMutationReasons: Array<{
332
409
  mutation: MutationSpec<T>;
@@ -356,6 +433,7 @@ export async function runOnAccount<T extends Transaction>({
356
433
  tx: r.transaction,
357
434
  // $FlowFixMe what the hell
358
435
  updates: r.updates,
436
+ destination: r.destination,
359
437
  });
360
438
  } catch (error: any) {
361
439
  if (process.env.CI) console.error(error);
@@ -398,9 +476,10 @@ export async function runOnAccount<T extends Transaction>({
398
476
  }
399
477
 
400
478
  report.transaction = transaction;
401
- report.destination = accounts.find(
402
- (a) => a.freshAddress === transaction.recipient
403
- );
479
+ const destination =
480
+ candidate.destination ||
481
+ accounts.find((a) => a.freshAddress === transaction.recipient);
482
+ report.destination = destination;
404
483
  status = await accountBridge.getTransactionStatus(account, transaction);
405
484
  report.status = status;
406
485
  report.statusTime = now();
@@ -480,6 +559,8 @@ export async function runOnAccount<T extends Transaction>({
480
559
  if (report.destination) {
481
560
  accountIdsNeedResync.push(report.destination.id);
482
561
  }
562
+ // even if the test will actively sync the account, we need to pessimisticly assume it won't, we may not reach the final step of it.
563
+ // after the runOnAccount() call, we actively remove from accountIdsNeedResync the account.id if it is actually sucessful
483
564
  accountIdsNeedResync.push(account.id);
484
565
 
485
566
  // broadcast the transaction
@@ -504,12 +585,11 @@ export async function runOnAccount<T extends Transaction>({
504
585
  );
505
586
 
506
587
  // wait the condition are good (operation confirmed)
588
+ // test() is run over and over until either timeout is reach OR success
507
589
  const testBefore = now();
508
-
590
+ const timeOut = mutation.testTimeout || spec.testTimeout || 30 * 1000;
509
591
  const step = (account) => {
510
- const timedOut =
511
- now() - testBefore >
512
- (mutation.testTimeout || spec.testTimeout || 30 * 1000);
592
+ const timedOut = now() - testBefore > timeOut;
513
593
  const operation = account.operations.find(
514
594
  (o) => o.id === optimisticOperation.id
515
595
  );
@@ -543,6 +623,7 @@ export async function runOnAccount<T extends Transaction>({
543
623
  throw e;
544
624
  }
545
625
 
626
+ log("bot", "failed confirm test. trying again. " + String(e));
546
627
  // We will try again
547
628
  return;
548
629
  }
@@ -551,17 +632,80 @@ export async function runOnAccount<T extends Transaction>({
551
632
  return operation;
552
633
  };
553
634
 
554
- const result = await awaitAccountOperation({
555
- account,
556
- step,
557
- });
558
- report.finalAccount = result.account;
559
- report.operation = result.operation;
635
+ const result = await awaitAccountOperation<Operation>({ account, step });
636
+ const { account: finalAccount, value: operation } = result;
637
+ report.finalAccount = finalAccount;
638
+ report.operation = operation;
560
639
  report.confirmedTime = now();
561
640
  log(
562
641
  "engine",
563
642
  `spec ${spec.name}/${account.name}/${optimisticOperation.hash} confirmed`
564
643
  );
644
+
645
+ const destinationBeforeTransaction = destination;
646
+ if (destination && mutation.testDestination) {
647
+ const { testDestination } = mutation;
648
+ // test() is run over and over until either timeout is reach OR success
649
+ const ntestBefore = now();
650
+ const newTimeOut = Math.max(10000, timeOut - (ntestBefore - testBefore));
651
+ log(
652
+ "bot",
653
+ "remaining time to test destination: " +
654
+ (newTimeOut / 1000).toFixed(0) +
655
+ "s"
656
+ );
657
+ const sendingOperation = operation;
658
+ const step = (account) => {
659
+ const timedOut = now() - ntestBefore > newTimeOut;
660
+ let operation;
661
+ try {
662
+ operation = account.operations.find(
663
+ (op) => op.hash === sendingOperation.hash
664
+ );
665
+ botTest(
666
+ "destination account should receive an operation (by tx hash)",
667
+ () =>
668
+ invariant(
669
+ operation,
670
+ "no operation found with hash %s",
671
+ operation.hash
672
+ )
673
+ );
674
+ if (!operation) throw new Error();
675
+ const arg: TransactionDestinationTestInput<T> = {
676
+ transaction,
677
+ status,
678
+ sendingAccount: finalAccount,
679
+ sendingOperation,
680
+ operation,
681
+ destinationBeforeTransaction,
682
+ destination: account,
683
+ };
684
+ botTest("destination", () => testDestination(arg));
685
+ report.testDestinationDuration = now() - ntestBefore;
686
+ } catch (e) {
687
+ // We never reach the final test success
688
+ if (timedOut) {
689
+ report.testDestinationDuration = now() - ntestBefore;
690
+ throw e;
691
+ }
692
+ log(
693
+ "bot",
694
+ "failed destination confirm test. trying again. " + String(e)
695
+ );
696
+ // We will try again
697
+ return;
698
+ }
699
+ return operation;
700
+ };
701
+ const result = await awaitAccountOperation<Operation>({
702
+ account: destination,
703
+ step,
704
+ });
705
+ report.finalDestination = result.account;
706
+ report.finalDestinationOperation = result.value;
707
+ report.destinationConfirmedTime = now();
708
+ }
565
709
  } catch (error: any) {
566
710
  if (process.env.CI) console.error(error);
567
711
  log("mutation-error", spec.name + ": " + formatError(error, true));
@@ -674,15 +818,15 @@ export function autoSignTransaction<T extends Transaction>({
674
818
  });
675
819
  }
676
820
 
677
- function awaitAccountOperation({
821
+ function awaitAccountOperation<T>({
678
822
  account,
679
823
  step,
680
824
  }: {
681
825
  account: Account;
682
- step: (arg0: Account) => Operation | null | undefined;
826
+ step: (arg0: Account) => T | null | undefined;
683
827
  }): Promise<{
684
828
  account: Account;
685
- operation: Operation;
829
+ value: T;
686
830
  }> {
687
831
  log("engine", "awaitAccountOperation on " + account.name);
688
832
  let syncCounter = 0;
@@ -692,13 +836,12 @@ function awaitAccountOperation({
692
836
  const targetInterval = getEnv("SYNC_PENDING_INTERVAL");
693
837
 
694
838
  async function loop() {
695
- const operation = step(acc);
839
+ const value = step(acc);
696
840
 
697
- if (operation) {
698
- log("engine", "found " + operation.id);
841
+ if (value) {
699
842
  return {
700
843
  account: acc,
701
- operation,
844
+ value,
702
845
  };
703
846
  }
704
847
  const spent = now() - lastSync;
@@ -720,14 +863,14 @@ function transactionTest<T>({
720
863
  optimisticOperation,
721
864
  account,
722
865
  }: TransactionTestInput<T>) {
723
- const timingThreshold = 30 * 60 * 1000;
724
- // FIXME: .valueOf to do arithmetic operations on date with typescript
725
- const dt = Date.now().valueOf() - operation.date.valueOf();
866
+ const dt = Date.now() - operation.date.getTime();
867
+ const lowerThreshold = -60 * 1000; // -1mn accepted
868
+ const upperThreshold = 30 * 60 * 1000; // 30mn up
726
869
  botTest("operation.date must not be in future", () =>
727
- expect(dt).toBeGreaterThanOrEqual(0)
870
+ expect(dt).toBeGreaterThan(lowerThreshold)
728
871
  );
729
872
  botTest("operation.date less than 30mn ago", () =>
730
- expect(dt).toBeLessThan(timingThreshold)
873
+ expect(dt).toBeLessThan(upperThreshold)
731
874
  );
732
875
  botTest("operation must not failed", () => {
733
876
  expect(!operation.hasFailed).toBe(true);
@@ -737,7 +880,7 @@ function transactionTest<T>({
737
880
 
738
881
  if (blockAvgTime && account.blockHeight) {
739
882
  const expected = getOperationConfirmationNumber(operation, account);
740
- const expectedMax = Math.ceil(timingThreshold / blockAvgTime);
883
+ const expectedMax = Math.ceil(upperThreshold / blockAvgTime);
741
884
  botTest("low amount of confirmations", () =>
742
885
  invariant(
743
886
  expected <= expectedMax,
@@ -74,6 +74,9 @@ export function formatReportForConsole<T extends Transaction>({
74
74
  operation,
75
75
  confirmedTime,
76
76
  finalAccount,
77
+ finalDestination,
78
+ finalDestinationOperation,
79
+ testDestinationDuration,
77
80
  testDuration,
78
81
  error,
79
82
  }: MutationReport<T>): string {
@@ -167,11 +170,21 @@ export function formatReportForConsole<T extends Transaction>({
167
170
  }
168
171
 
169
172
  if (finalAccount) {
170
- str += `✔️ ${formatAccount(finalAccount, "basic")}\n`;
173
+ str += `✔️ ${formatAccount(finalAccount, "basic")}`;
171
174
  }
172
175
 
173
176
  if (testDuration) {
174
- str += `(final state reached in ${formatTime(testDuration)})\n`;
177
+ str += `(in ${formatTime(testDuration)})\n`;
178
+ }
179
+
180
+ if (finalDestination && finalDestinationOperation) {
181
+ str += `✔️ destination operation ${formatOperation(finalDestination)(
182
+ finalDestinationOperation
183
+ )}\n`;
184
+ }
185
+
186
+ if (testDestinationDuration) {
187
+ str += `(in ${formatTime(testDestinationDuration)})\n`;
175
188
  }
176
189
 
177
190
  if (error) {
package/src/bot/index.ts CHANGED
@@ -9,7 +9,7 @@ import invariant from "invariant";
9
9
  import flatMap from "lodash/flatMap";
10
10
  import { getEnv } from "../env";
11
11
  import allSpecs from "../generated/specs";
12
- import type { MutationReport, SpecReport } from "./types";
12
+ import type { AppSpec, MutationReport, SpecReport } from "./types";
13
13
  import { promiseAllBatched } from "../promise";
14
14
  import {
15
15
  findCryptoCurrencyByKeyword,
@@ -17,7 +17,7 @@ import {
17
17
  formatCurrencyUnit,
18
18
  getFiatCurrencyByTicker,
19
19
  } from "../currencies";
20
- import { isAccountEmpty, toAccountRaw } from "../account";
20
+ import { formatAccount, isAccountEmpty, toAccountRaw } from "../account";
21
21
  import { runWithAppSpec } from "./engine";
22
22
  import { formatReportForConsole, formatError, formatTime } from "./formatters";
23
23
  import {
@@ -28,6 +28,7 @@ import {
28
28
  import { getPortfolio } from "../portfolio/v2";
29
29
  import { Account } from "@ledgerhq/types-live";
30
30
  import { getContext } from "./bot-test-context";
31
+
31
32
  type Arg = Partial<{
32
33
  currency: string;
33
34
  family: string;
@@ -71,7 +72,7 @@ export async function bot({
71
72
  }
72
73
 
73
74
  for (const key in familySpecs) {
74
- let spec = familySpecs[key];
75
+ let spec: AppSpec<any> = familySpecs[key];
75
76
 
76
77
  if (!isCurrencySupported(spec.currency) || spec.disabled) {
77
78
  continue;
@@ -81,7 +82,7 @@ export async function bot({
81
82
  if (mutation) {
82
83
  spec = {
83
84
  ...spec,
84
- mutations: spec.mutation.filter((m) =>
85
+ mutations: spec.mutations.filter((m) =>
85
86
  new RegExp(mutation).test(m.name)
86
87
  ),
87
88
  };
@@ -96,7 +97,7 @@ export async function bot({
96
97
  const results: Array<SpecReport<any>> = await promiseAllBatched(
97
98
  getEnv("BOT_MAX_CONCURRENT"),
98
99
  specs,
99
- (spec) => {
100
+ (spec: AppSpec<any>) => {
100
101
  const logs: string[] = [];
101
102
  specsLogs.push(logs);
102
103
  return runWithAppSpec(spec, (message) => {
@@ -109,6 +110,7 @@ export async function bot({
109
110
  mutations: [],
110
111
  accountsBefore: [],
111
112
  accountsAfter: [],
113
+ hintWarnings: [],
112
114
  }));
113
115
  }
114
116
  );
@@ -373,13 +375,31 @@ export async function bot({
373
375
 
374
376
  if (errorCases.length) {
375
377
  appendBody("<details>\n");
376
- appendBody(`<summary>${errorCases.length} mutation errors</summary>\n\n`);
378
+ appendBody(
379
+ `<summary>❌ ${errorCases.length} mutation errors</summary>\n\n`
380
+ );
377
381
  errorCases.forEach((c) => {
378
382
  appendBody("```\n" + formatReportForConsole(c) + "\n```\n\n");
379
383
  });
380
384
  appendBody("</details>\n\n");
381
385
  }
382
386
 
387
+ const specWithWarnings = results.filter((s) => s.hintWarnings.length > 0);
388
+ if (specWithWarnings.length > 0) {
389
+ appendBody("<details>\n");
390
+ appendBody(
391
+ `<summary>⚠️ ${specWithWarnings.reduce(
392
+ (sum, s) => s.hintWarnings.length + sum,
393
+ 0
394
+ )} spec hints</summary>\n\n`
395
+ );
396
+ specWithWarnings.forEach((s) => {
397
+ appendBody(`- Spec ${s.spec.name}:\n`);
398
+ s.hintWarnings.forEach((txt) => appendBody(` - ${txt}\n`));
399
+ });
400
+ appendBody("</details>\n\n");
401
+ }
402
+
383
403
  appendBodyFullOnly("<details>\n");
384
404
 
385
405
  appendBodyFullOnly(
@@ -508,12 +528,9 @@ export async function bot({
508
528
 
509
529
  const beforeOps = countOps(r.accountsBefore);
510
530
  const afterOps = countOps(r.accountsAfter);
511
- const firstAccount = (r.accountsAfter || r.accountsBefore || [])[0];
512
- appendBody(
513
- `| ${r.spec.name} (${
514
- (r.accountsBefore || []).filter((a) => a.used).length
515
- }) `
516
- );
531
+ const accounts = r.accountsAfter || r.accountsBefore || [];
532
+ const firstAccount = accounts[0];
533
+ appendBody(`| ${r.spec.name} (${accounts.filter((a) => a.used).length}) `);
517
534
  appendBody(
518
535
  `| ${afterOps || beforeOps}${
519
536
  afterOps > beforeOps ? ` (+${afterOps - beforeOps})` : ""
@@ -525,6 +542,11 @@ export async function bot({
525
542
  );
526
543
  appendBody("|\n");
527
544
  });
545
+
546
+ appendBody("\n```\n");
547
+ appendBody(allAccountsAfter.map((a) => formatAccount(a, "head")).join("\n"));
548
+ appendBody("\n```\n");
549
+
528
550
  appendBody("\n</details>\n\n");
529
551
 
530
552
  // Add performance details
@@ -545,9 +567,9 @@ export async function bot({
545
567
  }
546
568
 
547
569
  appendBody(
548
- "| Spec (accounts) | preload | scan | re-sync | tx status | sign op | broadcast | mutation confirm |\n"
570
+ "| Spec (accounts) | preload | scan | re-sync | tx status | sign op | broadcast | test | destination test |\n"
549
571
  );
550
- appendBody("|---|---|---|---|---|---|---|---|\n");
572
+ appendBody("|---|---|---|---|---|---|---|---|---|\n");
551
573
 
552
574
  appendBody("| **TOTAL** |");
553
575
  appendBody(`**${formatTime(sumResults((r) => r.preloadDuration))}** |`);
@@ -585,15 +607,17 @@ export async function bot({
585
607
  ? m.confirmedTime - m.broadcastedTime
586
608
  : 0
587
609
  )
610
+ )}** |`
611
+ );
612
+ appendBody(
613
+ `**${formatTime(
614
+ sumResultsMutation((m) => m.testDestinationDuration || 0)
588
615
  )}** |\n`
589
616
  );
590
617
 
591
618
  results.forEach((r) => {
592
- appendBody(
593
- `| ${r.spec.name} (${
594
- (r.accountsBefore || []).filter((a) => a.used).length
595
- }) |`
596
- );
619
+ const accounts = r.accountsAfter || r.accountsBefore || [];
620
+ appendBody(`| ${r.spec.name} (${accounts.filter((a) => a.used).length}) |`);
597
621
  appendBody(`${formatTime(r.preloadDuration || 0)} |`);
598
622
  appendBody(`${formatTime(r.scanDuration || 0)} |`);
599
623
  appendBody(
@@ -631,6 +655,11 @@ export async function bot({
631
655
  ? m.confirmedTime - m.broadcastedTime
632
656
  : 0
633
657
  )
658
+ )} |`
659
+ );
660
+ appendBody(
661
+ `${formatTime(
662
+ sumMutation(r.mutations, (m) => m.testDestinationDuration || 0)
634
663
  )} |\n`
635
664
  );
636
665
  });