@ledgerhq/context-module 1.15.0 → 1.17.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 (410) hide show
  1. package/README.md +10 -0
  2. package/lib/cjs/package.json +1 -2
  3. package/lib/cjs/src/ContextModule.js +1 -1
  4. package/lib/cjs/src/ContextModule.js.map +1 -1
  5. package/lib/cjs/src/ContextModuleBuilder.js +1 -1
  6. package/lib/cjs/src/ContextModuleBuilder.js.map +3 -3
  7. package/lib/cjs/src/ContextModuleBuilder.test.js +1 -1
  8. package/lib/cjs/src/ContextModuleBuilder.test.js.map +3 -3
  9. package/lib/cjs/src/DefaultContextModule.js +1 -1
  10. package/lib/cjs/src/DefaultContextModule.js.map +3 -3
  11. package/lib/cjs/src/DefaultContextModule.test.js +1 -1
  12. package/lib/cjs/src/DefaultContextModule.test.js.map +2 -2
  13. package/lib/cjs/src/account-ownership/data/AccountOwnershipDataSource.js +2 -0
  14. package/lib/cjs/src/account-ownership/data/AccountOwnershipDataSource.js.map +7 -0
  15. package/lib/cjs/src/account-ownership/data/AccountOwnershipError.js +2 -0
  16. package/lib/cjs/src/account-ownership/data/AccountOwnershipError.js.map +7 -0
  17. package/lib/cjs/src/account-ownership/data/HttpAccountOwnershipDataSource.js +2 -0
  18. package/lib/cjs/src/account-ownership/data/HttpAccountOwnershipDataSource.js.map +7 -0
  19. package/lib/cjs/src/account-ownership/data/HttpAccountOwnershipDataSource.test.js +2 -0
  20. package/lib/cjs/src/account-ownership/data/HttpAccountOwnershipDataSource.test.js.map +7 -0
  21. package/lib/cjs/src/account-ownership/data/dto/AccountOwnershipDto.js +2 -0
  22. package/lib/cjs/src/account-ownership/data/dto/AccountOwnershipDto.js.map +7 -0
  23. package/lib/cjs/src/account-ownership/di/accountOwnershipModuleFactory.js +2 -0
  24. package/lib/cjs/src/account-ownership/di/accountOwnershipModuleFactory.js.map +7 -0
  25. package/lib/cjs/src/account-ownership/di/accountOwnershipTypes.js +2 -0
  26. package/lib/cjs/src/account-ownership/di/accountOwnershipTypes.js.map +7 -0
  27. package/lib/cjs/src/account-ownership/domain/AccountOwnershipContextLoader.js +2 -0
  28. package/lib/cjs/src/account-ownership/domain/AccountOwnershipContextLoader.js.map +7 -0
  29. package/lib/cjs/src/account-ownership/domain/AccountOwnershipContextLoader.test.js +2 -0
  30. package/lib/cjs/src/account-ownership/domain/AccountOwnershipContextLoader.test.js.map +7 -0
  31. package/lib/cjs/src/calldata/data/HttpCalldataDescriptorDataSource.js +1 -1
  32. package/lib/cjs/src/calldata/data/HttpCalldataDescriptorDataSource.js.map +3 -3
  33. package/lib/cjs/src/calldata/data/HttpCalldataDescriptorDataSource.test.js +1 -1
  34. package/lib/cjs/src/calldata/data/HttpCalldataDescriptorDataSource.test.js.map +3 -3
  35. package/lib/cjs/src/calldata/di/calldataModuleFactory.js +1 -1
  36. package/lib/cjs/src/calldata/di/calldataModuleFactory.js.map +3 -3
  37. package/lib/cjs/src/config/di/configModuleFactory.js +1 -1
  38. package/lib/cjs/src/config/di/configModuleFactory.js.map +2 -2
  39. package/lib/cjs/src/config/model/ContextModuleConfig.js +1 -1
  40. package/lib/cjs/src/config/model/ContextModuleConfig.js.map +1 -1
  41. package/lib/cjs/src/di.js +1 -1
  42. package/lib/cjs/src/di.js.map +3 -3
  43. package/lib/cjs/src/dynamic-network/data/HttpDynamicNetworkDataSource.js +1 -1
  44. package/lib/cjs/src/dynamic-network/data/HttpDynamicNetworkDataSource.js.map +3 -3
  45. package/lib/cjs/src/dynamic-network/data/HttpDynamicNetworkDataSource.test.js +1 -1
  46. package/lib/cjs/src/dynamic-network/data/HttpDynamicNetworkDataSource.test.js.map +3 -3
  47. package/lib/cjs/src/dynamic-network/domain/DynamicNetworkContextLoader.js +1 -1
  48. package/lib/cjs/src/dynamic-network/domain/DynamicNetworkContextLoader.js.map +1 -1
  49. package/lib/cjs/src/dynamic-network/domain/DynamicNetworkContextLoader.test.js.map +1 -1
  50. package/lib/cjs/src/external-plugin/data/HttpExternalPluginDataSource.js +1 -1
  51. package/lib/cjs/src/external-plugin/data/HttpExternalPluginDataSource.js.map +3 -3
  52. package/lib/cjs/src/external-plugin/data/HttpExternalPluginDataSource.test.js +1 -1
  53. package/lib/cjs/src/external-plugin/data/HttpExternalPluginDataSource.test.js.map +3 -3
  54. package/lib/cjs/src/gated-signing/data/HttpGatedDescriptorDataSource.js +1 -1
  55. package/lib/cjs/src/gated-signing/data/HttpGatedDescriptorDataSource.js.map +3 -3
  56. package/lib/cjs/src/gated-signing/data/HttpGatedDescriptorDataSource.test.js +1 -1
  57. package/lib/cjs/src/gated-signing/data/HttpGatedDescriptorDataSource.test.js.map +3 -3
  58. package/lib/cjs/src/index.js +1 -1
  59. package/lib/cjs/src/index.js.map +2 -2
  60. package/lib/cjs/src/network/di/networkModuleFactory.js +2 -0
  61. package/lib/cjs/src/network/di/networkModuleFactory.js.map +7 -0
  62. package/lib/cjs/src/network/di/networkTypes.js +2 -0
  63. package/lib/cjs/src/network/di/networkTypes.js.map +7 -0
  64. package/lib/cjs/src/nft/data/HttpNftDataSource.js +1 -1
  65. package/lib/cjs/src/nft/data/HttpNftDataSource.js.map +3 -3
  66. package/lib/cjs/src/nft/data/HttpNftDataSource.test.js +1 -1
  67. package/lib/cjs/src/nft/data/HttpNftDataSource.test.js.map +3 -3
  68. package/lib/cjs/src/pki/data/HttpPkiCertificateDataSource.js +1 -1
  69. package/lib/cjs/src/pki/data/HttpPkiCertificateDataSource.js.map +3 -3
  70. package/lib/cjs/src/pki/data/HttpPkiCertificateDataSource.test.js +1 -1
  71. package/lib/cjs/src/pki/data/HttpPkiCertificateDataSource.test.js.map +3 -3
  72. package/lib/cjs/src/proxy/data/HttpProxyDataSource.js +1 -1
  73. package/lib/cjs/src/proxy/data/HttpProxyDataSource.js.map +3 -3
  74. package/lib/cjs/src/proxy/data/HttpProxyDataSource.test.js +1 -1
  75. package/lib/cjs/src/proxy/data/HttpProxyDataSource.test.js.map +3 -3
  76. package/lib/cjs/src/proxy/data/HttpSafeProxyDataSource.js +1 -1
  77. package/lib/cjs/src/proxy/data/HttpSafeProxyDataSource.js.map +3 -3
  78. package/lib/cjs/src/proxy/data/HttpSafeProxyDataSource.test.js +1 -1
  79. package/lib/cjs/src/proxy/data/HttpSafeProxyDataSource.test.js.map +3 -3
  80. package/lib/cjs/src/proxy/di/proxyModuleFactory.js +1 -1
  81. package/lib/cjs/src/proxy/di/proxyModuleFactory.js.map +3 -3
  82. package/lib/cjs/src/proxy/di/proxyModuleFactory.test.js +1 -1
  83. package/lib/cjs/src/proxy/di/proxyModuleFactory.test.js.map +3 -3
  84. package/lib/cjs/src/reporter/data/BlindSigningReporterDatasource.js +2 -0
  85. package/lib/cjs/src/reporter/data/BlindSigningReporterDatasource.js.map +7 -0
  86. package/lib/cjs/src/reporter/data/HttpBlindSigningReporterDatasource.js +2 -0
  87. package/lib/cjs/src/reporter/data/HttpBlindSigningReporterDatasource.js.map +7 -0
  88. package/lib/cjs/src/reporter/data/HttpBlindSigningReporterDatasource.test.js +2 -0
  89. package/lib/cjs/src/reporter/data/HttpBlindSigningReporterDatasource.test.js.map +7 -0
  90. package/lib/cjs/src/reporter/data/dto/BlindSigningEventDto.js +2 -0
  91. package/lib/cjs/src/reporter/data/dto/BlindSigningEventDto.js.map +7 -0
  92. package/lib/cjs/src/reporter/di/reporterModuleFactory.js +2 -0
  93. package/lib/cjs/src/reporter/di/reporterModuleFactory.js.map +7 -0
  94. package/lib/cjs/src/reporter/di/reporterTypes.js +2 -0
  95. package/lib/cjs/src/reporter/di/reporterTypes.js.map +7 -0
  96. package/lib/cjs/src/reporter/domain/BlindSigningReporter.js +2 -0
  97. package/lib/cjs/src/reporter/domain/BlindSigningReporter.js.map +7 -0
  98. package/lib/cjs/src/reporter/domain/DefaultBlindSigningReporter.js +2 -0
  99. package/lib/cjs/src/reporter/domain/DefaultBlindSigningReporter.js.map +7 -0
  100. package/lib/cjs/src/reporter/domain/DefaultBlindSigningReporter.test.js +2 -0
  101. package/lib/cjs/src/reporter/domain/DefaultBlindSigningReporter.test.js.map +7 -0
  102. package/lib/cjs/src/reporter/model/BlindSigningEvent.js +2 -0
  103. package/lib/cjs/src/reporter/model/BlindSigningEvent.js.map +7 -0
  104. package/lib/cjs/src/reporter/model/BlindSigningModelId.js +2 -0
  105. package/lib/cjs/src/reporter/model/BlindSigningModelId.js.map +7 -0
  106. package/lib/cjs/src/safe/data/HttpSafeAccountDataSource.js +1 -1
  107. package/lib/cjs/src/safe/data/HttpSafeAccountDataSource.js.map +3 -3
  108. package/lib/cjs/src/safe/data/HttpSafeAccountDataSource.test.js +1 -1
  109. package/lib/cjs/src/safe/data/HttpSafeAccountDataSource.test.js.map +3 -3
  110. package/lib/cjs/src/shared/model/ClearSignContext.js +1 -1
  111. package/lib/cjs/src/shared/model/ClearSignContext.js.map +2 -2
  112. package/lib/cjs/src/solana/data/HttpSolanaOwnerInfoDataSource.js +1 -1
  113. package/lib/cjs/src/solana/data/HttpSolanaOwnerInfoDataSource.js.map +3 -3
  114. package/lib/cjs/src/solana/data/HttpSolanaOwnerInfoDataSource.test.js +1 -1
  115. package/lib/cjs/src/solana/data/HttpSolanaOwnerInfoDataSource.test.js.map +3 -3
  116. package/lib/cjs/src/solana/domain/DefaultSolanaContextLoader.test.js +1 -1
  117. package/lib/cjs/src/solana/domain/DefaultSolanaContextLoader.test.js.map +1 -1
  118. package/lib/cjs/src/solanaLifi/data/HttpSolanaLifiDataSource.js +1 -1
  119. package/lib/cjs/src/solanaLifi/data/HttpSolanaLifiDataSource.js.map +3 -3
  120. package/lib/cjs/src/solanaLifi/data/HttpSolanaLifiDataSource.test.js +1 -1
  121. package/lib/cjs/src/solanaLifi/data/HttpSolanaLifiDataSource.test.js.map +3 -3
  122. package/lib/cjs/src/solanaLifi/domain/SolanaLifiContextLoader.js.map +1 -1
  123. package/lib/cjs/src/solanaLifi/domain/SolanaLifiContextLoader.test.js.map +1 -1
  124. package/lib/cjs/src/solanaToken/data/HttpSolanaTokenDataSource.js +1 -1
  125. package/lib/cjs/src/solanaToken/data/HttpSolanaTokenDataSource.js.map +3 -3
  126. package/lib/cjs/src/solanaToken/data/HttpSolanaTokenDataSource.test.js +6 -6
  127. package/lib/cjs/src/solanaToken/data/HttpSolanaTokenDataSource.test.js.map +3 -3
  128. package/lib/cjs/src/solanaToken/domain/SolanaTokenContextLoader.js +1 -1
  129. package/lib/cjs/src/solanaToken/domain/SolanaTokenContextLoader.js.map +2 -2
  130. package/lib/cjs/src/solanaToken/domain/SolanaTokenContextLoader.test.js +1 -1
  131. package/lib/cjs/src/solanaToken/domain/SolanaTokenContextLoader.test.js.map +1 -1
  132. package/lib/cjs/src/token/data/HttpTokenDataSource.js +1 -1
  133. package/lib/cjs/src/token/data/HttpTokenDataSource.js.map +3 -3
  134. package/lib/cjs/src/token/data/HttpTokenDataSource.test.js +1 -1
  135. package/lib/cjs/src/token/data/HttpTokenDataSource.test.js.map +3 -3
  136. package/lib/cjs/src/transaction-check/data/HttpTransactionCheckDataSource.js +1 -1
  137. package/lib/cjs/src/transaction-check/data/HttpTransactionCheckDataSource.js.map +3 -3
  138. package/lib/cjs/src/transaction-check/data/HttpTransactionCheckDataSource.test.js +1 -1
  139. package/lib/cjs/src/transaction-check/data/HttpTransactionCheckDataSource.test.js.map +3 -3
  140. package/lib/cjs/src/transaction-check/data/HttpTypedDataCheckDataSource.js +1 -1
  141. package/lib/cjs/src/transaction-check/data/HttpTypedDataCheckDataSource.js.map +3 -3
  142. package/lib/cjs/src/transaction-check/data/HttpTypedDataCheckDataSource.test.js +1 -1
  143. package/lib/cjs/src/transaction-check/data/HttpTypedDataCheckDataSource.test.js.map +3 -3
  144. package/lib/cjs/src/trusted-name/data/HttpTrustedNameDataSource.js +1 -1
  145. package/lib/cjs/src/trusted-name/data/HttpTrustedNameDataSource.js.map +3 -3
  146. package/lib/cjs/src/trusted-name/data/HttpTrustedNameDataSource.test.js +1 -1
  147. package/lib/cjs/src/trusted-name/data/HttpTrustedNameDataSource.test.js.map +3 -3
  148. package/lib/cjs/src/trusted-name/di/trustedNameModuleFactory.js +1 -1
  149. package/lib/cjs/src/trusted-name/di/trustedNameModuleFactory.js.map +3 -3
  150. package/lib/cjs/src/typed-data/data/HttpTypedDataDataSource.js +1 -1
  151. package/lib/cjs/src/typed-data/data/HttpTypedDataDataSource.js.map +3 -3
  152. package/lib/cjs/src/typed-data/data/HttpTypedDataDataSource.test.js +1 -1
  153. package/lib/cjs/src/typed-data/data/HttpTypedDataDataSource.test.js.map +3 -3
  154. package/lib/esm/package.json +1 -2
  155. package/lib/esm/src/ContextModuleBuilder.js +1 -1
  156. package/lib/esm/src/ContextModuleBuilder.js.map +3 -3
  157. package/lib/esm/src/ContextModuleBuilder.test.js +1 -1
  158. package/lib/esm/src/ContextModuleBuilder.test.js.map +3 -3
  159. package/lib/esm/src/DefaultContextModule.js +1 -1
  160. package/lib/esm/src/DefaultContextModule.js.map +3 -3
  161. package/lib/esm/src/DefaultContextModule.test.js +1 -1
  162. package/lib/esm/src/DefaultContextModule.test.js.map +2 -2
  163. package/lib/esm/src/account-ownership/data/AccountOwnershipDataSource.js +1 -0
  164. package/lib/esm/src/account-ownership/data/AccountOwnershipDataSource.js.map +7 -0
  165. package/lib/esm/src/account-ownership/data/AccountOwnershipError.js +2 -0
  166. package/lib/esm/src/account-ownership/data/AccountOwnershipError.js.map +7 -0
  167. package/lib/esm/src/account-ownership/data/HttpAccountOwnershipDataSource.js +2 -0
  168. package/lib/esm/src/account-ownership/data/HttpAccountOwnershipDataSource.js.map +7 -0
  169. package/lib/esm/src/account-ownership/data/HttpAccountOwnershipDataSource.test.js +2 -0
  170. package/lib/esm/src/account-ownership/data/HttpAccountOwnershipDataSource.test.js.map +7 -0
  171. package/lib/esm/src/account-ownership/data/dto/AccountOwnershipDto.js +1 -0
  172. package/lib/esm/src/account-ownership/data/dto/AccountOwnershipDto.js.map +7 -0
  173. package/lib/esm/src/account-ownership/di/accountOwnershipModuleFactory.js +2 -0
  174. package/lib/esm/src/account-ownership/di/accountOwnershipModuleFactory.js.map +7 -0
  175. package/lib/esm/src/account-ownership/di/accountOwnershipTypes.js +2 -0
  176. package/lib/esm/src/account-ownership/di/accountOwnershipTypes.js.map +7 -0
  177. package/lib/esm/src/account-ownership/domain/AccountOwnershipContextLoader.js +2 -0
  178. package/lib/esm/src/account-ownership/domain/AccountOwnershipContextLoader.js.map +7 -0
  179. package/lib/esm/src/account-ownership/domain/AccountOwnershipContextLoader.test.js +2 -0
  180. package/lib/esm/src/account-ownership/domain/AccountOwnershipContextLoader.test.js.map +7 -0
  181. package/lib/esm/src/calldata/data/HttpCalldataDescriptorDataSource.js +1 -1
  182. package/lib/esm/src/calldata/data/HttpCalldataDescriptorDataSource.js.map +3 -3
  183. package/lib/esm/src/calldata/data/HttpCalldataDescriptorDataSource.test.js +1 -1
  184. package/lib/esm/src/calldata/data/HttpCalldataDescriptorDataSource.test.js.map +3 -3
  185. package/lib/esm/src/calldata/di/calldataModuleFactory.js +1 -1
  186. package/lib/esm/src/calldata/di/calldataModuleFactory.js.map +3 -3
  187. package/lib/esm/src/config/di/configModuleFactory.js +1 -1
  188. package/lib/esm/src/config/di/configModuleFactory.js.map +2 -2
  189. package/lib/esm/src/di.js +1 -1
  190. package/lib/esm/src/di.js.map +3 -3
  191. package/lib/esm/src/dynamic-network/data/HttpDynamicNetworkDataSource.js +1 -1
  192. package/lib/esm/src/dynamic-network/data/HttpDynamicNetworkDataSource.js.map +3 -3
  193. package/lib/esm/src/dynamic-network/data/HttpDynamicNetworkDataSource.test.js +1 -1
  194. package/lib/esm/src/dynamic-network/data/HttpDynamicNetworkDataSource.test.js.map +3 -3
  195. package/lib/esm/src/dynamic-network/domain/DynamicNetworkContextLoader.js +1 -1
  196. package/lib/esm/src/dynamic-network/domain/DynamicNetworkContextLoader.js.map +1 -1
  197. package/lib/esm/src/dynamic-network/domain/DynamicNetworkContextLoader.test.js.map +1 -1
  198. package/lib/esm/src/external-plugin/data/HttpExternalPluginDataSource.js +1 -1
  199. package/lib/esm/src/external-plugin/data/HttpExternalPluginDataSource.js.map +3 -3
  200. package/lib/esm/src/external-plugin/data/HttpExternalPluginDataSource.test.js +1 -1
  201. package/lib/esm/src/external-plugin/data/HttpExternalPluginDataSource.test.js.map +3 -3
  202. package/lib/esm/src/gated-signing/data/HttpGatedDescriptorDataSource.js +1 -1
  203. package/lib/esm/src/gated-signing/data/HttpGatedDescriptorDataSource.js.map +3 -3
  204. package/lib/esm/src/gated-signing/data/HttpGatedDescriptorDataSource.test.js +1 -1
  205. package/lib/esm/src/gated-signing/data/HttpGatedDescriptorDataSource.test.js.map +3 -3
  206. package/lib/esm/src/index.js +1 -1
  207. package/lib/esm/src/index.js.map +2 -2
  208. package/lib/esm/src/network/di/networkModuleFactory.js +2 -0
  209. package/lib/esm/src/network/di/networkModuleFactory.js.map +7 -0
  210. package/lib/esm/src/network/di/networkTypes.js +2 -0
  211. package/lib/esm/src/network/di/networkTypes.js.map +7 -0
  212. package/lib/esm/src/nft/data/HttpNftDataSource.js +1 -1
  213. package/lib/esm/src/nft/data/HttpNftDataSource.js.map +3 -3
  214. package/lib/esm/src/nft/data/HttpNftDataSource.test.js +1 -1
  215. package/lib/esm/src/nft/data/HttpNftDataSource.test.js.map +3 -3
  216. package/lib/esm/src/pki/data/HttpPkiCertificateDataSource.js +1 -1
  217. package/lib/esm/src/pki/data/HttpPkiCertificateDataSource.js.map +3 -3
  218. package/lib/esm/src/pki/data/HttpPkiCertificateDataSource.test.js +1 -1
  219. package/lib/esm/src/pki/data/HttpPkiCertificateDataSource.test.js.map +3 -3
  220. package/lib/esm/src/proxy/data/HttpProxyDataSource.js +1 -1
  221. package/lib/esm/src/proxy/data/HttpProxyDataSource.js.map +3 -3
  222. package/lib/esm/src/proxy/data/HttpProxyDataSource.test.js +1 -1
  223. package/lib/esm/src/proxy/data/HttpProxyDataSource.test.js.map +3 -3
  224. package/lib/esm/src/proxy/data/HttpSafeProxyDataSource.js +1 -1
  225. package/lib/esm/src/proxy/data/HttpSafeProxyDataSource.js.map +3 -3
  226. package/lib/esm/src/proxy/data/HttpSafeProxyDataSource.test.js +1 -1
  227. package/lib/esm/src/proxy/data/HttpSafeProxyDataSource.test.js.map +3 -3
  228. package/lib/esm/src/proxy/di/proxyModuleFactory.js +1 -1
  229. package/lib/esm/src/proxy/di/proxyModuleFactory.js.map +3 -3
  230. package/lib/esm/src/proxy/di/proxyModuleFactory.test.js +1 -1
  231. package/lib/esm/src/proxy/di/proxyModuleFactory.test.js.map +3 -3
  232. package/lib/esm/src/reporter/data/BlindSigningReporterDatasource.js +1 -0
  233. package/lib/esm/src/reporter/data/BlindSigningReporterDatasource.js.map +7 -0
  234. package/lib/esm/src/reporter/data/HttpBlindSigningReporterDatasource.js +2 -0
  235. package/lib/esm/src/reporter/data/HttpBlindSigningReporterDatasource.js.map +7 -0
  236. package/lib/esm/src/reporter/data/HttpBlindSigningReporterDatasource.test.js +2 -0
  237. package/lib/esm/src/reporter/data/HttpBlindSigningReporterDatasource.test.js.map +7 -0
  238. package/lib/esm/src/reporter/data/dto/BlindSigningEventDto.js +1 -0
  239. package/lib/esm/src/reporter/data/dto/BlindSigningEventDto.js.map +7 -0
  240. package/lib/esm/src/reporter/di/reporterModuleFactory.js +2 -0
  241. package/lib/esm/src/reporter/di/reporterModuleFactory.js.map +7 -0
  242. package/lib/esm/src/reporter/di/reporterTypes.js +2 -0
  243. package/lib/esm/src/reporter/di/reporterTypes.js.map +7 -0
  244. package/lib/esm/src/reporter/domain/BlindSigningReporter.js +1 -0
  245. package/lib/esm/src/reporter/domain/BlindSigningReporter.js.map +7 -0
  246. package/lib/esm/src/reporter/domain/DefaultBlindSigningReporter.js +2 -0
  247. package/lib/esm/src/reporter/domain/DefaultBlindSigningReporter.js.map +7 -0
  248. package/lib/esm/src/reporter/domain/DefaultBlindSigningReporter.test.js +2 -0
  249. package/lib/esm/src/reporter/domain/DefaultBlindSigningReporter.test.js.map +7 -0
  250. package/lib/esm/src/reporter/model/BlindSigningEvent.js +2 -0
  251. package/lib/esm/src/reporter/model/BlindSigningEvent.js.map +7 -0
  252. package/lib/esm/src/reporter/model/BlindSigningModelId.js +2 -0
  253. package/lib/esm/src/reporter/model/BlindSigningModelId.js.map +7 -0
  254. package/lib/esm/src/safe/data/HttpSafeAccountDataSource.js +1 -1
  255. package/lib/esm/src/safe/data/HttpSafeAccountDataSource.js.map +3 -3
  256. package/lib/esm/src/safe/data/HttpSafeAccountDataSource.test.js +1 -1
  257. package/lib/esm/src/safe/data/HttpSafeAccountDataSource.test.js.map +3 -3
  258. package/lib/esm/src/shared/model/ClearSignContext.js +1 -1
  259. package/lib/esm/src/shared/model/ClearSignContext.js.map +2 -2
  260. package/lib/esm/src/solana/data/HttpSolanaOwnerInfoDataSource.js +1 -1
  261. package/lib/esm/src/solana/data/HttpSolanaOwnerInfoDataSource.js.map +3 -3
  262. package/lib/esm/src/solana/data/HttpSolanaOwnerInfoDataSource.test.js +1 -1
  263. package/lib/esm/src/solana/data/HttpSolanaOwnerInfoDataSource.test.js.map +3 -3
  264. package/lib/esm/src/solana/domain/DefaultSolanaContextLoader.test.js +1 -1
  265. package/lib/esm/src/solana/domain/DefaultSolanaContextLoader.test.js.map +1 -1
  266. package/lib/esm/src/solanaLifi/data/HttpSolanaLifiDataSource.js +1 -1
  267. package/lib/esm/src/solanaLifi/data/HttpSolanaLifiDataSource.js.map +3 -3
  268. package/lib/esm/src/solanaLifi/data/HttpSolanaLifiDataSource.test.js +1 -1
  269. package/lib/esm/src/solanaLifi/data/HttpSolanaLifiDataSource.test.js.map +3 -3
  270. package/lib/esm/src/solanaLifi/domain/SolanaLifiContextLoader.js.map +1 -1
  271. package/lib/esm/src/solanaLifi/domain/SolanaLifiContextLoader.test.js +1 -1
  272. package/lib/esm/src/solanaLifi/domain/SolanaLifiContextLoader.test.js.map +1 -1
  273. package/lib/esm/src/solanaToken/data/HttpSolanaTokenDataSource.js +1 -1
  274. package/lib/esm/src/solanaToken/data/HttpSolanaTokenDataSource.js.map +3 -3
  275. package/lib/esm/src/solanaToken/data/HttpSolanaTokenDataSource.test.js +6 -6
  276. package/lib/esm/src/solanaToken/data/HttpSolanaTokenDataSource.test.js.map +3 -3
  277. package/lib/esm/src/solanaToken/domain/SolanaTokenContextLoader.js +1 -1
  278. package/lib/esm/src/solanaToken/domain/SolanaTokenContextLoader.js.map +2 -2
  279. package/lib/esm/src/solanaToken/domain/SolanaTokenContextLoader.test.js +1 -1
  280. package/lib/esm/src/solanaToken/domain/SolanaTokenContextLoader.test.js.map +1 -1
  281. package/lib/esm/src/token/data/HttpTokenDataSource.js +1 -1
  282. package/lib/esm/src/token/data/HttpTokenDataSource.js.map +3 -3
  283. package/lib/esm/src/token/data/HttpTokenDataSource.test.js +1 -1
  284. package/lib/esm/src/token/data/HttpTokenDataSource.test.js.map +3 -3
  285. package/lib/esm/src/transaction-check/data/HttpTransactionCheckDataSource.js +1 -1
  286. package/lib/esm/src/transaction-check/data/HttpTransactionCheckDataSource.js.map +3 -3
  287. package/lib/esm/src/transaction-check/data/HttpTransactionCheckDataSource.test.js +1 -1
  288. package/lib/esm/src/transaction-check/data/HttpTransactionCheckDataSource.test.js.map +3 -3
  289. package/lib/esm/src/transaction-check/data/HttpTypedDataCheckDataSource.js +1 -1
  290. package/lib/esm/src/transaction-check/data/HttpTypedDataCheckDataSource.js.map +3 -3
  291. package/lib/esm/src/transaction-check/data/HttpTypedDataCheckDataSource.test.js +1 -1
  292. package/lib/esm/src/transaction-check/data/HttpTypedDataCheckDataSource.test.js.map +3 -3
  293. package/lib/esm/src/trusted-name/data/HttpTrustedNameDataSource.js +1 -1
  294. package/lib/esm/src/trusted-name/data/HttpTrustedNameDataSource.js.map +3 -3
  295. package/lib/esm/src/trusted-name/data/HttpTrustedNameDataSource.test.js +1 -1
  296. package/lib/esm/src/trusted-name/data/HttpTrustedNameDataSource.test.js.map +3 -3
  297. package/lib/esm/src/trusted-name/di/trustedNameModuleFactory.js +1 -1
  298. package/lib/esm/src/trusted-name/di/trustedNameModuleFactory.js.map +3 -3
  299. package/lib/esm/src/typed-data/data/HttpTypedDataDataSource.js +1 -1
  300. package/lib/esm/src/typed-data/data/HttpTypedDataDataSource.js.map +3 -3
  301. package/lib/esm/src/typed-data/data/HttpTypedDataDataSource.test.js +1 -1
  302. package/lib/esm/src/typed-data/data/HttpTypedDataDataSource.test.js.map +3 -3
  303. package/lib/types/src/ContextModule.d.ts +2 -0
  304. package/lib/types/src/ContextModule.d.ts.map +1 -1
  305. package/lib/types/src/ContextModuleBuilder.d.ts +30 -3
  306. package/lib/types/src/ContextModuleBuilder.d.ts.map +1 -1
  307. package/lib/types/src/DefaultContextModule.d.ts +6 -2
  308. package/lib/types/src/DefaultContextModule.d.ts.map +1 -1
  309. package/lib/types/src/account-ownership/data/AccountOwnershipDataSource.d.ts +17 -0
  310. package/lib/types/src/account-ownership/data/AccountOwnershipDataSource.d.ts.map +1 -0
  311. package/lib/types/src/account-ownership/data/AccountOwnershipError.d.ts +17 -0
  312. package/lib/types/src/account-ownership/data/AccountOwnershipError.d.ts.map +1 -0
  313. package/lib/types/src/account-ownership/data/HttpAccountOwnershipDataSource.d.ts +30 -0
  314. package/lib/types/src/account-ownership/data/HttpAccountOwnershipDataSource.d.ts.map +1 -0
  315. package/lib/types/src/account-ownership/data/HttpAccountOwnershipDataSource.test.d.ts +2 -0
  316. package/lib/types/src/account-ownership/data/HttpAccountOwnershipDataSource.test.d.ts.map +1 -0
  317. package/lib/types/src/account-ownership/data/dto/AccountOwnershipDto.d.ts +6 -0
  318. package/lib/types/src/account-ownership/data/dto/AccountOwnershipDto.d.ts.map +1 -0
  319. package/lib/types/src/account-ownership/di/accountOwnershipModuleFactory.d.ts +3 -0
  320. package/lib/types/src/account-ownership/di/accountOwnershipModuleFactory.d.ts.map +1 -0
  321. package/lib/types/src/account-ownership/di/accountOwnershipTypes.d.ts +5 -0
  322. package/lib/types/src/account-ownership/di/accountOwnershipTypes.d.ts.map +1 -0
  323. package/lib/types/src/account-ownership/domain/AccountOwnershipContextLoader.d.ts +20 -0
  324. package/lib/types/src/account-ownership/domain/AccountOwnershipContextLoader.d.ts.map +1 -0
  325. package/lib/types/src/account-ownership/domain/AccountOwnershipContextLoader.test.d.ts +2 -0
  326. package/lib/types/src/account-ownership/domain/AccountOwnershipContextLoader.test.d.ts.map +1 -0
  327. package/lib/types/src/calldata/data/HttpCalldataDescriptorDataSource.d.ts +4 -2
  328. package/lib/types/src/calldata/data/HttpCalldataDescriptorDataSource.d.ts.map +1 -1
  329. package/lib/types/src/calldata/di/calldataModuleFactory.d.ts.map +1 -1
  330. package/lib/types/src/config/di/configModuleFactory.d.ts +2 -2
  331. package/lib/types/src/config/di/configModuleFactory.d.ts.map +1 -1
  332. package/lib/types/src/config/model/ContextModuleConfig.d.ts +14 -3
  333. package/lib/types/src/config/model/ContextModuleConfig.d.ts.map +1 -1
  334. package/lib/types/src/di.d.ts +2 -2
  335. package/lib/types/src/di.d.ts.map +1 -1
  336. package/lib/types/src/dynamic-network/data/HttpDynamicNetworkDataSource.d.ts +4 -2
  337. package/lib/types/src/dynamic-network/data/HttpDynamicNetworkDataSource.d.ts.map +1 -1
  338. package/lib/types/src/dynamic-network/domain/DynamicNetworkContextLoader.d.ts +2 -2
  339. package/lib/types/src/dynamic-network/domain/DynamicNetworkContextLoader.d.ts.map +1 -1
  340. package/lib/types/src/external-plugin/data/HttpExternalPluginDataSource.d.ts +4 -2
  341. package/lib/types/src/external-plugin/data/HttpExternalPluginDataSource.d.ts.map +1 -1
  342. package/lib/types/src/gated-signing/data/HttpGatedDescriptorDataSource.d.ts +4 -2
  343. package/lib/types/src/gated-signing/data/HttpGatedDescriptorDataSource.d.ts.map +1 -1
  344. package/lib/types/src/index.d.ts +11 -1
  345. package/lib/types/src/index.d.ts.map +1 -1
  346. package/lib/types/src/network/di/networkModuleFactory.d.ts +4 -0
  347. package/lib/types/src/network/di/networkModuleFactory.d.ts.map +1 -0
  348. package/lib/types/src/network/di/networkTypes.d.ts +4 -0
  349. package/lib/types/src/network/di/networkTypes.d.ts.map +1 -0
  350. package/lib/types/src/nft/data/HttpNftDataSource.d.ts +4 -2
  351. package/lib/types/src/nft/data/HttpNftDataSource.d.ts.map +1 -1
  352. package/lib/types/src/pki/data/HttpPkiCertificateDataSource.d.ts +5 -2
  353. package/lib/types/src/pki/data/HttpPkiCertificateDataSource.d.ts.map +1 -1
  354. package/lib/types/src/proxy/data/HttpProxyDataSource.d.ts +4 -2
  355. package/lib/types/src/proxy/data/HttpProxyDataSource.d.ts.map +1 -1
  356. package/lib/types/src/proxy/data/HttpSafeProxyDataSource.d.ts +4 -2
  357. package/lib/types/src/proxy/data/HttpSafeProxyDataSource.d.ts.map +1 -1
  358. package/lib/types/src/proxy/di/proxyModuleFactory.d.ts +2 -2
  359. package/lib/types/src/proxy/di/proxyModuleFactory.d.ts.map +1 -1
  360. package/lib/types/src/reporter/data/BlindSigningReporterDatasource.d.ts +29 -0
  361. package/lib/types/src/reporter/data/BlindSigningReporterDatasource.d.ts.map +1 -0
  362. package/lib/types/src/reporter/data/HttpBlindSigningReporterDatasource.d.ts +11 -0
  363. package/lib/types/src/reporter/data/HttpBlindSigningReporterDatasource.d.ts.map +1 -0
  364. package/lib/types/src/reporter/data/HttpBlindSigningReporterDatasource.test.d.ts +2 -0
  365. package/lib/types/src/reporter/data/HttpBlindSigningReporterDatasource.test.d.ts.map +1 -0
  366. package/lib/types/src/reporter/data/dto/BlindSigningEventDto.d.ts +26 -0
  367. package/lib/types/src/reporter/data/dto/BlindSigningEventDto.d.ts.map +1 -0
  368. package/lib/types/src/reporter/di/reporterModuleFactory.d.ts +3 -0
  369. package/lib/types/src/reporter/di/reporterModuleFactory.d.ts.map +1 -0
  370. package/lib/types/src/reporter/di/reporterTypes.d.ts +5 -0
  371. package/lib/types/src/reporter/di/reporterTypes.d.ts.map +1 -0
  372. package/lib/types/src/reporter/domain/BlindSigningReporter.d.ts +6 -0
  373. package/lib/types/src/reporter/domain/BlindSigningReporter.d.ts.map +1 -0
  374. package/lib/types/src/reporter/domain/DefaultBlindSigningReporter.d.ts +9 -0
  375. package/lib/types/src/reporter/domain/DefaultBlindSigningReporter.d.ts.map +1 -0
  376. package/lib/types/src/reporter/domain/DefaultBlindSigningReporter.test.d.ts +2 -0
  377. package/lib/types/src/reporter/domain/DefaultBlindSigningReporter.test.d.ts.map +1 -0
  378. package/lib/types/src/reporter/model/BlindSigningEvent.d.ts +21 -0
  379. package/lib/types/src/reporter/model/BlindSigningEvent.d.ts.map +1 -0
  380. package/lib/types/src/reporter/model/BlindSigningModelId.d.ts +12 -0
  381. package/lib/types/src/reporter/model/BlindSigningModelId.d.ts.map +1 -0
  382. package/lib/types/src/safe/data/HttpSafeAccountDataSource.d.ts +4 -2
  383. package/lib/types/src/safe/data/HttpSafeAccountDataSource.d.ts.map +1 -1
  384. package/lib/types/src/shared/model/ClearSignContext.d.ts +2 -1
  385. package/lib/types/src/shared/model/ClearSignContext.d.ts.map +1 -1
  386. package/lib/types/src/solana/data/HttpSolanaOwnerInfoDataSource.d.ts +4 -2
  387. package/lib/types/src/solana/data/HttpSolanaOwnerInfoDataSource.d.ts.map +1 -1
  388. package/lib/types/src/solanaLifi/data/HttpSolanaLifiDataSource.d.ts +4 -3
  389. package/lib/types/src/solanaLifi/data/HttpSolanaLifiDataSource.d.ts.map +1 -1
  390. package/lib/types/src/solanaLifi/domain/SolanaLifiContextLoader.d.ts +2 -2
  391. package/lib/types/src/solanaLifi/domain/SolanaLifiContextLoader.d.ts.map +1 -1
  392. package/lib/types/src/solanaToken/data/HttpSolanaTokenDataSource.d.ts +4 -2
  393. package/lib/types/src/solanaToken/data/HttpSolanaTokenDataSource.d.ts.map +1 -1
  394. package/lib/types/src/solanaToken/domain/SolanaTokenContextLoader.d.ts +2 -2
  395. package/lib/types/src/solanaToken/domain/SolanaTokenContextLoader.d.ts.map +1 -1
  396. package/lib/types/src/token/data/HttpTokenDataSource.d.ts +4 -2
  397. package/lib/types/src/token/data/HttpTokenDataSource.d.ts.map +1 -1
  398. package/lib/types/src/transaction-check/data/HttpTransactionCheckDataSource.d.ts +4 -2
  399. package/lib/types/src/transaction-check/data/HttpTransactionCheckDataSource.d.ts.map +1 -1
  400. package/lib/types/src/transaction-check/data/HttpTypedDataCheckDataSource.d.ts +4 -2
  401. package/lib/types/src/transaction-check/data/HttpTypedDataCheckDataSource.d.ts.map +1 -1
  402. package/lib/types/src/trusted-name/data/HttpTrustedNameDataSource.d.ts +4 -2
  403. package/lib/types/src/trusted-name/data/HttpTrustedNameDataSource.d.ts.map +1 -1
  404. package/lib/types/src/trusted-name/di/trustedNameModuleFactory.d.ts +2 -2
  405. package/lib/types/src/trusted-name/di/trustedNameModuleFactory.d.ts.map +1 -1
  406. package/lib/types/src/typed-data/data/HttpTypedDataDataSource.d.ts +4 -2
  407. package/lib/types/src/typed-data/data/HttpTypedDataDataSource.d.ts.map +1 -1
  408. package/lib/types/src/typed-data/data/HttpTypedDataDataSource.test.d.ts.map +1 -1
  409. package/lib/types/tsconfig.prod.tsbuildinfo +1 -1
  410. package/package.json +6 -7
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "version": 3,
3
3
  "sources": ["../../../../../src/solana/data/HttpSolanaOwnerInfoDataSource.test.ts"],
