@ledgerhq/context-module 2.3.0 → 2.4.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 (169) hide show
  1. package/lib/cjs/package.json +2 -2
  2. package/lib/cjs/src/modules/multichain/transaction-check/loaders/SolanaTransactionCheckLoader.js +1 -1
  3. package/lib/cjs/src/modules/multichain/transaction-check/loaders/SolanaTransactionCheckLoader.js.map +3 -3
  4. package/lib/cjs/src/modules/multichain/transaction-check/loaders/SolanaTransactionCheckLoader.test.js +1 -1
  5. package/lib/cjs/src/modules/multichain/transaction-check/loaders/SolanaTransactionCheckLoader.test.js.map +3 -3
  6. package/lib/cjs/src/modules/solana/alt-resolution/data/AltResolutionDataSource.js +1 -1
  7. package/lib/cjs/src/modules/solana/alt-resolution/data/AltResolutionDataSource.js.map +1 -1
  8. package/lib/cjs/src/modules/solana/alt-resolution/data/HttpAltResolutionDataSource.js +1 -1
  9. package/lib/cjs/src/modules/solana/alt-resolution/data/HttpAltResolutionDataSource.js.map +2 -2
  10. package/lib/cjs/src/modules/solana/alt-resolution/domain/AltResolutionContextLoader.js +1 -1
  11. package/lib/cjs/src/modules/solana/alt-resolution/domain/AltResolutionContextLoader.js.map +2 -2
  12. package/lib/cjs/src/modules/solana/instruction-info/data/HttpInstructionInfoDataSource.js +1 -1
  13. package/lib/cjs/src/modules/solana/instruction-info/data/HttpInstructionInfoDataSource.js.map +2 -2
  14. package/lib/cjs/src/modules/solana/instruction-info/data/HttpInstructionInfoDataSource.test.js +1 -1
  15. package/lib/cjs/src/modules/solana/instruction-info/data/HttpInstructionInfoDataSource.test.js.map +3 -3
  16. package/lib/cjs/src/modules/solana/instruction-info/data/InstructionInfoDto.js +1 -1
  17. package/lib/cjs/src/modules/solana/instruction-info/data/InstructionInfoDto.js.map +2 -2
  18. package/lib/cjs/src/modules/solana/lifi/domain/LifiContextLoader.js +1 -1
  19. package/lib/cjs/src/modules/solana/lifi/domain/LifiContextLoader.js.map +3 -3
  20. package/lib/cjs/src/modules/solana/lifi/domain/LifiContextLoader.test.js +1 -1
  21. package/lib/cjs/src/modules/solana/lifi/domain/LifiContextLoader.test.js.map +3 -3
  22. package/lib/cjs/src/modules/solana/model/SolanaContextTypes.js.map +1 -1
  23. package/lib/cjs/src/modules/solana/model/SolanaPayloads.js +1 -1
  24. package/lib/cjs/src/modules/solana/model/SolanaPayloads.js.map +2 -2
  25. package/lib/cjs/src/modules/solana/model/SolanaTransactionContext.js +1 -1
  26. package/lib/cjs/src/modules/solana/model/SolanaTransactionContext.js.map +1 -1
  27. package/lib/cjs/src/modules/solana/owner-info/data/HttpOwnerInfoDataSource.js +1 -1
  28. package/lib/cjs/src/modules/solana/owner-info/data/HttpOwnerInfoDataSource.js.map +2 -2
  29. package/lib/cjs/src/modules/solana/owner-info/data/HttpOwnerInfoDataSource.test.js +1 -1
  30. package/lib/cjs/src/modules/solana/owner-info/data/HttpOwnerInfoDataSource.test.js.map +2 -2
  31. package/lib/cjs/src/modules/solana/token/data/HttpMintToIdDataSource.js +2 -0
  32. package/lib/cjs/src/modules/solana/token/data/HttpMintToIdDataSource.js.map +7 -0
  33. package/lib/cjs/src/modules/solana/token/data/HttpMintToIdDataSource.test.js +2 -0
  34. package/lib/cjs/src/modules/solana/token/data/HttpMintToIdDataSource.test.js.map +7 -0
  35. package/lib/cjs/src/modules/solana/token/data/MintToIdDataSource.js +2 -0
  36. package/lib/cjs/src/modules/solana/token/data/MintToIdDataSource.js.map +7 -0
  37. package/lib/cjs/src/modules/solana/token/di/tokenModuleFactory.js +1 -1
  38. package/lib/cjs/src/modules/solana/token/di/tokenModuleFactory.js.map +3 -3
  39. package/lib/cjs/src/modules/solana/token/di/tokenTypes.js +1 -1
  40. package/lib/cjs/src/modules/solana/token/di/tokenTypes.js.map +2 -2
  41. package/lib/cjs/src/modules/solana/token/domain/TokenContextLoader.js +1 -1
  42. package/lib/cjs/src/modules/solana/token/domain/TokenContextLoader.js.map +3 -3
  43. package/lib/cjs/src/modules/solana/token/domain/TokenContextLoader.test.js +1 -1
  44. package/lib/cjs/src/modules/solana/token/domain/TokenContextLoader.test.js.map +3 -3
  45. package/lib/cjs/src/modules/solana/token-account-state/data/HttpTokenAccountStateDataSource.js +1 -1
  46. package/lib/cjs/src/modules/solana/token-account-state/data/HttpTokenAccountStateDataSource.js.map +2 -2
  47. package/lib/cjs/src/modules/solana/token-account-state/data/TokenAccountStateDataSource.js +1 -1
  48. package/lib/cjs/src/modules/solana/token-account-state/data/TokenAccountStateDataSource.js.map +1 -1
  49. package/lib/cjs/src/modules/solana/token-account-state/domain/TokenAccountStateContextLoader.js +1 -1
  50. package/lib/cjs/src/modules/solana/token-account-state/domain/TokenAccountStateContextLoader.js.map +2 -2
  51. package/lib/cjs/src/modules/solana/token-info/data/HttpTokenInfoDataSource.js +1 -1
  52. package/lib/cjs/src/modules/solana/token-info/data/HttpTokenInfoDataSource.js.map +3 -3
  53. package/lib/cjs/src/modules/solana/token-info/data/HttpTokenInfoDataSource.test.js +1 -1
  54. package/lib/cjs/src/modules/solana/token-info/data/HttpTokenInfoDataSource.test.js.map +2 -2
  55. package/lib/cjs/src/modules/solana/trusted-name/data/HttpTrustedNameDataSource.js +1 -1
  56. package/lib/cjs/src/modules/solana/trusted-name/data/HttpTrustedNameDataSource.js.map +3 -3
  57. package/lib/cjs/src/modules/solana/trusted-name/data/HttpTrustedNameDataSource.test.js +1 -1
  58. package/lib/cjs/src/modules/solana/trusted-name/data/HttpTrustedNameDataSource.test.js.map +2 -2
  59. package/lib/cjs/src/modules/solana/trusted-name/data/TrustedNameDataSource.js +1 -1
  60. package/lib/cjs/src/modules/solana/trusted-name/data/TrustedNameDataSource.js.map +1 -1
  61. package/lib/cjs/src/modules/solana/trusted-name/domain/TrustedNameContextLoader.js +1 -1
  62. package/lib/cjs/src/modules/solana/trusted-name/domain/TrustedNameContextLoader.js.map +2 -2
  63. package/lib/cjs/src/modules/solana/trusted-name/domain/TrustedNameContextLoader.test.js +1 -1
  64. package/lib/cjs/src/modules/solana/trusted-name/domain/TrustedNameContextLoader.test.js.map +2 -2
  65. package/lib/cjs/src/shared/utils/deviceModelIdCodec.js +1 -1
  66. package/lib/cjs/src/shared/utils/deviceModelIdCodec.js.map +2 -2
  67. package/lib/cjs/src/shared/utils/deviceModelIdCodec.test.js +1 -1
  68. package/lib/cjs/src/shared/utils/deviceModelIdCodec.test.js.map +2 -2
  69. package/lib/esm/package.json +2 -2
  70. package/lib/esm/src/modules/multichain/transaction-check/loaders/SolanaTransactionCheckLoader.js +1 -1
  71. package/lib/esm/src/modules/multichain/transaction-check/loaders/SolanaTransactionCheckLoader.js.map +3 -3
  72. package/lib/esm/src/modules/multichain/transaction-check/loaders/SolanaTransactionCheckLoader.test.js +1 -1
  73. package/lib/esm/src/modules/multichain/transaction-check/loaders/SolanaTransactionCheckLoader.test.js.map +3 -3
  74. package/lib/esm/src/modules/solana/alt-resolution/data/HttpAltResolutionDataSource.js +1 -1
  75. package/lib/esm/src/modules/solana/alt-resolution/data/HttpAltResolutionDataSource.js.map +2 -2
  76. package/lib/esm/src/modules/solana/alt-resolution/domain/AltResolutionContextLoader.js +1 -1
  77. package/lib/esm/src/modules/solana/alt-resolution/domain/AltResolutionContextLoader.js.map +2 -2
  78. package/lib/esm/src/modules/solana/instruction-info/data/HttpInstructionInfoDataSource.js +1 -1
  79. package/lib/esm/src/modules/solana/instruction-info/data/HttpInstructionInfoDataSource.js.map +2 -2
  80. package/lib/esm/src/modules/solana/instruction-info/data/HttpInstructionInfoDataSource.test.js +1 -1
  81. package/lib/esm/src/modules/solana/instruction-info/data/HttpInstructionInfoDataSource.test.js.map +3 -3
  82. package/lib/esm/src/modules/solana/instruction-info/data/InstructionInfoDto.js +1 -1
  83. package/lib/esm/src/modules/solana/instruction-info/data/InstructionInfoDto.js.map +2 -2
  84. package/lib/esm/src/modules/solana/lifi/domain/LifiContextLoader.js +1 -1
  85. package/lib/esm/src/modules/solana/lifi/domain/LifiContextLoader.js.map +3 -3
  86. package/lib/esm/src/modules/solana/lifi/domain/LifiContextLoader.test.js +1 -1
  87. package/lib/esm/src/modules/solana/lifi/domain/LifiContextLoader.test.js.map +3 -3
  88. package/lib/esm/src/modules/solana/model/SolanaPayloads.js.map +2 -2
  89. package/lib/esm/src/modules/solana/owner-info/data/HttpOwnerInfoDataSource.js +1 -1
  90. package/lib/esm/src/modules/solana/owner-info/data/HttpOwnerInfoDataSource.js.map +2 -2
  91. package/lib/esm/src/modules/solana/owner-info/data/HttpOwnerInfoDataSource.test.js +1 -1
  92. package/lib/esm/src/modules/solana/owner-info/data/HttpOwnerInfoDataSource.test.js.map +2 -2
  93. package/lib/esm/src/modules/solana/token/data/HttpMintToIdDataSource.js +2 -0
  94. package/lib/esm/src/modules/solana/token/data/HttpMintToIdDataSource.js.map +7 -0
  95. package/lib/esm/src/modules/solana/token/data/HttpMintToIdDataSource.test.js +2 -0
  96. package/lib/esm/src/modules/solana/token/data/HttpMintToIdDataSource.test.js.map +7 -0
  97. package/lib/esm/src/modules/solana/token/data/MintToIdDataSource.js +1 -0
  98. package/lib/esm/src/modules/solana/token/data/MintToIdDataSource.js.map +7 -0
  99. package/lib/esm/src/modules/solana/token/di/tokenModuleFactory.js +1 -1
  100. package/lib/esm/src/modules/solana/token/di/tokenModuleFactory.js.map +3 -3
  101. package/lib/esm/src/modules/solana/token/di/tokenTypes.js +1 -1
  102. package/lib/esm/src/modules/solana/token/di/tokenTypes.js.map +2 -2
  103. package/lib/esm/src/modules/solana/token/domain/TokenContextLoader.js +1 -1
  104. package/lib/esm/src/modules/solana/token/domain/TokenContextLoader.js.map +3 -3
  105. package/lib/esm/src/modules/solana/token/domain/TokenContextLoader.test.js +1 -1
  106. package/lib/esm/src/modules/solana/token/domain/TokenContextLoader.test.js.map +3 -3
  107. package/lib/esm/src/modules/solana/token-account-state/data/HttpTokenAccountStateDataSource.js +1 -1
  108. package/lib/esm/src/modules/solana/token-account-state/data/HttpTokenAccountStateDataSource.js.map +2 -2
  109. package/lib/esm/src/modules/solana/token-account-state/domain/TokenAccountStateContextLoader.js +1 -1
  110. package/lib/esm/src/modules/solana/token-account-state/domain/TokenAccountStateContextLoader.js.map +3 -3
  111. package/lib/esm/src/modules/solana/token-info/data/HttpTokenInfoDataSource.js +1 -1
  112. package/lib/esm/src/modules/solana/token-info/data/HttpTokenInfoDataSource.js.map +3 -3
  113. package/lib/esm/src/modules/solana/token-info/data/HttpTokenInfoDataSource.test.js +1 -1
  114. package/lib/esm/src/modules/solana/token-info/data/HttpTokenInfoDataSource.test.js.map +2 -2
  115. package/lib/esm/src/modules/solana/trusted-name/data/HttpTrustedNameDataSource.js +1 -1
  116. package/lib/esm/src/modules/solana/trusted-name/data/HttpTrustedNameDataSource.js.map +3 -3
  117. package/lib/esm/src/modules/solana/trusted-name/data/HttpTrustedNameDataSource.test.js +1 -1
  118. package/lib/esm/src/modules/solana/trusted-name/data/HttpTrustedNameDataSource.test.js.map +2 -2
  119. package/lib/esm/src/modules/solana/trusted-name/domain/TrustedNameContextLoader.js +1 -1
  120. package/lib/esm/src/modules/solana/trusted-name/domain/TrustedNameContextLoader.js.map +2 -2
  121. package/lib/esm/src/modules/solana/trusted-name/domain/TrustedNameContextLoader.test.js +1 -1
  122. package/lib/esm/src/modules/solana/trusted-name/domain/TrustedNameContextLoader.test.js.map +2 -2
  123. package/lib/esm/src/shared/utils/deviceModelIdCodec.js +1 -1
  124. package/lib/esm/src/shared/utils/deviceModelIdCodec.js.map +2 -2
  125. package/lib/esm/src/shared/utils/deviceModelIdCodec.test.js +1 -1
  126. package/lib/esm/src/shared/utils/deviceModelIdCodec.test.js.map +2 -2
  127. package/lib/types/src/modules/multichain/transaction-check/loaders/SolanaTransactionCheckLoader.d.ts +0 -12
  128. package/lib/types/src/modules/multichain/transaction-check/loaders/SolanaTransactionCheckLoader.d.ts.map +1 -1
  129. package/lib/types/src/modules/solana/alt-resolution/data/AltResolutionDataSource.d.ts +1 -0
  130. package/lib/types/src/modules/solana/alt-resolution/data/AltResolutionDataSource.d.ts.map +1 -1
  131. package/lib/types/src/modules/solana/alt-resolution/data/HttpAltResolutionDataSource.d.ts.map +1 -1
  132. package/lib/types/src/modules/solana/alt-resolution/domain/AltResolutionContextLoader.d.ts.map +1 -1
  133. package/lib/types/src/modules/solana/instruction-info/data/HttpInstructionInfoDataSource.d.ts.map +1 -1
  134. package/lib/types/src/modules/solana/instruction-info/data/InstructionInfoDto.d.ts +2 -2
  135. package/lib/types/src/modules/solana/instruction-info/data/InstructionInfoDto.d.ts.map +1 -1
  136. package/lib/types/src/modules/solana/lifi/domain/LifiContextLoader.d.ts.map +1 -1
  137. package/lib/types/src/modules/solana/model/SolanaContextTypes.d.ts +5 -1
  138. package/lib/types/src/modules/solana/model/SolanaContextTypes.d.ts.map +1 -1
  139. package/lib/types/src/modules/solana/model/SolanaPayloads.d.ts +5 -1
  140. package/lib/types/src/modules/solana/model/SolanaPayloads.d.ts.map +1 -1
  141. package/lib/types/src/modules/solana/model/SolanaTransactionContext.d.ts +1 -0
  142. package/lib/types/src/modules/solana/model/SolanaTransactionContext.d.ts.map +1 -1
  143. package/lib/types/src/modules/solana/owner-info/data/HttpOwnerInfoDataSource.d.ts.map +1 -1
  144. package/lib/types/src/modules/solana/token/data/HttpMintToIdDataSource.d.ts +11 -0
  145. package/lib/types/src/modules/solana/token/data/HttpMintToIdDataSource.d.ts.map +1 -0
  146. package/lib/types/src/modules/solana/token/data/HttpMintToIdDataSource.test.d.ts +2 -0
  147. package/lib/types/src/modules/solana/token/data/HttpMintToIdDataSource.test.d.ts.map +1 -0
  148. package/lib/types/src/modules/solana/token/data/MintToIdDataSource.d.ts +8 -0
  149. package/lib/types/src/modules/solana/token/data/MintToIdDataSource.d.ts.map +1 -0
  150. package/lib/types/src/modules/solana/token/di/tokenModuleFactory.d.ts.map +1 -1
  151. package/lib/types/src/modules/solana/token/di/tokenTypes.d.ts +1 -0
  152. package/lib/types/src/modules/solana/token/di/tokenTypes.d.ts.map +1 -1
  153. package/lib/types/src/modules/solana/token/domain/TokenContextLoader.d.ts +3 -1
  154. package/lib/types/src/modules/solana/token/domain/TokenContextLoader.d.ts.map +1 -1
  155. package/lib/types/src/modules/solana/token-account-state/data/HttpTokenAccountStateDataSource.d.ts.map +1 -1
  156. package/lib/types/src/modules/solana/token-account-state/data/TokenAccountStateDataSource.d.ts +1 -0
  157. package/lib/types/src/modules/solana/token-account-state/data/TokenAccountStateDataSource.d.ts.map +1 -1
  158. package/lib/types/src/modules/solana/token-account-state/domain/TokenAccountStateContextLoader.d.ts.map +1 -1
  159. package/lib/types/src/modules/solana/token-info/data/HttpTokenInfoDataSource.d.ts.map +1 -1
  160. package/lib/types/src/modules/solana/trusted-name/data/HttpTrustedNameDataSource.d.ts +1 -1
  161. package/lib/types/src/modules/solana/trusted-name/data/HttpTrustedNameDataSource.d.ts.map +1 -1
  162. package/lib/types/src/modules/solana/trusted-name/data/TrustedNameDataSource.d.ts +1 -0
  163. package/lib/types/src/modules/solana/trusted-name/data/TrustedNameDataSource.d.ts.map +1 -1
  164. package/lib/types/src/modules/solana/trusted-name/domain/TrustedNameContextLoader.d.ts +1 -0
  165. package/lib/types/src/modules/solana/trusted-name/domain/TrustedNameContextLoader.d.ts.map +1 -1
  166. package/lib/types/src/shared/utils/deviceModelIdCodec.d.ts +2 -2
  167. package/lib/types/src/shared/utils/deviceModelIdCodec.d.ts.map +1 -1
  168. package/lib/types/tsconfig.prod.tsbuildinfo +1 -1
  169. package/package.json +4 -4
