@ledgerhq/context-module 2.1.0 → 2.2.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 (415) hide show
  1. package/lib/cjs/package.json +2 -2
  2. package/lib/cjs/src/DefaultContextModule.js +1 -1
  3. package/lib/cjs/src/DefaultContextModule.js.map +3 -3
  4. package/lib/cjs/src/di.js +1 -1
  5. package/lib/cjs/src/di.js.map +3 -3
  6. package/lib/cjs/src/index.js +1 -1
  7. package/lib/cjs/src/index.js.map +2 -2
  8. package/lib/cjs/src/modules/multichain/pki/model/KeyId.js +1 -1
  9. package/lib/cjs/src/modules/multichain/pki/model/KeyId.js.map +2 -2
  10. package/lib/cjs/src/modules/multichain/transaction-check/loaders/SolanaTransactionCheckLoader.js +1 -1
  11. package/lib/cjs/src/modules/multichain/transaction-check/loaders/SolanaTransactionCheckLoader.js.map +3 -3
  12. package/lib/cjs/src/modules/multichain/transaction-check/loaders/SolanaTransactionCheckLoader.test.js +1 -1
  13. package/lib/cjs/src/modules/multichain/transaction-check/loaders/SolanaTransactionCheckLoader.test.js.map +3 -3
  14. package/lib/cjs/src/modules/solana/alt-resolution/data/AltResolutionDataSource.js +2 -0
  15. package/lib/cjs/src/modules/solana/alt-resolution/data/AltResolutionDataSource.js.map +7 -0
  16. package/lib/cjs/src/modules/solana/alt-resolution/data/HttpAltResolutionDataSource.js +2 -0
  17. package/lib/cjs/src/modules/solana/alt-resolution/data/HttpAltResolutionDataSource.js.map +7 -0
  18. package/lib/cjs/src/modules/solana/alt-resolution/data/HttpAltResolutionDataSource.test.js +2 -0
  19. package/lib/cjs/src/modules/solana/alt-resolution/data/HttpAltResolutionDataSource.test.js.map +7 -0
  20. package/lib/cjs/src/modules/solana/alt-resolution/di/altResolutionModuleFactory.js +2 -0
  21. package/lib/cjs/src/modules/solana/alt-resolution/di/altResolutionModuleFactory.js.map +7 -0
  22. package/lib/cjs/src/modules/solana/alt-resolution/di/altResolutionTypes.js +2 -0
  23. package/lib/cjs/src/modules/solana/alt-resolution/di/altResolutionTypes.js.map +7 -0
  24. package/lib/cjs/src/modules/solana/alt-resolution/domain/AltResolutionContextLoader.js +2 -0
  25. package/lib/cjs/src/modules/solana/alt-resolution/domain/AltResolutionContextLoader.js.map +7 -0
  26. package/lib/cjs/src/modules/solana/alt-resolution/domain/AltResolutionContextLoader.test.js +2 -0
  27. package/lib/cjs/src/modules/solana/alt-resolution/domain/AltResolutionContextLoader.test.js.map +7 -0
  28. package/lib/cjs/src/modules/solana/enum-variant/di/enumVariantModuleFactory.js +2 -0
  29. package/lib/cjs/src/modules/solana/enum-variant/di/enumVariantModuleFactory.js.map +7 -0
  30. package/lib/cjs/src/modules/solana/enum-variant/di/enumVariantTypes.js +2 -0
  31. package/lib/cjs/src/modules/solana/enum-variant/di/enumVariantTypes.js.map +7 -0
  32. package/lib/cjs/src/modules/solana/enum-variant/domain/EnumVariantContextLoader.js +2 -0
  33. package/lib/cjs/src/modules/solana/enum-variant/domain/EnumVariantContextLoader.js.map +7 -0
  34. package/lib/cjs/src/modules/solana/enum-variant/domain/EnumVariantContextLoader.test.js +2 -0
  35. package/lib/cjs/src/modules/solana/enum-variant/domain/EnumVariantContextLoader.test.js.map +7 -0
  36. package/lib/cjs/src/modules/solana/instruction-info/data/HttpInstructionInfoDataSource.js +2 -0
  37. package/lib/cjs/src/modules/solana/instruction-info/data/HttpInstructionInfoDataSource.js.map +7 -0
  38. package/lib/cjs/src/modules/solana/instruction-info/data/HttpInstructionInfoDataSource.test.js +2 -0
  39. package/lib/cjs/src/modules/solana/instruction-info/data/HttpInstructionInfoDataSource.test.js.map +7 -0
  40. package/lib/cjs/src/modules/solana/instruction-info/data/InstructionInfoDataSource.js +2 -0
  41. package/lib/cjs/src/modules/solana/instruction-info/data/InstructionInfoDataSource.js.map +7 -0
  42. package/lib/cjs/src/modules/solana/instruction-info/data/InstructionInfoDto.js +2 -0
  43. package/lib/cjs/src/modules/solana/instruction-info/data/InstructionInfoDto.js.map +7 -0
  44. package/lib/cjs/src/modules/solana/instruction-info/data/InstructionInfoMapper.js +2 -0
  45. package/lib/cjs/src/modules/solana/instruction-info/data/InstructionInfoMapper.js.map +7 -0
  46. package/lib/cjs/src/modules/solana/instruction-info/data/InstructionInfoMapper.test.js +2 -0
  47. package/lib/cjs/src/modules/solana/instruction-info/data/InstructionInfoMapper.test.js.map +7 -0
  48. package/lib/cjs/src/modules/solana/instruction-info/di/instructionInfoModuleFactory.js +2 -0
  49. package/lib/cjs/src/modules/solana/instruction-info/di/instructionInfoModuleFactory.js.map +7 -0
  50. package/lib/cjs/src/modules/solana/instruction-info/di/instructionInfoTypes.js +2 -0
  51. package/lib/cjs/src/modules/solana/instruction-info/di/instructionInfoTypes.js.map +7 -0
  52. package/lib/cjs/src/modules/solana/instruction-info/domain/InstructionInfoContextLoader.js +2 -0
  53. package/lib/cjs/src/modules/solana/instruction-info/domain/InstructionInfoContextLoader.js.map +7 -0
  54. package/lib/cjs/src/modules/solana/instruction-info/domain/InstructionInfoContextLoader.test.js +2 -0
  55. package/lib/cjs/src/modules/solana/instruction-info/domain/InstructionInfoContextLoader.test.js.map +7 -0
  56. package/lib/cjs/src/modules/solana/model/SolanaClearSignContext.js +1 -1
  57. package/lib/cjs/src/modules/solana/model/SolanaClearSignContext.js.map +3 -3
  58. package/lib/cjs/src/modules/solana/model/SolanaContextTypes.js +1 -1
  59. package/lib/cjs/src/modules/solana/model/SolanaContextTypes.js.map +1 -1
  60. package/lib/cjs/src/modules/solana/model/SolanaPayloads.js +1 -1
  61. package/lib/cjs/src/modules/solana/model/SolanaPayloads.js.map +3 -3
  62. package/lib/cjs/src/modules/solana/model/SolanaTransactionScanChainId.js +1 -1
  63. package/lib/cjs/src/modules/solana/model/SolanaTransactionScanChainId.js.map +2 -2
  64. package/lib/cjs/src/modules/solana/owner-info/domain/OwnerInfoContextLoader.js +1 -1
  65. package/lib/cjs/src/modules/solana/owner-info/domain/OwnerInfoContextLoader.js.map +2 -2
  66. package/lib/cjs/src/modules/solana/owner-info/domain/OwnerInfoContextLoader.test.js +1 -1
  67. package/lib/cjs/src/modules/solana/owner-info/domain/OwnerInfoContextLoader.test.js.map +2 -2
  68. package/lib/cjs/src/modules/solana/owner-info/domain/solanaContextTypes.js +1 -1
  69. package/lib/cjs/src/modules/solana/owner-info/domain/solanaContextTypes.js.map +1 -1
  70. package/lib/cjs/src/modules/solana/token/domain/TokenContextLoader.js +1 -1
  71. package/lib/cjs/src/modules/solana/token/domain/TokenContextLoader.js.map +3 -3
  72. package/lib/cjs/src/modules/solana/token-account-state/data/HttpTokenAccountStateDataSource.js +2 -0
  73. package/lib/cjs/src/modules/solana/token-account-state/data/HttpTokenAccountStateDataSource.js.map +7 -0
  74. package/lib/cjs/src/modules/solana/token-account-state/data/HttpTokenAccountStateDataSource.test.js +2 -0
  75. package/lib/cjs/src/modules/solana/token-account-state/data/HttpTokenAccountStateDataSource.test.js.map +7 -0
  76. package/lib/cjs/src/modules/solana/token-account-state/data/TokenAccountStateDataSource.js +2 -0
  77. package/lib/cjs/src/modules/solana/token-account-state/data/TokenAccountStateDataSource.js.map +7 -0
  78. package/lib/cjs/src/modules/solana/token-account-state/di/tokenAccountStateModuleFactory.js +2 -0
  79. package/lib/cjs/src/modules/solana/token-account-state/di/tokenAccountStateModuleFactory.js.map +7 -0
  80. package/lib/cjs/src/modules/solana/token-account-state/di/tokenAccountStateTypes.js +2 -0
  81. package/lib/cjs/src/modules/solana/token-account-state/di/tokenAccountStateTypes.js.map +7 -0
  82. package/lib/cjs/src/modules/solana/token-account-state/domain/TokenAccountStateContextLoader.js +2 -0
  83. package/lib/cjs/src/modules/solana/token-account-state/domain/TokenAccountStateContextLoader.js.map +7 -0
  84. package/lib/cjs/src/modules/solana/token-account-state/domain/TokenAccountStateContextLoader.test.js +2 -0
  85. package/lib/cjs/src/modules/solana/token-account-state/domain/TokenAccountStateContextLoader.test.js.map +7 -0
  86. package/lib/cjs/src/modules/solana/token-info/data/HttpTokenInfoDataSource.js +2 -0
  87. package/lib/cjs/src/modules/solana/token-info/data/HttpTokenInfoDataSource.js.map +7 -0
  88. package/lib/cjs/src/modules/solana/token-info/data/HttpTokenInfoDataSource.test.js +2 -0
  89. package/lib/cjs/src/modules/solana/token-info/data/HttpTokenInfoDataSource.test.js.map +7 -0
  90. package/lib/cjs/src/modules/solana/token-info/data/TokenInfoDataSource.js +2 -0
  91. package/lib/cjs/src/modules/solana/token-info/data/TokenInfoDataSource.js.map +7 -0
  92. package/lib/cjs/src/modules/solana/token-info/di/tokenInfoModuleFactory.js +2 -0
  93. package/lib/cjs/src/modules/solana/token-info/di/tokenInfoModuleFactory.js.map +7 -0
  94. package/lib/cjs/src/modules/solana/token-info/di/tokenInfoTypes.js +2 -0
  95. package/lib/cjs/src/modules/solana/token-info/di/tokenInfoTypes.js.map +7 -0
  96. package/lib/cjs/src/modules/solana/token-info/domain/TokenInfoContextLoader.js +2 -0
  97. package/lib/cjs/src/modules/solana/token-info/domain/TokenInfoContextLoader.js.map +7 -0
  98. package/lib/cjs/src/modules/solana/token-info/domain/TokenInfoContextLoader.test.js +2 -0
  99. package/lib/cjs/src/modules/solana/token-info/domain/TokenInfoContextLoader.test.js.map +7 -0
  100. package/lib/cjs/src/modules/solana/trusted-name/data/HttpTrustedNameDataSource.js +2 -0
  101. package/lib/cjs/src/modules/solana/trusted-name/data/HttpTrustedNameDataSource.js.map +7 -0
  102. package/lib/cjs/src/modules/solana/trusted-name/data/HttpTrustedNameDataSource.test.js +2 -0
  103. package/lib/cjs/src/modules/solana/trusted-name/data/HttpTrustedNameDataSource.test.js.map +7 -0
  104. package/lib/cjs/src/modules/solana/trusted-name/data/TrustedNameDataSource.js +2 -0
  105. package/lib/cjs/src/modules/solana/trusted-name/data/TrustedNameDataSource.js.map +7 -0
  106. package/lib/cjs/src/modules/solana/trusted-name/di/trustedNameModuleFactory.js +2 -0
  107. package/lib/cjs/src/modules/solana/trusted-name/di/trustedNameModuleFactory.js.map +7 -0
  108. package/lib/cjs/src/modules/solana/trusted-name/di/trustedNameTypes.js +2 -0
  109. package/lib/cjs/src/modules/solana/trusted-name/di/trustedNameTypes.js.map +7 -0
  110. package/lib/cjs/src/modules/solana/trusted-name/domain/TrustedNameContextLoader.js +2 -0
  111. package/lib/cjs/src/modules/solana/trusted-name/domain/TrustedNameContextLoader.js.map +7 -0
  112. package/lib/cjs/src/modules/solana/trusted-name/domain/TrustedNameContextLoader.test.js +2 -0
  113. package/lib/cjs/src/modules/solana/trusted-name/domain/TrustedNameContextLoader.test.js.map +7 -0
  114. package/lib/cjs/src/shared/model/ClearSignContext.js +1 -1
  115. package/lib/cjs/src/shared/model/ClearSignContext.js.map +2 -2
  116. package/lib/cjs/src/shared/utils/HexStringUtils.js +1 -1
  117. package/lib/cjs/src/shared/utils/HexStringUtils.js.map +3 -3
  118. package/lib/cjs/src/shared/utils/HexStringUtils.test.js +1 -1
  119. package/lib/cjs/src/shared/utils/HexStringUtils.test.js.map +2 -2
  120. package/lib/cjs/src/shared/utils/certificateCache.js +2 -0
  121. package/lib/cjs/src/shared/utils/certificateCache.js.map +7 -0
  122. package/lib/cjs/src/shared/utils/certificateCache.test.js +2 -0
  123. package/lib/cjs/src/shared/utils/certificateCache.test.js.map +7 -0
  124. package/lib/cjs/src/shared/utils/certificateResult.js +2 -0
  125. package/lib/cjs/src/shared/utils/certificateResult.js.map +7 -0
  126. package/lib/cjs/src/shared/utils/certificateResult.test.js +2 -0
  127. package/lib/cjs/src/shared/utils/certificateResult.test.js.map +7 -0
  128. package/lib/cjs/src/shared/utils/challengeBoundLoader.js +2 -0
  129. package/lib/cjs/src/shared/utils/challengeBoundLoader.js.map +7 -0
  130. package/lib/cjs/src/shared/utils/challengeBoundLoader.test.js +2 -0
  131. package/lib/cjs/src/shared/utils/challengeBoundLoader.test.js.map +7 -0
  132. package/lib/cjs/src/shared/utils/deviceModelIdCodec.js +2 -0
  133. package/lib/cjs/src/shared/utils/deviceModelIdCodec.js.map +7 -0
  134. package/lib/cjs/src/shared/utils/deviceModelIdCodec.test.js +2 -0
  135. package/lib/cjs/src/shared/utils/deviceModelIdCodec.test.js.map +7 -0
  136. package/lib/cjs/src/shared/utils/signedDescriptorDto.js +2 -0
  137. package/lib/cjs/src/shared/utils/signedDescriptorDto.js.map +7 -0
  138. package/lib/cjs/src/shared/utils/signedDescriptorDto.test.js +2 -0
  139. package/lib/cjs/src/shared/utils/signedDescriptorDto.test.js.map +7 -0
  140. package/lib/cjs/src/shared/utils/uIntCodec.js +2 -0
  141. package/lib/cjs/src/shared/utils/uIntCodec.js.map +7 -0
  142. package/lib/cjs/src/shared/utils/uIntCodec.test.js +2 -0
  143. package/lib/cjs/src/shared/utils/uIntCodec.test.js.map +7 -0
  144. package/lib/esm/package.json +2 -2
  145. package/lib/esm/src/DefaultContextModule.js +1 -1
  146. package/lib/esm/src/DefaultContextModule.js.map +3 -3
  147. package/lib/esm/src/di.js +1 -1
  148. package/lib/esm/src/di.js.map +3 -3
  149. package/lib/esm/src/index.js +1 -1
  150. package/lib/esm/src/index.js.map +2 -2
  151. package/lib/esm/src/modules/multichain/pki/model/KeyId.js +1 -1
  152. package/lib/esm/src/modules/multichain/pki/model/KeyId.js.map +2 -2
  153. package/lib/esm/src/modules/multichain/transaction-check/loaders/SolanaTransactionCheckLoader.js +1 -1
  154. package/lib/esm/src/modules/multichain/transaction-check/loaders/SolanaTransactionCheckLoader.js.map +3 -3
  155. package/lib/esm/src/modules/multichain/transaction-check/loaders/SolanaTransactionCheckLoader.test.js +1 -1
  156. package/lib/esm/src/modules/multichain/transaction-check/loaders/SolanaTransactionCheckLoader.test.js.map +3 -3
  157. package/lib/esm/src/modules/solana/alt-resolution/data/AltResolutionDataSource.js +1 -0
  158. package/lib/esm/src/modules/solana/alt-resolution/data/AltResolutionDataSource.js.map +7 -0
  159. package/lib/esm/src/modules/solana/alt-resolution/data/HttpAltResolutionDataSource.js +2 -0
  160. package/lib/esm/src/modules/solana/alt-resolution/data/HttpAltResolutionDataSource.js.map +7 -0
  161. package/lib/esm/src/modules/solana/alt-resolution/data/HttpAltResolutionDataSource.test.js +2 -0
  162. package/lib/esm/src/modules/solana/alt-resolution/data/HttpAltResolutionDataSource.test.js.map +7 -0
  163. package/lib/esm/src/modules/solana/alt-resolution/di/altResolutionModuleFactory.js +2 -0
  164. package/lib/esm/src/modules/solana/alt-resolution/di/altResolutionModuleFactory.js.map +7 -0
  165. package/lib/esm/src/modules/solana/alt-resolution/di/altResolutionTypes.js +2 -0
  166. package/lib/esm/src/modules/solana/alt-resolution/di/altResolutionTypes.js.map +7 -0
  167. package/lib/esm/src/modules/solana/alt-resolution/domain/AltResolutionContextLoader.js +2 -0
  168. package/lib/esm/src/modules/solana/alt-resolution/domain/AltResolutionContextLoader.js.map +7 -0
  169. package/lib/esm/src/modules/solana/alt-resolution/domain/AltResolutionContextLoader.test.js +2 -0
  170. package/lib/esm/src/modules/solana/alt-resolution/domain/AltResolutionContextLoader.test.js.map +7 -0
  171. package/lib/esm/src/modules/solana/enum-variant/di/enumVariantModuleFactory.js +2 -0
  172. package/lib/esm/src/modules/solana/enum-variant/di/enumVariantModuleFactory.js.map +7 -0
  173. package/lib/esm/src/modules/solana/enum-variant/di/enumVariantTypes.js +2 -0
  174. package/lib/esm/src/modules/solana/enum-variant/di/enumVariantTypes.js.map +7 -0
  175. package/lib/esm/src/modules/solana/enum-variant/domain/EnumVariantContextLoader.js +2 -0
  176. package/lib/esm/src/modules/solana/enum-variant/domain/EnumVariantContextLoader.js.map +7 -0
  177. package/lib/esm/src/modules/solana/enum-variant/domain/EnumVariantContextLoader.test.js +2 -0
  178. package/lib/esm/src/modules/solana/enum-variant/domain/EnumVariantContextLoader.test.js.map +7 -0
  179. package/lib/esm/src/modules/solana/instruction-info/data/HttpInstructionInfoDataSource.js +2 -0
  180. package/lib/esm/src/modules/solana/instruction-info/data/HttpInstructionInfoDataSource.js.map +7 -0
  181. package/lib/esm/src/modules/solana/instruction-info/data/HttpInstructionInfoDataSource.test.js +2 -0
  182. package/lib/esm/src/modules/solana/instruction-info/data/HttpInstructionInfoDataSource.test.js.map +7 -0
  183. package/lib/esm/src/modules/solana/instruction-info/data/InstructionInfoDataSource.js +1 -0
  184. package/lib/esm/src/modules/solana/instruction-info/data/InstructionInfoDataSource.js.map +7 -0
  185. package/lib/esm/src/modules/solana/instruction-info/data/InstructionInfoDto.js +2 -0
  186. package/lib/esm/src/modules/solana/instruction-info/data/InstructionInfoDto.js.map +7 -0
  187. package/lib/esm/src/modules/solana/instruction-info/data/InstructionInfoMapper.js +2 -0
  188. package/lib/esm/src/modules/solana/instruction-info/data/InstructionInfoMapper.js.map +7 -0
  189. package/lib/esm/src/modules/solana/instruction-info/data/InstructionInfoMapper.test.js +2 -0
  190. package/lib/esm/src/modules/solana/instruction-info/data/InstructionInfoMapper.test.js.map +7 -0
  191. package/lib/esm/src/modules/solana/instruction-info/di/instructionInfoModuleFactory.js +2 -0
  192. package/lib/esm/src/modules/solana/instruction-info/di/instructionInfoModuleFactory.js.map +7 -0
  193. package/lib/esm/src/modules/solana/instruction-info/di/instructionInfoTypes.js +2 -0
  194. package/lib/esm/src/modules/solana/instruction-info/di/instructionInfoTypes.js.map +7 -0
  195. package/lib/esm/src/modules/solana/instruction-info/domain/InstructionInfoContextLoader.js +2 -0
  196. package/lib/esm/src/modules/solana/instruction-info/domain/InstructionInfoContextLoader.js.map +7 -0
  197. package/lib/esm/src/modules/solana/instruction-info/domain/InstructionInfoContextLoader.test.js +2 -0
  198. package/lib/esm/src/modules/solana/instruction-info/domain/InstructionInfoContextLoader.test.js.map +7 -0
  199. package/lib/esm/src/modules/solana/model/SolanaClearSignContext.js +1 -1
  200. package/lib/esm/src/modules/solana/model/SolanaClearSignContext.js.map +3 -3
  201. package/lib/esm/src/modules/solana/model/SolanaPayloads.js +1 -0
  202. package/lib/esm/src/modules/solana/model/SolanaPayloads.js.map +4 -4
  203. package/lib/esm/src/modules/solana/model/SolanaTransactionScanChainId.js +1 -1
  204. package/lib/esm/src/modules/solana/model/SolanaTransactionScanChainId.js.map +2 -2
  205. package/lib/esm/src/modules/solana/owner-info/domain/OwnerInfoContextLoader.js +1 -1
  206. package/lib/esm/src/modules/solana/owner-info/domain/OwnerInfoContextLoader.js.map +2 -2
  207. package/lib/esm/src/modules/solana/owner-info/domain/OwnerInfoContextLoader.test.js +1 -1
  208. package/lib/esm/src/modules/solana/owner-info/domain/OwnerInfoContextLoader.test.js.map +2 -2
  209. package/lib/esm/src/modules/solana/token/domain/TokenContextLoader.js +1 -1
  210. package/lib/esm/src/modules/solana/token/domain/TokenContextLoader.js.map +3 -3
  211. package/lib/esm/src/modules/solana/token-account-state/data/HttpTokenAccountStateDataSource.js +2 -0
  212. package/lib/esm/src/modules/solana/token-account-state/data/HttpTokenAccountStateDataSource.js.map +7 -0
  213. package/lib/esm/src/modules/solana/token-account-state/data/HttpTokenAccountStateDataSource.test.js +2 -0
  214. package/lib/esm/src/modules/solana/token-account-state/data/HttpTokenAccountStateDataSource.test.js.map +7 -0
  215. package/lib/esm/src/modules/solana/token-account-state/data/TokenAccountStateDataSource.js +1 -0
  216. package/lib/esm/src/modules/solana/token-account-state/data/TokenAccountStateDataSource.js.map +7 -0
  217. package/lib/esm/src/modules/solana/token-account-state/di/tokenAccountStateModuleFactory.js +2 -0
  218. package/lib/esm/src/modules/solana/token-account-state/di/tokenAccountStateModuleFactory.js.map +7 -0
  219. package/lib/esm/src/modules/solana/token-account-state/di/tokenAccountStateTypes.js +2 -0
  220. package/lib/esm/src/modules/solana/token-account-state/di/tokenAccountStateTypes.js.map +7 -0
  221. package/lib/esm/src/modules/solana/token-account-state/domain/TokenAccountStateContextLoader.js +2 -0
  222. package/lib/esm/src/modules/solana/token-account-state/domain/TokenAccountStateContextLoader.js.map +7 -0
  223. package/lib/esm/src/modules/solana/token-account-state/domain/TokenAccountStateContextLoader.test.js +2 -0
  224. package/lib/esm/src/modules/solana/token-account-state/domain/TokenAccountStateContextLoader.test.js.map +7 -0
  225. package/lib/esm/src/modules/solana/token-info/data/HttpTokenInfoDataSource.js +2 -0
  226. package/lib/esm/src/modules/solana/token-info/data/HttpTokenInfoDataSource.js.map +7 -0
  227. package/lib/esm/src/modules/solana/token-info/data/HttpTokenInfoDataSource.test.js +2 -0
  228. package/lib/esm/src/modules/solana/token-info/data/HttpTokenInfoDataSource.test.js.map +7 -0
  229. package/lib/esm/src/modules/solana/token-info/data/TokenInfoDataSource.js +1 -0
  230. package/lib/esm/src/modules/solana/token-info/data/TokenInfoDataSource.js.map +7 -0
  231. package/lib/esm/src/modules/solana/token-info/di/tokenInfoModuleFactory.js +2 -0
  232. package/lib/esm/src/modules/solana/token-info/di/tokenInfoModuleFactory.js.map +7 -0
  233. package/lib/esm/src/modules/solana/token-info/di/tokenInfoTypes.js +2 -0
  234. package/lib/esm/src/modules/solana/token-info/di/tokenInfoTypes.js.map +7 -0
  235. package/lib/esm/src/modules/solana/token-info/domain/TokenInfoContextLoader.js +2 -0
  236. package/lib/esm/src/modules/solana/token-info/domain/TokenInfoContextLoader.js.map +7 -0
  237. package/lib/esm/src/modules/solana/token-info/domain/TokenInfoContextLoader.test.js +2 -0
  238. package/lib/esm/src/modules/solana/token-info/domain/TokenInfoContextLoader.test.js.map +7 -0
  239. package/lib/esm/src/modules/solana/trusted-name/data/HttpTrustedNameDataSource.js +2 -0
  240. package/lib/esm/src/modules/solana/trusted-name/data/HttpTrustedNameDataSource.js.map +7 -0
  241. package/lib/esm/src/modules/solana/trusted-name/data/HttpTrustedNameDataSource.test.js +2 -0
  242. package/lib/esm/src/modules/solana/trusted-name/data/HttpTrustedNameDataSource.test.js.map +7 -0
  243. package/lib/esm/src/modules/solana/trusted-name/data/TrustedNameDataSource.js +1 -0
  244. package/lib/esm/src/modules/solana/trusted-name/data/TrustedNameDataSource.js.map +7 -0
  245. package/lib/esm/src/modules/solana/trusted-name/di/trustedNameModuleFactory.js +2 -0
  246. package/lib/esm/src/modules/solana/trusted-name/di/trustedNameModuleFactory.js.map +7 -0
  247. package/lib/esm/src/modules/solana/trusted-name/di/trustedNameTypes.js +2 -0
  248. package/lib/esm/src/modules/solana/trusted-name/di/trustedNameTypes.js.map +7 -0
  249. package/lib/esm/src/modules/solana/trusted-name/domain/TrustedNameContextLoader.js +2 -0
  250. package/lib/esm/src/modules/solana/trusted-name/domain/TrustedNameContextLoader.js.map +7 -0
  251. package/lib/esm/src/modules/solana/trusted-name/domain/TrustedNameContextLoader.test.js +2 -0
  252. package/lib/esm/src/modules/solana/trusted-name/domain/TrustedNameContextLoader.test.js.map +7 -0
  253. package/lib/esm/src/shared/model/ClearSignContext.js +1 -1
  254. package/lib/esm/src/shared/model/ClearSignContext.js.map +2 -2
  255. package/lib/esm/src/shared/utils/HexStringUtils.js +1 -1
  256. package/lib/esm/src/shared/utils/HexStringUtils.js.map +3 -3
  257. package/lib/esm/src/shared/utils/HexStringUtils.test.js +1 -1
  258. package/lib/esm/src/shared/utils/HexStringUtils.test.js.map +2 -2
  259. package/lib/esm/src/shared/utils/certificateCache.js +2 -0
  260. package/lib/esm/src/shared/utils/certificateCache.js.map +7 -0
  261. package/lib/esm/src/shared/utils/certificateCache.test.js +2 -0
  262. package/lib/esm/src/shared/utils/certificateCache.test.js.map +7 -0
  263. package/lib/esm/src/shared/utils/certificateResult.js +2 -0
  264. package/lib/esm/src/shared/utils/certificateResult.js.map +7 -0
  265. package/lib/esm/src/shared/utils/certificateResult.test.js +2 -0
  266. package/lib/esm/src/shared/utils/certificateResult.test.js.map +7 -0
  267. package/lib/esm/src/shared/utils/challengeBoundLoader.js +2 -0
  268. package/lib/esm/src/shared/utils/challengeBoundLoader.js.map +7 -0
  269. package/lib/esm/src/shared/utils/challengeBoundLoader.test.js +2 -0
  270. package/lib/esm/src/shared/utils/challengeBoundLoader.test.js.map +7 -0
  271. package/lib/esm/src/shared/utils/deviceModelIdCodec.js +2 -0
  272. package/lib/esm/src/shared/utils/deviceModelIdCodec.js.map +7 -0
  273. package/lib/esm/src/shared/utils/deviceModelIdCodec.test.js +2 -0
  274. package/lib/esm/src/shared/utils/deviceModelIdCodec.test.js.map +7 -0
  275. package/lib/esm/src/shared/utils/signedDescriptorDto.js +2 -0
  276. package/lib/esm/src/shared/utils/signedDescriptorDto.js.map +7 -0
  277. package/lib/esm/src/shared/utils/signedDescriptorDto.test.js +2 -0
  278. package/lib/esm/src/shared/utils/signedDescriptorDto.test.js.map +7 -0
  279. package/lib/esm/src/shared/utils/uIntCodec.js +2 -0
  280. package/lib/esm/src/shared/utils/uIntCodec.js.map +7 -0
  281. package/lib/esm/src/shared/utils/uIntCodec.test.js +2 -0
  282. package/lib/esm/src/shared/utils/uIntCodec.test.js.map +7 -0
  283. package/lib/types/src/DefaultContextModule.d.ts.map +1 -1
  284. package/lib/types/src/di.d.ts.map +1 -1
  285. package/lib/types/src/index.d.ts +16 -0
  286. package/lib/types/src/index.d.ts.map +1 -1
  287. package/lib/types/src/modules/multichain/pki/model/KeyId.d.ts +1 -0
  288. package/lib/types/src/modules/multichain/pki/model/KeyId.d.ts.map +1 -1
  289. package/lib/types/src/modules/multichain/transaction-check/loaders/SolanaTransactionCheckLoader.d.ts +1 -1
  290. package/lib/types/src/modules/multichain/transaction-check/loaders/SolanaTransactionCheckLoader.d.ts.map +1 -1
  291. package/lib/types/src/modules/solana/alt-resolution/data/AltResolutionDataSource.d.ts +17 -0
  292. package/lib/types/src/modules/solana/alt-resolution/data/AltResolutionDataSource.d.ts.map +1 -0
  293. package/lib/types/src/modules/solana/alt-resolution/data/HttpAltResolutionDataSource.d.ts +11 -0
  294. package/lib/types/src/modules/solana/alt-resolution/data/HttpAltResolutionDataSource.d.ts.map +1 -0
  295. package/lib/types/src/modules/solana/alt-resolution/data/HttpAltResolutionDataSource.test.d.ts +2 -0
  296. package/lib/types/src/modules/solana/alt-resolution/data/HttpAltResolutionDataSource.test.d.ts.map +1 -0
  297. package/lib/types/src/modules/solana/alt-resolution/di/altResolutionModuleFactory.d.ts +3 -0
  298. package/lib/types/src/modules/solana/alt-resolution/di/altResolutionModuleFactory.d.ts.map +1 -0
  299. package/lib/types/src/modules/solana/alt-resolution/di/altResolutionTypes.d.ts +5 -0
  300. package/lib/types/src/modules/solana/alt-resolution/di/altResolutionTypes.d.ts.map +1 -0
  301. package/lib/types/src/modules/solana/alt-resolution/domain/AltResolutionContextLoader.d.ts +23 -0
  302. package/lib/types/src/modules/solana/alt-resolution/domain/AltResolutionContextLoader.d.ts.map +1 -0
  303. package/lib/types/src/modules/solana/alt-resolution/domain/AltResolutionContextLoader.test.d.ts +2 -0
  304. package/lib/types/src/modules/solana/alt-resolution/domain/AltResolutionContextLoader.test.d.ts.map +1 -0
  305. package/lib/types/src/modules/solana/enum-variant/di/enumVariantModuleFactory.d.ts +3 -0
  306. package/lib/types/src/modules/solana/enum-variant/di/enumVariantModuleFactory.d.ts.map +1 -0
  307. package/lib/types/src/modules/solana/enum-variant/di/enumVariantTypes.d.ts +4 -0
  308. package/lib/types/src/modules/solana/enum-variant/di/enumVariantTypes.d.ts.map +1 -0
  309. package/lib/types/src/modules/solana/enum-variant/domain/EnumVariantContextLoader.d.ts +45 -0
  310. package/lib/types/src/modules/solana/enum-variant/domain/EnumVariantContextLoader.d.ts.map +1 -0
  311. package/lib/types/src/modules/solana/enum-variant/domain/EnumVariantContextLoader.test.d.ts +2 -0
  312. package/lib/types/src/modules/solana/enum-variant/domain/EnumVariantContextLoader.test.d.ts.map +1 -0
  313. package/lib/types/src/modules/solana/instruction-info/data/HttpInstructionInfoDataSource.d.ts +11 -0
  314. package/lib/types/src/modules/solana/instruction-info/data/HttpInstructionInfoDataSource.d.ts.map +1 -0
  315. package/lib/types/src/modules/solana/instruction-info/data/HttpInstructionInfoDataSource.test.d.ts +2 -0
  316. package/lib/types/src/modules/solana/instruction-info/data/HttpInstructionInfoDataSource.test.d.ts.map +1 -0
  317. package/lib/types/src/modules/solana/instruction-info/data/InstructionInfoDataSource.d.ts +32 -0
  318. package/lib/types/src/modules/solana/instruction-info/data/InstructionInfoDataSource.d.ts.map +1 -0
  319. package/lib/types/src/modules/solana/instruction-info/data/InstructionInfoDto.d.ts +135 -0
  320. package/lib/types/src/modules/solana/instruction-info/data/InstructionInfoDto.d.ts.map +1 -0
  321. package/lib/types/src/modules/solana/instruction-info/data/InstructionInfoMapper.d.ts +23 -0
  322. package/lib/types/src/modules/solana/instruction-info/data/InstructionInfoMapper.d.ts.map +1 -0
  323. package/lib/types/src/modules/solana/instruction-info/data/InstructionInfoMapper.test.d.ts +2 -0
  324. package/lib/types/src/modules/solana/instruction-info/data/InstructionInfoMapper.test.d.ts.map +1 -0
  325. package/lib/types/src/modules/solana/instruction-info/di/instructionInfoModuleFactory.d.ts +3 -0
  326. package/lib/types/src/modules/solana/instruction-info/di/instructionInfoModuleFactory.d.ts.map +1 -0
  327. package/lib/types/src/modules/solana/instruction-info/di/instructionInfoTypes.d.ts +5 -0
  328. package/lib/types/src/modules/solana/instruction-info/di/instructionInfoTypes.d.ts.map +1 -0
  329. package/lib/types/src/modules/solana/instruction-info/domain/InstructionInfoContextLoader.d.ts +39 -0
  330. package/lib/types/src/modules/solana/instruction-info/domain/InstructionInfoContextLoader.d.ts.map +1 -0
  331. package/lib/types/src/modules/solana/instruction-info/domain/InstructionInfoContextLoader.test.d.ts +2 -0
  332. package/lib/types/src/modules/solana/instruction-info/domain/InstructionInfoContextLoader.test.d.ts.map +1 -0
  333. package/lib/types/src/modules/solana/model/SolanaClearSignContext.d.ts +33 -2
  334. package/lib/types/src/modules/solana/model/SolanaClearSignContext.d.ts.map +1 -1
  335. package/lib/types/src/modules/solana/model/SolanaContextTypes.d.ts +8 -1
  336. package/lib/types/src/modules/solana/model/SolanaContextTypes.d.ts.map +1 -1
  337. package/lib/types/src/modules/solana/model/SolanaPayloads.d.ts +126 -0
  338. package/lib/types/src/modules/solana/model/SolanaPayloads.d.ts.map +1 -1
  339. package/lib/types/src/modules/solana/model/SolanaTransactionScanChainId.d.ts +6 -5
  340. package/lib/types/src/modules/solana/model/SolanaTransactionScanChainId.d.ts.map +1 -1
  341. package/lib/types/src/modules/solana/owner-info/domain/solanaContextTypes.d.ts +2 -5
  342. package/lib/types/src/modules/solana/owner-info/domain/solanaContextTypes.d.ts.map +1 -1
  343. package/lib/types/src/modules/solana/token/domain/TokenContextLoader.d.ts.map +1 -1
  344. package/lib/types/src/modules/solana/token-account-state/data/HttpTokenAccountStateDataSource.d.ts +11 -0
  345. package/lib/types/src/modules/solana/token-account-state/data/HttpTokenAccountStateDataSource.d.ts.map +1 -0
  346. package/lib/types/src/modules/solana/token-account-state/data/HttpTokenAccountStateDataSource.test.d.ts +2 -0
  347. package/lib/types/src/modules/solana/token-account-state/data/HttpTokenAccountStateDataSource.test.d.ts.map +1 -0
  348. package/lib/types/src/modules/solana/token-account-state/data/TokenAccountStateDataSource.d.ts +15 -0
  349. package/lib/types/src/modules/solana/token-account-state/data/TokenAccountStateDataSource.d.ts.map +1 -0
  350. package/lib/types/src/modules/solana/token-account-state/di/tokenAccountStateModuleFactory.d.ts +3 -0
  351. package/lib/types/src/modules/solana/token-account-state/di/tokenAccountStateModuleFactory.d.ts.map +1 -0
  352. package/lib/types/src/modules/solana/token-account-state/di/tokenAccountStateTypes.d.ts +5 -0
  353. package/lib/types/src/modules/solana/token-account-state/di/tokenAccountStateTypes.d.ts.map +1 -0
  354. package/lib/types/src/modules/solana/token-account-state/domain/TokenAccountStateContextLoader.d.ts +26 -0
  355. package/lib/types/src/modules/solana/token-account-state/domain/TokenAccountStateContextLoader.d.ts.map +1 -0
  356. package/lib/types/src/modules/solana/token-account-state/domain/TokenAccountStateContextLoader.test.d.ts +2 -0
  357. package/lib/types/src/modules/solana/token-account-state/domain/TokenAccountStateContextLoader.test.d.ts.map +1 -0
  358. package/lib/types/src/modules/solana/token-info/data/HttpTokenInfoDataSource.d.ts +11 -0
  359. package/lib/types/src/modules/solana/token-info/data/HttpTokenInfoDataSource.d.ts.map +1 -0
  360. package/lib/types/src/modules/solana/token-info/data/HttpTokenInfoDataSource.test.d.ts +2 -0
  361. package/lib/types/src/modules/solana/token-info/data/HttpTokenInfoDataSource.test.d.ts.map +1 -0
  362. package/lib/types/src/modules/solana/token-info/data/TokenInfoDataSource.d.ts +24 -0
  363. package/lib/types/src/modules/solana/token-info/data/TokenInfoDataSource.d.ts.map +1 -0
  364. package/lib/types/src/modules/solana/token-info/di/tokenInfoModuleFactory.d.ts +3 -0
  365. package/lib/types/src/modules/solana/token-info/di/tokenInfoModuleFactory.d.ts.map +1 -0
  366. package/lib/types/src/modules/solana/token-info/di/tokenInfoTypes.d.ts +5 -0
  367. package/lib/types/src/modules/solana/token-info/di/tokenInfoTypes.d.ts.map +1 -0
  368. package/lib/types/src/modules/solana/token-info/domain/TokenInfoContextLoader.d.ts +26 -0
  369. package/lib/types/src/modules/solana/token-info/domain/TokenInfoContextLoader.d.ts.map +1 -0
  370. package/lib/types/src/modules/solana/token-info/domain/TokenInfoContextLoader.test.d.ts +2 -0
  371. package/lib/types/src/modules/solana/token-info/domain/TokenInfoContextLoader.test.d.ts.map +1 -0
  372. package/lib/types/src/modules/solana/trusted-name/data/HttpTrustedNameDataSource.d.ts +11 -0
  373. package/lib/types/src/modules/solana/trusted-name/data/HttpTrustedNameDataSource.d.ts.map +1 -0
  374. package/lib/types/src/modules/solana/trusted-name/data/HttpTrustedNameDataSource.test.d.ts +2 -0
  375. package/lib/types/src/modules/solana/trusted-name/data/HttpTrustedNameDataSource.test.d.ts.map +1 -0
  376. package/lib/types/src/modules/solana/trusted-name/data/TrustedNameDataSource.d.ts +18 -0
  377. package/lib/types/src/modules/solana/trusted-name/data/TrustedNameDataSource.d.ts.map +1 -0
  378. package/lib/types/src/modules/solana/trusted-name/di/trustedNameModuleFactory.d.ts +3 -0
  379. package/lib/types/src/modules/solana/trusted-name/di/trustedNameModuleFactory.d.ts.map +1 -0
  380. package/lib/types/src/modules/solana/trusted-name/di/trustedNameTypes.d.ts +5 -0
  381. package/lib/types/src/modules/solana/trusted-name/di/trustedNameTypes.d.ts.map +1 -0
  382. package/lib/types/src/modules/solana/trusted-name/domain/TrustedNameContextLoader.d.ts +29 -0
  383. package/lib/types/src/modules/solana/trusted-name/domain/TrustedNameContextLoader.d.ts.map +1 -0
  384. package/lib/types/src/modules/solana/trusted-name/domain/TrustedNameContextLoader.test.d.ts +2 -0
  385. package/lib/types/src/modules/solana/trusted-name/domain/TrustedNameContextLoader.test.d.ts.map +1 -0
  386. package/lib/types/src/shared/model/ClearSignContext.d.ts +7 -1
  387. package/lib/types/src/shared/model/ClearSignContext.d.ts.map +1 -1
  388. package/lib/types/src/shared/utils/HexStringUtils.d.ts +7 -0
  389. package/lib/types/src/shared/utils/HexStringUtils.d.ts.map +1 -1
  390. package/lib/types/src/shared/utils/certificateCache.d.ts +23 -0
  391. package/lib/types/src/shared/utils/certificateCache.d.ts.map +1 -0
  392. package/lib/types/src/shared/utils/certificateCache.test.d.ts +2 -0
  393. package/lib/types/src/shared/utils/certificateCache.test.d.ts.map +1 -0
  394. package/lib/types/src/shared/utils/certificateResult.d.ts +26 -0
  395. package/lib/types/src/shared/utils/certificateResult.d.ts.map +1 -0
  396. package/lib/types/src/shared/utils/certificateResult.test.d.ts +2 -0
  397. package/lib/types/src/shared/utils/certificateResult.test.d.ts.map +1 -0
  398. package/lib/types/src/shared/utils/challengeBoundLoader.d.ts +43 -0
  399. package/lib/types/src/shared/utils/challengeBoundLoader.d.ts.map +1 -0
  400. package/lib/types/src/shared/utils/challengeBoundLoader.test.d.ts +2 -0
  401. package/lib/types/src/shared/utils/challengeBoundLoader.test.d.ts.map +1 -0
  402. package/lib/types/src/shared/utils/deviceModelIdCodec.d.ts +7 -0
  403. package/lib/types/src/shared/utils/deviceModelIdCodec.d.ts.map +1 -0
  404. package/lib/types/src/shared/utils/deviceModelIdCodec.test.d.ts +2 -0
  405. package/lib/types/src/shared/utils/deviceModelIdCodec.test.d.ts.map +1 -0
  406. package/lib/types/src/shared/utils/signedDescriptorDto.d.ts +15 -0
  407. package/lib/types/src/shared/utils/signedDescriptorDto.d.ts.map +1 -0
  408. package/lib/types/src/shared/utils/signedDescriptorDto.test.d.ts +2 -0
  409. package/lib/types/src/shared/utils/signedDescriptorDto.test.d.ts.map +1 -0
  410. package/lib/types/src/shared/utils/uIntCodec.d.ts +20 -0
  411. package/lib/types/src/shared/utils/uIntCodec.d.ts.map +1 -0
  412. package/lib/types/src/shared/utils/uIntCodec.test.d.ts +2 -0
  413. package/lib/types/src/shared/utils/uIntCodec.test.d.ts.map +1 -0
  414. package/lib/types/tsconfig.prod.tsbuildinfo +1 -1
  415. package/package.json +6 -6