4
- "sourcesContent": ["/* eslint-disable @typescript-eslint/no-explicit-any */\nimport {\n DeviceModelId,\n hexaStringToBuffer,\n} from \"@ledgerhq/device-management-kit\";\nimport axios from \"axios\";\nimport { Left } from \"purify-ts\";\n\nimport type { ContextModuleConfig } from \"@/config/model/ContextModuleConfig\";\nimport { LEDGER_CLIENT_VERSION_HEADER } from \"@/shared/constant/HttpHeaders\";\nimport { HttpSolanaOwnerInfoDataSource } from \"@/solana/data/HttpSolanaOwnerInfoDataSource\";\nimport type { SolanaTransactionContext } from \"@/solana/domain/solanaContextTypes\";\nimport PACKAGE from \"@root/package.json\";\n\nvi.mock(\"axios\");\n\nfunction stringToHex(str: string): string {\n const encoder = new TextEncoder();\n const bytes = encoder.encode(str); // Uint8Array\n return Array.from(bytes)\n .map((byte) => byte.toString(16).padStart(2, \"0\"))\n .join(\"\");\n}\n\ndescribe(\"HttpSolanaOwnerInfoDataSource\", () => {\n const config = {\n metadataServiceDomain: { url: \"https://some.doma.in\" },\n originToken: \"mock-origin-token\",\n } as ContextModuleConfig;\n\n const signedDescriptorHex = stringToHex(\"mock-descriptor\");\n const responseData = {\n tokenAccount: \"token-account\",\n owner: \"owner-address\",\n contract: \"contract-address\",\n signedDescriptor: signedDescriptorHex,\n };\n\n beforeEach(() => {\n vi.resetAllMocks();\n });\n\n it(\"should fetch address metadata via tokenAddress\", async () => {\n const context: SolanaTransactionContext = {\n deviceModelId: DeviceModelId.FLEX,\n tokenAddress: \"some-token\",\n challenge: \"random\",\n createATA: undefined,\n };\n vi.spyOn(axios, \"request\").mockResolvedValueOnce({ data: responseData });\n\n const dataSource = new HttpSolanaOwnerInfoDataSource(config);\n const result = await dataSource.getOwnerInfo(context);\n\n expect(result.isRight()).toBe(true);\n expect(result.extract()).toEqual({\n tlvDescriptor: hexaStringToBuffer(signedDescriptorHex),\n });\n });\n\n it(\"should return an error if both tokenAddress and createATA are missing or invalid\", async () => {\n const context: SolanaTransactionContext = {\n deviceModelId: DeviceModelId.FLEX,\n tokenAddress: undefined,\n challenge: \"random\",\n createATA: undefined,\n };\n\n const dataSource = new HttpSolanaOwnerInfoDataSource(config);\n const result = await dataSource.getOwnerInfo(context);\n\n expect(result).toEqual(\n Left(\n new Error(\n \"[ContextModule] - HttpSolanaOwnerInfoDataSource: either tokenAddress or valid createATA must be provided\",\n ),\n ),\n );\n });\n\n it(\"should return an error if challenge is missing\", async () => {\n const context: SolanaTransactionContext = {\n deviceModelId: DeviceModelId.FLEX,\n tokenAddress: \"some-token\",\n challenge: undefined,\n createATA: undefined,\n };\n\n const dataSource = new HttpSolanaOwnerInfoDataSource(config);\n const result = await dataSource.getOwnerInfo(context);\n\n expect(result).toEqual(\n Left(\n new Error(\n \"[ContextModule] - HttpSolanaOwnerInfoDataSource: challenge is required\",\n ),\n ),\n );\n });\n\n it(\"should return an error if the descriptor is not valid base64\", async () => {\n vi.spyOn(axios, \"request\").mockResolvedValueOnce({\n data: { ...responseData, signedDescriptor: \"!!!not-valid-base64!!!\" },\n });\n const context: SolanaTransactionContext = {\n deviceModelId: DeviceModelId.FLEX,\n tokenAddress: \"some-token\",\n challenge: \"random\",\n createATA: undefined,\n };\n\n const dataSource = new HttpSolanaOwnerInfoDataSource(config);\n const result = await dataSource.getOwnerInfo(context);\n\n expect(result).toEqual(\n Left(\n new Error(\n \"[ContextModule] - HttpSolanaOwnerInfoDataSource: invalid base64 tlvDescriptor received\",\n ),\n ),\n );\n });\n\n it(\"should return an error if the metadata request fails\", async () => {\n vi.spyOn(axios, \"request\").mockRejectedValueOnce(\n new Error(\"Network error\"),\n );\n const context: SolanaTransactionContext = {\n deviceModelId: DeviceModelId.FLEX,\n tokenAddress: \"some-token\",\n challenge: \"random\",\n createATA: undefined,\n };\n\n const dataSource = new HttpSolanaOwnerInfoDataSource(config);\n const result = await dataSource.getOwnerInfo(context);\n\n expect(result).toEqual(\n Left(\n new Error(\n \"[ContextModule] - HttpSolanaOwnerInfoDataSource: Failed to fetch address metadata\",\n ),\n ),\n );\n });\n\n it(\"should return an error if axios request return wrong shape for fetchAddressMetadata\", async () => {\n vi.spyOn(axios, \"request\").mockResolvedValueOnce({\n data: { wrong: \"field\" },\n });\n\n const context: SolanaTransactionContext = {\n deviceModelId: DeviceModelId.FLEX,\n tokenAddress: \"some-token\",\n challenge: \"random\",\n createATA: undefined,\n };\n\n const dataSource = new HttpSolanaOwnerInfoDataSource(config);\n const result = await dataSource.getOwnerInfo(context);\n\n expect(result).toEqual(\n Left(\n new Error(\n \"[ContextModule] - HttpSolanaOwnerInfoDataSource: invalid fetchAddressMetadata response shape\",\n ),\n ),\n );\n });\n\n it(\"should return an error if axios request return wrong shape for computeAddressMetadata\", async () => {\n vi.spyOn(axios, \"request\").mockResolvedValueOnce({\n data: { wrong: \"field\" },\n });\n\n const context: SolanaTransactionContext = {\n deviceModelId: DeviceModelId.FLEX,\n tokenAddress: undefined,\n challenge: \"random\",\n createATA: {\n address: \"some-address\",\n mintAddress: \"some-mint\",\n },\n };\n\n const dataSource = new HttpSolanaOwnerInfoDataSource(config);\n const result = await dataSource.getOwnerInfo(context);\n\n expect(result).toEqual(\n Left(\n new Error(\n \"[ContextModule] - HttpSolanaOwnerInfoDataSource: invalid computeAddressMetadata response shape\",\n ),\n ),\n );\n });\n\n it(\"should throw if originToken is missing\", () => {\n expect(() => {\n new HttpSolanaOwnerInfoDataSource({\n ...config,\n originToken: undefined,\n } as any);\n }).toThrow(\n \"[ContextModule] - HttpSolanaOwnerInfoDataSource: origin token is required\",\n );\n });\n\n it(\"should call axios with correct headers\", async () => {\n const context: SolanaTransactionContext = {\n deviceModelId: DeviceModelId.FLEX,\n tokenAddress: \"some-token\",\n challenge: \"random\",\n createATA: undefined,\n };\n const spy = vi\n .spyOn(axios, \"request\")\n .mockResolvedValueOnce({ data: responseData });\n\n const dataSource = new HttpSolanaOwnerInfoDataSource(config);\n await dataSource.getOwnerInfo(context);\n\n expect(spy).toHaveBeenCalledWith(\n expect.objectContaining({\n headers: {\n [LEDGER_CLIENT_VERSION_HEADER]: `context-module/${PACKAGE.version}`,\n \"X-Ledger-Client-Origin\": config.originToken,\n },\n }),\n );\n });\n});\n"],
5
- "mappings": "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",
6
- "names": ["DeviceModelId", "hexaStringToBuffer", "axios", "Left", "LEDGER_CLIENT_VERSION_HEADER", "HttpSolanaOwnerInfoDataSource", "PACKAGE", "stringToHex", "str", "bytes", "byte", "config", "signedDescriptorHex", "responseData", "context", "result", "spy"]
4
+ "sourcesContent": ["/* eslint-disable @typescript-eslint/no-explicit-any */\nimport {\n DeviceModelId,\n type DmkNetworkClient,\n hexaStringToBuffer,\n} from \"@ledgerhq/device-management-kit\";\nimport { Left } from \"purify-ts\";\n\nimport type { ContextModuleServiceConfig } from \"@/config/model/ContextModuleConfig\";\nimport { HttpSolanaOwnerInfoDataSource } from \"@/solana/data/HttpSolanaOwnerInfoDataSource\";\nimport type { SolanaTransactionContext } from \"@/solana/domain/solanaContextTypes\";\n\nfunction stringToHex(str: string): string {\n const encoder = new TextEncoder();\n const bytes = encoder.encode(str); // Uint8Array\n return Array.from(bytes)\n .map((byte) => byte.toString(16).padStart(2, \"0\"))\n .join(\"\");\n}\n\ndescribe(\"HttpSolanaOwnerInfoDataSource\", () => {\n const config = {\n metadataServiceDomain: { url: \"https://some.doma.in\" },\n originToken: \"mock-origin-token\",\n } as ContextModuleServiceConfig;\n\n const signedDescriptorHex = stringToHex(\"mock-descriptor\");\n const responseData = {\n tokenAccount: \"token-account\",\n owner: \"owner-address\",\n contract: \"contract-address\",\n signedDescriptor: signedDescriptorHex,\n };\n\n let httpMock: { get: ReturnType<typeof vi.fn> };\n\n beforeEach(() => {\n vi.resetAllMocks();\n httpMock = { get: vi.fn() };\n });\n\n it(\"should fetch address metadata via tokenAddress\", async () => {\n const context: SolanaTransactionContext = {\n deviceModelId: DeviceModelId.FLEX,\n tokenAddress: \"some-token\",\n challenge: \"random\",\n createATA: undefined,\n };\n httpMock.get.mockResolvedValueOnce(responseData);\n\n const dataSource = new HttpSolanaOwnerInfoDataSource(\n config,\n httpMock as unknown as DmkNetworkClient,\n );\n const result = await dataSource.getOwnerInfo(context);\n\n expect(httpMock.get).toHaveBeenCalledWith(\n `${config.metadataServiceDomain.url}/v2/solana/owner/some-token`,\n { params: { challenge: \"random\" } },\n );\n expect(result.isRight()).toBe(true);\n expect(result.extract()).toEqual({\n tlvDescriptor: hexaStringToBuffer(signedDescriptorHex),\n });\n });\n\n it(\"should return an error if both tokenAddress and createATA are missing or invalid\", async () => {\n const context: SolanaTransactionContext = {\n deviceModelId: DeviceModelId.FLEX,\n tokenAddress: undefined,\n challenge: \"random\",\n createATA: undefined,\n };\n\n const dataSource = new HttpSolanaOwnerInfoDataSource(\n config,\n httpMock as unknown as DmkNetworkClient,\n );\n const result = await dataSource.getOwnerInfo(context);\n\n expect(result).toEqual(\n Left(\n new Error(\n \"[ContextModule] - HttpSolanaOwnerInfoDataSource: either tokenAddress or valid createATA must be provided\",\n ),\n ),\n );\n });\n\n it(\"should return an error if challenge is missing\", async () => {\n const context: SolanaTransactionContext = {\n deviceModelId: DeviceModelId.FLEX,\n tokenAddress: \"some-token\",\n challenge: undefined,\n createATA: undefined,\n };\n\n const dataSource = new HttpSolanaOwnerInfoDataSource(\n config,\n httpMock as unknown as DmkNetworkClient,\n );\n const result = await dataSource.getOwnerInfo(context);\n\n expect(result).toEqual(\n Left(\n new Error(\n \"[ContextModule] - HttpSolanaOwnerInfoDataSource: challenge is required\",\n ),\n ),\n );\n });\n\n it(\"should return an error if the descriptor is not valid base64\", async () => {\n httpMock.get.mockResolvedValueOnce({\n ...responseData,\n signedDescriptor: \"!!!not-valid-base64!!!\",\n });\n const context: SolanaTransactionContext = {\n deviceModelId: DeviceModelId.FLEX,\n tokenAddress: \"some-token\",\n challenge: \"random\",\n createATA: undefined,\n };\n\n const dataSource = new HttpSolanaOwnerInfoDataSource(\n config,\n httpMock as unknown as DmkNetworkClient,\n );\n const result = await dataSource.getOwnerInfo(context);\n\n expect(result).toEqual(\n Left(\n new Error(\n \"[ContextModule] - HttpSolanaOwnerInfoDataSource: invalid base64 tlvDescriptor received\",\n ),\n ),\n );\n });\n\n it(\"should return an error if the metadata request fails\", async () => {\n httpMock.get.mockRejectedValueOnce(new Error(\"Network error\"));\n const context: SolanaTransactionContext = {\n deviceModelId: DeviceModelId.FLEX,\n tokenAddress: \"some-token\",\n challenge: \"random\",\n createATA: undefined,\n };\n\n const dataSource = new HttpSolanaOwnerInfoDataSource(\n config,\n httpMock as unknown as DmkNetworkClient,\n );\n const result = await dataSource.getOwnerInfo(context);\n\n expect(result).toEqual(\n Left(\n new Error(\n \"[ContextModule] - HttpSolanaOwnerInfoDataSource: Failed to fetch address metadata\",\n ),\n ),\n );\n });\n\n it(\"should return an error if fetch request return wrong shape for fetchAddressMetadata\", async () => {\n httpMock.get.mockResolvedValueOnce({ wrong: \"field\" });\n\n const context: SolanaTransactionContext = {\n deviceModelId: DeviceModelId.FLEX,\n tokenAddress: \"some-token\",\n challenge: \"random\",\n createATA: undefined,\n };\n\n const dataSource = new HttpSolanaOwnerInfoDataSource(\n config,\n httpMock as unknown as DmkNetworkClient,\n );\n const result = await dataSource.getOwnerInfo(context);\n\n expect(result).toEqual(\n Left(\n new Error(\n \"[ContextModule] - HttpSolanaOwnerInfoDataSource: invalid fetchAddressMetadata response shape\",\n ),\n ),\n );\n });\n\n it(\"should return an error if fetch request return wrong shape for computeAddressMetadata\", async () => {\n httpMock.get.mockResolvedValueOnce({ wrong: \"field\" });\n\n const context: SolanaTransactionContext = {\n deviceModelId: DeviceModelId.FLEX,\n tokenAddress: undefined,\n challenge: \"random\",\n createATA: {\n address: \"some-address\",\n mintAddress: \"some-mint\",\n },\n };\n\n const dataSource = new HttpSolanaOwnerInfoDataSource(\n config,\n httpMock as unknown as DmkNetworkClient,\n );\n const result = await dataSource.getOwnerInfo(context);\n\n expect(httpMock.get).toHaveBeenCalledWith(\n `${config.metadataServiceDomain.url}/v2/solana/computed-token-account/some-address/some-mint`,\n { params: { challenge: \"random\" } },\n );\n expect(result).toEqual(\n Left(\n new Error(\n \"[ContextModule] - HttpSolanaOwnerInfoDataSource: invalid computeAddressMetadata response shape\",\n ),\n ),\n );\n });\n\n it(\"should throw if originToken is missing\", () => {\n expect(() => {\n new HttpSolanaOwnerInfoDataSource(\n {\n ...config,\n originToken: undefined,\n } as any,\n httpMock as unknown as DmkNetworkClient,\n );\n }).toThrow(\n \"[ContextModule] - HttpSolanaOwnerInfoDataSource: origin token is required\",\n );\n });\n});\n"],
5
+ "mappings": "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",
6
+ "names": ["DeviceModelId", "hexaStringToBuffer", "Left", "HttpSolanaOwnerInfoDataSource", "stringToHex", "str", "bytes", "byte", "config", "signedDescriptorHex", "responseData", "httpMock", "context", "result"]
7
7
  }