@@ -1,2 +1,2 @@
1
- var g=Object.defineProperty;var E=Object.getOwnPropertyDescriptor;var d=(s,o,n,e)=>{for(var r=e>1?void 0:e?E(o,n):o,i=s.length-1,t;i>=0;i--)(t=s[i])&&(r=(e?t(o,n,r):t(r))||r);return e&&r&&g(o,n,r),r},l=(s,o)=>(n,e)=>o(n,e,s);import{inject as I,injectable as y}from"inversify";import{Left as c,Right as D}from"purify-ts";import{configTypes as w}from"../../../../config/di/configTypes";import{SolanaTransactionScanChainId as m}from"../../../../modules/solana/model/SolanaTransactionScanChainId";import{networkTypes as N}from"../../../../shared/network/di/networkTypes";import{calInstructionProgramCodec as S}from"./InstructionInfoDto";import{toInstructionInfoPayload as T,toProgramEnumVariants as M}from"./InstructionInfoMapper";const k={"solana-mainnet":m.MAINNET,"solana-devnet":m.DEVNET,"solana-testnet":m.TESTNET};let u=class{constructor(o,n){this.config=o;this.http=n}async getInstructionInfo({programId:o,network:n}){const e=k[n]??m.MAINNET;let r;try{r=await this.http.get(`${this.config.cal.url}/solana_programs`,{params:{id:o,chain_id:e,output:"id,chain_id,instructions",ref:`branch:${this.config.cal.branch}`}})}catch(t){const f=t instanceof Error?t.message:String(t);return c(new Error(`[ContextModule] HttpInstructionInfoDataSource: Failed to fetch instruction descriptors: ${f}`))}if(!Array.isArray(r)||r.length===0)return c(new Error(`[ContextModule] HttpInstructionInfoDataSource: empty response for program ${o}`));const i=r.find(t=>t!=null&&typeof t=="object"&&t.id===o);return i===void 0?c(new Error(`[ContextModule] HttpInstructionInfoDataSource: no descriptors for program ${o}`)):S.decode(i).caseOf({Left:t=>c(new Error(`[ContextModule] HttpInstructionInfoDataSource: malformed descriptors for program ${o}: ${t}`)),Right:()=>{const t=this.config.cal.mode??"prod",f=i.instructions,p=Object.fromEntries(f.map(a=>[a.discriminator_hex,a])),h=Object.fromEntries(Object.entries(p).map(([a,C])=>[a,T(o,a,C,t)]));return D({programId:o,descriptors:h,enumVariants:M(p,t)})}})}};u=d([y(),l(0,I(w.Config)),l(1,I(N.NetworkClient))],u);export{u as HttpInstructionInfoDataSource};
1
+ var g=Object.defineProperty;var E=Object.getOwnPropertyDescriptor;var d=(s,o,n,e)=>{for(var r=e>1?void 0:e?E(o,n):o,i=s.length-1,t;i>=0;i--)(t=s[i])&&(r=(e?t(o,n,r):t(r))||r);return e&&r&&g(o,n,r),r},l=(s,o)=>(n,e)=>o(n,e,s);import{inject as I,injectable as y}from"inversify";import{Left as c,Right as D}from"purify-ts";import{configTypes as w}from"../../../../config/di/configTypes";import{SolanaTransactionScanChainId as m}from"../../../../modules/solana/model/SolanaTransactionScanChainId";import{networkTypes as N}from"../../../../shared/network/di/networkTypes";import{calInstructionProgramCodec as S}from"./InstructionInfoDto";import{toInstructionInfoPayload as T,toProgramEnumVariants as M}from"./InstructionInfoMapper";const k={"solana-mainnet":m.MAINNET,"solana-devnet":m.DEVNET,"solana-testnet":m.TESTNET};let u=class{constructor(o,n){this.config=o;this.http=n}async getInstructionInfo({programId:o,network:n}){const e=k[n]??m.MAINNET;let r;try{r=await this.http.get(`${this.config.cal.url}/solana_programs`,{params:{id:o,chain_id:e,output:"id,chain_id,instructions",ref:`branch:${this.config.cal.branch}`}})}catch(t){const f=t instanceof Error?t.message:String(t);return c(new Error(`[ContextModule] HttpInstructionInfoDataSource: Failed to fetch instruction descriptors: ${f}`))}if(!Array.isArray(r)||r.length===0)return c(new Error(`[ContextModule] HttpInstructionInfoDataSource: empty response for program ${o}`));const i=r.find(t=>t!=null&&typeof t=="object"&&t.id===o);return i===void 0?c(new Error(`[ContextModule] HttpInstructionInfoDataSource: no descriptors for program ${o}`)):S.decode(i).caseOf({Left:t=>c(new Error(`[ContextModule] HttpInstructionInfoDataSource: malformed descriptors for program ${o}: ${t}`)),Right:()=>{const t=this.config.cal.mode??"prod",f=i.instructions,p=Object.fromEntries(f.map(a=>[a.discriminator_hex??"",a])),h=Object.fromEntries(Object.entries(p).map(([a,C])=>[a,T(o,a,C,t)]));return D({programId:o,descriptors:h,enumVariants:M(p,t)})}})}};u=d([y(),l(0,I(w.Config)),l(1,I(N.NetworkClient))],u);export{u as HttpInstructionInfoDataSource};
2
2
  //# sourceMappingURL=HttpInstructionInfoDataSource.js.map
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "version": 3,
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 { Either, Left, Right } from \"purify-ts\";\n\nimport { configTypes } from \"@/config/di/configTypes\";\nimport { type ContextModuleServiceConfig } from \"@/config/model/ContextModuleConfig\";\nimport { SolanaTransactionScanChainId } from \"@/modules/solana/model/SolanaTransactionScanChainId\";\nimport { networkTypes } from \"@/shared/network/di/networkTypes\";\n\nimport {\n GetInstructionInfoParams,\n InstructionInfoDataSource,\n InstructionInfoResult,\n} from \"./InstructionInfoDataSource\";\nimport {\n type CalInstructionDescriptorDto,\n calInstructionProgramCodec,\n type CalInstructionProgramDto,\n} from \"./InstructionInfoDto\";\nimport {\n type CalMode,\n toInstructionInfoPayload,\n toProgramEnumVariants,\n} from \"./InstructionInfoMapper\";\n\n// Maps the DMK network label to the numeric CAL `chain_id` (the extended\n// Solana network ids 900/901/902). Unknown labels fall back to mainnet.\nconst CHAIN_ID_BY_NETWORK: Record<string, SolanaTransactionScanChainId> = {\n \"solana-mainnet\": SolanaTransactionScanChainId.MAINNET,\n \"solana-devnet\": SolanaTransactionScanChainId.DEVNET,\n \"solana-testnet\": SolanaTransactionScanChainId.TESTNET,\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 const chainId =\n CHAIN_ID_BY_NETWORK[network] ?? SolanaTransactionScanChainId.MAINNET;\n let data: unknown;\n try {\n data = await this.http.get(`${this.config.cal.url}/solana_programs`, {\n params: {\n id: programId,\n chain_id: chainId,\n output: \"id,chain_id,instructions\",\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 // Select the program object whose `id` matches the requested `programId`\n // (the response is an array, one object per requested id).\n const program = data.find(\n (entry): entry is { id: unknown } =>\n entry != null &&\n typeof entry === \"object\" &&\n (entry as { id?: unknown }).id === programId,\n );\n if (program === undefined) {\n return Left(\n new Error(\n `[ContextModule] HttpInstructionInfoDataSource: no descriptors for program ${programId}`,\n ),\n );\n }\n\n // Validate the program shape so the mapper can dereference `descriptor` /\n // `enum_variants` without runtime-throwing on a malformed CAL payload. A\n // malformed program degrades to a per-program ERROR rather than rejecting\n // the batch. On success we transform each validated DTO into the core\n // payload so the loader never sees the CAL DTO shapes.\n return calInstructionProgramCodec\n .decode(program)\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 Right: () => {\n const mode: CalMode = this.config.cal.mode ?? \"prod\";\n // The codec strips undeclared fields, so we key the original\n // (full) instruction objects by `discriminator_hex` \u2014 the cast is\n // justified now that the shape has been validated.\n const instructions = (program as CalInstructionProgramDto)\n .instructions;\n const descriptorsByDiscriminator: Record<\n string,\n CalInstructionDescriptorDto\n > = Object.fromEntries(\n instructions.map((dto) => [dto.discriminator_hex, dto]),\n );\n const mapped = Object.fromEntries(\n Object.entries(descriptorsByDiscriminator).map(\n ([discriminator, dto]) => [\n discriminator,\n toInstructionInfoPayload(programId, discriminator, dto, mode),\n ],\n ),\n );\n return Right({\n programId,\n descriptors: mapped,\n enumVariants: toProgramEnumVariants(\n descriptorsByDiscriminator,\n mode,\n ),\n });\n },\n });\n }\n}\n"],
5
- "mappings": "iOACA,OAAS,UAAAA,EAAQ,cAAAC,MAAkB,YACnC,OAAiB,QAAAC,EAAM,SAAAC,MAAa,YAEpC,OAAS,eAAAC,MAAmB,0BAE5B,OAAS,gCAAAC,MAAoC,sDAC7C,OAAS,gBAAAC,MAAoB,mCAO7B,OAEE,8BAAAC,MAEK,uBACP,OAEE,4BAAAC,EACA,yBAAAC,MACK,0BAIP,MAAMC,EAAoE,CACxE,iBAAkBC,EAA6B,QAC/C,gBAAiBA,EAA6B,OAC9C,iBAAkBA,EAA6B,OACjD,EAGO,IAAMC,EAAN,KAEP,CACE,YAEmBC,EAEAC,EACjB,CAHiB,YAAAD,EAEA,UAAAC,CAChB,CAEH,MAAa,mBAAmB,CAC9B,UAAAC,EACA,QAAAC,CACF,EAA4E,CAC1E,MAAMC,EACJP,EAAoBM,CAAO,GAAKL,EAA6B,QAC/D,IAAIO,EACJ,GAAI,CACFA,EAAO,MAAM,KAAK,KAAK,IAAI,GAAG,KAAK,OAAO,IAAI,GAAG,mBAAoB,CACnE,OAAQ,CACN,GAAIH,EACJ,SAAUE,EACV,OAAQ,2BACR,IAAK,UAAU,KAAK,OAAO,IAAI,MAAM,EACvC,CACF,CAAC,CACH,OAASE,EAAO,CACd,MAAMC,EAASD,aAAiB,MAAQA,EAAM,QAAU,OAAOA,CAAK,EACpE,OAAOE,EACL,IAAI,MACF,2FAA2FD,CAAM,EACnG,CACF,CACF,CAEA,GAAI,CAAC,MAAM,QAAQF,CAAI,GAAKA,EAAK,SAAW,EAC1C,OAAOG,EACL,IAAI,MACF,6EAA6EN,CAAS,EACxF,CACF,EAKF,MAAMO,EAAUJ,EAAK,KAClBK,GACCA,GAAS,MACT,OAAOA,GAAU,UAChBA,EAA2B,KAAOR,CACvC,EACA,OAAIO,IAAY,OACPD,EACL,IAAI,MACF,6EAA6EN,CAAS,EACxF,CACF,EAQKS,EACJ,OAAOF,CAAO,EACd,OAA6C,CAC5C,KAAOH,GACLE,EACE,IAAI,MACF,oFAAoFN,CAAS,KAAKI,CAAK,EACzG,CACF,EACF,MAAO,IAAM,CACX,MAAMM,EAAgB,KAAK,OAAO,IAAI,MAAQ,OAIxCC,EAAgBJ,EACnB,aACGK,EAGF,OAAO,YACTD,EAAa,IAAKE,GAAQ,CAACA,EAAI,kBAAmBA,CAAG,CAAC,CACxD,EACMC,EAAS,OAAO,YACpB,OAAO,QAAQF,CAA0B,EAAE,IACzC,CAAC,CAACG,EAAeF,CAAG,IAAM,CACxBE,EACAC,EAAyBhB,EAAWe,EAAeF,EAAKH,CAAI,CAC9D,CACF,CACF,EACA,OAAOO,EAAM,CACX,UAAAjB,EACA,YAAac,EACb,aAAcI,EACZN,EACAF,CACF,CACF,CAAC,CACH,CACF,CAAC,CACL,CACF,EAzGab,EAANsB,EAAA,CADNC,EAAW,EAKPC,EAAA,EAAAC,EAAOC,EAAY,MAAM,GAEzBF,EAAA,EAAAC,EAAOE,EAAa,aAAa,IANzB3B",
4
+ "sourcesContent": ["import { DmkNetworkClient } from \"@ledgerhq/device-management-kit\";\nimport { inject, injectable } from \"inversify\";\nimport { Either, Left, Right } from \"purify-ts\";\n\nimport { configTypes } from \"@/config/di/configTypes\";\nimport { type ContextModuleServiceConfig } from \"@/config/model/ContextModuleConfig\";\nimport { SolanaTransactionScanChainId } from \"@/modules/solana/model/SolanaTransactionScanChainId\";\nimport { networkTypes } from \"@/shared/network/di/networkTypes\";\n\nimport {\n GetInstructionInfoParams,\n InstructionInfoDataSource,\n InstructionInfoResult,\n} from \"./InstructionInfoDataSource\";\nimport {\n type CalInstructionDescriptorDto,\n calInstructionProgramCodec,\n type CalInstructionProgramDto,\n} from \"./InstructionInfoDto\";\nimport {\n type CalMode,\n toInstructionInfoPayload,\n toProgramEnumVariants,\n} from \"./InstructionInfoMapper\";\n\n// Maps the DMK network label to the numeric CAL `chain_id` (the extended\n// Solana network ids 900/901/902). Unknown labels fall back to mainnet.\nconst CHAIN_ID_BY_NETWORK: Record<string, SolanaTransactionScanChainId> = {\n \"solana-mainnet\": SolanaTransactionScanChainId.MAINNET,\n \"solana-devnet\": SolanaTransactionScanChainId.DEVNET,\n \"solana-testnet\": SolanaTransactionScanChainId.TESTNET,\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 const chainId =\n CHAIN_ID_BY_NETWORK[network] ?? SolanaTransactionScanChainId.MAINNET;\n let data: unknown;\n try {\n data = await this.http.get(`${this.config.cal.url}/solana_programs`, {\n params: {\n id: programId,\n chain_id: chainId,\n output: \"id,chain_id,instructions\",\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 // Select the program object whose `id` matches the requested `programId`\n // (the response is an array, one object per requested id).\n const program = data.find(\n (entry): entry is { id: unknown } =>\n entry != null &&\n typeof entry === \"object\" &&\n (entry as { id?: unknown }).id === programId,\n );\n if (program === undefined) {\n return Left(\n new Error(\n `[ContextModule] HttpInstructionInfoDataSource: no descriptors for program ${programId}`,\n ),\n );\n }\n\n // Validate the program shape so the mapper can dereference `descriptor` /\n // `enum_variants` without runtime-throwing on a malformed CAL payload. A\n // malformed program degrades to a per-program ERROR rather than rejecting\n // the batch. On success we transform each validated DTO into the core\n // payload so the loader never sees the CAL DTO shapes.\n return calInstructionProgramCodec\n .decode(program)\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 Right: () => {\n const mode: CalMode = this.config.cal.mode ?? \"prod\";\n // The codec strips undeclared fields, so we key the original\n // (full) instruction objects by `discriminator_hex` \u2014 the cast is\n // justified now that the shape has been validated. A descriptor\n // without a discriminator (single-instruction programs such as SPL\n // Memo) is keyed under the empty string.\n const instructions = (program as CalInstructionProgramDto)\n .instructions;\n const descriptorsByDiscriminator: Record<\n string,\n CalInstructionDescriptorDto\n > = Object.fromEntries(\n instructions.map((dto) => [dto.discriminator_hex ?? \"\", dto]),\n );\n const mapped = Object.fromEntries(\n Object.entries(descriptorsByDiscriminator).map(\n ([discriminator, dto]) => [\n discriminator,\n toInstructionInfoPayload(programId, discriminator, dto, mode),\n ],\n ),\n );\n return Right({\n programId,\n descriptors: mapped,\n enumVariants: toProgramEnumVariants(\n descriptorsByDiscriminator,\n mode,\n ),\n });\n },\n });\n }\n}\n"],
5
+ "mappings": "iOACA,OAAS,UAAAA,EAAQ,cAAAC,MAAkB,YACnC,OAAiB,QAAAC,EAAM,SAAAC,MAAa,YAEpC,OAAS,eAAAC,MAAmB,0BAE5B,OAAS,gCAAAC,MAAoC,sDAC7C,OAAS,gBAAAC,MAAoB,mCAO7B,OAEE,8BAAAC,MAEK,uBACP,OAEE,4BAAAC,EACA,yBAAAC,MACK,0BAIP,MAAMC,EAAoE,CACxE,iBAAkBC,EAA6B,QAC/C,gBAAiBA,EAA6B,OAC9C,iBAAkBA,EAA6B,OACjD,EAGO,IAAMC,EAAN,KAEP,CACE,YAEmBC,EAEAC,EACjB,CAHiB,YAAAD,EAEA,UAAAC,CAChB,CAEH,MAAa,mBAAmB,CAC9B,UAAAC,EACA,QAAAC,CACF,EAA4E,CAC1E,MAAMC,EACJP,EAAoBM,CAAO,GAAKL,EAA6B,QAC/D,IAAIO,EACJ,GAAI,CACFA,EAAO,MAAM,KAAK,KAAK,IAAI,GAAG,KAAK,OAAO,IAAI,GAAG,mBAAoB,CACnE,OAAQ,CACN,GAAIH,EACJ,SAAUE,EACV,OAAQ,2BACR,IAAK,UAAU,KAAK,OAAO,IAAI,MAAM,EACvC,CACF,CAAC,CACH,OAASE,EAAO,CACd,MAAMC,EAASD,aAAiB,MAAQA,EAAM,QAAU,OAAOA,CAAK,EACpE,OAAOE,EACL,IAAI,MACF,2FAA2FD,CAAM,EACnG,CACF,CACF,CAEA,GAAI,CAAC,MAAM,QAAQF,CAAI,GAAKA,EAAK,SAAW,EAC1C,OAAOG,EACL,IAAI,MACF,6EAA6EN,CAAS,EACxF,CACF,EAKF,MAAMO,EAAUJ,EAAK,KAClBK,GACCA,GAAS,MACT,OAAOA,GAAU,UAChBA,EAA2B,KAAOR,CACvC,EACA,OAAIO,IAAY,OACPD,EACL,IAAI,MACF,6EAA6EN,CAAS,EACxF,CACF,EAQKS,EACJ,OAAOF,CAAO,EACd,OAA6C,CAC5C,KAAOH,GACLE,EACE,IAAI,MACF,oFAAoFN,CAAS,KAAKI,CAAK,EACzG,CACF,EACF,MAAO,IAAM,CACX,MAAMM,EAAgB,KAAK,OAAO,IAAI,MAAQ,OAMxCC,EAAgBJ,EACnB,aACGK,EAGF,OAAO,YACTD,EAAa,IAAKE,GAAQ,CAACA,EAAI,mBAAqB,GAAIA,CAAG,CAAC,CAC9D,EACMC,EAAS,OAAO,YACpB,OAAO,QAAQF,CAA0B,EAAE,IACzC,CAAC,CAACG,EAAeF,CAAG,IAAM,CACxBE,EACAC,EAAyBhB,EAAWe,EAAeF,EAAKH,CAAI,CAC9D,CACF,CACF,EACA,OAAOO,EAAM,CACX,UAAAjB,EACA,YAAac,EACb,aAAcI,EACZN,EACAF,CACF,CACF,CAAC,CACH,CACF,CAAC,CACL,CACF,EA3Gab,EAANsB,EAAA,CADNC,EAAW,EAKPC,EAAA,EAAAC,EAAOC,EAAY,MAAM,GAEzBF,EAAA,EAAAC,EAAOE,EAAa,aAAa,IANzB3B",
6
6
  "names": ["inject", "injectable", "Left", "Right", "configTypes", "SolanaTransactionScanChainId", "networkTypes", "calInstructionProgramCodec", "toInstructionInfoPayload", "toProgramEnumVariants", "CHAIN_ID_BY_NETWORK", "SolanaTransactionScanChainId", "HttpInstructionInfoDataSource", "config", "http", "programId", "network", "chainId", "data", "error", "reason", "Left", "program", "entry", "calInstructionProgramCodec", "mode", "instructions", "descriptorsByDiscriminator", "dto", "mapped", "discriminator", "toInstructionInfoPayload", "Right", "toProgramEnumVariants", "__decorateClass", "injectable", "__decorateParam", "inject", "configTypes", "networkTypes"]
7
7
  }