@@ -0,0 +1,7 @@
1
+ {
2
+ "version": 3,
3
+ "sources": ["../../../../../../../src/modules/solana/alt-resolution/domain/AltResolutionContextLoader.test.ts"],
4
+ "sourcesContent": ["/* eslint-disable @typescript-eslint/no-explicit-any */\nimport { DeviceModelId } from \"@ledgerhq/device-management-kit\";\nimport { Left, Right } from \"purify-ts\";\n\nimport { type PkiCertificateLoader } from \"@/modules/multichain/pki/domain/PkiCertificateLoader\";\nimport { type AltResolutionDataSource } from \"@/modules/solana/alt-resolution/data/AltResolutionDataSource\";\nimport { ClearSignContextType } from \"@/shared/model/ClearSignContext\";\n\nimport { AltResolutionContextLoader } from \"./AltResolutionContextLoader\";\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 = { keyUsageNumber: 8, payload: new Uint8Array([1]) };\nconst ALT_A = \"AltA1111111111111111111111111111111111111111\";\nconst ALT_B = \"AltB2222222222222222222222222222222222222222\";\n\ndescribe(\"AltResolutionContextLoader\", () => {\n let dataSource: AltResolutionDataSource;\n let certificateLoader: PkiCertificateLoader;\n\n beforeEach(() => {\n vi.restoreAllMocks();\n dataSource = {\n getAltResolution: vi.fn(),\n };\n certificateLoader = {\n loadCertificate: vi.fn().mockResolvedValue(mockCertificate),\n };\n });\n\n const makeLoader = () =>\n new AltResolutionContextLoader(\n dataSource,\n certificateLoader,\n mockLoggerFactory,\n );\n\n describe(\"canHandle\", () => {\n it(\"returns true when SOLANA_ALT_RESOLUTION is requested with valid requests\", () => {\n expect(\n makeLoader().canHandle(\n {\n deviceModelId: DeviceModelId.NANO_X,\n requests: [{ altAddress: ALT_A, entryIndex: 0, challenge: \"c\" }],\n },\n [ClearSignContextType.SOLANA_ALT_RESOLUTION],\n ),\n ).toBe(true);\n });\n\n it(\"returns false when SOLANA_ALT_RESOLUTION is not requested\", () => {\n expect(\n makeLoader().canHandle(\n {\n deviceModelId: DeviceModelId.NANO_X,\n requests: [{ altAddress: ALT_A, entryIndex: 0, challenge: \"c\" }],\n },\n [ClearSignContextType.SOLANA_TOKEN],\n ),\n ).toBe(false);\n });\n\n it(\"rejects out-of-range entryIndex\", () => {\n const loader = makeLoader();\n const types = [ClearSignContextType.SOLANA_ALT_RESOLUTION];\n expect(\n loader.canHandle(\n {\n requests: [{ altAddress: ALT_A, entryIndex: -1, challenge: \"c\" }],\n } as any,\n types,\n ),\n ).toBe(false);\n expect(\n loader.canHandle(\n {\n requests: [{ altAddress: ALT_A, entryIndex: 256, challenge: \"c\" }],\n } as any,\n types,\n ),\n ).toBe(false);\n expect(\n loader.canHandle(\n {\n requests: [{ altAddress: ALT_A, entryIndex: 1.5, challenge: \"c\" }],\n } as any,\n types,\n ),\n ).toBe(false);\n });\n });\n\n describe(\"load\", () => {\n it(\"emits one SOLANA_ALT_RESOLUTION per request\", async () => {\n vi.spyOn(dataSource, \"getAltResolution\").mockImplementation(\n async ({ altAddress, entryIndex }) =>\n Right({\n altAddress,\n entryIndex,\n descriptor: new Uint8Array([entryIndex]),\n keyId: \"alt_key\",\n keyUsage: \"coin_meta\",\n }),\n );\n\n const result = await makeLoader().load({\n deviceModelId: DeviceModelId.NANO_X,\n requests: [\n { altAddress: ALT_A, entryIndex: 1, challenge: \"c1\" },\n { altAddress: ALT_B, entryIndex: 7, challenge: \"c2\" },\n ],\n });\n\n expect(result).toHaveLength(2);\n expect(result[0]).toMatchObject({\n type: ClearSignContextType.SOLANA_ALT_RESOLUTION,\n payload: { descriptor: new Uint8Array([1]) },\n certificate: mockCertificate,\n });\n expect(result[1]).toMatchObject({\n type: ClearSignContextType.SOLANA_ALT_RESOLUTION,\n payload: { descriptor: new Uint8Array([7]) },\n });\n });\n\n it(\"dedups certificate loads across requests sharing the same (keyId, keyUsage)\", async () => {\n vi.spyOn(dataSource, \"getAltResolution\").mockImplementation(\n async ({ altAddress, entryIndex }) =>\n Right({\n altAddress,\n entryIndex,\n descriptor: new Uint8Array([entryIndex]),\n keyId: \"alt_key\",\n keyUsage: \"coin_meta\",\n }),\n );\n\n await makeLoader().load({\n deviceModelId: DeviceModelId.NANO_X,\n requests: [\n { altAddress: ALT_A, entryIndex: 0, challenge: \"c1\" },\n { altAddress: ALT_A, entryIndex: 1, challenge: \"c2\" },\n { altAddress: ALT_B, entryIndex: 2, challenge: \"c3\" },\n ],\n });\n\n expect(certificateLoader.loadCertificate).toHaveBeenCalledTimes(1);\n });\n\n it(\"issues distinct cert loads when (keyId, keyUsage) differ\", async () => {\n vi.spyOn(dataSource, \"getAltResolution\").mockImplementation(\n async ({ altAddress, entryIndex }) =>\n Right({\n altAddress,\n entryIndex,\n descriptor: new Uint8Array([entryIndex]),\n keyId: altAddress === ALT_A ? \"alt_key_a\" : \"alt_key_b\",\n keyUsage: \"coin_meta\",\n }),\n );\n\n await makeLoader().load({\n deviceModelId: DeviceModelId.NANO_X,\n requests: [\n { altAddress: ALT_A, entryIndex: 0, challenge: \"c1\" },\n { altAddress: ALT_B, entryIndex: 1, challenge: \"c2\" },\n ],\n });\n\n expect(certificateLoader.loadCertificate).toHaveBeenCalledTimes(2);\n });\n\n it(\"emits an ERROR per failing request and keeps the others\", async () => {\n vi.spyOn(dataSource, \"getAltResolution\").mockImplementation(\n async ({ altAddress }) => {\n if (altAddress === ALT_A) {\n return Right({\n altAddress,\n entryIndex: 0,\n descriptor: new Uint8Array([0xaa]),\n keyId: \"k\",\n keyUsage: \"u\",\n });\n }\n return Left(new Error(\"upstream-500\"));\n },\n );\n\n const out = await makeLoader().load({\n deviceModelId: DeviceModelId.NANO_X,\n requests: [\n { altAddress: ALT_A, entryIndex: 0, challenge: \"c1\" },\n { altAddress: ALT_B, entryIndex: 1, challenge: \"c2\" },\n ],\n });\n\n expect(out[0]?.type).toBe(ClearSignContextType.SOLANA_ALT_RESOLUTION);\n expect(out[1]?.type).toBe(ClearSignContextType.ERROR);\n });\n });\n});\n"],
5
+ "mappings": "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",
6
+ "names": ["DeviceModelId", "Left", "Right", "ClearSignContextType", "AltResolutionContextLoader", "mockLoggerFactory", "mockCertificate", "ALT_A", "ALT_B", "dataSource", "certificateLoader", "makeLoader", "loader", "types", "altAddress", "entryIndex", "result", "out"]
7
+ }
@@ -0,0 +1,2 @@
1
+ import{ContainerModule as t}from"inversify";import{enumVariantTypes as r}from"../../../../modules/solana/enum-variant/di/enumVariantTypes";import{EnumVariantContextLoader as n}from"../../../../modules/solana/enum-variant/domain/EnumVariantContextLoader";const i=()=>new t(({bind:o})=>{o(r.EnumVariantContextLoader).to(n)});export{i as enumVariantModuleFactory};
2
+ //# sourceMappingURL=enumVariantModuleFactory.js.map
@@ -0,0 +1,7 @@
1
+ {
2
+ "version": 3,
3
+ "sources": ["../../../../../../../src/modules/solana/enum-variant/di/enumVariantModuleFactory.ts"],
4
+ "sourcesContent": ["import { ContainerModule } from \"inversify\";\n\nimport { enumVariantTypes } from \"@/modules/solana/enum-variant/di/enumVariantTypes\";\nimport { EnumVariantContextLoader } from \"@/modules/solana/enum-variant/domain/EnumVariantContextLoader\";\n\n// EnumVariantContextLoader shares InstructionInfoDataSource \u2014 its binding\n// is owned by `instructionInfoModuleFactory` and reused here via DI.\nexport const enumVariantModuleFactory = () =>\n new ContainerModule(({ bind }) => {\n bind(enumVariantTypes.EnumVariantContextLoader).to(\n EnumVariantContextLoader,\n );\n });\n"],
5
+ "mappings": "AAAA,OAAS,mBAAAA,MAAuB,YAEhC,OAAS,oBAAAC,MAAwB,oDACjC,OAAS,4BAAAC,MAAgC,gEAIlC,MAAMC,EAA2B,IACtC,IAAIH,EAAgB,CAAC,CAAE,KAAAI,CAAK,IAAM,CAChCA,EAAKH,EAAiB,wBAAwB,EAAE,GAC9CC,CACF,CACF,CAAC",
6
+ "names": ["ContainerModule", "enumVariantTypes", "EnumVariantContextLoader", "enumVariantModuleFactory", "bind"]
7
+ }
@@ -0,0 +1,2 @@
1
+ const n={EnumVariantContextLoader:Symbol.for("EnumVariantContextLoader")};export{n as enumVariantTypes};
2
+ //# sourceMappingURL=enumVariantTypes.js.map
@@ -0,0 +1,7 @@
1
+ {
2
+ "version": 3,
3
+ "sources": ["../../../../../../../src/modules/solana/enum-variant/di/enumVariantTypes.ts"],
4
+ "sourcesContent": ["export const enumVariantTypes = {\n EnumVariantContextLoader: Symbol.for(\"EnumVariantContextLoader\"),\n};\n"],
5
+ "mappings": "AAAO,MAAMA,EAAmB,CAC9B,yBAA0B,OAAO,IAAI,0BAA0B,CACjE",
6
+ "names": ["enumVariantTypes"]
7
+ }
@@ -0,0 +1,2 @@
1
+ var V=Object.defineProperty;var A=Object.getOwnPropertyDescriptor;var y=(m,t,a,e)=>{for(var n=e>1?void 0:e?A(t,a):t,u=m.length-1,o;u>=0;u--)(o=m[u])&&(n=(e?o(t,a,n):o(n))||n);return e&&n&&V(t,a,n),n},p=(m,t)=>(a,e)=>t(a,e,m);import{inject as g,injectable as M}from"inversify";import{array as L,Codec as x,optional as T,string as f}from"purify-ts";import{configTypes as v}from"../../../../config/di/configTypes";import{pkiTypes as w}from"../../../../modules/multichain/pki/di/pkiTypes";import{KeyId as N}from"../../../../modules/multichain/pki/model/KeyId";import{KeyUsage as P}from"../../../../modules/multichain/pki/model/KeyUsage";import{instructionInfoTypes as k}from"../../../../modules/solana/instruction-info/di/instructionInfoTypes";import{ClearSignContextType as d}from"../../../../shared/model/ClearSignContext";import{loadCertificateResult as O}from"../../../../shared/utils/certificateResult";import{deviceModelIdCodec as U}from"../../../../shared/utils/deviceModelIdCodec";import{u16Codec as _}from"../../../../shared/utils/uIntCodec";const b=[d.SOLANA_ENUM_VARIANT],D="solana-mainnet",$=x.interface({programId:f,enumId:f,variantIndex:_}),K=x.interface({deviceModelId:U,selections:L($),network:T(f)});let I=class{constructor(t,a,e,n){this.dataSource=t;this.config=a;this.certificateLoader=e;this.logger=n("EnumVariantContextLoader")}logger;canHandle(t,a){return b.every(e=>a.includes(e))?K.decode(t).caseOf({Left:()=>!1,Right:({selections:e})=>e.length>0&&e.every(n=>n.programId.length>0&&n.enumId.length>0)}):!1}async load(t){const a=t.network||D,e=Array.from(new Set(t.selections.map(r=>r.programId)));this.logger.debug("[load] Fetching enum variants",{data:{network:a,programCount:e.length,selectionCount:t.selections.length}});const n=O(this.certificateLoader,{keyId:N.TokenMetadataKey,keyUsage:P.CoinMeta,targetDevice:t.deviceModelId}),u=Promise.all(e.map(r=>this.dataSource.getInstructionInfo({programId:r,network:a}))),[o,S]=await Promise.all([n,u]);if(!o.ok||!o.value){const r=o.ok?new Error("[ContextModule] EnumVariantContextLoader: certificate is missing"):o.error;return this.logger.warn("[load] ENUM_VARIANT certificate unavailable",{data:{error:r.message}}),t.selections.map(()=>({type:d.ERROR,error:r}))}const E=o.value,R=new Map(e.map((r,s)=>[r,S[s]])),C=this.config.cal.mode??"prod";return t.selections.map(r=>{const s=R.get(r.programId);if(!s){const i=new Error(`[ContextModule] EnumVariantContextLoader: no CAL response for program ${r.programId}`);return this.logger.warn("[load] ENUM_VARIANT fetch failed",{data:{programId:r.programId,enumId:r.enumId,variantIndex:r.variantIndex,error:i.message}}),{type:d.ERROR,error:i}}return s.caseOf({Left:i=>(this.logger.warn("[load] ENUM_VARIANT fetch failed",{data:{programId:r.programId,enumId:r.enumId,variantIndex:r.variantIndex,error:i.message}}),{type:d.ERROR,error:i}),Right:i=>{const c=this.lookupVariant(i,r);if(!c){const l=new Error(`[ContextModule] EnumVariantContextLoader: CAL has no enum variant for (${r.programId}, ${r.enumId}, ${r.variantIndex})`);return this.logger.warn("[load] ENUM_VARIANT not found in CAL response",{data:{programId:r.programId,enumId:r.enumId,variantIndex:r.variantIndex}}),{type:d.ERROR,error:l}}if(!c.descriptor.signature){const l=new Error(`[ContextModule] EnumVariantContextLoader: missing '${C}' signature for (${r.programId}, ${r.enumId}, ${r.variantIndex})`);return this.logger.warn("[load] ENUM_VARIANT missing signature",{data:{programId:r.programId,enumId:r.enumId,variantIndex:r.variantIndex,mode:C}}),{type:d.ERROR,error:l}}const h={programId:r.programId,enumId:r.enumId,variantIndex:r.variantIndex,descriptor:c.descriptor};return{type:d.SOLANA_ENUM_VARIANT,payload:h,certificate:E}}})})}lookupVariant(t,a){return t.enumVariants.find(e=>e.enumId===a.enumId&&e.variantIndex===a.variantIndex)}};I=y([M(),p(0,g(k.InstructionInfoDataSource)),p(1,g(v.Config)),p(2,g(w.PkiCertificateLoader)),p(3,g(v.ContextModuleLoggerFactory))],I);export{I as EnumVariantContextLoader};
2
+ //# sourceMappingURL=EnumVariantContextLoader.js.map
@@ -0,0 +1,7 @@
1
+ {
2
+ "version": 3,
3
+ "sources": ["../../../../../../../src/modules/solana/enum-variant/domain/EnumVariantContextLoader.ts"],
4
+ "sourcesContent": ["import {\n type DeviceModelId,\n type LoggerPublisherService,\n} from \"@ledgerhq/device-management-kit\";\nimport { inject, injectable } from \"inversify\";\nimport { array, Codec, optional, string } from \"purify-ts\";\n\nimport { configTypes } from \"@/config/di/configTypes\";\nimport { type ContextModuleServiceConfig } from \"@/config/model/ContextModuleConfig\";\nimport { pkiTypes } from \"@/modules/multichain/pki/di/pkiTypes\";\nimport { type PkiCertificateLoader } from \"@/modules/multichain/pki/domain/PkiCertificateLoader\";\nimport { KeyId } from \"@/modules/multichain/pki/model/KeyId\";\nimport { KeyUsage } from \"@/modules/multichain/pki/model/KeyUsage\";\nimport {\n type InstructionInfoDataSource,\n type InstructionInfoResult,\n} from \"@/modules/solana/instruction-info/data/InstructionInfoDataSource\";\nimport { instructionInfoTypes } from \"@/modules/solana/instruction-info/di/instructionInfoTypes\";\nimport {\n type SolanaEnumVariantPayload,\n type SolanaInstructionEnumVariant,\n} from \"@/modules/solana/model/SolanaPayloads\";\nimport { type ContextLoader } from \"@/shared/domain/ContextLoader\";\nimport {\n type ClearSignContext,\n ClearSignContextType,\n} from \"@/shared/model/ClearSignContext\";\nimport { loadCertificateResult } from \"@/shared/utils/certificateResult\";\nimport { deviceModelIdCodec } from \"@/shared/utils/deviceModelIdCodec\";\nimport { u16Codec } from \"@/shared/utils/uIntCodec\";\n\nconst SUPPORTED_TYPES: ClearSignContextType[] = [\n ClearSignContextType.SOLANA_ENUM_VARIANT,\n];\n\nconst NETWORK_DEFAULT = \"solana-mainnet\";\n\n/**\n * One enum-variant selection the caller wants resolved. `variantIndex` is\n * constrained to a u16 (0..=65535).\n */\nexport type SolanaEnumVariantSelection = {\n programId: string;\n enumId: string;\n variantIndex: number;\n};\n\nexport type SolanaEnumVariantContextInput = {\n deviceModelId: DeviceModelId;\n selections: SolanaEnumVariantSelection[];\n network?: string;\n};\n\nconst enumVariantSelectionCodec = Codec.interface({\n programId: string,\n enumId: string,\n variantIndex: u16Codec,\n});\n\nconst solanaEnumVariantInputCodec = Codec.interface({\n deviceModelId: deviceModelIdCodec,\n selections: array(enumVariantSelectionCodec),\n network: optional(string),\n});\n\n/**\n * Emits one SOLANA_ENUM_VARIANT context per `(programId, enumId,\n * variantIndex)` selection: fetches the CAL response for each distinct\n * program, looks up the matching variant, and emits only the selected ones.\n *\n * Shares {@link InstructionInfoDataSource} with\n * {@link InstructionInfoContextLoader}.\n */\n@injectable()\nexport class EnumVariantContextLoader\n implements ContextLoader<SolanaEnumVariantContextInput>\n{\n private readonly logger: LoggerPublisherService;\n\n constructor(\n @inject(instructionInfoTypes.InstructionInfoDataSource)\n private readonly dataSource: InstructionInfoDataSource,\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(\"EnumVariantContextLoader\");\n }\n\n public canHandle(\n input: unknown,\n expectedTypes: ClearSignContextType[],\n ): input is SolanaEnumVariantContextInput {\n if (!SUPPORTED_TYPES.every((t) => expectedTypes.includes(t))) return false;\n return solanaEnumVariantInputCodec.decode(input).caseOf({\n Left: () => false,\n Right: ({ selections }) =>\n selections.length > 0 &&\n selections.every((s) => s.programId.length > 0 && s.enumId.length > 0),\n });\n }\n\n public async load(\n input: SolanaEnumVariantContextInput,\n ): Promise<ClearSignContext[]> {\n const network = input.network || NETWORK_DEFAULT;\n const distinctProgramIds = Array.from(\n new Set(input.selections.map((s) => s.programId)),\n );\n\n this.logger.debug(\"[load] Fetching enum variants\", {\n data: {\n network,\n programCount: distinctProgramIds.length,\n selectionCount: input.selections.length,\n },\n });\n\n // Cert load and CAL fetches are independent \u2014 run them in parallel. A\n // PKI failure still degrades each selection to ERROR.\n const certPromise = loadCertificateResult(this.certificateLoader, {\n keyId: KeyId.TokenMetadataKey,\n keyUsage: KeyUsage.CoinMeta,\n targetDevice: input.deviceModelId,\n });\n\n const dataPromise = Promise.all(\n distinctProgramIds.map((programId) =>\n this.dataSource.getInstructionInfo({ programId, network }),\n ),\n );\n\n const [certResult, results] = await Promise.all([certPromise, dataPromise]);\n\n if (!certResult.ok || !certResult.value) {\n const error = certResult.ok\n ? new Error(\n \"[ContextModule] EnumVariantContextLoader: certificate is missing\",\n )\n : certResult.error;\n this.logger.warn(\"[load] ENUM_VARIANT certificate unavailable\", {\n data: { error: error.message },\n });\n return input.selections.map(() => ({\n type: ClearSignContextType.ERROR,\n error,\n }));\n }\n const certificate = certResult.value;\n\n const programToEither = new Map(\n distinctProgramIds.map((programId, i) => [programId, results[i]!]),\n );\n\n const mode = this.config.cal.mode ?? \"prod\";\n\n return input.selections.map((selection) => {\n const either = programToEither.get(selection.programId);\n if (!either) {\n const error = new Error(\n `[ContextModule] EnumVariantContextLoader: no CAL response for program ${selection.programId}`,\n );\n this.logger.warn(\"[load] ENUM_VARIANT fetch failed\", {\n data: {\n programId: selection.programId,\n enumId: selection.enumId,\n variantIndex: selection.variantIndex,\n error: error.message,\n },\n });\n return { type: ClearSignContextType.ERROR, error };\n }\n\n return either.caseOf<ClearSignContext>({\n Left: (err) => {\n this.logger.warn(\"[load] ENUM_VARIANT fetch failed\", {\n data: {\n programId: selection.programId,\n enumId: selection.enumId,\n variantIndex: selection.variantIndex,\n error: err.message,\n },\n });\n return { type: ClearSignContextType.ERROR, error: err };\n },\n Right: (value) => {\n const variant = this.lookupVariant(value, selection);\n if (!variant) {\n const error = new Error(\n `[ContextModule] EnumVariantContextLoader: CAL has no enum variant for (${selection.programId}, ${selection.enumId}, ${selection.variantIndex})`,\n );\n this.logger.warn(\"[load] ENUM_VARIANT not found in CAL response\", {\n data: {\n programId: selection.programId,\n enumId: selection.enumId,\n variantIndex: selection.variantIndex,\n },\n });\n return { type: ClearSignContextType.ERROR, error };\n }\n\n // The mapper already picked the signature for the configured mode (or\n // left it empty when CAL has none for that mode).\n if (!variant.descriptor.signature) {\n const error = new Error(\n `[ContextModule] EnumVariantContextLoader: missing '${mode}' signature for (${selection.programId}, ${selection.enumId}, ${selection.variantIndex})`,\n );\n this.logger.warn(\"[load] ENUM_VARIANT missing signature\", {\n data: {\n programId: selection.programId,\n enumId: selection.enumId,\n variantIndex: selection.variantIndex,\n mode,\n },\n });\n return { type: ClearSignContextType.ERROR, error };\n }\n\n const payload: SolanaEnumVariantPayload = {\n programId: selection.programId,\n enumId: selection.enumId,\n variantIndex: selection.variantIndex,\n descriptor: variant.descriptor,\n };\n return {\n type: ClearSignContextType.SOLANA_ENUM_VARIANT,\n payload,\n certificate,\n };\n },\n });\n });\n }\n\n /**\n * Find the decoded enum variant for a selection. The data source flattens\n * `enum_variants` across all of the program's descriptors into a single list\n * (malformed `u16` keys already dropped), and CAL guarantees `(enumId,\n * variantIndex)` is unique across a program's instructions.\n */\n private lookupVariant(\n result: InstructionInfoResult,\n selection: SolanaEnumVariantSelection,\n ): SolanaInstructionEnumVariant | undefined {\n return result.enumVariants.find(\n (variant) =>\n variant.enumId === selection.enumId &&\n variant.variantIndex === selection.variantIndex,\n );\n }\n}\n"],
5
+ "mappings": "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",
6
+ "names": ["inject", "injectable", "array", "Codec", "optional", "string", "configTypes", "pkiTypes", "KeyId", "KeyUsage", "instructionInfoTypes", "ClearSignContextType", "loadCertificateResult", "deviceModelIdCodec", "u16Codec", "SUPPORTED_TYPES", "ClearSignContextType", "NETWORK_DEFAULT", "enumVariantSelectionCodec", "Codec", "string", "u16Codec", "solanaEnumVariantInputCodec", "deviceModelIdCodec", "array", "optional", "EnumVariantContextLoader", "dataSource", "config", "certificateLoader", "loggerFactory", "input", "expectedTypes", "t", "selections", "s", "network", "distinctProgramIds", "certPromise", "loadCertificateResult", "KeyId", "KeyUsage", "dataPromise", "programId", "certResult", "results", "error", "certificate", "programToEither", "i", "mode", "selection", "either", "err", "value", "variant", "payload", "result", "__decorateClass", "injectable", "__decorateParam", "inject", "instructionInfoTypes", "configTypes", "pkiTypes"]
7
+ }
@@ -0,0 +1,2 @@
1
+ import{DeviceModelId as d}from"@ledgerhq/device-management-kit";import{Left as f,Right as l}from"purify-ts";import{beforeEach as y,describe as p,expect as a,it as s,vi as n}from"vitest";import{ClearSignContextType as c}from"../../../../shared/model/ClearSignContext";import{EnumVariantContextLoader as R}from"./EnumVariantContextLoader";const N=()=>({debug:n.fn(),info:n.fn(),warn:n.fn(),error:n.fn(),subscribers:[]}),g={keyUsageNumber:8,payload:new Uint8Array([66])},u={cal:{url:"https://crypto-assets-service.api.ledger.com/v1",mode:"prod",branch:"main"}},t="JUP6LkbZbjS1jKKwapdHNy74zcZ3tLUZoi5QNyVTaV4",A="OtherProgram111111111111111111111111111111";function I(){return{programId:t,descriptors:{},enumVariants:[{enumId:"swap",variantIndex:46,descriptor:{data:"01_raydium_tlv",signature:"prodsig_v46"}},{enumId:"swap",variantIndex:12,descriptor:{data:"01_orca_tlv",signature:"prodsig_v12"}}]}}p("EnumVariantContextLoader",()=>{let i,m;y(()=>{n.restoreAllMocks(),i={getInstructionInfo:n.fn()},m={loadCertificate:n.fn().mockResolvedValue(g)}});const o=(e=u)=>new R(i,e,m,N);p("canHandle",()=>{s("returns true when SOLANA_ENUM_VARIANT is requested and selections are valid",()=>{a(o().canHandle({deviceModelId:d.NANO_X,selections:[{programId:t,enumId:"swap",variantIndex:46}]},[c.SOLANA_ENUM_VARIANT])).toBe(!0)}),s("returns false when SOLANA_ENUM_VARIANT is not requested",()=>{a(o().canHandle({deviceModelId:d.NANO_X,selections:[{programId:t,enumId:"swap",variantIndex:46}]},[c.SOLANA_INSTRUCTION_INFO])).toBe(!1)}),s.each([-1,65536,1.5,"46",null])("rejects non-u16 variantIndex: %s",e=>{const r=o();a(r.canHandle({deviceModelId:d.NANO_X,selections:[{programId:t,enumId:"swap",variantIndex:e}]},[c.SOLANA_ENUM_VARIANT])).toBe(!1)}),s("rejects empty programId / enumId / selections",()=>{const e=o(),r=[c.SOLANA_ENUM_VARIANT];a(e.canHandle({selections:[]},r)).toBe(!1),a(e.canHandle({selections:[{programId:"",enumId:"swap",variantIndex:1}]},r)).toBe(!1),a(e.canHandle({selections:[{programId:t,enumId:"",variantIndex:1}]},r)).toBe(!1)})}),p("load",()=>{s("emits one SOLANA_ENUM_VARIANT per selection with certificate",async()=>{n.spyOn(i,"getInstructionInfo").mockResolvedValue(l(I()));const e=await o().load({deviceModelId:d.NANO_X,selections:[{programId:t,enumId:"swap",variantIndex:46},{programId:t,enumId:"swap",variantIndex:12}]});a(e).toHaveLength(2),a(e[0]).toMatchObject({type:c.SOLANA_ENUM_VARIANT,payload:{programId:t,enumId:"swap",variantIndex:46,descriptor:{data:"01_raydium_tlv",signature:"prodsig_v46"}},certificate:g}),a(e[1]).toMatchObject({payload:{variantIndex:12,descriptor:{data:"01_orca_tlv",signature:"prodsig_v12"}}})}),s("dedups CAL fetches across selections that share a programId",async()=>{const e=n.spyOn(i,"getInstructionInfo").mockResolvedValue(l(I()));await o().load({deviceModelId:d.NANO_X,selections:[{programId:t,enumId:"swap",variantIndex:46},{programId:t,enumId:"swap",variantIndex:12}]}),a(e).toHaveBeenCalledTimes(1)}),s("resolves a variant index > 255 (u16, disc_kind U16 enums)",async()=>{const e={programId:t,descriptors:{},enumVariants:[{enumId:"swap",variantIndex:300,descriptor:{data:"01_big_tlv",signature:"prodsig_v300"}}]};n.spyOn(i,"getInstructionInfo").mockResolvedValue(l(e));const r=await o().load({deviceModelId:d.NANO_X,selections:[{programId:t,enumId:"swap",variantIndex:300}]});a(r).toHaveLength(1),a(r[0]?.type).toBe(c.SOLANA_ENUM_VARIANT),a(r[0].payload).toMatchObject({variantIndex:300,descriptor:{data:"01_big_tlv",signature:"prodsig_v300"}})}),s("emits ERROR when CAL has no matching variant for a selection",async()=>{n.spyOn(i,"getInstructionInfo").mockResolvedValue(l(I()));const e=await o().load({deviceModelId:d.NANO_X,selections:[{programId:t,enumId:"swap",variantIndex:99}]});a(e).toHaveLength(1),a(e[0]?.type).toBe(c.ERROR),a(e[0].error.message).toMatch(/no enum variant/)}),s("emits ERROR when CAL fetch fails",async()=>{n.spyOn(i,"getInstructionInfo").mockResolvedValue(f(new Error("upstream-500")));const e=await o().load({deviceModelId:d.NANO_X,selections:[{programId:A,enumId:"x",variantIndex:0}]});a(e[0]?.type).toBe(c.ERROR),a(e[0].error.message).toBe("upstream-500")}),s("emits ERROR when configured signature mode is missing",async()=>{const e={programId:t,descriptors:{},enumVariants:[{enumId:"swap",variantIndex:46,descriptor:{data:"01_raydium_tlv",signature:""}}]};n.spyOn(i,"getInstructionInfo").mockResolvedValue(l(e));const v=await o({...u,cal:{...u.cal,mode:"test"}}).load({deviceModelId:d.NANO_X,selections:[{programId:t,enumId:"swap",variantIndex:46}]});a(v[0]?.type).toBe(c.ERROR),a(v[0].error.message).toMatch(/missing 'test' signature/)}),s("degrades every selection to ERROR when certificate loading fails",async()=>{n.spyOn(m,"loadCertificate").mockRejectedValue(new Error("pki-down")),n.spyOn(i,"getInstructionInfo").mockResolvedValue(l(I()));const e=await o().load({deviceModelId:d.NANO_X,selections:[{programId:t,enumId:"swap",variantIndex:46},{programId:t,enumId:"swap",variantIndex:12}]});a(e).toHaveLength(2),a(e.every(r=>r.type===c.ERROR)).toBe(!0)}),s("falls back to default network when input.network is empty / missing",async()=>{const e=n.spyOn(i,"getInstructionInfo").mockResolvedValue(l(I()));await o().load({deviceModelId:d.NANO_X,selections:[{programId:t,enumId:"swap",variantIndex:46}],network:""}),a(e).toHaveBeenCalledWith({programId:t,network:"solana-mainnet"})})})});
2
+ //# sourceMappingURL=EnumVariantContextLoader.test.js.map
@@ -0,0 +1,7 @@
1
+ {
2
+ "version": 3,
3
+ "sources": ["../../../../../../../src/modules/solana/enum-variant/domain/EnumVariantContextLoader.test.ts"],
4
+ "sourcesContent": ["/* eslint-disable @typescript-eslint/no-explicit-any */\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 \"@/modules/multichain/pki/domain/PkiCertificateLoader\";\nimport {\n type InstructionInfoDataSource,\n type InstructionInfoResult,\n} from \"@/modules/solana/instruction-info/data/InstructionInfoDataSource\";\nimport { ClearSignContextType } from \"@/shared/model/ClearSignContext\";\n\nimport { EnumVariantContextLoader } from \"./EnumVariantContextLoader\";\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: 8,\n payload: new Uint8Array([0x42]),\n};\n\nconst mockConfig = {\n cal: {\n url: \"https://crypto-assets-service.api.ledger.com/v1\",\n mode: \"prod\",\n branch: \"main\",\n },\n} as ContextModuleServiceConfig;\n\nconst JUPITER_PROGRAM = \"JUP6LkbZbjS1jKKwapdHNy74zcZ3tLUZoi5QNyVTaV4\";\nconst OTHER_PROGRAM = \"OtherProgram111111111111111111111111111111\";\n\n// The data source flattens enum variants into core models, with the signature\n// already picked for the configured mode.\nfunction makeJupiterWithVariants(): InstructionInfoResult {\n return {\n programId: JUPITER_PROGRAM,\n descriptors: {},\n enumVariants: [\n {\n enumId: \"swap\",\n variantIndex: 46,\n descriptor: { data: \"01_raydium_tlv\", signature: \"prodsig_v46\" },\n },\n {\n enumId: \"swap\",\n variantIndex: 12,\n descriptor: { data: \"01_orca_tlv\", signature: \"prodsig_v12\" },\n },\n ],\n };\n}\n\ndescribe(\"EnumVariantContextLoader\", () => {\n let dataSource: InstructionInfoDataSource;\n let certificateLoader: PkiCertificateLoader;\n\n beforeEach(() => {\n vi.restoreAllMocks();\n dataSource = {\n getInstructionInfo: vi.fn(),\n };\n certificateLoader = {\n loadCertificate: vi.fn().mockResolvedValue(mockCertificate),\n };\n });\n\n const makeLoader = (config = mockConfig) =>\n new EnumVariantContextLoader(\n dataSource,\n config,\n certificateLoader,\n mockLoggerFactory,\n );\n\n describe(\"canHandle\", () => {\n it(\"returns true when SOLANA_ENUM_VARIANT is requested and selections are valid\", () => {\n expect(\n makeLoader().canHandle(\n {\n deviceModelId: DeviceModelId.NANO_X,\n selections: [\n {\n programId: JUPITER_PROGRAM,\n enumId: \"swap\",\n variantIndex: 46,\n },\n ],\n },\n [ClearSignContextType.SOLANA_ENUM_VARIANT],\n ),\n ).toBe(true);\n });\n\n it(\"returns false when SOLANA_ENUM_VARIANT is not requested\", () => {\n expect(\n makeLoader().canHandle(\n {\n deviceModelId: DeviceModelId.NANO_X,\n selections: [\n { programId: JUPITER_PROGRAM, enumId: \"swap\", variantIndex: 46 },\n ],\n },\n [ClearSignContextType.SOLANA_INSTRUCTION_INFO],\n ),\n ).toBe(false);\n });\n\n it.each([-1, 65536, 1.5, \"46\", null])(\n \"rejects non-u16 variantIndex: %s\",\n (badIndex) => {\n const loader = makeLoader();\n expect(\n loader.canHandle(\n {\n deviceModelId: DeviceModelId.NANO_X,\n selections: [\n {\n programId: JUPITER_PROGRAM,\n enumId: \"swap\",\n variantIndex: badIndex,\n },\n ],\n } as any,\n [ClearSignContextType.SOLANA_ENUM_VARIANT],\n ),\n ).toBe(false);\n },\n );\n\n it(\"rejects empty programId / enumId / selections\", () => {\n const loader = makeLoader();\n const types = [ClearSignContextType.SOLANA_ENUM_VARIANT];\n expect(loader.canHandle({ selections: [] } as any, types)).toBe(false);\n expect(\n loader.canHandle(\n {\n selections: [{ programId: \"\", enumId: \"swap\", variantIndex: 1 }],\n } as any,\n types,\n ),\n ).toBe(false);\n expect(\n loader.canHandle(\n {\n selections: [\n { programId: JUPITER_PROGRAM, enumId: \"\", variantIndex: 1 },\n ],\n } as any,\n types,\n ),\n ).toBe(false);\n });\n });\n\n describe(\"load\", () => {\n it(\"emits one SOLANA_ENUM_VARIANT per selection with certificate\", async () => {\n vi.spyOn(dataSource, \"getInstructionInfo\").mockResolvedValue(\n Right(makeJupiterWithVariants()),\n );\n\n const result = await makeLoader().load({\n deviceModelId: DeviceModelId.NANO_X,\n selections: [\n { programId: JUPITER_PROGRAM, enumId: \"swap\", variantIndex: 46 },\n { programId: JUPITER_PROGRAM, enumId: \"swap\", variantIndex: 12 },\n ],\n });\n\n expect(result).toHaveLength(2);\n expect(result[0]).toMatchObject({\n type: ClearSignContextType.SOLANA_ENUM_VARIANT,\n payload: {\n programId: JUPITER_PROGRAM,\n enumId: \"swap\",\n variantIndex: 46,\n descriptor: { data: \"01_raydium_tlv\", signature: \"prodsig_v46\" },\n },\n certificate: mockCertificate,\n });\n expect(result[1]).toMatchObject({\n payload: {\n variantIndex: 12,\n descriptor: { data: \"01_orca_tlv\", signature: \"prodsig_v12\" },\n },\n });\n });\n\n it(\"dedups CAL fetches across selections that share a programId\", async () => {\n const spy = vi\n .spyOn(dataSource, \"getInstructionInfo\")\n .mockResolvedValue(Right(makeJupiterWithVariants()));\n\n await makeLoader().load({\n deviceModelId: DeviceModelId.NANO_X,\n selections: [\n { programId: JUPITER_PROGRAM, enumId: \"swap\", variantIndex: 46 },\n { programId: JUPITER_PROGRAM, enumId: \"swap\", variantIndex: 12 },\n ],\n });\n\n expect(spy).toHaveBeenCalledTimes(1);\n });\n\n it(\"resolves a variant index > 255 (u16, disc_kind U16 enums)\", async () => {\n const result: InstructionInfoResult = {\n programId: JUPITER_PROGRAM,\n descriptors: {},\n enumVariants: [\n {\n enumId: \"swap\",\n variantIndex: 300,\n descriptor: { data: \"01_big_tlv\", signature: \"prodsig_v300\" },\n },\n ],\n };\n vi.spyOn(dataSource, \"getInstructionInfo\").mockResolvedValue(\n Right(result),\n );\n\n const out = await makeLoader().load({\n deviceModelId: DeviceModelId.NANO_X,\n selections: [\n { programId: JUPITER_PROGRAM, enumId: \"swap\", variantIndex: 300 },\n ],\n });\n\n expect(out).toHaveLength(1);\n expect(out[0]?.type).toBe(ClearSignContextType.SOLANA_ENUM_VARIANT);\n expect((out[0] as any).payload).toMatchObject({\n variantIndex: 300,\n descriptor: { data: \"01_big_tlv\", signature: \"prodsig_v300\" },\n });\n });\n\n it(\"emits ERROR when CAL has no matching variant for a selection\", async () => {\n vi.spyOn(dataSource, \"getInstructionInfo\").mockResolvedValue(\n Right(makeJupiterWithVariants()),\n );\n\n const result = await makeLoader().load({\n deviceModelId: DeviceModelId.NANO_X,\n selections: [\n { programId: JUPITER_PROGRAM, enumId: \"swap\", variantIndex: 99 },\n ],\n });\n\n expect(result).toHaveLength(1);\n expect(result[0]?.type).toBe(ClearSignContextType.ERROR);\n expect((result[0] as any).error.message).toMatch(/no enum variant/);\n });\n\n it(\"emits ERROR when CAL fetch fails\", async () => {\n vi.spyOn(dataSource, \"getInstructionInfo\").mockResolvedValue(\n Left(new Error(\"upstream-500\")),\n );\n\n const result = await makeLoader().load({\n deviceModelId: DeviceModelId.NANO_X,\n selections: [\n { programId: OTHER_PROGRAM, enumId: \"x\", variantIndex: 0 },\n ],\n });\n\n expect(result[0]?.type).toBe(ClearSignContextType.ERROR);\n expect((result[0] as any).error.message).toBe(\"upstream-500\");\n });\n\n it(\"emits ERROR when configured signature mode is missing\", async () => {\n // The mapper leaves the signature empty when CAL has none for the mode.\n const result: InstructionInfoResult = {\n programId: JUPITER_PROGRAM,\n descriptors: {},\n enumVariants: [\n {\n enumId: \"swap\",\n variantIndex: 46,\n descriptor: { data: \"01_raydium_tlv\", signature: \"\" },\n },\n ],\n };\n vi.spyOn(dataSource, \"getInstructionInfo\").mockResolvedValue(\n Right(result),\n );\n\n const loader = makeLoader({\n ...mockConfig,\n cal: { ...mockConfig.cal, mode: \"test\" },\n } as any);\n\n const out = await loader.load({\n deviceModelId: DeviceModelId.NANO_X,\n selections: [\n { programId: JUPITER_PROGRAM, enumId: \"swap\", variantIndex: 46 },\n ],\n });\n\n expect(out[0]?.type).toBe(ClearSignContextType.ERROR);\n expect((out[0] as any).error.message).toMatch(/missing 'test' signature/);\n });\n\n it(\"degrades every selection to ERROR when certificate loading fails\", async () => {\n vi.spyOn(certificateLoader, \"loadCertificate\").mockRejectedValue(\n new Error(\"pki-down\"),\n );\n // Data fetches run in parallel with cert load; resolve so awaits settle.\n vi.spyOn(dataSource, \"getInstructionInfo\").mockResolvedValue(\n Right(makeJupiterWithVariants()),\n );\n\n const out = await makeLoader().load({\n deviceModelId: DeviceModelId.NANO_X,\n selections: [\n { programId: JUPITER_PROGRAM, enumId: \"swap\", variantIndex: 46 },\n { programId: JUPITER_PROGRAM, enumId: \"swap\", variantIndex: 12 },\n ],\n });\n\n expect(out).toHaveLength(2);\n expect(out.every((c) => c.type === ClearSignContextType.ERROR)).toBe(\n true,\n );\n });\n\n it(\"falls back to default network when input.network is empty / missing\", async () => {\n const spy = vi\n .spyOn(dataSource, \"getInstructionInfo\")\n .mockResolvedValue(Right(makeJupiterWithVariants()));\n\n await makeLoader().load({\n deviceModelId: DeviceModelId.NANO_X,\n selections: [\n { programId: JUPITER_PROGRAM, enumId: \"swap\", variantIndex: 46 },\n ],\n network: \"\",\n });\n\n expect(spy).toHaveBeenCalledWith({\n programId: JUPITER_PROGRAM,\n network: \"solana-mainnet\",\n });\n });\n });\n});\n"],
5
+ "mappings": "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",
6
+ "names": ["DeviceModelId", "Left", "Right", "beforeEach", "describe", "expect", "it", "vi", "ClearSignContextType", "EnumVariantContextLoader", "mockLoggerFactory", "mockCertificate", "mockConfig", "JUPITER_PROGRAM", "OTHER_PROGRAM", "makeJupiterWithVariants", "dataSource", "certificateLoader", "makeLoader", "config", "badIndex", "loader", "types", "result", "spy", "out", "c"]
7
+ }
@@ -0,0 +1,2 @@
1
+ var C=Object.defineProperty;var g=Object.getOwnPropertyDescriptor;var l=(s,t,n,o)=>{for(var r=o>1?void 0:o?g(t,n):t,e=s.length-1,i;e>=0;e--)(i=s[e])&&(r=(o?i(t,n,r):i(r))||r);return o&&r&&C(t,n,r),r},u=(s,t)=>(n,o)=>t(n,o,s);import{inject as m,injectable as h}from"inversify";import{Codec as E,Left as c,record as y,Right as w,string as D,unknown as k}from"purify-ts";import{configTypes as M}from"../../../../config/di/configTypes";import{networkTypes as $}from"../../../../shared/network/di/networkTypes";import{calInstructionDescriptorsCodec as x}from"./InstructionInfoDto";import{toInstructionInfoPayload as R,toProgramEnumVariants as b}from"./InstructionInfoMapper";const S=E.interface({descriptors_instruction:y(D,k)});let a=class{constructor(t,n){this.config=t;this.http=n}async getInstructionInfo({programId:t,network:n}){let o;try{o=await this.http.get(`${this.config.cal.url}/solana`,{params:{output:"descriptors_instruction",network:n,program:t,ref:`branch:${this.config.cal.branch}`}})}catch(r){const e=r instanceof Error?r.message:String(r);return c(new Error(`[ContextModule] HttpInstructionInfoDataSource: Failed to fetch instruction descriptors: ${e}`))}return!Array.isArray(o)||o.length===0?c(new Error(`[ContextModule] HttpInstructionInfoDataSource: empty response for program ${t}`)):S.decode(o[0]).caseOf({Left:r=>c(new Error(`[ContextModule] HttpInstructionInfoDataSource: malformed response for program ${t}: ${r}`)),Right:r=>{const e=r.descriptors_instruction[t];return e==null||typeof e!="object"?c(new Error(`[ContextModule] HttpInstructionInfoDataSource: no descriptors for program ${t}`)):x.decode(e).caseOf({Left:i=>c(new Error(`[ContextModule] HttpInstructionInfoDataSource: malformed descriptors for program ${t}: ${i}`)),Right:()=>{const i=this.config.cal.mode??"prod",f=e,d=Object.fromEntries(Object.entries(f).map(([p,I])=>[p,R(p,I,i)]));return w({programId:t,descriptors:d,enumVariants:b(f,i)})}})}})}};a=l([h(),u(0,m(M.Config)),u(1,m($.NetworkClient))],a);export{a as HttpInstructionInfoDataSource};
2
+ //# sourceMappingURL=HttpInstructionInfoDataSource.js.map
@@ -0,0 +1,7 @@
1
+ {
2
+ "version": 3,
3
+ "sources": ["../../../../../../../src/modules/solana/instruction-info/data/HttpInstructionInfoDataSource.ts"],
4
+ "sourcesContent": ["import { DmkNetworkClient } from \"@ledgerhq/device-management-kit\";\nimport { inject, injectable } from \"inversify\";\nimport {\n Codec,\n Either,\n Left,\n record,\n Right,\n string,\n unknown as unknownCodec,\n} from \"purify-ts\";\n\nimport { configTypes } from \"@/config/di/configTypes\";\nimport { type ContextModuleServiceConfig } from \"@/config/model/ContextModuleConfig\";\nimport { networkTypes } from \"@/shared/network/di/networkTypes\";\n\nimport {\n GetInstructionInfoParams,\n InstructionInfoDataSource,\n InstructionInfoResult,\n} from \"./InstructionInfoDataSource\";\nimport {\n type CalInstructionDescriptorDto,\n calInstructionDescriptorsCodec,\n} from \"./InstructionInfoDto\";\nimport {\n type CalMode,\n toInstructionInfoPayload,\n toProgramEnumVariants,\n} from \"./InstructionInfoMapper\";\n\n// Validates the outer envelope shape only. Per-discriminator descriptor\n// content is validated downstream by the loader before being consumed.\nconst calInstructionInfoEnvelopeCodec = Codec.interface({\n descriptors_instruction: record(string, unknownCodec),\n});\n\n@injectable()\nexport class HttpInstructionInfoDataSource\n implements InstructionInfoDataSource\n{\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 getInstructionInfo({\n programId,\n network,\n }: GetInstructionInfoParams): Promise<Either<Error, InstructionInfoResult>> {\n let data: unknown;\n try {\n data = await this.http.get(`${this.config.cal.url}/solana`, {\n params: {\n output: \"descriptors_instruction\",\n network,\n program: programId,\n ref: `branch:${this.config.cal.branch}`,\n },\n });\n } catch (error) {\n const reason = error instanceof Error ? error.message : String(error);\n return Left(\n new Error(\n `[ContextModule] HttpInstructionInfoDataSource: Failed to fetch instruction descriptors: ${reason}`,\n ),\n );\n }\n\n if (!Array.isArray(data) || data.length === 0) {\n return Left(\n new Error(\n `[ContextModule] HttpInstructionInfoDataSource: empty response for program ${programId}`,\n ),\n );\n }\n\n return calInstructionInfoEnvelopeCodec\n .decode(data[0])\n .caseOf<Either<Error, InstructionInfoResult>>({\n Left: (error) =>\n Left(\n new Error(\n `[ContextModule] HttpInstructionInfoDataSource: malformed response for program ${programId}: ${error}`,\n ),\n ),\n Right: (envelope) => {\n const descriptors = envelope.descriptors_instruction[programId];\n if (descriptors == null || typeof descriptors !== \"object\") {\n return Left(\n new Error(\n `[ContextModule] HttpInstructionInfoDataSource: no descriptors for program ${programId}`,\n ),\n );\n }\n\n // Validate the inner descriptor shape so the mapper can dereference\n // `instruction_info.descriptor` / `enum_variants` without\n // runtime-throwing on a malformed CAL payload. A malformed descriptor\n // degrades the whole program to a per-program ERROR rather than\n // rejecting the batch. On success we transform each validated DTO into\n // the core payload so the loader never sees the CAL DTO shapes.\n return calInstructionDescriptorsCodec\n .decode(descriptors)\n .caseOf<Either<Error, InstructionInfoResult>>({\n Left: (error) =>\n Left(\n new Error(\n `[ContextModule] HttpInstructionInfoDataSource: malformed descriptors for program ${programId}: ${error}`,\n ),\n ),\n // The codec only validates the consumed shape and strips\n // undeclared fields, so we transform the original (full) object \u2014\n // the cast is justified now that the shape has been validated.\n Right: () => {\n const mode: CalMode = this.config.cal.mode ?? \"prod\";\n const validatedDescriptors = descriptors as Record<\n string,\n CalInstructionDescriptorDto\n >;\n const mapped = Object.fromEntries(\n Object.entries(validatedDescriptors).map(\n ([discriminator, dto]) => [\n discriminator,\n toInstructionInfoPayload(discriminator, dto, mode),\n ],\n ),\n );\n return Right({\n programId,\n descriptors: mapped,\n enumVariants: toProgramEnumVariants(\n validatedDescriptors,\n mode,\n ),\n });\n },\n });\n },\n });\n }\n}\n"],
5
+ "mappings": "iOACA,OAAS,UAAAA,EAAQ,cAAAC,MAAkB,YACnC,OACE,SAAAC,EAEA,QAAAC,EACA,UAAAC,EACA,SAAAC,EACA,UAAAC,EACA,WAAWC,MACN,YAEP,OAAS,eAAAC,MAAmB,0BAE5B,OAAS,gBAAAC,MAAoB,mCAO7B,OAEE,kCAAAC,MACK,uBACP,OAEE,4BAAAC,EACA,yBAAAC,MACK,0BAIP,MAAMC,EAAkCC,EAAM,UAAU,CACtD,wBAAyBC,EAAOC,EAAQC,CAAY,CACtD,CAAC,EAGM,IAAMC,EAAN,KAEP,CACE,YAEmBC,EAEAC,EACjB,CAHiB,YAAAD,EAEA,UAAAC,CAChB,CAEH,MAAa,mBAAmB,CAC9B,UAAAC,EACA,QAAAC,CACF,EAA4E,CAC1E,IAAIC,EACJ,GAAI,CACFA,EAAO,MAAM,KAAK,KAAK,IAAI,GAAG,KAAK,OAAO,IAAI,GAAG,UAAW,CAC1D,OAAQ,CACN,OAAQ,0BACR,QAAAD,EACA,QAASD,EACT,IAAK,UAAU,KAAK,OAAO,IAAI,MAAM,EACvC,CACF,CAAC,CACH,OAASG,EAAO,CACd,MAAMC,EAASD,aAAiB,MAAQA,EAAM,QAAU,OAAOA,CAAK,EACpE,OAAOE,EACL,IAAI,MACF,2FAA2FD,CAAM,EACnG,CACF,CACF,CAEA,MAAI,CAAC,MAAM,QAAQF,CAAI,GAAKA,EAAK,SAAW,EACnCG,EACL,IAAI,MACF,6EAA6EL,CAAS,EACxF,CACF,EAGKR,EACJ,OAAOU,EAAK,CAAC,CAAC,EACd,OAA6C,CAC5C,KAAOC,GACLE,EACE,IAAI,MACF,iFAAiFL,CAAS,KAAKG,CAAK,EACtG,CACF,EACF,MAAQG,GAAa,CACnB,MAAMC,EAAcD,EAAS,wBAAwBN,CAAS,EAC9D,OAAIO,GAAe,MAAQ,OAAOA,GAAgB,SACzCF,EACL,IAAI,MACF,6EAA6EL,CAAS,EACxF,CACF,EASKQ,EACJ,OAAOD,CAAW,EAClB,OAA6C,CAC5C,KAAOJ,GACLE,EACE,IAAI,MACF,oFAAoFL,CAAS,KAAKG,CAAK,EACzG,CACF,EAIF,MAAO,IAAM,CACX,MAAMM,EAAgB,KAAK,OAAO,IAAI,MAAQ,OACxCC,EAAuBH,EAIvBI,EAAS,OAAO,YACpB,OAAO,QAAQD,CAAoB,EAAE,IACnC,CAAC,CAACE,EAAeC,CAAG,IAAM,CACxBD,EACAE,EAAyBF,EAAeC,EAAKJ,CAAI,CACnD,CACF,CACF,EACA,OAAOM,EAAM,CACX,UAAAf,EACA,YAAaW,EACb,aAAcK,EACZN,EACAD,CACF,CACF,CAAC,CACH,CACF,CAAC,CACL,CACF,CAAC,CACL,CACF,EAzGaZ,EAANoB,EAAA,CADNC,EAAW,EAKPC,EAAA,EAAAC,EAAOC,EAAY,MAAM,GAEzBF,EAAA,EAAAC,EAAOE,EAAa,aAAa,IANzBzB",
6
+ "names": ["inject", "injectable", "Codec", "Left", "record", "Right", "string", "unknownCodec", "configTypes", "networkTypes", "calInstructionDescriptorsCodec", "toInstructionInfoPayload", "toProgramEnumVariants", "calInstructionInfoEnvelopeCodec", "Codec", "record", "string", "unknownCodec", "HttpInstructionInfoDataSource", "config", "http", "programId", "network", "data", "error", "reason", "Left", "envelope", "descriptors", "calInstructionDescriptorsCodec", "mode", "validatedDescriptors", "mapped", "discriminator", "dto", "toInstructionInfoPayload", "Right", "toProgramEnumVariants", "__decorateClass", "injectable", "__decorateParam", "inject", "configTypes", "networkTypes"]
7
+ }
@@ -0,0 +1,2 @@
1
+ import{Left as i,Right as u}from"purify-ts";import{beforeEach as d,describe as f,expect as r,it as a,vi as p}from"vitest";import{HttpInstructionInfoDataSource as m}from"./HttpInstructionInfoDataSource";f("HttpInstructionInfoDataSource",()=>{let n,o;const t="11111111111111111111111111111111",s="solana-mainnet",l={cal:{url:"https://crypto-assets-service.api.ledger.com/v1",mode:"prod",branch:"main"}},c=[{descriptors_instruction:{[t]:{"00000000":{type:"instruction",network:"solana-mainnet",version:"v1",instruction_info:{version:1,program_id:t,discriminator:"00000000",hash:"deadbeef",descriptor:{data:"00010101",signatures:{prod:"prodsig",test:"testsig"}}},display_fields:[],value_flow_ports:[],hide_rules:[],account_resets:[]}}}}];d(()=>{p.clearAllMocks(),o={get:p.fn()},n=new m(l,o)}),a("calls CAL with singular program= and ref=branch:<branch>",async()=>{o.get.mockResolvedValue(c),await n.getInstructionInfo({programId:t,network:s}),r(o.get).toHaveBeenCalledTimes(1),r(o.get).toHaveBeenCalledWith("https://crypto-assets-service.api.ledger.com/v1/solana",{params:{output:"descriptors_instruction",network:s,program:t,ref:"branch:main"}})}),a("returns Right with each descriptor transformed into the core payload on success",async()=>{o.get.mockResolvedValue(c);const e=await n.getInstructionInfo({programId:t,network:s});r(e).toEqual(u({programId:t,descriptors:{"00000000":u({programId:t,discriminator:"00000000",instructionInfo:{data:"00010101",signature:"prodsig"},substructures:[],enumVariants:[],idlDescriptor:{typePool:[],rootType:0},mintAssociations:[],valueFlowPorts:[],accountResets:[],displayFields:[]})},enumVariants:[]}))}),a("returns Left when the response array is empty",async()=>{o.get.mockResolvedValue([]);const e=await n.getInstructionInfo({programId:t,network:s});r(e).toEqual(i(new Error(`[ContextModule] HttpInstructionInfoDataSource: empty response for program ${t}`)))}),a("returns Left when the envelope is malformed",async()=>{o.get.mockResolvedValue([{foo:"bar"}]);const e=await n.getInstructionInfo({programId:t,network:s});r(e.isLeft()).toBe(!0),r(e.extract().message).toMatch(new RegExp(String.raw`\[ContextModule\] HttpInstructionInfoDataSource: malformed response for program ${t}:`))}),a("returns Left when the response doesn't contain the requested programId",async()=>{o.get.mockResolvedValue([{descriptors_instruction:{OtherProgram:{}}}]);const e=await n.getInstructionInfo({programId:t,network:s});r(e).toEqual(i(new Error(`[ContextModule] HttpInstructionInfoDataSource: no descriptors for program ${t}`)))}),a("returns Left (not a throw) when an inner descriptor is malformed",async()=>{o.get.mockResolvedValue([{descriptors_instruction:{[t]:{"00000000":{type:"instruction",instruction_info:{}}}}}]);const e=await n.getInstructionInfo({programId:t,network:s});r(e.isLeft()).toBe(!0),r(e.extract().message).toMatch(new RegExp(String.raw`\[ContextModule\] HttpInstructionInfoDataSource: malformed descriptors for program ${t}:`))}),a("returns Left when the HTTP client throws",async()=>{o.get.mockRejectedValue(new Error("network"));const e=await n.getInstructionInfo({programId:t,network:s});r(e).toEqual(i(new Error("[ContextModule] HttpInstructionInfoDataSource: Failed to fetch instruction descriptors: network")))})});
2
+ //# sourceMappingURL=HttpInstructionInfoDataSource.test.js.map
@@ -0,0 +1,7 @@
1
+ {
2
+ "version": 3,
3
+ "sources": ["../../../../../../../src/modules/solana/instruction-info/data/HttpInstructionInfoDataSource.test.ts"],
4
+ "sourcesContent": ["import { 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 { HttpInstructionInfoDataSource } from \"./HttpInstructionInfoDataSource\";\nimport { type InstructionInfoDataSource } from \"./InstructionInfoDataSource\";\nimport { type CalInstructionInfoResponseDto } from \"./InstructionInfoDto\";\n\ndescribe(\"HttpInstructionInfoDataSource\", () => {\n let datasource: InstructionInfoDataSource;\n let httpMock: { get: ReturnType<typeof vi.fn> };\n const programId = \"11111111111111111111111111111111\";\n const network = \"solana-mainnet\";\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 const successResponse: CalInstructionInfoResponseDto = [\n {\n descriptors_instruction: {\n [programId]: {\n \"00000000\": {\n type: \"instruction\",\n network: \"solana-mainnet\",\n version: \"v1\",\n instruction_info: {\n version: 1,\n program_id: programId,\n discriminator: \"00000000\",\n hash: \"deadbeef\",\n descriptor: {\n data: \"00010101\",\n signatures: { prod: \"prodsig\", test: \"testsig\" },\n },\n },\n display_fields: [],\n value_flow_ports: [],\n hide_rules: [],\n account_resets: [],\n },\n },\n },\n },\n ];\n\n beforeEach(() => {\n vi.clearAllMocks();\n httpMock = { get: vi.fn() };\n datasource = new HttpInstructionInfoDataSource(\n config,\n httpMock as unknown as DmkNetworkClient,\n );\n });\n\n it(\"calls CAL with singular program= and ref=branch:<branch>\", async () => {\n httpMock.get.mockResolvedValue(successResponse);\n\n await datasource.getInstructionInfo({ programId, network });\n\n expect(httpMock.get).toHaveBeenCalledTimes(1);\n expect(httpMock.get).toHaveBeenCalledWith(\n \"https://crypto-assets-service.api.ledger.com/v1/solana\",\n {\n params: {\n output: \"descriptors_instruction\",\n network,\n program: programId,\n ref: \"branch:main\",\n },\n },\n );\n });\n\n it(\"returns Right with each descriptor transformed into the core payload on success\", async () => {\n httpMock.get.mockResolvedValue(successResponse);\n\n const result = await datasource.getInstructionInfo({ programId, network });\n\n expect(result).toEqual(\n Right({\n programId,\n descriptors: {\n \"00000000\": Right({\n programId,\n discriminator: \"00000000\",\n instructionInfo: { data: \"00010101\", signature: \"prodsig\" },\n substructures: [],\n enumVariants: [],\n idlDescriptor: { typePool: [], rootType: 0 },\n mintAssociations: [],\n valueFlowPorts: [],\n accountResets: [],\n displayFields: [],\n }),\n },\n enumVariants: [],\n }),\n );\n });\n\n it(\"returns Left when the response array is empty\", async () => {\n httpMock.get.mockResolvedValue([]);\n\n const result = await datasource.getInstructionInfo({ programId, network });\n\n expect(result).toEqual(\n Left(\n new Error(\n `[ContextModule] HttpInstructionInfoDataSource: empty response for program ${programId}`,\n ),\n ),\n );\n });\n\n it(\"returns Left when the envelope is malformed\", async () => {\n httpMock.get.mockResolvedValue([{ foo: \"bar\" }]);\n\n const result = await datasource.getInstructionInfo({ programId, network });\n\n expect(result.isLeft()).toBe(true);\n expect((result.extract() as Error).message).toMatch(\n new RegExp(\n String.raw`\\[ContextModule\\] HttpInstructionInfoDataSource: malformed response for program ${programId}:`,\n ),\n );\n });\n\n it(\"returns Left when the response doesn't contain the requested programId\", async () => {\n httpMock.get.mockResolvedValue([\n { descriptors_instruction: { OtherProgram: {} } },\n ]);\n\n const result = await datasource.getInstructionInfo({ programId, network });\n\n expect(result).toEqual(\n Left(\n new Error(\n `[ContextModule] HttpInstructionInfoDataSource: no descriptors for program ${programId}`,\n ),\n ),\n );\n });\n\n it(\"returns Left (not a throw) when an inner descriptor is malformed\", async () => {\n // `instruction_info.descriptor` missing \u2014 would crash the loader if the\n // datasource handed it through unvalidated.\n httpMock.get.mockResolvedValue([\n {\n descriptors_instruction: {\n [programId]: {\n \"00000000\": { type: \"instruction\", instruction_info: {} },\n },\n },\n },\n ]);\n\n const result = await datasource.getInstructionInfo({ programId, network });\n\n expect(result.isLeft()).toBe(true);\n expect((result.extract() as Error).message).toMatch(\n new RegExp(\n String.raw`\\[ContextModule\\] HttpInstructionInfoDataSource: malformed descriptors for program ${programId}:`,\n ),\n );\n });\n\n it(\"returns Left when the HTTP client throws\", async () => {\n httpMock.get.mockRejectedValue(new Error(\"network\"));\n\n const result = await datasource.getInstructionInfo({ programId, network });\n\n expect(result).toEqual(\n Left(\n new Error(\n \"[ContextModule] HttpInstructionInfoDataSource: Failed to fetch instruction descriptors: network\",\n ),\n ),\n );\n });\n});\n"],
5
+ "mappings": "AACA,OAAS,QAAAA,EAAM,SAAAC,MAAa,YAC5B,OAAS,cAAAC,EAAY,YAAAC,EAAU,UAAAC,EAAQ,MAAAC,EAAI,MAAAC,MAAU,SAIrD,OAAS,iCAAAC,MAAqC,kCAI9CJ,EAAS,gCAAiC,IAAM,CAC9C,IAAIK,EACAC,EACJ,MAAMC,EAAY,mCACZC,EAAU,iBACVC,EAAqC,CACzC,IAAK,CACH,IAAK,kDACL,KAAM,OACN,OAAQ,MACV,CACF,EAEMC,EAAiD,CACrD,CACE,wBAAyB,CACvB,CAACH,CAAS,EAAG,CACX,WAAY,CACV,KAAM,cACN,QAAS,iBACT,QAAS,KACT,iBAAkB,CAChB,QAAS,EACT,WAAYA,EACZ,cAAe,WACf,KAAM,WACN,WAAY,CACV,KAAM,WACN,WAAY,CAAE,KAAM,UAAW,KAAM,SAAU,CACjD,CACF,EACA,eAAgB,CAAC,EACjB,iBAAkB,CAAC,EACnB,WAAY,CAAC,EACb,eAAgB,CAAC,CACnB,CACF,CACF,CACF,CACF,EAEAR,EAAW,IAAM,CACfI,EAAG,cAAc,EACjBG,EAAW,CAAE,IAAKH,EAAG,GAAG,CAAE,EAC1BE,EAAa,IAAID,EACfK,EACAH,CACF,CACF,CAAC,EAEDJ,EAAG,2DAA4D,SAAY,CACzEI,EAAS,IAAI,kBAAkBI,CAAe,EAE9C,MAAML,EAAW,mBAAmB,CAAE,UAAAE,EAAW,QAAAC,CAAQ,CAAC,EAE1DP,EAAOK,EAAS,GAAG,EAAE,sBAAsB,CAAC,EAC5CL,EAAOK,EAAS,GAAG,EAAE,qBACnB,yDACA,CACE,OAAQ,CACN,OAAQ,0BACR,QAAAE,EACA,QAASD,EACT,IAAK,aACP,CACF,CACF,CACF,CAAC,EAEDL,EAAG,kFAAmF,SAAY,CAChGI,EAAS,IAAI,kBAAkBI,CAAe,EAE9C,MAAMC,EAAS,MAAMN,EAAW,mBAAmB,CAAE,UAAAE,EAAW,QAAAC,CAAQ,CAAC,EAEzEP,EAAOU,CAAM,EAAE,QACbb,EAAM,CACJ,UAAAS,EACA,YAAa,CACX,WAAYT,EAAM,CAChB,UAAAS,EACA,cAAe,WACf,gBAAiB,CAAE,KAAM,WAAY,UAAW,SAAU,EAC1D,cAAe,CAAC,EAChB,aAAc,CAAC,EACf,cAAe,CAAE,SAAU,CAAC,EAAG,SAAU,CAAE,EAC3C,iBAAkB,CAAC,EACnB,eAAgB,CAAC,EACjB,cAAe,CAAC,EAChB,cAAe,CAAC,CAClB,CAAC,CACH,EACA,aAAc,CAAC,CACjB,CAAC,CACH,CACF,CAAC,EAEDL,EAAG,gDAAiD,SAAY,CAC9DI,EAAS,IAAI,kBAAkB,CAAC,CAAC,EAEjC,MAAMK,EAAS,MAAMN,EAAW,mBAAmB,CAAE,UAAAE,EAAW,QAAAC,CAAQ,CAAC,EAEzEP,EAAOU,CAAM,EAAE,QACbd,EACE,IAAI,MACF,6EAA6EU,CAAS,EACxF,CACF,CACF,CACF,CAAC,EAEDL,EAAG,8CAA+C,SAAY,CAC5DI,EAAS,IAAI,kBAAkB,CAAC,CAAE,IAAK,KAAM,CAAC,CAAC,EAE/C,MAAMK,EAAS,MAAMN,EAAW,mBAAmB,CAAE,UAAAE,EAAW,QAAAC,CAAQ,CAAC,EAEzEP,EAAOU,EAAO,OAAO,CAAC,EAAE,KAAK,EAAI,EACjCV,EAAQU,EAAO,QAAQ,EAAY,OAAO,EAAE,QAC1C,IAAI,OACF,OAAO,sFAAsFJ,CAAS,GACxG,CACF,CACF,CAAC,EAEDL,EAAG,yEAA0E,SAAY,CACvFI,EAAS,IAAI,kBAAkB,CAC7B,CAAE,wBAAyB,CAAE,aAAc,CAAC,CAAE,CAAE,CAClD,CAAC,EAED,MAAMK,EAAS,MAAMN,EAAW,mBAAmB,CAAE,UAAAE,EAAW,QAAAC,CAAQ,CAAC,EAEzEP,EAAOU,CAAM,EAAE,QACbd,EACE,IAAI,MACF,6EAA6EU,CAAS,EACxF,CACF,CACF,CACF,CAAC,EAEDL,EAAG,mEAAoE,SAAY,CAGjFI,EAAS,IAAI,kBAAkB,CAC7B,CACE,wBAAyB,CACvB,CAACC,CAAS,EAAG,CACX,WAAY,CAAE,KAAM,cAAe,iBAAkB,CAAC,CAAE,CAC1D,CACF,CACF,CACF,CAAC,EAED,MAAMI,EAAS,MAAMN,EAAW,mBAAmB,CAAE,UAAAE,EAAW,QAAAC,CAAQ,CAAC,EAEzEP,EAAOU,EAAO,OAAO,CAAC,EAAE,KAAK,EAAI,EACjCV,EAAQU,EAAO,QAAQ,EAAY,OAAO,EAAE,QAC1C,IAAI,OACF,OAAO,yFAAyFJ,CAAS,GAC3G,CACF,CACF,CAAC,EAEDL,EAAG,2CAA4C,SAAY,CACzDI,EAAS,IAAI,kBAAkB,IAAI,MAAM,SAAS,CAAC,EAEnD,MAAMK,EAAS,MAAMN,EAAW,mBAAmB,CAAE,UAAAE,EAAW,QAAAC,CAAQ,CAAC,EAEzEP,EAAOU,CAAM,EAAE,QACbd,EACE,IAAI,MACF,iGACF,CACF,CACF,CACF,CAAC,CACH,CAAC",
6
+ "names": ["Left", "Right", "beforeEach", "describe", "expect", "it", "vi", "HttpInstructionInfoDataSource", "datasource", "httpMock", "programId", "network", "config", "successResponse", "result"]
7
+ }
@@ -0,0 +1 @@
1
+ //# sourceMappingURL=InstructionInfoDataSource.js.map
@@ -0,0 +1,7 @@
1
+ {
2
+ "version": 3,
3
+ "sources": [],
4
+ "sourcesContent": [],
5
+ "mappings": "",
6
+ "names": []
7
+ }
@@ -0,0 +1,2 @@
1
+ import{array as n,Codec as e,optional as r,record as i,string as t}from"purify-ts";const a=e.interface({prod:r(t),test:r(t)}),s=e.interface({data:t,signatures:a}),c=e.interface({program_id:t,descriptor:s}),u=e.interface({data:t,signatures:a}),o=e.interface({descriptor:t}),l=e.interface({instruction_info:c,enum_variants:r(i(t,i(t,u))),display_fields:r(n(o)),value_flow_ports:r(n(o)),hide_rules:r(n(o)),account_resets:r(n(o))}),d=i(t,l);export{d as calInstructionDescriptorsCodec};
2
+ //# sourceMappingURL=InstructionInfoDto.js.map
@@ -0,0 +1,7 @@
1
+ {
2
+ "version": 3,
3
+ "sources": ["../../../../../../../src/modules/solana/instruction-info/data/InstructionInfoDto.ts"],
4
+ "sourcesContent": ["// DTO + codecs for the CAL instruction-descriptors response (one object per\n// `programId`, wrapped in a JSON array).\n//\n// The hand-written types describe the consumed shape (with genuinely optional\n// `?:` fields); the codecs below validate that shape at runtime so\n// `HttpInstructionInfoDataSource` can hand the loaders a payload they can\n// dereference without runtime-throwing on a malformed descriptor.\n\nimport { array, Codec, optional, record, string } from \"purify-ts\";\n\nexport type CalSignatures = {\n prod?: string;\n test?: string;\n};\n\nexport type CalSignedDescriptorDto = {\n data: string;\n signatures: CalSignatures;\n};\n\n// Decoded CAL JSON shapes (snake_case mirrors the CAL response) that drive\n// host-side requirement building.\n\nexport type CalValueDto = {\n source: string;\n account_index?: number;\n data?: string;\n path?: { steps: number[] };\n};\n\nexport type CalTokenValueDto = {\n kind: string;\n value?: CalValueDto;\n account_index?: number;\n};\n\nexport type CalMintAssociationDto = {\n account_index: number;\n mint_index: number;\n};\n\nexport type CalTypePoolEntryDto = {\n index: number;\n kind: string;\n refs?: number[];\n size?: number;\n encoding?: number;\n len_kind?: string;\n flag_kind?: string;\n sentinel?: string;\n disc_kind?: string;\n total_variants?: number;\n enum_id?: string;\n};\n\nexport type CalInstructionInfoDto = {\n version: number;\n program_id: string;\n discriminator: string;\n hash: string;\n operation_type?: string;\n program_name?: string;\n descriptor: CalSignedDescriptorDto;\n idl_descriptor?: {\n type_pool?: CalTypePoolEntryDto[];\n root_type?: number;\n };\n mint_association?: CalMintAssociationDto;\n owner_association?: unknown;\n};\n\nexport type CalEnumVariantDto = {\n variant_name: string;\n payload_kind?: string;\n data: string;\n signatures: CalSignatures;\n};\n\n/** A substructure CAL serves only as opaque TLV (e.g. HIDE_RULE). */\nexport type CalSubstructureDto = {\n descriptor: string;\n};\n\nexport type CalValueFlowPortDto = CalSubstructureDto & {\n account_indices?: number[];\n account_index?: number;\n optional_account_strategy?: string;\n token_value?: CalTokenValueDto;\n};\n\nexport type CalAccountResetDto = CalSubstructureDto & {\n account_index?: number;\n require_pre_balance_zero?: boolean;\n};\n\nexport type CalDisplayFieldDto = CalSubstructureDto & {\n name?: string;\n param?: { type: string; value?: CalValueDto; token?: CalValueDto };\n};\n\nexport type CalInstructionDescriptorDto = {\n type: string;\n source?: string;\n network?: string;\n version?: string;\n instruction_info: CalInstructionInfoDto;\n enum_variants?: Record<string, Record<string, CalEnumVariantDto>>;\n display_fields?: CalDisplayFieldDto[];\n value_flow_ports?: CalValueFlowPortDto[];\n hide_rules?: CalSubstructureDto[];\n account_resets?: CalAccountResetDto[];\n};\n\n// Outer shape: array containing one envelope object keyed by program_id\n// then by discriminator hex.\nexport type CalInstructionInfoResponseDto = Array<{\n descriptors_instruction: Record<\n string,\n Record<string, CalInstructionDescriptorDto>\n >;\n}>;\n\n// --- Validation codecs (runtime). Validate only the fields the loaders read;\n// `Codec.interface` ignores unknown extras so CAL can add fields freely. ---\n\nconst calSignaturesCodec = Codec.interface({\n prod: optional(string),\n test: optional(string),\n});\n\nconst calSignedDescriptorCodec = Codec.interface({\n data: string,\n signatures: calSignaturesCodec,\n});\n\nconst calInstructionInfoCodec = Codec.interface({\n program_id: string,\n descriptor: calSignedDescriptorCodec,\n});\n\nconst calEnumVariantCodec = Codec.interface({\n data: string,\n signatures: calSignaturesCodec,\n});\n\nconst calSubstructureCodec = Codec.interface({\n descriptor: string,\n});\n\nconst calInstructionDescriptorCodec = Codec.interface({\n instruction_info: calInstructionInfoCodec,\n enum_variants: optional(record(string, record(string, calEnumVariantCodec))),\n display_fields: optional(array(calSubstructureCodec)),\n value_flow_ports: optional(array(calSubstructureCodec)),\n hide_rules: optional(array(calSubstructureCodec)),\n account_resets: optional(array(calSubstructureCodec)),\n});\n\n/**\n * Codec for the per-program descriptor map (keyed by discriminator hex).\n * Used by the datasource to validate the inner CAL payload before handing\n * it to the loaders. Only loader-consumed fields are validated; unrelated\n * CAL fields (`idl_descriptor`, `mint_association`, \u2026) are ignored.\n */\nexport const calInstructionDescriptorsCodec = record(\n string,\n calInstructionDescriptorCodec,\n);\n"],
5
+ "mappings": "AAQA,OAAS,SAAAA,EAAO,SAAAC,EAAO,YAAAC,EAAU,UAAAC,EAAQ,UAAAC,MAAc,YAqHvD,MAAMC,EAAqBJ,EAAM,UAAU,CACzC,KAAMC,EAASE,CAAM,EACrB,KAAMF,EAASE,CAAM,CACvB,CAAC,EAEKE,EAA2BL,EAAM,UAAU,CAC/C,KAAMG,EACN,WAAYC,CACd,CAAC,EAEKE,EAA0BN,EAAM,UAAU,CAC9C,WAAYG,EACZ,WAAYE,CACd,CAAC,EAEKE,EAAsBP,EAAM,UAAU,CAC1C,KAAMG,EACN,WAAYC,CACd,CAAC,EAEKI,EAAuBR,EAAM,UAAU,CAC3C,WAAYG,CACd,CAAC,EAEKM,EAAgCT,EAAM,UAAU,CACpD,iBAAkBM,EAClB,cAAeL,EAASC,EAAOC,EAAQD,EAAOC,EAAQI,CAAmB,CAAC,CAAC,EAC3E,eAAgBN,EAASF,EAAMS,CAAoB,CAAC,EACpD,iBAAkBP,EAASF,EAAMS,CAAoB,CAAC,EACtD,WAAYP,EAASF,EAAMS,CAAoB,CAAC,EAChD,eAAgBP,EAASF,EAAMS,CAAoB,CAAC,CACtD,CAAC,EAQYE,EAAiCR,EAC5CC,EACAM,CACF",
6
+ "names": ["array", "Codec", "optional", "record", "string", "calSignaturesCodec", "calSignedDescriptorCodec", "calInstructionInfoCodec", "calEnumVariantCodec", "calSubstructureCodec", "calInstructionDescriptorCodec", "calInstructionDescriptorsCodec"]
7
+ }
@@ -0,0 +1,2 @@
1
+ import{Left as p,Right as d}from"purify-ts";import{SolanaInstructionSubstructureKind as e}from"../../../../modules/solana/model/SolanaPayloads";import{u16Codec as _}from"../../../../shared/utils/uIntCodec";function u(n,t){return n[t]}function f(n=[]){return n.map(t=>({account_indices:t.account_indices,account_index:t.account_index,optional_account_strategy:t.optional_account_strategy,token_value:t.token_value}))}function m(n=[]){return n.flatMap(t=>t.account_index===void 0?[]:[{account_index:t.account_index,require_pre_balance_zero:t.require_pre_balance_zero}])}function y(n=[]){return n.map(t=>({name:t.name,param:t.param??{type:""}}))}function C(n){return[...(n.display_fields??[]).map(t=>({kind:e.DISPLAY_FIELD,data:t.descriptor})),...(n.value_flow_ports??[]).map(t=>({kind:e.VALUE_FLOW_PORT,data:t.descriptor})),...(n.hide_rules??[]).map(t=>({kind:e.HIDE_RULE,data:t.descriptor})),...(n.account_resets??[]).map(t=>({kind:e.ACCOUNT_RESET,data:t.descriptor}))]}function c(n,t){const o=[];for(const[a,r]of Object.entries(n.enum_variants??{}))for(const[l,i]of Object.entries(r)){const s=Number(l);_.decode(s).isLeft()||o.push({enumId:a,variantIndex:s,descriptor:{data:i.data,signature:u(i.signatures,t)??""}})}return o}function g(n,t){return Object.values(n).flatMap(o=>c(o,t))}function E(n,t,o){const a=t.instruction_info,r=u(a.descriptor.signatures,o);return r?d({programId:a.program_id,discriminator:n,instructionInfo:{data:a.descriptor.data,signature:r},substructures:C(t),enumVariants:c(t,o),idlDescriptor:{typePool:a.idl_descriptor?.type_pool??[],rootType:a.idl_descriptor?.root_type??0},mintAssociations:a.mint_association?[a.mint_association]:[],valueFlowPorts:f(t.value_flow_ports),accountResets:m(t.account_resets),displayFields:y(t.display_fields)}):p(new Error(`[ContextModule] InstructionInfoDataSource: missing '${o}' signature for (${a.program_id}, ${n})`))}export{m as toAccountResets,y as toDisplayFields,E as toInstructionInfoPayload,g as toProgramEnumVariants,f as toValueFlowPorts};
2
+ //# sourceMappingURL=InstructionInfoMapper.js.map
@@ -0,0 +1,7 @@
1
+ {
2
+ "version": 3,
3
+ "sources": ["../../../../../../../src/modules/solana/instruction-info/data/InstructionInfoMapper.ts"],
4
+ "sourcesContent": ["// Maps the validated CAL instruction-descriptor DTOs into the core\n// `SolanaInstructionInfoPayload` model. Keeping this in the data layer means\n// the domain `InstructionInfoContextLoader` never has to know the CAL DTO\n// shapes \u2014 it consumes core models only.\n\nimport { type Either, Left, Right } from \"purify-ts\";\n\nimport {\n type SolanaCalAccountReset,\n type SolanaCalDisplayField,\n type SolanaCalValueFlowPort,\n type SolanaInstructionEnumVariant,\n type SolanaInstructionInfoPayload,\n type SolanaInstructionSubstructure,\n SolanaInstructionSubstructureKind,\n} from \"@/modules/solana/model/SolanaPayloads\";\nimport { u16Codec } from \"@/shared/utils/uIntCodec\";\n\nimport {\n type CalAccountResetDto,\n type CalDisplayFieldDto,\n type CalInstructionDescriptorDto,\n type CalSignatures,\n type CalValueFlowPortDto,\n} from \"./InstructionInfoDto\";\n\nexport type CalMode = \"prod\" | \"test\";\n\nfunction pickSignature(\n signatures: CalSignatures,\n mode: CalMode,\n): string | undefined {\n return signatures[mode];\n}\n\n// --- DTO \u2192 decoded-payload projections. Pick only the fields the host-side\n// requirement builder reads, dropping the signed-TLV `descriptor` carried by\n// the DTO. ---\n\nexport function toValueFlowPorts(\n dtos: CalValueFlowPortDto[] = [],\n): SolanaCalValueFlowPort[] {\n return dtos.map((port) => ({\n account_indices: port.account_indices,\n account_index: port.account_index,\n optional_account_strategy: port.optional_account_strategy,\n token_value: port.token_value,\n }));\n}\n\nexport function toAccountResets(\n dtos: CalAccountResetDto[] = [],\n): SolanaCalAccountReset[] {\n // Drop malformed resets (missing account_index) rather than defaulting to\n // slot 0, which would create an unintended TOKEN_ACCOUNT_STATE requirement.\n return dtos.flatMap((reset) =>\n reset.account_index === undefined\n ? []\n : [\n {\n account_index: reset.account_index,\n require_pre_balance_zero: reset.require_pre_balance_zero,\n },\n ],\n );\n}\n\nexport function toDisplayFields(\n dtos: CalDisplayFieldDto[] = [],\n): SolanaCalDisplayField[] {\n return dtos.map((field) => ({\n name: field.name,\n param: field.param ?? { type: \"\" },\n }));\n}\n\nfunction toSubstructures(\n dto: CalInstructionDescriptorDto,\n): SolanaInstructionSubstructure[] {\n return [\n ...(dto.display_fields ?? []).map((s) => ({\n kind: SolanaInstructionSubstructureKind.DISPLAY_FIELD,\n data: s.descriptor,\n })),\n ...(dto.value_flow_ports ?? []).map((s) => ({\n kind: SolanaInstructionSubstructureKind.VALUE_FLOW_PORT,\n data: s.descriptor,\n })),\n ...(dto.hide_rules ?? []).map((s) => ({\n kind: SolanaInstructionSubstructureKind.HIDE_RULE,\n data: s.descriptor,\n })),\n ...(dto.account_resets ?? []).map((s) => ({\n kind: SolanaInstructionSubstructureKind.ACCOUNT_RESET,\n data: s.descriptor,\n })),\n ];\n}\n\n/**\n * Flatten the CAL-bundled enum variants (keyed enumId \u2192 variantIndex). Keys\n * that don't validate as a u16 are skipped rather than leaking NaN/out-of-range\n * indices into the payload.\n */\nfunction toEnumVariants(\n dto: CalInstructionDescriptorDto,\n mode: CalMode,\n): SolanaInstructionEnumVariant[] {\n const enumVariants: SolanaInstructionEnumVariant[] = [];\n for (const [enumId, variants] of Object.entries(dto.enum_variants ?? {})) {\n for (const [variantIndex, variant] of Object.entries(variants)) {\n const index = Number(variantIndex);\n if (u16Codec.decode(index).isLeft()) {\n continue;\n }\n enumVariants.push({\n enumId,\n variantIndex: index,\n descriptor: {\n data: variant.data,\n signature: pickSignature(variant.signatures, mode) ?? \"\",\n },\n });\n }\n }\n return enumVariants;\n}\n\n/**\n * Flatten the enum variants of every descriptor in a program into a single\n * list. CAL nests `enum_variants` inside each instruction descriptor but\n * guarantees `(enumId, variantIndex)` is unique across a program, so the enum\n * loader resolves a selection against this program-level list \u2014 independently\n * of whether any individual instruction descriptor carried a usable signature.\n */\nexport function toProgramEnumVariants(\n descriptors: Record<string, CalInstructionDescriptorDto>,\n mode: CalMode,\n): SolanaInstructionEnumVariant[] {\n return Object.values(descriptors).flatMap((dto) => toEnumVariants(dto, mode));\n}\n\n/**\n * Transform one validated CAL descriptor DTO into the core\n * {@link SolanaInstructionInfoPayload}. Returns a `Left` when the descriptor is\n * unusable (no signature for the configured `mode`), so the caller can surface\n * a per-descriptor ERROR rather than emitting an empty signature.\n */\nexport function toInstructionInfoPayload(\n discriminator: string,\n dto: CalInstructionDescriptorDto,\n mode: CalMode,\n): Either<Error, SolanaInstructionInfoPayload> {\n const info = dto.instruction_info;\n const signature = pickSignature(info.descriptor.signatures, mode);\n if (!signature) {\n return Left(\n new Error(\n `[ContextModule] InstructionInfoDataSource: missing '${mode}' signature for (${info.program_id}, ${discriminator})`,\n ),\n );\n }\n\n return Right({\n programId: info.program_id,\n discriminator,\n instructionInfo: {\n data: info.descriptor.data,\n signature,\n },\n substructures: toSubstructures(dto),\n enumVariants: toEnumVariants(dto, mode),\n idlDescriptor: {\n typePool: info.idl_descriptor?.type_pool ?? [],\n rootType: info.idl_descriptor?.root_type ?? 0,\n },\n mintAssociations: info.mint_association ? [info.mint_association] : [],\n valueFlowPorts: toValueFlowPorts(dto.value_flow_ports),\n accountResets: toAccountResets(dto.account_resets),\n displayFields: toDisplayFields(dto.display_fields),\n });\n}\n"],
5
+ "mappings": "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",
6
+ "names": ["Left", "Right", "SolanaInstructionSubstructureKind", "u16Codec", "pickSignature", "signatures", "mode", "toValueFlowPorts", "dtos", "port", "toAccountResets", "reset", "toDisplayFields", "field", "toSubstructures", "dto", "s", "toEnumVariants", "enumVariants", "enumId", "variants", "variantIndex", "variant", "index", "toProgramEnumVariants", "descriptors", "toInstructionInfoPayload", "discriminator", "info", "signature"]
7
+ }
@@ -0,0 +1,2 @@
1
+ import{describe as o,expect as t,it as a}from"vitest";import{toAccountResets as s,toDisplayFields as d,toInstructionInfoPayload as i,toProgramEnumVariants as p,toValueFlowPorts as u}from"./InstructionInfoMapper";const c="11111111111111111111111111111111";function r(e={}){return{type:"instruction",instruction_info:{version:1,program_id:c,discriminator:"00000000",hash:"feedface",descriptor:{data:"0001sys_data",signatures:{prod:"prodsig",test:"testsig"}}},...e}}o("InstructionInfoMapper",()=>{o("toValueFlowPorts",()=>{a("returns an empty list for undefined input",()=>{t(u()).toEqual([])}),a("picks only the decoded fields, dropping the signed-TLV descriptor",()=>{t(u([{descriptor:"vfp1",account_indices:[0,1],account_index:0,optional_account_strategy:"OMITTED",token_value:{kind:"NATIVE"}}])).toEqual([{account_indices:[0,1],account_index:0,optional_account_strategy:"OMITTED",token_value:{kind:"NATIVE"}}])}),a("leaves absent optional fields as undefined",()=>{t(u([{descriptor:"vfp1"}])).toEqual([{account_indices:void 0,account_index:void 0,optional_account_strategy:void 0,token_value:void 0}])})}),o("toAccountResets",()=>{a("returns an empty list for undefined input",()=>{t(s()).toEqual([])}),a("maps the decoded fields, dropping the signed-TLV descriptor",()=>{t(s([{descriptor:"ar1",account_index:2,require_pre_balance_zero:!0}])).toEqual([{account_index:2,require_pre_balance_zero:!0}])}),a("drops entries missing account_index instead of defaulting to slot 0",()=>{t(s([{descriptor:"ar0",account_index:0},{descriptor:"arBad"},{descriptor:"ar1",account_index:1}])).toEqual([{account_index:0,require_pre_balance_zero:void 0},{account_index:1,require_pre_balance_zero:void 0}])})}),o("toDisplayFields",()=>{a("returns an empty list for undefined input",()=>{t(d()).toEqual([])}),a("picks name and param, dropping the signed-TLV descriptor",()=>{t(d([{descriptor:"df1",name:"New Account",param:{type:"ACCOUNT",value:{source:"ACCOUNT_PATH",account_index:1}}}])).toEqual([{name:"New Account",param:{type:"ACCOUNT",value:{source:"ACCOUNT_PATH",account_index:1}}}])}),a("falls back to an empty-type param when param is absent",()=>{t(d([{descriptor:"df1"}])).toEqual([{name:void 0,param:{type:""}}])})}),o("toInstructionInfoPayload",()=>{a("surfaces CAL's decoded JSON (type pool, mint assoc, ports, resets, fields) and ordered substructures",()=>{const e=r({instruction_info:{version:1,program_id:c,discriminator:"00000000",hash:"feedface",descriptor:{data:"0001sys_data",signatures:{prod:"prodsig",test:"testsig"}},idl_descriptor:{root_type:3,type_pool:[{index:0,kind:"STRUCT",refs:[1]},{index:1,kind:"U64"}]},mint_association:{account_index:1,mint_index:3}},display_fields:[{descriptor:"df1",name:"New Account",param:{type:"ACCOUNT",value:{source:"ACCOUNT_PATH",account_index:1}}}],value_flow_ports:[{descriptor:"vfp1",account_indices:[0],token_value:{kind:"NATIVE"}}],hide_rules:[{descriptor:"hr1"}],account_resets:[{descriptor:"ar1",account_index:1,require_pre_balance_zero:!0}]}),n=i("00000000",e,"prod").unsafeCoerce();t(n).toMatchObject({programId:c,discriminator:"00000000",instructionInfo:{data:"0001sys_data",signature:"prodsig"},idlDescriptor:{rootType:3,typePool:[{index:0,kind:"STRUCT",refs:[1]},{index:1,kind:"U64"}]},mintAssociations:[{account_index:1,mint_index:3}],valueFlowPorts:[{account_indices:[0],optional_account_strategy:void 0,token_value:{kind:"NATIVE"}}],accountResets:[{account_index:1,require_pre_balance_zero:!0}],displayFields:[{name:"New Account",param:{type:"ACCOUNT",value:{source:"ACCOUNT_PATH",account_index:1}}}]}),t(n.substructures).toEqual([{kind:0,data:"df1"},{kind:1,data:"vfp1"},{kind:2,data:"hr1"},{kind:3,data:"ar1"}])}),a("defaults idlDescriptor when CAL omits it",()=>{const e=i("00000000",r(),"prod").unsafeCoerce();t(e.idlDescriptor).toEqual({typePool:[],rootType:0}),t(e.mintAssociations).toEqual([])}),a("bundles CAL enum_variants into the payload with the mode signature",()=>{const e=r({enum_variants:{swap:{46:{variant_name:"raydiumCP",data:"01_raydium_tlv",signatures:{prod:"prodsig_v46",test:"testsig_v46"}}}}}),n=i("00000000",e,"prod").unsafeCoerce();t(n.enumVariants).toEqual([{enumId:"swap",variantIndex:46,descriptor:{data:"01_raydium_tlv",signature:"prodsig_v46"}}])}),a("skips enum_variants keyed by a non-u16 index instead of leaking NaN",()=>{const e=r({enum_variants:{swap:{46:{variant_name:"raydiumCP",data:"01_raydium_tlv",signatures:{prod:"prodsig_v46",test:"testsig_v46"}},"7abc":{variant_name:"junk",data:"junk_tlv",signatures:{prod:"x",test:"x"}},7e4:{variant_name:"overflow",data:"overflow_tlv",signatures:{prod:"x",test:"x"}}}}}),n=i("00000000",e,"prod").unsafeCoerce();t(n.enumVariants).toEqual([{enumId:"swap",variantIndex:46,descriptor:{data:"01_raydium_tlv",signature:"prodsig_v46"}}])}),a("selects the signature for the configured mode",()=>{const e=i("00000000",r(),"test").unsafeCoerce();t(e.instructionInfo.signature).toBe("testsig")}),a("returns Left when the configured mode signature is missing",()=>{const e=r();delete e.instruction_info.descriptor.signatures.test;const n=i("00000000",e,"test");t(n.isLeft()).toBe(!0),t(n.swap().unsafeCoerce().message).toMatch(/missing 'test' signature/)})}),o("toProgramEnumVariants",()=>{a("flattens enum variants across all descriptors, dropping malformed keys",()=>{const e={"00000000":r({enum_variants:{swap:{46:{variant_name:"raydiumCP",data:"01_raydium_tlv",signatures:{prod:"prodsig_v46",test:"testsig_v46"}},bad:{variant_name:"junk",data:"junk_tlv",signatures:{prod:"x",test:"x"}}}}}),"00000001":r({enum_variants:{route:{12:{variant_name:"orca",data:"02_orca_tlv",signatures:{prod:"prodsig_v12",test:"testsig_v12"}}}}})};t(p(e,"prod")).toEqual([{enumId:"swap",variantIndex:46,descriptor:{data:"01_raydium_tlv",signature:"prodsig_v46"}},{enumId:"route",variantIndex:12,descriptor:{data:"02_orca_tlv",signature:"prodsig_v12"}}])}),a("leaves the signature empty when CAL has none for the configured mode",()=>{const e=r({enum_variants:{swap:{46:{variant_name:"raydiumCP",data:"01_raydium_tlv",signatures:{prod:"prodsig_v46"}}}}});t(p({"00000000":e},"test")).toEqual([{enumId:"swap",variantIndex:46,descriptor:{data:"01_raydium_tlv",signature:""}}])})})});
2
+ //# sourceMappingURL=InstructionInfoMapper.test.js.map
@@ -0,0 +1,7 @@
1
+ {
2
+ "version": 3,
3
+ "sources": ["../../../../../../../src/modules/solana/instruction-info/data/InstructionInfoMapper.test.ts"],
4
+ "sourcesContent": ["import { describe, expect, it } from \"vitest\";\n\nimport { type CalInstructionDescriptorDto } from \"./InstructionInfoDto\";\nimport {\n toAccountResets,\n toDisplayFields,\n toInstructionInfoPayload,\n toProgramEnumVariants,\n toValueFlowPorts,\n} from \"./InstructionInfoMapper\";\n\nconst PROGRAM = \"11111111111111111111111111111111\";\n\nfunction makeDescriptor(\n overrides: Partial<CalInstructionDescriptorDto> = {},\n): CalInstructionDescriptorDto {\n return {\n type: \"instruction\",\n instruction_info: {\n version: 1,\n program_id: PROGRAM,\n discriminator: \"00000000\",\n hash: \"feedface\",\n descriptor: {\n data: \"0001sys_data\",\n signatures: { prod: \"prodsig\", test: \"testsig\" },\n },\n },\n ...overrides,\n };\n}\n\ndescribe(\"InstructionInfoMapper\", () => {\n describe(\"toValueFlowPorts\", () => {\n it(\"returns an empty list for undefined input\", () => {\n expect(toValueFlowPorts()).toEqual([]);\n });\n\n it(\"picks only the decoded fields, dropping the signed-TLV descriptor\", () => {\n expect(\n toValueFlowPorts([\n {\n descriptor: \"vfp1\",\n account_indices: [0, 1],\n account_index: 0,\n optional_account_strategy: \"OMITTED\",\n token_value: { kind: \"NATIVE\" },\n },\n ]),\n ).toEqual([\n {\n account_indices: [0, 1],\n account_index: 0,\n optional_account_strategy: \"OMITTED\",\n token_value: { kind: \"NATIVE\" },\n },\n ]);\n });\n\n it(\"leaves absent optional fields as undefined\", () => {\n expect(toValueFlowPorts([{ descriptor: \"vfp1\" }])).toEqual([\n {\n account_indices: undefined,\n account_index: undefined,\n optional_account_strategy: undefined,\n token_value: undefined,\n },\n ]);\n });\n });\n\n describe(\"toAccountResets\", () => {\n it(\"returns an empty list for undefined input\", () => {\n expect(toAccountResets()).toEqual([]);\n });\n\n it(\"maps the decoded fields, dropping the signed-TLV descriptor\", () => {\n expect(\n toAccountResets([\n {\n descriptor: \"ar1\",\n account_index: 2,\n require_pre_balance_zero: true,\n },\n ]),\n ).toEqual([{ account_index: 2, require_pre_balance_zero: true }]);\n });\n\n it(\"drops entries missing account_index instead of defaulting to slot 0\", () => {\n expect(\n toAccountResets([\n { descriptor: \"ar0\", account_index: 0 },\n { descriptor: \"arBad\" },\n { descriptor: \"ar1\", account_index: 1 },\n ]),\n ).toEqual([\n { account_index: 0, require_pre_balance_zero: undefined },\n { account_index: 1, require_pre_balance_zero: undefined },\n ]);\n });\n });\n\n describe(\"toDisplayFields\", () => {\n it(\"returns an empty list for undefined input\", () => {\n expect(toDisplayFields()).toEqual([]);\n });\n\n it(\"picks name and param, dropping the signed-TLV descriptor\", () => {\n expect(\n toDisplayFields([\n {\n descriptor: \"df1\",\n name: \"New Account\",\n param: {\n type: \"ACCOUNT\",\n value: { source: \"ACCOUNT_PATH\", account_index: 1 },\n },\n },\n ]),\n ).toEqual([\n {\n name: \"New Account\",\n param: {\n type: \"ACCOUNT\",\n value: { source: \"ACCOUNT_PATH\", account_index: 1 },\n },\n },\n ]);\n });\n\n it(\"falls back to an empty-type param when param is absent\", () => {\n expect(toDisplayFields([{ descriptor: \"df1\" }])).toEqual([\n { name: undefined, param: { type: \"\" } },\n ]);\n });\n });\n\n describe(\"toInstructionInfoPayload\", () => {\n it(\"surfaces CAL's decoded JSON (type pool, mint assoc, ports, resets, fields) and ordered substructures\", () => {\n const dto = makeDescriptor({\n instruction_info: {\n version: 1,\n program_id: PROGRAM,\n discriminator: \"00000000\",\n hash: \"feedface\",\n descriptor: {\n data: \"0001sys_data\",\n signatures: { prod: \"prodsig\", test: \"testsig\" },\n },\n idl_descriptor: {\n root_type: 3,\n type_pool: [\n { index: 0, kind: \"STRUCT\", refs: [1] },\n { index: 1, kind: \"U64\" },\n ],\n },\n mint_association: { account_index: 1, mint_index: 3 },\n },\n display_fields: [\n {\n descriptor: \"df1\",\n name: \"New Account\",\n param: {\n type: \"ACCOUNT\",\n value: { source: \"ACCOUNT_PATH\", account_index: 1 },\n },\n },\n ],\n value_flow_ports: [\n {\n descriptor: \"vfp1\",\n account_indices: [0],\n token_value: { kind: \"NATIVE\" },\n },\n ],\n hide_rules: [{ descriptor: \"hr1\" }],\n account_resets: [\n {\n descriptor: \"ar1\",\n account_index: 1,\n require_pre_balance_zero: true,\n },\n ],\n });\n\n const payload = toInstructionInfoPayload(\n \"00000000\",\n dto,\n \"prod\",\n ).unsafeCoerce();\n\n expect(payload).toMatchObject({\n programId: PROGRAM,\n discriminator: \"00000000\",\n instructionInfo: { data: \"0001sys_data\", signature: \"prodsig\" },\n idlDescriptor: {\n rootType: 3,\n typePool: [\n { index: 0, kind: \"STRUCT\", refs: [1] },\n { index: 1, kind: \"U64\" },\n ],\n },\n mintAssociations: [{ account_index: 1, mint_index: 3 }],\n valueFlowPorts: [\n {\n account_indices: [0],\n optional_account_strategy: undefined,\n token_value: { kind: \"NATIVE\" },\n },\n ],\n accountResets: [{ account_index: 1, require_pre_balance_zero: true }],\n displayFields: [\n {\n name: \"New Account\",\n param: {\n type: \"ACCOUNT\",\n value: { source: \"ACCOUNT_PATH\", account_index: 1 },\n },\n },\n ],\n });\n // Substructures carry the signed TLVs for the device, in order.\n expect(payload.substructures).toEqual([\n { kind: 0x00, data: \"df1\" },\n { kind: 0x01, data: \"vfp1\" },\n { kind: 0x02, data: \"hr1\" },\n { kind: 0x03, data: \"ar1\" },\n ]);\n });\n\n it(\"defaults idlDescriptor when CAL omits it\", () => {\n const payload = toInstructionInfoPayload(\n \"00000000\",\n makeDescriptor(),\n \"prod\",\n ).unsafeCoerce();\n expect(payload.idlDescriptor).toEqual({ typePool: [], rootType: 0 });\n expect(payload.mintAssociations).toEqual([]);\n });\n\n it(\"bundles CAL enum_variants into the payload with the mode signature\", () => {\n const dto = makeDescriptor({\n enum_variants: {\n swap: {\n \"46\": {\n variant_name: \"raydiumCP\",\n data: \"01_raydium_tlv\",\n signatures: { prod: \"prodsig_v46\", test: \"testsig_v46\" },\n },\n },\n },\n });\n const payload = toInstructionInfoPayload(\n \"00000000\",\n dto,\n \"prod\",\n ).unsafeCoerce();\n expect(payload.enumVariants).toEqual([\n {\n enumId: \"swap\",\n variantIndex: 46,\n descriptor: { data: \"01_raydium_tlv\", signature: \"prodsig_v46\" },\n },\n ]);\n });\n\n it(\"skips enum_variants keyed by a non-u16 index instead of leaking NaN\", () => {\n const dto = makeDescriptor({\n enum_variants: {\n swap: {\n \"46\": {\n variant_name: \"raydiumCP\",\n data: \"01_raydium_tlv\",\n signatures: { prod: \"prodsig_v46\", test: \"testsig_v46\" },\n },\n \"7abc\": {\n variant_name: \"junk\",\n data: \"junk_tlv\",\n signatures: { prod: \"x\", test: \"x\" },\n },\n \"70000\": {\n variant_name: \"overflow\",\n data: \"overflow_tlv\",\n signatures: { prod: \"x\", test: \"x\" },\n },\n },\n },\n });\n const payload = toInstructionInfoPayload(\n \"00000000\",\n dto,\n \"prod\",\n ).unsafeCoerce();\n expect(payload.enumVariants).toEqual([\n {\n enumId: \"swap\",\n variantIndex: 46,\n descriptor: { data: \"01_raydium_tlv\", signature: \"prodsig_v46\" },\n },\n ]);\n });\n\n it(\"selects the signature for the configured mode\", () => {\n const payload = toInstructionInfoPayload(\n \"00000000\",\n makeDescriptor(),\n \"test\",\n ).unsafeCoerce();\n expect(payload.instructionInfo.signature).toBe(\"testsig\");\n });\n\n it(\"returns Left when the configured mode signature is missing\", () => {\n const dto = makeDescriptor();\n delete (dto.instruction_info.descriptor.signatures as { test?: string })\n .test;\n const result = toInstructionInfoPayload(\"00000000\", dto, \"test\");\n expect(result.isLeft()).toBe(true);\n expect(result.swap().unsafeCoerce().message).toMatch(\n /missing 'test' signature/,\n );\n });\n });\n\n describe(\"toProgramEnumVariants\", () => {\n it(\"flattens enum variants across all descriptors, dropping malformed keys\", () => {\n const descriptors: Record<string, CalInstructionDescriptorDto> = {\n \"00000000\": makeDescriptor({\n enum_variants: {\n swap: {\n \"46\": {\n variant_name: \"raydiumCP\",\n data: \"01_raydium_tlv\",\n signatures: { prod: \"prodsig_v46\", test: \"testsig_v46\" },\n },\n bad: {\n variant_name: \"junk\",\n data: \"junk_tlv\",\n signatures: { prod: \"x\", test: \"x\" },\n },\n },\n },\n }),\n \"00000001\": makeDescriptor({\n enum_variants: {\n route: {\n \"12\": {\n variant_name: \"orca\",\n data: \"02_orca_tlv\",\n signatures: { prod: \"prodsig_v12\", test: \"testsig_v12\" },\n },\n },\n },\n }),\n };\n expect(toProgramEnumVariants(descriptors, \"prod\")).toEqual([\n {\n enumId: \"swap\",\n variantIndex: 46,\n descriptor: { data: \"01_raydium_tlv\", signature: \"prodsig_v46\" },\n },\n {\n enumId: \"route\",\n variantIndex: 12,\n descriptor: { data: \"02_orca_tlv\", signature: \"prodsig_v12\" },\n },\n ]);\n });\n\n it(\"leaves the signature empty when CAL has none for the configured mode\", () => {\n const dto = makeDescriptor({\n enum_variants: {\n swap: {\n \"46\": {\n variant_name: \"raydiumCP\",\n data: \"01_raydium_tlv\",\n signatures: { prod: \"prodsig_v46\" },\n },\n },\n },\n });\n expect(toProgramEnumVariants({ \"00000000\": dto }, \"test\")).toEqual([\n {\n enumId: \"swap\",\n variantIndex: 46,\n descriptor: { data: \"01_raydium_tlv\", signature: \"\" },\n },\n ]);\n });\n });\n});\n"],
5
+ "mappings": "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",
6
+ "names": ["describe", "expect", "it", "toAccountResets", "toDisplayFields", "toInstructionInfoPayload", "toProgramEnumVariants", "toValueFlowPorts", "PROGRAM", "makeDescriptor", "overrides", "dto", "payload", "result", "descriptors"]
7
+ }
@@ -0,0 +1,2 @@
1
+ import{ContainerModule as n}from"inversify";import{HttpInstructionInfoDataSource as r}from"../../../../modules/solana/instruction-info/data/HttpInstructionInfoDataSource";import{instructionInfoTypes as t}from"../../../../modules/solana/instruction-info/di/instructionInfoTypes";import{InstructionInfoContextLoader as e}from"../../../../modules/solana/instruction-info/domain/InstructionInfoContextLoader";const I=()=>new n(({bind:o})=>{o(t.InstructionInfoDataSource).to(r),o(t.InstructionInfoContextLoader).to(e)});export{I as instructionInfoModuleFactory};
2
+ //# sourceMappingURL=instructionInfoModuleFactory.js.map
@@ -0,0 +1,7 @@
1
+ {
2
+ "version": 3,
3
+ "sources": ["../../../../../../../src/modules/solana/instruction-info/di/instructionInfoModuleFactory.ts"],
4
+ "sourcesContent": ["import { ContainerModule } from \"inversify\";\n\nimport { HttpInstructionInfoDataSource } from \"@/modules/solana/instruction-info/data/HttpInstructionInfoDataSource\";\nimport { instructionInfoTypes } from \"@/modules/solana/instruction-info/di/instructionInfoTypes\";\nimport { InstructionInfoContextLoader } from \"@/modules/solana/instruction-info/domain/InstructionInfoContextLoader\";\n\nexport const instructionInfoModuleFactory = () =>\n new ContainerModule(({ bind }) => {\n bind(instructionInfoTypes.InstructionInfoDataSource).to(\n HttpInstructionInfoDataSource,\n );\n bind(instructionInfoTypes.InstructionInfoContextLoader).to(\n InstructionInfoContextLoader,\n );\n });\n"],
5
+ "mappings": "AAAA,OAAS,mBAAAA,MAAuB,YAEhC,OAAS,iCAAAC,MAAqC,uEAC9C,OAAS,wBAAAC,MAA4B,4DACrC,OAAS,gCAAAC,MAAoC,wEAEtC,MAAMC,EAA+B,IAC1C,IAAIJ,EAAgB,CAAC,CAAE,KAAAK,CAAK,IAAM,CAChCA,EAAKH,EAAqB,yBAAyB,EAAE,GACnDD,CACF,EACAI,EAAKH,EAAqB,4BAA4B,EAAE,GACtDC,CACF,CACF,CAAC",
6
+ "names": ["ContainerModule", "HttpInstructionInfoDataSource", "instructionInfoTypes", "InstructionInfoContextLoader", "instructionInfoModuleFactory", "bind"]
7
+ }
@@ -0,0 +1,2 @@
1
+ const o={InstructionInfoDataSource:Symbol.for("InstructionInfoDataSource"),InstructionInfoContextLoader:Symbol.for("InstructionInfoContextLoader")};export{o as instructionInfoTypes};
2
+ //# sourceMappingURL=instructionInfoTypes.js.map
@@ -0,0 +1,7 @@
1
+ {
2
+ "version": 3,
3
+ "sources": ["../../../../../../../src/modules/solana/instruction-info/di/instructionInfoTypes.ts"],
4
+ "sourcesContent": ["export const instructionInfoTypes = {\n InstructionInfoDataSource: Symbol.for(\"InstructionInfoDataSource\"),\n InstructionInfoContextLoader: Symbol.for(\"InstructionInfoContextLoader\"),\n};\n"],
5
+ "mappings": "AAAO,MAAMA,EAAuB,CAClC,0BAA2B,OAAO,IAAI,2BAA2B,EACjE,6BAA8B,OAAO,IAAI,8BAA8B,CACzE",
6
+ "names": ["instructionInfoTypes"]
7
+ }
@@ -0,0 +1,2 @@
1
+ var T=Object.defineProperty;var L=Object.getOwnPropertyDescriptor;var y=(s,e,o,t)=>{for(var r=t>1?void 0:t?L(e,o):e,i=s.length-1,a;i>=0;i--)(a=s[i])&&(r=(t?a(e,o,r):a(r))||r);return t&&r&&T(e,o,r),r},u=(s,e)=>(o,t)=>e(o,t,s);import{inject as p,injectable as N}from"inversify";import{array as P,Codec as S,optional as h,string as m}from"purify-ts";import{configTypes as k}from"../../../../config/di/configTypes";import{pkiTypes as w}from"../../../../modules/multichain/pki/di/pkiTypes";import{KeyId as D}from"../../../../modules/multichain/pki/model/KeyId";import{KeyUsage as b}from"../../../../modules/multichain/pki/model/KeyUsage";import{instructionInfoTypes as M}from"../../../../modules/solana/instruction-info/di/instructionInfoTypes";import{ClearSignContextType as c}from"../../../../shared/model/ClearSignContext";import{loadCertificateResult as E}from"../../../../shared/utils/certificateResult";import{deviceModelIdCodec as U}from"../../../../shared/utils/deviceModelIdCodec";const F=[c.SOLANA_INSTRUCTION_INFO],_="solana-mainnet",A=S.interface({programId:m,discriminator:h(m)}),K=S.interface({deviceModelId:U,instructions:P(A),network:h(m)});let f=class{constructor(e,o,t){this.dataSource=e;this.certificateLoader=o;this.logger=t("InstructionInfoContextLoader")}logger;canHandle(e,o){return F.every(t=>o.includes(t))?K.decode(e).caseOf({Left:()=>!1,Right:({instructions:t})=>t.length>0&&t.every(r=>r.programId.length>0)}):!1}async load(e){const o=e.network||_,t=Array.from(new Set(e.instructions.map(n=>n.programId)));this.logger.debug("[load] Fetching instruction descriptors",{data:{network:o,programCount:t.length,instructionCount:e.instructions.length}});const r=E(this.certificateLoader,{keyId:D.TokenMetadataKey,keyUsage:b.CoinMeta,targetDevice:e.deviceModelId}),i=Promise.all(t.map(async n=>({programId:n,either:await this.dataSource.getInstructionInfo({programId:n,network:o})}))),[a,R]=await Promise.all([r,i]);if(!a.ok||!a.value){const n=a.ok?new Error("[ContextModule] InstructionInfoContextLoader: certificate is missing"):a.error;return this.logger.warn("[load] INSTRUCTION_INFO certificate unavailable",{data:{error:n.message}}),t.map(()=>({type:c.ERROR,error:n}))}const v=a.value,l=[];for(const{programId:n,either:x}of R)x.caseOf({Left:d=>{this.logger.warn("[load] Failed to fetch instruction descriptors for program",{data:{programId:n,error:d.message}}),l.push({type:c.ERROR,error:d})},Right:d=>{const I=this.collectWantedDiscriminators(n,e.instructions);for(const[C,O]of Object.entries(d.descriptors))I!==null&&!I.has(C)||l.push(O.caseOf({Left:g=>(this.logger.warn("[load] INSTRUCTION_INFO descriptor error",{data:{programId:n,discriminator:C,error:g.message}}),{type:c.ERROR,error:g}),Right:g=>({type:c.SOLANA_INSTRUCTION_INFO,payload:g,certificate:v})}))}});return this.logger.debug("[load] Emitted contexts",{data:{count:l.length}}),l}collectWantedDiscriminators(e,o){const t=new Set;let r=!1;for(const i of o)i.programId===e&&(i.discriminator===void 0?r=!0:t.add(i.discriminator));return r?null:t}};f=y([N(),u(0,p(M.InstructionInfoDataSource)),u(1,p(w.PkiCertificateLoader)),u(2,p(k.ContextModuleLoggerFactory))],f);export{f as InstructionInfoContextLoader};
2
+ //# sourceMappingURL=InstructionInfoContextLoader.js.map
@@ -0,0 +1,7 @@
1
+ {
2
+ "version": 3,
3
+ "sources": ["../../../../../../../src/modules/solana/instruction-info/domain/InstructionInfoContextLoader.ts"],
4
+ "sourcesContent": ["import {\n type DeviceModelId,\n type LoggerPublisherService,\n} from \"@ledgerhq/device-management-kit\";\nimport { inject, injectable } from \"inversify\";\nimport { array, Codec, optional, string } from \"purify-ts\";\n\nimport { configTypes } from \"@/config/di/configTypes\";\nimport { pkiTypes } from \"@/modules/multichain/pki/di/pkiTypes\";\nimport { type PkiCertificateLoader } from \"@/modules/multichain/pki/domain/PkiCertificateLoader\";\nimport { KeyId } from \"@/modules/multichain/pki/model/KeyId\";\nimport { KeyUsage } from \"@/modules/multichain/pki/model/KeyUsage\";\nimport { type InstructionInfoDataSource } from \"@/modules/solana/instruction-info/data/InstructionInfoDataSource\";\nimport { instructionInfoTypes } from \"@/modules/solana/instruction-info/di/instructionInfoTypes\";\nimport { type ContextLoader } from \"@/shared/domain/ContextLoader\";\nimport {\n type ClearSignContext,\n ClearSignContextType,\n} from \"@/shared/model/ClearSignContext\";\nimport { loadCertificateResult } from \"@/shared/utils/certificateResult\";\nimport { deviceModelIdCodec } from \"@/shared/utils/deviceModelIdCodec\";\n\nconst SUPPORTED_TYPES: ClearSignContextType[] = [\n ClearSignContextType.SOLANA_INSTRUCTION_INFO,\n];\n\nconst NETWORK_DEFAULT = \"solana-mainnet\";\n\n/**\n * Per-instruction reference the caller provides for the TX it wants to\n * clear-sign. Discriminator is optional: when omitted, the loader emits\n * every descriptor CAL returns for that `programId`. When present, the\n * loader filters down to descriptors whose `discriminator` matches.\n */\nexport type SolanaInstructionRef = {\n programId: string;\n discriminator?: string;\n};\n\nexport type SolanaInstructionInfoContextInput = {\n deviceModelId: DeviceModelId;\n instructions: SolanaInstructionRef[];\n network?: string;\n};\n\nconst instructionRefCodec = Codec.interface({\n programId: string,\n discriminator: optional(string),\n});\n\nconst solanaInstructionInfoInputCodec = Codec.interface({\n deviceModelId: deviceModelIdCodec,\n instructions: array(instructionRefCodec),\n network: optional(string),\n});\n\n/**\n * Emits SOLANA_INSTRUCTION_INFO contexts for the requested instructions.\n * Enum-variant emission lives in the sibling {@link EnumVariantContextLoader}.\n */\n@injectable()\nexport class InstructionInfoContextLoader\n implements ContextLoader<SolanaInstructionInfoContextInput>\n{\n private readonly logger: LoggerPublisherService;\n\n constructor(\n @inject(instructionInfoTypes.InstructionInfoDataSource)\n private readonly dataSource: InstructionInfoDataSource,\n @inject(pkiTypes.PkiCertificateLoader)\n private readonly certificateLoader: PkiCertificateLoader,\n @inject(configTypes.ContextModuleLoggerFactory)\n loggerFactory: (tag: string) => LoggerPublisherService,\n ) {\n this.logger = loggerFactory(\"InstructionInfoContextLoader\");\n }\n\n public canHandle(\n input: unknown,\n expectedTypes: ClearSignContextType[],\n ): input is SolanaInstructionInfoContextInput {\n if (!SUPPORTED_TYPES.every((t) => expectedTypes.includes(t))) {\n return false;\n }\n return solanaInstructionInfoInputCodec.decode(input).caseOf({\n Left: () => false,\n Right: ({ instructions }) =>\n instructions.length > 0 &&\n instructions.every((ix) => ix.programId.length > 0),\n });\n }\n\n public async load(\n input: SolanaInstructionInfoContextInput,\n ): Promise<ClearSignContext[]> {\n const network = input.network || NETWORK_DEFAULT;\n const distinctProgramIds = Array.from(\n new Set(input.instructions.map((ix) => ix.programId)),\n );\n\n this.logger.debug(\"[load] Fetching instruction descriptors\", {\n data: {\n network,\n programCount: distinctProgramIds.length,\n instructionCount: input.instructions.length,\n },\n });\n\n // Run cert load in parallel with CAL fetches \u2014 neither depends on the\n // other. The tagged-Result wrapper lets us preserve the data fetches\n // if cert fails so we can surface a per-program ERROR rather than\n // silently dropping them.\n const certPromise = loadCertificateResult(this.certificateLoader, {\n keyId: KeyId.TokenMetadataKey,\n keyUsage: KeyUsage.CoinMeta,\n targetDevice: input.deviceModelId,\n });\n\n // One CAL call per program, fanned out in parallel.\n const dataPromise = Promise.all(\n distinctProgramIds.map(async (programId) => ({\n programId,\n either: await this.dataSource.getInstructionInfo({\n programId,\n network,\n }),\n })),\n );\n\n const [certResult, results] = await Promise.all([certPromise, dataPromise]);\n\n if (!certResult.ok || !certResult.value) {\n const error = certResult.ok\n ? new Error(\n \"[ContextModule] InstructionInfoContextLoader: certificate is missing\",\n )\n : certResult.error;\n this.logger.warn(\"[load] INSTRUCTION_INFO certificate unavailable\", {\n data: { error: error.message },\n });\n return distinctProgramIds.map(() => ({\n type: ClearSignContextType.ERROR,\n error,\n }));\n }\n const certificate = certResult.value;\n\n const contexts: ClearSignContext[] = [];\n\n for (const { programId, either } of results) {\n either.caseOf<void>({\n Left: (err) => {\n this.logger.warn(\n \"[load] Failed to fetch instruction descriptors for program\",\n { data: { programId, error: err.message } },\n );\n contexts.push({\n type: ClearSignContextType.ERROR,\n error: err,\n });\n },\n Right: (value) => {\n const wantedDiscriminators = this.collectWantedDiscriminators(\n programId,\n input.instructions,\n );\n\n for (const [discriminator, result] of Object.entries(\n value.descriptors,\n )) {\n if (\n wantedDiscriminators !== null &&\n !wantedDiscriminators.has(discriminator)\n ) {\n continue;\n }\n contexts.push(\n result.caseOf<ClearSignContext>({\n Left: (error) => {\n this.logger.warn(\"[load] INSTRUCTION_INFO descriptor error\", {\n data: { programId, discriminator, error: error.message },\n });\n return { type: ClearSignContextType.ERROR, error };\n },\n Right: (payload) => ({\n type: ClearSignContextType.SOLANA_INSTRUCTION_INFO,\n payload,\n certificate,\n }),\n }),\n );\n }\n },\n });\n }\n\n this.logger.debug(\"[load] Emitted contexts\", {\n data: { count: contexts.length },\n });\n\n return contexts;\n }\n\n /**\n * Returns the set of discriminators the caller has explicitly asked\n * about for this `programId`, or `null` when the caller wants every\n * descriptor CAL has for the program.\n */\n private collectWantedDiscriminators(\n programId: string,\n instructions: SolanaInstructionRef[],\n ): Set<string> | null {\n const set = new Set<string>();\n let hasUnconstrained = false;\n for (const ix of instructions) {\n if (ix.programId !== programId) continue;\n if (ix.discriminator === undefined) {\n hasUnconstrained = true;\n } else {\n set.add(ix.discriminator);\n }\n }\n return hasUnconstrained ? null : set;\n }\n}\n"],
5
+ "mappings": "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",
6
+ "names": ["inject", "injectable", "array", "Codec", "optional", "string", "configTypes", "pkiTypes", "KeyId", "KeyUsage", "instructionInfoTypes", "ClearSignContextType", "loadCertificateResult", "deviceModelIdCodec", "SUPPORTED_TYPES", "ClearSignContextType", "NETWORK_DEFAULT", "instructionRefCodec", "Codec", "string", "optional", "solanaInstructionInfoInputCodec", "deviceModelIdCodec", "array", "InstructionInfoContextLoader", "dataSource", "certificateLoader", "loggerFactory", "input", "expectedTypes", "instructions", "ix", "network", "distinctProgramIds", "certPromise", "loadCertificateResult", "KeyId", "KeyUsage", "dataPromise", "programId", "certResult", "results", "error", "certificate", "contexts", "either", "err", "value", "wantedDiscriminators", "discriminator", "result", "payload", "set", "hasUnconstrained", "__decorateClass", "injectable", "__decorateParam", "inject", "instructionInfoTypes", "pkiTypes", "configTypes"]
7
+ }
@@ -0,0 +1,2 @@
1
+ import{DeviceModelId as u}from"@ledgerhq/device-management-kit";import{Left as g,Right as d}from"purify-ts";import{beforeEach as v,describe as O,expect as e,it as I,vi as s}from"vitest";import{ClearSignContextType as i}from"../../../../shared/model/ClearSignContext";import{InstructionInfoContextLoader as S}from"./InstructionInfoContextLoader";const w=()=>({debug:s.fn(),info:s.fn(),warn:s.fn(),error:s.fn(),subscribers:[]}),_={keyUsageNumber:8,payload:new Uint8Array([66])},a="11111111111111111111111111111111",m="JUP6LkbZbjS1jKKwapdHNy74zcZ3tLUZoi5QNyVTaV4";function y(){return{programId:a,discriminator:"00000000",instructionInfo:{data:"0001sys_data",signature:"prodsig_sys"},substructures:[{kind:0,data:"df1"},{kind:0,data:"df2"},{kind:1,data:"vfp1"}],enumVariants:[],idlDescriptor:{typePool:[],rootType:0},mintAssociations:[],valueFlowPorts:[],accountResets:[],displayFields:[]}}function f(){return{programId:a,descriptors:{"00000000":d(y())},enumVariants:[]}}function A(){return{programId:m,discriminator:"e517cb977ae3ad2a",instructionInfo:{data:"0001jup_data",signature:"prodsig_jup"},substructures:[],enumVariants:[],idlDescriptor:{typePool:[],rootType:0},mintAssociations:[],valueFlowPorts:[],accountResets:[],displayFields:[]}}function k(){return{programId:m,descriptors:{e517cb977ae3ad2a:d(A())},enumVariants:[]}}function R(c=[]){return{programId:m,descriptors:{e517cb977ae3ad2a:d({...A(),enumVariants:c})},enumVariants:c}}O("InstructionInfoContextLoader",()=>{let c,N;v(()=>{s.restoreAllMocks(),c={getInstructionInfo:s.fn()},N={loadCertificate:s.fn().mockResolvedValue(_)}});const l=()=>new S(c,N,w);O("canHandle",()=>{I("returns true when SOLANA_INSTRUCTION_INFO is requested and instructions are present",()=>{e(l().canHandle({deviceModelId:u.NANO_X,instructions:[{programId:a}]},[i.SOLANA_INSTRUCTION_INFO])).toBe(!0)}),I("returns false when SOLANA_INSTRUCTION_INFO is not requested",()=>{e(l().canHandle({deviceModelId:u.NANO_X,instructions:[{programId:a}]},[i.SOLANA_TOKEN])).toBe(!1)}),I("returns false on missing / empty / malformed instructions",()=>{const o=l(),t=[i.SOLANA_INSTRUCTION_INFO];e(o.canHandle({},t)).toBe(!1),e(o.canHandle({instructions:[]},t)).toBe(!1),e(o.canHandle({instructions:[{programId:""}]},t)).toBe(!1),e(o.canHandle(null,t)).toBe(!1),e(o.canHandle("string",t)).toBe(!1)})}),O("load",()=>{I("fans out one CAL call per distinct programId in parallel",async()=>{const o=l(),t=s.spyOn(c,"getInstructionInfo").mockImplementation(async({programId:r})=>r===a?d(f()):r===m?d(k()):g(new Error("unknown program"))),n=await o.load({deviceModelId:u.NANO_X,instructions:[{programId:a,discriminator:"00000000"},{programId:a,discriminator:"00000000"},{programId:m,discriminator:"e517cb977ae3ad2a"}],network:"solana-mainnet"});e(t).toHaveBeenCalledTimes(2),e(t).toHaveBeenCalledWith({programId:a,network:"solana-mainnet"}),e(t).toHaveBeenCalledWith({programId:m,network:"solana-mainnet"}),e(n.every(r=>r.type===i.SOLANA_INSTRUCTION_INFO||r.type===i.ERROR)).toBe(!0),e(n.filter(r=>r.type===i.SOLANA_INSTRUCTION_INFO)).toHaveLength(2)}),I("emits one SOLANA_INSTRUCTION_INFO per matching (programId, discriminator), passing the decoded payload through with the certificate",async()=>{const o=l();s.spyOn(c,"getInstructionInfo").mockResolvedValue(d(f()));const n=(await o.load({deviceModelId:u.NANO_X,instructions:[{programId:a,discriminator:"00000000"}]})).find(r=>r.type===i.SOLANA_INSTRUCTION_INFO);e(n).toBeDefined(),e(n).toMatchObject({type:i.SOLANA_INSTRUCTION_INFO,certificate:_}),e(n.payload).toEqual(y())}),I("does NOT emit SOLANA_ENUM_VARIANT contexts (those come from EnumVariantContextLoader)",async()=>{const o=l(),t=R([{enumId:"swap",variantIndex:46,descriptor:{data:"01_raydium_tlv",signature:"prodsig_v46"}}]);s.spyOn(c,"getInstructionInfo").mockResolvedValue(d(t));const n=await o.load({deviceModelId:u.NANO_X,instructions:[{programId:m,discriminator:"e517cb977ae3ad2a"}]});e(n.filter(r=>r.type===i.SOLANA_ENUM_VARIANT)).toHaveLength(0)}),I("bundles CAL enum_variants into the SOLANA_INSTRUCTION_INFO payload (host decode cache)",async()=>{const o=l(),t=[{enumId:"swap",variantIndex:46,descriptor:{data:"01_raydium_tlv",signature:"prodsig_v46"}}];s.spyOn(c,"getInstructionInfo").mockResolvedValue(d(R(t)));const r=(await o.load({deviceModelId:u.NANO_X,instructions:[{programId:m,discriminator:"e517cb977ae3ad2a"}]})).find(p=>p.type===i.SOLANA_INSTRUCTION_INFO);e(r.payload.enumVariants).toEqual(t)}),I("forwards exactly the enumVariants the data source decoded \u2014 no NaN indices",async()=>{const o=l(),t={enumId:"swap",variantIndex:46,descriptor:{data:"01_raydium_tlv",signature:"prodsig_v46"}};s.spyOn(c,"getInstructionInfo").mockResolvedValue(d(R([t])));const r=(await o.load({deviceModelId:u.NANO_X,instructions:[{programId:m,discriminator:"e517cb977ae3ad2a"}]})).find(p=>p.type===i.SOLANA_INSTRUCTION_INFO);e(r.payload.enumVariants).toEqual([t])}),I("filters descriptors by requested discriminator",async()=>{const o=l(),t={programId:a,descriptors:{"00000000":d(y()),"00000001":d({...y(),discriminator:"00000001",instructionInfo:{data:"0001other",signature:"p"}})},enumVariants:[]};s.spyOn(c,"getInstructionInfo").mockResolvedValue(d(t));const r=(await o.load({deviceModelId:u.NANO_X,instructions:[{programId:a,discriminator:"00000000"}]})).filter(p=>p.type===i.SOLANA_INSTRUCTION_INFO);e(r).toHaveLength(1),e(r[0].payload.discriminator).toBe("00000000")}),I("emits an ERROR context for a descriptor the data source could not decode",async()=>{const o=l(),t={programId:a,descriptors:{"00000000":g(new Error("missing 'test' signature"))},enumVariants:[]};s.spyOn(c,"getInstructionInfo").mockResolvedValue(d(t));const n=await o.load({deviceModelId:u.NANO_X,instructions:[{programId:a,discriminator:"00000000"}]});e(n).toHaveLength(1),e(n[0]?.type).toBe(i.ERROR),e(n[0].error.message).toMatch(/missing 'test' signature/)}),I("emits one ERROR context when CAL fails for a program but keeps processing the others",async()=>{const o=l();s.spyOn(c,"getInstructionInfo").mockImplementation(async({programId:p})=>p===a?d(f()):g(new Error("upstream-500")));const t=await o.load({deviceModelId:u.NANO_X,instructions:[{programId:a,discriminator:"00000000"},{programId:m,discriminator:"e517cb977ae3ad2a"}]}),n=t.filter(p=>p.type===i.ERROR),r=t.filter(p=>p.type===i.SOLANA_INSTRUCTION_INFO);e(n).toHaveLength(1),e(r).toHaveLength(1)}),I("degrades every program to ERROR when certificate loading fails",async()=>{s.spyOn(N,"loadCertificate").mockRejectedValue(new Error("pki-down")),s.spyOn(c,"getInstructionInfo").mockResolvedValue(d(f()));const t=await l().load({deviceModelId:u.NANO_X,instructions:[{programId:a},{programId:m}]});e(t).toHaveLength(2),e(t.every(n=>n.type===i.ERROR)).toBe(!0)}),I("degrades every program to ERROR when the certificate resolves undefined",async()=>{s.spyOn(N,"loadCertificate").mockResolvedValue(void 0),s.spyOn(c,"getInstructionInfo").mockResolvedValue(d(f()));const t=await l().load({deviceModelId:u.NANO_X,instructions:[{programId:a},{programId:m}]});e(t).toHaveLength(2),e(t.every(n=>n.type===i.ERROR)).toBe(!0),e(t[0].error.message).toMatch(/certificate is missing/)}),I("falls back to default network when input.network is omitted or empty string",async()=>{const o=l(),t=s.spyOn(c,"getInstructionInfo").mockResolvedValue(d(f()));await o.load({deviceModelId:u.NANO_X,instructions:[{programId:a}]}),e(t).toHaveBeenLastCalledWith({programId:a,network:"solana-mainnet"}),await o.load({deviceModelId:u.NANO_X,instructions:[{programId:a}],network:""}),e(t).toHaveBeenLastCalledWith({programId:a,network:"solana-mainnet"})})})});
2
+ //# sourceMappingURL=InstructionInfoContextLoader.test.js.map