@@ -1,2 +1,2 @@
1
- import{DeviceModelId as y}from"@ledgerhq/device-management-kit";import{Left as m,Right as f}from"purify-ts";import{beforeEach as g,describe as p,expect as t,it as s,vi as a}from"vitest";import{KeyUsage as T}from"../../pki/model/KeyUsage";import{SolanaContextTypes as d}from"../../shared/model/SolanaContextTypes";import{SolanaTokenContextLoader as I}from"../../solanaToken/domain/SolanaTokenContextLoader";const O=()=>({debug:a.fn(),info:a.fn(),warn:a.fn(),error:a.fn(),subscribers:[]});p("SolanaTokenContextLoader",()=>{let l,i;const c=new Uint8Array([240,202,204,26]),n={descriptor:{data:{symbol:"SOL",name:"Solana",decimals:9},signatures:{prod:"prod-sig",test:"test-sig"}}},k={tokenInternalId:"token-1",deviceModelId:y.FLEX};g(()=>{a.restoreAllMocks(),l={getTokenInfosPayload:a.fn()},i={loadCertificate:a.fn()}});const r=e=>{const o={cal:{mode:e}};return new I(l,o,i,O)};p("canHandle",()=>{s("returns true when tokenInternalId is provided",()=>{const e=r("prod");t(e.canHandle({tokenInternalId:"abc123"},d.SOLANA_TOKEN)).toBe(!0)}),s("returns false when tokenInternalId is missing or falsy",()=>{const e=r("prod");t(e.canHandle({tokenInternalId:""},d.SOLANA_TOKEN)).toBe(!1),t(e.canHandle({tokenInternalId:void 0},d.SOLANA_TOKEN)).toBe(!1),t(e.canHandle({},d.SOLANA_TOKEN)).toBe(!1)})}),p("loadField",()=>{s("returns an error when datasource returns Left(error) and still fetched certificate beforehand",async()=>{const e=r("prod"),o=new Error("datasource failed");a.spyOn(l,"getTokenInfosPayload").mockResolvedValue(m(o)),a.spyOn(i,"loadCertificate").mockResolvedValue({keyUsageNumber:0,payload:c});const u=await e.loadField(k);t(l.getTokenInfosPayload).toHaveBeenCalledWith({tokenInternalId:"token-1"}),t(i.loadCertificate).toHaveBeenCalledWith({keyId:"token_metadata_key",keyUsage:T.CoinMeta,targetDevice:k.deviceModelId}),t(u).toEqual({type:d.ERROR,error:o})}),s("returns SOLANA_TOKEN with prod signature by default (falsy mode), and includes certificate",async()=>{const e=r("");a.spyOn(l,"getTokenInfosPayload").mockResolvedValue(f(n)),a.spyOn(i,"loadCertificate").mockResolvedValue({keyUsageNumber:0,payload:c});const o=await e.loadField({...k,tokenInternalId:"token-2"});t(o).toEqual({type:d.SOLANA_TOKEN,payload:{solanaTokenDescriptor:{data:n.descriptor.data,signature:"prod-sig"}},certificate:{keyUsageNumber:0,payload:c}})}),s("returns SOLANA_TOKEN with signature matching config.cal.mode",async()=>{const e=r("test");a.spyOn(l,"getTokenInfosPayload").mockResolvedValue(f(n)),a.spyOn(i,"loadCertificate").mockResolvedValue({keyUsageNumber:1,payload:c});const o=await e.loadField({...k,tokenInternalId:"token-3"});t(o).toEqual({type:d.SOLANA_TOKEN,payload:{solanaTokenDescriptor:{data:n.descriptor.data,signature:"test-sig"}},certificate:{keyUsageNumber:1,payload:c}})}),s("works even if certificate loader returns undefined (certificate omitted)",async()=>{const e=r("prod");a.spyOn(l,"getTokenInfosPayload").mockResolvedValue(f(n)),a.spyOn(i,"loadCertificate").mockResolvedValue(void 0);const o=await e.loadField(k);t(o).toEqual({type:d.SOLANA_TOKEN,payload:{solanaTokenDescriptor:{data:n.descriptor.data,signature:"prod-sig"}},certificate:void 0})})}),p("pluckTokenData (private)",()=>{s("picks the signature for the configured mode",()=>{const e=r("test"),u=e.pluckTokenData.bind(e)(n);t(u).toEqual({solanaTokenDescriptor:{data:n.descriptor.data,signature:"test-sig"}})}),s("falls back to 'prod' when config.cal.mode is falsy",()=>{const o=r(void 0).pluckTokenData(n);t(o).toEqual({solanaTokenDescriptor:{data:n.descriptor.data,signature:"prod-sig"}})})})});
1
+ import{DeviceModelId as y}from"@ledgerhq/device-management-kit";import{Left as m,Right as f}from"purify-ts";import{beforeEach as g,describe as p,expect as t,it as s,vi as a}from"vitest";import{KeyUsage as T}from"../../pki/model/KeyUsage";import{SolanaContextTypes as d}from"../../shared/model/SolanaContextTypes";import{SolanaTokenContextLoader as I}from"../../solanaToken/domain/SolanaTokenContextLoader";const O=()=>({debug:a.fn(),info:a.fn(),warn:a.fn(),error:a.fn(),subscribers:[]});p("SolanaTokenContextLoader",()=>{let i,l;const c=new Uint8Array([240,202,204,26]),n={descriptor:{data:{symbol:"SOL",name:"Solana",decimals:9},signatures:{prod:"prod-sig",test:"test-sig"}}},k={tokenInternalId:"token-1",deviceModelId:y.FLEX};g(()=>{a.restoreAllMocks(),i={getTokenInfosPayload:a.fn()},l={loadCertificate:a.fn()}});const r=e=>{const o={cal:{mode:e}};return new I(i,o,l,O)};p("canHandle",()=>{s("returns true when tokenInternalId is provided",()=>{const e=r("prod");t(e.canHandle({tokenInternalId:"abc123"},d.SOLANA_TOKEN)).toBe(!0)}),s("returns false when tokenInternalId is missing or falsy",()=>{const e=r("prod");t(e.canHandle({tokenInternalId:""},d.SOLANA_TOKEN)).toBe(!1),t(e.canHandle({tokenInternalId:void 0},d.SOLANA_TOKEN)).toBe(!1),t(e.canHandle({},d.SOLANA_TOKEN)).toBe(!1)})}),p("loadField",()=>{s("returns an error when datasource returns Left(error) and still fetched certificate beforehand",async()=>{const e=r("prod"),o=new Error("datasource failed");a.spyOn(i,"getTokenInfosPayload").mockResolvedValue(m(o)),a.spyOn(l,"loadCertificate").mockResolvedValue({keyUsageNumber:0,payload:c});const u=await e.loadField(k);t(i.getTokenInfosPayload).toHaveBeenCalledWith({tokenInternalId:"token-1"}),t(l.loadCertificate).toHaveBeenCalledWith({keyId:"token_metadata_key",keyUsage:T.CoinMeta,targetDevice:k.deviceModelId}),t(u).toEqual({type:d.ERROR,error:o})}),s("returns SOLANA_TOKEN with prod signature by default (falsy mode), and includes certificate",async()=>{const e=r("");a.spyOn(i,"getTokenInfosPayload").mockResolvedValue(f(n)),a.spyOn(l,"loadCertificate").mockResolvedValue({keyUsageNumber:0,payload:c});const o=await e.loadField({...k,tokenInternalId:"token-2"});t(o).toEqual({type:d.SOLANA_TOKEN,payload:{solanaTokenDescriptor:{data:n.descriptor.data,signature:"prod-sig"}},certificate:{keyUsageNumber:0,payload:c}})}),s("returns SOLANA_TOKEN with signature matching config.cal.mode",async()=>{const e=r("test");a.spyOn(i,"getTokenInfosPayload").mockResolvedValue(f(n)),a.spyOn(l,"loadCertificate").mockResolvedValue({keyUsageNumber:1,payload:c});const o=await e.loadField({...k,tokenInternalId:"token-3"});t(o).toEqual({type:d.SOLANA_TOKEN,payload:{solanaTokenDescriptor:{data:n.descriptor.data,signature:"test-sig"}},certificate:{keyUsageNumber:1,payload:c}})}),s("works even if certificate loader returns undefined (certificate omitted)",async()=>{const e=r("prod");a.spyOn(i,"getTokenInfosPayload").mockResolvedValue(f(n)),a.spyOn(l,"loadCertificate").mockResolvedValue(void 0);const o=await e.loadField(k);t(o).toEqual({type:d.SOLANA_TOKEN,payload:{solanaTokenDescriptor:{data:n.descriptor.data,signature:"prod-sig"}},certificate:void 0})})}),p("pluckTokenData (private)",()=>{s("picks the signature for the configured mode",()=>{const e=r("test"),u=e.pluckTokenData.bind(e)(n);t(u).toEqual({solanaTokenDescriptor:{data:n.descriptor.data,signature:"test-sig"}})}),s("falls back to 'prod' when config.cal.mode is falsy",()=>{const o=r(void 0).pluckTokenData(n);t(o).toEqual({solanaTokenDescriptor:{data:n.descriptor.data,signature:"prod-sig"}})})})});
2
2
  //# sourceMappingURL=DefaultSolanaContextLoader.test.js.map
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "version": 3,
3
3
  "sources": ["../../../../../src/solana/domain/DefaultSolanaContextLoader.test.ts"],
4
- "sourcesContent": ["/* eslint-disable @typescript-eslint/no-unsafe-call */\n/* eslint-disable @typescript-eslint/no-unsafe-member-access */\n/* eslint-disable @typescript-eslint/no-explicit-any */\n/* eslint-disable @typescript-eslint/no-unsafe-assignment */\nimport { DeviceModelId } from \"@ledgerhq/device-management-kit\";\nimport { Left, Right } from \"purify-ts\";\nimport { beforeEach, describe, expect, it, vi } from \"vitest\";\n\nimport { type ContextModuleConfig } from \"@/config/model/ContextModuleConfig\";\nimport type { PkiCertificateLoader } from \"@/pki/domain/PkiCertificateLoader\";\nimport { KeyUsage } from \"@/pki/model/KeyUsage\";\nimport { SolanaContextTypes } from \"@/shared/model/SolanaContextTypes\";\nimport type { SolanaTransactionContext } from \"@/solana/domain/solanaContextTypes\";\nimport {\n type SolanaTokenDataSource,\n type TokenDataResponse,\n} from \"@/solanaToken/data/SolanaTokenDataSource\";\nimport { SolanaTokenContextLoader } from \"@/solanaToken/domain/SolanaTokenContextLoader\";\n\nconst mockLoggerFactory = () => ({\n debug: vi.fn(),\n info: vi.fn(),\n warn: vi.fn(),\n error: vi.fn(),\n subscribers: [],\n});\n\ndescribe(\"SolanaTokenContextLoader\", () => {\n let mockDataSource: SolanaTokenDataSource;\n let mockCertLoader: PkiCertificateLoader;\n\n const bytes = new Uint8Array([0xf0, 0xca, 0xcc, 0x1a]);\n\n const tokenDataResponse: TokenDataResponse = {\n descriptor: {\n data: { symbol: \"SOL\", name: \"Solana\", decimals: 9 } as any,\n signatures: {\n prod: \"prod-sig\",\n test: \"test-sig\",\n } as any,\n },\n } as any;\n\n const baseCtx = {\n tokenInternalId: \"token-1\",\n deviceModelId: DeviceModelId.FLEX,\n } as any;\n\n beforeEach(() => {\n vi.restoreAllMocks();\n\n mockDataSource = {\n getTokenInfosPayload: vi.fn(),\n } as unknown as SolanaTokenDataSource;\n\n mockCertLoader = {\n loadCertificate: vi.fn(),\n } as unknown as PkiCertificateLoader;\n });\n\n const makeLoader = (mode?: string) => {\n const config = { cal: { mode } } as unknown as ContextModuleConfig;\n return new SolanaTokenContextLoader(\n mockDataSource,\n config,\n mockCertLoader,\n mockLoggerFactory,\n );\n };\n\n describe(\"canHandle\", () => {\n it(\"returns true when tokenInternalId is provided\", () => {\n const loader = makeLoader(\"prod\");\n\n expect(\n loader.canHandle(\n {\n tokenInternalId: \"abc123\",\n } as SolanaTransactionContext,\n SolanaContextTypes.SOLANA_TOKEN,\n ),\n ).toBe(true);\n });\n\n it(\"returns false when tokenInternalId is missing or falsy\", () => {\n const loader = makeLoader(\"prod\");\n\n expect(\n loader.canHandle(\n { tokenInternalId: \"\" } as any,\n SolanaContextTypes.SOLANA_TOKEN,\n ),\n ).toBe(false);\n expect(\n loader.canHandle(\n { tokenInternalId: undefined } as any,\n SolanaContextTypes.SOLANA_TOKEN,\n ),\n ).toBe(false);\n expect(loader.canHandle({} as any, SolanaContextTypes.SOLANA_TOKEN)).toBe(\n false,\n );\n });\n });\n\n describe(\"loadField\", () => {\n it(\"returns an error when datasource returns Left(error) and still fetched certificate beforehand\", async () => {\n const loader = makeLoader(\"prod\");\n const error = new Error(\"datasource failed\");\n\n vi.spyOn(mockDataSource, \"getTokenInfosPayload\").mockResolvedValue(\n Left(error),\n );\n vi.spyOn(mockCertLoader, \"loadCertificate\").mockResolvedValue({\n keyUsageNumber: 0,\n payload: bytes,\n });\n\n const result = await loader.loadField(baseCtx);\n\n expect(mockDataSource.getTokenInfosPayload).toHaveBeenCalledWith({\n tokenInternalId: \"token-1\",\n });\n expect(mockCertLoader.loadCertificate).toHaveBeenCalledWith({\n keyId: \"token_metadata_key\",\n keyUsage: KeyUsage.CoinMeta,\n targetDevice: baseCtx.deviceModelId,\n });\n expect(result).toEqual({\n type: SolanaContextTypes.ERROR,\n error,\n });\n });\n\n it(\"returns SOLANA_TOKEN with prod signature by default (falsy mode), and includes certificate\", async () => {\n const loader = makeLoader(\"\"); // falsy -> default 'prod'\n\n vi.spyOn(mockDataSource, \"getTokenInfosPayload\").mockResolvedValue(\n Right(tokenDataResponse),\n );\n vi.spyOn(mockCertLoader, \"loadCertificate\").mockResolvedValue({\n keyUsageNumber: 0,\n payload: bytes,\n });\n\n const result = await loader.loadField({\n ...baseCtx,\n tokenInternalId: \"token-2\",\n });\n\n expect(result).toEqual({\n type: SolanaContextTypes.SOLANA_TOKEN,\n payload: {\n solanaTokenDescriptor: {\n data: tokenDataResponse.descriptor.data,\n signature: \"prod-sig\",\n },\n },\n certificate: { keyUsageNumber: 0, payload: bytes },\n });\n });\n\n it(\"returns SOLANA_TOKEN with signature matching config.cal.mode\", async () => {\n const loader = makeLoader(\"test\");\n\n vi.spyOn(mockDataSource, \"getTokenInfosPayload\").mockResolvedValue(\n Right(tokenDataResponse),\n );\n vi.spyOn(mockCertLoader, \"loadCertificate\").mockResolvedValue({\n keyUsageNumber: 1,\n payload: bytes,\n });\n\n const result = await loader.loadField({\n ...baseCtx,\n tokenInternalId: \"token-3\",\n });\n\n expect(result).toEqual({\n type: SolanaContextTypes.SOLANA_TOKEN,\n payload: {\n solanaTokenDescriptor: {\n data: tokenDataResponse.descriptor.data,\n signature: \"test-sig\",\n },\n },\n certificate: { keyUsageNumber: 1, payload: bytes },\n });\n });\n\n it(\"works even if certificate loader returns undefined (certificate omitted)\", async () => {\n const loader = makeLoader(\"prod\");\n\n vi.spyOn(mockDataSource, \"getTokenInfosPayload\").mockResolvedValue(\n Right(tokenDataResponse),\n );\n vi.spyOn(mockCertLoader, \"loadCertificate\").mockResolvedValue(undefined);\n\n const result = await loader.loadField(baseCtx);\n\n expect(result).toEqual({\n type: SolanaContextTypes.SOLANA_TOKEN,\n payload: {\n solanaTokenDescriptor: {\n data: tokenDataResponse.descriptor.data,\n signature: \"prod-sig\",\n },\n },\n certificate: undefined,\n });\n });\n });\n\n describe(\"pluckTokenData (private)\", () => {\n it(\"picks the signature for the configured mode\", () => {\n const loader = makeLoader(\"test\");\n const pluck = (loader as any).pluckTokenData.bind(loader);\n\n const result = pluck(tokenDataResponse);\n\n expect(result).toEqual({\n solanaTokenDescriptor: {\n data: tokenDataResponse.descriptor.data,\n signature: \"test-sig\",\n },\n });\n });\n\n it(\"falls back to 'prod' when config.cal.mode is falsy\", () => {\n const loader = makeLoader(undefined as any);\n const result = (loader as any).pluckTokenData(tokenDataResponse);\n\n expect(result).toEqual({\n solanaTokenDescriptor: {\n data: tokenDataResponse.descriptor.data,\n signature: \"prod-sig\",\n },\n });\n });\n });\n});\n"],
4
+ "sourcesContent": ["/* eslint-disable @typescript-eslint/no-unsafe-call */\n/* eslint-disable @typescript-eslint/no-unsafe-member-access */\n/* eslint-disable @typescript-eslint/no-explicit-any */\n/* eslint-disable @typescript-eslint/no-unsafe-assignment */\nimport { DeviceModelId } from \"@ledgerhq/device-management-kit\";\nimport { Left, Right } from \"purify-ts\";\nimport { beforeEach, describe, expect, it, vi } from \"vitest\";\n\nimport { type ContextModuleServiceConfig } from \"@/config/model/ContextModuleConfig\";\nimport type { PkiCertificateLoader } from \"@/pki/domain/PkiCertificateLoader\";\nimport { KeyUsage } from \"@/pki/model/KeyUsage\";\nimport { SolanaContextTypes } from \"@/shared/model/SolanaContextTypes\";\nimport type { SolanaTransactionContext } from \"@/solana/domain/solanaContextTypes\";\nimport {\n type SolanaTokenDataSource,\n type TokenDataResponse,\n} from \"@/solanaToken/data/SolanaTokenDataSource\";\nimport { SolanaTokenContextLoader } from \"@/solanaToken/domain/SolanaTokenContextLoader\";\n\nconst mockLoggerFactory = () => ({\n debug: vi.fn(),\n info: vi.fn(),\n warn: vi.fn(),\n error: vi.fn(),\n subscribers: [],\n});\n\ndescribe(\"SolanaTokenContextLoader\", () => {\n let mockDataSource: SolanaTokenDataSource;\n let mockCertLoader: PkiCertificateLoader;\n\n const bytes = new Uint8Array([0xf0, 0xca, 0xcc, 0x1a]);\n\n const tokenDataResponse: TokenDataResponse = {\n descriptor: {\n data: { symbol: \"SOL\", name: \"Solana\", decimals: 9 } as any,\n signatures: {\n prod: \"prod-sig\",\n test: \"test-sig\",\n } as any,\n },\n } as any;\n\n const baseCtx = {\n tokenInternalId: \"token-1\",\n deviceModelId: DeviceModelId.FLEX,\n } as any;\n\n beforeEach(() => {\n vi.restoreAllMocks();\n\n mockDataSource = {\n getTokenInfosPayload: vi.fn(),\n } as unknown as SolanaTokenDataSource;\n\n mockCertLoader = {\n loadCertificate: vi.fn(),\n } as unknown as PkiCertificateLoader;\n });\n\n const makeLoader = (mode?: string) => {\n const config = { cal: { mode } } as unknown as ContextModuleServiceConfig;\n return new SolanaTokenContextLoader(\n mockDataSource,\n config,\n mockCertLoader,\n mockLoggerFactory,\n );\n };\n\n describe(\"canHandle\", () => {\n it(\"returns true when tokenInternalId is provided\", () => {\n const loader = makeLoader(\"prod\");\n\n expect(\n loader.canHandle(\n {\n tokenInternalId: \"abc123\",\n } as SolanaTransactionContext,\n SolanaContextTypes.SOLANA_TOKEN,\n ),\n ).toBe(true);\n });\n\n it(\"returns false when tokenInternalId is missing or falsy\", () => {\n const loader = makeLoader(\"prod\");\n\n expect(\n loader.canHandle(\n { tokenInternalId: \"\" } as any,\n SolanaContextTypes.SOLANA_TOKEN,\n ),\n ).toBe(false);\n expect(\n loader.canHandle(\n { tokenInternalId: undefined } as any,\n SolanaContextTypes.SOLANA_TOKEN,\n ),\n ).toBe(false);\n expect(loader.canHandle({} as any, SolanaContextTypes.SOLANA_TOKEN)).toBe(\n false,\n );\n });\n });\n\n describe(\"loadField\", () => {\n it(\"returns an error when datasource returns Left(error) and still fetched certificate beforehand\", async () => {\n const loader = makeLoader(\"prod\");\n const error = new Error(\"datasource failed\");\n\n vi.spyOn(mockDataSource, \"getTokenInfosPayload\").mockResolvedValue(\n Left(error),\n );\n vi.spyOn(mockCertLoader, \"loadCertificate\").mockResolvedValue({\n keyUsageNumber: 0,\n payload: bytes,\n });\n\n const result = await loader.loadField(baseCtx);\n\n expect(mockDataSource.getTokenInfosPayload).toHaveBeenCalledWith({\n tokenInternalId: \"token-1\",\n });\n expect(mockCertLoader.loadCertificate).toHaveBeenCalledWith({\n keyId: \"token_metadata_key\",\n keyUsage: KeyUsage.CoinMeta,\n targetDevice: baseCtx.deviceModelId,\n });\n expect(result).toEqual({\n type: SolanaContextTypes.ERROR,\n error,\n });\n });\n\n it(\"returns SOLANA_TOKEN with prod signature by default (falsy mode), and includes certificate\", async () => {\n const loader = makeLoader(\"\"); // falsy -> default 'prod'\n\n vi.spyOn(mockDataSource, \"getTokenInfosPayload\").mockResolvedValue(\n Right(tokenDataResponse),\n );\n vi.spyOn(mockCertLoader, \"loadCertificate\").mockResolvedValue({\n keyUsageNumber: 0,\n payload: bytes,\n });\n\n const result = await loader.loadField({\n ...baseCtx,\n tokenInternalId: \"token-2\",\n });\n\n expect(result).toEqual({\n type: SolanaContextTypes.SOLANA_TOKEN,\n payload: {\n solanaTokenDescriptor: {\n data: tokenDataResponse.descriptor.data,\n signature: \"prod-sig\",\n },\n },\n certificate: { keyUsageNumber: 0, payload: bytes },\n });\n });\n\n it(\"returns SOLANA_TOKEN with signature matching config.cal.mode\", async () => {\n const loader = makeLoader(\"test\");\n\n vi.spyOn(mockDataSource, \"getTokenInfosPayload\").mockResolvedValue(\n Right(tokenDataResponse),\n );\n vi.spyOn(mockCertLoader, \"loadCertificate\").mockResolvedValue({\n keyUsageNumber: 1,\n payload: bytes,\n });\n\n const result = await loader.loadField({\n ...baseCtx,\n tokenInternalId: \"token-3\",\n });\n\n expect(result).toEqual({\n type: SolanaContextTypes.SOLANA_TOKEN,\n payload: {\n solanaTokenDescriptor: {\n data: tokenDataResponse.descriptor.data,\n signature: \"test-sig\",\n },\n },\n certificate: { keyUsageNumber: 1, payload: bytes },\n });\n });\n\n it(\"works even if certificate loader returns undefined (certificate omitted)\", async () => {\n const loader = makeLoader(\"prod\");\n\n vi.spyOn(mockDataSource, \"getTokenInfosPayload\").mockResolvedValue(\n Right(tokenDataResponse),\n );\n vi.spyOn(mockCertLoader, \"loadCertificate\").mockResolvedValue(undefined);\n\n const result = await loader.loadField(baseCtx);\n\n expect(result).toEqual({\n type: SolanaContextTypes.SOLANA_TOKEN,\n payload: {\n solanaTokenDescriptor: {\n data: tokenDataResponse.descriptor.data,\n signature: \"prod-sig\",\n },\n },\n certificate: undefined,\n });\n });\n });\n\n describe(\"pluckTokenData (private)\", () => {\n it(\"picks the signature for the configured mode\", () => {\n const loader = makeLoader(\"test\");\n const pluck = (loader as any).pluckTokenData.bind(loader);\n\n const result = pluck(tokenDataResponse);\n\n expect(result).toEqual({\n solanaTokenDescriptor: {\n data: tokenDataResponse.descriptor.data,\n signature: \"test-sig\",\n },\n });\n });\n\n it(\"falls back to 'prod' when config.cal.mode is falsy\", () => {\n const loader = makeLoader(undefined as any);\n const result = (loader as any).pluckTokenData(tokenDataResponse);\n\n expect(result).toEqual({\n solanaTokenDescriptor: {\n data: tokenDataResponse.descriptor.data,\n signature: \"prod-sig\",\n },\n });\n });\n });\n});\n"],
5
5
  "mappings": "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",