@@ -1,2 +1,2 @@
1
- import{Left as u,Right as l}from"purify-ts";import{beforeEach as m,describe as g,expect as o,it as a,vi as d}from"vitest";import{SolanaTransactionScanChainId as i}from"../../../../modules/solana/model/SolanaTransactionScanChainId";import{HttpInstructionInfoDataSource as f}from"./HttpInstructionInfoDataSource";g("HttpInstructionInfoDataSource",()=>{let r,e;const t="11111111111111111111111111111111",s="solana-mainnet",p={cal:{url:"https://global.api.prd.ledger.com/cal/v1",mode:"prod",branch:"main"}},c=[{id:t,chain_id:i.MAINNET,instructions:[{discriminator_hex:"00000000",instruction_name:"createAccount",descriptor:{data:"00010101",signatures:{prod:"prodsig",test:"testsig"}},display_fields:[],value_flow_ports:[],hide_rules:[],account_resets:[]}]}];m(()=>{d.clearAllMocks(),e={get:d.fn()},r=new f(p,e)}),a("calls CAL /solana_programs with id, chain_id and output params",async()=>{e.get.mockResolvedValue(c),await r.getInstructionInfo({programId:t,network:s}),o(e.get).toHaveBeenCalledTimes(1),o(e.get).toHaveBeenCalledWith("https://global.api.prd.ledger.com/cal/v1/solana_programs",{params:{id:t,chain_id:i.MAINNET,output:"id,chain_id,instructions",ref:"branch:main"}})}),a("maps devnet/testnet networks to their numeric chain ids",async()=>{e.get.mockResolvedValue(c),await r.getInstructionInfo({programId:t,network:"solana-devnet"}),o(e.get).toHaveBeenCalledWith("https://global.api.prd.ledger.com/cal/v1/solana_programs",o.objectContaining({params:o.objectContaining({chain_id:901})}))}),a("returns Right with each descriptor transformed into the core payload on success",async()=>{e.get.mockResolvedValue(c);const n=await r.getInstructionInfo({programId:t,network:s});o(n).toEqual(l({programId:t,descriptors:{"00000000":l({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()=>{e.get.mockResolvedValue([]);const n=await r.getInstructionInfo({programId:t,network:s});o(n).toEqual(u(new Error(`[ContextModule] HttpInstructionInfoDataSource: empty response for program ${t}`)))}),a("returns Left when no program object matches the requested programId",async()=>{e.get.mockResolvedValue([{id:"OtherProgram",chain_id:i.MAINNET,instructions:[]}]);const n=await r.getInstructionInfo({programId:t,network:s});o(n).toEqual(u(new Error(`[ContextModule] HttpInstructionInfoDataSource: no descriptors for program ${t}`)))}),a("returns Left (not a throw) when an instruction descriptor is malformed",async()=>{e.get.mockResolvedValue([{id:t,chain_id:i.MAINNET,instructions:[{discriminator_hex:"00000000"}]}]);const n=await r.getInstructionInfo({programId:t,network:s});o(n.isLeft()).toBe(!0),o(n.extract().message).toMatch(new RegExp(String.raw`\[ContextModule\] HttpInstructionInfoDataSource: malformed descriptors for program ${t}:`))}),a("returns Left when the HTTP client throws",async()=>{e.get.mockRejectedValue(new Error("network"));const n=await r.getInstructionInfo({programId:t,network:s});o(n).toEqual(u(new Error("[ContextModule] HttpInstructionInfoDataSource: Failed to fetch instruction descriptors: network")))})});
1
+ import{Left as u,Right as l}from"purify-ts";import{beforeEach as g,describe as f,expect as e,it as s,vi as p}from"vitest";import{SolanaTransactionScanChainId as i}from"../../../../modules/solana/model/SolanaTransactionScanChainId";import{HttpInstructionInfoDataSource as h}from"./HttpInstructionInfoDataSource";f("HttpInstructionInfoDataSource",()=>{let r,o;const t="11111111111111111111111111111111",a="solana-mainnet",m={cal:{url:"https://global.api.prd.ledger.com/cal/v1",mode:"prod",branch:"main"}},c=[{id:t,chain_id:i.MAINNET,instructions:[{discriminator_hex:"00000000",instruction_name:"createAccount",descriptor:{data:"00010101",signatures:{prod:"prodsig",test:"testsig"}},display_fields:[],value_flow_ports:[],hide_rules:[],account_resets:[]}]}];g(()=>{p.clearAllMocks(),o={get:p.fn()},r=new h(m,o)}),s("calls CAL /solana_programs with id, chain_id and output params",async()=>{o.get.mockResolvedValue(c),await r.getInstructionInfo({programId:t,network:a}),e(o.get).toHaveBeenCalledTimes(1),e(o.get).toHaveBeenCalledWith("https://global.api.prd.ledger.com/cal/v1/solana_programs",{params:{id:t,chain_id:i.MAINNET,output:"id,chain_id,instructions",ref:"branch:main"}})}),s("maps devnet/testnet networks to their numeric chain ids",async()=>{o.get.mockResolvedValue(c),await r.getInstructionInfo({programId:t,network:"solana-devnet"}),e(o.get).toHaveBeenCalledWith("https://global.api.prd.ledger.com/cal/v1/solana_programs",e.objectContaining({params:e.objectContaining({chain_id:901})}))}),s("returns Right with each descriptor transformed into the core payload on success",async()=>{o.get.mockResolvedValue(c);const n=await r.getInstructionInfo({programId:t,network:a});e(n).toEqual(l({programId:t,descriptors:{"00000000":l({programId:t,discriminator:"00000000",instructionInfo:{data:"00010101",signature:"prodsig"},substructures:[],enumVariants:[],idlDescriptor:{typePool:[],rootType:0},mintAssociations:[],valueFlowPorts:[],accountResets:[],displayFields:[]})},enumVariants:[]}))}),s("keys a descriptor without `discriminator_hex` under the empty string",async()=>{o.get.mockResolvedValue([{id:t,chain_id:i.MAINNET,instructions:[{instruction_name:"addMemo",descriptor:{data:"00010101",signatures:{prod:"prodsig",test:"testsig"}}}]}]);const n=await r.getInstructionInfo({programId:t,network:a});e(n.isRight()).toBe(!0);const{descriptors:d}=n.unsafeCoerce();e(Object.keys(d)).toEqual([""]),e(d[""].unsafeCoerce()).toEqual(e.objectContaining({programId:t,discriminator:"",instructionInfo:{data:"00010101",signature:"prodsig"}}))}),s("returns Left when the response array is empty",async()=>{o.get.mockResolvedValue([]);const n=await r.getInstructionInfo({programId:t,network:a});e(n).toEqual(u(new Error(`[ContextModule] HttpInstructionInfoDataSource: empty response for program ${t}`)))}),s("returns Left when no program object matches the requested programId",async()=>{o.get.mockResolvedValue([{id:"OtherProgram",chain_id:i.MAINNET,instructions:[]}]);const n=await r.getInstructionInfo({programId:t,network:a});e(n).toEqual(u(new Error(`[ContextModule] HttpInstructionInfoDataSource: no descriptors for program ${t}`)))}),s("returns Left (not a throw) when an instruction descriptor is malformed",async()=>{o.get.mockResolvedValue([{id:t,chain_id:i.MAINNET,instructions:[{discriminator_hex:"00000000"}]}]);const n=await r.getInstructionInfo({programId:t,network:a});e(n.isLeft()).toBe(!0),e(n.extract().message).toMatch(new RegExp(String.raw`\[ContextModule\] HttpInstructionInfoDataSource: malformed descriptors for program ${t}:`))}),s("returns Left when the HTTP client throws",async()=>{o.get.mockRejectedValue(new Error("network"));const n=await r.getInstructionInfo({programId:t,network:a});e(n).toEqual(u(new Error("[ContextModule] HttpInstructionInfoDataSource: Failed to fetch instruction descriptors: network")))})});
2
2
  //# sourceMappingURL=HttpInstructionInfoDataSource.test.js.map
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "version": 3,
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\";\nimport { SolanaTransactionScanChainId } from \"@/modules/solana/model/SolanaTransactionScanChainId\";\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://global.api.prd.ledger.com/cal/v1\",\n mode: \"prod\",\n branch: \"main\",\n },\n } as ContextModuleServiceConfig;\n\n const successResponse: CalInstructionInfoResponseDto = [\n {\n id: programId,\n chain_id: SolanaTransactionScanChainId.MAINNET,\n instructions: [\n {\n discriminator_hex: \"00000000\",\n instruction_name: \"createAccount\",\n descriptor: {\n data: \"00010101\",\n signatures: { prod: \"prodsig\", test: \"testsig\" },\n },\n display_fields: [],\n value_flow_ports: [],\n hide_rules: [],\n account_resets: [],\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 /solana_programs with id, chain_id and output params\", 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://global.api.prd.ledger.com/cal/v1/solana_programs\",\n {\n params: {\n id: programId,\n chain_id: SolanaTransactionScanChainId.MAINNET,\n output: \"id,chain_id,instructions\",\n ref: \"branch:main\",\n },\n },\n );\n });\n\n it(\"maps devnet/testnet networks to their numeric chain ids\", async () => {\n httpMock.get.mockResolvedValue(successResponse);\n\n await datasource.getInstructionInfo({\n programId,\n network: \"solana-devnet\",\n });\n\n expect(httpMock.get).toHaveBeenCalledWith(\n \"https://global.api.prd.ledger.com/cal/v1/solana_programs\",\n expect.objectContaining({\n params: expect.objectContaining({ chain_id: 901 }),\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 no program object matches the requested programId\", async () => {\n httpMock.get.mockResolvedValue([\n {\n id: \"OtherProgram\",\n chain_id: SolanaTransactionScanChainId.MAINNET,\n instructions: [],\n },\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 instruction descriptor is malformed\", async () => {\n // `descriptor` missing on the instruction \u2014 would crash the loader if the\n // datasource handed it through unvalidated.\n httpMock.get.mockResolvedValue([\n {\n id: programId,\n chain_id: SolanaTransactionScanChainId.MAINNET,\n instructions: [{ discriminator_hex: \"00000000\" }],\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": "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",
6
- "names": ["Left", "Right", "beforeEach", "describe", "expect", "it", "vi", "SolanaTransactionScanChainId", "HttpInstructionInfoDataSource", "datasource", "httpMock", "programId", "network", "config", "successResponse", "result"]
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\";\nimport { SolanaTransactionScanChainId } from \"@/modules/solana/model/SolanaTransactionScanChainId\";\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://global.api.prd.ledger.com/cal/v1\",\n mode: \"prod\",\n branch: \"main\",\n },\n } as ContextModuleServiceConfig;\n\n const successResponse: CalInstructionInfoResponseDto = [\n {\n id: programId,\n chain_id: SolanaTransactionScanChainId.MAINNET,\n instructions: [\n {\n discriminator_hex: \"00000000\",\n instruction_name: \"createAccount\",\n descriptor: {\n data: \"00010101\",\n signatures: { prod: \"prodsig\", test: \"testsig\" },\n },\n display_fields: [],\n value_flow_ports: [],\n hide_rules: [],\n account_resets: [],\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 /solana_programs with id, chain_id and output params\", 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://global.api.prd.ledger.com/cal/v1/solana_programs\",\n {\n params: {\n id: programId,\n chain_id: SolanaTransactionScanChainId.MAINNET,\n output: \"id,chain_id,instructions\",\n ref: \"branch:main\",\n },\n },\n );\n });\n\n it(\"maps devnet/testnet networks to their numeric chain ids\", async () => {\n httpMock.get.mockResolvedValue(successResponse);\n\n await datasource.getInstructionInfo({\n programId,\n network: \"solana-devnet\",\n });\n\n expect(httpMock.get).toHaveBeenCalledWith(\n \"https://global.api.prd.ledger.com/cal/v1/solana_programs\",\n expect.objectContaining({\n params: expect.objectContaining({ chain_id: 901 }),\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(\"keys a descriptor without `discriminator_hex` under the empty string\", async () => {\n // Single-instruction programs (e.g. SPL Memo `addMemo`) genuinely have no\n // discriminator, so CAL omits the field.\n httpMock.get.mockResolvedValue([\n {\n id: programId,\n chain_id: SolanaTransactionScanChainId.MAINNET,\n instructions: [\n {\n instruction_name: \"addMemo\",\n descriptor: {\n data: \"00010101\",\n signatures: { prod: \"prodsig\", test: \"testsig\" },\n },\n },\n ],\n },\n ]);\n\n const result = await datasource.getInstructionInfo({ programId, network });\n\n expect(result.isRight()).toBe(true);\n const { descriptors } = result.unsafeCoerce();\n expect(Object.keys(descriptors)).toEqual([\"\"]);\n expect(descriptors[\"\"]!.unsafeCoerce()).toEqual(\n expect.objectContaining({\n programId,\n discriminator: \"\",\n instructionInfo: { data: \"00010101\", signature: \"prodsig\" },\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 no program object matches the requested programId\", async () => {\n httpMock.get.mockResolvedValue([\n {\n id: \"OtherProgram\",\n chain_id: SolanaTransactionScanChainId.MAINNET,\n instructions: [],\n },\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 instruction descriptor is malformed\", async () => {\n // `descriptor` missing on the instruction \u2014 would crash the loader if the\n // datasource handed it through unvalidated.\n httpMock.get.mockResolvedValue([\n {\n id: programId,\n chain_id: SolanaTransactionScanChainId.MAINNET,\n instructions: [{ discriminator_hex: \"00000000\" }],\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": "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",
6
+ "names": ["Left", "Right", "beforeEach", "describe", "expect", "it", "vi", "SolanaTransactionScanChainId", "HttpInstructionInfoDataSource", "datasource", "httpMock", "programId", "network", "config", "successResponse", "result", "descriptors"]
7
7
  }
@@ -1,2 +1,2 @@
1
- import{array as n,Codec as r,number as s,optional as e,record as i,string as t}from"purify-ts";const c=r.interface({prod:e(t),test:e(t)}),a=r.interface({data:t,signatures:c}),u=r.interface({descriptor:a}),o=r.interface({descriptor:t}),l=r.interface({discriminator_hex:t,descriptor:a,enum_variants:e(i(t,i(t,u))),display_fields:e(n(o)),value_flow_ports:e(n(o)),hide_rules:e(n(o)),account_resets:e(n(o))}),d=r.interface({id:t,chain_id:s,instructions:n(l)});export{d as calInstructionProgramCodec};
1
+ import{array as n,Codec as r,number as s,optional as t,record as i,string as e}from"purify-ts";const c=r.interface({prod:t(e),test:t(e)}),a=r.interface({data:e,signatures:c}),u=r.interface({descriptor:a}),o=r.interface({descriptor:e}),l=r.interface({discriminator_hex:t(e),descriptor:a,enum_variants:t(i(e,i(e,u))),display_fields:t(n(o)),value_flow_ports:t(n(o)),hide_rules:t(n(o)),account_resets:t(n(o))}),d=r.interface({id:e,chain_id:s,instructions:n(l)});export{d as calInstructionProgramCodec};
2
2
  //# sourceMappingURL=InstructionInfoDto.js.map
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "version": 3,
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, number, 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 CalEnumVariantDto = {\n variant_name: string;\n payload_kind?: string;\n descriptor: CalSignedDescriptorDto;\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 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 discriminator_hex: string;\n instruction_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 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// One program object of the `solana_programs` response: the program `id`, its\n// `chain_id`, and the flat `instructions` array (keyed downstream by\n// `discriminator_hex`).\nexport type CalInstructionProgramDto = {\n id: string;\n chain_id: number;\n instructions: CalInstructionDescriptorDto[];\n};\n\n// Outer shape: array of program objects (one per requested `id`).\nexport type CalInstructionInfoResponseDto = CalInstructionProgramDto[];\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 calEnumVariantCodec = Codec.interface({\n descriptor: calSignedDescriptorCodec,\n});\n\nconst calSubstructureCodec = Codec.interface({\n descriptor: string,\n});\n\nconst calInstructionDescriptorCodec = Codec.interface({\n discriminator_hex: string,\n descriptor: calSignedDescriptorCodec,\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 one program object of the `solana_programs` response. Used by the\n * datasource to validate the CAL payload before handing it to the loaders.\n * Only loader-consumed fields are validated; unrelated CAL fields\n * (`idl_descriptor`, `mint_association`, \u2026) are ignored.\n */\nexport const calInstructionProgramCodec = Codec.interface({\n id: string,\n chain_id: number,\n instructions: array(calInstructionDescriptorCodec),\n});\n"],
5
- "mappings": "AAQA,OAAS,SAAAA,EAAO,SAAAC,EAAO,UAAAC,EAAQ,YAAAC,EAAU,UAAAC,EAAQ,UAAAC,MAAc,YA0G/D,MAAMC,EAAqBL,EAAM,UAAU,CACzC,KAAME,EAASE,CAAM,EACrB,KAAMF,EAASE,CAAM,CACvB,CAAC,EAEKE,EAA2BN,EAAM,UAAU,CAC/C,KAAMI,EACN,WAAYC,CACd,CAAC,EAEKE,EAAsBP,EAAM,UAAU,CAC1C,WAAYM,CACd,CAAC,EAEKE,EAAuBR,EAAM,UAAU,CAC3C,WAAYI,CACd,CAAC,EAEKK,EAAgCT,EAAM,UAAU,CACpD,kBAAmBI,EACnB,WAAYE,EACZ,cAAeJ,EAASC,EAAOC,EAAQD,EAAOC,EAAQG,CAAmB,CAAC,CAAC,EAC3E,eAAgBL,EAASH,EAAMS,CAAoB,CAAC,EACpD,iBAAkBN,EAASH,EAAMS,CAAoB,CAAC,EACtD,WAAYN,EAASH,EAAMS,CAAoB,CAAC,EAChD,eAAgBN,EAASH,EAAMS,CAAoB,CAAC,CACtD,CAAC,EAQYE,EAA6BV,EAAM,UAAU,CACxD,GAAII,EACJ,SAAUH,EACV,aAAcF,EAAMU,CAA6B,CACnD,CAAC",
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, number, 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 CalEnumVariantDto = {\n variant_name: string;\n payload_kind?: string;\n descriptor: CalSignedDescriptorDto;\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 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 discriminator_hex?: string;\n instruction_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 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// One program object of the `solana_programs` response: the program `id`, its\n// `chain_id`, and the flat `instructions` array (keyed downstream by\n// `discriminator_hex`).\nexport type CalInstructionProgramDto = {\n id: string;\n chain_id: number;\n instructions: CalInstructionDescriptorDto[];\n};\n\n// Outer shape: array of program objects (one per requested `id`).\nexport type CalInstructionInfoResponseDto = CalInstructionProgramDto[];\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 calEnumVariantCodec = Codec.interface({\n descriptor: calSignedDescriptorCodec,\n});\n\nconst calSubstructureCodec = Codec.interface({\n descriptor: string,\n});\n\nconst calInstructionDescriptorCodec = Codec.interface({\n discriminator_hex: optional(string),\n descriptor: calSignedDescriptorCodec,\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 one program object of the `solana_programs` response. Used by the\n * datasource to validate the CAL payload before handing it to the loaders.\n * Only loader-consumed fields are validated; unrelated CAL fields\n * (`idl_descriptor`, `mint_association`, \u2026) are ignored.\n */\nexport const calInstructionProgramCodec = Codec.interface({\n id: string,\n chain_id: number,\n instructions: array(calInstructionDescriptorCodec),\n});\n"],
5
+ "mappings": "AAQA,OAAS,SAAAA,EAAO,SAAAC,EAAO,UAAAC,EAAQ,YAAAC,EAAU,UAAAC,EAAQ,UAAAC,MAAc,YA0G/D,MAAMC,EAAqBL,EAAM,UAAU,CACzC,KAAME,EAASE,CAAM,EACrB,KAAMF,EAASE,CAAM,CACvB,CAAC,EAEKE,EAA2BN,EAAM,UAAU,CAC/C,KAAMI,EACN,WAAYC,CACd,CAAC,EAEKE,EAAsBP,EAAM,UAAU,CAC1C,WAAYM,CACd,CAAC,EAEKE,EAAuBR,EAAM,UAAU,CAC3C,WAAYI,CACd,CAAC,EAEKK,EAAgCT,EAAM,UAAU,CACpD,kBAAmBE,EAASE,CAAM,EAClC,WAAYE,EACZ,cAAeJ,EAASC,EAAOC,EAAQD,EAAOC,EAAQG,CAAmB,CAAC,CAAC,EAC3E,eAAgBL,EAASH,EAAMS,CAAoB,CAAC,EACpD,iBAAkBN,EAASH,EAAMS,CAAoB,CAAC,EACtD,WAAYN,EAASH,EAAMS,CAAoB,CAAC,EAChD,eAAgBN,EAASH,EAAMS,CAAoB,CAAC,CACtD,CAAC,EAQYE,EAA6BV,EAAM,UAAU,CACxD,GAAII,EACJ,SAAUH,EACV,aAAcF,EAAMU,CAA6B,CACnD,CAAC",
6
6
  "names": ["array", "Codec", "number", "optional", "record", "string", "calSignaturesCodec", "calSignedDescriptorCodec", "calEnumVariantCodec", "calSubstructureCodec", "calInstructionDescriptorCodec", "calInstructionProgramCodec"]
7
7
  }
@@ -1,2 +1,2 @@
1
- var m=Object.defineProperty;var f=Object.getOwnPropertyDescriptor;var g=(s,t,a,e)=>{for(var r=e>1?void 0:e?f(t,a):t,o=s.length-1,i;o>=0;o--)(i=s[o])&&(r=(e?i(t,a,r):i(r))||r);return e&&r&&m(t,a,r),r},c=(s,t)=>(a,e)=>t(a,e,s);import{inject as d,injectable as y}from"inversify";import{configTypes as u}from"../../../../config/di/configTypes";import{pkiTypes as S}from"../../../../modules/multichain/pki/di/pkiTypes";import{KeyId as C}from"../../../../modules/multichain/pki/model/KeyId";import{KeyUsage as x}from"../../../../modules/multichain/pki/model/KeyUsage";import{lifiTypes as L}from"../../../../modules/solana/lifi/di/lifiTypes";import{ClearSignContextType as n}from"../../../../shared/model/ClearSignContext";const h=[n.SOLANA_LIFI];let l=class{constructor(t,a,e,r){this.dataSource=t;this.config=a;this._certificateLoader=e;this.logger=r("LifiContextLoader")}logger;canHandle(t,a){if(!h.every(e=>a.includes(e)))return this.logger.debug("[canHandle] Skipping, expected type does not match",{data:{expectedTypes:a,required:n.SOLANA_LIFI}}),!1;if(typeof t=="object"&&t!==null&&"templateId"in t){const e=t.templateId,r=typeof e=="string"&&e.length>0;return this.logger.debug("[canHandle] Field validation result",{data:{templateId:e,isValid:r}}),r}return this.logger.debug("[canHandle] Field does not contain a valid templateId",{data:{input:t}}),!1}async load(t){this.logger.debug("[load] Loading solana Lifi context",{data:{input:t}});const a=await this._loadInternal(t);if(a.type===n.ERROR)return[{type:n.ERROR,error:a.error}];const e=a;return[{type:n.SOLANA_LIFI,payload:e.payload,certificate:e.certificate}]}async _loadInternal(t){this.logger.debug("[_loadInternal] Loading solana Lifi context",{data:{input:t}});const{templateId:a,deviceModelId:e}=t;if(!a)return{type:n.ERROR,error:new Error("[ContextModule] LifiContextLoader: templateId is missing")};const r=await this.dataSource.getTransactionDescriptorsPayload({templateId:a}),o=await this._certificateLoader.loadCertificate({keyId:C.SwapTemplateKey,keyUsage:x.SwapTemplate,targetDevice:e});return r.caseOf({Left:i=>(this.logger.error("[_loadInternal] Error loading solana Lifi context",{data:{error:i}}),{type:n.ERROR,error:i}),Right:i=>{const p=this.buildPayload(i);return this.logger.debug("[_loadInternal] Successfully loaded solana Lifi context",{data:{descriptors:p.descriptors,instructionsCount:p.instructions.length,certificate:o}}),{type:n.SOLANA_LIFI,payload:p,certificate:o}}})}buildPayload(t){return{descriptors:this.pluckTransactionData(t),instructions:this.extractInstructionsMeta(t)}}pluckTransactionData(t){const a=this.config.cal.mode||"prod",e={},r=t.descriptors??[];this.logger.debug("[pluckTransactionData] Processing descriptors",{data:{descriptorsCount:r.length,signatureKind:a}});for(const o of r){const i=`${o.program_id}:${o.discriminator_hex??""}`;e[i]={data:o.descriptor.data,descriptorType:o.descriptor.descriptorType,descriptorVersion:o.descriptor.descriptorVersion,signature:o.descriptor.signatures[a]??""},this.logger.debug("[pluckTransactionData] Mapped program descriptor",{data:{programId:o.program_id,discriminatorHex:o.discriminator_hex??"",key:i}})}return this.logger.debug("[pluckTransactionData] Completed processing",{data:{outputKeys:Object.keys(e)}}),e}extractInstructionsMeta(t){const a=t.instructions??[];this.logger.debug("[extractInstructionsMeta] Extracting instructions metadata",{data:{instructionsCount:a.length}});const e=a.map(r=>({program_id:r.program_id,...r.discriminator_hex!==void 0&&{discriminator_hex:r.discriminator_hex}}));return this.logger.debug("[extractInstructionsMeta] Completed extracting instructions metadata",{data:{meta:e.map(r=>({programId:r.program_id,discriminatorHex:r.discriminator_hex}))}}),e}};l=g([y(),c(0,d(L.LifiDataSource)),c(1,d(u.Config)),c(2,d(S.PkiCertificateLoader)),c(3,d(u.ContextModuleLoggerFactory))],l);export{l as LifiContextLoader};
1
+ var m=Object.defineProperty;var f=Object.getOwnPropertyDescriptor;var g=(s,t,r,a)=>{for(var e=a>1?void 0:a?f(t,r):t,o=s.length-1,i;o>=0;o--)(i=s[o])&&(e=(a?i(t,r,e):i(e))||e);return a&&e&&m(t,r,e),e},d=(s,t)=>(r,a)=>t(r,a,s);import{inject as p,injectable as y}from"inversify";import{configTypes as u}from"../../../../config/di/configTypes";import{pkiTypes as S}from"../../../../modules/multichain/pki/di/pkiTypes";import{KeyId as C}from"../../../../modules/multichain/pki/model/KeyId";import{KeyUsage as h}from"../../../../modules/multichain/pki/model/KeyUsage";import{lifiTypes as x}from"../../../../modules/solana/lifi/di/lifiTypes";import{ClearSignContextType as n}from"../../../../shared/model/ClearSignContext";const L=[n.SOLANA_LIFI];let l=class{constructor(t,r,a,e){this.dataSource=t;this.config=r;this._certificateLoader=a;this.logger=e("LifiContextLoader")}logger;canHandle(t,r){if(!L.every(a=>r.includes(a)))return this.logger.debug("[canHandle] Skipping, expected type does not match",{data:{expectedTypes:r,required:n.SOLANA_LIFI}}),!1;if(typeof t=="object"&&t!==null&&"templateId"in t){const a=t.templateId,e=typeof a=="string"&&a.length>0;return this.logger.debug("[canHandle] Field validation result",{data:{templateId:a,isValid:e}}),e}return this.logger.debug("[canHandle] Field does not contain a valid templateId",{data:{input:t}}),!1}async load(t){this.logger.debug("[load] Loading solana Lifi context",{data:{input:t}});const r=await this._loadInternal(t);if(r.type===n.ERROR)return[{type:n.ERROR,error:r.error}];const a=r;return[{type:n.SOLANA_LIFI,payload:a.payload,certificate:a.certificate}]}async _loadInternal(t){this.logger.debug("[_loadInternal] Loading solana Lifi context",{data:{input:t}});const{templateId:r,deviceModelId:a}=t;if(!r)return{type:n.ERROR,error:new Error("[ContextModule] LifiContextLoader: templateId is missing")};const e=await this.dataSource.getTransactionDescriptorsPayload({templateId:r}),o=await this._certificateLoader.loadCertificate({keyId:C.SwapTemplateKey,keyUsage:h.SwapTemplate,targetDevice:a});return e.caseOf({Left:i=>(this.logger.error("[_loadInternal] Error loading solana Lifi context",{data:{error:i}}),{type:n.ERROR,error:i}),Right:i=>{const c=this.buildPayload(i);return this.logger.debug("[_loadInternal] Successfully loaded solana Lifi context",{data:{descriptors:c.descriptors,instructionsCount:c.instructions.length,certificate:o}}),{type:n.SOLANA_LIFI,payload:c,certificate:o}}})}buildPayload(t){return{descriptors:this.pluckTransactionData(t),instructions:this.extractInstructionsMeta(t)}}pluckTransactionData(t){const r=this.config.cal.mode||"prod",a={},e=t.descriptors??[];this.logger.debug("[pluckTransactionData] Processing descriptors",{data:{descriptorsCount:e.length,signatureKind:r}});for(const o of e){const i=`${o.program_id}:${o.discriminator_hex??""}`,c={data:o.descriptor.data,descriptorType:o.descriptor.descriptorType,descriptorVersion:o.descriptor.descriptorVersion,signature:o.descriptor.signatures[r]??"",...o.has_basis_point!==void 0&&{has_basis_point:o.has_basis_point}};(a[i]??=[]).push(c),this.logger.debug("[pluckTransactionData] Mapped program descriptor",{data:{programId:o.program_id,discriminatorHex:o.discriminator_hex??"",key:i}})}return this.logger.debug("[pluckTransactionData] Completed processing",{data:{outputKeys:Object.keys(a)}}),a}extractInstructionsMeta(t){const r=t.instructions??[];this.logger.debug("[extractInstructionsMeta] Extracting instructions metadata",{data:{instructionsCount:r.length}});const a=r.map(e=>({program_id:e.program_id,...e.discriminator_hex!==void 0&&{discriminator_hex:e.discriminator_hex},...e.amount!==void 0&&{has_basis_point:e.amount.capped_bps!==void 0}}));return this.logger.debug("[extractInstructionsMeta] Completed extracting instructions metadata",{data:{meta:a.map(e=>({programId:e.program_id,discriminatorHex:e.discriminator_hex}))}}),a}};l=g([y(),d(0,p(x.LifiDataSource)),d(1,p(u.Config)),d(2,p(S.PkiCertificateLoader)),d(3,p(u.ContextModuleLoggerFactory))],l);export{l as LifiContextLoader};
2
2
  //# sourceMappingURL=LifiContextLoader.js.map
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "version": 3,
3
3
  "sources": ["../../../../../../../src/modules/solana/lifi/domain/LifiContextLoader.ts"],
4
- "sourcesContent": ["import { LoggerPublisherService } from \"@ledgerhq/device-management-kit\";\nimport { inject, injectable } from \"inversify\";\n\nimport { configTypes } from \"@/config/di/configTypes\";\nimport { type ContextModuleServiceConfig } from \"@/config/model/ContextModuleConfig\";\nimport { pkiTypes } from \"@/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 PkiCertificate } from \"@/modules/multichain/pki/model/PkiCertificate\";\nimport {\n GetTransactionDescriptorsResponse,\n type LifiDataSource,\n} from \"@/modules/solana/lifi/data/LifiDataSource\";\nimport { lifiTypes } from \"@/modules/solana/lifi/di/lifiTypes\";\nimport {\n type SolanaContextError,\n type SolanaLifiContextSuccess,\n type SolanaTransactionDescriptorList,\n} from \"@/modules/solana/model/SolanaContextTypes\";\nimport {\n type SolanaLifiInstructionMeta,\n type SolanaLifiPayload,\n} from \"@/modules/solana/model/SolanaPayloads\";\nimport { type SolanaTransactionContext } from \"@/modules/solana/model/SolanaTransactionContext\";\nimport { type ContextLoader } from \"@/shared/domain/ContextLoader\";\nimport {\n type ClearSignContext,\n ClearSignContextType,\n} from \"@/shared/model/ClearSignContext\";\n\nconst SUPPORTED_TYPES: ClearSignContextType[] = [\n ClearSignContextType.SOLANA_LIFI,\n];\n\n@injectable()\nexport class LifiContextLoader\n implements ContextLoader<SolanaTransactionContext>\n{\n private logger: LoggerPublisherService;\n\n constructor(\n @inject(lifiTypes.LifiDataSource)\n private readonly dataSource: LifiDataSource,\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(\"LifiContextLoader\");\n }\n\n public canHandle(\n input: unknown,\n expectedTypes: ClearSignContextType[],\n ): input is SolanaTransactionContext {\n if (!SUPPORTED_TYPES.every((t) => expectedTypes.includes(t))) {\n this.logger.debug(\"[canHandle] Skipping, expected type does not match\", {\n data: { expectedTypes, required: ClearSignContextType.SOLANA_LIFI },\n });\n return false;\n }\n\n if (typeof input === \"object\" && input !== null && \"templateId\" in input) {\n const templateId = (input as { templateId: unknown }).templateId;\n const isValid = typeof templateId === \"string\" && templateId.length > 0;\n this.logger.debug(\"[canHandle] Field validation result\", {\n data: { templateId, isValid },\n });\n return isValid;\n }\n\n this.logger.debug(\"[canHandle] Field does not contain a valid templateId\", {\n data: { input },\n });\n return false;\n }\n\n public async load(\n solanaLifiContextInput: SolanaTransactionContext,\n ): Promise<ClearSignContext[]> {\n this.logger.debug(\"[load] Loading solana Lifi context\", {\n data: { input: solanaLifiContextInput },\n });\n const result = await this._loadInternal(solanaLifiContextInput);\n if (result.type === ClearSignContextType.ERROR) {\n return [{ type: ClearSignContextType.ERROR, error: result.error }];\n }\n const r = result as SolanaLifiContextSuccess;\n return [\n {\n type: ClearSignContextType.SOLANA_LIFI,\n payload: r.payload,\n certificate: r.certificate,\n },\n ];\n }\n\n private async _loadInternal(\n solanaLifiContextInput: SolanaTransactionContext,\n ): Promise<SolanaLifiContextSuccess | SolanaContextError> {\n this.logger.debug(\"[_loadInternal] Loading solana Lifi context\", {\n data: { input: solanaLifiContextInput },\n });\n const { templateId, deviceModelId } = solanaLifiContextInput;\n\n if (!templateId) {\n return {\n type: ClearSignContextType.ERROR,\n error: new Error(\n \"[ContextModule] LifiContextLoader: templateId is missing\",\n ),\n };\n }\n\n const payload = await this.dataSource.getTransactionDescriptorsPayload({\n templateId,\n });\n\n const certificate: PkiCertificate | undefined =\n await this._certificateLoader.loadCertificate({\n keyId: KeyId.SwapTemplateKey,\n keyUsage: KeyUsage.SwapTemplate,\n targetDevice: deviceModelId,\n });\n\n return payload.caseOf({\n Left: (error): SolanaLifiContextSuccess | SolanaContextError => {\n this.logger.error(\"[_loadInternal] Error loading solana Lifi context\", {\n data: { error },\n });\n\n return {\n type: ClearSignContextType.ERROR,\n error,\n };\n },\n Right: (value): SolanaLifiContextSuccess | SolanaContextError => {\n const lifiPayload = this.buildPayload(value);\n this.logger.debug(\n \"[_loadInternal] Successfully loaded solana Lifi context\",\n {\n data: {\n descriptors: lifiPayload.descriptors,\n instructionsCount: lifiPayload.instructions.length,\n certificate,\n },\n },\n );\n\n return {\n type: ClearSignContextType.SOLANA_LIFI,\n payload: lifiPayload,\n certificate,\n };\n },\n });\n }\n\n private buildPayload(\n response: GetTransactionDescriptorsResponse,\n ): SolanaLifiPayload {\n return {\n descriptors: this.pluckTransactionData(response),\n instructions: this.extractInstructionsMeta(response),\n };\n }\n\n private pluckTransactionData(\n tokenData: GetTransactionDescriptorsResponse,\n ): SolanaTransactionDescriptorList {\n const signatureKind = this.config.cal.mode || \"prod\";\n const output: SolanaTransactionDescriptorList = {};\n const descriptors = tokenData.descriptors ?? [];\n\n this.logger.debug(\"[pluckTransactionData] Processing descriptors\", {\n data: { descriptorsCount: descriptors.length, signatureKind },\n });\n\n for (const item of descriptors) {\n const key = `${item.program_id}:${item.discriminator_hex ?? \"\"}`;\n output[key] = {\n data: item.descriptor.data,\n descriptorType: item.descriptor.descriptorType,\n descriptorVersion: item.descriptor.descriptorVersion,\n signature: item.descriptor.signatures[signatureKind] ?? \"\",\n };\n this.logger.debug(\"[pluckTransactionData] Mapped program descriptor\", {\n data: {\n programId: item.program_id,\n discriminatorHex: item.discriminator_hex ?? \"\",\n key,\n },\n });\n }\n\n this.logger.debug(\"[pluckTransactionData] Completed processing\", {\n data: { outputKeys: Object.keys(output) },\n });\n\n return output;\n }\n\n private extractInstructionsMeta(\n response: GetTransactionDescriptorsResponse,\n ): SolanaLifiInstructionMeta[] {\n const instructions = response.instructions ?? [];\n\n this.logger.debug(\n \"[extractInstructionsMeta] Extracting instructions metadata\",\n {\n data: { instructionsCount: instructions.length },\n },\n );\n\n const meta = instructions.map((ix) => ({\n program_id: ix.program_id,\n ...(ix.discriminator_hex !== undefined && {\n discriminator_hex: ix.discriminator_hex,\n }),\n }));\n\n this.logger.debug(\n \"[extractInstructionsMeta] Completed extracting instructions metadata\",\n {\n data: {\n meta: meta.map((m) => ({\n programId: m.program_id,\n discriminatorHex: m.discriminator_hex,\n })),\n },\n },\n );\n\n return meta;\n }\n}\n"],
5
- "mappings": "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",
6
- "names": ["inject", "injectable", "configTypes", "pkiTypes", "KeyId", "KeyUsage", "lifiTypes", "ClearSignContextType", "SUPPORTED_TYPES", "ClearSignContextType", "LifiContextLoader", "dataSource", "config", "_certificateLoader", "loggerFactory", "input", "expectedTypes", "t", "templateId", "isValid", "solanaLifiContextInput", "result", "r", "deviceModelId", "payload", "certificate", "KeyId", "KeyUsage", "error", "value", "lifiPayload", "response", "tokenData", "signatureKind", "output", "descriptors", "item", "key", "instructions", "meta", "ix", "m", "__decorateClass", "injectable", "__decorateParam", "inject", "lifiTypes", "configTypes", "pkiTypes"]
4
+ "sourcesContent": ["import { LoggerPublisherService } from \"@ledgerhq/device-management-kit\";\nimport { inject, injectable } from \"inversify\";\n\nimport { configTypes } from \"@/config/di/configTypes\";\nimport { type ContextModuleServiceConfig } from \"@/config/model/ContextModuleConfig\";\nimport { pkiTypes } from \"@/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 PkiCertificate } from \"@/modules/multichain/pki/model/PkiCertificate\";\nimport {\n GetTransactionDescriptorsResponse,\n type LifiDataSource,\n} from \"@/modules/solana/lifi/data/LifiDataSource\";\nimport { lifiTypes } from \"@/modules/solana/lifi/di/lifiTypes\";\nimport {\n type SolanaContextError,\n type SolanaLifiContextSuccess,\n type SolanaTransactionDescriptorList,\n} from \"@/modules/solana/model/SolanaContextTypes\";\nimport {\n type SolanaLifiInstructionMeta,\n type SolanaLifiPayload,\n} from \"@/modules/solana/model/SolanaPayloads\";\nimport { type SolanaTransactionContext } from \"@/modules/solana/model/SolanaTransactionContext\";\nimport { type ContextLoader } from \"@/shared/domain/ContextLoader\";\nimport {\n type ClearSignContext,\n ClearSignContextType,\n} from \"@/shared/model/ClearSignContext\";\n\nconst SUPPORTED_TYPES: ClearSignContextType[] = [\n ClearSignContextType.SOLANA_LIFI,\n];\n\n@injectable()\nexport class LifiContextLoader\n implements ContextLoader<SolanaTransactionContext>\n{\n private logger: LoggerPublisherService;\n\n constructor(\n @inject(lifiTypes.LifiDataSource)\n private readonly dataSource: LifiDataSource,\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(\"LifiContextLoader\");\n }\n\n public canHandle(\n input: unknown,\n expectedTypes: ClearSignContextType[],\n ): input is SolanaTransactionContext {\n if (!SUPPORTED_TYPES.every((t) => expectedTypes.includes(t))) {\n this.logger.debug(\"[canHandle] Skipping, expected type does not match\", {\n data: { expectedTypes, required: ClearSignContextType.SOLANA_LIFI },\n });\n return false;\n }\n\n if (typeof input === \"object\" && input !== null && \"templateId\" in input) {\n const templateId = (input as { templateId: unknown }).templateId;\n const isValid = typeof templateId === \"string\" && templateId.length > 0;\n this.logger.debug(\"[canHandle] Field validation result\", {\n data: { templateId, isValid },\n });\n return isValid;\n }\n\n this.logger.debug(\"[canHandle] Field does not contain a valid templateId\", {\n data: { input },\n });\n return false;\n }\n\n public async load(\n solanaLifiContextInput: SolanaTransactionContext,\n ): Promise<ClearSignContext[]> {\n this.logger.debug(\"[load] Loading solana Lifi context\", {\n data: { input: solanaLifiContextInput },\n });\n const result = await this._loadInternal(solanaLifiContextInput);\n if (result.type === ClearSignContextType.ERROR) {\n return [{ type: ClearSignContextType.ERROR, error: result.error }];\n }\n const r = result as SolanaLifiContextSuccess;\n return [\n {\n type: ClearSignContextType.SOLANA_LIFI,\n payload: r.payload,\n certificate: r.certificate,\n },\n ];\n }\n\n private async _loadInternal(\n solanaLifiContextInput: SolanaTransactionContext,\n ): Promise<SolanaLifiContextSuccess | SolanaContextError> {\n this.logger.debug(\"[_loadInternal] Loading solana Lifi context\", {\n data: { input: solanaLifiContextInput },\n });\n const { templateId, deviceModelId } = solanaLifiContextInput;\n\n if (!templateId) {\n return {\n type: ClearSignContextType.ERROR,\n error: new Error(\n \"[ContextModule] LifiContextLoader: templateId is missing\",\n ),\n };\n }\n\n const payload = await this.dataSource.getTransactionDescriptorsPayload({\n templateId,\n });\n\n const certificate: PkiCertificate | undefined =\n await this._certificateLoader.loadCertificate({\n keyId: KeyId.SwapTemplateKey,\n keyUsage: KeyUsage.SwapTemplate,\n targetDevice: deviceModelId,\n });\n\n return payload.caseOf({\n Left: (error): SolanaLifiContextSuccess | SolanaContextError => {\n this.logger.error(\"[_loadInternal] Error loading solana Lifi context\", {\n data: { error },\n });\n\n return {\n type: ClearSignContextType.ERROR,\n error,\n };\n },\n Right: (value): SolanaLifiContextSuccess | SolanaContextError => {\n const lifiPayload = this.buildPayload(value);\n this.logger.debug(\n \"[_loadInternal] Successfully loaded solana Lifi context\",\n {\n data: {\n descriptors: lifiPayload.descriptors,\n instructionsCount: lifiPayload.instructions.length,\n certificate,\n },\n },\n );\n\n return {\n type: ClearSignContextType.SOLANA_LIFI,\n payload: lifiPayload,\n certificate,\n };\n },\n });\n }\n\n private buildPayload(\n response: GetTransactionDescriptorsResponse,\n ): SolanaLifiPayload {\n return {\n descriptors: this.pluckTransactionData(response),\n instructions: this.extractInstructionsMeta(response),\n };\n }\n\n private pluckTransactionData(\n tokenData: GetTransactionDescriptorsResponse,\n ): SolanaTransactionDescriptorList {\n const signatureKind = this.config.cal.mode || \"prod\";\n const output: SolanaTransactionDescriptorList = {};\n const descriptors = tokenData.descriptors ?? [];\n\n this.logger.debug(\"[pluckTransactionData] Processing descriptors\", {\n data: { descriptorsCount: descriptors.length, signatureKind },\n });\n\n for (const item of descriptors) {\n const key = `${item.program_id}:${item.discriminator_hex ?? \"\"}`;\n const descriptor = {\n data: item.descriptor.data,\n descriptorType: item.descriptor.descriptorType,\n descriptorVersion: item.descriptor.descriptorVersion,\n signature: item.descriptor.signatures[signatureKind] ?? \"\",\n ...(item.has_basis_point !== undefined && {\n has_basis_point: item.has_basis_point,\n }),\n };\n (output[key] ??= []).push(descriptor);\n this.logger.debug(\"[pluckTransactionData] Mapped program descriptor\", {\n data: {\n programId: item.program_id,\n discriminatorHex: item.discriminator_hex ?? \"\",\n key,\n },\n });\n }\n\n this.logger.debug(\"[pluckTransactionData] Completed processing\", {\n data: { outputKeys: Object.keys(output) },\n });\n\n return output;\n }\n\n private extractInstructionsMeta(\n response: GetTransactionDescriptorsResponse,\n ): SolanaLifiInstructionMeta[] {\n const instructions = response.instructions ?? [];\n\n this.logger.debug(\n \"[extractInstructionsMeta] Extracting instructions metadata\",\n {\n data: { instructionsCount: instructions.length },\n },\n );\n\n const meta = instructions.map((ix) => ({\n program_id: ix.program_id,\n ...(ix.discriminator_hex !== undefined && {\n discriminator_hex: ix.discriminator_hex,\n }),\n ...(ix.amount !== undefined && {\n has_basis_point: ix.amount.capped_bps !== undefined,\n }),\n }));\n\n this.logger.debug(\n \"[extractInstructionsMeta] Completed extracting instructions metadata\",\n {\n data: {\n meta: meta.map((m) => ({\n programId: m.program_id,\n discriminatorHex: m.discriminator_hex,\n })),\n },\n },\n );\n\n return meta;\n }\n}\n"],
5
+ "mappings": "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",
6
+ "names": ["inject", "injectable", "configTypes", "pkiTypes", "KeyId", "KeyUsage", "lifiTypes", "ClearSignContextType", "SUPPORTED_TYPES", "ClearSignContextType", "LifiContextLoader", "dataSource", "config", "_certificateLoader", "loggerFactory", "input", "expectedTypes", "t", "templateId", "isValid", "solanaLifiContextInput", "result", "r", "deviceModelId", "payload", "certificate", "KeyId", "KeyUsage", "error", "value", "lifiPayload", "response", "tokenData", "signatureKind", "output", "descriptors", "item", "key", "descriptor", "instructions", "meta", "ix", "m", "__decorateClass", "injectable", "__decorateParam", "inject", "lifiTypes", "configTypes", "pkiTypes"]
7
7
  }
@@ -1,2 +1,2 @@
1
- import{Left as L,Right as _}from"purify-ts";import{beforeEach as x,describe as m,expect as e,it as n,vi as c}from"vitest";import{ClearSignContextType as d}from"../../../../shared/model/ClearSignContext";import{LifiContextLoader as T}from"./LifiContextLoader";const h=()=>({debug:c.fn(),info:c.fn(),warn:c.fn(),error:c.fn(),subscribers:[]}),y={keyUsageNumber:13,payload:new Uint8Array([1,2])},N={cal:{url:"https://global.api.prd.ledger.com/cal/v1",mode:"test",branch:"main"}};m("LifiContextLoader",()=>{let p,u;const i=(r,a="deadbeef")=>({data:r,descriptorType:"swap_template",descriptorVersion:"v1",signatures:{test:a,prod:`prod_${a}`}}),g=(r,a="deadbeef")=>({data:r,descriptorType:"swap_template",descriptorVersion:"v1",signature:a}),k=[{program_id:"SomeProgram",discriminator_hex:"1",descriptor:i("abc123")},{program_id:"AnotherProgram",descriptor:i("def456")}],b={"SomeProgram:1":g("abc123"),"AnotherProgram:":g("def456")},l={id:"tpl-1",chain_id:101,instructions:[{program_id:"SomeProgram",discriminator:1,discriminator_hex:"1"},{program_id:"AnotherProgram"}],descriptors:k};x(()=>{c.restoreAllMocks(),p={getTransactionDescriptorsPayload:c.fn()},u={loadCertificate:c.fn().mockResolvedValue(y)}});const s=()=>new T(p,N,u,h);m("canHandle",()=>{n("returns true when templateId is provided and SOLANA_LIFI is in expectedTypes",()=>{const r=s();e(r.canHandle({templateId:"tpl-123",deviceModelId:"nanoS"},[d.SOLANA_LIFI])).toBe(!0)}),n("returns false when SOLANA_LIFI is not in expectedTypes",()=>{const r=s();e(r.canHandle({templateId:"tpl-123"},[d.SOLANA_TOKEN])).toBe(!1)}),n("returns false when templateId is missing or falsy",()=>{const r=s();e(r.canHandle({templateId:""},[d.SOLANA_LIFI])).toBe(!1),e(r.canHandle({templateId:void 0},[d.SOLANA_LIFI])).toBe(!1),e(r.canHandle({},[d.SOLANA_LIFI])).toBe(!1)})}),m("load",()=>{n("returns an array with an error when datasource returns Left(error)",async()=>{const r=s(),a=new Error("boom");c.spyOn(p,"getTransactionDescriptorsPayload").mockResolvedValue(L(a));const o={templateId:"tpl-err",deviceModelId:"nanoS"},t=await r.load(o);e(p.getTransactionDescriptorsPayload).toHaveBeenCalledWith({templateId:"tpl-err"}),e(t).toEqual([{type:d.ERROR,error:a}])}),n("returns SOLANA_LIFI array with plucked descriptors and certificate when datasource returns Right(value)",async()=>{const r=s();c.spyOn(p,"getTransactionDescriptorsPayload").mockResolvedValue(_(l));const a={templateId:"tpl-ok",deviceModelId:"nanoS"},o=await r.load(a);e(p.getTransactionDescriptorsPayload).toHaveBeenCalledWith({templateId:"tpl-ok"}),e(u.loadCertificate).toHaveBeenCalledWith({keyId:"swap_template_key",keyUsage:"swap_template",targetDevice:"nanoS"}),e(o).toEqual([{type:d.SOLANA_LIFI,payload:{descriptors:b,instructions:[{program_id:"SomeProgram",discriminator_hex:"1"},{program_id:"AnotherProgram"}]},certificate:y}])})}),m("pluckTransactionData (private)",()=>{n("returns a map keyed by `${program_id}:${discriminator_hex ?? '0'}`",()=>{const r=s(),o=r.pluckTransactionData.bind(r)(l);e(o).toEqual(b)})}),m("extractInstructionsMeta (private)",()=>{n("returns instruction metadata from the API response",()=>{const r=s(),o=r.extractInstructionsMeta.bind(r)(l);e(o).toEqual([{program_id:"SomeProgram",discriminator_hex:"1"},{program_id:"AnotherProgram"}])}),n("returns empty array when instructions are missing",()=>{const r=s(),o=r.extractInstructionsMeta.bind(r)({...l,instructions:void 0});e(o).toEqual([])})}),m("pluckTransactionData mode resolution (private)",()=>{n("resolves signature using config.cal.mode",()=>{const r=s(),o=r.pluckTransactionData.bind(r)(l);e(o["SomeProgram:1"]?.signature).toBe("deadbeef")})}),m("real CAL payload (LiFi template 4c694669)",()=>{const r={id:"4c694669",chain_id:101,instructions:[{program_id:"ATokenGPvbdGVxr1b2hvZbsiqW5xWH25efTNsLJA8knL",discriminator:1,discriminator_hex:"1"},{program_id:"11111111111111111111111111111111",discriminator:2,discriminator_hex:"2"},{program_id:"JUP6LkbZbjS1jKKwapdHNy74zcZ3tLUZoi5QNyVTaV4",discriminator:0x2aade37a97cb1800,discriminator_hex:"2aade37a97cb17e0"},{program_id:"JUP6LkbZbjS1jKKwapdHNy74zcZ3tLUZoi5QNyVTaV4",discriminator:9339575302786589e3,discriminator_hex:"819cd641339b2148"},{program_id:"MemoSq4gqABAXKb96qnH8TysNcWxMyWCqXgDLGmfcHr"},{program_id:"ATokenGPvbdGVxr1b2hvZbsiqW5xWH25efTNsLJA8knL",discriminator:1,discriminator_hex:"1"},{program_id:"3i5JeuZuUxeKtVysUnwQNGerJP2bSMX9fTFfS4Nxe3Br"},{program_id:"ComputeBudget111111111111111111111111111111",discriminator:2,discriminator_hex:"2"},{program_id:"ComputeBudget111111111111111111111111111111",discriminator:3,discriminator_hex:"3"},{program_id:"TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA",discriminator:3,discriminator_hex:"3"},{program_id:"TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA",discriminator:17,discriminator_hex:"11"},{program_id:"BrdgN2RPzEMWF96ZbnnJaUtQDQx7VRXYaHHbYCBvceWB"}],descriptors:[{program_id:"ATokenGPvbdGVxr1b2hvZbsiqW5xWH25efTNsLJA8knL",discriminator_hex:"1",descriptor:i("atoken_1","sig_atoken")},{program_id:"11111111111111111111111111111111",discriminator_hex:"2",descriptor:i("system_2","sig_system")},{program_id:"JUP6LkbZbjS1jKKwapdHNy74zcZ3tLUZoi5QNyVTaV4",discriminator_hex:"2aade37a97cb17e0",descriptor:i("jup_route","sig_jup_route")},{program_id:"JUP6LkbZbjS1jKKwapdHNy74zcZ3tLUZoi5QNyVTaV4",discriminator_hex:"819cd641339b2148",descriptor:i("jup_shared","sig_jup_shared")},{program_id:"MemoSq4gqABAXKb96qnH8TysNcWxMyWCqXgDLGmfcHr",descriptor:i("memo","sig_memo")},{program_id:"ATokenGPvbdGVxr1b2hvZbsiqW5xWH25efTNsLJA8knL",discriminator_hex:"1",descriptor:i("atoken_1","sig_atoken")},{program_id:"3i5JeuZuUxeKtVysUnwQNGerJP2bSMX9fTFfS4Nxe3Br",descriptor:i("3i5jeu","sig_3i5jeu")},{program_id:"ComputeBudget111111111111111111111111111111",discriminator_hex:"2",descriptor:i("cb_2","sig_cb2")},{program_id:"ComputeBudget111111111111111111111111111111",discriminator_hex:"3",descriptor:i("cb_3","sig_cb3")},{program_id:"TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA",discriminator_hex:"3",descriptor:i("tokenkeg_3","sig_tk3")},{program_id:"TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA",discriminator_hex:"11",descriptor:i("tokenkeg_11","sig_tk11")},{program_id:"BrdgN2RPzEMWF96ZbnnJaUtQDQx7VRXYaHHbYCBvceWB",descriptor:i("brdg","sig_brdg")}]};n("produces 11 unique descriptor keys (ATokenGP:1 appears twice but deduplicates)",()=>{const a=s(),t=a.pluckTransactionData.bind(a)(r),f=Object.keys(t);e(f).toHaveLength(11)}),n("creates distinct keys for same program_id with different discriminators",()=>{const a=s(),t=a.pluckTransactionData.bind(a)(r);e(t["JUP6LkbZbjS1jKKwapdHNy74zcZ3tLUZoi5QNyVTaV4:2aade37a97cb17e0"]?.data).toBe("jup_route"),e(t["JUP6LkbZbjS1jKKwapdHNy74zcZ3tLUZoi5QNyVTaV4:819cd641339b2148"]?.data).toBe("jup_shared"),e(t["ComputeBudget111111111111111111111111111111:2"]?.data).toBe("cb_2"),e(t["ComputeBudget111111111111111111111111111111:3"]?.data).toBe("cb_3"),e(t["TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA:3"]?.data).toBe("tokenkeg_3"),e(t["TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA:11"]?.data).toBe("tokenkeg_11")}),n("uses :0 suffix for programs without a discriminator",()=>{const a=s(),t=a.pluckTransactionData.bind(a)(r);e(t["MemoSq4gqABAXKb96qnH8TysNcWxMyWCqXgDLGmfcHr:"]?.data).toBe("memo"),e(t["3i5JeuZuUxeKtVysUnwQNGerJP2bSMX9fTFfS4Nxe3Br:"]?.data).toBe("3i5jeu"),e(t["BrdgN2RPzEMWF96ZbnnJaUtQDQx7VRXYaHHbYCBvceWB:"]?.data).toBe("brdg")}),n("extracts 12 instruction metadata entries preserving order and discriminators",()=>{const a=s(),t=a.extractInstructionsMeta.bind(a)(r);e(t).toHaveLength(12),e(t[0]).toEqual({program_id:"ATokenGPvbdGVxr1b2hvZbsiqW5xWH25efTNsLJA8knL",discriminator_hex:"1"}),e(t[2]).toEqual({program_id:"JUP6LkbZbjS1jKKwapdHNy74zcZ3tLUZoi5QNyVTaV4",discriminator_hex:"2aade37a97cb17e0"}),e(t[3]).toEqual({program_id:"JUP6LkbZbjS1jKKwapdHNy74zcZ3tLUZoi5QNyVTaV4",discriminator_hex:"819cd641339b2148"}),e(t[4]).toEqual({program_id:"MemoSq4gqABAXKb96qnH8TysNcWxMyWCqXgDLGmfcHr"}),e(t[11]).toEqual({program_id:"BrdgN2RPzEMWF96ZbnnJaUtQDQx7VRXYaHHbYCBvceWB"})}),n("load returns full payload with descriptors and instructions from real API response",async()=>{const a=s();c.spyOn(p,"getTransactionDescriptorsPayload").mockResolvedValue(_(r));const o={templateId:"4c694669",deviceModelId:"nanoS"},t=await a.load(o);e(t).toHaveLength(1),e(t[0]).toMatchObject({type:d.SOLANA_LIFI,payload:{descriptors:e.objectContaining({"JUP6LkbZbjS1jKKwapdHNy74zcZ3tLUZoi5QNyVTaV4:2aade37a97cb17e0":e.objectContaining({data:"jup_route"}),"JUP6LkbZbjS1jKKwapdHNy74zcZ3tLUZoi5QNyVTaV4:819cd641339b2148":e.objectContaining({data:"jup_shared"})}),instructions:e.arrayContaining([e.objectContaining({program_id:"JUP6LkbZbjS1jKKwapdHNy74zcZ3tLUZoi5QNyVTaV4",discriminator_hex:"2aade37a97cb17e0"}),e.objectContaining({program_id:"JUP6LkbZbjS1jKKwapdHNy74zcZ3tLUZoi5QNyVTaV4",discriminator_hex:"819cd641339b2148"})])}}),e(Object.keys(t[0].payload.descriptors)).toHaveLength(11),e(t[0].payload.instructions).toHaveLength(12)})})});
1
+ import{Left as L,Right as b}from"purify-ts";import{beforeEach as h,describe as d,expect as r,it as n,vi as c}from"vitest";import{ClearSignContextType as p}from"../../../../shared/model/ClearSignContext";import{LifiContextLoader as x}from"./LifiContextLoader";const T=()=>({debug:c.fn(),info:c.fn(),warn:c.fn(),error:c.fn(),subscribers:[]}),y={keyUsageNumber:13,payload:new Uint8Array([1,2])},N={cal:{url:"https://global.api.prd.ledger.com/cal/v1",mode:"test",branch:"main"}};d("LifiContextLoader",()=>{let m,u;const i=(e,t="deadbeef")=>({data:e,descriptorType:"swap_template",descriptorVersion:"v1",signatures:{test:t,prod:`prod_${t}`}}),g=(e,t="deadbeef")=>({data:e,descriptorType:"swap_template",descriptorVersion:"v1",signature:t}),k=[{program_id:"SomeProgram",discriminator_hex:"1",descriptor:i("abc123")},{program_id:"AnotherProgram",descriptor:i("def456")}],_={"SomeProgram:1":[g("abc123")],"AnotherProgram:":[g("def456")]},l={id:"tpl-1",chain_id:101,instructions:[{program_id:"SomeProgram",discriminator:1,discriminator_hex:"1"},{program_id:"AnotherProgram"}],descriptors:k};h(()=>{c.restoreAllMocks(),m={getTransactionDescriptorsPayload:c.fn()},u={loadCertificate:c.fn().mockResolvedValue(y)}});const s=()=>new x(m,N,u,T);d("canHandle",()=>{n("returns true when templateId is provided and SOLANA_LIFI is in expectedTypes",()=>{const e=s();r(e.canHandle({templateId:"tpl-123",deviceModelId:"nanoS"},[p.SOLANA_LIFI])).toBe(!0)}),n("returns false when SOLANA_LIFI is not in expectedTypes",()=>{const e=s();r(e.canHandle({templateId:"tpl-123"},[p.SOLANA_TOKEN])).toBe(!1)}),n("returns false when templateId is missing or falsy",()=>{const e=s();r(e.canHandle({templateId:""},[p.SOLANA_LIFI])).toBe(!1),r(e.canHandle({templateId:void 0},[p.SOLANA_LIFI])).toBe(!1),r(e.canHandle({},[p.SOLANA_LIFI])).toBe(!1)})}),d("load",()=>{n("returns an array with an error when datasource returns Left(error)",async()=>{const e=s(),t=new Error("boom");c.spyOn(m,"getTransactionDescriptorsPayload").mockResolvedValue(L(t));const o={templateId:"tpl-err",deviceModelId:"nanoS"},a=await e.load(o);r(m.getTransactionDescriptorsPayload).toHaveBeenCalledWith({templateId:"tpl-err"}),r(a).toEqual([{type:p.ERROR,error:t}])}),n("returns SOLANA_LIFI array with plucked descriptors and certificate when datasource returns Right(value)",async()=>{const e=s();c.spyOn(m,"getTransactionDescriptorsPayload").mockResolvedValue(b(l));const t={templateId:"tpl-ok",deviceModelId:"nanoS"},o=await e.load(t);r(m.getTransactionDescriptorsPayload).toHaveBeenCalledWith({templateId:"tpl-ok"}),r(u.loadCertificate).toHaveBeenCalledWith({keyId:"swap_template_key",keyUsage:"swap_template",targetDevice:"nanoS"}),r(o).toEqual([{type:p.SOLANA_LIFI,payload:{descriptors:_,instructions:[{program_id:"SomeProgram",discriminator_hex:"1"},{program_id:"AnotherProgram"}]},certificate:y}])})}),d("pluckTransactionData (private)",()=>{n("returns a map keyed by `${program_id}:${discriminator_hex ?? '0'}`",()=>{const e=s(),o=e.pluckTransactionData.bind(e)(l);r(o).toEqual(_)})}),d("extractInstructionsMeta (private)",()=>{n("returns instruction metadata from the API response",()=>{const e=s(),o=e.extractInstructionsMeta.bind(e)(l);r(o).toEqual([{program_id:"SomeProgram",discriminator_hex:"1"},{program_id:"AnotherProgram"}])}),n("returns empty array when instructions are missing",()=>{const e=s(),o=e.extractInstructionsMeta.bind(e)({...l,instructions:void 0});r(o).toEqual([])})}),d("pluckTransactionData mode resolution (private)",()=>{n("resolves signature using config.cal.mode",()=>{const e=s(),o=e.pluckTransactionData.bind(e)(l);r(o["SomeProgram:1"]?.[0]?.signature).toBe("deadbeef")})}),d("duplicate discriminator handling (private)",()=>{n("collects both descriptors into an array when same (program_id, discriminator_hex) appears twice",()=>{const e=s(),t=e.pluckTransactionData.bind(e),o={id:"dup-test",chain_id:101,instructions:[{program_id:"11111111111111111111111111111111",discriminator:2,discriminator_hex:"02"},{program_id:"11111111111111111111111111111111",discriminator:2,discriminator_hex:"02"}],descriptors:[{program_id:"11111111111111111111111111111111",discriminator_hex:"02",has_basis_point:!1,descriptor:i("transfer_descriptor","sig_transfer")},{program_id:"11111111111111111111111111111111",discriminator_hex:"02",has_basis_point:!0,descriptor:i("fee_descriptor","sig_fee")}]},a=t(o);r(Object.keys(a)).toHaveLength(1),r(a["11111111111111111111111111111111:02"]).toHaveLength(2),r(a["11111111111111111111111111111111:02"]?.[0]?.data).toBe("transfer_descriptor"),r(a["11111111111111111111111111111111:02"]?.[0]?.has_basis_point).toBe(!1),r(a["11111111111111111111111111111111:02"]?.[1]?.data).toBe("fee_descriptor"),r(a["11111111111111111111111111111111:02"]?.[1]?.has_basis_point).toBe(!0)})}),d("real CAL payload (LiFi template 4c694669)",()=>{const e={id:"4c694669",chain_id:101,instructions:[{program_id:"ATokenGPvbdGVxr1b2hvZbsiqW5xWH25efTNsLJA8knL",discriminator:1,discriminator_hex:"1"},{program_id:"11111111111111111111111111111111",discriminator:2,discriminator_hex:"2"},{program_id:"JUP6LkbZbjS1jKKwapdHNy74zcZ3tLUZoi5QNyVTaV4",discriminator:0x2aade37a97cb1800,discriminator_hex:"2aade37a97cb17e0"},{program_id:"JUP6LkbZbjS1jKKwapdHNy74zcZ3tLUZoi5QNyVTaV4",discriminator:9339575302786589e3,discriminator_hex:"819cd641339b2148"},{program_id:"MemoSq4gqABAXKb96qnH8TysNcWxMyWCqXgDLGmfcHr"},{program_id:"ATokenGPvbdGVxr1b2hvZbsiqW5xWH25efTNsLJA8knL",discriminator:1,discriminator_hex:"1"},{program_id:"3i5JeuZuUxeKtVysUnwQNGerJP2bSMX9fTFfS4Nxe3Br"},{program_id:"ComputeBudget111111111111111111111111111111",discriminator:2,discriminator_hex:"2"},{program_id:"ComputeBudget111111111111111111111111111111",discriminator:3,discriminator_hex:"3"},{program_id:"TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA",discriminator:3,discriminator_hex:"3"},{program_id:"TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA",discriminator:17,discriminator_hex:"11"},{program_id:"BrdgN2RPzEMWF96ZbnnJaUtQDQx7VRXYaHHbYCBvceWB"}],descriptors:[{program_id:"ATokenGPvbdGVxr1b2hvZbsiqW5xWH25efTNsLJA8knL",discriminator_hex:"1",descriptor:i("atoken_1","sig_atoken")},{program_id:"11111111111111111111111111111111",discriminator_hex:"2",descriptor:i("system_2","sig_system")},{program_id:"JUP6LkbZbjS1jKKwapdHNy74zcZ3tLUZoi5QNyVTaV4",discriminator_hex:"2aade37a97cb17e0",descriptor:i("jup_route","sig_jup_route")},{program_id:"JUP6LkbZbjS1jKKwapdHNy74zcZ3tLUZoi5QNyVTaV4",discriminator_hex:"819cd641339b2148",descriptor:i("jup_shared","sig_jup_shared")},{program_id:"MemoSq4gqABAXKb96qnH8TysNcWxMyWCqXgDLGmfcHr",descriptor:i("memo","sig_memo")},{program_id:"ATokenGPvbdGVxr1b2hvZbsiqW5xWH25efTNsLJA8knL",discriminator_hex:"1",descriptor:i("atoken_1","sig_atoken")},{program_id:"3i5JeuZuUxeKtVysUnwQNGerJP2bSMX9fTFfS4Nxe3Br",descriptor:i("3i5jeu","sig_3i5jeu")},{program_id:"ComputeBudget111111111111111111111111111111",discriminator_hex:"2",descriptor:i("cb_2","sig_cb2")},{program_id:"ComputeBudget111111111111111111111111111111",discriminator_hex:"3",descriptor:i("cb_3","sig_cb3")},{program_id:"TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA",discriminator_hex:"3",descriptor:i("tokenkeg_3","sig_tk3")},{program_id:"TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA",discriminator_hex:"11",descriptor:i("tokenkeg_11","sig_tk11")},{program_id:"BrdgN2RPzEMWF96ZbnnJaUtQDQx7VRXYaHHbYCBvceWB",descriptor:i("brdg","sig_brdg")}]};n("produces 11 unique descriptor keys (ATokenGP:1 appears twice -> array of 2)",()=>{const t=s(),a=t.pluckTransactionData.bind(t)(e),f=Object.keys(a);r(f).toHaveLength(11),r(a["ATokenGPvbdGVxr1b2hvZbsiqW5xWH25efTNsLJA8knL:1"]).toHaveLength(2)}),n("creates distinct keys for same program_id with different discriminators",()=>{const t=s(),a=t.pluckTransactionData.bind(t)(e);r(a["JUP6LkbZbjS1jKKwapdHNy74zcZ3tLUZoi5QNyVTaV4:2aade37a97cb17e0"]?.[0]?.data).toBe("jup_route"),r(a["JUP6LkbZbjS1jKKwapdHNy74zcZ3tLUZoi5QNyVTaV4:819cd641339b2148"]?.[0]?.data).toBe("jup_shared"),r(a["ComputeBudget111111111111111111111111111111:2"]?.[0]?.data).toBe("cb_2"),r(a["ComputeBudget111111111111111111111111111111:3"]?.[0]?.data).toBe("cb_3"),r(a["TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA:3"]?.[0]?.data).toBe("tokenkeg_3"),r(a["TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA:11"]?.[0]?.data).toBe("tokenkeg_11")}),n("uses :0 suffix for programs without a discriminator",()=>{const t=s(),a=t.pluckTransactionData.bind(t)(e);r(a["MemoSq4gqABAXKb96qnH8TysNcWxMyWCqXgDLGmfcHr:"]?.[0]?.data).toBe("memo"),r(a["3i5JeuZuUxeKtVysUnwQNGerJP2bSMX9fTFfS4Nxe3Br:"]?.[0]?.data).toBe("3i5jeu"),r(a["BrdgN2RPzEMWF96ZbnnJaUtQDQx7VRXYaHHbYCBvceWB:"]?.[0]?.data).toBe("brdg")}),n("extracts 12 instruction metadata entries preserving order and discriminators",()=>{const t=s(),a=t.extractInstructionsMeta.bind(t)(e);r(a).toHaveLength(12),r(a[0]).toEqual({program_id:"ATokenGPvbdGVxr1b2hvZbsiqW5xWH25efTNsLJA8knL",discriminator_hex:"1"}),r(a[2]).toEqual({program_id:"JUP6LkbZbjS1jKKwapdHNy74zcZ3tLUZoi5QNyVTaV4",discriminator_hex:"2aade37a97cb17e0"}),r(a[3]).toEqual({program_id:"JUP6LkbZbjS1jKKwapdHNy74zcZ3tLUZoi5QNyVTaV4",discriminator_hex:"819cd641339b2148"}),r(a[4]).toEqual({program_id:"MemoSq4gqABAXKb96qnH8TysNcWxMyWCqXgDLGmfcHr"}),r(a[11]).toEqual({program_id:"BrdgN2RPzEMWF96ZbnnJaUtQDQx7VRXYaHHbYCBvceWB"})}),n("load returns full payload with descriptors and instructions from real API response",async()=>{const t=s();c.spyOn(m,"getTransactionDescriptorsPayload").mockResolvedValue(b(e));const o={templateId:"4c694669",deviceModelId:"nanoS"},a=await t.load(o);r(a).toHaveLength(1),r(a[0]).toMatchObject({type:p.SOLANA_LIFI,payload:{descriptors:r.objectContaining({"JUP6LkbZbjS1jKKwapdHNy74zcZ3tLUZoi5QNyVTaV4:2aade37a97cb17e0":r.arrayContaining([r.objectContaining({data:"jup_route"})]),"JUP6LkbZbjS1jKKwapdHNy74zcZ3tLUZoi5QNyVTaV4:819cd641339b2148":r.arrayContaining([r.objectContaining({data:"jup_shared"})])}),instructions:r.arrayContaining([r.objectContaining({program_id:"JUP6LkbZbjS1jKKwapdHNy74zcZ3tLUZoi5QNyVTaV4",discriminator_hex:"2aade37a97cb17e0"}),r.objectContaining({program_id:"JUP6LkbZbjS1jKKwapdHNy74zcZ3tLUZoi5QNyVTaV4",discriminator_hex:"819cd641339b2148"})])}}),r(Object.keys(a[0].payload.descriptors)).toHaveLength(11),r(a[0].payload.instructions).toHaveLength(12)})})});
2
2
  //# sourceMappingURL=LifiContextLoader.test.js.map
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "version": 3,
3
3
  "sources": ["../../../../../../../src/modules/solana/lifi/domain/LifiContextLoader.test.ts"],
4
- "sourcesContent": ["/* eslint-disable @typescript-eslint/no-unsafe-member-access */\n/* eslint-disable @typescript-eslint/no-unsafe-call */\n/* eslint-disable @typescript-eslint/no-unsafe-assignment */\n/* eslint-disable @typescript-eslint/no-explicit-any */\nimport { Left, Right } from \"purify-ts\";\nimport { beforeEach, describe, expect, it, vi } from \"vitest\";\n\nimport { type ContextModuleServiceConfig } from \"@/config/model/ContextModuleConfig\";\nimport { type PkiCertificateLoader } from \"@/modules/multichain/pki/domain/PkiCertificateLoader\";\nimport {\n type GetTransactionDescriptorsResponse,\n type LifiDataSource,\n} from \"@/modules/solana/lifi/data/LifiDataSource\";\nimport {\n type SolanaTransactionDescriptorList,\n type SolanaTransactionDescriptorRaw,\n} from \"@/modules/solana/model/SolanaContextTypes\";\nimport { type SolanaTransactionDescriptor } from \"@/modules/solana/model/SolanaPayloads\";\nimport { ClearSignContextType } from \"@/shared/model/ClearSignContext\";\n\nimport { LifiContextLoader } from \"./LifiContextLoader\";\n\nconst mockLoggerFactory = () => ({\n debug: vi.fn(),\n info: vi.fn(),\n warn: vi.fn(),\n error: vi.fn(),\n subscribers: [],\n});\n\nconst mockCertificate = {\n keyUsageNumber: 13,\n payload: new Uint8Array([0x01, 0x02]),\n};\n\nconst mockConfig = {\n cal: {\n url: \"https://global.api.prd.ledger.com/cal/v1\",\n mode: \"test\",\n branch: \"main\",\n },\n} as ContextModuleServiceConfig;\n\ndescribe(\"LifiContextLoader\", () => {\n let mockDataSource: LifiDataSource;\n let mockCertificateLoader: PkiCertificateLoader;\n\n const makeRawDescriptor = (\n data: string,\n sig = \"deadbeef\",\n ): SolanaTransactionDescriptorRaw => ({\n data,\n descriptorType: \"swap_template\",\n descriptorVersion: \"v1\",\n signatures: { test: sig, prod: `prod_${sig}` },\n });\n\n const makeResolvedDescriptor = (\n data: string,\n sig = \"deadbeef\",\n ): SolanaTransactionDescriptor => ({\n data,\n descriptorType: \"swap_template\",\n descriptorVersion: \"v1\",\n signature: sig,\n });\n\n const responseDescriptorsArray: GetTransactionDescriptorsResponse[\"descriptors\"] =\n [\n {\n program_id: \"SomeProgram\",\n discriminator_hex: \"1\",\n descriptor: makeRawDescriptor(\"abc123\"),\n },\n {\n program_id: \"AnotherProgram\",\n // discriminator_hex intentionally omitted -> defaults to \"\"\n descriptor: makeRawDescriptor(\"def456\"),\n },\n ];\n\n const expectedPlucked: SolanaTransactionDescriptorList = {\n \"SomeProgram:1\": makeResolvedDescriptor(\"abc123\"),\n \"AnotherProgram:\": makeResolvedDescriptor(\"def456\"),\n };\n\n const responseInstructionsArray: GetTransactionDescriptorsResponse[\"instructions\"] =\n [\n {\n program_id: \"SomeProgram\",\n discriminator: 1,\n discriminator_hex: \"1\",\n },\n {\n program_id: \"AnotherProgram\",\n // discriminator_hex intentionally omitted\n },\n ];\n\n const txDescriptorsResponse: GetTransactionDescriptorsResponse = {\n id: \"tpl-1\",\n chain_id: 101,\n instructions: responseInstructionsArray,\n descriptors: responseDescriptorsArray,\n };\n\n beforeEach(() => {\n vi.restoreAllMocks();\n mockDataSource = {\n getTransactionDescriptorsPayload: vi.fn(),\n } as unknown as LifiDataSource;\n mockCertificateLoader = {\n loadCertificate: vi.fn().mockResolvedValue(mockCertificate),\n } as unknown as PkiCertificateLoader;\n });\n\n const makeLoader = () =>\n new LifiContextLoader(\n mockDataSource,\n mockConfig,\n mockCertificateLoader,\n mockLoggerFactory,\n );\n\n describe(\"canHandle\", () => {\n it(\"returns true when templateId is provided and SOLANA_LIFI is in expectedTypes\", () => {\n const loader = makeLoader();\n\n expect(\n loader.canHandle(\n {\n templateId: \"tpl-123\",\n deviceModelId: \"nanoS\" as any,\n },\n [ClearSignContextType.SOLANA_LIFI],\n ),\n ).toBe(true);\n });\n\n it(\"returns false when SOLANA_LIFI is not in expectedTypes\", () => {\n const loader = makeLoader();\n\n expect(\n loader.canHandle({ templateId: \"tpl-123\" } as any, [\n ClearSignContextType.SOLANA_TOKEN,\n ]),\n ).toBe(false);\n });\n\n it(\"returns false when templateId is missing or falsy\", () => {\n const loader = makeLoader();\n\n expect(\n loader.canHandle({ templateId: \"\" } as any, [\n ClearSignContextType.SOLANA_LIFI,\n ]),\n ).toBe(false);\n expect(\n loader.canHandle({ templateId: undefined } as any, [\n ClearSignContextType.SOLANA_LIFI,\n ]),\n ).toBe(false);\n expect(\n loader.canHandle({} as any, [ClearSignContextType.SOLANA_LIFI]),\n ).toBe(false);\n });\n });\n\n describe(\"load\", () => {\n it(\"returns an array with an error when datasource returns Left(error)\", async () => {\n const loader = makeLoader();\n const error = new Error(\"boom\");\n\n vi.spyOn(\n mockDataSource,\n \"getTransactionDescriptorsPayload\",\n ).mockResolvedValue(Left(error));\n\n const input = { templateId: \"tpl-err\", deviceModelId: \"nanoS\" as any };\n const result = await loader.load(input);\n\n expect(\n mockDataSource.getTransactionDescriptorsPayload,\n ).toHaveBeenCalledWith({\n templateId: \"tpl-err\",\n });\n\n expect(result).toEqual([\n {\n type: ClearSignContextType.ERROR,\n error,\n },\n ]);\n });\n\n it(\"returns SOLANA_LIFI array with plucked descriptors and certificate when datasource returns Right(value)\", async () => {\n const loader = makeLoader();\n\n vi.spyOn(\n mockDataSource,\n \"getTransactionDescriptorsPayload\",\n ).mockResolvedValue(Right(txDescriptorsResponse));\n\n const input = { templateId: \"tpl-ok\", deviceModelId: \"nanoS\" as any };\n const result = await loader.load(input);\n\n expect(\n mockDataSource.getTransactionDescriptorsPayload,\n ).toHaveBeenCalledWith({\n templateId: \"tpl-ok\",\n });\n\n expect(mockCertificateLoader.loadCertificate).toHaveBeenCalledWith({\n keyId: \"swap_template_key\",\n keyUsage: \"swap_template\",\n targetDevice: \"nanoS\",\n });\n\n expect(result).toEqual([\n {\n type: ClearSignContextType.SOLANA_LIFI,\n payload: {\n descriptors: expectedPlucked,\n instructions: [\n { program_id: \"SomeProgram\", discriminator_hex: \"1\" },\n { program_id: \"AnotherProgram\" },\n ],\n },\n certificate: mockCertificate,\n },\n ]);\n });\n });\n\n describe(\"pluckTransactionData (private)\", () => {\n it(\"returns a map keyed by `${program_id}:${discriminator_hex ?? '0'}`\", () => {\n const loader = makeLoader();\n const pluck = (loader as any).pluckTransactionData.bind(loader);\n\n const result: SolanaTransactionDescriptorList = pluck(\n txDescriptorsResponse,\n );\n\n expect(result).toEqual(expectedPlucked);\n });\n });\n\n describe(\"extractInstructionsMeta (private)\", () => {\n it(\"returns instruction metadata from the API response\", () => {\n const loader = makeLoader();\n const extract = (loader as any).extractInstructionsMeta.bind(loader);\n\n const result = extract(txDescriptorsResponse);\n\n expect(result).toEqual([\n { program_id: \"SomeProgram\", discriminator_hex: \"1\" },\n { program_id: \"AnotherProgram\" },\n ]);\n });\n\n it(\"returns empty array when instructions are missing\", () => {\n const loader = makeLoader();\n const extract = (loader as any).extractInstructionsMeta.bind(loader);\n\n const result = extract({\n ...txDescriptorsResponse,\n instructions: undefined,\n });\n\n expect(result).toEqual([]);\n });\n });\n\n describe(\"pluckTransactionData mode resolution (private)\", () => {\n it(\"resolves signature using config.cal.mode\", () => {\n const loader = makeLoader();\n const pluck = (loader as any).pluckTransactionData.bind(loader);\n\n const result: SolanaTransactionDescriptorList = pluck(\n txDescriptorsResponse,\n );\n\n expect(result[\"SomeProgram:1\"]?.signature).toBe(\"deadbeef\");\n });\n });\n\n describe(\"real CAL payload (LiFi template 4c694669)\", () => {\n const realApiResponse: GetTransactionDescriptorsResponse = {\n id: \"4c694669\",\n chain_id: 101,\n instructions: [\n {\n program_id: \"ATokenGPvbdGVxr1b2hvZbsiqW5xWH25efTNsLJA8knL\",\n discriminator: 1,\n discriminator_hex: \"1\",\n },\n {\n program_id: \"11111111111111111111111111111111\",\n discriminator: 2,\n discriminator_hex: \"2\",\n },\n {\n program_id: \"JUP6LkbZbjS1jKKwapdHNy74zcZ3tLUZoi5QNyVTaV4\",\n discriminator: 3.0753642362361016e18,\n discriminator_hex: \"2aade37a97cb17e0\",\n },\n {\n program_id: \"JUP6LkbZbjS1jKKwapdHNy74zcZ3tLUZoi5QNyVTaV4\",\n discriminator: 9.339575302786589e18,\n discriminator_hex: \"819cd641339b2148\",\n },\n { program_id: \"MemoSq4gqABAXKb96qnH8TysNcWxMyWCqXgDLGmfcHr\" },\n {\n program_id: \"ATokenGPvbdGVxr1b2hvZbsiqW5xWH25efTNsLJA8knL\",\n discriminator: 1,\n discriminator_hex: \"1\",\n },\n { program_id: \"3i5JeuZuUxeKtVysUnwQNGerJP2bSMX9fTFfS4Nxe3Br\" },\n {\n program_id: \"ComputeBudget111111111111111111111111111111\",\n discriminator: 2,\n discriminator_hex: \"2\",\n },\n {\n program_id: \"ComputeBudget111111111111111111111111111111\",\n discriminator: 3,\n discriminator_hex: \"3\",\n },\n {\n program_id: \"TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA\",\n discriminator: 3,\n discriminator_hex: \"3\",\n },\n {\n program_id: \"TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA\",\n discriminator: 17,\n discriminator_hex: \"11\",\n },\n { program_id: \"BrdgN2RPzEMWF96ZbnnJaUtQDQx7VRXYaHHbYCBvceWB\" },\n ],\n descriptors: [\n {\n program_id: \"ATokenGPvbdGVxr1b2hvZbsiqW5xWH25efTNsLJA8knL\",\n discriminator_hex: \"1\",\n descriptor: makeRawDescriptor(\"atoken_1\", \"sig_atoken\"),\n },\n {\n program_id: \"11111111111111111111111111111111\",\n discriminator_hex: \"2\",\n descriptor: makeRawDescriptor(\"system_2\", \"sig_system\"),\n },\n {\n program_id: \"JUP6LkbZbjS1jKKwapdHNy74zcZ3tLUZoi5QNyVTaV4\",\n discriminator_hex: \"2aade37a97cb17e0\",\n descriptor: makeRawDescriptor(\"jup_route\", \"sig_jup_route\"),\n },\n {\n program_id: \"JUP6LkbZbjS1jKKwapdHNy74zcZ3tLUZoi5QNyVTaV4\",\n discriminator_hex: \"819cd641339b2148\",\n descriptor: makeRawDescriptor(\"jup_shared\", \"sig_jup_shared\"),\n },\n {\n program_id: \"MemoSq4gqABAXKb96qnH8TysNcWxMyWCqXgDLGmfcHr\",\n descriptor: makeRawDescriptor(\"memo\", \"sig_memo\"),\n },\n {\n program_id: \"ATokenGPvbdGVxr1b2hvZbsiqW5xWH25efTNsLJA8knL\",\n discriminator_hex: \"1\",\n descriptor: makeRawDescriptor(\"atoken_1\", \"sig_atoken\"),\n },\n {\n program_id: \"3i5JeuZuUxeKtVysUnwQNGerJP2bSMX9fTFfS4Nxe3Br\",\n descriptor: makeRawDescriptor(\"3i5jeu\", \"sig_3i5jeu\"),\n },\n {\n program_id: \"ComputeBudget111111111111111111111111111111\",\n discriminator_hex: \"2\",\n descriptor: makeRawDescriptor(\"cb_2\", \"sig_cb2\"),\n },\n {\n program_id: \"ComputeBudget111111111111111111111111111111\",\n discriminator_hex: \"3\",\n descriptor: makeRawDescriptor(\"cb_3\", \"sig_cb3\"),\n },\n {\n program_id: \"TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA\",\n discriminator_hex: \"3\",\n descriptor: makeRawDescriptor(\"tokenkeg_3\", \"sig_tk3\"),\n },\n {\n program_id: \"TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA\",\n discriminator_hex: \"11\",\n descriptor: makeRawDescriptor(\"tokenkeg_11\", \"sig_tk11\"),\n },\n {\n program_id: \"BrdgN2RPzEMWF96ZbnnJaUtQDQx7VRXYaHHbYCBvceWB\",\n descriptor: makeRawDescriptor(\"brdg\", \"sig_brdg\"),\n },\n ],\n };\n\n it(\"produces 11 unique descriptor keys (ATokenGP:1 appears twice but deduplicates)\", () => {\n const loader = makeLoader();\n const pluck = (loader as any).pluckTransactionData.bind(loader);\n\n const result: SolanaTransactionDescriptorList = pluck(realApiResponse);\n const keys = Object.keys(result);\n\n // 12 descriptors but ATokenGP:1 appears twice -> 11 unique keys\n expect(keys).toHaveLength(11);\n });\n\n it(\"creates distinct keys for same program_id with different discriminators\", () => {\n const loader = makeLoader();\n const pluck = (loader as any).pluckTransactionData.bind(loader);\n\n const result: SolanaTransactionDescriptorList = pluck(realApiResponse);\n\n // JUP6 has two different discriminators -> two distinct entries\n expect(\n result[\"JUP6LkbZbjS1jKKwapdHNy74zcZ3tLUZoi5QNyVTaV4:2aade37a97cb17e0\"]\n ?.data,\n ).toBe(\"jup_route\");\n expect(\n result[\"JUP6LkbZbjS1jKKwapdHNy74zcZ3tLUZoi5QNyVTaV4:819cd641339b2148\"]\n ?.data,\n ).toBe(\"jup_shared\");\n\n // ComputeBudget has discriminator 2 and 3\n expect(\n result[\"ComputeBudget111111111111111111111111111111:2\"]?.data,\n ).toBe(\"cb_2\");\n expect(\n result[\"ComputeBudget111111111111111111111111111111:3\"]?.data,\n ).toBe(\"cb_3\");\n\n // TokenkegQ has discriminator 3 and 11\n expect(\n result[\"TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA:3\"]?.data,\n ).toBe(\"tokenkeg_3\");\n expect(\n result[\"TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA:11\"]?.data,\n ).toBe(\"tokenkeg_11\");\n });\n\n it(\"uses :0 suffix for programs without a discriminator\", () => {\n const loader = makeLoader();\n const pluck = (loader as any).pluckTransactionData.bind(loader);\n\n const result: SolanaTransactionDescriptorList = pluck(realApiResponse);\n\n expect(result[\"MemoSq4gqABAXKb96qnH8TysNcWxMyWCqXgDLGmfcHr:\"]?.data).toBe(\n \"memo\",\n );\n expect(\n result[\"3i5JeuZuUxeKtVysUnwQNGerJP2bSMX9fTFfS4Nxe3Br:\"]?.data,\n ).toBe(\"3i5jeu\");\n expect(\n result[\"BrdgN2RPzEMWF96ZbnnJaUtQDQx7VRXYaHHbYCBvceWB:\"]?.data,\n ).toBe(\"brdg\");\n });\n\n it(\"extracts 12 instruction metadata entries preserving order and discriminators\", () => {\n const loader = makeLoader();\n const extract = (loader as any).extractInstructionsMeta.bind(loader);\n\n const result = extract(realApiResponse);\n\n expect(result).toHaveLength(12);\n\n // First: ATokenGP with discriminator\n expect(result[0]).toEqual({\n program_id: \"ATokenGPvbdGVxr1b2hvZbsiqW5xWH25efTNsLJA8knL\",\n discriminator_hex: \"1\",\n });\n // JUP6 route (8-byte discriminator)\n expect(result[2]).toEqual({\n program_id: \"JUP6LkbZbjS1jKKwapdHNy74zcZ3tLUZoi5QNyVTaV4\",\n discriminator_hex: \"2aade37a97cb17e0\",\n });\n // JUP6 shared (8-byte discriminator)\n expect(result[3]).toEqual({\n program_id: \"JUP6LkbZbjS1jKKwapdHNy74zcZ3tLUZoi5QNyVTaV4\",\n discriminator_hex: \"819cd641339b2148\",\n });\n // Memo: no discriminator\n expect(result[4]).toEqual({\n program_id: \"MemoSq4gqABAXKb96qnH8TysNcWxMyWCqXgDLGmfcHr\",\n });\n // BrdgN2: no discriminator (last entry)\n expect(result[11]).toEqual({\n program_id: \"BrdgN2RPzEMWF96ZbnnJaUtQDQx7VRXYaHHbYCBvceWB\",\n });\n });\n\n it(\"load returns full payload with descriptors and instructions from real API response\", async () => {\n const loader = makeLoader();\n\n vi.spyOn(\n mockDataSource,\n \"getTransactionDescriptorsPayload\",\n ).mockResolvedValue(Right(realApiResponse));\n\n const input = { templateId: \"4c694669\", deviceModelId: \"nanoS\" as any };\n const result = await loader.load(input);\n\n expect(result).toHaveLength(1);\n expect(result[0]).toMatchObject({\n type: ClearSignContextType.SOLANA_LIFI,\n payload: {\n descriptors: expect.objectContaining({\n \"JUP6LkbZbjS1jKKwapdHNy74zcZ3tLUZoi5QNyVTaV4:2aade37a97cb17e0\":\n expect.objectContaining({ data: \"jup_route\" }),\n \"JUP6LkbZbjS1jKKwapdHNy74zcZ3tLUZoi5QNyVTaV4:819cd641339b2148\":\n expect.objectContaining({ data: \"jup_shared\" }),\n }),\n instructions: expect.arrayContaining([\n expect.objectContaining({\n program_id: \"JUP6LkbZbjS1jKKwapdHNy74zcZ3tLUZoi5QNyVTaV4\",\n discriminator_hex: \"2aade37a97cb17e0\",\n }),\n expect.objectContaining({\n program_id: \"JUP6LkbZbjS1jKKwapdHNy74zcZ3tLUZoi5QNyVTaV4\",\n discriminator_hex: \"819cd641339b2148\",\n }),\n ]),\n },\n });\n\n expect(Object.keys((result[0] as any).payload.descriptors)).toHaveLength(\n 11,\n );\n expect((result[0] as any).payload.instructions).toHaveLength(12);\n });\n });\n});\n"],
5
- "mappings": "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",
6
- "names": ["Left", "Right", "beforeEach", "describe", "expect", "it", "vi", "ClearSignContextType", "LifiContextLoader", "mockLoggerFactory", "mockCertificate", "mockConfig", "mockDataSource", "mockCertificateLoader", "makeRawDescriptor", "data", "sig", "makeResolvedDescriptor", "responseDescriptorsArray", "expectedPlucked", "txDescriptorsResponse", "makeLoader", "loader", "error", "input", "result", "realApiResponse", "keys"]
4
+ "sourcesContent": ["/* eslint-disable @typescript-eslint/no-unsafe-member-access */\n/* eslint-disable @typescript-eslint/no-unsafe-call */\n/* eslint-disable @typescript-eslint/no-unsafe-assignment */\n/* eslint-disable @typescript-eslint/no-explicit-any */\nimport { Left, Right } from \"purify-ts\";\nimport { beforeEach, describe, expect, it, vi } from \"vitest\";\n\nimport { type ContextModuleServiceConfig } from \"@/config/model/ContextModuleConfig\";\nimport { type PkiCertificateLoader } from \"@/modules/multichain/pki/domain/PkiCertificateLoader\";\nimport {\n type GetTransactionDescriptorsResponse,\n type LifiDataSource,\n} from \"@/modules/solana/lifi/data/LifiDataSource\";\nimport {\n type SolanaTransactionDescriptorList,\n type SolanaTransactionDescriptorRaw,\n} from \"@/modules/solana/model/SolanaContextTypes\";\nimport { type SolanaTransactionDescriptor } from \"@/modules/solana/model/SolanaPayloads\";\nimport { ClearSignContextType } from \"@/shared/model/ClearSignContext\";\n\nimport { LifiContextLoader } from \"./LifiContextLoader\";\n\nconst mockLoggerFactory = () => ({\n debug: vi.fn(),\n info: vi.fn(),\n warn: vi.fn(),\n error: vi.fn(),\n subscribers: [],\n});\n\nconst mockCertificate = {\n keyUsageNumber: 13,\n payload: new Uint8Array([0x01, 0x02]),\n};\n\nconst mockConfig = {\n cal: {\n url: \"https://global.api.prd.ledger.com/cal/v1\",\n mode: \"test\",\n branch: \"main\",\n },\n} as ContextModuleServiceConfig;\n\ndescribe(\"LifiContextLoader\", () => {\n let mockDataSource: LifiDataSource;\n let mockCertificateLoader: PkiCertificateLoader;\n\n const makeRawDescriptor = (\n data: string,\n sig = \"deadbeef\",\n ): SolanaTransactionDescriptorRaw => ({\n data,\n descriptorType: \"swap_template\",\n descriptorVersion: \"v1\",\n signatures: { test: sig, prod: `prod_${sig}` },\n });\n\n const makeResolvedDescriptor = (\n data: string,\n sig = \"deadbeef\",\n ): SolanaTransactionDescriptor => ({\n data,\n descriptorType: \"swap_template\",\n descriptorVersion: \"v1\",\n signature: sig,\n });\n\n const responseDescriptorsArray: GetTransactionDescriptorsResponse[\"descriptors\"] =\n [\n {\n program_id: \"SomeProgram\",\n discriminator_hex: \"1\",\n descriptor: makeRawDescriptor(\"abc123\"),\n },\n {\n program_id: \"AnotherProgram\",\n // discriminator_hex intentionally omitted -> defaults to \"\"\n descriptor: makeRawDescriptor(\"def456\"),\n },\n ];\n\n const expectedPlucked: SolanaTransactionDescriptorList = {\n \"SomeProgram:1\": [makeResolvedDescriptor(\"abc123\")],\n \"AnotherProgram:\": [makeResolvedDescriptor(\"def456\")],\n };\n\n const responseInstructionsArray: GetTransactionDescriptorsResponse[\"instructions\"] =\n [\n {\n program_id: \"SomeProgram\",\n discriminator: 1,\n discriminator_hex: \"1\",\n },\n {\n program_id: \"AnotherProgram\",\n // discriminator_hex intentionally omitted\n },\n ];\n\n const txDescriptorsResponse: GetTransactionDescriptorsResponse = {\n id: \"tpl-1\",\n chain_id: 101,\n instructions: responseInstructionsArray,\n descriptors: responseDescriptorsArray,\n };\n\n beforeEach(() => {\n vi.restoreAllMocks();\n mockDataSource = {\n getTransactionDescriptorsPayload: vi.fn(),\n } as unknown as LifiDataSource;\n mockCertificateLoader = {\n loadCertificate: vi.fn().mockResolvedValue(mockCertificate),\n } as unknown as PkiCertificateLoader;\n });\n\n const makeLoader = () =>\n new LifiContextLoader(\n mockDataSource,\n mockConfig,\n mockCertificateLoader,\n mockLoggerFactory,\n );\n\n describe(\"canHandle\", () => {\n it(\"returns true when templateId is provided and SOLANA_LIFI is in expectedTypes\", () => {\n const loader = makeLoader();\n\n expect(\n loader.canHandle(\n {\n templateId: \"tpl-123\",\n deviceModelId: \"nanoS\" as any,\n },\n [ClearSignContextType.SOLANA_LIFI],\n ),\n ).toBe(true);\n });\n\n it(\"returns false when SOLANA_LIFI is not in expectedTypes\", () => {\n const loader = makeLoader();\n\n expect(\n loader.canHandle({ templateId: \"tpl-123\" } as any, [\n ClearSignContextType.SOLANA_TOKEN,\n ]),\n ).toBe(false);\n });\n\n it(\"returns false when templateId is missing or falsy\", () => {\n const loader = makeLoader();\n\n expect(\n loader.canHandle({ templateId: \"\" } as any, [\n ClearSignContextType.SOLANA_LIFI,\n ]),\n ).toBe(false);\n expect(\n loader.canHandle({ templateId: undefined } as any, [\n ClearSignContextType.SOLANA_LIFI,\n ]),\n ).toBe(false);\n expect(\n loader.canHandle({} as any, [ClearSignContextType.SOLANA_LIFI]),\n ).toBe(false);\n });\n });\n\n describe(\"load\", () => {\n it(\"returns an array with an error when datasource returns Left(error)\", async () => {\n const loader = makeLoader();\n const error = new Error(\"boom\");\n\n vi.spyOn(\n mockDataSource,\n \"getTransactionDescriptorsPayload\",\n ).mockResolvedValue(Left(error));\n\n const input = { templateId: \"tpl-err\", deviceModelId: \"nanoS\" as any };\n const result = await loader.load(input);\n\n expect(\n mockDataSource.getTransactionDescriptorsPayload,\n ).toHaveBeenCalledWith({\n templateId: \"tpl-err\",\n });\n\n expect(result).toEqual([\n {\n type: ClearSignContextType.ERROR,\n error,\n },\n ]);\n });\n\n it(\"returns SOLANA_LIFI array with plucked descriptors and certificate when datasource returns Right(value)\", async () => {\n const loader = makeLoader();\n\n vi.spyOn(\n mockDataSource,\n \"getTransactionDescriptorsPayload\",\n ).mockResolvedValue(Right(txDescriptorsResponse));\n\n const input = { templateId: \"tpl-ok\", deviceModelId: \"nanoS\" as any };\n const result = await loader.load(input);\n\n expect(\n mockDataSource.getTransactionDescriptorsPayload,\n ).toHaveBeenCalledWith({\n templateId: \"tpl-ok\",\n });\n\n expect(mockCertificateLoader.loadCertificate).toHaveBeenCalledWith({\n keyId: \"swap_template_key\",\n keyUsage: \"swap_template\",\n targetDevice: \"nanoS\",\n });\n\n expect(result).toEqual([\n {\n type: ClearSignContextType.SOLANA_LIFI,\n payload: {\n descriptors: expectedPlucked,\n instructions: [\n { program_id: \"SomeProgram\", discriminator_hex: \"1\" },\n { program_id: \"AnotherProgram\" },\n ],\n },\n certificate: mockCertificate,\n },\n ]);\n });\n });\n\n describe(\"pluckTransactionData (private)\", () => {\n it(\"returns a map keyed by `${program_id}:${discriminator_hex ?? '0'}`\", () => {\n const loader = makeLoader();\n const pluck = (loader as any).pluckTransactionData.bind(loader);\n\n const result: SolanaTransactionDescriptorList = pluck(\n txDescriptorsResponse,\n );\n\n expect(result).toEqual(expectedPlucked);\n });\n });\n\n describe(\"extractInstructionsMeta (private)\", () => {\n it(\"returns instruction metadata from the API response\", () => {\n const loader = makeLoader();\n const extract = (loader as any).extractInstructionsMeta.bind(loader);\n\n const result = extract(txDescriptorsResponse);\n\n expect(result).toEqual([\n { program_id: \"SomeProgram\", discriminator_hex: \"1\" },\n { program_id: \"AnotherProgram\" },\n ]);\n });\n\n it(\"returns empty array when instructions are missing\", () => {\n const loader = makeLoader();\n const extract = (loader as any).extractInstructionsMeta.bind(loader);\n\n const result = extract({\n ...txDescriptorsResponse,\n instructions: undefined,\n });\n\n expect(result).toEqual([]);\n });\n });\n\n describe(\"pluckTransactionData mode resolution (private)\", () => {\n it(\"resolves signature using config.cal.mode\", () => {\n const loader = makeLoader();\n const pluck = (loader as any).pluckTransactionData.bind(loader);\n\n const result: SolanaTransactionDescriptorList = pluck(\n txDescriptorsResponse,\n );\n\n expect(result[\"SomeProgram:1\"]?.[0]?.signature).toBe(\"deadbeef\");\n });\n });\n\n describe(\"duplicate discriminator handling (private)\", () => {\n it(\"collects both descriptors into an array when same (program_id, discriminator_hex) appears twice\", () => {\n // Models the LiFi CAL PR fix: System Program Transfer has two descriptors \u2014\n // one for the transfer amount and one for fees (distinguished by capped_bps).\n const loader = makeLoader();\n const pluck = (loader as any).pluckTransactionData.bind(loader);\n\n const response: GetTransactionDescriptorsResponse = {\n id: \"dup-test\",\n chain_id: 101,\n instructions: [\n {\n program_id: \"11111111111111111111111111111111\",\n discriminator: 2,\n discriminator_hex: \"02\",\n },\n {\n program_id: \"11111111111111111111111111111111\",\n discriminator: 2,\n discriminator_hex: \"02\",\n },\n ],\n descriptors: [\n {\n program_id: \"11111111111111111111111111111111\",\n discriminator_hex: \"02\",\n has_basis_point: false,\n descriptor: makeRawDescriptor(\n \"transfer_descriptor\",\n \"sig_transfer\",\n ),\n },\n {\n program_id: \"11111111111111111111111111111111\",\n discriminator_hex: \"02\",\n has_basis_point: true,\n descriptor: makeRawDescriptor(\"fee_descriptor\", \"sig_fee\"),\n },\n ],\n };\n\n const result: SolanaTransactionDescriptorList = pluck(response);\n\n expect(Object.keys(result)).toHaveLength(1);\n expect(result[\"11111111111111111111111111111111:02\"]).toHaveLength(2);\n expect(result[\"11111111111111111111111111111111:02\"]?.[0]?.data).toBe(\n \"transfer_descriptor\",\n );\n expect(\n result[\"11111111111111111111111111111111:02\"]?.[0]?.has_basis_point,\n ).toBe(false);\n expect(result[\"11111111111111111111111111111111:02\"]?.[1]?.data).toBe(\n \"fee_descriptor\",\n );\n expect(\n result[\"11111111111111111111111111111111:02\"]?.[1]?.has_basis_point,\n ).toBe(true);\n });\n });\n\n describe(\"real CAL payload (LiFi template 4c694669)\", () => {\n const realApiResponse: GetTransactionDescriptorsResponse = {\n id: \"4c694669\",\n chain_id: 101,\n instructions: [\n {\n program_id: \"ATokenGPvbdGVxr1b2hvZbsiqW5xWH25efTNsLJA8knL\",\n discriminator: 1,\n discriminator_hex: \"1\",\n },\n {\n program_id: \"11111111111111111111111111111111\",\n discriminator: 2,\n discriminator_hex: \"2\",\n },\n {\n program_id: \"JUP6LkbZbjS1jKKwapdHNy74zcZ3tLUZoi5QNyVTaV4\",\n discriminator: 3.0753642362361016e18,\n discriminator_hex: \"2aade37a97cb17e0\",\n },\n {\n program_id: \"JUP6LkbZbjS1jKKwapdHNy74zcZ3tLUZoi5QNyVTaV4\",\n discriminator: 9.339575302786589e18,\n discriminator_hex: \"819cd641339b2148\",\n },\n { program_id: \"MemoSq4gqABAXKb96qnH8TysNcWxMyWCqXgDLGmfcHr\" },\n {\n program_id: \"ATokenGPvbdGVxr1b2hvZbsiqW5xWH25efTNsLJA8knL\",\n discriminator: 1,\n discriminator_hex: \"1\",\n },\n { program_id: \"3i5JeuZuUxeKtVysUnwQNGerJP2bSMX9fTFfS4Nxe3Br\" },\n {\n program_id: \"ComputeBudget111111111111111111111111111111\",\n discriminator: 2,\n discriminator_hex: \"2\",\n },\n {\n program_id: \"ComputeBudget111111111111111111111111111111\",\n discriminator: 3,\n discriminator_hex: \"3\",\n },\n {\n program_id: \"TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA\",\n discriminator: 3,\n discriminator_hex: \"3\",\n },\n {\n program_id: \"TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA\",\n discriminator: 17,\n discriminator_hex: \"11\",\n },\n { program_id: \"BrdgN2RPzEMWF96ZbnnJaUtQDQx7VRXYaHHbYCBvceWB\" },\n ],\n descriptors: [\n {\n program_id: \"ATokenGPvbdGVxr1b2hvZbsiqW5xWH25efTNsLJA8knL\",\n discriminator_hex: \"1\",\n descriptor: makeRawDescriptor(\"atoken_1\", \"sig_atoken\"),\n },\n {\n program_id: \"11111111111111111111111111111111\",\n discriminator_hex: \"2\",\n descriptor: makeRawDescriptor(\"system_2\", \"sig_system\"),\n },\n {\n program_id: \"JUP6LkbZbjS1jKKwapdHNy74zcZ3tLUZoi5QNyVTaV4\",\n discriminator_hex: \"2aade37a97cb17e0\",\n descriptor: makeRawDescriptor(\"jup_route\", \"sig_jup_route\"),\n },\n {\n program_id: \"JUP6LkbZbjS1jKKwapdHNy74zcZ3tLUZoi5QNyVTaV4\",\n discriminator_hex: \"819cd641339b2148\",\n descriptor: makeRawDescriptor(\"jup_shared\", \"sig_jup_shared\"),\n },\n {\n program_id: \"MemoSq4gqABAXKb96qnH8TysNcWxMyWCqXgDLGmfcHr\",\n descriptor: makeRawDescriptor(\"memo\", \"sig_memo\"),\n },\n {\n program_id: \"ATokenGPvbdGVxr1b2hvZbsiqW5xWH25efTNsLJA8knL\",\n discriminator_hex: \"1\",\n descriptor: makeRawDescriptor(\"atoken_1\", \"sig_atoken\"),\n },\n {\n program_id: \"3i5JeuZuUxeKtVysUnwQNGerJP2bSMX9fTFfS4Nxe3Br\",\n descriptor: makeRawDescriptor(\"3i5jeu\", \"sig_3i5jeu\"),\n },\n {\n program_id: \"ComputeBudget111111111111111111111111111111\",\n discriminator_hex: \"2\",\n descriptor: makeRawDescriptor(\"cb_2\", \"sig_cb2\"),\n },\n {\n program_id: \"ComputeBudget111111111111111111111111111111\",\n discriminator_hex: \"3\",\n descriptor: makeRawDescriptor(\"cb_3\", \"sig_cb3\"),\n },\n {\n program_id: \"TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA\",\n discriminator_hex: \"3\",\n descriptor: makeRawDescriptor(\"tokenkeg_3\", \"sig_tk3\"),\n },\n {\n program_id: \"TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA\",\n discriminator_hex: \"11\",\n descriptor: makeRawDescriptor(\"tokenkeg_11\", \"sig_tk11\"),\n },\n {\n program_id: \"BrdgN2RPzEMWF96ZbnnJaUtQDQx7VRXYaHHbYCBvceWB\",\n descriptor: makeRawDescriptor(\"brdg\", \"sig_brdg\"),\n },\n ],\n };\n\n it(\"produces 11 unique descriptor keys (ATokenGP:1 appears twice -> array of 2)\", () => {\n const loader = makeLoader();\n const pluck = (loader as any).pluckTransactionData.bind(loader);\n\n const result: SolanaTransactionDescriptorList = pluck(realApiResponse);\n const keys = Object.keys(result);\n\n // 12 descriptors but ATokenGP:1 appears twice -> 11 unique keys, ATokenGP:1 has 2 entries\n expect(keys).toHaveLength(11);\n expect(\n result[\"ATokenGPvbdGVxr1b2hvZbsiqW5xWH25efTNsLJA8knL:1\"],\n ).toHaveLength(2);\n });\n\n it(\"creates distinct keys for same program_id with different discriminators\", () => {\n const loader = makeLoader();\n const pluck = (loader as any).pluckTransactionData.bind(loader);\n\n const result: SolanaTransactionDescriptorList = pluck(realApiResponse);\n\n // JUP6 has two different discriminators -> two distinct entries\n expect(\n result[\n \"JUP6LkbZbjS1jKKwapdHNy74zcZ3tLUZoi5QNyVTaV4:2aade37a97cb17e0\"\n ]?.[0]?.data,\n ).toBe(\"jup_route\");\n expect(\n result[\n \"JUP6LkbZbjS1jKKwapdHNy74zcZ3tLUZoi5QNyVTaV4:819cd641339b2148\"\n ]?.[0]?.data,\n ).toBe(\"jup_shared\");\n\n // ComputeBudget has discriminator 2 and 3\n expect(\n result[\"ComputeBudget111111111111111111111111111111:2\"]?.[0]?.data,\n ).toBe(\"cb_2\");\n expect(\n result[\"ComputeBudget111111111111111111111111111111:3\"]?.[0]?.data,\n ).toBe(\"cb_3\");\n\n // TokenkegQ has discriminator 3 and 11\n expect(\n result[\"TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA:3\"]?.[0]?.data,\n ).toBe(\"tokenkeg_3\");\n expect(\n result[\"TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA:11\"]?.[0]?.data,\n ).toBe(\"tokenkeg_11\");\n });\n\n it(\"uses :0 suffix for programs without a discriminator\", () => {\n const loader = makeLoader();\n const pluck = (loader as any).pluckTransactionData.bind(loader);\n\n const result: SolanaTransactionDescriptorList = pluck(realApiResponse);\n\n expect(\n result[\"MemoSq4gqABAXKb96qnH8TysNcWxMyWCqXgDLGmfcHr:\"]?.[0]?.data,\n ).toBe(\"memo\");\n expect(\n result[\"3i5JeuZuUxeKtVysUnwQNGerJP2bSMX9fTFfS4Nxe3Br:\"]?.[0]?.data,\n ).toBe(\"3i5jeu\");\n expect(\n result[\"BrdgN2RPzEMWF96ZbnnJaUtQDQx7VRXYaHHbYCBvceWB:\"]?.[0]?.data,\n ).toBe(\"brdg\");\n });\n\n it(\"extracts 12 instruction metadata entries preserving order and discriminators\", () => {\n const loader = makeLoader();\n const extract = (loader as any).extractInstructionsMeta.bind(loader);\n\n const result = extract(realApiResponse);\n\n expect(result).toHaveLength(12);\n\n // First: ATokenGP with discriminator\n expect(result[0]).toEqual({\n program_id: \"ATokenGPvbdGVxr1b2hvZbsiqW5xWH25efTNsLJA8knL\",\n discriminator_hex: \"1\",\n });\n // JUP6 route (8-byte discriminator)\n expect(result[2]).toEqual({\n program_id: \"JUP6LkbZbjS1jKKwapdHNy74zcZ3tLUZoi5QNyVTaV4\",\n discriminator_hex: \"2aade37a97cb17e0\",\n });\n // JUP6 shared (8-byte discriminator)\n expect(result[3]).toEqual({\n program_id: \"JUP6LkbZbjS1jKKwapdHNy74zcZ3tLUZoi5QNyVTaV4\",\n discriminator_hex: \"819cd641339b2148\",\n });\n // Memo: no discriminator\n expect(result[4]).toEqual({\n program_id: \"MemoSq4gqABAXKb96qnH8TysNcWxMyWCqXgDLGmfcHr\",\n });\n // BrdgN2: no discriminator (last entry)\n expect(result[11]).toEqual({\n program_id: \"BrdgN2RPzEMWF96ZbnnJaUtQDQx7VRXYaHHbYCBvceWB\",\n });\n });\n\n it(\"load returns full payload with descriptors and instructions from real API response\", async () => {\n const loader = makeLoader();\n\n vi.spyOn(\n mockDataSource,\n \"getTransactionDescriptorsPayload\",\n ).mockResolvedValue(Right(realApiResponse));\n\n const input = { templateId: \"4c694669\", deviceModelId: \"nanoS\" as any };\n const result = await loader.load(input);\n\n expect(result).toHaveLength(1);\n expect(result[0]).toMatchObject({\n type: ClearSignContextType.SOLANA_LIFI,\n payload: {\n descriptors: expect.objectContaining({\n \"JUP6LkbZbjS1jKKwapdHNy74zcZ3tLUZoi5QNyVTaV4:2aade37a97cb17e0\":\n expect.arrayContaining([\n expect.objectContaining({ data: \"jup_route\" }),\n ]),\n \"JUP6LkbZbjS1jKKwapdHNy74zcZ3tLUZoi5QNyVTaV4:819cd641339b2148\":\n expect.arrayContaining([\n expect.objectContaining({ data: \"jup_shared\" }),\n ]),\n }),\n instructions: expect.arrayContaining([\n expect.objectContaining({\n program_id: \"JUP6LkbZbjS1jKKwapdHNy74zcZ3tLUZoi5QNyVTaV4\",\n discriminator_hex: \"2aade37a97cb17e0\",\n }),\n expect.objectContaining({\n program_id: \"JUP6LkbZbjS1jKKwapdHNy74zcZ3tLUZoi5QNyVTaV4\",\n discriminator_hex: \"819cd641339b2148\",\n }),\n ]),\n },\n });\n\n expect(Object.keys((result[0] as any).payload.descriptors)).toHaveLength(\n 11,\n );\n expect((result[0] as any).payload.instructions).toHaveLength(12);\n });\n });\n});\n"],
5
+ "mappings": "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",
6
+ "names": ["Left", "Right", "beforeEach", "describe", "expect", "it", "vi", "ClearSignContextType", "LifiContextLoader", "mockLoggerFactory", "mockCertificate", "mockConfig", "mockDataSource", "mockCertificateLoader", "makeRawDescriptor", "data", "sig", "makeResolvedDescriptor", "responseDescriptorsArray", "expectedPlucked", "txDescriptorsResponse", "makeLoader", "loader", "error", "input", "result", "pluck", "response", "realApiResponse", "keys"]
7
7
  }
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "version": 3,
3
3
  "sources": ["../../../../../../src/modules/solana/model/SolanaPayloads.ts"],
4
- "sourcesContent": ["// Solana payload types \u2014 used both by Solana loaders and (type-only)\n// referenced by the shared ClearSignContext union for typed-payload variants.\n\nexport type SolanaTokenData = {\n solanaTokenDescriptor: {\n data: string;\n signature: string;\n };\n};\n\nexport type SolanaTransactionDescriptor = {\n data: string;\n descriptorType: string;\n descriptorVersion: string;\n signature: string;\n};\n\nexport type SolanaLifiInstructionMeta = {\n program_id: string;\n discriminator_hex?: string;\n};\n\nexport type SolanaLifiPayload = {\n descriptors: Record<string, SolanaTransactionDescriptor>;\n instructions: SolanaLifiInstructionMeta[];\n};\n\nexport type SolanaTransactionCheckPayload = {\n descriptor: string;\n};\n\n// --- Generic clear-signing payloads ---\n\n// CAL static descriptor payloads. `data` is the signed TLV (hex string);\n// `signature` is the resolved signature for the configured CAL signature\n// kind (`prod` | `test`).\n\nexport type SolanaSignedDescriptor = {\n data: string;\n signature: string;\n};\n\n/**\n * One enum-variant descriptor bundled with an instruction descriptor by CAL.\n * The signed TLV (`descriptor.data`) feeds the host-side type-pool decode\n * cache, `enumId`/`variantIndex` identify which variant it describes (and let\n * the host stream the selected variant's signed descriptor to the device).\n */\nexport type SolanaInstructionEnumVariant = {\n enumId: string;\n variantIndex: number;\n descriptor: SolanaSignedDescriptor;\n};\n\n/**\n * Payload for ClearSignContextType.SOLANA_INSTRUCTION_INFO.\n *\n * `instructionInfo` + `substructures` are the signed TLVs streamed to the\n * device, and `enumVariants` are the signed enum-variant descriptors CAL\n * bundles for the program's enums (used to build the host decode cache). The\n * remaining fields are CAL's decoded JSON consumed host-side by the\n * requirement builder.\n */\nexport type SolanaInstructionInfoPayload = {\n programId: string;\n discriminator: string;\n instructionInfo: SolanaSignedDescriptor;\n substructures: SolanaInstructionSubstructure[];\n enumVariants: SolanaInstructionEnumVariant[];\n idlDescriptor: {\n typePool: SolanaCalTypePoolEntry[];\n rootType: number;\n };\n mintAssociations: SolanaCalMintAssociation[];\n valueFlowPorts: SolanaCalValueFlowPort[];\n accountResets: SolanaCalAccountReset[];\n displayFields: SolanaCalDisplayField[];\n};\n\nexport enum SolanaInstructionSubstructureKind {\n DISPLAY_FIELD = 0x00,\n VALUE_FLOW_PORT = 0x01,\n HIDE_RULE = 0x02,\n ACCOUNT_RESET = 0x03,\n}\n\nexport type SolanaInstructionSubstructure = {\n kind: SolanaInstructionSubstructureKind;\n // TLV payload (hex string) for the substructure.\n data: string;\n};\n\n// --- Decoded CAL JSON (snake_case mirrors the CAL response) ---\n\nexport type SolanaCalValue = {\n source: string;\n /** ACCOUNT_PATH: index into the instruction's accounts. */\n account_index?: number;\n /** CONSTANT: hex-encoded bytes. */\n data?: string;\n /** ARGUMENT_PATH: decoded steps. */\n path?: { steps: number[] };\n};\n\nexport type SolanaCalTokenValue = {\n kind: string;\n value?: SolanaCalValue;\n account_index?: number;\n};\n\nexport type SolanaCalValueFlowPort = {\n /** Ordered candidate list of account indices (length 1 for a single-account port). */\n account_indices: number[];\n optional_account_strategy?: string;\n token_value: SolanaCalTokenValue;\n};\n\nexport type SolanaCalAccountReset = {\n account_index: number;\n require_pre_balance_zero?: boolean;\n};\n\nexport type SolanaCalDisplayField = {\n name?: string;\n param: { type: string; value?: SolanaCalValue; token?: SolanaCalValue };\n};\n\nexport type SolanaCalTypePoolEntry = {\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 SolanaCalMintAssociation = {\n account_index: number;\n mint_index: number;\n};\n\n/**\n * Payload for ClearSignContextType.SOLANA_ENUM_VARIANT: one signed\n * ENUM_VARIANT descriptor for a `(programId, enumId, variantIndex)` triple.\n */\nexport type SolanaEnumVariantPayload = {\n programId: string;\n enumId: string;\n variantIndex: number;\n descriptor: SolanaSignedDescriptor;\n};\n\n/**\n * Payload for ClearSignContextType.SOLANA_TOKEN_INFO, keyed by mint pubkey.\n * Distinct from the legacy SOLANA_TOKEN context.\n */\nexport type SolanaTokenInfoPayload = {\n mint: string;\n descriptor: SolanaSignedDescriptor;\n};\n\n// --- Dynamic descriptor payloads (challenge-bound) ---\n//\n// Each payload carries the raw signed TLV bytes decoded from the backend's\n// hex `signedDescriptor`.\n\nexport type SolanaTokenAccountStatePayload = {\n descriptor: Uint8Array;\n};\n\nexport type SolanaAltResolutionPayload = {\n descriptor: Uint8Array;\n};\n\n// SOLANA_TRUSTED_NAME (generic flow, with 2-byte length prefix) is emitted by\n// SolanaTrustedNameContextLoader. SOLANA_BASIC_TRUSTED_NAME (basic flow, raw\n// bytes) is emitted by OwnerInfoContextLoader. Both carry `payload: Uint8Array`.\n"],
5
- "mappings": "AA+EO,IAAKA,OACVA,IAAA,cAAgB,GAAhB,gBACAA,IAAA,gBAAkB,GAAlB,kBACAA,IAAA,UAAY,GAAZ,YACAA,IAAA,cAAgB,GAAhB,gBAJUA,OAAA",
4
+ "sourcesContent": ["// Solana payload types \u2014 used both by Solana loaders and (type-only)\n// referenced by the shared ClearSignContext union for typed-payload variants.\n\nexport type SolanaTokenData = {\n solanaTokenDescriptor: {\n data: string;\n signature: string;\n };\n};\n\nexport type SolanaTransactionDescriptor = {\n data: string;\n descriptorType: string;\n descriptorVersion: string;\n signature: string;\n has_basis_point?: boolean;\n};\n\nexport type SolanaLifiInstructionMeta = {\n program_id: string;\n discriminator_hex?: string;\n has_basis_point?: boolean;\n};\n\nexport type SolanaLifiPayload = {\n descriptors: Record<string, SolanaTransactionDescriptor[]>;\n instructions: SolanaLifiInstructionMeta[];\n};\n\nexport type SolanaTransactionCheckPayload = {\n descriptor: string;\n};\n\n// --- Generic clear-signing payloads ---\n\n// CAL static descriptor payloads. `data` is the signed TLV (hex string);\n// `signature` is the resolved signature for the configured CAL signature\n// kind (`prod` | `test`).\n\nexport type SolanaSignedDescriptor = {\n data: string;\n signature: string;\n};\n\n/**\n * One enum-variant descriptor bundled with an instruction descriptor by CAL.\n * The signed TLV (`descriptor.data`) feeds the host-side type-pool decode\n * cache, `enumId`/`variantIndex` identify which variant it describes (and let\n * the host stream the selected variant's signed descriptor to the device).\n */\nexport type SolanaInstructionEnumVariant = {\n enumId: string;\n variantIndex: number;\n descriptor: SolanaSignedDescriptor;\n};\n\n/**\n * Payload for ClearSignContextType.SOLANA_INSTRUCTION_INFO.\n *\n * `instructionInfo` + `substructures` are the signed TLVs streamed to the\n * device, and `enumVariants` are the signed enum-variant descriptors CAL\n * bundles for the program's enums (used to build the host decode cache). The\n * remaining fields are CAL's decoded JSON consumed host-side by the\n * requirement builder.\n */\nexport type SolanaInstructionInfoPayload = {\n programId: string;\n discriminator: string;\n instructionInfo: SolanaSignedDescriptor;\n substructures: SolanaInstructionSubstructure[];\n enumVariants: SolanaInstructionEnumVariant[];\n idlDescriptor: {\n typePool: SolanaCalTypePoolEntry[];\n rootType: number;\n };\n mintAssociations: SolanaCalMintAssociation[];\n valueFlowPorts: SolanaCalValueFlowPort[];\n accountResets: SolanaCalAccountReset[];\n displayFields: SolanaCalDisplayField[];\n};\n\nexport enum SolanaInstructionSubstructureKind {\n DISPLAY_FIELD = 0x00,\n VALUE_FLOW_PORT = 0x01,\n HIDE_RULE = 0x02,\n ACCOUNT_RESET = 0x03,\n}\n\nexport type SolanaInstructionSubstructure = {\n kind: SolanaInstructionSubstructureKind;\n // TLV payload (hex string) for the substructure.\n data: string;\n};\n\n// --- Decoded CAL JSON (snake_case mirrors the CAL response) ---\n\nexport type SolanaCalValue = {\n source: string;\n /** ACCOUNT_PATH: index into the instruction's accounts. */\n account_index?: number;\n /** CONSTANT: hex-encoded bytes. */\n data?: string;\n /** ARGUMENT_PATH: decoded steps. */\n path?: { steps: number[] };\n};\n\nexport type SolanaCalTokenValue = {\n kind: string;\n value?: SolanaCalValue;\n account_index?: number;\n};\n\nexport type SolanaCalValueFlowPort = {\n /** Ordered candidate list of account indices (length 1 for a single-account port). */\n account_indices: number[];\n optional_account_strategy?: string;\n token_value: SolanaCalTokenValue;\n};\n\nexport type SolanaCalAccountReset = {\n account_index: number;\n require_pre_balance_zero?: boolean;\n};\n\nexport type SolanaCalDisplayField = {\n name?: string;\n param: { type: string; value?: SolanaCalValue; token?: SolanaCalValue };\n};\n\nexport type SolanaCalTypePoolEntry = {\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 SolanaCalMintAssociation = {\n account_index: number;\n mint_index: number;\n};\n\n/**\n * Payload for ClearSignContextType.SOLANA_ENUM_VARIANT: one signed\n * ENUM_VARIANT descriptor for a `(programId, enumId, variantIndex)` triple.\n */\nexport type SolanaEnumVariantPayload = {\n programId: string;\n enumId: string;\n variantIndex: number;\n descriptor: SolanaSignedDescriptor;\n};\n\n/**\n * Payload for ClearSignContextType.SOLANA_TOKEN_INFO, keyed by mint pubkey.\n * Distinct from the legacy SOLANA_TOKEN context.\n */\nexport type SolanaTokenInfoPayload = {\n mint: string;\n descriptor: SolanaSignedDescriptor;\n};\n\n// --- Dynamic descriptor payloads (challenge-bound) ---\n//\n// Each payload carries the raw signed TLV bytes decoded from the backend's\n// hex `signedDescriptor`.\n\nexport type SolanaTokenAccountStatePayload = {\n descriptor: Uint8Array;\n mint?: string;\n};\n\nexport type SolanaAltResolutionPayload = {\n descriptor: Uint8Array;\n resolvedAddress?: string;\n};\n\n// SOLANA_TRUSTED_NAME (generic flow, with 2-byte length prefix) is emitted by\n// SolanaTrustedNameContextLoader. SOLANA_BASIC_TRUSTED_NAME (basic flow, raw\n// bytes) is emitted by OwnerInfoContextLoader. Both carry `payload: Uint8Array`.\n"],
5
+ "mappings": "AAiFO,IAAKA,OACVA,IAAA,cAAgB,GAAhB,gBACAA,IAAA,gBAAkB,GAAlB,kBACAA,IAAA,UAAY,GAAZ,YACAA,IAAA,cAAgB,GAAhB,gBAJUA,OAAA",
6
6
  "names": ["SolanaInstructionSubstructureKind"]
7
7
  }
@@ -1,2 +1,2 @@
1
- var w=Object.defineProperty;var m=Object.getOwnPropertyDescriptor;var u=(i,e,n,t)=>{for(var r=t>1?void 0:t?m(e,n):e,o=i.length-1,s;o>=0;o--)(s=i[o])&&(r=(t?s(e,n,r):s(r))||r);return t&&r&&w(e,n,r),r},d=(i,e)=>(n,t)=>e(n,t,i);import{hexaStringToBuffer as S}from"@ledgerhq/device-management-kit";import{inject as p,injectable as h}from"inversify";import{Left as a,Right as f}from"purify-ts";import{configTypes as g}from"../../../../config/di/configTypes";import{networkTypes as I}from"../../../../shared/network/di/networkTypes";let c=class{constructor(e,n){this.config=e;this.http=n;if(!this.config.originToken)throw new Error("[ContextModule] - HttpOwnerInfoDataSource: origin token is required")}isSolanaSPLOwnerInfo(e){return typeof e!="object"||e===null?!1:typeof e.tokenAccount=="string"&&typeof e.owner=="string"&&typeof e.contract=="string"&&typeof e.signedDescriptor=="string"}async fetchAddressMetadata(e,n){try{const t=await this.http.get(`${this.config.metadataServiceDomain.url}/v2/solana/owner/${e}`,{params:{challenge:n}});return this.isSolanaSPLOwnerInfo(t)?f(t):a(new Error("[ContextModule] - HttpOwnerInfoDataSource: invalid fetchAddressMetadata response shape"))}catch{return a(new Error("[ContextModule] - HttpOwnerInfoDataSource: Failed to fetch address metadata"))}}async computeAddressMetadata(e,n,t){try{const r=await this.http.get(`${this.config.metadataServiceDomain.url}/v2/solana/computed-token-account/${e}/${n}`,{params:{challenge:t}});return this.isSolanaSPLOwnerInfo(r)?f(r):a(new Error("[ContextModule] - HttpOwnerInfoDataSource: invalid computeAddressMetadata response shape"))}catch{return a(new Error("[ContextModule] - HttpOwnerInfoDataSource: Failed to compute address metadata"))}}async getOwnerInfo(e){const{tokenAddress:n,challenge:t,createATA:r}=e;if(!t)return a(new Error("[ContextModule] - HttpOwnerInfoDataSource: challenge is required"));let o;if(n)o=await this.fetchAddressMetadata(n,t);else if(r?.address&&r?.mintAddress)o=await this.computeAddressMetadata(r.address,r.mintAddress,t);else return a(new Error("[ContextModule] - HttpOwnerInfoDataSource: either tokenAddress or valid createATA must be provided"));return o.chain(s=>{const l=S(s.signedDescriptor);return l?f({tlvDescriptor:l}):a(new Error("[ContextModule] - HttpOwnerInfoDataSource: invalid base64 tlvDescriptor received"))})}};c=u([h(),d(0,p(g.Config)),d(1,p(I.NetworkClient))],c);export{c as HttpOwnerInfoDataSource};
1
+ var w=Object.defineProperty;var m=Object.getOwnPropertyDescriptor;var u=(i,e,n,t)=>{for(var r=t>1?void 0:t?m(e,n):e,o=i.length-1,s;o>=0;o--)(s=i[o])&&(r=(t?s(e,n,r):s(r))||r);return t&&r&&w(e,n,r),r},d=(i,e)=>(n,t)=>e(n,t,i);import{hexaStringToBuffer as S}from"@ledgerhq/device-management-kit";import{inject as p,injectable as h}from"inversify";import{Left as a,Right as f}from"purify-ts";import{configTypes as g}from"../../../../config/di/configTypes";import{networkTypes as I}from"../../../../shared/network/di/networkTypes";let c=class{constructor(e,n){this.config=e;this.http=n}isSolanaSPLOwnerInfo(e){return typeof e!="object"||e===null?!1:typeof e.tokenAccount=="string"&&typeof e.owner=="string"&&typeof e.contract=="string"&&typeof e.signedDescriptor=="string"}async fetchAddressMetadata(e,n){try{const t=await this.http.get(`${this.config.metadataServiceDomain.url}/v2/solana/owner/${e}`,{params:{challenge:n}});return this.isSolanaSPLOwnerInfo(t)?f(t):a(new Error("[ContextModule] - HttpOwnerInfoDataSource: invalid fetchAddressMetadata response shape"))}catch{return a(new Error("[ContextModule] - HttpOwnerInfoDataSource: Failed to fetch address metadata"))}}async computeAddressMetadata(e,n,t){try{const r=await this.http.get(`${this.config.metadataServiceDomain.url}/v2/solana/computed-token-account/${e}/${n}`,{params:{challenge:t}});return this.isSolanaSPLOwnerInfo(r)?f(r):a(new Error("[ContextModule] - HttpOwnerInfoDataSource: invalid computeAddressMetadata response shape"))}catch{return a(new Error("[ContextModule] - HttpOwnerInfoDataSource: Failed to compute address metadata"))}}async getOwnerInfo(e){const{tokenAddress:n,challenge:t,createATA:r}=e;if(!t)return a(new Error("[ContextModule] - HttpOwnerInfoDataSource: challenge is required"));let o;if(n)o=await this.fetchAddressMetadata(n,t);else if(r?.address&&r?.mintAddress)o=await this.computeAddressMetadata(r.address,r.mintAddress,t);else return a(new Error("[ContextModule] - HttpOwnerInfoDataSource: either tokenAddress or valid createATA must be provided"));return o.chain(s=>{const l=S(s.signedDescriptor);return l?f({tlvDescriptor:l}):a(new Error("[ContextModule] - HttpOwnerInfoDataSource: invalid base64 tlvDescriptor received"))})}};c=u([h(),d(0,p(g.Config)),d(1,p(I.NetworkClient))],c);export{c as HttpOwnerInfoDataSource};
2
2
  //# sourceMappingURL=HttpOwnerInfoDataSource.js.map