6
6
  "names": ["DeviceModelId", "Left", "Right", "beforeEach", "describe", "expect", "it", "vi", "KeyUsage", "SolanaContextTypes", "SolanaTokenContextLoader", "mockLoggerFactory", "mockDataSource", "mockCertLoader", "bytes", "tokenDataResponse", "baseCtx", "makeLoader", "mode", "config", "loader", "error", "result"]
7
7
  }
@@ -1,2 +1,2 @@
1
- var h=Object.defineProperty;var u=Object.getOwnPropertyDescriptor;var g=(s,o,t,e)=>{for(var r=e>1?void 0:e?u(o,t):o,a=s.length-1,n;a>=0;a--)(n=s[a])&&(r=(e?n(o,t,r):n(r))||r);return e&&r&&h(o,t,r),r},c=(s,o)=>(t,e)=>o(t,e,s);import f from"axios";import{inject as p,injectable as m}from"inversify";import{Left as l,Right as D}from"purify-ts";import{configTypes as d}from"../../config/di/configTypes";import{LEDGER_CLIENT_VERSION_HEADER as E}from"../../shared/constant/HttpHeaders";import T from"../../../package.json";let i=class{constructor(o,t){this.config=o;this.logger=t("HttpSolanaLifiDataSource")}logger;async getTransactionDescriptorsPayload({templateId:o}){const t=`${this.config.cal.url}/swap_templates`,e={id:o,output:"id,chain_id,instructions,descriptors"};this.logger.debug("[getTransactionDescriptorsPayload] Fetching transaction descriptors",{data:{templateId:o,url:t,params:e}});try{const{data:r}=await f.request({method:"GET",url:t,params:e,headers:{[E]:`context-module/${T.version}`}});return this.logger.debug("[getTransactionDescriptorsPayload] Received response",{data:{templateId:o,responseLength:r?.length??0,hasData:!!r&&r.length>0}}),!r||r.length===0||!r[0]?(this.logger.warn("[getTransactionDescriptorsPayload] No transaction descriptors found",{data:{templateId:o,responseLength:r?.length??0}}),l(new Error(`[ContextModule] HttpSolanaLifiDataSource: no transaction descriptors for id ${o}`))):(this.logger.info("[getTransactionDescriptorsPayload] Successfully fetched transaction descriptors",{data:{templateId:o,descriptorsCount:r[0].descriptors?.length??0}}),D(r[0]))}catch(r){return this.logger.error("[getTransactionDescriptorsPayload] Failed to fetch transaction descriptors",{data:{templateId:o,url:t,error:r instanceof Error?r.message:String(r)}}),l(new Error("[ContextModule] HttpSolanaLifiDataSource: Failed to fetch transaction descriptors"))}}};i=g([m(),c(0,p(d.Config)),c(1,p(d.ContextModuleLoggerFactory))],i);export{i as HttpSolanaLifiDataSource};
1
+ var f=Object.defineProperty;var h=Object.getOwnPropertyDescriptor;var p=(s,t,r,e)=>{for(var o=e>1?void 0:e?h(t,r):t,n=s.length-1,c;n>=0;n--)(c=s[n])&&(o=(e?c(t,r,o):c(o))||o);return e&&o&&f(t,r,o),o},i=(s,t)=>(r,e)=>t(r,e,s);import{inject as g,injectable as u}from"inversify";import{Left as l,Right as m}from"purify-ts";import{configTypes as d}from"../../config/di/configTypes";import{networkTypes as D}from"../../network/di/networkTypes";let a=class{constructor(t,r,e){this.config=t;this.http=e;this.logger=r("HttpSolanaLifiDataSource")}logger;async getTransactionDescriptorsPayload({templateId:t}){this.logger.debug("[getTransactionDescriptorsPayload] Fetching transaction descriptors",{data:{templateId:t}});try{const r=await this.http.get(`${this.config.cal.url}/swap_templates`,{params:{template_id:t,output:"id,chain_id,instructions,descriptors",ref:"ref=commit:866b6e7633a7a806fab7f9941bcc3df7ee640784"}});return this.logger.debug("[getTransactionDescriptorsPayload] Received response",{data:{templateId:t,responseLength:r?.length??0,hasData:!!r&&r.length>0}}),!r||r.length===0||!r[0]?(this.logger.warn("[getTransactionDescriptorsPayload] No transaction descriptors found",{data:{templateId:t,responseLength:r?.length??0}}),l(new Error(`[ContextModule] HttpSolanaLifiDataSource: no transaction descriptors for id ${t}`))):(this.logger.info("[getTransactionDescriptorsPayload] Successfully fetched transaction descriptors",{data:{templateId:t,descriptorsCount:r[0].descriptors?.length??0}}),m(r[0]))}catch(r){return this.logger.error("[getTransactionDescriptorsPayload] Failed to fetch transaction descriptors",{data:{templateId:t,error:r instanceof Error?r.message:String(r)}}),l(new Error("[ContextModule] HttpSolanaLifiDataSource: Failed to fetch transaction descriptors"))}}};a=p([u(),i(0,g(d.Config)),i(1,g(d.ContextModuleLoggerFactory)),i(2,g(D.NetworkClient))],a);export{a as HttpSolanaLifiDataSource};
2
2
  //# sourceMappingURL=HttpSolanaLifiDataSource.js.map
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "version": 3,
3
3
  "sources": ["../../../../../src/solanaLifi/data/HttpSolanaLifiDataSource.ts"],
4
- "sourcesContent": ["import { LoggerPublisherService } from \"@ledgerhq/device-management-kit\";\nimport axios from \"axios\";\nimport { inject, injectable } from \"inversify\";\nimport { Either, Left, Right } from \"purify-ts\";\n\nimport { configTypes } from \"@/config/di/configTypes\";\nimport { type ContextModuleConfig } from \"@/config/model/ContextModuleConfig\";\nimport { LEDGER_CLIENT_VERSION_HEADER } from \"@/shared/constant/HttpHeaders\";\nimport PACKAGE from \"@root/package.json\";\n\nimport {\n GetTransactionDescriptorsParams,\n GetTransactionDescriptorsResponse,\n SolanaLifiDataSource,\n} from \"./SolanaLifiDataSource\";\n\n@injectable()\nexport class HttpSolanaLifiDataSource implements SolanaLifiDataSource {\n private logger: LoggerPublisherService;\n\n constructor(\n @inject(configTypes.Config) private readonly config: ContextModuleConfig,\n @inject(configTypes.ContextModuleLoggerFactory)\n loggerFactory: (tag: string) => LoggerPublisherService,\n ) {\n this.logger = loggerFactory(\"HttpSolanaLifiDataSource\");\n }\n\n public async getTransactionDescriptorsPayload({\n templateId,\n }: GetTransactionDescriptorsParams): Promise<\n Either<Error, GetTransactionDescriptorsResponse>\n > {\n const url = `${this.config.cal.url}/swap_templates`;\n const params = {\n id: templateId,\n output: \"id,chain_id,instructions,descriptors\",\n };\n\n this.logger.debug(\n \"[getTransactionDescriptorsPayload] Fetching transaction descriptors\",\n {\n data: { templateId, url, params },\n },\n );\n\n try {\n const { data } = await axios.request<GetTransactionDescriptorsResponse[]>(\n {\n method: \"GET\",\n url,\n params,\n headers: {\n [LEDGER_CLIENT_VERSION_HEADER]: `context-module/${PACKAGE.version}`,\n },\n },\n );\n\n this.logger.debug(\n \"[getTransactionDescriptorsPayload] Received response\",\n {\n data: {\n templateId,\n responseLength: data?.length ?? 0,\n hasData: !!data && data.length > 0,\n },\n },\n );\n\n if (!data || data.length === 0 || !data[0]) {\n this.logger.warn(\n \"[getTransactionDescriptorsPayload] No transaction descriptors found\",\n {\n data: { templateId, responseLength: data?.length ?? 0 },\n },\n );\n return Left(\n new Error(\n `[ContextModule] HttpSolanaLifiDataSource: no transaction descriptors for id ${templateId}`,\n ),\n );\n }\n\n this.logger.info(\n \"[getTransactionDescriptorsPayload] Successfully fetched transaction descriptors\",\n {\n data: {\n templateId,\n descriptorsCount: data[0].descriptors?.length ?? 0,\n },\n },\n );\n\n return Right(data[0]);\n } catch (error) {\n this.logger.error(\n \"[getTransactionDescriptorsPayload] Failed to fetch transaction descriptors\",\n {\n data: {\n templateId,\n url,\n error: error instanceof Error ? error.message : String(error),\n },\n },\n );\n return Left(\n new Error(\n \"[ContextModule] HttpSolanaLifiDataSource: Failed to fetch transaction descriptors\",\n ),\n );\n }\n }\n}\n"],
5
- "mappings": "iOACA,OAAOA,MAAW,QAClB,OAAS,UAAAC,EAAQ,cAAAC,MAAkB,YACnC,OAAiB,QAAAC,EAAM,SAAAC,MAAa,YAEpC,OAAS,eAAAC,MAAmB,0BAE5B,OAAS,gCAAAC,MAAoC,gCAC7C,OAAOC,MAAa,qBASb,IAAMC,EAAN,KAA+D,CAGpE,YAC+CC,EAE7CC,EACA,CAH6C,YAAAD,EAI7C,KAAK,OAASC,EAAc,0BAA0B,CACxD,CARQ,OAUR,MAAa,iCAAiC,CAC5C,WAAAC,CACF,EAEE,CACA,MAAMC,EAAM,GAAG,KAAK,OAAO,IAAI,GAAG,kBAC5BC,EAAS,CACb,GAAIF,EACJ,OAAQ,sCACV,EAEA,KAAK,OAAO,MACV,sEACA,CACE,KAAM,CAAE,WAAAA,EAAY,IAAAC,EAAK,OAAAC,CAAO,CAClC,CACF,EAEA,GAAI,CACF,KAAM,CAAE,KAAAC,CAAK,EAAI,MAAMC,EAAM,QAC3B,CACE,OAAQ,MACR,IAAAH,EACA,OAAAC,EACA,QAAS,CACP,CAACG,CAA4B,EAAG,kBAAkBC,EAAQ,OAAO,EACnE,CACF,CACF,EAaA,OAXA,KAAK,OAAO,MACV,uDACA,CACE,KAAM,CACJ,WAAAN,EACA,eAAgBG,GAAM,QAAU,EAChC,QAAS,CAAC,CAACA,GAAQA,EAAK,OAAS,CACnC,CACF,CACF,EAEI,CAACA,GAAQA,EAAK,SAAW,GAAK,CAACA,EAAK,CAAC,GACvC,KAAK,OAAO,KACV,sEACA,CACE,KAAM,CAAE,WAAAH,EAAY,eAAgBG,GAAM,QAAU,CAAE,CACxD,CACF,EACOI,EACL,IAAI,MACF,+EAA+EP,CAAU,EAC3F,CACF,IAGF,KAAK,OAAO,KACV,kFACA,CACE,KAAM,CACJ,WAAAA,EACA,iBAAkBG,EAAK,CAAC,EAAE,aAAa,QAAU,CACnD,CACF,CACF,EAEOK,EAAML,EAAK,CAAC,CAAC,EACtB,OAASM,EAAO,CACd,YAAK,OAAO,MACV,6EACA,CACE,KAAM,CACJ,WAAAT,EACA,IAAAC,EACA,MAAOQ,aAAiB,MAAQA,EAAM,QAAU,OAAOA,CAAK,CAC9D,CACF,CACF,EACOF,EACL,IAAI,MACF,mFACF,CACF,CACF,CACF,CACF,EA/FaV,EAANa,EAAA,CADNC,EAAW,EAKPC,EAAA,EAAAC,EAAOC,EAAY,MAAM,GACzBF,EAAA,EAAAC,EAAOC,EAAY,0BAA0B,IALrCjB",
6
- "names": ["axios", "inject", "injectable", "Left", "Right", "configTypes", "LEDGER_CLIENT_VERSION_HEADER", "PACKAGE", "HttpSolanaLifiDataSource", "config", "loggerFactory", "templateId", "url", "params", "data", "axios", "LEDGER_CLIENT_VERSION_HEADER", "PACKAGE", "Left", "Right", "error", "__decorateClass", "injectable", "__decorateParam", "inject", "configTypes"]
4
+ "sourcesContent": ["import {\n DmkNetworkClient,\n LoggerPublisherService,\n} from \"@ledgerhq/device-management-kit\";\nimport { inject, injectable } from \"inversify\";\nimport { Either, Left, Right } from \"purify-ts\";\n\nimport { configTypes } from \"@/config/di/configTypes\";\nimport { type ContextModuleServiceConfig } from \"@/config/model/ContextModuleConfig\";\nimport { networkTypes } from \"@/network/di/networkTypes\";\n\nimport {\n GetTransactionDescriptorsParams,\n GetTransactionDescriptorsResponse,\n SolanaLifiDataSource,\n} from \"./SolanaLifiDataSource\";\n\n@injectable()\nexport class HttpSolanaLifiDataSource implements SolanaLifiDataSource {\n private logger: LoggerPublisherService;\n\n constructor(\n @inject(configTypes.Config)\n private readonly config: ContextModuleServiceConfig,\n @inject(configTypes.ContextModuleLoggerFactory)\n loggerFactory: (tag: string) => LoggerPublisherService,\n @inject(networkTypes.NetworkClient)\n private readonly http: DmkNetworkClient,\n ) {\n this.logger = loggerFactory(\"HttpSolanaLifiDataSource\");\n }\n\n public async getTransactionDescriptorsPayload({\n templateId,\n }: GetTransactionDescriptorsParams): Promise<\n Either<Error, GetTransactionDescriptorsResponse>\n > {\n this.logger.debug(\n \"[getTransactionDescriptorsPayload] Fetching transaction descriptors\",\n {\n data: { templateId },\n },\n );\n\n try {\n const data = (await this.http.get(\n `${this.config.cal.url}/swap_templates`,\n {\n params: {\n template_id: templateId,\n output: \"id,chain_id,instructions,descriptors\",\n // TODO LIFI\n // REVERT WHEN CAL SUPPORTS IT\n ref: \"ref=commit:866b6e7633a7a806fab7f9941bcc3df7ee640784\",\n },\n },\n )) as GetTransactionDescriptorsResponse[];\n\n this.logger.debug(\n \"[getTransactionDescriptorsPayload] Received response\",\n {\n data: {\n templateId,\n responseLength: data?.length ?? 0,\n hasData: !!data && data.length > 0,\n },\n },\n );\n\n if (!data || data.length === 0 || !data[0]) {\n this.logger.warn(\n \"[getTransactionDescriptorsPayload] No transaction descriptors found\",\n {\n data: { templateId, responseLength: data?.length ?? 0 },\n },\n );\n return Left(\n new Error(\n `[ContextModule] HttpSolanaLifiDataSource: no transaction descriptors for id ${templateId}`,\n ),\n );\n }\n\n this.logger.info(\n \"[getTransactionDescriptorsPayload] Successfully fetched transaction descriptors\",\n {\n data: {\n templateId,\n descriptorsCount: data[0].descriptors?.length ?? 0,\n },\n },\n );\n\n return Right(data[0]);\n } catch (error) {\n this.logger.error(\n \"[getTransactionDescriptorsPayload] Failed to fetch transaction descriptors\",\n {\n data: {\n templateId,\n error: error instanceof Error ? error.message : String(error),\n },\n },\n );\n return Left(\n new Error(\n \"[ContextModule] HttpSolanaLifiDataSource: Failed to fetch transaction descriptors\",\n ),\n );\n }\n }\n}\n"],
5
+ "mappings": "iOAIA,OAAS,UAAAA,EAAQ,cAAAC,MAAkB,YACnC,OAAiB,QAAAC,EAAM,SAAAC,MAAa,YAEpC,OAAS,eAAAC,MAAmB,0BAE5B,OAAS,gBAAAC,MAAoB,4BAStB,IAAMC,EAAN,KAA+D,CAGpE,YAEmBC,EAEjBC,EAEiBC,EACjB,CALiB,YAAAF,EAIA,UAAAE,EAEjB,KAAK,OAASD,EAAc,0BAA0B,CACxD,CAXQ,OAaR,MAAa,iCAAiC,CAC5C,WAAAE,CACF,EAEE,CACA,KAAK,OAAO,MACV,sEACA,CACE,KAAM,CAAE,WAAAA,CAAW,CACrB,CACF,EAEA,GAAI,CACF,MAAMC,EAAQ,MAAM,KAAK,KAAK,IAC5B,GAAG,KAAK,OAAO,IAAI,GAAG,kBACtB,CACE,OAAQ,CACN,YAAaD,EACb,OAAQ,uCAGR,IAAK,qDACP,CACF,CACF,EAaA,OAXA,KAAK,OAAO,MACV,uDACA,CACE,KAAM,CACJ,WAAAA,EACA,eAAgBC,GAAM,QAAU,EAChC,QAAS,CAAC,CAACA,GAAQA,EAAK,OAAS,CACnC,CACF,CACF,EAEI,CAACA,GAAQA,EAAK,SAAW,GAAK,CAACA,EAAK,CAAC,GACvC,KAAK,OAAO,KACV,sEACA,CACE,KAAM,CAAE,WAAAD,EAAY,eAAgBC,GAAM,QAAU,CAAE,CACxD,CACF,EACOC,EACL,IAAI,MACF,+EAA+EF,CAAU,EAC3F,CACF,IAGF,KAAK,OAAO,KACV,kFACA,CACE,KAAM,CACJ,WAAAA,EACA,iBAAkBC,EAAK,CAAC,EAAE,aAAa,QAAU,CACnD,CACF,CACF,EAEOE,EAAMF,EAAK,CAAC,CAAC,EACtB,OAASG,EAAO,CACd,YAAK,OAAO,MACV,6EACA,CACE,KAAM,CACJ,WAAAJ,EACA,MAAOI,aAAiB,MAAQA,EAAM,QAAU,OAAOA,CAAK,CAC9D,CACF,CACF,EACOF,EACL,IAAI,MACF,mFACF,CACF,CACF,CACF,CACF,EA7FaN,EAANS,EAAA,CADNC,EAAW,EAKPC,EAAA,EAAAC,EAAOC,EAAY,MAAM,GAEzBF,EAAA,EAAAC,EAAOC,EAAY,0BAA0B,GAE7CF,EAAA,EAAAC,EAAOE,EAAa,aAAa,IARzBd",
6
+ "names": ["inject", "injectable", "Left", "Right", "configTypes", "networkTypes", "HttpSolanaLifiDataSource", "config", "loggerFactory", "http", "templateId", "data", "Left", "Right", "error", "__decorateClass", "injectable", "__decorateParam", "inject", "configTypes", "networkTypes"]
7
7
  }
@@ -1,2 +1,2 @@
1
- import s from"axios";import{Left as i,Right as d}from"purify-ts";import{beforeAll as u,beforeEach as p,describe as m,expect as a,it as n,vi as t}from"vitest";import{LEDGER_CLIENT_VERSION_HEADER as f}from"../../shared/constant/HttpHeaders";import y from"../../../package.json";import{HttpSolanaLifiDataSource as h}from"./HttpSolanaLifiDataSource";t.mock("axios");const w=()=>({debug:t.fn(),info:t.fn(),warn:t.fn(),error:t.fn(),subscribers:[]});m("HttpSolanaLifiDataSource",()=>{let r;const o="tpl-123",c={cal:{url:"https://crypto-assets-service.api.ledger.com/v1",mode:"prod",branch:"main"}};u(()=>{r=new h(c,w)}),p(()=>{t.clearAllMocks()}),n("should call axios with the ledger client version header and correct params",async()=>{const e=t.fn(()=>Promise.resolve({data:[]}));t.spyOn(s,"request").mockImplementation(e),await r.getTransactionDescriptorsPayload({templateId:o}),a(e).toHaveBeenCalledTimes(1),a(e).toHaveBeenCalledWith(a.objectContaining({method:"GET",url:`${c.cal.url}/swap_templates`,params:{id:o,output:"id,chain_id,instructions,descriptors"},headers:{[f]:`context-module/${y.version}`}}))}),n("should return Right(data[0]) when axios responds with a non-empty array",async()=>{const e={descriptors:{swap:{programId:"SwapProgram",accounts:[],data:"abcd"}}};t.spyOn(s,"request").mockResolvedValue({data:[e]});const l=await r.getTransactionDescriptorsPayload({templateId:o});a(l).toEqual(d(e))}),n("should return an error when data is undefined",async()=>{t.spyOn(s,"request").mockResolvedValue({data:void 0});const e=await r.getTransactionDescriptorsPayload({templateId:o});a(e).toEqual(i(new Error(`[ContextModule] HttpSolanaLifiDataSource: no transaction descriptors for id ${o}`)))}),n("should return an error when data array is empty",async()=>{t.spyOn(s,"request").mockResolvedValue({data:[]});const e=await r.getTransactionDescriptorsPayload({templateId:o});a(e).toEqual(i(new Error(`[ContextModule] HttpSolanaLifiDataSource: no transaction descriptors for id ${o}`)))}),n("should return an error when first element is falsy",async()=>{t.spyOn(s,"request").mockResolvedValue({data:[void 0]});const e=await r.getTransactionDescriptorsPayload({templateId:o});a(e).toEqual(i(new Error(`[ContextModule] HttpSolanaLifiDataSource: no transaction descriptors for id ${o}`)))}),n("should return an error when axios throws",async()=>{t.spyOn(s,"request").mockRejectedValue(new Error("network"));const e=await r.getTransactionDescriptorsPayload({templateId:o});a(e).toEqual(i(new Error("[ContextModule] HttpSolanaLifiDataSource: Failed to fetch transaction descriptors")))})});
1
+ import{Left as i,Right as d}from"purify-ts";import{beforeEach as p,describe as u,expect as r,it as n,vi as s}from"vitest";import{HttpSolanaLifiDataSource as f}from"./HttpSolanaLifiDataSource";const m=()=>({debug:s.fn(),info:s.fn(),warn:s.fn(),error:s.fn(),subscribers:[]});u("HttpSolanaLifiDataSource",()=>{let a,e;const t="tpl-123",c={cal:{url:"https://crypto-assets-service.api.ledger.com/v1",mode:"prod",branch:"main"}};p(()=>{s.clearAllMocks(),e={get:s.fn()},a=new f(c,m,e)}),n("should call the network client with the expected URL and params",async()=>{e.get.mockResolvedValue([]),await a.getTransactionDescriptorsPayload({templateId:t}),r(e.get).toHaveBeenCalledTimes(1),r(e.get).toHaveBeenCalledWith("https://crypto-assets-service.api.ledger.com/v1/swap_templates",{params:{template_id:t,output:"id,chain_id,instructions,descriptors",ref:"ref=commit:866b6e7633a7a806fab7f9941bcc3df7ee640784"}})}),n("should return Right(data[0]) when the network client responds with a non-empty array",async()=>{const o={descriptors:{swap:{programId:"SwapProgram",accounts:[],data:"abcd"}}};e.get.mockResolvedValue([o]);const l=await a.getTransactionDescriptorsPayload({templateId:t});r(l).toEqual(d(o))}),n("should return an error when data is undefined",async()=>{e.get.mockResolvedValue(null);const o=await a.getTransactionDescriptorsPayload({templateId:t});r(o).toEqual(i(new Error(`[ContextModule] HttpSolanaLifiDataSource: no transaction descriptors for id ${t}`)))}),n("should return an error when data array is empty",async()=>{e.get.mockResolvedValue([]);const o=await a.getTransactionDescriptorsPayload({templateId:t});r(o).toEqual(i(new Error(`[ContextModule] HttpSolanaLifiDataSource: no transaction descriptors for id ${t}`)))}),n("should return an error when first element is falsy",async()=>{e.get.mockResolvedValue([null]);const o=await a.getTransactionDescriptorsPayload({templateId:t});r(o).toEqual(i(new Error(`[ContextModule] HttpSolanaLifiDataSource: no transaction descriptors for id ${t}`)))}),n("should return an error when the network client throws",async()=>{e.get.mockRejectedValue(new Error("network"));const o=await a.getTransactionDescriptorsPayload({templateId:t});r(o).toEqual(i(new Error("[ContextModule] HttpSolanaLifiDataSource: Failed to fetch transaction descriptors")))})});
2
2
  //# sourceMappingURL=HttpSolanaLifiDataSource.test.js.map
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "version": 3,
3
3
  "sources": ["../../../../../src/solanaLifi/data/HttpSolanaLifiDataSource.test.ts"],
4
- "sourcesContent": ["/* eslint-disable @typescript-eslint/no-explicit-any */\n/* eslint-disable @typescript-eslint/no-unsafe-assignment */\nimport axios from \"axios\";\nimport { Left, Right } from \"purify-ts\";\nimport { beforeAll, beforeEach, describe, expect, it, vi } from \"vitest\";\n\nimport { type ContextModuleConfig } from \"@/config/model/ContextModuleConfig\";\nimport { LEDGER_CLIENT_VERSION_HEADER } from \"@/shared/constant/HttpHeaders\";\nimport PACKAGE from \"@root/package.json\";\n\nimport { HttpSolanaLifiDataSource } from \"./HttpSolanaLifiDataSource\";\nimport {\n type GetTransactionDescriptorsResponse,\n type SolanaLifiDataSource,\n} from \"./SolanaLifiDataSource\";\n\nvi.mock(\"axios\");\n\nconst mockLoggerFactory = () => ({\n debug: vi.fn(),\n info: vi.fn(),\n warn: vi.fn(),\n error: vi.fn(),\n subscribers: [],\n});\n\ndescribe(\"HttpSolanaLifiDataSource\", () => {\n let datasource: SolanaLifiDataSource;\n const templateId = \"tpl-123\";\n const config: ContextModuleConfig = {\n cal: {\n url: \"https://crypto-assets-service.api.ledger.com/v1\",\n mode: \"prod\",\n branch: \"main\",\n },\n } as ContextModuleConfig;\n\n beforeAll(() => {\n datasource = new HttpSolanaLifiDataSource(config, mockLoggerFactory);\n });\n\n beforeEach(() => {\n vi.clearAllMocks();\n });\n\n it(\"should call axios with the ledger client version header and correct params\", async () => {\n // given\n const requestSpy = vi.fn(() => Promise.resolve({ data: [] }));\n vi.spyOn(axios, \"request\").mockImplementation(requestSpy);\n\n // when\n await datasource.getTransactionDescriptorsPayload({ templateId });\n\n // then\n expect(requestSpy).toHaveBeenCalledTimes(1);\n expect(requestSpy).toHaveBeenCalledWith(\n expect.objectContaining({\n method: \"GET\",\n url: `${config.cal.url}/swap_templates`,\n params: {\n id: templateId,\n output: \"id,chain_id,instructions,descriptors\",\n },\n headers: {\n [LEDGER_CLIENT_VERSION_HEADER]: `context-module/${PACKAGE.version}`,\n },\n }),\n );\n });\n\n it(\"should return Right(data[0]) when axios responds with a non-empty array\", async () => {\n // given\n const response0: GetTransactionDescriptorsResponse = {\n descriptors: {\n swap: { programId: \"SwapProgram\", accounts: [], data: \"abcd\" } as any,\n },\n } as any;\n\n vi.spyOn(axios, \"request\").mockResolvedValue({ data: [response0] });\n\n // when\n const result = await datasource.getTransactionDescriptorsPayload({\n templateId,\n });\n\n // then\n expect(result).toEqual(Right(response0));\n });\n\n it(\"should return an error when data is undefined\", async () => {\n // given\n vi.spyOn(axios, \"request\").mockResolvedValue({ data: undefined });\n\n // when\n const result = await datasource.getTransactionDescriptorsPayload({\n templateId,\n });\n\n // then\n expect(result).toEqual(\n Left(\n new Error(\n `[ContextModule] HttpSolanaLifiDataSource: no transaction descriptors for id ${templateId}`,\n ),\n ),\n );\n });\n\n it(\"should return an error when data array is empty\", async () => {\n // given\n vi.spyOn(axios, \"request\").mockResolvedValue({ data: [] });\n\n // when\n const result = await datasource.getTransactionDescriptorsPayload({\n templateId,\n });\n\n // then\n expect(result).toEqual(\n Left(\n new Error(\n `[ContextModule] HttpSolanaLifiDataSource: no transaction descriptors for id ${templateId}`,\n ),\n ),\n );\n });\n\n it(\"should return an error when first element is falsy\", async () => {\n // given\n vi.spyOn(axios, \"request\").mockResolvedValue({ data: [undefined] });\n\n // when\n const result = await datasource.getTransactionDescriptorsPayload({\n templateId,\n });\n\n // then\n expect(result).toEqual(\n Left(\n new Error(\n `[ContextModule] HttpSolanaLifiDataSource: no transaction descriptors for id ${templateId}`,\n ),\n ),\n );\n });\n\n it(\"should return an error when axios throws\", async () => {\n // given\n vi.spyOn(axios, \"request\").mockRejectedValue(new Error(\"network\"));\n\n // when\n const result = await datasource.getTransactionDescriptorsPayload({\n templateId,\n });\n\n // then\n expect(result).toEqual(\n Left(\n new Error(\n \"[ContextModule] HttpSolanaLifiDataSource: Failed to fetch transaction descriptors\",\n ),\n ),\n );\n });\n});\n"],
5
- "mappings": "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",
6
- "names": ["axios", "Left", "Right", "beforeAll", "beforeEach", "describe", "expect", "it", "vi", "LEDGER_CLIENT_VERSION_HEADER", "PACKAGE", "HttpSolanaLifiDataSource", "mockLoggerFactory", "datasource", "templateId", "config", "requestSpy", "response0", "result"]
4
+ "sourcesContent": ["/* eslint-disable @typescript-eslint/no-explicit-any */\n/* eslint-disable @typescript-eslint/no-unsafe-assignment */\nimport { type DmkNetworkClient } from \"@ledgerhq/device-management-kit\";\nimport { Left, Right } from \"purify-ts\";\nimport { beforeEach, describe, expect, it, vi } from \"vitest\";\n\nimport { type ContextModuleServiceConfig } from \"@/config/model/ContextModuleConfig\";\n\nimport { HttpSolanaLifiDataSource } from \"./HttpSolanaLifiDataSource\";\nimport {\n type GetTransactionDescriptorsResponse,\n type SolanaLifiDataSource,\n} from \"./SolanaLifiDataSource\";\n\nconst mockLoggerFactory = () => ({\n debug: vi.fn(),\n info: vi.fn(),\n warn: vi.fn(),\n error: vi.fn(),\n subscribers: [],\n});\n\ndescribe(\"HttpSolanaLifiDataSource\", () => {\n let datasource: SolanaLifiDataSource;\n let httpMock: { get: ReturnType<typeof vi.fn> };\n const templateId = \"tpl-123\";\n const config: ContextModuleServiceConfig = {\n cal: {\n url: \"https://crypto-assets-service.api.ledger.com/v1\",\n mode: \"prod\",\n branch: \"main\",\n },\n } as ContextModuleServiceConfig;\n\n beforeEach(() => {\n vi.clearAllMocks();\n httpMock = { get: vi.fn() };\n datasource = new HttpSolanaLifiDataSource(\n config,\n mockLoggerFactory,\n httpMock as unknown as DmkNetworkClient,\n );\n });\n\n it(\"should call the network client with the expected URL and params\", async () => {\n // given\n httpMock.get.mockResolvedValue([]);\n\n // when\n await datasource.getTransactionDescriptorsPayload({ templateId });\n\n // then\n expect(httpMock.get).toHaveBeenCalledTimes(1);\n expect(httpMock.get).toHaveBeenCalledWith(\n \"https://crypto-assets-service.api.ledger.com/v1/swap_templates\",\n {\n params: {\n template_id: templateId,\n output: \"id,chain_id,instructions,descriptors\",\n ref: \"ref=commit:866b6e7633a7a806fab7f9941bcc3df7ee640784\",\n },\n },\n );\n });\n\n it(\"should return Right(data[0]) when the network client responds with a non-empty array\", async () => {\n // given\n const response0: GetTransactionDescriptorsResponse = {\n descriptors: {\n swap: { programId: \"SwapProgram\", accounts: [], data: \"abcd\" } as any,\n },\n } as any;\n\n httpMock.get.mockResolvedValue([response0]);\n\n // when\n const result = await datasource.getTransactionDescriptorsPayload({\n templateId,\n });\n\n // then\n expect(result).toEqual(Right(response0));\n });\n\n it(\"should return an error when data is undefined\", async () => {\n // given\n httpMock.get.mockResolvedValue(null);\n\n // when\n const result = await datasource.getTransactionDescriptorsPayload({\n templateId,\n });\n\n // then\n expect(result).toEqual(\n Left(\n new Error(\n `[ContextModule] HttpSolanaLifiDataSource: no transaction descriptors for id ${templateId}`,\n ),\n ),\n );\n });\n\n it(\"should return an error when data array is empty\", async () => {\n // given\n httpMock.get.mockResolvedValue([]);\n\n // when\n const result = await datasource.getTransactionDescriptorsPayload({\n templateId,\n });\n\n // then\n expect(result).toEqual(\n Left(\n new Error(\n `[ContextModule] HttpSolanaLifiDataSource: no transaction descriptors for id ${templateId}`,\n ),\n ),\n );\n });\n\n it(\"should return an error when first element is falsy\", async () => {\n // given\n httpMock.get.mockResolvedValue([null]);\n\n // when\n const result = await datasource.getTransactionDescriptorsPayload({\n templateId,\n });\n\n // then\n expect(result).toEqual(\n Left(\n new Error(\n `[ContextModule] HttpSolanaLifiDataSource: no transaction descriptors for id ${templateId}`,\n ),\n ),\n );\n });\n\n it(\"should return an error when the network client throws\", async () => {\n // given\n httpMock.get.mockRejectedValue(new Error(\"network\"));\n\n // when\n const result = await datasource.getTransactionDescriptorsPayload({\n templateId,\n });\n\n // then\n expect(result).toEqual(\n Left(\n new Error(\n \"[ContextModule] HttpSolanaLifiDataSource: Failed to fetch transaction descriptors\",\n ),\n ),\n );\n });\n});\n"],
5
+ "mappings": "AAGA,OAAS,QAAAA,EAAM,SAAAC,MAAa,YAC5B,OAAS,cAAAC,EAAY,YAAAC,EAAU,UAAAC,EAAQ,MAAAC,EAAI,MAAAC,MAAU,SAIrD,OAAS,4BAAAC,MAAgC,6BAMzC,MAAMC,EAAoB,KAAO,CAC/B,MAAOF,EAAG,GAAG,EACb,KAAMA,EAAG,GAAG,EACZ,KAAMA,EAAG,GAAG,EACZ,MAAOA,EAAG,GAAG,EACb,YAAa,CAAC,CAChB,GAEAH,EAAS,2BAA4B,IAAM,CACzC,IAAIM,EACAC,EACJ,MAAMC,EAAa,UACbC,EAAqC,CACzC,IAAK,CACH,IAAK,kDACL,KAAM,OACN,OAAQ,MACV,CACF,EAEAV,EAAW,IAAM,CACfI,EAAG,cAAc,EACjBI,EAAW,CAAE,IAAKJ,EAAG,GAAG,CAAE,EAC1BG,EAAa,IAAIF,EACfK,EACAJ,EACAE,CACF,CACF,CAAC,EAEDL,EAAG,kEAAmE,SAAY,CAEhFK,EAAS,IAAI,kBAAkB,CAAC,CAAC,EAGjC,MAAMD,EAAW,iCAAiC,CAAE,WAAAE,CAAW,CAAC,EAGhEP,EAAOM,EAAS,GAAG,EAAE,sBAAsB,CAAC,EAC5CN,EAAOM,EAAS,GAAG,EAAE,qBACnB,iEACA,CACE,OAAQ,CACN,YAAaC,EACb,OAAQ,uCACR,IAAK,qDACP,CACF,CACF,CACF,CAAC,EAEDN,EAAG,uFAAwF,SAAY,CAErG,MAAMQ,EAA+C,CACnD,YAAa,CACX,KAAM,CAAE,UAAW,cAAe,SAAU,CAAC,EAAG,KAAM,MAAO,CAC/D,CACF,EAEAH,EAAS,IAAI,kBAAkB,CAACG,CAAS,CAAC,EAG1C,MAAMC,EAAS,MAAML,EAAW,iCAAiC,CAC/D,WAAAE,CACF,CAAC,EAGDP,EAAOU,CAAM,EAAE,QAAQb,EAAMY,CAAS,CAAC,CACzC,CAAC,EAEDR,EAAG,gDAAiD,SAAY,CAE9DK,EAAS,IAAI,kBAAkB,IAAI,EAGnC,MAAMI,EAAS,MAAML,EAAW,iCAAiC,CAC/D,WAAAE,CACF,CAAC,EAGDP,EAAOU,CAAM,EAAE,QACbd,EACE,IAAI,MACF,+EAA+EW,CAAU,EAC3F,CACF,CACF,CACF,CAAC,EAEDN,EAAG,kDAAmD,SAAY,CAEhEK,EAAS,IAAI,kBAAkB,CAAC,CAAC,EAGjC,MAAMI,EAAS,MAAML,EAAW,iCAAiC,CAC/D,WAAAE,CACF,CAAC,EAGDP,EAAOU,CAAM,EAAE,QACbd,EACE,IAAI,MACF,+EAA+EW,CAAU,EAC3F,CACF,CACF,CACF,CAAC,EAEDN,EAAG,qDAAsD,SAAY,CAEnEK,EAAS,IAAI,kBAAkB,CAAC,IAAI,CAAC,EAGrC,MAAMI,EAAS,MAAML,EAAW,iCAAiC,CAC/D,WAAAE,CACF,CAAC,EAGDP,EAAOU,CAAM,EAAE,QACbd,EACE,IAAI,MACF,+EAA+EW,CAAU,EAC3F,CACF,CACF,CACF,CAAC,EAEDN,EAAG,wDAAyD,SAAY,CAEtEK,EAAS,IAAI,kBAAkB,IAAI,MAAM,SAAS,CAAC,EAGnD,MAAMI,EAAS,MAAML,EAAW,iCAAiC,CAC/D,WAAAE,CACF,CAAC,EAGDP,EAAOU,CAAM,EAAE,QACbd,EACE,IAAI,MACF,mFACF,CACF,CACF,CACF,CAAC,CACH,CAAC",
6
+ "names": ["Left", "Right", "beforeEach", "describe", "expect", "it", "vi", "HttpSolanaLifiDataSource", "mockLoggerFactory", "datasource", "httpMock", "templateId", "config", "response0", "result"]
7
7
  }
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "version": 3,
3
3
  "sources": ["../../../../../src/solanaLifi/domain/SolanaLifiContextLoader.ts"],
4
- "sourcesContent": ["import { LoggerPublisherService } from \"@ledgerhq/device-management-kit\";\nimport { inject, injectable } from \"inversify\";\n\nimport { configTypes } from \"@/config/di/configTypes\";\nimport { type ContextModuleConfig } from \"@/config/model/ContextModuleConfig\";\nimport { pkiTypes } from \"@/pki/di/pkiTypes\";\nimport { type PkiCertificateLoader } from \"@/pki/domain/PkiCertificateLoader\";\nimport { KeyId } from \"@/pki/model/KeyId\";\nimport { KeyUsage } from \"@/pki/model/KeyUsage\";\nimport { type PkiCertificate } from \"@/pki/model/PkiCertificate\";\nimport { ContextFieldLoader } from \"@/shared/domain/ContextFieldLoader\";\nimport {\n SolanaContextTypes,\n SolanaLifiContextResult,\n type SolanaLifiInstructionMeta,\n type SolanaLifiPayload,\n SolanaTransactionDescriptorList,\n} from \"@/shared/model/SolanaContextTypes\";\nimport { SolanaTransactionContext } from \"@/solana/domain/solanaContextTypes\";\nimport {\n GetTransactionDescriptorsResponse,\n type SolanaLifiDataSource,\n} from \"@/solanaLifi/data/SolanaLifiDataSource\";\nimport { lifiTypes } from \"@/solanaLifi/di/solanaLifiTypes\";\n\n@injectable()\nexport class SolanaLifiContextLoader\n implements\n ContextFieldLoader<\n SolanaTransactionContext,\n SolanaContextTypes,\n SolanaLifiContextResult\n >\n{\n private logger: LoggerPublisherService;\n\n constructor(\n @inject(lifiTypes.SolanaLifiDataSource)\n private readonly dataSource: SolanaLifiDataSource,\n @inject(configTypes.Config)\n private readonly config: ContextModuleConfig,\n @inject(pkiTypes.PkiCertificateLoader)\n private readonly _certificateLoader: PkiCertificateLoader,\n @inject(configTypes.ContextModuleLoggerFactory)\n loggerFactory: (tag: string) => LoggerPublisherService,\n ) {\n this.logger = loggerFactory(\"SolanaLifiContextLoader\");\n }\n\n public canHandle(\n field: unknown,\n expectedType: SolanaContextTypes,\n ): field is SolanaTransactionContext {\n if (expectedType !== SolanaContextTypes.SOLANA_LIFI) {\n this.logger.debug(\"[canHandle] Skipping, expected type does not match\", {\n data: { expectedType, required: SolanaContextTypes.SOLANA_LIFI },\n });\n return false;\n }\n\n if (typeof field === \"object\" && field !== null && \"templateId\" in field) {\n const templateId = (field as { templateId: unknown }).templateId;\n const isValid = typeof templateId === \"string\" && templateId.length > 0;\n this.logger.debug(\"[canHandle] Field validation result\", {\n data: { templateId, isValid },\n });\n return isValid;\n }\n\n this.logger.debug(\"[canHandle] Field does not contain a valid templateId\", {\n data: { field },\n });\n return false;\n }\n\n public async loadField(\n solanaLifiContextInput: SolanaTransactionContext,\n ): Promise<SolanaLifiContextResult> {\n this.logger.debug(\"[loadField] Loading solana Lifi context\", {\n data: { input: solanaLifiContextInput },\n });\n const { templateId, deviceModelId } = solanaLifiContextInput;\n\n if (!templateId) {\n return {\n type: SolanaContextTypes.ERROR,\n error: new Error(\n \"[ContextModule] SolanaLifiContextLoader: templateId is missing\",\n ),\n };\n }\n\n const payload = await this.dataSource.getTransactionDescriptorsPayload({\n templateId,\n });\n\n const certificate: PkiCertificate | undefined =\n await this._certificateLoader.loadCertificate({\n keyId: KeyId.SwapTemplateKey,\n keyUsage: KeyUsage.SwapTemplate,\n targetDevice: deviceModelId,\n });\n\n return payload.caseOf({\n Left: (error): SolanaLifiContextResult => {\n this.logger.error(\"[loadField] Error loading solana Lifi context\", {\n data: { error },\n });\n\n return {\n type: SolanaContextTypes.ERROR,\n error,\n };\n },\n Right: (value): SolanaLifiContextResult => {\n const lifiPayload = this.buildPayload(value);\n this.logger.debug(\n \"[loadField] Successfully loaded solana Lifi context\",\n {\n data: {\n descriptors: lifiPayload.descriptors,\n instructionsCount: lifiPayload.instructions.length,\n certificate,\n },\n },\n );\n\n return {\n type: SolanaContextTypes.SOLANA_LIFI,\n payload: lifiPayload,\n certificate,\n };\n },\n });\n }\n\n private buildPayload(\n response: GetTransactionDescriptorsResponse,\n ): SolanaLifiPayload {\n return {\n descriptors: this.pluckTransactionData(response),\n instructions: this.extractInstructionsMeta(response),\n };\n }\n\n private pluckTransactionData(\n tokenData: GetTransactionDescriptorsResponse,\n ): SolanaTransactionDescriptorList {\n const signatureKind = this.config.cal.mode || \"prod\";\n const output: SolanaTransactionDescriptorList = {};\n const descriptors = tokenData.descriptors ?? [];\n\n this.logger.debug(\"[pluckTransactionData] Processing descriptors\", {\n data: { descriptorsCount: descriptors.length, signatureKind },\n });\n\n for (const item of descriptors) {\n const key = `${item.program_id}:${item.discriminator_hex ?? \"\"}`;\n output[key] = {\n data: item.descriptor.data,\n descriptorType: item.descriptor.descriptorType,\n descriptorVersion: item.descriptor.descriptorVersion,\n signature: item.descriptor.signatures[signatureKind] ?? \"\",\n };\n this.logger.debug(\"[pluckTransactionData] Mapped program descriptor\", {\n data: {\n programId: item.program_id,\n discriminatorHex: item.discriminator_hex ?? \"\",\n key,\n },\n });\n }\n\n this.logger.debug(\"[pluckTransactionData] Completed processing\", {\n data: { outputKeys: Object.keys(output) },\n });\n\n return output;\n }\n\n private extractInstructionsMeta(\n response: GetTransactionDescriptorsResponse,\n ): SolanaLifiInstructionMeta[] {\n const instructions = response.instructions ?? [];\n\n this.logger.debug(\n \"[extractInstructionsMeta] Extracting instructions metadata\",\n {\n data: { instructionsCount: instructions.length },\n },\n );\n\n const meta = instructions.map((ix) => ({\n program_id: ix.program_id,\n ...(ix.discriminator_hex !== undefined && {\n discriminator_hex: ix.discriminator_hex,\n }),\n }));\n\n this.logger.debug(\n \"[extractInstructionsMeta] Completed extracting instructions metadata\",\n {\n data: {\n meta: meta.map((m) => ({\n programId: m.program_id,\n discriminatorHex: m.discriminator_hex,\n })),\n },\n },\n );\n\n return meta;\n }\n}\n"],
4
+ "sourcesContent": ["import { LoggerPublisherService } from \"@ledgerhq/device-management-kit\";\nimport { inject, injectable } from \"inversify\";\n\nimport { configTypes } from \"@/config/di/configTypes\";\nimport { type ContextModuleServiceConfig } from \"@/config/model/ContextModuleConfig\";\nimport { pkiTypes } from \"@/pki/di/pkiTypes\";\nimport { type PkiCertificateLoader } from \"@/pki/domain/PkiCertificateLoader\";\nimport { KeyId } from \"@/pki/model/KeyId\";\nimport { KeyUsage } from \"@/pki/model/KeyUsage\";\nimport { type PkiCertificate } from \"@/pki/model/PkiCertificate\";\nimport { ContextFieldLoader } from \"@/shared/domain/ContextFieldLoader\";\nimport {\n SolanaContextTypes,\n SolanaLifiContextResult,\n type SolanaLifiInstructionMeta,\n type SolanaLifiPayload,\n SolanaTransactionDescriptorList,\n} from \"@/shared/model/SolanaContextTypes\";\nimport { SolanaTransactionContext } from \"@/solana/domain/solanaContextTypes\";\nimport {\n GetTransactionDescriptorsResponse,\n type SolanaLifiDataSource,\n} from \"@/solanaLifi/data/SolanaLifiDataSource\";\nimport { lifiTypes } from \"@/solanaLifi/di/solanaLifiTypes\";\n\n@injectable()\nexport class SolanaLifiContextLoader\n implements\n ContextFieldLoader<\n SolanaTransactionContext,\n SolanaContextTypes,\n SolanaLifiContextResult\n >\n{\n private logger: LoggerPublisherService;\n\n constructor(\n @inject(lifiTypes.SolanaLifiDataSource)\n private readonly dataSource: SolanaLifiDataSource,\n @inject(configTypes.Config)\n private readonly config: ContextModuleServiceConfig,\n @inject(pkiTypes.PkiCertificateLoader)\n private readonly _certificateLoader: PkiCertificateLoader,\n @inject(configTypes.ContextModuleLoggerFactory)\n loggerFactory: (tag: string) => LoggerPublisherService,\n ) {\n this.logger = loggerFactory(\"SolanaLifiContextLoader\");\n }\n\n public canHandle(\n field: unknown,\n expectedType: SolanaContextTypes,\n ): field is SolanaTransactionContext {\n if (expectedType !== SolanaContextTypes.SOLANA_LIFI) {\n this.logger.debug(\"[canHandle] Skipping, expected type does not match\", {\n data: { expectedType, required: SolanaContextTypes.SOLANA_LIFI },\n });\n return false;\n }\n\n if (typeof field === \"object\" && field !== null && \"templateId\" in field) {\n const templateId = (field as { templateId: unknown }).templateId;\n const isValid = typeof templateId === \"string\" && templateId.length > 0;\n this.logger.debug(\"[canHandle] Field validation result\", {\n data: { templateId, isValid },\n });\n return isValid;\n }\n\n this.logger.debug(\"[canHandle] Field does not contain a valid templateId\", {\n data: { field },\n });\n return false;\n }\n\n public async loadField(\n solanaLifiContextInput: SolanaTransactionContext,\n ): Promise<SolanaLifiContextResult> {\n this.logger.debug(\"[loadField] Loading solana Lifi context\", {\n data: { input: solanaLifiContextInput },\n });\n const { templateId, deviceModelId } = solanaLifiContextInput;\n\n if (!templateId) {\n return {\n type: SolanaContextTypes.ERROR,\n error: new Error(\n \"[ContextModule] SolanaLifiContextLoader: templateId is missing\",\n ),\n };\n }\n\n const payload = await this.dataSource.getTransactionDescriptorsPayload({\n templateId,\n });\n\n const certificate: PkiCertificate | undefined =\n await this._certificateLoader.loadCertificate({\n keyId: KeyId.SwapTemplateKey,\n keyUsage: KeyUsage.SwapTemplate,\n targetDevice: deviceModelId,\n });\n\n return payload.caseOf({\n Left: (error): SolanaLifiContextResult => {\n this.logger.error(\"[loadField] Error loading solana Lifi context\", {\n data: { error },\n });\n\n return {\n type: SolanaContextTypes.ERROR,\n error,\n };\n },\n Right: (value): SolanaLifiContextResult => {\n const lifiPayload = this.buildPayload(value);\n this.logger.debug(\n \"[loadField] Successfully loaded solana Lifi context\",\n {\n data: {\n descriptors: lifiPayload.descriptors,\n instructionsCount: lifiPayload.instructions.length,\n certificate,\n },\n },\n );\n\n return {\n type: SolanaContextTypes.SOLANA_LIFI,\n payload: lifiPayload,\n certificate,\n };\n },\n });\n }\n\n private buildPayload(\n response: GetTransactionDescriptorsResponse,\n ): SolanaLifiPayload {\n return {\n descriptors: this.pluckTransactionData(response),\n instructions: this.extractInstructionsMeta(response),\n };\n }\n\n private pluckTransactionData(\n tokenData: GetTransactionDescriptorsResponse,\n ): SolanaTransactionDescriptorList {\n const signatureKind = this.config.cal.mode || \"prod\";\n const output: SolanaTransactionDescriptorList = {};\n const descriptors = tokenData.descriptors ?? [];\n\n this.logger.debug(\"[pluckTransactionData] Processing descriptors\", {\n data: { descriptorsCount: descriptors.length, signatureKind },\n });\n\n for (const item of descriptors) {\n const key = `${item.program_id}:${item.discriminator_hex ?? \"\"}`;\n output[key] = {\n data: item.descriptor.data,\n descriptorType: item.descriptor.descriptorType,\n descriptorVersion: item.descriptor.descriptorVersion,\n signature: item.descriptor.signatures[signatureKind] ?? \"\",\n };\n this.logger.debug(\"[pluckTransactionData] Mapped program descriptor\", {\n data: {\n programId: item.program_id,\n discriminatorHex: item.discriminator_hex ?? \"\",\n key,\n },\n });\n }\n\n this.logger.debug(\"[pluckTransactionData] Completed processing\", {\n data: { outputKeys: Object.keys(output) },\n });\n\n return output;\n }\n\n private extractInstructionsMeta(\n response: GetTransactionDescriptorsResponse,\n ): SolanaLifiInstructionMeta[] {\n const instructions = response.instructions ?? [];\n\n this.logger.debug(\n \"[extractInstructionsMeta] Extracting instructions metadata\",\n {\n data: { instructionsCount: instructions.length },\n },\n );\n\n const meta = instructions.map((ix) => ({\n program_id: ix.program_id,\n ...(ix.discriminator_hex !== undefined && {\n discriminator_hex: ix.discriminator_hex,\n }),\n }));\n\n this.logger.debug(\n \"[extractInstructionsMeta] Completed extracting instructions metadata\",\n {\n data: {\n meta: meta.map((m) => ({\n programId: m.program_id,\n discriminatorHex: m.discriminator_hex,\n })),\n },\n },\n );\n\n return meta;\n }\n}\n"],
5
5
  "mappings": "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",
6
6
  "names": ["inject", "injectable", "configTypes", "pkiTypes", "KeyId", "KeyUsage", "SolanaContextTypes", "lifiTypes", "SolanaLifiContextLoader", "dataSource", "config", "_certificateLoader", "loggerFactory", "field", "expectedType", "SolanaContextTypes", "templateId", "isValid", "solanaLifiContextInput", "deviceModelId", "payload", "certificate", "KeyId", "KeyUsage", "error", "value", "lifiPayload", "response", "tokenData", "signatureKind", "output", "descriptors", "item", "key", "instructions", "meta", "ix", "m", "__decorateClass", "injectable", "__decorateParam", "inject", "lifiTypes", "configTypes", "pkiTypes"]
7
7
  }
@@ -1,2 +1,2 @@
1
- import{Left as L,Right as _}from"purify-ts";import{beforeEach as x,describe as p,expect as e,it as n,vi as c}from"vitest";import{SolanaContextTypes as m}from"../../shared/model/SolanaContextTypes";import{SolanaLifiContextLoader as T}from"./SolanaLifiContextLoader";const h=()=>({debug:c.fn(),info:c.fn(),warn:c.fn(),error:c.fn(),subscribers:[]}),y={keyUsageNumber:13,payload:new Uint8Array([1,2])},S={cal:{url:"https://crypto-assets-service.api.ledger.com",mode:"test",branch:"main"}};p("SolanaLifiContextLoader",()=>{let d,u;const i=(r,a="deadbeef")=>({data:r,descriptorType:"swap_template",descriptorVersion:"v1",signatures:{test:a,prod:`prod_${a}`}}),g=(r,a="deadbeef")=>({data:r,descriptorType:"swap_template",descriptorVersion:"v1",signature:a}),k=[{program_id:"SomeProgram",discriminator_hex:"1",descriptor:i("abc123")},{program_id:"AnotherProgram",descriptor:i("def456")}],b={"SomeProgram:1":g("abc123"),"AnotherProgram:":g("def456")},l={id:"tpl-1",chain_id:101,instructions:[{program_id:"SomeProgram",discriminator:1,discriminator_hex:"1"},{program_id:"AnotherProgram"}],descriptors:k};x(()=>{c.restoreAllMocks(),d={getTransactionDescriptorsPayload:c.fn()},u={loadCertificate:c.fn().mockResolvedValue(y)}});const s=()=>new T(d,S,u,h);p("canHandle",()=>{n("returns true when templateId is provided",()=>{const r=s();e(r.canHandle({templateId:"tpl-123",deviceModelId:"nanoS"},m.SOLANA_LIFI)).toBe(!0)}),n("returns false when templateId is missing or falsy",()=>{const r=s();e(r.canHandle({templateId:""},m.SOLANA_LIFI)).toBe(!1),e(r.canHandle({templateId:void 0},m.SOLANA_LIFI)).toBe(!1),e(r.canHandle({},m.SOLANA_LIFI)).toBe(!1)})}),p("loadField",()=>{n("returns an error when datasource returns Left(error)",async()=>{const r=s(),a=new Error("boom");c.spyOn(d,"getTransactionDescriptorsPayload").mockResolvedValue(L(a));const o={templateId:"tpl-err",deviceModelId:"nanoS"},t=await r.loadField(o);e(d.getTransactionDescriptorsPayload).toHaveBeenCalledWith({templateId:"tpl-err"}),e(t).toEqual({type:m.ERROR,error:a})}),n("returns SOLANA_LIFI with plucked descriptors and certificate when datasource returns Right(value)",async()=>{const r=s();c.spyOn(d,"getTransactionDescriptorsPayload").mockResolvedValue(_(l));const a={templateId:"tpl-ok",deviceModelId:"nanoS"},o=await r.loadField(a);e(d.getTransactionDescriptorsPayload).toHaveBeenCalledWith({templateId:"tpl-ok"}),e(u.loadCertificate).toHaveBeenCalledWith({keyId:"swap_template_key",keyUsage:"swap_template",targetDevice:"nanoS"}),e(o).toEqual({type:m.SOLANA_LIFI,payload:{descriptors:b,instructions:[{program_id:"SomeProgram",discriminator_hex:"1"},{program_id:"AnotherProgram"}]},certificate:y})})}),p("pluckTransactionData (private)",()=>{n("returns a map keyed by `${program_id}:${discriminator_hex ?? '0'}`",()=>{const r=s(),o=r.pluckTransactionData.bind(r)(l);e(o).toEqual(b)})}),p("extractInstructionsMeta (private)",()=>{n("returns instruction metadata from the API response",()=>{const r=s(),o=r.extractInstructionsMeta.bind(r)(l);e(o).toEqual([{program_id:"SomeProgram",discriminator_hex:"1"},{program_id:"AnotherProgram"}])}),n("returns empty array when instructions are missing",()=>{const r=s(),o=r.extractInstructionsMeta.bind(r)({...l,instructions:void 0});e(o).toEqual([])})}),p("pluckTransactionData mode resolution (private)",()=>{n("resolves signature using config.cal.mode",()=>{const r=s(),o=r.pluckTransactionData.bind(r)(l);e(o["SomeProgram:1"]?.signature).toBe("deadbeef")})}),p("real CAL payload (LiFi template 4c694669)",()=>{const r={id:"4c694669",chain_id:101,instructions:[{program_id:"ATokenGPvbdGVxr1b2hvZbsiqW5xWH25efTNsLJA8knL",discriminator:1,discriminator_hex:"1"},{program_id:"11111111111111111111111111111111",discriminator:2,discriminator_hex:"2"},{program_id:"JUP6LkbZbjS1jKKwapdHNy74zcZ3tLUZoi5QNyVTaV4",discriminator:0x2aade37a97cb1800,discriminator_hex:"2aade37a97cb17e0"},{program_id:"JUP6LkbZbjS1jKKwapdHNy74zcZ3tLUZoi5QNyVTaV4",discriminator:9339575302786589e3,discriminator_hex:"819cd641339b2148"},{program_id:"MemoSq4gqABAXKb96qnH8TysNcWxMyWCqXgDLGmfcHr"},{program_id:"ATokenGPvbdGVxr1b2hvZbsiqW5xWH25efTNsLJA8knL",discriminator:1,discriminator_hex:"1"},{program_id:"3i5JeuZuUxeKtVysUnwQNGerJP2bSMX9fTFfS4Nxe3Br"},{program_id:"ComputeBudget111111111111111111111111111111",discriminator:2,discriminator_hex:"2"},{program_id:"ComputeBudget111111111111111111111111111111",discriminator:3,discriminator_hex:"3"},{program_id:"TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA",discriminator:3,discriminator_hex:"3"},{program_id:"TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA",discriminator:17,discriminator_hex:"11"},{program_id:"BrdgN2RPzEMWF96ZbnnJaUtQDQx7VRXYaHHbYCBvceWB"}],descriptors:[{program_id:"ATokenGPvbdGVxr1b2hvZbsiqW5xWH25efTNsLJA8knL",discriminator_hex:"1",descriptor:i("atoken_1","sig_atoken")},{program_id:"11111111111111111111111111111111",discriminator_hex:"2",descriptor:i("system_2","sig_system")},{program_id:"JUP6LkbZbjS1jKKwapdHNy74zcZ3tLUZoi5QNyVTaV4",discriminator_hex:"2aade37a97cb17e0",descriptor:i("jup_route","sig_jup_route")},{program_id:"JUP6LkbZbjS1jKKwapdHNy74zcZ3tLUZoi5QNyVTaV4",discriminator_hex:"819cd641339b2148",descriptor:i("jup_shared","sig_jup_shared")},{program_id:"MemoSq4gqABAXKb96qnH8TysNcWxMyWCqXgDLGmfcHr",descriptor:i("memo","sig_memo")},{program_id:"ATokenGPvbdGVxr1b2hvZbsiqW5xWH25efTNsLJA8knL",discriminator_hex:"1",descriptor:i("atoken_1","sig_atoken")},{program_id:"3i5JeuZuUxeKtVysUnwQNGerJP2bSMX9fTFfS4Nxe3Br",descriptor:i("3i5jeu","sig_3i5jeu")},{program_id:"ComputeBudget111111111111111111111111111111",discriminator_hex:"2",descriptor:i("cb_2","sig_cb2")},{program_id:"ComputeBudget111111111111111111111111111111",discriminator_hex:"3",descriptor:i("cb_3","sig_cb3")},{program_id:"TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA",discriminator_hex:"3",descriptor:i("tokenkeg_3","sig_tk3")},{program_id:"TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA",discriminator_hex:"11",descriptor:i("tokenkeg_11","sig_tk11")},{program_id:"BrdgN2RPzEMWF96ZbnnJaUtQDQx7VRXYaHHbYCBvceWB",descriptor:i("brdg","sig_brdg")}]};n("produces 11 unique descriptor keys (ATokenGP:1 appears twice but deduplicates)",()=>{const a=s(),t=a.pluckTransactionData.bind(a)(r),f=Object.keys(t);e(f).toHaveLength(11)}),n("creates distinct keys for same program_id with different discriminators",()=>{const a=s(),t=a.pluckTransactionData.bind(a)(r);e(t["JUP6LkbZbjS1jKKwapdHNy74zcZ3tLUZoi5QNyVTaV4:2aade37a97cb17e0"]?.data).toBe("jup_route"),e(t["JUP6LkbZbjS1jKKwapdHNy74zcZ3tLUZoi5QNyVTaV4:819cd641339b2148"]?.data).toBe("jup_shared"),e(t["ComputeBudget111111111111111111111111111111:2"]?.data).toBe("cb_2"),e(t["ComputeBudget111111111111111111111111111111:3"]?.data).toBe("cb_3"),e(t["TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA:3"]?.data).toBe("tokenkeg_3"),e(t["TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA:11"]?.data).toBe("tokenkeg_11")}),n("uses :0 suffix for programs without a discriminator",()=>{const a=s(),t=a.pluckTransactionData.bind(a)(r);e(t["MemoSq4gqABAXKb96qnH8TysNcWxMyWCqXgDLGmfcHr:"]?.data).toBe("memo"),e(t["3i5JeuZuUxeKtVysUnwQNGerJP2bSMX9fTFfS4Nxe3Br:"]?.data).toBe("3i5jeu"),e(t["BrdgN2RPzEMWF96ZbnnJaUtQDQx7VRXYaHHbYCBvceWB:"]?.data).toBe("brdg")}),n("extracts 12 instruction metadata entries preserving order and discriminators",()=>{const a=s(),t=a.extractInstructionsMeta.bind(a)(r);e(t).toHaveLength(12),e(t[0]).toEqual({program_id:"ATokenGPvbdGVxr1b2hvZbsiqW5xWH25efTNsLJA8knL",discriminator_hex:"1"}),e(t[2]).toEqual({program_id:"JUP6LkbZbjS1jKKwapdHNy74zcZ3tLUZoi5QNyVTaV4",discriminator_hex:"2aade37a97cb17e0"}),e(t[3]).toEqual({program_id:"JUP6LkbZbjS1jKKwapdHNy74zcZ3tLUZoi5QNyVTaV4",discriminator_hex:"819cd641339b2148"}),e(t[4]).toEqual({program_id:"MemoSq4gqABAXKb96qnH8TysNcWxMyWCqXgDLGmfcHr"}),e(t[11]).toEqual({program_id:"BrdgN2RPzEMWF96ZbnnJaUtQDQx7VRXYaHHbYCBvceWB"})}),n("loadField returns full payload with descriptors and instructions from real API response",async()=>{const a=s();c.spyOn(d,"getTransactionDescriptorsPayload").mockResolvedValue(_(r));const o={templateId:"4c694669",deviceModelId:"nanoS"},t=await a.loadField(o);e(t).toMatchObject({type:m.SOLANA_LIFI,payload:{descriptors:e.objectContaining({"JUP6LkbZbjS1jKKwapdHNy74zcZ3tLUZoi5QNyVTaV4:2aade37a97cb17e0":e.objectContaining({data:"jup_route"}),"JUP6LkbZbjS1jKKwapdHNy74zcZ3tLUZoi5QNyVTaV4:819cd641339b2148":e.objectContaining({data:"jup_shared"})}),instructions:e.arrayContaining([e.objectContaining({program_id:"JUP6LkbZbjS1jKKwapdHNy74zcZ3tLUZoi5QNyVTaV4",discriminator_hex:"2aade37a97cb17e0"}),e.objectContaining({program_id:"JUP6LkbZbjS1jKKwapdHNy74zcZ3tLUZoi5QNyVTaV4",discriminator_hex:"819cd641339b2148"})])}}),e(Object.keys(t.payload.descriptors)).toHaveLength(11),e(t.payload.instructions).toHaveLength(12)})})});
1
+ import{Left as L,Right as _}from"purify-ts";import{beforeEach as x,describe as p,expect as e,it as n,vi as c}from"vitest";import{SolanaContextTypes as m}from"../../shared/model/SolanaContextTypes";import{SolanaLifiContextLoader as S}from"./SolanaLifiContextLoader";const T=()=>({debug:c.fn(),info:c.fn(),warn:c.fn(),error:c.fn(),subscribers:[]}),y={keyUsageNumber:13,payload:new Uint8Array([1,2])},h={cal:{url:"https://crypto-assets-service.api.ledger.com",mode:"test",branch:"main"}};p("SolanaLifiContextLoader",()=>{let d,u;const i=(r,a="deadbeef")=>({data:r,descriptorType:"swap_template",descriptorVersion:"v1",signatures:{test:a,prod:`prod_${a}`}}),g=(r,a="deadbeef")=>({data:r,descriptorType:"swap_template",descriptorVersion:"v1",signature:a}),k=[{program_id:"SomeProgram",discriminator_hex:"1",descriptor:i("abc123")},{program_id:"AnotherProgram",descriptor:i("def456")}],b={"SomeProgram:1":g("abc123"),"AnotherProgram:":g("def456")},l={id:"tpl-1",chain_id:101,instructions:[{program_id:"SomeProgram",discriminator:1,discriminator_hex:"1"},{program_id:"AnotherProgram"}],descriptors:k};x(()=>{c.restoreAllMocks(),d={getTransactionDescriptorsPayload:c.fn()},u={loadCertificate:c.fn().mockResolvedValue(y)}});const s=()=>new S(d,h,u,T);p("canHandle",()=>{n("returns true when templateId is provided",()=>{const r=s();e(r.canHandle({templateId:"tpl-123",deviceModelId:"nanoS"},m.SOLANA_LIFI)).toBe(!0)}),n("returns false when templateId is missing or falsy",()=>{const r=s();e(r.canHandle({templateId:""},m.SOLANA_LIFI)).toBe(!1),e(r.canHandle({templateId:void 0},m.SOLANA_LIFI)).toBe(!1),e(r.canHandle({},m.SOLANA_LIFI)).toBe(!1)})}),p("loadField",()=>{n("returns an error when datasource returns Left(error)",async()=>{const r=s(),a=new Error("boom");c.spyOn(d,"getTransactionDescriptorsPayload").mockResolvedValue(L(a));const o={templateId:"tpl-err",deviceModelId:"nanoS"},t=await r.loadField(o);e(d.getTransactionDescriptorsPayload).toHaveBeenCalledWith({templateId:"tpl-err"}),e(t).toEqual({type:m.ERROR,error:a})}),n("returns SOLANA_LIFI with plucked descriptors and certificate when datasource returns Right(value)",async()=>{const r=s();c.spyOn(d,"getTransactionDescriptorsPayload").mockResolvedValue(_(l));const a={templateId:"tpl-ok",deviceModelId:"nanoS"},o=await r.loadField(a);e(d.getTransactionDescriptorsPayload).toHaveBeenCalledWith({templateId:"tpl-ok"}),e(u.loadCertificate).toHaveBeenCalledWith({keyId:"swap_template_key",keyUsage:"swap_template",targetDevice:"nanoS"}),e(o).toEqual({type:m.SOLANA_LIFI,payload:{descriptors:b,instructions:[{program_id:"SomeProgram",discriminator_hex:"1"},{program_id:"AnotherProgram"}]},certificate:y})})}),p("pluckTransactionData (private)",()=>{n("returns a map keyed by `${program_id}:${discriminator_hex ?? '0'}`",()=>{const r=s(),o=r.pluckTransactionData.bind(r)(l);e(o).toEqual(b)})}),p("extractInstructionsMeta (private)",()=>{n("returns instruction metadata from the API response",()=>{const r=s(),o=r.extractInstructionsMeta.bind(r)(l);e(o).toEqual([{program_id:"SomeProgram",discriminator_hex:"1"},{program_id:"AnotherProgram"}])}),n("returns empty array when instructions are missing",()=>{const r=s(),o=r.extractInstructionsMeta.bind(r)({...l,instructions:void 0});e(o).toEqual([])})}),p("pluckTransactionData mode resolution (private)",()=>{n("resolves signature using config.cal.mode",()=>{const r=s(),o=r.pluckTransactionData.bind(r)(l);e(o["SomeProgram:1"]?.signature).toBe("deadbeef")})}),p("real CAL payload (LiFi template 4c694669)",()=>{const r={id:"4c694669",chain_id:101,instructions:[{program_id:"ATokenGPvbdGVxr1b2hvZbsiqW5xWH25efTNsLJA8knL",discriminator:1,discriminator_hex:"1"},{program_id:"11111111111111111111111111111111",discriminator:2,discriminator_hex:"2"},{program_id:"JUP6LkbZbjS1jKKwapdHNy74zcZ3tLUZoi5QNyVTaV4",discriminator:0x2aade37a97cb1800,discriminator_hex:"2aade37a97cb17e0"},{program_id:"JUP6LkbZbjS1jKKwapdHNy74zcZ3tLUZoi5QNyVTaV4",discriminator:9339575302786589e3,discriminator_hex:"819cd641339b2148"},{program_id:"MemoSq4gqABAXKb96qnH8TysNcWxMyWCqXgDLGmfcHr"},{program_id:"ATokenGPvbdGVxr1b2hvZbsiqW5xWH25efTNsLJA8knL",discriminator:1,discriminator_hex:"1"},{program_id:"3i5JeuZuUxeKtVysUnwQNGerJP2bSMX9fTFfS4Nxe3Br"},{program_id:"ComputeBudget111111111111111111111111111111",discriminator:2,discriminator_hex:"2"},{program_id:"ComputeBudget111111111111111111111111111111",discriminator:3,discriminator_hex:"3"},{program_id:"TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA",discriminator:3,discriminator_hex:"3"},{program_id:"TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA",discriminator:17,discriminator_hex:"11"},{program_id:"BrdgN2RPzEMWF96ZbnnJaUtQDQx7VRXYaHHbYCBvceWB"}],descriptors:[{program_id:"ATokenGPvbdGVxr1b2hvZbsiqW5xWH25efTNsLJA8knL",discriminator_hex:"1",descriptor:i("atoken_1","sig_atoken")},{program_id:"11111111111111111111111111111111",discriminator_hex:"2",descriptor:i("system_2","sig_system")},{program_id:"JUP6LkbZbjS1jKKwapdHNy74zcZ3tLUZoi5QNyVTaV4",discriminator_hex:"2aade37a97cb17e0",descriptor:i("jup_route","sig_jup_route")},{program_id:"JUP6LkbZbjS1jKKwapdHNy74zcZ3tLUZoi5QNyVTaV4",discriminator_hex:"819cd641339b2148",descriptor:i("jup_shared","sig_jup_shared")},{program_id:"MemoSq4gqABAXKb96qnH8TysNcWxMyWCqXgDLGmfcHr",descriptor:i("memo","sig_memo")},{program_id:"ATokenGPvbdGVxr1b2hvZbsiqW5xWH25efTNsLJA8knL",discriminator_hex:"1",descriptor:i("atoken_1","sig_atoken")},{program_id:"3i5JeuZuUxeKtVysUnwQNGerJP2bSMX9fTFfS4Nxe3Br",descriptor:i("3i5jeu","sig_3i5jeu")},{program_id:"ComputeBudget111111111111111111111111111111",discriminator_hex:"2",descriptor:i("cb_2","sig_cb2")},{program_id:"ComputeBudget111111111111111111111111111111",discriminator_hex:"3",descriptor:i("cb_3","sig_cb3")},{program_id:"TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA",discriminator_hex:"3",descriptor:i("tokenkeg_3","sig_tk3")},{program_id:"TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA",discriminator_hex:"11",descriptor:i("tokenkeg_11","sig_tk11")},{program_id:"BrdgN2RPzEMWF96ZbnnJaUtQDQx7VRXYaHHbYCBvceWB",descriptor:i("brdg","sig_brdg")}]};n("produces 11 unique descriptor keys (ATokenGP:1 appears twice but deduplicates)",()=>{const a=s(),t=a.pluckTransactionData.bind(a)(r),f=Object.keys(t);e(f).toHaveLength(11)}),n("creates distinct keys for same program_id with different discriminators",()=>{const a=s(),t=a.pluckTransactionData.bind(a)(r);e(t["JUP6LkbZbjS1jKKwapdHNy74zcZ3tLUZoi5QNyVTaV4:2aade37a97cb17e0"]?.data).toBe("jup_route"),e(t["JUP6LkbZbjS1jKKwapdHNy74zcZ3tLUZoi5QNyVTaV4:819cd641339b2148"]?.data).toBe("jup_shared"),e(t["ComputeBudget111111111111111111111111111111:2"]?.data).toBe("cb_2"),e(t["ComputeBudget111111111111111111111111111111:3"]?.data).toBe("cb_3"),e(t["TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA:3"]?.data).toBe("tokenkeg_3"),e(t["TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA:11"]?.data).toBe("tokenkeg_11")}),n("uses :0 suffix for programs without a discriminator",()=>{const a=s(),t=a.pluckTransactionData.bind(a)(r);e(t["MemoSq4gqABAXKb96qnH8TysNcWxMyWCqXgDLGmfcHr:"]?.data).toBe("memo"),e(t["3i5JeuZuUxeKtVysUnwQNGerJP2bSMX9fTFfS4Nxe3Br:"]?.data).toBe("3i5jeu"),e(t["BrdgN2RPzEMWF96ZbnnJaUtQDQx7VRXYaHHbYCBvceWB:"]?.data).toBe("brdg")}),n("extracts 12 instruction metadata entries preserving order and discriminators",()=>{const a=s(),t=a.extractInstructionsMeta.bind(a)(r);e(t).toHaveLength(12),e(t[0]).toEqual({program_id:"ATokenGPvbdGVxr1b2hvZbsiqW5xWH25efTNsLJA8knL",discriminator_hex:"1"}),e(t[2]).toEqual({program_id:"JUP6LkbZbjS1jKKwapdHNy74zcZ3tLUZoi5QNyVTaV4",discriminator_hex:"2aade37a97cb17e0"}),e(t[3]).toEqual({program_id:"JUP6LkbZbjS1jKKwapdHNy74zcZ3tLUZoi5QNyVTaV4",discriminator_hex:"819cd641339b2148"}),e(t[4]).toEqual({program_id:"MemoSq4gqABAXKb96qnH8TysNcWxMyWCqXgDLGmfcHr"}),e(t[11]).toEqual({program_id:"BrdgN2RPzEMWF96ZbnnJaUtQDQx7VRXYaHHbYCBvceWB"})}),n("loadField returns full payload with descriptors and instructions from real API response",async()=>{const a=s();c.spyOn(d,"getTransactionDescriptorsPayload").mockResolvedValue(_(r));const o={templateId:"4c694669",deviceModelId:"nanoS"},t=await a.loadField(o);e(t).toMatchObject({type:m.SOLANA_LIFI,payload:{descriptors:e.objectContaining({"JUP6LkbZbjS1jKKwapdHNy74zcZ3tLUZoi5QNyVTaV4:2aade37a97cb17e0":e.objectContaining({data:"jup_route"}),"JUP6LkbZbjS1jKKwapdHNy74zcZ3tLUZoi5QNyVTaV4:819cd641339b2148":e.objectContaining({data:"jup_shared"})}),instructions:e.arrayContaining([e.objectContaining({program_id:"JUP6LkbZbjS1jKKwapdHNy74zcZ3tLUZoi5QNyVTaV4",discriminator_hex:"2aade37a97cb17e0"}),e.objectContaining({program_id:"JUP6LkbZbjS1jKKwapdHNy74zcZ3tLUZoi5QNyVTaV4",discriminator_hex:"819cd641339b2148"})])}}),e(Object.keys(t.payload.descriptors)).toHaveLength(11),e(t.payload.instructions).toHaveLength(12)})})});
2
2
  //# sourceMappingURL=SolanaLifiContextLoader.test.js.map
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "version": 3,
3
3
  "sources": ["../../../../../src/solanaLifi/domain/SolanaLifiContextLoader.test.ts"],
4
- "sourcesContent": ["/* eslint-disable @typescript-eslint/no-unsafe-member-access */\n/* eslint-disable @typescript-eslint/no-unsafe-call */\n/* eslint-disable @typescript-eslint/no-unsafe-assignment */\n/* eslint-disable @typescript-eslint/no-explicit-any */\nimport { Left, Right } from \"purify-ts\";\nimport { beforeEach, describe, expect, it, vi } from \"vitest\";\n\nimport { type ContextModuleConfig } from \"@/config/model/ContextModuleConfig\";\nimport { type PkiCertificateLoader } from \"@/pki/domain/PkiCertificateLoader\";\nimport {\n SolanaContextTypes,\n type SolanaTransactionDescriptor,\n type SolanaTransactionDescriptorList,\n type SolanaTransactionDescriptorRaw,\n} from \"@/shared/model/SolanaContextTypes\";\nimport {\n type GetTransactionDescriptorsResponse,\n type SolanaLifiDataSource,\n} from \"@/solanaLifi/data/SolanaLifiDataSource\";\n\nimport { SolanaLifiContextLoader } from \"./SolanaLifiContextLoader\";\n\nconst mockLoggerFactory = () => ({\n debug: vi.fn(),\n info: vi.fn(),\n warn: vi.fn(),\n error: vi.fn(),\n subscribers: [],\n});\n\nconst mockCertificate = {\n keyUsageNumber: 13,\n payload: new Uint8Array([0x01, 0x02]),\n};\n\nconst mockConfig = {\n cal: {\n url: \"https://crypto-assets-service.api.ledger.com\",\n mode: \"test\",\n branch: \"main\",\n },\n} as ContextModuleConfig;\n\ndescribe(\"SolanaLifiContextLoader\", () => {\n let mockDataSource: SolanaLifiDataSource;\n let mockCertificateLoader: PkiCertificateLoader;\n\n const makeRawDescriptor = (\n data: string,\n sig = \"deadbeef\",\n ): SolanaTransactionDescriptorRaw => ({\n data,\n descriptorType: \"swap_template\",\n descriptorVersion: \"v1\",\n signatures: { test: sig, prod: `prod_${sig}` },\n });\n\n const makeResolvedDescriptor = (\n data: string,\n sig = \"deadbeef\",\n ): SolanaTransactionDescriptor => ({\n data,\n descriptorType: \"swap_template\",\n descriptorVersion: \"v1\",\n signature: sig,\n });\n\n const responseDescriptorsArray: GetTransactionDescriptorsResponse[\"descriptors\"] =\n [\n {\n program_id: \"SomeProgram\",\n discriminator_hex: \"1\",\n descriptor: makeRawDescriptor(\"abc123\"),\n },\n {\n program_id: \"AnotherProgram\",\n // discriminator_hex intentionally omitted -> defaults to \"\"\n descriptor: makeRawDescriptor(\"def456\"),\n },\n ];\n\n const expectedPlucked: SolanaTransactionDescriptorList = {\n \"SomeProgram:1\": makeResolvedDescriptor(\"abc123\"),\n \"AnotherProgram:\": makeResolvedDescriptor(\"def456\"),\n };\n\n const responseInstructionsArray: GetTransactionDescriptorsResponse[\"instructions\"] =\n [\n {\n program_id: \"SomeProgram\",\n discriminator: 1,\n discriminator_hex: \"1\",\n },\n {\n program_id: \"AnotherProgram\",\n // discriminator_hex intentionally omitted\n },\n ];\n\n const txDescriptorsResponse: GetTransactionDescriptorsResponse = {\n id: \"tpl-1\",\n chain_id: 101,\n instructions: responseInstructionsArray,\n descriptors: responseDescriptorsArray,\n };\n\n beforeEach(() => {\n vi.restoreAllMocks();\n mockDataSource = {\n getTransactionDescriptorsPayload: vi.fn(),\n } as unknown as SolanaLifiDataSource;\n mockCertificateLoader = {\n loadCertificate: vi.fn().mockResolvedValue(mockCertificate),\n } as unknown as PkiCertificateLoader;\n });\n\n const makeLoader = () =>\n new SolanaLifiContextLoader(\n mockDataSource,\n mockConfig,\n mockCertificateLoader,\n mockLoggerFactory,\n );\n\n describe(\"canHandle\", () => {\n it(\"returns true when templateId is provided\", () => {\n const loader = makeLoader();\n\n expect(\n loader.canHandle(\n {\n templateId: \"tpl-123\",\n deviceModelId: \"nanoS\" as any,\n },\n SolanaContextTypes.SOLANA_LIFI,\n ),\n ).toBe(true);\n });\n\n it(\"returns false when templateId is missing or falsy\", () => {\n const loader = makeLoader();\n\n expect(\n loader.canHandle(\n { templateId: \"\" } as any,\n SolanaContextTypes.SOLANA_LIFI,\n ),\n ).toBe(false);\n expect(\n loader.canHandle(\n { templateId: undefined } as any,\n SolanaContextTypes.SOLANA_LIFI,\n ),\n ).toBe(false);\n expect(loader.canHandle({} as any, SolanaContextTypes.SOLANA_LIFI)).toBe(\n false,\n );\n });\n });\n\n describe(\"loadField\", () => {\n it(\"returns an error when datasource returns Left(error)\", async () => {\n const loader = makeLoader();\n const error = new Error(\"boom\");\n\n vi.spyOn(\n mockDataSource,\n \"getTransactionDescriptorsPayload\",\n ).mockResolvedValue(Left(error));\n\n const input = { templateId: \"tpl-err\", deviceModelId: \"nanoS\" as any };\n const result = await loader.loadField(input);\n\n expect(\n mockDataSource.getTransactionDescriptorsPayload,\n ).toHaveBeenCalledWith({\n templateId: \"tpl-err\",\n });\n\n expect(result).toEqual({\n type: SolanaContextTypes.ERROR,\n error,\n });\n });\n\n it(\"returns SOLANA_LIFI with plucked descriptors and certificate when datasource returns Right(value)\", async () => {\n const loader = makeLoader();\n\n vi.spyOn(\n mockDataSource,\n \"getTransactionDescriptorsPayload\",\n ).mockResolvedValue(Right(txDescriptorsResponse));\n\n const input = { templateId: \"tpl-ok\", deviceModelId: \"nanoS\" as any };\n const result = await loader.loadField(input);\n\n expect(\n mockDataSource.getTransactionDescriptorsPayload,\n ).toHaveBeenCalledWith({\n templateId: \"tpl-ok\",\n });\n\n expect(mockCertificateLoader.loadCertificate).toHaveBeenCalledWith({\n keyId: \"swap_template_key\",\n keyUsage: \"swap_template\",\n targetDevice: \"nanoS\",\n });\n\n expect(result).toEqual({\n type: SolanaContextTypes.SOLANA_LIFI,\n payload: {\n descriptors: expectedPlucked,\n instructions: [\n { program_id: \"SomeProgram\", discriminator_hex: \"1\" },\n { program_id: \"AnotherProgram\" },\n ],\n },\n certificate: mockCertificate,\n });\n });\n });\n\n describe(\"pluckTransactionData (private)\", () => {\n it(\"returns a map keyed by `${program_id}:${discriminator_hex ?? '0'}`\", () => {\n const loader = makeLoader();\n const pluck = (loader as any).pluckTransactionData.bind(loader);\n\n const result: SolanaTransactionDescriptorList = pluck(\n txDescriptorsResponse,\n );\n\n expect(result).toEqual(expectedPlucked);\n });\n });\n\n describe(\"extractInstructionsMeta (private)\", () => {\n it(\"returns instruction metadata from the API response\", () => {\n const loader = makeLoader();\n const extract = (loader as any).extractInstructionsMeta.bind(loader);\n\n const result = extract(txDescriptorsResponse);\n\n expect(result).toEqual([\n { program_id: \"SomeProgram\", discriminator_hex: \"1\" },\n { program_id: \"AnotherProgram\" },\n ]);\n });\n\n it(\"returns empty array when instructions are missing\", () => {\n const loader = makeLoader();\n const extract = (loader as any).extractInstructionsMeta.bind(loader);\n\n const result = extract({\n ...txDescriptorsResponse,\n instructions: undefined,\n });\n\n expect(result).toEqual([]);\n });\n });\n\n describe(\"pluckTransactionData mode resolution (private)\", () => {\n it(\"resolves signature using config.cal.mode\", () => {\n const loader = makeLoader();\n const pluck = (loader as any).pluckTransactionData.bind(loader);\n\n const result: SolanaTransactionDescriptorList = pluck(\n txDescriptorsResponse,\n );\n\n expect(result[\"SomeProgram:1\"]?.signature).toBe(\"deadbeef\");\n });\n });\n\n describe(\"real CAL payload (LiFi template 4c694669)\", () => {\n const realApiResponse: GetTransactionDescriptorsResponse = {\n id: \"4c694669\",\n chain_id: 101,\n instructions: [\n {\n program_id: \"ATokenGPvbdGVxr1b2hvZbsiqW5xWH25efTNsLJA8knL\",\n discriminator: 1,\n discriminator_hex: \"1\",\n },\n {\n program_id: \"11111111111111111111111111111111\",\n discriminator: 2,\n discriminator_hex: \"2\",\n },\n {\n program_id: \"JUP6LkbZbjS1jKKwapdHNy74zcZ3tLUZoi5QNyVTaV4\",\n discriminator: 3.0753642362361016e18,\n discriminator_hex: \"2aade37a97cb17e0\",\n },\n {\n program_id: \"JUP6LkbZbjS1jKKwapdHNy74zcZ3tLUZoi5QNyVTaV4\",\n discriminator: 9.339575302786589e18,\n discriminator_hex: \"819cd641339b2148\",\n },\n { program_id: \"MemoSq4gqABAXKb96qnH8TysNcWxMyWCqXgDLGmfcHr\" },\n {\n program_id: \"ATokenGPvbdGVxr1b2hvZbsiqW5xWH25efTNsLJA8knL\",\n discriminator: 1,\n discriminator_hex: \"1\",\n },\n { program_id: \"3i5JeuZuUxeKtVysUnwQNGerJP2bSMX9fTFfS4Nxe3Br\" },\n {\n program_id: \"ComputeBudget111111111111111111111111111111\",\n discriminator: 2,\n discriminator_hex: \"2\",\n },\n {\n program_id: \"ComputeBudget111111111111111111111111111111\",\n discriminator: 3,\n discriminator_hex: \"3\",\n },\n {\n program_id: \"TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA\",\n discriminator: 3,\n discriminator_hex: \"3\",\n },\n {\n program_id: \"TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA\",\n discriminator: 17,\n discriminator_hex: \"11\",\n },\n { program_id: \"BrdgN2RPzEMWF96ZbnnJaUtQDQx7VRXYaHHbYCBvceWB\" },\n ],\n descriptors: [\n {\n program_id: \"ATokenGPvbdGVxr1b2hvZbsiqW5xWH25efTNsLJA8knL\",\n discriminator_hex: \"1\",\n descriptor: makeRawDescriptor(\"atoken_1\", \"sig_atoken\"),\n },\n {\n program_id: \"11111111111111111111111111111111\",\n discriminator_hex: \"2\",\n descriptor: makeRawDescriptor(\"system_2\", \"sig_system\"),\n },\n {\n program_id: \"JUP6LkbZbjS1jKKwapdHNy74zcZ3tLUZoi5QNyVTaV4\",\n discriminator_hex: \"2aade37a97cb17e0\",\n descriptor: makeRawDescriptor(\"jup_route\", \"sig_jup_route\"),\n },\n {\n program_id: \"JUP6LkbZbjS1jKKwapdHNy74zcZ3tLUZoi5QNyVTaV4\",\n discriminator_hex: \"819cd641339b2148\",\n descriptor: makeRawDescriptor(\"jup_shared\", \"sig_jup_shared\"),\n },\n {\n program_id: \"MemoSq4gqABAXKb96qnH8TysNcWxMyWCqXgDLGmfcHr\",\n descriptor: makeRawDescriptor(\"memo\", \"sig_memo\"),\n },\n {\n program_id: \"ATokenGPvbdGVxr1b2hvZbsiqW5xWH25efTNsLJA8knL\",\n discriminator_hex: \"1\",\n descriptor: makeRawDescriptor(\"atoken_1\", \"sig_atoken\"),\n },\n {\n program_id: \"3i5JeuZuUxeKtVysUnwQNGerJP2bSMX9fTFfS4Nxe3Br\",\n descriptor: makeRawDescriptor(\"3i5jeu\", \"sig_3i5jeu\"),\n },\n {\n program_id: \"ComputeBudget111111111111111111111111111111\",\n discriminator_hex: \"2\",\n descriptor: makeRawDescriptor(\"cb_2\", \"sig_cb2\"),\n },\n {\n program_id: \"ComputeBudget111111111111111111111111111111\",\n discriminator_hex: \"3\",\n descriptor: makeRawDescriptor(\"cb_3\", \"sig_cb3\"),\n },\n {\n program_id: \"TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA\",\n discriminator_hex: \"3\",\n descriptor: makeRawDescriptor(\"tokenkeg_3\", \"sig_tk3\"),\n },\n {\n program_id: \"TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA\",\n discriminator_hex: \"11\",\n descriptor: makeRawDescriptor(\"tokenkeg_11\", \"sig_tk11\"),\n },\n {\n program_id: \"BrdgN2RPzEMWF96ZbnnJaUtQDQx7VRXYaHHbYCBvceWB\",\n descriptor: makeRawDescriptor(\"brdg\", \"sig_brdg\"),\n },\n ],\n };\n\n it(\"produces 11 unique descriptor keys (ATokenGP:1 appears twice but deduplicates)\", () => {\n const loader = makeLoader();\n const pluck = (loader as any).pluckTransactionData.bind(loader);\n\n const result: SolanaTransactionDescriptorList = pluck(realApiResponse);\n const keys = Object.keys(result);\n\n // 12 descriptors but ATokenGP:1 appears twice -> 11 unique keys\n expect(keys).toHaveLength(11);\n });\n\n it(\"creates distinct keys for same program_id with different discriminators\", () => {\n const loader = makeLoader();\n const pluck = (loader as any).pluckTransactionData.bind(loader);\n\n const result: SolanaTransactionDescriptorList = pluck(realApiResponse);\n\n // JUP6 has two different discriminators -> two distinct entries\n expect(\n result[\"JUP6LkbZbjS1jKKwapdHNy74zcZ3tLUZoi5QNyVTaV4:2aade37a97cb17e0\"]\n ?.data,\n ).toBe(\"jup_route\");\n expect(\n result[\"JUP6LkbZbjS1jKKwapdHNy74zcZ3tLUZoi5QNyVTaV4:819cd641339b2148\"]\n ?.data,\n ).toBe(\"jup_shared\");\n\n // ComputeBudget has discriminator 2 and 3\n expect(\n result[\"ComputeBudget111111111111111111111111111111:2\"]?.data,\n ).toBe(\"cb_2\");\n expect(\n result[\"ComputeBudget111111111111111111111111111111:3\"]?.data,\n ).toBe(\"cb_3\");\n\n // TokenkegQ has discriminator 3 and 11\n expect(\n result[\"TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA:3\"]?.data,\n ).toBe(\"tokenkeg_3\");\n expect(\n result[\"TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA:11\"]?.data,\n ).toBe(\"tokenkeg_11\");\n });\n\n it(\"uses :0 suffix for programs without a discriminator\", () => {\n const loader = makeLoader();\n const pluck = (loader as any).pluckTransactionData.bind(loader);\n\n const result: SolanaTransactionDescriptorList = pluck(realApiResponse);\n\n expect(result[\"MemoSq4gqABAXKb96qnH8TysNcWxMyWCqXgDLGmfcHr:\"]?.data).toBe(\n \"memo\",\n );\n expect(\n result[\"3i5JeuZuUxeKtVysUnwQNGerJP2bSMX9fTFfS4Nxe3Br:\"]?.data,\n ).toBe(\"3i5jeu\");\n expect(\n result[\"BrdgN2RPzEMWF96ZbnnJaUtQDQx7VRXYaHHbYCBvceWB:\"]?.data,\n ).toBe(\"brdg\");\n });\n\n it(\"extracts 12 instruction metadata entries preserving order and discriminators\", () => {\n const loader = makeLoader();\n const extract = (loader as any).extractInstructionsMeta.bind(loader);\n\n const result = extract(realApiResponse);\n\n expect(result).toHaveLength(12);\n\n // First: ATokenGP with discriminator\n expect(result[0]).toEqual({\n program_id: \"ATokenGPvbdGVxr1b2hvZbsiqW5xWH25efTNsLJA8knL\",\n discriminator_hex: \"1\",\n });\n // JUP6 route (8-byte discriminator)\n expect(result[2]).toEqual({\n program_id: \"JUP6LkbZbjS1jKKwapdHNy74zcZ3tLUZoi5QNyVTaV4\",\n discriminator_hex: \"2aade37a97cb17e0\",\n });\n // JUP6 shared (8-byte discriminator)\n expect(result[3]).toEqual({\n program_id: \"JUP6LkbZbjS1jKKwapdHNy74zcZ3tLUZoi5QNyVTaV4\",\n discriminator_hex: \"819cd641339b2148\",\n });\n // Memo: no discriminator\n expect(result[4]).toEqual({\n program_id: \"MemoSq4gqABAXKb96qnH8TysNcWxMyWCqXgDLGmfcHr\",\n });\n // BrdgN2: no discriminator (last entry)\n expect(result[11]).toEqual({\n program_id: \"BrdgN2RPzEMWF96ZbnnJaUtQDQx7VRXYaHHbYCBvceWB\",\n });\n });\n\n it(\"loadField returns full payload with descriptors and instructions from real API response\", async () => {\n const loader = makeLoader();\n\n vi.spyOn(\n mockDataSource,\n \"getTransactionDescriptorsPayload\",\n ).mockResolvedValue(Right(realApiResponse));\n\n const input = { templateId: \"4c694669\", deviceModelId: \"nanoS\" as any };\n const result = await loader.loadField(input);\n\n expect(result).toMatchObject({\n type: SolanaContextTypes.SOLANA_LIFI,\n payload: {\n descriptors: expect.objectContaining({\n \"JUP6LkbZbjS1jKKwapdHNy74zcZ3tLUZoi5QNyVTaV4:2aade37a97cb17e0\":\n expect.objectContaining({ data: \"jup_route\" }),\n \"JUP6LkbZbjS1jKKwapdHNy74zcZ3tLUZoi5QNyVTaV4:819cd641339b2148\":\n expect.objectContaining({ data: \"jup_shared\" }),\n }),\n instructions: expect.arrayContaining([\n expect.objectContaining({\n program_id: \"JUP6LkbZbjS1jKKwapdHNy74zcZ3tLUZoi5QNyVTaV4\",\n discriminator_hex: \"2aade37a97cb17e0\",\n }),\n expect.objectContaining({\n program_id: \"JUP6LkbZbjS1jKKwapdHNy74zcZ3tLUZoi5QNyVTaV4\",\n discriminator_hex: \"819cd641339b2148\",\n }),\n ]),\n },\n });\n\n expect(Object.keys((result as any).payload.descriptors)).toHaveLength(11);\n expect((result as any).payload.instructions).toHaveLength(12);\n });\n });\n});\n"],
4
+ "sourcesContent": ["/* eslint-disable @typescript-eslint/no-unsafe-member-access */\n/* eslint-disable @typescript-eslint/no-unsafe-call */\n/* eslint-disable @typescript-eslint/no-unsafe-assignment */\n/* eslint-disable @typescript-eslint/no-explicit-any */\nimport { Left, Right } from \"purify-ts\";\nimport { beforeEach, describe, expect, it, vi } from \"vitest\";\n\nimport { type ContextModuleServiceConfig } from \"@/config/model/ContextModuleConfig\";\nimport { type PkiCertificateLoader } from \"@/pki/domain/PkiCertificateLoader\";\nimport {\n SolanaContextTypes,\n type SolanaTransactionDescriptor,\n type SolanaTransactionDescriptorList,\n type SolanaTransactionDescriptorRaw,\n} from \"@/shared/model/SolanaContextTypes\";\nimport {\n type GetTransactionDescriptorsResponse,\n type SolanaLifiDataSource,\n} from \"@/solanaLifi/data/SolanaLifiDataSource\";\n\nimport { SolanaLifiContextLoader } from \"./SolanaLifiContextLoader\";\n\nconst mockLoggerFactory = () => ({\n debug: vi.fn(),\n info: vi.fn(),\n warn: vi.fn(),\n error: vi.fn(),\n subscribers: [],\n});\n\nconst mockCertificate = {\n keyUsageNumber: 13,\n payload: new Uint8Array([0x01, 0x02]),\n};\n\nconst mockConfig = {\n cal: {\n url: \"https://crypto-assets-service.api.ledger.com\",\n mode: \"test\",\n branch: \"main\",\n },\n} as ContextModuleServiceConfig;\n\ndescribe(\"SolanaLifiContextLoader\", () => {\n let mockDataSource: SolanaLifiDataSource;\n let mockCertificateLoader: PkiCertificateLoader;\n\n const makeRawDescriptor = (\n data: string,\n sig = \"deadbeef\",\n ): SolanaTransactionDescriptorRaw => ({\n data,\n descriptorType: \"swap_template\",\n descriptorVersion: \"v1\",\n signatures: { test: sig, prod: `prod_${sig}` },\n });\n\n const makeResolvedDescriptor = (\n data: string,\n sig = \"deadbeef\",\n ): SolanaTransactionDescriptor => ({\n data,\n descriptorType: \"swap_template\",\n descriptorVersion: \"v1\",\n signature: sig,\n });\n\n const responseDescriptorsArray: GetTransactionDescriptorsResponse[\"descriptors\"] =\n [\n {\n program_id: \"SomeProgram\",\n discriminator_hex: \"1\",\n descriptor: makeRawDescriptor(\"abc123\"),\n },\n {\n program_id: \"AnotherProgram\",\n // discriminator_hex intentionally omitted -> defaults to \"\"\n descriptor: makeRawDescriptor(\"def456\"),\n },\n ];\n\n const expectedPlucked: SolanaTransactionDescriptorList = {\n \"SomeProgram:1\": makeResolvedDescriptor(\"abc123\"),\n \"AnotherProgram:\": makeResolvedDescriptor(\"def456\"),\n };\n\n const responseInstructionsArray: GetTransactionDescriptorsResponse[\"instructions\"] =\n [\n {\n program_id: \"SomeProgram\",\n discriminator: 1,\n discriminator_hex: \"1\",\n },\n {\n program_id: \"AnotherProgram\",\n // discriminator_hex intentionally omitted\n },\n ];\n\n const txDescriptorsResponse: GetTransactionDescriptorsResponse = {\n id: \"tpl-1\",\n chain_id: 101,\n instructions: responseInstructionsArray,\n descriptors: responseDescriptorsArray,\n };\n\n beforeEach(() => {\n vi.restoreAllMocks();\n mockDataSource = {\n getTransactionDescriptorsPayload: vi.fn(),\n } as unknown as SolanaLifiDataSource;\n mockCertificateLoader = {\n loadCertificate: vi.fn().mockResolvedValue(mockCertificate),\n } as unknown as PkiCertificateLoader;\n });\n\n const makeLoader = () =>\n new SolanaLifiContextLoader(\n mockDataSource,\n mockConfig,\n mockCertificateLoader,\n mockLoggerFactory,\n );\n\n describe(\"canHandle\", () => {\n it(\"returns true when templateId is provided\", () => {\n const loader = makeLoader();\n\n expect(\n loader.canHandle(\n {\n templateId: \"tpl-123\",\n deviceModelId: \"nanoS\" as any,\n },\n SolanaContextTypes.SOLANA_LIFI,\n ),\n ).toBe(true);\n });\n\n it(\"returns false when templateId is missing or falsy\", () => {\n const loader = makeLoader();\n\n expect(\n loader.canHandle(\n { templateId: \"\" } as any,\n SolanaContextTypes.SOLANA_LIFI,\n ),\n ).toBe(false);\n expect(\n loader.canHandle(\n { templateId: undefined } as any,\n SolanaContextTypes.SOLANA_LIFI,\n ),\n ).toBe(false);\n expect(loader.canHandle({} as any, SolanaContextTypes.SOLANA_LIFI)).toBe(\n false,\n );\n });\n });\n\n describe(\"loadField\", () => {\n it(\"returns an error when datasource returns Left(error)\", async () => {\n const loader = makeLoader();\n const error = new Error(\"boom\");\n\n vi.spyOn(\n mockDataSource,\n \"getTransactionDescriptorsPayload\",\n ).mockResolvedValue(Left(error));\n\n const input = { templateId: \"tpl-err\", deviceModelId: \"nanoS\" as any };\n const result = await loader.loadField(input);\n\n expect(\n mockDataSource.getTransactionDescriptorsPayload,\n ).toHaveBeenCalledWith({\n templateId: \"tpl-err\",\n });\n\n expect(result).toEqual({\n type: SolanaContextTypes.ERROR,\n error,\n });\n });\n\n it(\"returns SOLANA_LIFI with plucked descriptors and certificate when datasource returns Right(value)\", async () => {\n const loader = makeLoader();\n\n vi.spyOn(\n mockDataSource,\n \"getTransactionDescriptorsPayload\",\n ).mockResolvedValue(Right(txDescriptorsResponse));\n\n const input = { templateId: \"tpl-ok\", deviceModelId: \"nanoS\" as any };\n const result = await loader.loadField(input);\n\n expect(\n mockDataSource.getTransactionDescriptorsPayload,\n ).toHaveBeenCalledWith({\n templateId: \"tpl-ok\",\n });\n\n expect(mockCertificateLoader.loadCertificate).toHaveBeenCalledWith({\n keyId: \"swap_template_key\",\n keyUsage: \"swap_template\",\n targetDevice: \"nanoS\",\n });\n\n expect(result).toEqual({\n type: SolanaContextTypes.SOLANA_LIFI,\n payload: {\n descriptors: expectedPlucked,\n instructions: [\n { program_id: \"SomeProgram\", discriminator_hex: \"1\" },\n { program_id: \"AnotherProgram\" },\n ],\n },\n certificate: mockCertificate,\n });\n });\n });\n\n describe(\"pluckTransactionData (private)\", () => {\n it(\"returns a map keyed by `${program_id}:${discriminator_hex ?? '0'}`\", () => {\n const loader = makeLoader();\n const pluck = (loader as any).pluckTransactionData.bind(loader);\n\n const result: SolanaTransactionDescriptorList = pluck(\n txDescriptorsResponse,\n );\n\n expect(result).toEqual(expectedPlucked);\n });\n });\n\n describe(\"extractInstructionsMeta (private)\", () => {\n it(\"returns instruction metadata from the API response\", () => {\n const loader = makeLoader();\n const extract = (loader as any).extractInstructionsMeta.bind(loader);\n\n const result = extract(txDescriptorsResponse);\n\n expect(result).toEqual([\n { program_id: \"SomeProgram\", discriminator_hex: \"1\" },\n { program_id: \"AnotherProgram\" },\n ]);\n });\n\n it(\"returns empty array when instructions are missing\", () => {\n const loader = makeLoader();\n const extract = (loader as any).extractInstructionsMeta.bind(loader);\n\n const result = extract({\n ...txDescriptorsResponse,\n instructions: undefined,\n });\n\n expect(result).toEqual([]);\n });\n });\n\n describe(\"pluckTransactionData mode resolution (private)\", () => {\n it(\"resolves signature using config.cal.mode\", () => {\n const loader = makeLoader();\n const pluck = (loader as any).pluckTransactionData.bind(loader);\n\n const result: SolanaTransactionDescriptorList = pluck(\n txDescriptorsResponse,\n );\n\n expect(result[\"SomeProgram:1\"]?.signature).toBe(\"deadbeef\");\n });\n });\n\n describe(\"real CAL payload (LiFi template 4c694669)\", () => {\n const realApiResponse: GetTransactionDescriptorsResponse = {\n id: \"4c694669\",\n chain_id: 101,\n instructions: [\n {\n program_id: \"ATokenGPvbdGVxr1b2hvZbsiqW5xWH25efTNsLJA8knL\",\n discriminator: 1,\n discriminator_hex: \"1\",\n },\n {\n program_id: \"11111111111111111111111111111111\",\n discriminator: 2,\n discriminator_hex: \"2\",\n },\n {\n program_id: \"JUP6LkbZbjS1jKKwapdHNy74zcZ3tLUZoi5QNyVTaV4\",\n discriminator: 3.0753642362361016e18,\n discriminator_hex: \"2aade37a97cb17e0\",\n },\n {\n program_id: \"JUP6LkbZbjS1jKKwapdHNy74zcZ3tLUZoi5QNyVTaV4\",\n discriminator: 9.339575302786589e18,\n discriminator_hex: \"819cd641339b2148\",\n },\n { program_id: \"MemoSq4gqABAXKb96qnH8TysNcWxMyWCqXgDLGmfcHr\" },\n {\n program_id: \"ATokenGPvbdGVxr1b2hvZbsiqW5xWH25efTNsLJA8knL\",\n discriminator: 1,\n discriminator_hex: \"1\",\n },\n { program_id: \"3i5JeuZuUxeKtVysUnwQNGerJP2bSMX9fTFfS4Nxe3Br\" },\n {\n program_id: \"ComputeBudget111111111111111111111111111111\",\n discriminator: 2,\n discriminator_hex: \"2\",\n },\n {\n program_id: \"ComputeBudget111111111111111111111111111111\",\n discriminator: 3,\n discriminator_hex: \"3\",\n },\n {\n program_id: \"TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA\",\n discriminator: 3,\n discriminator_hex: \"3\",\n },\n {\n program_id: \"TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA\",\n discriminator: 17,\n discriminator_hex: \"11\",\n },\n { program_id: \"BrdgN2RPzEMWF96ZbnnJaUtQDQx7VRXYaHHbYCBvceWB\" },\n ],\n descriptors: [\n {\n program_id: \"ATokenGPvbdGVxr1b2hvZbsiqW5xWH25efTNsLJA8knL\",\n discriminator_hex: \"1\",\n descriptor: makeRawDescriptor(\"atoken_1\", \"sig_atoken\"),\n },\n {\n program_id: \"11111111111111111111111111111111\",\n discriminator_hex: \"2\",\n descriptor: makeRawDescriptor(\"system_2\", \"sig_system\"),\n },\n {\n program_id: \"JUP6LkbZbjS1jKKwapdHNy74zcZ3tLUZoi5QNyVTaV4\",\n discriminator_hex: \"2aade37a97cb17e0\",\n descriptor: makeRawDescriptor(\"jup_route\", \"sig_jup_route\"),\n },\n {\n program_id: \"JUP6LkbZbjS1jKKwapdHNy74zcZ3tLUZoi5QNyVTaV4\",\n discriminator_hex: \"819cd641339b2148\",\n descriptor: makeRawDescriptor(\"jup_shared\", \"sig_jup_shared\"),\n },\n {\n program_id: \"MemoSq4gqABAXKb96qnH8TysNcWxMyWCqXgDLGmfcHr\",\n descriptor: makeRawDescriptor(\"memo\", \"sig_memo\"),\n },\n {\n program_id: \"ATokenGPvbdGVxr1b2hvZbsiqW5xWH25efTNsLJA8knL\",\n discriminator_hex: \"1\",\n descriptor: makeRawDescriptor(\"atoken_1\", \"sig_atoken\"),\n },\n {\n program_id: \"3i5JeuZuUxeKtVysUnwQNGerJP2bSMX9fTFfS4Nxe3Br\",\n descriptor: makeRawDescriptor(\"3i5jeu\", \"sig_3i5jeu\"),\n },\n {\n program_id: \"ComputeBudget111111111111111111111111111111\",\n discriminator_hex: \"2\",\n descriptor: makeRawDescriptor(\"cb_2\", \"sig_cb2\"),\n },\n {\n program_id: \"ComputeBudget111111111111111111111111111111\",\n discriminator_hex: \"3\",\n descriptor: makeRawDescriptor(\"cb_3\", \"sig_cb3\"),\n },\n {\n program_id: \"TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA\",\n discriminator_hex: \"3\",\n descriptor: makeRawDescriptor(\"tokenkeg_3\", \"sig_tk3\"),\n },\n {\n program_id: \"TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA\",\n discriminator_hex: \"11\",\n descriptor: makeRawDescriptor(\"tokenkeg_11\", \"sig_tk11\"),\n },\n {\n program_id: \"BrdgN2RPzEMWF96ZbnnJaUtQDQx7VRXYaHHbYCBvceWB\",\n descriptor: makeRawDescriptor(\"brdg\", \"sig_brdg\"),\n },\n ],\n };\n\n it(\"produces 11 unique descriptor keys (ATokenGP:1 appears twice but deduplicates)\", () => {\n const loader = makeLoader();\n const pluck = (loader as any).pluckTransactionData.bind(loader);\n\n const result: SolanaTransactionDescriptorList = pluck(realApiResponse);\n const keys = Object.keys(result);\n\n // 12 descriptors but ATokenGP:1 appears twice -> 11 unique keys\n expect(keys).toHaveLength(11);\n });\n\n it(\"creates distinct keys for same program_id with different discriminators\", () => {\n const loader = makeLoader();\n const pluck = (loader as any).pluckTransactionData.bind(loader);\n\n const result: SolanaTransactionDescriptorList = pluck(realApiResponse);\n\n // JUP6 has two different discriminators -> two distinct entries\n expect(\n result[\"JUP6LkbZbjS1jKKwapdHNy74zcZ3tLUZoi5QNyVTaV4:2aade37a97cb17e0\"]\n ?.data,\n ).toBe(\"jup_route\");\n expect(\n result[\"JUP6LkbZbjS1jKKwapdHNy74zcZ3tLUZoi5QNyVTaV4:819cd641339b2148\"]\n ?.data,\n ).toBe(\"jup_shared\");\n\n // ComputeBudget has discriminator 2 and 3\n expect(\n result[\"ComputeBudget111111111111111111111111111111:2\"]?.data,\n ).toBe(\"cb_2\");\n expect(\n result[\"ComputeBudget111111111111111111111111111111:3\"]?.data,\n ).toBe(\"cb_3\");\n\n // TokenkegQ has discriminator 3 and 11\n expect(\n result[\"TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA:3\"]?.data,\n ).toBe(\"tokenkeg_3\");\n expect(\n result[\"TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA:11\"]?.data,\n ).toBe(\"tokenkeg_11\");\n });\n\n it(\"uses :0 suffix for programs without a discriminator\", () => {\n const loader = makeLoader();\n const pluck = (loader as any).pluckTransactionData.bind(loader);\n\n const result: SolanaTransactionDescriptorList = pluck(realApiResponse);\n\n expect(result[\"MemoSq4gqABAXKb96qnH8TysNcWxMyWCqXgDLGmfcHr:\"]?.data).toBe(\n \"memo\",\n );\n expect(\n result[\"3i5JeuZuUxeKtVysUnwQNGerJP2bSMX9fTFfS4Nxe3Br:\"]?.data,\n ).toBe(\"3i5jeu\");\n expect(\n result[\"BrdgN2RPzEMWF96ZbnnJaUtQDQx7VRXYaHHbYCBvceWB:\"]?.data,\n ).toBe(\"brdg\");\n });\n\n it(\"extracts 12 instruction metadata entries preserving order and discriminators\", () => {\n const loader = makeLoader();\n const extract = (loader as any).extractInstructionsMeta.bind(loader);\n\n const result = extract(realApiResponse);\n\n expect(result).toHaveLength(12);\n\n // First: ATokenGP with discriminator\n expect(result[0]).toEqual({\n program_id: \"ATokenGPvbdGVxr1b2hvZbsiqW5xWH25efTNsLJA8knL\",\n discriminator_hex: \"1\",\n });\n // JUP6 route (8-byte discriminator)\n expect(result[2]).toEqual({\n program_id: \"JUP6LkbZbjS1jKKwapdHNy74zcZ3tLUZoi5QNyVTaV4\",\n discriminator_hex: \"2aade37a97cb17e0\",\n });\n // JUP6 shared (8-byte discriminator)\n expect(result[3]).toEqual({\n program_id: \"JUP6LkbZbjS1jKKwapdHNy74zcZ3tLUZoi5QNyVTaV4\",\n discriminator_hex: \"819cd641339b2148\",\n });\n // Memo: no discriminator\n expect(result[4]).toEqual({\n program_id: \"MemoSq4gqABAXKb96qnH8TysNcWxMyWCqXgDLGmfcHr\",\n });\n // BrdgN2: no discriminator (last entry)\n expect(result[11]).toEqual({\n program_id: \"BrdgN2RPzEMWF96ZbnnJaUtQDQx7VRXYaHHbYCBvceWB\",\n });\n });\n\n it(\"loadField returns full payload with descriptors and instructions from real API response\", async () => {\n const loader = makeLoader();\n\n vi.spyOn(\n mockDataSource,\n \"getTransactionDescriptorsPayload\",\n ).mockResolvedValue(Right(realApiResponse));\n\n const input = { templateId: \"4c694669\", deviceModelId: \"nanoS\" as any };\n const result = await loader.loadField(input);\n\n expect(result).toMatchObject({\n type: SolanaContextTypes.SOLANA_LIFI,\n payload: {\n descriptors: expect.objectContaining({\n \"JUP6LkbZbjS1jKKwapdHNy74zcZ3tLUZoi5QNyVTaV4:2aade37a97cb17e0\":\n expect.objectContaining({ data: \"jup_route\" }),\n \"JUP6LkbZbjS1jKKwapdHNy74zcZ3tLUZoi5QNyVTaV4:819cd641339b2148\":\n expect.objectContaining({ data: \"jup_shared\" }),\n }),\n instructions: expect.arrayContaining([\n expect.objectContaining({\n program_id: \"JUP6LkbZbjS1jKKwapdHNy74zcZ3tLUZoi5QNyVTaV4\",\n discriminator_hex: \"2aade37a97cb17e0\",\n }),\n expect.objectContaining({\n program_id: \"JUP6LkbZbjS1jKKwapdHNy74zcZ3tLUZoi5QNyVTaV4\",\n discriminator_hex: \"819cd641339b2148\",\n }),\n ]),\n },\n });\n\n expect(Object.keys((result as any).payload.descriptors)).toHaveLength(11);\n expect((result as any).payload.instructions).toHaveLength(12);\n });\n });\n});\n"],
5
5
  "mappings": "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",
6
6
  "names": ["Left", "Right", "beforeEach", "describe", "expect", "it", "vi", "SolanaContextTypes", "SolanaLifiContextLoader", "mockLoggerFactory", "mockCertificate", "mockConfig", "mockDataSource", "mockCertificateLoader", "makeRawDescriptor", "data", "sig", "makeResolvedDescriptor", "responseDescriptorsArray", "expectedPlucked", "txDescriptorsResponse", "makeLoader", "loader", "error", "input", "result", "realApiResponse", "keys"]
7
7
  }
@@ -1,2 +1,2 @@
1
- var l=Object.defineProperty;var p=Object.getOwnPropertyDescriptor;var c=(n,e,o,t)=>{for(var r=t>1?void 0:t?p(e,o):e,i=n.length-1,s;i>=0;i--)(s=n[i])&&(r=(t?s(e,o,r):s(r))||r);return t&&r&&l(e,o,r),r},m=(n,e)=>(o,t)=>e(o,t,n);import d from"axios";import{inject as u,injectable as h}from"inversify";import{Left as f,Right as _}from"purify-ts";import{configTypes as g}from"../../config/di/configTypes";import{LEDGER_CLIENT_VERSION_HEADER as k}from"../../shared/constant/HttpHeaders";import E from"../../../package.json";let a=class{constructor(e){this.config=e}async getTokenInfosPayload({tokenInternalId:e}){try{const{data:o}=await d.request({method:"GET",url:`${this.config.cal.url}/tokens`,params:{id:e,output:"id,name,network,network_family,network_type,exchange_app_config_serialized,live_signature,ticker,decimals,blockchain_name,chain_id,contract_address,descriptor,descriptor_exchange_app,units,symbol",ref:`branch:${this.config.cal.branch}`},headers:{[k]:`context-module/${E.version}`}});return!o||o.length===0||!o[0]?f(new Error(`[ContextModule] HttpSolanaTokenDataSource: no token metadata for id ${e}`)):_(o[0])}catch{return f(new Error("[ContextModule] HttpSolanaTokenDataSource: Failed to fetch token informations"))}}};a=c([h(),m(0,u(g.Config))],a);export{a as HttpSolanaTokenDataSource};
1
+ var f=Object.defineProperty;var k=Object.getOwnPropertyDescriptor;var m=(n,o,e,r)=>{for(var t=r>1?void 0:r?k(o,e):o,i=n.length-1,s;i>=0;i--)(s=n[i])&&(t=(r?s(o,e,t):s(t))||t);return r&&t&&f(o,e,t),t},c=(n,o)=>(e,r)=>o(e,r,n);import{inject as p,injectable as d}from"inversify";import{Left as l,Right as h}from"purify-ts";import{configTypes as g}from"../../config/di/configTypes";import{networkTypes as u}from"../../network/di/networkTypes";let a=class{constructor(o,e){this.config=o;this.http=e}async getTokenInfosPayload({tokenInternalId:o}){try{const e=await this.http.get(`${this.config.cal.url}/tokens`,{params:{id:o,output:"id,name,network,network_family,network_type,exchange_app_config_serialized,live_signature,ticker,decimals,blockchain_name,chain_id,contract_address,descriptor,descriptor_exchange_app,units,symbol",ref:`branch:${this.config.cal.branch}`}});return!e||e.length===0||!e[0]?l(new Error(`[ContextModule] HttpSolanaTokenDataSource: no token metadata for id ${o}`)):h(e[0])}catch{return l(new Error("[ContextModule] HttpSolanaTokenDataSource: Failed to fetch token informations"))}}};a=m([d(),c(0,p(g.Config)),c(1,p(u.NetworkClient))],a);export{a as HttpSolanaTokenDataSource};
2
2
  //# sourceMappingURL=HttpSolanaTokenDataSource.js.map
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "version": 3,
3
3
  "sources": ["../../../../../src/solanaToken/data/HttpSolanaTokenDataSource.ts"],
4
- "sourcesContent": ["import axios from \"axios\";\nimport { inject, injectable } from \"inversify\";\nimport { Either, Left, Right } from \"purify-ts\";\n\nimport { configTypes } from \"@/config/di/configTypes\";\nimport { type ContextModuleConfig } from \"@/config/model/ContextModuleConfig\";\nimport { LEDGER_CLIENT_VERSION_HEADER } from \"@/shared/constant/HttpHeaders\";\nimport PACKAGE from \"@root/package.json\";\n\nimport {\n GetSolanaTokenInfosParams,\n SolanaTokenDataSource,\n TokenDataResponse,\n} from \"./SolanaTokenDataSource\";\n\n@injectable()\nexport class HttpSolanaTokenDataSource implements SolanaTokenDataSource {\n constructor(\n @inject(configTypes.Config) private readonly config: ContextModuleConfig,\n ) {}\n public async getTokenInfosPayload({\n tokenInternalId,\n }: GetSolanaTokenInfosParams): Promise<Either<Error, TokenDataResponse>> {\n try {\n const { data } = await axios.request<TokenDataResponse[]>({\n method: \"GET\",\n url: `${this.config.cal.url}/tokens`,\n params: {\n id: tokenInternalId,\n output:\n \"id,name,network,network_family,network_type,exchange_app_config_serialized,live_signature,ticker,decimals,blockchain_name,chain_id,contract_address,descriptor,descriptor_exchange_app,units,symbol\",\n ref: `branch:${this.config.cal.branch}`,\n },\n headers: {\n [LEDGER_CLIENT_VERSION_HEADER]: `context-module/${PACKAGE.version}`,\n },\n });\n\n if (!data || data.length === 0 || !data[0]) {\n return Left(\n new Error(\n `[ContextModule] HttpSolanaTokenDataSource: no token metadata for id ${tokenInternalId}`,\n ),\n );\n }\n\n return Right(data[0]);\n } catch (_error) {\n return Left(\n new Error(\n \"[ContextModule] HttpSolanaTokenDataSource: Failed to fetch token informations\",\n ),\n );\n }\n }\n}\n"],
5
- "mappings": "iOAAA,OAAOA,MAAW,QAClB,OAAS,UAAAC,EAAQ,cAAAC,MAAkB,YACnC,OAAiB,QAAAC,EAAM,SAAAC,MAAa,YAEpC,OAAS,eAAAC,MAAmB,0BAE5B,OAAS,gCAAAC,MAAoC,gCAC7C,OAAOC,MAAa,qBASb,IAAMC,EAAN,KAAiE,CACtE,YAC+CC,EAC7C,CAD6C,YAAAA,CAC5C,CACH,MAAa,qBAAqB,CAChC,gBAAAC,CACF,EAAyE,CACvE,GAAI,CACF,KAAM,CAAE,KAAAC,CAAK,EAAI,MAAMC,EAAM,QAA6B,CACxD,OAAQ,MACR,IAAK,GAAG,KAAK,OAAO,IAAI,GAAG,UAC3B,OAAQ,CACN,GAAIF,EACJ,OACE,sMACF,IAAK,UAAU,KAAK,OAAO,IAAI,MAAM,EACvC,EACA,QAAS,CACP,CAACG,CAA4B,EAAG,kBAAkBC,EAAQ,OAAO,EACnE,CACF,CAAC,EAED,MAAI,CAACH,GAAQA,EAAK,SAAW,GAAK,CAACA,EAAK,CAAC,EAChCI,EACL,IAAI,MACF,uEAAuEL,CAAe,EACxF,CACF,EAGKM,EAAML,EAAK,CAAC,CAAC,CACtB,MAAiB,CACf,OAAOI,EACL,IAAI,MACF,+EACF,CACF,CACF,CACF,CACF,EAvCaP,EAANS,EAAA,CADNC,EAAW,EAGPC,EAAA,EAAAC,EAAOC,EAAY,MAAM,IAFjBb",
6
- "names": ["axios", "inject", "injectable", "Left", "Right", "configTypes", "LEDGER_CLIENT_VERSION_HEADER", "PACKAGE", "HttpSolanaTokenDataSource", "config", "tokenInternalId", "data", "axios", "LEDGER_CLIENT_VERSION_HEADER", "PACKAGE", "Left", "Right", "__decorateClass", "injectable", "__decorateParam", "inject", "configTypes"]
4
+ "sourcesContent": ["import { DmkNetworkClient } from \"@ledgerhq/device-management-kit\";\nimport { inject, injectable } from \"inversify\";\nimport { Either, Left, Right } from \"purify-ts\";\n\nimport { configTypes } from \"@/config/di/configTypes\";\nimport { type ContextModuleServiceConfig } from \"@/config/model/ContextModuleConfig\";\nimport { networkTypes } from \"@/network/di/networkTypes\";\n\nimport {\n GetSolanaTokenInfosParams,\n SolanaTokenDataSource,\n TokenDataResponse,\n} from \"./SolanaTokenDataSource\";\n\n@injectable()\nexport class HttpSolanaTokenDataSource implements SolanaTokenDataSource {\n constructor(\n @inject(configTypes.Config)\n private readonly config: ContextModuleServiceConfig,\n @inject(networkTypes.NetworkClient)\n private readonly http: DmkNetworkClient,\n ) {}\n\n public async getTokenInfosPayload({\n tokenInternalId,\n }: GetSolanaTokenInfosParams): Promise<Either<Error, TokenDataResponse>> {\n try {\n const data = (await this.http.get(`${this.config.cal.url}/tokens`, {\n params: {\n id: tokenInternalId,\n output:\n \"id,name,network,network_family,network_type,exchange_app_config_serialized,live_signature,ticker,decimals,blockchain_name,chain_id,contract_address,descriptor,descriptor_exchange_app,units,symbol\",\n ref: `branch:${this.config.cal.branch}`,\n },\n })) as TokenDataResponse[];\n\n if (!data || data.length === 0 || !data[0]) {\n return Left(\n new Error(\n `[ContextModule] HttpSolanaTokenDataSource: no token metadata for id ${tokenInternalId}`,\n ),\n );\n }\n\n return Right(data[0]);\n } catch (_error) {\n return Left(\n new Error(\n \"[ContextModule] HttpSolanaTokenDataSource: Failed to fetch token informations\",\n ),\n );\n }\n }\n}\n"],
5
+ "mappings": "iOACA,OAAS,UAAAA,EAAQ,cAAAC,MAAkB,YACnC,OAAiB,QAAAC,EAAM,SAAAC,MAAa,YAEpC,OAAS,eAAAC,MAAmB,0BAE5B,OAAS,gBAAAC,MAAoB,4BAStB,IAAMC,EAAN,KAAiE,CACtE,YAEmBC,EAEAC,EACjB,CAHiB,YAAAD,EAEA,UAAAC,CAChB,CAEH,MAAa,qBAAqB,CAChC,gBAAAC,CACF,EAAyE,CACvE,GAAI,CACF,MAAMC,EAAQ,MAAM,KAAK,KAAK,IAAI,GAAG,KAAK,OAAO,IAAI,GAAG,UAAW,CACjE,OAAQ,CACN,GAAID,EACJ,OACE,sMACF,IAAK,UAAU,KAAK,OAAO,IAAI,MAAM,EACvC,CACF,CAAC,EAED,MAAI,CAACC,GAAQA,EAAK,SAAW,GAAK,CAACA,EAAK,CAAC,EAChCC,EACL,IAAI,MACF,uEAAuEF,CAAe,EACxF,CACF,EAGKG,EAAMF,EAAK,CAAC,CAAC,CACtB,MAAiB,CACf,OAAOC,EACL,IAAI,MACF,+EACF,CACF,CACF,CACF,CACF,EAtCaL,EAANO,EAAA,CADNC,EAAW,EAGPC,EAAA,EAAAC,EAAOC,EAAY,MAAM,GAEzBF,EAAA,EAAAC,EAAOE,EAAa,aAAa,IAJzBZ",
6
+ "names": ["inject", "injectable", "Left", "Right", "configTypes", "networkTypes", "HttpSolanaTokenDataSource", "config", "http", "tokenInternalId", "data", "Left", "Right", "__decorateClass", "injectable", "__decorateParam", "inject", "configTypes", "networkTypes"]
7
7
  }
@@ -1,7 +1,7 @@
1
- import r from"axios";import{Left as c,Right as p}from"purify-ts";import{beforeAll as f,beforeEach as h,describe as d,expect as o,it as s,vi as a}from"vitest";import{LEDGER_CLIENT_VERSION_HEADER as y}from"../../shared/constant/HttpHeaders";import k from"../../../package.json";import{HttpSolanaTokenDataSource as g}from"./HttpSolanaTokenDataSource";a.mock("axios");d("HttpSolanaTokenDataSource",()=>{let n;const t="sol:usdc",l={cal:{url:"https://crypto-assets-service.api.ledger.com/v1",mode:"prod",branch:"main"}},u=e=>`[ContextModule] HttpSolanaTokenDataSource: no token metadata for id ${e}`;f(()=>{n=new g(l)}),h(()=>{a.clearAllMocks()}),s("should call axios with the ledger client version header and correct params",async()=>{const e=a.fn(()=>Promise.resolve({data:[]}));a.spyOn(r,"request").mockImplementation(e),await n.getTokenInfosPayload({tokenInternalId:t}),o(e).toHaveBeenCalledTimes(1),o(e).toHaveBeenCalledWith(o.objectContaining({method:"GET",url:`${l.cal.url}/tokens`,params:o.objectContaining({id:t,ref:`branch:${l.cal.branch}`}),headers:{[y]:`context-module/${k.version}`}}))}),s("should return Right(data[0]) when axios responds with a non-empty array",async()=>{const e={descriptor:{data:"ABCD",signatures:{prod:"SIG-PROD",test:"SIG-TEST"}}};a.spyOn(r,"request").mockResolvedValue({data:[e]});const i=await n.getTokenInfosPayload({tokenInternalId:t});o(i).toEqual(p(e))}),d.each`
2
- caseName | apiResponse
3
- ${"data is undefined"} | ${{data:void 0}}
4
- ${"data array is empty"} | ${{data:[]}}
5
- ${"first element is falsy"} | ${{data:[void 0]}}
6
- `("Error cases",({caseName:e,apiResponse:i})=>{s(`should return an error when ${e}`,async()=>{a.spyOn(r,"request").mockResolvedValue(i);const m=await n.getTokenInfosPayload({tokenInternalId:t});o(m).toEqual(c(new Error(u(t))))})}),s("should return an error when axios throws",async()=>{a.spyOn(r,"request").mockRejectedValue(new Error("network"));const e=await n.getTokenInfosPayload({tokenInternalId:t});o(e).toEqual(c(new Error("[ContextModule] HttpSolanaTokenDataSource: Failed to fetch token informations")))})});
1
+ import{Left as c,Right as m}from"purify-ts";import{beforeEach as k,describe as i,expect as n,it as r,vi as d}from"vitest";import{HttpSolanaTokenDataSource as g}from"./HttpSolanaTokenDataSource";i("HttpSolanaTokenDataSource",()=>{let a,e;const o="sol:usdc",s={cal:{url:"https://crypto-assets-service.api.ledger.com/v1",mode:"prod",branch:"main"}},p=t=>`[ContextModule] HttpSolanaTokenDataSource: no token metadata for id ${t}`;k(()=>{d.clearAllMocks(),e={get:d.fn()},a=new g(s,e)}),r("should call http.get with the correct url and params",async()=>{e.get.mockResolvedValue([]),await a.getTokenInfosPayload({tokenInternalId:o}),n(e.get).toHaveBeenCalledTimes(1),n(e.get).toHaveBeenCalledWith(`${s.cal.url}/tokens`,{params:{id:o,output:"id,name,network,network_family,network_type,exchange_app_config_serialized,live_signature,ticker,decimals,blockchain_name,chain_id,contract_address,descriptor,descriptor_exchange_app,units,symbol",ref:`branch:${s.cal.branch}`}})}),r("should return Right(data[0]) when http.get responds with a non-empty array",async()=>{const t={descriptor:{data:"ABCD",signatures:{prod:"SIG-PROD",test:"SIG-TEST"}}};e.get.mockResolvedValue([t]);const l=await a.getTokenInfosPayload({tokenInternalId:o});n(l).toEqual(m(t))}),i.each`
2
+ caseName | responseBody
3
+ ${"data is undefined"} | ${null}
4
+ ${"data array is empty"} | ${[]}
5
+ ${"first element is falsy"} | ${[null]}
6
+ `("Error cases",({caseName:t,responseBody:l})=>{r(`should return an error when ${t}`,async()=>{e.get.mockResolvedValue(l);const u=await a.getTokenInfosPayload({tokenInternalId:o});n(u).toEqual(c(new Error(p(o))))})}),r("should return an error when http.get throws",async()=>{e.get.mockRejectedValue(new Error("network"));const t=await a.getTokenInfosPayload({tokenInternalId:o});n(t).toEqual(c(new Error("[ContextModule] HttpSolanaTokenDataSource: Failed to fetch token informations")))})});
7
7
  //# sourceMappingURL=HttpSolanaTokenDataSource.test.js.map