@ledgerhq/context-module 0.0.0-develop-20260702003423 → 0.0.0-develop-20260703002922

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 (67) hide show
  1. package/lib/cjs/package.json +1 -1
  2. package/lib/cjs/src/modules/solana/enum-variant/domain/EnumVariantContextLoader.js +1 -1
  3. package/lib/cjs/src/modules/solana/enum-variant/domain/EnumVariantContextLoader.js.map +3 -3
  4. package/lib/cjs/src/modules/solana/enum-variant/domain/EnumVariantContextLoader.test.js +1 -1
  5. package/lib/cjs/src/modules/solana/enum-variant/domain/EnumVariantContextLoader.test.js.map +3 -3
  6. package/lib/cjs/src/modules/solana/instruction-info/data/HttpInstructionInfoDataSource.js +1 -1
  7. package/lib/cjs/src/modules/solana/instruction-info/data/HttpInstructionInfoDataSource.js.map +3 -3
  8. package/lib/cjs/src/modules/solana/instruction-info/data/HttpInstructionInfoDataSource.test.js +1 -1
  9. package/lib/cjs/src/modules/solana/instruction-info/data/HttpInstructionInfoDataSource.test.js.map +3 -3
  10. package/lib/cjs/src/modules/solana/instruction-info/data/InstructionInfoDataSource.js +1 -1
  11. package/lib/cjs/src/modules/solana/instruction-info/data/InstructionInfoDataSource.js.map +1 -1
  12. package/lib/cjs/src/modules/solana/instruction-info/data/InstructionInfoDto.js +1 -1
  13. package/lib/cjs/src/modules/solana/instruction-info/data/InstructionInfoDto.js.map +2 -2
  14. package/lib/cjs/src/modules/solana/instruction-info/data/InstructionInfoMapper.js +2 -0
  15. package/lib/cjs/src/modules/solana/instruction-info/data/InstructionInfoMapper.js.map +7 -0
  16. package/lib/cjs/src/modules/solana/instruction-info/data/InstructionInfoMapper.test.js +2 -0
  17. package/lib/cjs/src/modules/solana/instruction-info/data/InstructionInfoMapper.test.js.map +7 -0
  18. package/lib/cjs/src/modules/solana/instruction-info/domain/InstructionInfoContextLoader.js +1 -1
  19. package/lib/cjs/src/modules/solana/instruction-info/domain/InstructionInfoContextLoader.js.map +3 -3
  20. package/lib/cjs/src/modules/solana/instruction-info/domain/InstructionInfoContextLoader.test.js +1 -1
  21. package/lib/cjs/src/modules/solana/instruction-info/domain/InstructionInfoContextLoader.test.js.map +3 -3
  22. package/lib/cjs/src/modules/solana/model/SolanaClearSignContext.js +1 -1
  23. package/lib/cjs/src/modules/solana/model/SolanaClearSignContext.js.map +2 -2
  24. package/lib/cjs/src/modules/solana/model/SolanaPayloads.js +1 -1
  25. package/lib/cjs/src/modules/solana/model/SolanaPayloads.js.map +2 -2
  26. package/lib/esm/package.json +1 -1
  27. package/lib/esm/src/modules/solana/enum-variant/domain/EnumVariantContextLoader.js +1 -1
  28. package/lib/esm/src/modules/solana/enum-variant/domain/EnumVariantContextLoader.js.map +3 -3
  29. package/lib/esm/src/modules/solana/enum-variant/domain/EnumVariantContextLoader.test.js +1 -1
  30. package/lib/esm/src/modules/solana/enum-variant/domain/EnumVariantContextLoader.test.js.map +3 -3
  31. package/lib/esm/src/modules/solana/instruction-info/data/HttpInstructionInfoDataSource.js +1 -1
  32. package/lib/esm/src/modules/solana/instruction-info/data/HttpInstructionInfoDataSource.js.map +3 -3
  33. package/lib/esm/src/modules/solana/instruction-info/data/HttpInstructionInfoDataSource.test.js +1 -1
  34. package/lib/esm/src/modules/solana/instruction-info/data/HttpInstructionInfoDataSource.test.js.map +3 -3
  35. package/lib/esm/src/modules/solana/instruction-info/data/InstructionInfoDto.js +1 -1
  36. package/lib/esm/src/modules/solana/instruction-info/data/InstructionInfoDto.js.map +2 -2
  37. package/lib/esm/src/modules/solana/instruction-info/data/InstructionInfoMapper.js +2 -0
  38. package/lib/esm/src/modules/solana/instruction-info/data/InstructionInfoMapper.js.map +7 -0
  39. package/lib/esm/src/modules/solana/instruction-info/data/InstructionInfoMapper.test.js +2 -0
  40. package/lib/esm/src/modules/solana/instruction-info/data/InstructionInfoMapper.test.js.map +7 -0
  41. package/lib/esm/src/modules/solana/instruction-info/domain/InstructionInfoContextLoader.js +1 -1
  42. package/lib/esm/src/modules/solana/instruction-info/domain/InstructionInfoContextLoader.js.map +3 -3
  43. package/lib/esm/src/modules/solana/instruction-info/domain/InstructionInfoContextLoader.test.js +1 -1
  44. package/lib/esm/src/modules/solana/instruction-info/domain/InstructionInfoContextLoader.test.js.map +3 -3
  45. package/lib/esm/src/modules/solana/model/SolanaClearSignContext.js +1 -1
  46. package/lib/esm/src/modules/solana/model/SolanaClearSignContext.js.map +2 -2
  47. package/lib/esm/src/modules/solana/model/SolanaPayloads.js +1 -1
  48. package/lib/esm/src/modules/solana/model/SolanaPayloads.js.map +2 -2
  49. package/lib/types/src/modules/solana/enum-variant/domain/EnumVariantContextLoader.d.ts +4 -4
  50. package/lib/types/src/modules/solana/enum-variant/domain/EnumVariantContextLoader.d.ts.map +1 -1
  51. package/lib/types/src/modules/solana/instruction-info/data/HttpInstructionInfoDataSource.d.ts.map +1 -1
  52. package/lib/types/src/modules/solana/instruction-info/data/InstructionInfoDataSource.d.ts +13 -4
  53. package/lib/types/src/modules/solana/instruction-info/data/InstructionInfoDataSource.d.ts.map +1 -1
  54. package/lib/types/src/modules/solana/instruction-info/data/InstructionInfoDto.d.ts +54 -5
  55. package/lib/types/src/modules/solana/instruction-info/data/InstructionInfoDto.d.ts.map +1 -1
  56. package/lib/types/src/modules/solana/instruction-info/data/InstructionInfoMapper.d.ts +23 -0
  57. package/lib/types/src/modules/solana/instruction-info/data/InstructionInfoMapper.d.ts.map +1 -0
  58. package/lib/types/src/modules/solana/instruction-info/data/InstructionInfoMapper.test.d.ts +2 -0
  59. package/lib/types/src/modules/solana/instruction-info/data/InstructionInfoMapper.test.d.ts.map +1 -0
  60. package/lib/types/src/modules/solana/instruction-info/domain/InstructionInfoContextLoader.d.ts +1 -5
  61. package/lib/types/src/modules/solana/instruction-info/domain/InstructionInfoContextLoader.d.ts.map +1 -1
  62. package/lib/types/src/modules/solana/model/SolanaClearSignContext.d.ts +1 -1
  63. package/lib/types/src/modules/solana/model/SolanaClearSignContext.d.ts.map +1 -1
  64. package/lib/types/src/modules/solana/model/SolanaPayloads.d.ts +68 -4
  65. package/lib/types/src/modules/solana/model/SolanaPayloads.d.ts.map +1 -1
  66. package/lib/types/tsconfig.prod.tsbuildinfo +1 -1
  67. package/package.json +5 -5
@@ -58,5 +58,5 @@
58
58
  "watch:builds": "pnpm ldmk-tool watch --entryPoints index.ts,src/**/*.ts --tsconfig tsconfig.prod.json",
59
59
  "watch:types": "concurrently \"tsc --watch -p tsconfig.prod.json\" \"tsc-alias --watch -p tsconfig.prod.json\""
60
60
  },
61
- "version": "0.0.0-develop-20260702003423"
61
+ "version": "0.0.0-develop-20260703002922"
62
62
  }
@@ -1,2 +1,2 @@
1
- "use strict";var f=Object.defineProperty;var R=Object.getOwnPropertyDescriptor;var O=Object.getOwnPropertyNames;var b=Object.prototype.hasOwnProperty;var _=(o,e)=>{for(var n in e)f(o,n,{get:e[n],enumerable:!0})},U=(o,e,n,a)=>{if(e&&typeof e=="object"||typeof e=="function")for(let t of O(e))!b.call(o,t)&&t!==n&&f(o,t,{get:()=>e[t],enumerable:!(a=R(e,t))||a.enumerable});return o};var D=o=>U(f({},"__esModule",{value:!0}),o),h=(o,e,n,a)=>{for(var t=a>1?void 0:a?R(e,n):e,s=o.length-1,i;s>=0;s--)(i=o[s])&&(t=(a?i(e,n,t):i(t))||t);return a&&t&&f(e,n,t),t},p=(o,e)=>(n,a)=>e(n,a,o);var H={};_(H,{EnumVariantContextLoader:()=>c});module.exports=D(H);var g=require("inversify"),d=require("purify-ts"),x=require("../../../../config/di/configTypes"),A=require("../../../../modules/multichain/pki/di/pkiTypes"),M=require("../../../../modules/multichain/pki/model/KeyId"),L=require("../../../../modules/multichain/pki/model/KeyUsage"),V=require("../../../../modules/solana/instruction-info/di/instructionInfoTypes"),m=require("../../../../shared/model/ClearSignContext"),T=require("../../../../shared/utils/certificateResult"),N=require("../../../../shared/utils/deviceModelIdCodec"),S=require("../../../../shared/utils/uIntCodec");const $=[m.ClearSignContextType.SOLANA_ENUM_VARIANT],j="solana-mainnet",K=d.Codec.interface({programId:d.string,enumId:d.string,variantIndex:S.u16Codec}),F=d.Codec.interface({deviceModelId:N.deviceModelIdCodec,selections:(0,d.array)(K),network:(0,d.optional)(d.string)});let c=class{constructor(e,n,a,t){this.dataSource=e;this.config=n;this.certificateLoader=a;this.logger=t("EnumVariantContextLoader")}logger;canHandle(e,n){return $.every(a=>n.includes(a))?F.decode(e).caseOf({Left:()=>!1,Right:({selections:a})=>a.length>0&&a.every(t=>t.programId.length>0&&t.enumId.length>0)}):!1}async load(e){const n=e.network||j,a=Array.from(new Set(e.selections.map(r=>r.programId)));this.logger.debug("[load] Fetching enum variants",{data:{network:n,programCount:a.length,selectionCount:e.selections.length}});const t=(0,T.loadCertificateResult)(this.certificateLoader,{keyId:M.KeyId.TokenMetadataKey,keyUsage:L.KeyUsage.CoinMeta,targetDevice:e.deviceModelId}),s=Promise.all(a.map(r=>this.dataSource.getInstructionInfo({programId:r,network:n}))),[i,I]=await Promise.all([t,s]);if(!i.ok||!i.value){const r=i.ok?new Error("[ContextModule] EnumVariantContextLoader: certificate is missing"):i.error;return this.logger.warn("[load] ENUM_VARIANT certificate unavailable",{data:{error:r.message}}),e.selections.map(()=>({type:m.ClearSignContextType.ERROR,error:r}))}const w=i.value,P=new Map(a.map((r,l)=>[r,I[l]])),C=this.config.cal.mode??"prod";return e.selections.map(r=>{const l=P.get(r.programId);if(!l){const u=new Error(`[ContextModule] EnumVariantContextLoader: no CAL response for program ${r.programId}`);return this.logger.warn("[load] ENUM_VARIANT fetch failed",{data:{programId:r.programId,enumId:r.enumId,variantIndex:r.variantIndex,error:u.message}}),{type:m.ClearSignContextType.ERROR,error:u}}return l.caseOf({Left:u=>(this.logger.warn("[load] ENUM_VARIANT fetch failed",{data:{programId:r.programId,enumId:r.enumId,variantIndex:r.variantIndex,error:u.message}}),{type:m.ClearSignContextType.ERROR,error:u}),Right:u=>{const v=this.lookupVariant(u,r);if(!v){const y=new Error(`[ContextModule] EnumVariantContextLoader: CAL has no enum variant for (${r.programId}, ${r.enumId}, ${r.variantIndex})`);return this.logger.warn("[load] ENUM_VARIANT not found in CAL response",{data:{programId:r.programId,enumId:r.enumId,variantIndex:r.variantIndex}}),{type:m.ClearSignContextType.ERROR,error:y}}const E=v.signatures[C];if(!E){const y=new Error(`[ContextModule] EnumVariantContextLoader: missing '${C}' signature for (${r.programId}, ${r.enumId}, ${r.variantIndex})`);return this.logger.warn("[load] ENUM_VARIANT missing signature",{data:{programId:r.programId,enumId:r.enumId,variantIndex:r.variantIndex,mode:C}}),{type:m.ClearSignContextType.ERROR,error:y}}const k={programId:r.programId,enumId:r.enumId,variantIndex:r.variantIndex,descriptor:{data:v.data,signature:E}};return{type:m.ClearSignContextType.SOLANA_ENUM_VARIANT,payload:k,certificate:w}}})})}lookupVariant(e,n){for(const a of Object.values(e.descriptors)){const t=a.enum_variants?.[n.enumId];if(t)for(const[s,i]of Object.entries(t)){const I=S.u16Codec.decode(Number(s));if(!I.isLeft()&&I.extract()===n.variantIndex)return i}}}};c=h([(0,g.injectable)(),p(0,(0,g.inject)(V.instructionInfoTypes.InstructionInfoDataSource)),p(1,(0,g.inject)(x.configTypes.Config)),p(2,(0,g.inject)(A.pkiTypes.PkiCertificateLoader)),p(3,(0,g.inject)(x.configTypes.ContextModuleLoggerFactory))],c);0&&(module.exports={EnumVariantContextLoader});
1
+ "use strict";var l=Object.defineProperty;var x=Object.getOwnPropertyDescriptor;var k=Object.getOwnPropertyNames;var O=Object.prototype.hasOwnProperty;var U=(o,e)=>{for(var n in e)l(o,n,{get:e[n],enumerable:!0})},_=(o,e,n,t)=>{if(e&&typeof e=="object"||typeof e=="function")for(let a of k(e))!O.call(o,a)&&a!==n&&l(o,a,{get:()=>e[a],enumerable:!(t=x(e,a))||t.enumerable});return o};var b=o=>_(l({},"__esModule",{value:!0}),o),S=(o,e,n,t)=>{for(var a=t>1?void 0:t?x(e,n):e,s=o.length-1,d;s>=0;s--)(d=o[s])&&(a=(t?d(e,n,a):d(a))||a);return t&&a&&l(e,n,a),a},g=(o,e)=>(n,t)=>e(n,t,o);var j={};U(j,{EnumVariantContextLoader:()=>I});module.exports=b(j);var p=require("inversify"),i=require("purify-ts"),y=require("../../../../config/di/configTypes"),E=require("../../../../modules/multichain/pki/di/pkiTypes"),R=require("../../../../modules/multichain/pki/model/KeyId"),h=require("../../../../modules/multichain/pki/model/KeyUsage"),V=require("../../../../modules/solana/instruction-info/di/instructionInfoTypes"),m=require("../../../../shared/model/ClearSignContext"),A=require("../../../../shared/utils/certificateResult"),M=require("../../../../shared/utils/deviceModelIdCodec"),L=require("../../../../shared/utils/uIntCodec");const D=[m.ClearSignContextType.SOLANA_ENUM_VARIANT],$="solana-mainnet",K=i.Codec.interface({programId:i.string,enumId:i.string,variantIndex:L.u16Codec}),F=i.Codec.interface({deviceModelId:M.deviceModelIdCodec,selections:(0,i.array)(K),network:(0,i.optional)(i.string)});let I=class{constructor(e,n,t,a){this.dataSource=e;this.config=n;this.certificateLoader=t;this.logger=a("EnumVariantContextLoader")}logger;canHandle(e,n){return D.every(t=>n.includes(t))?F.decode(e).caseOf({Left:()=>!1,Right:({selections:t})=>t.length>0&&t.every(a=>a.programId.length>0&&a.enumId.length>0)}):!1}async load(e){const n=e.network||$,t=Array.from(new Set(e.selections.map(r=>r.programId)));this.logger.debug("[load] Fetching enum variants",{data:{network:n,programCount:t.length,selectionCount:e.selections.length}});const a=(0,A.loadCertificateResult)(this.certificateLoader,{keyId:R.KeyId.TokenMetadataKey,keyUsage:h.KeyUsage.CoinMeta,targetDevice:e.deviceModelId}),s=Promise.all(t.map(r=>this.dataSource.getInstructionInfo({programId:r,network:n}))),[d,T]=await Promise.all([a,s]);if(!d.ok||!d.value){const r=d.ok?new Error("[ContextModule] EnumVariantContextLoader: certificate is missing"):d.error;return this.logger.warn("[load] ENUM_VARIANT certificate unavailable",{data:{error:r.message}}),e.selections.map(()=>({type:m.ClearSignContextType.ERROR,error:r}))}const w=d.value,N=new Map(t.map((r,c)=>[r,T[c]])),v=this.config.cal.mode??"prod";return e.selections.map(r=>{const c=N.get(r.programId);if(!c){const u=new Error(`[ContextModule] EnumVariantContextLoader: no CAL response for program ${r.programId}`);return this.logger.warn("[load] ENUM_VARIANT fetch failed",{data:{programId:r.programId,enumId:r.enumId,variantIndex:r.variantIndex,error:u.message}}),{type:m.ClearSignContextType.ERROR,error:u}}return c.caseOf({Left:u=>(this.logger.warn("[load] ENUM_VARIANT fetch failed",{data:{programId:r.programId,enumId:r.enumId,variantIndex:r.variantIndex,error:u.message}}),{type:m.ClearSignContextType.ERROR,error:u}),Right:u=>{const f=this.lookupVariant(u,r);if(!f){const C=new Error(`[ContextModule] EnumVariantContextLoader: CAL has no enum variant for (${r.programId}, ${r.enumId}, ${r.variantIndex})`);return this.logger.warn("[load] ENUM_VARIANT not found in CAL response",{data:{programId:r.programId,enumId:r.enumId,variantIndex:r.variantIndex}}),{type:m.ClearSignContextType.ERROR,error:C}}if(!f.descriptor.signature){const C=new Error(`[ContextModule] EnumVariantContextLoader: missing '${v}' signature for (${r.programId}, ${r.enumId}, ${r.variantIndex})`);return this.logger.warn("[load] ENUM_VARIANT missing signature",{data:{programId:r.programId,enumId:r.enumId,variantIndex:r.variantIndex,mode:v}}),{type:m.ClearSignContextType.ERROR,error:C}}const P={programId:r.programId,enumId:r.enumId,variantIndex:r.variantIndex,descriptor:f.descriptor};return{type:m.ClearSignContextType.SOLANA_ENUM_VARIANT,payload:P,certificate:w}}})})}lookupVariant(e,n){return e.enumVariants.find(t=>t.enumId===n.enumId&&t.variantIndex===n.variantIndex)}};I=S([(0,p.injectable)(),g(0,(0,p.inject)(V.instructionInfoTypes.InstructionInfoDataSource)),g(1,(0,p.inject)(y.configTypes.Config)),g(2,(0,p.inject)(E.pkiTypes.PkiCertificateLoader)),g(3,(0,p.inject)(y.configTypes.ContextModuleLoggerFactory))],I);0&&(module.exports={EnumVariantContextLoader});
2
2
  //# sourceMappingURL=EnumVariantContextLoader.js.map
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "version": 3,
3
3
  "sources": ["../../../../../../../src/modules/solana/enum-variant/domain/EnumVariantContextLoader.ts"],
4
- "sourcesContent": ["import {\n type DeviceModelId,\n type LoggerPublisherService,\n} from \"@ledgerhq/device-management-kit\";\nimport { inject, injectable } from \"inversify\";\nimport { array, Codec, optional, string } from \"purify-ts\";\n\nimport { configTypes } from \"@/config/di/configTypes\";\nimport { type ContextModuleServiceConfig } from \"@/config/model/ContextModuleConfig\";\nimport { pkiTypes } from \"@/modules/multichain/pki/di/pkiTypes\";\nimport { type PkiCertificateLoader } from \"@/modules/multichain/pki/domain/PkiCertificateLoader\";\nimport { KeyId } from \"@/modules/multichain/pki/model/KeyId\";\nimport { KeyUsage } from \"@/modules/multichain/pki/model/KeyUsage\";\nimport {\n type InstructionInfoDataSource,\n type InstructionInfoResult,\n} from \"@/modules/solana/instruction-info/data/InstructionInfoDataSource\";\nimport { type CalSignatures } from \"@/modules/solana/instruction-info/data/InstructionInfoDto\";\nimport { instructionInfoTypes } from \"@/modules/solana/instruction-info/di/instructionInfoTypes\";\nimport { type SolanaEnumVariantPayload } from \"@/modules/solana/model/SolanaPayloads\";\nimport { type ContextLoader } from \"@/shared/domain/ContextLoader\";\nimport {\n type ClearSignContext,\n ClearSignContextType,\n} from \"@/shared/model/ClearSignContext\";\nimport { loadCertificateResult } from \"@/shared/utils/certificateResult\";\nimport { deviceModelIdCodec } from \"@/shared/utils/deviceModelIdCodec\";\nimport { u16Codec } from \"@/shared/utils/uIntCodec\";\n\nconst SUPPORTED_TYPES: ClearSignContextType[] = [\n ClearSignContextType.SOLANA_ENUM_VARIANT,\n];\n\nconst NETWORK_DEFAULT = \"solana-mainnet\";\n\n/**\n * One enum-variant selection the caller wants resolved. `variantIndex` is\n * constrained to a u16 (0..=65535).\n */\nexport type SolanaEnumVariantSelection = {\n programId: string;\n enumId: string;\n variantIndex: number;\n};\n\nexport type SolanaEnumVariantContextInput = {\n deviceModelId: DeviceModelId;\n selections: SolanaEnumVariantSelection[];\n network?: string;\n};\n\nconst enumVariantSelectionCodec = Codec.interface({\n programId: string,\n enumId: string,\n variantIndex: u16Codec,\n});\n\nconst solanaEnumVariantInputCodec = Codec.interface({\n deviceModelId: deviceModelIdCodec,\n selections: array(enumVariantSelectionCodec),\n network: optional(string),\n});\n\n/**\n * Emits one SOLANA_ENUM_VARIANT context per `(programId, enumId,\n * variantIndex)` selection: fetches the CAL response for each distinct\n * program, looks up the matching variant, and emits only the selected ones.\n *\n * Shares {@link InstructionInfoDataSource} with\n * {@link InstructionInfoContextLoader}.\n */\n@injectable()\nexport class EnumVariantContextLoader\n implements ContextLoader<SolanaEnumVariantContextInput>\n{\n private readonly logger: LoggerPublisherService;\n\n constructor(\n @inject(instructionInfoTypes.InstructionInfoDataSource)\n private readonly dataSource: InstructionInfoDataSource,\n @inject(configTypes.Config)\n private readonly config: ContextModuleServiceConfig,\n @inject(pkiTypes.PkiCertificateLoader)\n private readonly certificateLoader: PkiCertificateLoader,\n @inject(configTypes.ContextModuleLoggerFactory)\n loggerFactory: (tag: string) => LoggerPublisherService,\n ) {\n this.logger = loggerFactory(\"EnumVariantContextLoader\");\n }\n\n public canHandle(\n input: unknown,\n expectedTypes: ClearSignContextType[],\n ): input is SolanaEnumVariantContextInput {\n if (!SUPPORTED_TYPES.every((t) => expectedTypes.includes(t))) return false;\n return solanaEnumVariantInputCodec.decode(input).caseOf({\n Left: () => false,\n Right: ({ selections }) =>\n selections.length > 0 &&\n selections.every((s) => s.programId.length > 0 && s.enumId.length > 0),\n });\n }\n\n public async load(\n input: SolanaEnumVariantContextInput,\n ): Promise<ClearSignContext[]> {\n const network = input.network || NETWORK_DEFAULT;\n const distinctProgramIds = Array.from(\n new Set(input.selections.map((s) => s.programId)),\n );\n\n this.logger.debug(\"[load] Fetching enum variants\", {\n data: {\n network,\n programCount: distinctProgramIds.length,\n selectionCount: input.selections.length,\n },\n });\n\n // Cert load and CAL fetches are independent \u2014 run them in parallel. A\n // PKI failure still degrades each selection to ERROR.\n const certPromise = loadCertificateResult(this.certificateLoader, {\n keyId: KeyId.TokenMetadataKey,\n keyUsage: KeyUsage.CoinMeta,\n targetDevice: input.deviceModelId,\n });\n\n const dataPromise = Promise.all(\n distinctProgramIds.map((programId) =>\n this.dataSource.getInstructionInfo({ programId, network }),\n ),\n );\n\n const [certResult, results] = await Promise.all([certPromise, dataPromise]);\n\n if (!certResult.ok || !certResult.value) {\n const error = certResult.ok\n ? new Error(\n \"[ContextModule] EnumVariantContextLoader: certificate is missing\",\n )\n : certResult.error;\n this.logger.warn(\"[load] ENUM_VARIANT certificate unavailable\", {\n data: { error: error.message },\n });\n return input.selections.map(() => ({\n type: ClearSignContextType.ERROR,\n error,\n }));\n }\n const certificate = certResult.value;\n\n const programToEither = new Map(\n distinctProgramIds.map((programId, i) => [programId, results[i]!]),\n );\n\n const mode = this.config.cal.mode ?? \"prod\";\n\n return input.selections.map((selection) => {\n const either = programToEither.get(selection.programId);\n if (!either) {\n const error = new Error(\n `[ContextModule] EnumVariantContextLoader: no CAL response for program ${selection.programId}`,\n );\n this.logger.warn(\"[load] ENUM_VARIANT fetch failed\", {\n data: {\n programId: selection.programId,\n enumId: selection.enumId,\n variantIndex: selection.variantIndex,\n error: error.message,\n },\n });\n return { type: ClearSignContextType.ERROR, error };\n }\n\n return either.caseOf<ClearSignContext>({\n Left: (err) => {\n this.logger.warn(\"[load] ENUM_VARIANT fetch failed\", {\n data: {\n programId: selection.programId,\n enumId: selection.enumId,\n variantIndex: selection.variantIndex,\n error: err.message,\n },\n });\n return { type: ClearSignContextType.ERROR, error: err };\n },\n Right: (value) => {\n const variant = this.lookupVariant(value, selection);\n if (!variant) {\n const error = new Error(\n `[ContextModule] EnumVariantContextLoader: CAL has no enum variant for (${selection.programId}, ${selection.enumId}, ${selection.variantIndex})`,\n );\n this.logger.warn(\"[load] ENUM_VARIANT not found in CAL response\", {\n data: {\n programId: selection.programId,\n enumId: selection.enumId,\n variantIndex: selection.variantIndex,\n },\n });\n return { type: ClearSignContextType.ERROR, error };\n }\n\n const signature = variant.signatures[mode];\n if (!signature) {\n const error = new Error(\n `[ContextModule] EnumVariantContextLoader: missing '${mode}' signature for (${selection.programId}, ${selection.enumId}, ${selection.variantIndex})`,\n );\n this.logger.warn(\"[load] ENUM_VARIANT missing signature\", {\n data: {\n programId: selection.programId,\n enumId: selection.enumId,\n variantIndex: selection.variantIndex,\n mode,\n },\n });\n return { type: ClearSignContextType.ERROR, error };\n }\n\n const payload: SolanaEnumVariantPayload = {\n programId: selection.programId,\n enumId: selection.enumId,\n variantIndex: selection.variantIndex,\n descriptor: {\n data: variant.data,\n signature,\n },\n };\n return {\n type: ClearSignContextType.SOLANA_ENUM_VARIANT,\n payload,\n certificate,\n };\n },\n });\n });\n }\n\n /**\n * Find the CAL enum variant entry for a selection. CAL nests\n * `enum_variants` inside each instruction descriptor, so we scan every\n * descriptor for the program looking for a matching `(enumId, variantIndex)`\n * \u2014 CAL guarantees uniqueness of this key across a program's instructions.\n */\n private lookupVariant(\n result: InstructionInfoResult,\n selection: SolanaEnumVariantSelection,\n ): { data: string; signatures: CalSignatures } | undefined {\n for (const dto of Object.values(result.descriptors)) {\n const variants = dto.enum_variants?.[selection.enumId];\n if (!variants) continue;\n // CAL keys variants by their stringified u16 index. Iterate then check\n // u16 equality through the codec so malformed keys (\"7abc\", \"-1\",\n // \"1e10\") are rejected rather than silently truncated by parseInt.\n for (const [indexStr, variant] of Object.entries(variants)) {\n const parsed = u16Codec.decode(Number(indexStr));\n if (parsed.isLeft()) continue;\n if (parsed.extract() === selection.variantIndex) {\n return variant;\n }\n }\n }\n return undefined;\n }\n}\n"],
5
- "mappings": "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",
6
- "names": ["EnumVariantContextLoader_exports", "__export", "EnumVariantContextLoader", "__toCommonJS", "import_inversify", "import_purify_ts", "import_configTypes", "import_pkiTypes", "import_KeyId", "import_KeyUsage", "import_instructionInfoTypes", "import_ClearSignContext", "import_certificateResult", "import_deviceModelIdCodec", "import_uIntCodec", "SUPPORTED_TYPES", "NETWORK_DEFAULT", "enumVariantSelectionCodec", "solanaEnumVariantInputCodec", "EnumVariantContextLoader", "dataSource", "config", "certificateLoader", "loggerFactory", "input", "expectedTypes", "t", "selections", "s", "network", "distinctProgramIds", "certPromise", "dataPromise", "programId", "certResult", "results", "error", "certificate", "programToEither", "i", "mode", "selection", "either", "err", "value", "variant", "signature", "payload", "result", "dto", "variants", "indexStr", "parsed", "__decorateClass", "__decorateParam"]
4
+ "sourcesContent": ["import {\n type DeviceModelId,\n type LoggerPublisherService,\n} from \"@ledgerhq/device-management-kit\";\nimport { inject, injectable } from \"inversify\";\nimport { array, Codec, optional, string } from \"purify-ts\";\n\nimport { configTypes } from \"@/config/di/configTypes\";\nimport { type ContextModuleServiceConfig } from \"@/config/model/ContextModuleConfig\";\nimport { pkiTypes } from \"@/modules/multichain/pki/di/pkiTypes\";\nimport { type PkiCertificateLoader } from \"@/modules/multichain/pki/domain/PkiCertificateLoader\";\nimport { KeyId } from \"@/modules/multichain/pki/model/KeyId\";\nimport { KeyUsage } from \"@/modules/multichain/pki/model/KeyUsage\";\nimport {\n type InstructionInfoDataSource,\n type InstructionInfoResult,\n} from \"@/modules/solana/instruction-info/data/InstructionInfoDataSource\";\nimport { instructionInfoTypes } from \"@/modules/solana/instruction-info/di/instructionInfoTypes\";\nimport {\n type SolanaEnumVariantPayload,\n type SolanaInstructionEnumVariant,\n} from \"@/modules/solana/model/SolanaPayloads\";\nimport { type ContextLoader } from \"@/shared/domain/ContextLoader\";\nimport {\n type ClearSignContext,\n ClearSignContextType,\n} from \"@/shared/model/ClearSignContext\";\nimport { loadCertificateResult } from \"@/shared/utils/certificateResult\";\nimport { deviceModelIdCodec } from \"@/shared/utils/deviceModelIdCodec\";\nimport { u16Codec } from \"@/shared/utils/uIntCodec\";\n\nconst SUPPORTED_TYPES: ClearSignContextType[] = [\n ClearSignContextType.SOLANA_ENUM_VARIANT,\n];\n\nconst NETWORK_DEFAULT = \"solana-mainnet\";\n\n/**\n * One enum-variant selection the caller wants resolved. `variantIndex` is\n * constrained to a u16 (0..=65535).\n */\nexport type SolanaEnumVariantSelection = {\n programId: string;\n enumId: string;\n variantIndex: number;\n};\n\nexport type SolanaEnumVariantContextInput = {\n deviceModelId: DeviceModelId;\n selections: SolanaEnumVariantSelection[];\n network?: string;\n};\n\nconst enumVariantSelectionCodec = Codec.interface({\n programId: string,\n enumId: string,\n variantIndex: u16Codec,\n});\n\nconst solanaEnumVariantInputCodec = Codec.interface({\n deviceModelId: deviceModelIdCodec,\n selections: array(enumVariantSelectionCodec),\n network: optional(string),\n});\n\n/**\n * Emits one SOLANA_ENUM_VARIANT context per `(programId, enumId,\n * variantIndex)` selection: fetches the CAL response for each distinct\n * program, looks up the matching variant, and emits only the selected ones.\n *\n * Shares {@link InstructionInfoDataSource} with\n * {@link InstructionInfoContextLoader}.\n */\n@injectable()\nexport class EnumVariantContextLoader\n implements ContextLoader<SolanaEnumVariantContextInput>\n{\n private readonly logger: LoggerPublisherService;\n\n constructor(\n @inject(instructionInfoTypes.InstructionInfoDataSource)\n private readonly dataSource: InstructionInfoDataSource,\n @inject(configTypes.Config)\n private readonly config: ContextModuleServiceConfig,\n @inject(pkiTypes.PkiCertificateLoader)\n private readonly certificateLoader: PkiCertificateLoader,\n @inject(configTypes.ContextModuleLoggerFactory)\n loggerFactory: (tag: string) => LoggerPublisherService,\n ) {\n this.logger = loggerFactory(\"EnumVariantContextLoader\");\n }\n\n public canHandle(\n input: unknown,\n expectedTypes: ClearSignContextType[],\n ): input is SolanaEnumVariantContextInput {\n if (!SUPPORTED_TYPES.every((t) => expectedTypes.includes(t))) return false;\n return solanaEnumVariantInputCodec.decode(input).caseOf({\n Left: () => false,\n Right: ({ selections }) =>\n selections.length > 0 &&\n selections.every((s) => s.programId.length > 0 && s.enumId.length > 0),\n });\n }\n\n public async load(\n input: SolanaEnumVariantContextInput,\n ): Promise<ClearSignContext[]> {\n const network = input.network || NETWORK_DEFAULT;\n const distinctProgramIds = Array.from(\n new Set(input.selections.map((s) => s.programId)),\n );\n\n this.logger.debug(\"[load] Fetching enum variants\", {\n data: {\n network,\n programCount: distinctProgramIds.length,\n selectionCount: input.selections.length,\n },\n });\n\n // Cert load and CAL fetches are independent \u2014 run them in parallel. A\n // PKI failure still degrades each selection to ERROR.\n const certPromise = loadCertificateResult(this.certificateLoader, {\n keyId: KeyId.TokenMetadataKey,\n keyUsage: KeyUsage.CoinMeta,\n targetDevice: input.deviceModelId,\n });\n\n const dataPromise = Promise.all(\n distinctProgramIds.map((programId) =>\n this.dataSource.getInstructionInfo({ programId, network }),\n ),\n );\n\n const [certResult, results] = await Promise.all([certPromise, dataPromise]);\n\n if (!certResult.ok || !certResult.value) {\n const error = certResult.ok\n ? new Error(\n \"[ContextModule] EnumVariantContextLoader: certificate is missing\",\n )\n : certResult.error;\n this.logger.warn(\"[load] ENUM_VARIANT certificate unavailable\", {\n data: { error: error.message },\n });\n return input.selections.map(() => ({\n type: ClearSignContextType.ERROR,\n error,\n }));\n }\n const certificate = certResult.value;\n\n const programToEither = new Map(\n distinctProgramIds.map((programId, i) => [programId, results[i]!]),\n );\n\n const mode = this.config.cal.mode ?? \"prod\";\n\n return input.selections.map((selection) => {\n const either = programToEither.get(selection.programId);\n if (!either) {\n const error = new Error(\n `[ContextModule] EnumVariantContextLoader: no CAL response for program ${selection.programId}`,\n );\n this.logger.warn(\"[load] ENUM_VARIANT fetch failed\", {\n data: {\n programId: selection.programId,\n enumId: selection.enumId,\n variantIndex: selection.variantIndex,\n error: error.message,\n },\n });\n return { type: ClearSignContextType.ERROR, error };\n }\n\n return either.caseOf<ClearSignContext>({\n Left: (err) => {\n this.logger.warn(\"[load] ENUM_VARIANT fetch failed\", {\n data: {\n programId: selection.programId,\n enumId: selection.enumId,\n variantIndex: selection.variantIndex,\n error: err.message,\n },\n });\n return { type: ClearSignContextType.ERROR, error: err };\n },\n Right: (value) => {\n const variant = this.lookupVariant(value, selection);\n if (!variant) {\n const error = new Error(\n `[ContextModule] EnumVariantContextLoader: CAL has no enum variant for (${selection.programId}, ${selection.enumId}, ${selection.variantIndex})`,\n );\n this.logger.warn(\"[load] ENUM_VARIANT not found in CAL response\", {\n data: {\n programId: selection.programId,\n enumId: selection.enumId,\n variantIndex: selection.variantIndex,\n },\n });\n return { type: ClearSignContextType.ERROR, error };\n }\n\n // The mapper already picked the signature for the configured mode (or\n // left it empty when CAL has none for that mode).\n if (!variant.descriptor.signature) {\n const error = new Error(\n `[ContextModule] EnumVariantContextLoader: missing '${mode}' signature for (${selection.programId}, ${selection.enumId}, ${selection.variantIndex})`,\n );\n this.logger.warn(\"[load] ENUM_VARIANT missing signature\", {\n data: {\n programId: selection.programId,\n enumId: selection.enumId,\n variantIndex: selection.variantIndex,\n mode,\n },\n });\n return { type: ClearSignContextType.ERROR, error };\n }\n\n const payload: SolanaEnumVariantPayload = {\n programId: selection.programId,\n enumId: selection.enumId,\n variantIndex: selection.variantIndex,\n descriptor: variant.descriptor,\n };\n return {\n type: ClearSignContextType.SOLANA_ENUM_VARIANT,\n payload,\n certificate,\n };\n },\n });\n });\n }\n\n /**\n * Find the decoded enum variant for a selection. The data source flattens\n * `enum_variants` across all of the program's descriptors into a single list\n * (malformed `u16` keys already dropped), and CAL guarantees `(enumId,\n * variantIndex)` is unique across a program's instructions.\n */\n private lookupVariant(\n result: InstructionInfoResult,\n selection: SolanaEnumVariantSelection,\n ): SolanaInstructionEnumVariant | undefined {\n return result.enumVariants.find(\n (variant) =>\n variant.enumId === selection.enumId &&\n variant.variantIndex === selection.variantIndex,\n );\n }\n}\n"],
5
+ "mappings": "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",
6
+ "names": ["EnumVariantContextLoader_exports", "__export", "EnumVariantContextLoader", "__toCommonJS", "import_inversify", "import_purify_ts", "import_configTypes", "import_pkiTypes", "import_KeyId", "import_KeyUsage", "import_instructionInfoTypes", "import_ClearSignContext", "import_certificateResult", "import_deviceModelIdCodec", "import_uIntCodec", "SUPPORTED_TYPES", "NETWORK_DEFAULT", "enumVariantSelectionCodec", "solanaEnumVariantInputCodec", "EnumVariantContextLoader", "dataSource", "config", "certificateLoader", "loggerFactory", "input", "expectedTypes", "selections", "s", "network", "distinctProgramIds", "certPromise", "dataPromise", "programId", "certResult", "results", "error", "certificate", "programToEither", "i", "mode", "selection", "either", "err", "value", "variant", "payload", "result", "__decorateClass", "__decorateParam"]
7
7
  }
@@ -1,2 +1,2 @@
1
- "use strict";var r=require("@ledgerhq/device-management-kit"),d=require("purify-ts"),e=require("vitest"),s=require("../../../../shared/model/ClearSignContext"),I=require("./EnumVariantContextLoader");const v=()=>({debug:e.vi.fn(),info:e.vi.fn(),warn:e.vi.fn(),error:e.vi.fn(),subscribers:[]}),m={keyUsageNumber:8,payload:new Uint8Array([66])},p={cal:{url:"https://crypto-assets-service.api.ledger.com/v1",mode:"prod",branch:"main"}},a="JUP6LkbZbjS1jKKwapdHNy74zcZ3tLUZoi5QNyVTaV4",g="OtherProgram111111111111111111111111111111";function c(){return{programId:a,descriptors:{e517cb977ae3ad2a:{type:"instruction",instruction_info:{version:1,program_id:a,discriminator:"e517cb977ae3ad2a",hash:"deadbeef",descriptor:{data:"jup_route_tlv",signatures:{prod:"psig_jup",test:"tsig_jup"}}},enum_variants:{swap:{46:{variant_name:"raydiumCP",data:"01_raydium_tlv",signatures:{prod:"prodsig_v46",test:"testsig_v46"}},12:{variant_name:"orcaWhirlpool",data:"01_orca_tlv",signatures:{prod:"prodsig_v12",test:"testsig_v12"}}}}}}}}(0,e.describe)("EnumVariantContextLoader",()=>{let i,l;(0,e.beforeEach)(()=>{e.vi.restoreAllMocks(),i={getInstructionInfo:e.vi.fn()},l={loadCertificate:e.vi.fn().mockResolvedValue(m)}});const o=(t=p)=>new I.EnumVariantContextLoader(i,t,l,v);(0,e.describe)("canHandle",()=>{(0,e.it)("returns true when SOLANA_ENUM_VARIANT is requested and selections are valid",()=>{(0,e.expect)(o().canHandle({deviceModelId:r.DeviceModelId.NANO_X,selections:[{programId:a,enumId:"swap",variantIndex:46}]},[s.ClearSignContextType.SOLANA_ENUM_VARIANT])).toBe(!0)}),(0,e.it)("returns false when SOLANA_ENUM_VARIANT is not requested",()=>{(0,e.expect)(o().canHandle({deviceModelId:r.DeviceModelId.NANO_X,selections:[{programId:a,enumId:"swap",variantIndex:46}]},[s.ClearSignContextType.SOLANA_INSTRUCTION_INFO])).toBe(!1)}),e.it.each([-1,65536,1.5,"46",null])("rejects non-u16 variantIndex: %s",t=>{const n=o();(0,e.expect)(n.canHandle({deviceModelId:r.DeviceModelId.NANO_X,selections:[{programId:a,enumId:"swap",variantIndex:t}]},[s.ClearSignContextType.SOLANA_ENUM_VARIANT])).toBe(!1)}),(0,e.it)("rejects empty programId / enumId / selections",()=>{const t=o(),n=[s.ClearSignContextType.SOLANA_ENUM_VARIANT];(0,e.expect)(t.canHandle({selections:[]},n)).toBe(!1),(0,e.expect)(t.canHandle({selections:[{programId:"",enumId:"swap",variantIndex:1}]},n)).toBe(!1),(0,e.expect)(t.canHandle({selections:[{programId:a,enumId:"",variantIndex:1}]},n)).toBe(!1)})}),(0,e.describe)("load",()=>{(0,e.it)("emits one SOLANA_ENUM_VARIANT per selection with certificate",async()=>{e.vi.spyOn(i,"getInstructionInfo").mockResolvedValue((0,d.Right)(c()));const t=await o().load({deviceModelId:r.DeviceModelId.NANO_X,selections:[{programId:a,enumId:"swap",variantIndex:46},{programId:a,enumId:"swap",variantIndex:12}]});(0,e.expect)(t).toHaveLength(2),(0,e.expect)(t[0]).toMatchObject({type:s.ClearSignContextType.SOLANA_ENUM_VARIANT,payload:{programId:a,enumId:"swap",variantIndex:46,descriptor:{data:"01_raydium_tlv",signature:"prodsig_v46"}},certificate:m}),(0,e.expect)(t[1]).toMatchObject({payload:{variantIndex:12,descriptor:{data:"01_orca_tlv",signature:"prodsig_v12"}}})}),(0,e.it)("dedups CAL fetches across selections that share a programId",async()=>{const t=e.vi.spyOn(i,"getInstructionInfo").mockResolvedValue((0,d.Right)(c()));await o().load({deviceModelId:r.DeviceModelId.NANO_X,selections:[{programId:a,enumId:"swap",variantIndex:46},{programId:a,enumId:"swap",variantIndex:12}]}),(0,e.expect)(t).toHaveBeenCalledTimes(1)}),(0,e.it)("resolves a variant index > 255 (u16, disc_kind U16 enums)",async()=>{const t={programId:a,descriptors:{e517cb977ae3ad2a:{type:"instruction",instruction_info:{version:1,program_id:a,discriminator:"e517cb977ae3ad2a",hash:"deadbeef",descriptor:{data:"jup_route_tlv",signatures:{prod:"psig",test:"tsig"}}},enum_variants:{swap:{300:{variant_name:"bigEnumVariant",data:"01_big_tlv",signatures:{prod:"prodsig_v300",test:"testsig_v300"}}}}}}};e.vi.spyOn(i,"getInstructionInfo").mockResolvedValue((0,d.Right)(t));const n=await o().load({deviceModelId:r.DeviceModelId.NANO_X,selections:[{programId:a,enumId:"swap",variantIndex:300}]});(0,e.expect)(n).toHaveLength(1),(0,e.expect)(n[0]?.type).toBe(s.ClearSignContextType.SOLANA_ENUM_VARIANT),(0,e.expect)(n[0].payload).toMatchObject({variantIndex:300,descriptor:{data:"01_big_tlv",signature:"prodsig_v300"}})}),(0,e.it)("emits ERROR when CAL has no matching variant for a selection",async()=>{e.vi.spyOn(i,"getInstructionInfo").mockResolvedValue((0,d.Right)(c()));const t=await o().load({deviceModelId:r.DeviceModelId.NANO_X,selections:[{programId:a,enumId:"swap",variantIndex:99}]});(0,e.expect)(t).toHaveLength(1),(0,e.expect)(t[0]?.type).toBe(s.ClearSignContextType.ERROR),(0,e.expect)(t[0].error.message).toMatch(/no enum variant/)}),(0,e.it)("emits ERROR when CAL fetch fails",async()=>{e.vi.spyOn(i,"getInstructionInfo").mockResolvedValue((0,d.Left)(new Error("upstream-500")));const t=await o().load({deviceModelId:r.DeviceModelId.NANO_X,selections:[{programId:g,enumId:"x",variantIndex:0}]});(0,e.expect)(t[0]?.type).toBe(s.ClearSignContextType.ERROR),(0,e.expect)(t[0].error.message).toBe("upstream-500")}),(0,e.it)("emits ERROR when configured signature mode is missing",async()=>{const t=c(),n=t.descriptors.e517cb977ae3ad2a?.enum_variants?.swap?.["46"];if(!n)throw new Error("fixture: variant must exist");delete n.signatures.test,e.vi.spyOn(i,"getInstructionInfo").mockResolvedValue((0,d.Right)(t));const u=await o({...p,cal:{...p.cal,mode:"test"}}).load({deviceModelId:r.DeviceModelId.NANO_X,selections:[{programId:a,enumId:"swap",variantIndex:46}]});(0,e.expect)(u[0]?.type).toBe(s.ClearSignContextType.ERROR),(0,e.expect)(u[0].error.message).toMatch(/missing 'test' signature/)}),(0,e.it)("degrades every selection to ERROR when certificate loading fails",async()=>{e.vi.spyOn(l,"loadCertificate").mockRejectedValue(new Error("pki-down")),e.vi.spyOn(i,"getInstructionInfo").mockResolvedValue((0,d.Right)(c()));const t=await o().load({deviceModelId:r.DeviceModelId.NANO_X,selections:[{programId:a,enumId:"swap",variantIndex:46},{programId:a,enumId:"swap",variantIndex:12}]});(0,e.expect)(t).toHaveLength(2),(0,e.expect)(t.every(n=>n.type===s.ClearSignContextType.ERROR)).toBe(!0)}),(0,e.it)("falls back to default network when input.network is empty / missing",async()=>{const t=e.vi.spyOn(i,"getInstructionInfo").mockResolvedValue((0,d.Right)(c()));await o().load({deviceModelId:r.DeviceModelId.NANO_X,selections:[{programId:a,enumId:"swap",variantIndex:46}],network:""}),(0,e.expect)(t).toHaveBeenCalledWith({programId:a,network:"solana-mainnet"})})})});
1
+ "use strict";var r=require("@ledgerhq/device-management-kit"),i=require("purify-ts"),e=require("vitest"),s=require("../../../../shared/model/ClearSignContext"),u=require("./EnumVariantContextLoader");const v=()=>({debug:e.vi.fn(),info:e.vi.fn(),warn:e.vi.fn(),error:e.vi.fn(),subscribers:[]}),p={keyUsageNumber:8,payload:new Uint8Array([66])},I={cal:{url:"https://crypto-assets-service.api.ledger.com/v1",mode:"prod",branch:"main"}},t="JUP6LkbZbjS1jKKwapdHNy74zcZ3tLUZoi5QNyVTaV4",g="OtherProgram111111111111111111111111111111";function c(){return{programId:t,descriptors:{},enumVariants:[{enumId:"swap",variantIndex:46,descriptor:{data:"01_raydium_tlv",signature:"prodsig_v46"}},{enumId:"swap",variantIndex:12,descriptor:{data:"01_orca_tlv",signature:"prodsig_v12"}}]}}(0,e.describe)("EnumVariantContextLoader",()=>{let d,l;(0,e.beforeEach)(()=>{e.vi.restoreAllMocks(),d={getInstructionInfo:e.vi.fn()},l={loadCertificate:e.vi.fn().mockResolvedValue(p)}});const n=(a=I)=>new u.EnumVariantContextLoader(d,a,l,v);(0,e.describe)("canHandle",()=>{(0,e.it)("returns true when SOLANA_ENUM_VARIANT is requested and selections are valid",()=>{(0,e.expect)(n().canHandle({deviceModelId:r.DeviceModelId.NANO_X,selections:[{programId:t,enumId:"swap",variantIndex:46}]},[s.ClearSignContextType.SOLANA_ENUM_VARIANT])).toBe(!0)}),(0,e.it)("returns false when SOLANA_ENUM_VARIANT is not requested",()=>{(0,e.expect)(n().canHandle({deviceModelId:r.DeviceModelId.NANO_X,selections:[{programId:t,enumId:"swap",variantIndex:46}]},[s.ClearSignContextType.SOLANA_INSTRUCTION_INFO])).toBe(!1)}),e.it.each([-1,65536,1.5,"46",null])("rejects non-u16 variantIndex: %s",a=>{const o=n();(0,e.expect)(o.canHandle({deviceModelId:r.DeviceModelId.NANO_X,selections:[{programId:t,enumId:"swap",variantIndex:a}]},[s.ClearSignContextType.SOLANA_ENUM_VARIANT])).toBe(!1)}),(0,e.it)("rejects empty programId / enumId / selections",()=>{const a=n(),o=[s.ClearSignContextType.SOLANA_ENUM_VARIANT];(0,e.expect)(a.canHandle({selections:[]},o)).toBe(!1),(0,e.expect)(a.canHandle({selections:[{programId:"",enumId:"swap",variantIndex:1}]},o)).toBe(!1),(0,e.expect)(a.canHandle({selections:[{programId:t,enumId:"",variantIndex:1}]},o)).toBe(!1)})}),(0,e.describe)("load",()=>{(0,e.it)("emits one SOLANA_ENUM_VARIANT per selection with certificate",async()=>{e.vi.spyOn(d,"getInstructionInfo").mockResolvedValue((0,i.Right)(c()));const a=await n().load({deviceModelId:r.DeviceModelId.NANO_X,selections:[{programId:t,enumId:"swap",variantIndex:46},{programId:t,enumId:"swap",variantIndex:12}]});(0,e.expect)(a).toHaveLength(2),(0,e.expect)(a[0]).toMatchObject({type:s.ClearSignContextType.SOLANA_ENUM_VARIANT,payload:{programId:t,enumId:"swap",variantIndex:46,descriptor:{data:"01_raydium_tlv",signature:"prodsig_v46"}},certificate:p}),(0,e.expect)(a[1]).toMatchObject({payload:{variantIndex:12,descriptor:{data:"01_orca_tlv",signature:"prodsig_v12"}}})}),(0,e.it)("dedups CAL fetches across selections that share a programId",async()=>{const a=e.vi.spyOn(d,"getInstructionInfo").mockResolvedValue((0,i.Right)(c()));await n().load({deviceModelId:r.DeviceModelId.NANO_X,selections:[{programId:t,enumId:"swap",variantIndex:46},{programId:t,enumId:"swap",variantIndex:12}]}),(0,e.expect)(a).toHaveBeenCalledTimes(1)}),(0,e.it)("resolves a variant index > 255 (u16, disc_kind U16 enums)",async()=>{const a={programId:t,descriptors:{},enumVariants:[{enumId:"swap",variantIndex:300,descriptor:{data:"01_big_tlv",signature:"prodsig_v300"}}]};e.vi.spyOn(d,"getInstructionInfo").mockResolvedValue((0,i.Right)(a));const o=await n().load({deviceModelId:r.DeviceModelId.NANO_X,selections:[{programId:t,enumId:"swap",variantIndex:300}]});(0,e.expect)(o).toHaveLength(1),(0,e.expect)(o[0]?.type).toBe(s.ClearSignContextType.SOLANA_ENUM_VARIANT),(0,e.expect)(o[0].payload).toMatchObject({variantIndex:300,descriptor:{data:"01_big_tlv",signature:"prodsig_v300"}})}),(0,e.it)("emits ERROR when CAL has no matching variant for a selection",async()=>{e.vi.spyOn(d,"getInstructionInfo").mockResolvedValue((0,i.Right)(c()));const a=await n().load({deviceModelId:r.DeviceModelId.NANO_X,selections:[{programId:t,enumId:"swap",variantIndex:99}]});(0,e.expect)(a).toHaveLength(1),(0,e.expect)(a[0]?.type).toBe(s.ClearSignContextType.ERROR),(0,e.expect)(a[0].error.message).toMatch(/no enum variant/)}),(0,e.it)("emits ERROR when CAL fetch fails",async()=>{e.vi.spyOn(d,"getInstructionInfo").mockResolvedValue((0,i.Left)(new Error("upstream-500")));const a=await n().load({deviceModelId:r.DeviceModelId.NANO_X,selections:[{programId:g,enumId:"x",variantIndex:0}]});(0,e.expect)(a[0]?.type).toBe(s.ClearSignContextType.ERROR),(0,e.expect)(a[0].error.message).toBe("upstream-500")}),(0,e.it)("emits ERROR when configured signature mode is missing",async()=>{const a={programId:t,descriptors:{},enumVariants:[{enumId:"swap",variantIndex:46,descriptor:{data:"01_raydium_tlv",signature:""}}]};e.vi.spyOn(d,"getInstructionInfo").mockResolvedValue((0,i.Right)(a));const m=await n({...I,cal:{...I.cal,mode:"test"}}).load({deviceModelId:r.DeviceModelId.NANO_X,selections:[{programId:t,enumId:"swap",variantIndex:46}]});(0,e.expect)(m[0]?.type).toBe(s.ClearSignContextType.ERROR),(0,e.expect)(m[0].error.message).toMatch(/missing 'test' signature/)}),(0,e.it)("degrades every selection to ERROR when certificate loading fails",async()=>{e.vi.spyOn(l,"loadCertificate").mockRejectedValue(new Error("pki-down")),e.vi.spyOn(d,"getInstructionInfo").mockResolvedValue((0,i.Right)(c()));const a=await n().load({deviceModelId:r.DeviceModelId.NANO_X,selections:[{programId:t,enumId:"swap",variantIndex:46},{programId:t,enumId:"swap",variantIndex:12}]});(0,e.expect)(a).toHaveLength(2),(0,e.expect)(a.every(o=>o.type===s.ClearSignContextType.ERROR)).toBe(!0)}),(0,e.it)("falls back to default network when input.network is empty / missing",async()=>{const a=e.vi.spyOn(d,"getInstructionInfo").mockResolvedValue((0,i.Right)(c()));await n().load({deviceModelId:r.DeviceModelId.NANO_X,selections:[{programId:t,enumId:"swap",variantIndex:46}],network:""}),(0,e.expect)(a).toHaveBeenCalledWith({programId:t,network:"solana-mainnet"})})})});
2
2
  //# sourceMappingURL=EnumVariantContextLoader.test.js.map
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "version": 3,
3
3
  "sources": ["../../../../../../../src/modules/solana/enum-variant/domain/EnumVariantContextLoader.test.ts"],
4
- "sourcesContent": ["/* eslint-disable @typescript-eslint/no-explicit-any */\nimport { DeviceModelId } from \"@ledgerhq/device-management-kit\";\nimport { Left, Right } from \"purify-ts\";\nimport { beforeEach, describe, expect, it, vi } from \"vitest\";\n\nimport { type ContextModuleServiceConfig } from \"@/config/model/ContextModuleConfig\";\nimport { type PkiCertificateLoader } from \"@/modules/multichain/pki/domain/PkiCertificateLoader\";\nimport {\n type InstructionInfoDataSource,\n type InstructionInfoResult,\n} from \"@/modules/solana/instruction-info/data/InstructionInfoDataSource\";\nimport { ClearSignContextType } from \"@/shared/model/ClearSignContext\";\n\nimport { EnumVariantContextLoader } from \"./EnumVariantContextLoader\";\n\nconst mockLoggerFactory = () => ({\n debug: vi.fn(),\n info: vi.fn(),\n warn: vi.fn(),\n error: vi.fn(),\n subscribers: [],\n});\n\nconst mockCertificate = {\n keyUsageNumber: 8,\n payload: new Uint8Array([0x42]),\n};\n\nconst mockConfig = {\n cal: {\n url: \"https://crypto-assets-service.api.ledger.com/v1\",\n mode: \"prod\",\n branch: \"main\",\n },\n} as ContextModuleServiceConfig;\n\nconst JUPITER_PROGRAM = \"JUP6LkbZbjS1jKKwapdHNy74zcZ3tLUZoi5QNyVTaV4\";\nconst OTHER_PROGRAM = \"OtherProgram111111111111111111111111111111\";\n\nfunction makeJupiterWithVariants(): InstructionInfoResult {\n return {\n programId: JUPITER_PROGRAM,\n descriptors: {\n e517cb977ae3ad2a: {\n type: \"instruction\",\n instruction_info: {\n version: 1,\n program_id: JUPITER_PROGRAM,\n discriminator: \"e517cb977ae3ad2a\",\n hash: \"deadbeef\",\n descriptor: {\n data: \"jup_route_tlv\",\n signatures: { prod: \"psig_jup\", test: \"tsig_jup\" },\n },\n },\n enum_variants: {\n swap: {\n \"46\": {\n variant_name: \"raydiumCP\",\n data: \"01_raydium_tlv\",\n signatures: { prod: \"prodsig_v46\", test: \"testsig_v46\" },\n },\n \"12\": {\n variant_name: \"orcaWhirlpool\",\n data: \"01_orca_tlv\",\n signatures: { prod: \"prodsig_v12\", test: \"testsig_v12\" },\n },\n },\n },\n },\n },\n };\n}\n\ndescribe(\"EnumVariantContextLoader\", () => {\n let dataSource: InstructionInfoDataSource;\n let certificateLoader: PkiCertificateLoader;\n\n beforeEach(() => {\n vi.restoreAllMocks();\n dataSource = {\n getInstructionInfo: vi.fn(),\n };\n certificateLoader = {\n loadCertificate: vi.fn().mockResolvedValue(mockCertificate),\n };\n });\n\n const makeLoader = (config = mockConfig) =>\n new EnumVariantContextLoader(\n dataSource,\n config,\n certificateLoader,\n mockLoggerFactory,\n );\n\n describe(\"canHandle\", () => {\n it(\"returns true when SOLANA_ENUM_VARIANT is requested and selections are valid\", () => {\n expect(\n makeLoader().canHandle(\n {\n deviceModelId: DeviceModelId.NANO_X,\n selections: [\n {\n programId: JUPITER_PROGRAM,\n enumId: \"swap\",\n variantIndex: 46,\n },\n ],\n },\n [ClearSignContextType.SOLANA_ENUM_VARIANT],\n ),\n ).toBe(true);\n });\n\n it(\"returns false when SOLANA_ENUM_VARIANT is not requested\", () => {\n expect(\n makeLoader().canHandle(\n {\n deviceModelId: DeviceModelId.NANO_X,\n selections: [\n { programId: JUPITER_PROGRAM, enumId: \"swap\", variantIndex: 46 },\n ],\n },\n [ClearSignContextType.SOLANA_INSTRUCTION_INFO],\n ),\n ).toBe(false);\n });\n\n it.each([-1, 65536, 1.5, \"46\", null])(\n \"rejects non-u16 variantIndex: %s\",\n (badIndex) => {\n const loader = makeLoader();\n expect(\n loader.canHandle(\n {\n deviceModelId: DeviceModelId.NANO_X,\n selections: [\n {\n programId: JUPITER_PROGRAM,\n enumId: \"swap\",\n variantIndex: badIndex,\n },\n ],\n } as any,\n [ClearSignContextType.SOLANA_ENUM_VARIANT],\n ),\n ).toBe(false);\n },\n );\n\n it(\"rejects empty programId / enumId / selections\", () => {\n const loader = makeLoader();\n const types = [ClearSignContextType.SOLANA_ENUM_VARIANT];\n expect(loader.canHandle({ selections: [] } as any, types)).toBe(false);\n expect(\n loader.canHandle(\n {\n selections: [{ programId: \"\", enumId: \"swap\", variantIndex: 1 }],\n } as any,\n types,\n ),\n ).toBe(false);\n expect(\n loader.canHandle(\n {\n selections: [\n { programId: JUPITER_PROGRAM, enumId: \"\", variantIndex: 1 },\n ],\n } as any,\n types,\n ),\n ).toBe(false);\n });\n });\n\n describe(\"load\", () => {\n it(\"emits one SOLANA_ENUM_VARIANT per selection with certificate\", async () => {\n vi.spyOn(dataSource, \"getInstructionInfo\").mockResolvedValue(\n Right(makeJupiterWithVariants()),\n );\n\n const result = await makeLoader().load({\n deviceModelId: DeviceModelId.NANO_X,\n selections: [\n { programId: JUPITER_PROGRAM, enumId: \"swap\", variantIndex: 46 },\n { programId: JUPITER_PROGRAM, enumId: \"swap\", variantIndex: 12 },\n ],\n });\n\n expect(result).toHaveLength(2);\n expect(result[0]).toMatchObject({\n type: ClearSignContextType.SOLANA_ENUM_VARIANT,\n payload: {\n programId: JUPITER_PROGRAM,\n enumId: \"swap\",\n variantIndex: 46,\n descriptor: { data: \"01_raydium_tlv\", signature: \"prodsig_v46\" },\n },\n certificate: mockCertificate,\n });\n expect(result[1]).toMatchObject({\n payload: {\n variantIndex: 12,\n descriptor: { data: \"01_orca_tlv\", signature: \"prodsig_v12\" },\n },\n });\n });\n\n it(\"dedups CAL fetches across selections that share a programId\", async () => {\n const spy = vi\n .spyOn(dataSource, \"getInstructionInfo\")\n .mockResolvedValue(Right(makeJupiterWithVariants()));\n\n await makeLoader().load({\n deviceModelId: DeviceModelId.NANO_X,\n selections: [\n { programId: JUPITER_PROGRAM, enumId: \"swap\", variantIndex: 46 },\n { programId: JUPITER_PROGRAM, enumId: \"swap\", variantIndex: 12 },\n ],\n });\n\n expect(spy).toHaveBeenCalledTimes(1);\n });\n\n it(\"resolves a variant index > 255 (u16, disc_kind U16 enums)\", async () => {\n const result: InstructionInfoResult = {\n programId: JUPITER_PROGRAM,\n descriptors: {\n e517cb977ae3ad2a: {\n type: \"instruction\",\n instruction_info: {\n version: 1,\n program_id: JUPITER_PROGRAM,\n discriminator: \"e517cb977ae3ad2a\",\n hash: \"deadbeef\",\n descriptor: {\n data: \"jup_route_tlv\",\n signatures: { prod: \"psig\", test: \"tsig\" },\n },\n },\n enum_variants: {\n swap: {\n \"300\": {\n variant_name: \"bigEnumVariant\",\n data: \"01_big_tlv\",\n signatures: { prod: \"prodsig_v300\", test: \"testsig_v300\" },\n },\n },\n },\n },\n },\n };\n vi.spyOn(dataSource, \"getInstructionInfo\").mockResolvedValue(\n Right(result),\n );\n\n const out = await makeLoader().load({\n deviceModelId: DeviceModelId.NANO_X,\n selections: [\n { programId: JUPITER_PROGRAM, enumId: \"swap\", variantIndex: 300 },\n ],\n });\n\n expect(out).toHaveLength(1);\n expect(out[0]?.type).toBe(ClearSignContextType.SOLANA_ENUM_VARIANT);\n expect((out[0] as any).payload).toMatchObject({\n variantIndex: 300,\n descriptor: { data: \"01_big_tlv\", signature: \"prodsig_v300\" },\n });\n });\n\n it(\"emits ERROR when CAL has no matching variant for a selection\", async () => {\n vi.spyOn(dataSource, \"getInstructionInfo\").mockResolvedValue(\n Right(makeJupiterWithVariants()),\n );\n\n const result = await makeLoader().load({\n deviceModelId: DeviceModelId.NANO_X,\n selections: [\n { programId: JUPITER_PROGRAM, enumId: \"swap\", variantIndex: 99 },\n ],\n });\n\n expect(result).toHaveLength(1);\n expect(result[0]?.type).toBe(ClearSignContextType.ERROR);\n expect((result[0] as any).error.message).toMatch(/no enum variant/);\n });\n\n it(\"emits ERROR when CAL fetch fails\", async () => {\n vi.spyOn(dataSource, \"getInstructionInfo\").mockResolvedValue(\n Left(new Error(\"upstream-500\")),\n );\n\n const result = await makeLoader().load({\n deviceModelId: DeviceModelId.NANO_X,\n selections: [\n { programId: OTHER_PROGRAM, enumId: \"x\", variantIndex: 0 },\n ],\n });\n\n expect(result[0]?.type).toBe(ClearSignContextType.ERROR);\n expect((result[0] as any).error.message).toBe(\"upstream-500\");\n });\n\n it(\"emits ERROR when configured signature mode is missing\", async () => {\n const result = makeJupiterWithVariants();\n const variant =\n result.descriptors[\"e517cb977ae3ad2a\"]?.enum_variants?.[\"swap\"]?.[\"46\"];\n if (!variant) throw new Error(\"fixture: variant must exist\");\n delete (variant.signatures as any).test;\n vi.spyOn(dataSource, \"getInstructionInfo\").mockResolvedValue(\n Right(result),\n );\n\n const loader = makeLoader({\n ...mockConfig,\n cal: { ...mockConfig.cal, mode: \"test\" },\n } as any);\n\n const out = await loader.load({\n deviceModelId: DeviceModelId.NANO_X,\n selections: [\n { programId: JUPITER_PROGRAM, enumId: \"swap\", variantIndex: 46 },\n ],\n });\n\n expect(out[0]?.type).toBe(ClearSignContextType.ERROR);\n expect((out[0] as any).error.message).toMatch(/missing 'test' signature/);\n });\n\n it(\"degrades every selection to ERROR when certificate loading fails\", async () => {\n vi.spyOn(certificateLoader, \"loadCertificate\").mockRejectedValue(\n new Error(\"pki-down\"),\n );\n // Data fetches run in parallel with cert load; resolve so awaits settle.\n vi.spyOn(dataSource, \"getInstructionInfo\").mockResolvedValue(\n Right(makeJupiterWithVariants()),\n );\n\n const out = await makeLoader().load({\n deviceModelId: DeviceModelId.NANO_X,\n selections: [\n { programId: JUPITER_PROGRAM, enumId: \"swap\", variantIndex: 46 },\n { programId: JUPITER_PROGRAM, enumId: \"swap\", variantIndex: 12 },\n ],\n });\n\n expect(out).toHaveLength(2);\n expect(out.every((c) => c.type === ClearSignContextType.ERROR)).toBe(\n true,\n );\n });\n\n it(\"falls back to default network when input.network is empty / missing\", async () => {\n const spy = vi\n .spyOn(dataSource, \"getInstructionInfo\")\n .mockResolvedValue(Right(makeJupiterWithVariants()));\n\n await makeLoader().load({\n deviceModelId: DeviceModelId.NANO_X,\n selections: [\n { programId: JUPITER_PROGRAM, enumId: \"swap\", variantIndex: 46 },\n ],\n network: \"\",\n });\n\n expect(spy).toHaveBeenCalledWith({\n programId: JUPITER_PROGRAM,\n network: \"solana-mainnet\",\n });\n });\n });\n});\n"],
5
- "mappings": "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",
6
- "names": ["import_device_management_kit", "import_purify_ts", "import_vitest", "import_ClearSignContext", "import_EnumVariantContextLoader", "mockLoggerFactory", "mockCertificate", "mockConfig", "JUPITER_PROGRAM", "OTHER_PROGRAM", "makeJupiterWithVariants", "dataSource", "certificateLoader", "makeLoader", "config", "badIndex", "loader", "types", "result", "spy", "out", "variant", "c"]
4
+ "sourcesContent": ["/* eslint-disable @typescript-eslint/no-explicit-any */\nimport { DeviceModelId } from \"@ledgerhq/device-management-kit\";\nimport { Left, Right } from \"purify-ts\";\nimport { beforeEach, describe, expect, it, vi } from \"vitest\";\n\nimport { type ContextModuleServiceConfig } from \"@/config/model/ContextModuleConfig\";\nimport { type PkiCertificateLoader } from \"@/modules/multichain/pki/domain/PkiCertificateLoader\";\nimport {\n type InstructionInfoDataSource,\n type InstructionInfoResult,\n} from \"@/modules/solana/instruction-info/data/InstructionInfoDataSource\";\nimport { ClearSignContextType } from \"@/shared/model/ClearSignContext\";\n\nimport { EnumVariantContextLoader } from \"./EnumVariantContextLoader\";\n\nconst mockLoggerFactory = () => ({\n debug: vi.fn(),\n info: vi.fn(),\n warn: vi.fn(),\n error: vi.fn(),\n subscribers: [],\n});\n\nconst mockCertificate = {\n keyUsageNumber: 8,\n payload: new Uint8Array([0x42]),\n};\n\nconst mockConfig = {\n cal: {\n url: \"https://crypto-assets-service.api.ledger.com/v1\",\n mode: \"prod\",\n branch: \"main\",\n },\n} as ContextModuleServiceConfig;\n\nconst JUPITER_PROGRAM = \"JUP6LkbZbjS1jKKwapdHNy74zcZ3tLUZoi5QNyVTaV4\";\nconst OTHER_PROGRAM = \"OtherProgram111111111111111111111111111111\";\n\n// The data source flattens enum variants into core models, with the signature\n// already picked for the configured mode.\nfunction makeJupiterWithVariants(): InstructionInfoResult {\n return {\n programId: JUPITER_PROGRAM,\n descriptors: {},\n enumVariants: [\n {\n enumId: \"swap\",\n variantIndex: 46,\n descriptor: { data: \"01_raydium_tlv\", signature: \"prodsig_v46\" },\n },\n {\n enumId: \"swap\",\n variantIndex: 12,\n descriptor: { data: \"01_orca_tlv\", signature: \"prodsig_v12\" },\n },\n ],\n };\n}\n\ndescribe(\"EnumVariantContextLoader\", () => {\n let dataSource: InstructionInfoDataSource;\n let certificateLoader: PkiCertificateLoader;\n\n beforeEach(() => {\n vi.restoreAllMocks();\n dataSource = {\n getInstructionInfo: vi.fn(),\n };\n certificateLoader = {\n loadCertificate: vi.fn().mockResolvedValue(mockCertificate),\n };\n });\n\n const makeLoader = (config = mockConfig) =>\n new EnumVariantContextLoader(\n dataSource,\n config,\n certificateLoader,\n mockLoggerFactory,\n );\n\n describe(\"canHandle\", () => {\n it(\"returns true when SOLANA_ENUM_VARIANT is requested and selections are valid\", () => {\n expect(\n makeLoader().canHandle(\n {\n deviceModelId: DeviceModelId.NANO_X,\n selections: [\n {\n programId: JUPITER_PROGRAM,\n enumId: \"swap\",\n variantIndex: 46,\n },\n ],\n },\n [ClearSignContextType.SOLANA_ENUM_VARIANT],\n ),\n ).toBe(true);\n });\n\n it(\"returns false when SOLANA_ENUM_VARIANT is not requested\", () => {\n expect(\n makeLoader().canHandle(\n {\n deviceModelId: DeviceModelId.NANO_X,\n selections: [\n { programId: JUPITER_PROGRAM, enumId: \"swap\", variantIndex: 46 },\n ],\n },\n [ClearSignContextType.SOLANA_INSTRUCTION_INFO],\n ),\n ).toBe(false);\n });\n\n it.each([-1, 65536, 1.5, \"46\", null])(\n \"rejects non-u16 variantIndex: %s\",\n (badIndex) => {\n const loader = makeLoader();\n expect(\n loader.canHandle(\n {\n deviceModelId: DeviceModelId.NANO_X,\n selections: [\n {\n programId: JUPITER_PROGRAM,\n enumId: \"swap\",\n variantIndex: badIndex,\n },\n ],\n } as any,\n [ClearSignContextType.SOLANA_ENUM_VARIANT],\n ),\n ).toBe(false);\n },\n );\n\n it(\"rejects empty programId / enumId / selections\", () => {\n const loader = makeLoader();\n const types = [ClearSignContextType.SOLANA_ENUM_VARIANT];\n expect(loader.canHandle({ selections: [] } as any, types)).toBe(false);\n expect(\n loader.canHandle(\n {\n selections: [{ programId: \"\", enumId: \"swap\", variantIndex: 1 }],\n } as any,\n types,\n ),\n ).toBe(false);\n expect(\n loader.canHandle(\n {\n selections: [\n { programId: JUPITER_PROGRAM, enumId: \"\", variantIndex: 1 },\n ],\n } as any,\n types,\n ),\n ).toBe(false);\n });\n });\n\n describe(\"load\", () => {\n it(\"emits one SOLANA_ENUM_VARIANT per selection with certificate\", async () => {\n vi.spyOn(dataSource, \"getInstructionInfo\").mockResolvedValue(\n Right(makeJupiterWithVariants()),\n );\n\n const result = await makeLoader().load({\n deviceModelId: DeviceModelId.NANO_X,\n selections: [\n { programId: JUPITER_PROGRAM, enumId: \"swap\", variantIndex: 46 },\n { programId: JUPITER_PROGRAM, enumId: \"swap\", variantIndex: 12 },\n ],\n });\n\n expect(result).toHaveLength(2);\n expect(result[0]).toMatchObject({\n type: ClearSignContextType.SOLANA_ENUM_VARIANT,\n payload: {\n programId: JUPITER_PROGRAM,\n enumId: \"swap\",\n variantIndex: 46,\n descriptor: { data: \"01_raydium_tlv\", signature: \"prodsig_v46\" },\n },\n certificate: mockCertificate,\n });\n expect(result[1]).toMatchObject({\n payload: {\n variantIndex: 12,\n descriptor: { data: \"01_orca_tlv\", signature: \"prodsig_v12\" },\n },\n });\n });\n\n it(\"dedups CAL fetches across selections that share a programId\", async () => {\n const spy = vi\n .spyOn(dataSource, \"getInstructionInfo\")\n .mockResolvedValue(Right(makeJupiterWithVariants()));\n\n await makeLoader().load({\n deviceModelId: DeviceModelId.NANO_X,\n selections: [\n { programId: JUPITER_PROGRAM, enumId: \"swap\", variantIndex: 46 },\n { programId: JUPITER_PROGRAM, enumId: \"swap\", variantIndex: 12 },\n ],\n });\n\n expect(spy).toHaveBeenCalledTimes(1);\n });\n\n it(\"resolves a variant index > 255 (u16, disc_kind U16 enums)\", async () => {\n const result: InstructionInfoResult = {\n programId: JUPITER_PROGRAM,\n descriptors: {},\n enumVariants: [\n {\n enumId: \"swap\",\n variantIndex: 300,\n descriptor: { data: \"01_big_tlv\", signature: \"prodsig_v300\" },\n },\n ],\n };\n vi.spyOn(dataSource, \"getInstructionInfo\").mockResolvedValue(\n Right(result),\n );\n\n const out = await makeLoader().load({\n deviceModelId: DeviceModelId.NANO_X,\n selections: [\n { programId: JUPITER_PROGRAM, enumId: \"swap\", variantIndex: 300 },\n ],\n });\n\n expect(out).toHaveLength(1);\n expect(out[0]?.type).toBe(ClearSignContextType.SOLANA_ENUM_VARIANT);\n expect((out[0] as any).payload).toMatchObject({\n variantIndex: 300,\n descriptor: { data: \"01_big_tlv\", signature: \"prodsig_v300\" },\n });\n });\n\n it(\"emits ERROR when CAL has no matching variant for a selection\", async () => {\n vi.spyOn(dataSource, \"getInstructionInfo\").mockResolvedValue(\n Right(makeJupiterWithVariants()),\n );\n\n const result = await makeLoader().load({\n deviceModelId: DeviceModelId.NANO_X,\n selections: [\n { programId: JUPITER_PROGRAM, enumId: \"swap\", variantIndex: 99 },\n ],\n });\n\n expect(result).toHaveLength(1);\n expect(result[0]?.type).toBe(ClearSignContextType.ERROR);\n expect((result[0] as any).error.message).toMatch(/no enum variant/);\n });\n\n it(\"emits ERROR when CAL fetch fails\", async () => {\n vi.spyOn(dataSource, \"getInstructionInfo\").mockResolvedValue(\n Left(new Error(\"upstream-500\")),\n );\n\n const result = await makeLoader().load({\n deviceModelId: DeviceModelId.NANO_X,\n selections: [\n { programId: OTHER_PROGRAM, enumId: \"x\", variantIndex: 0 },\n ],\n });\n\n expect(result[0]?.type).toBe(ClearSignContextType.ERROR);\n expect((result[0] as any).error.message).toBe(\"upstream-500\");\n });\n\n it(\"emits ERROR when configured signature mode is missing\", async () => {\n // The mapper leaves the signature empty when CAL has none for the mode.\n const result: InstructionInfoResult = {\n programId: JUPITER_PROGRAM,\n descriptors: {},\n enumVariants: [\n {\n enumId: \"swap\",\n variantIndex: 46,\n descriptor: { data: \"01_raydium_tlv\", signature: \"\" },\n },\n ],\n };\n vi.spyOn(dataSource, \"getInstructionInfo\").mockResolvedValue(\n Right(result),\n );\n\n const loader = makeLoader({\n ...mockConfig,\n cal: { ...mockConfig.cal, mode: \"test\" },\n } as any);\n\n const out = await loader.load({\n deviceModelId: DeviceModelId.NANO_X,\n selections: [\n { programId: JUPITER_PROGRAM, enumId: \"swap\", variantIndex: 46 },\n ],\n });\n\n expect(out[0]?.type).toBe(ClearSignContextType.ERROR);\n expect((out[0] as any).error.message).toMatch(/missing 'test' signature/);\n });\n\n it(\"degrades every selection to ERROR when certificate loading fails\", async () => {\n vi.spyOn(certificateLoader, \"loadCertificate\").mockRejectedValue(\n new Error(\"pki-down\"),\n );\n // Data fetches run in parallel with cert load; resolve so awaits settle.\n vi.spyOn(dataSource, \"getInstructionInfo\").mockResolvedValue(\n Right(makeJupiterWithVariants()),\n );\n\n const out = await makeLoader().load({\n deviceModelId: DeviceModelId.NANO_X,\n selections: [\n { programId: JUPITER_PROGRAM, enumId: \"swap\", variantIndex: 46 },\n { programId: JUPITER_PROGRAM, enumId: \"swap\", variantIndex: 12 },\n ],\n });\n\n expect(out).toHaveLength(2);\n expect(out.every((c) => c.type === ClearSignContextType.ERROR)).toBe(\n true,\n );\n });\n\n it(\"falls back to default network when input.network is empty / missing\", async () => {\n const spy = vi\n .spyOn(dataSource, \"getInstructionInfo\")\n .mockResolvedValue(Right(makeJupiterWithVariants()));\n\n await makeLoader().load({\n deviceModelId: DeviceModelId.NANO_X,\n selections: [\n { programId: JUPITER_PROGRAM, enumId: \"swap\", variantIndex: 46 },\n ],\n network: \"\",\n });\n\n expect(spy).toHaveBeenCalledWith({\n programId: JUPITER_PROGRAM,\n network: \"solana-mainnet\",\n });\n });\n });\n});\n"],
5
+ "mappings": "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",
6
+ "names": ["import_device_management_kit", "import_purify_ts", "import_vitest", "import_ClearSignContext", "import_EnumVariantContextLoader", "mockLoggerFactory", "mockCertificate", "mockConfig", "JUPITER_PROGRAM", "OTHER_PROGRAM", "makeJupiterWithVariants", "dataSource", "certificateLoader", "makeLoader", "config", "badIndex", "loader", "types", "result", "spy", "out", "c"]
7
7
  }
@@ -1,2 +1,2 @@
1
- "use strict";var f=Object.defineProperty;var l=Object.getOwnPropertyDescriptor;var h=Object.getOwnPropertyNames;var g=Object.prototype.hasOwnProperty;var E=(n,t)=>{for(var i in t)f(n,i,{get:t[i],enumerable:!0})},w=(n,t,i,e)=>{if(t&&typeof t=="object"||typeof t=="function")for(let r of h(t))!g.call(n,r)&&r!==i&&f(n,r,{get:()=>t[r],enumerable:!(e=l(t,r))||e.enumerable});return n};var y=n=>w(f({},"__esModule",{value:!0}),n),m=(n,t,i,e)=>{for(var r=e>1?void 0:e?l(t,i):t,s=n.length-1,c;s>=0;s--)(c=n[s])&&(r=(e?c(t,i,r):c(r))||r);return e&&r&&f(t,i,r),r},p=(n,t)=>(i,e)=>t(i,e,n);var k={};E(k,{HttpInstructionInfoDataSource:()=>a});module.exports=y(k);var u=require("inversify"),o=require("purify-ts"),d=require("../../../../config/di/configTypes"),I=require("../../../../shared/network/di/networkTypes"),C=require("./InstructionInfoDto");const D=o.Codec.interface({descriptors_instruction:(0,o.record)(o.string,o.unknown)});let a=class{constructor(t,i){this.config=t;this.http=i}async getInstructionInfo({programId:t,network:i}){let e;try{e=await this.http.get(`${this.config.cal.url}/solana`,{params:{output:"descriptors_instruction",network:i,program:t,ref:`branch:${this.config.cal.branch}`}})}catch(r){const s=r instanceof Error?r.message:String(r);return(0,o.Left)(new Error(`[ContextModule] HttpInstructionInfoDataSource: Failed to fetch instruction descriptors: ${s}`))}return!Array.isArray(e)||e.length===0?(0,o.Left)(new Error(`[ContextModule] HttpInstructionInfoDataSource: empty response for program ${t}`)):D.decode(e[0]).caseOf({Left:r=>(0,o.Left)(new Error(`[ContextModule] HttpInstructionInfoDataSource: malformed response for program ${t}: ${r}`)),Right:r=>{const s=r.descriptors_instruction[t];return s==null||typeof s!="object"?(0,o.Left)(new Error(`[ContextModule] HttpInstructionInfoDataSource: no descriptors for program ${t}`)):C.calInstructionDescriptorsCodec.decode(s).caseOf({Left:c=>(0,o.Left)(new Error(`[ContextModule] HttpInstructionInfoDataSource: malformed descriptors for program ${t}: ${c}`)),Right:()=>(0,o.Right)({programId:t,descriptors:s})})}})}};a=m([(0,u.injectable)(),p(0,(0,u.inject)(d.configTypes.Config)),p(1,(0,u.inject)(I.networkTypes.NetworkClient))],a);0&&(module.exports={HttpInstructionInfoDataSource});
1
+ "use strict";var f=Object.defineProperty;var I=Object.getOwnPropertyDescriptor;var D=Object.getOwnPropertyNames;var k=Object.prototype.hasOwnProperty;var M=(n,t)=>{for(var i in t)f(n,i,{get:t[i],enumerable:!0})},$=(n,t,i,e)=>{if(t&&typeof t=="object"||typeof t=="function")for(let r of D(t))!k.call(n,r)&&r!==i&&f(n,r,{get:()=>t[r],enumerable:!(e=I(t,r))||e.enumerable});return n};var x=n=>$(f({},"__esModule",{value:!0}),n),C=(n,t,i,e)=>{for(var r=e>1?void 0:e?I(t,i):t,s=n.length-1,c;s>=0;s--)(c=n[s])&&(r=(e?c(t,i,r):c(r))||r);return e&&r&&f(t,i,r),r},l=(n,t)=>(i,e)=>t(i,e,n);var b={};M(b,{HttpInstructionInfoDataSource:()=>a});module.exports=x(b);var u=require("inversify"),o=require("purify-ts"),g=require("../../../../config/di/configTypes"),h=require("../../../../shared/network/di/networkTypes"),E=require("./InstructionInfoDto"),p=require("./InstructionInfoMapper");const R=o.Codec.interface({descriptors_instruction:(0,o.record)(o.string,o.unknown)});let a=class{constructor(t,i){this.config=t;this.http=i}async getInstructionInfo({programId:t,network:i}){let e;try{e=await this.http.get(`${this.config.cal.url}/solana`,{params:{output:"descriptors_instruction",network:i,program:t,ref:`branch:${this.config.cal.branch}`}})}catch(r){const s=r instanceof Error?r.message:String(r);return(0,o.Left)(new Error(`[ContextModule] HttpInstructionInfoDataSource: Failed to fetch instruction descriptors: ${s}`))}return!Array.isArray(e)||e.length===0?(0,o.Left)(new Error(`[ContextModule] HttpInstructionInfoDataSource: empty response for program ${t}`)):R.decode(e[0]).caseOf({Left:r=>(0,o.Left)(new Error(`[ContextModule] HttpInstructionInfoDataSource: malformed response for program ${t}: ${r}`)),Right:r=>{const s=r.descriptors_instruction[t];return s==null||typeof s!="object"?(0,o.Left)(new Error(`[ContextModule] HttpInstructionInfoDataSource: no descriptors for program ${t}`)):E.calInstructionDescriptorsCodec.decode(s).caseOf({Left:c=>(0,o.Left)(new Error(`[ContextModule] HttpInstructionInfoDataSource: malformed descriptors for program ${t}: ${c}`)),Right:()=>{const c=this.config.cal.mode??"prod",m=s,y=Object.fromEntries(Object.entries(m).map(([d,w])=>[d,(0,p.toInstructionInfoPayload)(d,w,c)]));return(0,o.Right)({programId:t,descriptors:y,enumVariants:(0,p.toProgramEnumVariants)(m,c)})}})}})}};a=C([(0,u.injectable)(),l(0,(0,u.inject)(g.configTypes.Config)),l(1,(0,u.inject)(h.networkTypes.NetworkClient))],a);0&&(module.exports={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 {\n Codec,\n Either,\n Left,\n record,\n Right,\n string,\n unknown as unknownCodec,\n} from \"purify-ts\";\n\nimport { configTypes } from \"@/config/di/configTypes\";\nimport { type ContextModuleServiceConfig } from \"@/config/model/ContextModuleConfig\";\nimport { networkTypes } from \"@/shared/network/di/networkTypes\";\n\nimport {\n GetInstructionInfoParams,\n InstructionInfoDataSource,\n InstructionInfoResult,\n} from \"./InstructionInfoDataSource\";\nimport {\n type CalInstructionDescriptorDto,\n calInstructionDescriptorsCodec,\n} from \"./InstructionInfoDto\";\n\n// Validates the outer envelope shape only. Per-discriminator descriptor\n// content is validated downstream by the loader before being consumed.\nconst calInstructionInfoEnvelopeCodec = Codec.interface({\n descriptors_instruction: record(string, unknownCodec),\n});\n\n@injectable()\nexport class HttpInstructionInfoDataSource\n implements InstructionInfoDataSource\n{\n constructor(\n @inject(configTypes.Config)\n private readonly config: ContextModuleServiceConfig,\n @inject(networkTypes.NetworkClient)\n private readonly http: DmkNetworkClient,\n ) {}\n\n public async getInstructionInfo({\n programId,\n network,\n }: GetInstructionInfoParams): Promise<Either<Error, InstructionInfoResult>> {\n let data: unknown;\n try {\n data = await this.http.get(`${this.config.cal.url}/solana`, {\n params: {\n output: \"descriptors_instruction\",\n network,\n program: programId,\n ref: `branch:${this.config.cal.branch}`,\n },\n });\n } catch (error) {\n const reason = error instanceof Error ? error.message : String(error);\n return Left(\n new Error(\n `[ContextModule] HttpInstructionInfoDataSource: Failed to fetch instruction descriptors: ${reason}`,\n ),\n );\n }\n\n if (!Array.isArray(data) || data.length === 0) {\n return Left(\n new Error(\n `[ContextModule] HttpInstructionInfoDataSource: empty response for program ${programId}`,\n ),\n );\n }\n\n return calInstructionInfoEnvelopeCodec\n .decode(data[0])\n .caseOf<Either<Error, InstructionInfoResult>>({\n Left: (error) =>\n Left(\n new Error(\n `[ContextModule] HttpInstructionInfoDataSource: malformed response for program ${programId}: ${error}`,\n ),\n ),\n Right: (envelope) => {\n const descriptors = envelope.descriptors_instruction[programId];\n if (descriptors == null || typeof descriptors !== \"object\") {\n return Left(\n new Error(\n `[ContextModule] HttpInstructionInfoDataSource: no descriptors for program ${programId}`,\n ),\n );\n }\n\n // Validate the inner descriptor shape so the loaders can dereference\n // `instruction_info.descriptor` / `enum_variants` without\n // runtime-throwing on a malformed CAL payload. A malformed descriptor\n // degrades the whole program to a per-program ERROR rather than\n // rejecting the batch. On success we pass the original (full) object\n // through \u2014 the cast is now justified because the consumed shape has\n // been validated.\n return calInstructionDescriptorsCodec\n .decode(descriptors)\n .caseOf<Either<Error, InstructionInfoResult>>({\n Left: (error) =>\n Left(\n new Error(\n `[ContextModule] HttpInstructionInfoDataSource: malformed descriptors for program ${programId}: ${error}`,\n ),\n ),\n Right: () =>\n Right({\n programId,\n descriptors: descriptors as Record<\n string,\n CalInstructionDescriptorDto\n >,\n }),\n });\n },\n });\n }\n}\n"],
5
- "mappings": "okBAAA,IAAAA,EAAA,GAAAC,EAAAD,EAAA,mCAAAE,IAAA,eAAAC,EAAAH,GACA,IAAAI,EAAmC,qBACnCC,EAQO,qBAEPC,EAA4B,mCAE5BC,EAA6B,4CAO7BC,EAGO,gCAIP,MAAMC,EAAkC,QAAM,UAAU,CACtD,2BAAyB,UAAO,SAAQ,EAAAC,OAAY,CACtD,CAAC,EAGM,IAAMC,EAAN,KAEP,CACE,YAEmBC,EAEAC,EACjB,CAHiB,YAAAD,EAEA,UAAAC,CAChB,CAEH,MAAa,mBAAmB,CAC9B,UAAAC,EACA,QAAAC,CACF,EAA4E,CAC1E,IAAIC,EACJ,GAAI,CACFA,EAAO,MAAM,KAAK,KAAK,IAAI,GAAG,KAAK,OAAO,IAAI,GAAG,UAAW,CAC1D,OAAQ,CACN,OAAQ,0BACR,QAAAD,EACA,QAASD,EACT,IAAK,UAAU,KAAK,OAAO,IAAI,MAAM,EACvC,CACF,CAAC,CACH,OAASG,EAAO,CACd,MAAMC,EAASD,aAAiB,MAAQA,EAAM,QAAU,OAAOA,CAAK,EACpE,SAAO,QACL,IAAI,MACF,2FAA2FC,CAAM,EACnG,CACF,CACF,CAEA,MAAI,CAAC,MAAM,QAAQF,CAAI,GAAKA,EAAK,SAAW,KACnC,QACL,IAAI,MACF,6EAA6EF,CAAS,EACxF,CACF,EAGKL,EACJ,OAAOO,EAAK,CAAC,CAAC,EACd,OAA6C,CAC5C,KAAOC,MACL,QACE,IAAI,MACF,iFAAiFH,CAAS,KAAKG,CAAK,EACtG,CACF,EACF,MAAQE,GAAa,CACnB,MAAMC,EAAcD,EAAS,wBAAwBL,CAAS,EAC9D,OAAIM,GAAe,MAAQ,OAAOA,GAAgB,YACzC,QACL,IAAI,MACF,6EAA6EN,CAAS,EACxF,CACF,EAUK,iCACJ,OAAOM,CAAW,EAClB,OAA6C,CAC5C,KAAOH,MACL,QACE,IAAI,MACF,oFAAoFH,CAAS,KAAKG,CAAK,EACzG,CACF,EACF,MAAO,OACL,SAAM,CACJ,UAAAH,EACA,YAAaM,CAIf,CAAC,CACL,CAAC,CACL,CACF,CAAC,CACL,CACF,EAxFaT,EAANU,EAAA,IADN,cAAW,EAKPC,EAAA,eAAO,cAAY,MAAM,GAEzBA,EAAA,eAAO,eAAa,aAAa,IANzBX",
6
- "names": ["HttpInstructionInfoDataSource_exports", "__export", "HttpInstructionInfoDataSource", "__toCommonJS", "import_inversify", "import_purify_ts", "import_configTypes", "import_networkTypes", "import_InstructionInfoDto", "calInstructionInfoEnvelopeCodec", "unknownCodec", "HttpInstructionInfoDataSource", "config", "http", "programId", "network", "data", "error", "reason", "envelope", "descriptors", "__decorateClass", "__decorateParam"]
4
+ "sourcesContent": ["import { DmkNetworkClient } from \"@ledgerhq/device-management-kit\";\nimport { inject, injectable } from \"inversify\";\nimport {\n Codec,\n Either,\n Left,\n record,\n Right,\n string,\n unknown as unknownCodec,\n} from \"purify-ts\";\n\nimport { configTypes } from \"@/config/di/configTypes\";\nimport { type ContextModuleServiceConfig } from \"@/config/model/ContextModuleConfig\";\nimport { networkTypes } from \"@/shared/network/di/networkTypes\";\n\nimport {\n GetInstructionInfoParams,\n InstructionInfoDataSource,\n InstructionInfoResult,\n} from \"./InstructionInfoDataSource\";\nimport {\n type CalInstructionDescriptorDto,\n calInstructionDescriptorsCodec,\n} from \"./InstructionInfoDto\";\nimport {\n type CalMode,\n toInstructionInfoPayload,\n toProgramEnumVariants,\n} from \"./InstructionInfoMapper\";\n\n// Validates the outer envelope shape only. Per-discriminator descriptor\n// content is validated downstream by the loader before being consumed.\nconst calInstructionInfoEnvelopeCodec = Codec.interface({\n descriptors_instruction: record(string, unknownCodec),\n});\n\n@injectable()\nexport class HttpInstructionInfoDataSource\n implements InstructionInfoDataSource\n{\n constructor(\n @inject(configTypes.Config)\n private readonly config: ContextModuleServiceConfig,\n @inject(networkTypes.NetworkClient)\n private readonly http: DmkNetworkClient,\n ) {}\n\n public async getInstructionInfo({\n programId,\n network,\n }: GetInstructionInfoParams): Promise<Either<Error, InstructionInfoResult>> {\n let data: unknown;\n try {\n data = await this.http.get(`${this.config.cal.url}/solana`, {\n params: {\n output: \"descriptors_instruction\",\n network,\n program: programId,\n ref: `branch:${this.config.cal.branch}`,\n },\n });\n } catch (error) {\n const reason = error instanceof Error ? error.message : String(error);\n return Left(\n new Error(\n `[ContextModule] HttpInstructionInfoDataSource: Failed to fetch instruction descriptors: ${reason}`,\n ),\n );\n }\n\n if (!Array.isArray(data) || data.length === 0) {\n return Left(\n new Error(\n `[ContextModule] HttpInstructionInfoDataSource: empty response for program ${programId}`,\n ),\n );\n }\n\n return calInstructionInfoEnvelopeCodec\n .decode(data[0])\n .caseOf<Either<Error, InstructionInfoResult>>({\n Left: (error) =>\n Left(\n new Error(\n `[ContextModule] HttpInstructionInfoDataSource: malformed response for program ${programId}: ${error}`,\n ),\n ),\n Right: (envelope) => {\n const descriptors = envelope.descriptors_instruction[programId];\n if (descriptors == null || typeof descriptors !== \"object\") {\n return Left(\n new Error(\n `[ContextModule] HttpInstructionInfoDataSource: no descriptors for program ${programId}`,\n ),\n );\n }\n\n // Validate the inner descriptor shape so the mapper can dereference\n // `instruction_info.descriptor` / `enum_variants` without\n // runtime-throwing on a malformed CAL payload. A malformed descriptor\n // degrades the whole program to a per-program ERROR rather than\n // rejecting the batch. On success we transform each validated DTO into\n // the core payload so the loader never sees the CAL DTO shapes.\n return calInstructionDescriptorsCodec\n .decode(descriptors)\n .caseOf<Either<Error, InstructionInfoResult>>({\n Left: (error) =>\n Left(\n new Error(\n `[ContextModule] HttpInstructionInfoDataSource: malformed descriptors for program ${programId}: ${error}`,\n ),\n ),\n // The codec only validates the consumed shape and strips\n // undeclared fields, so we transform the original (full) object \u2014\n // the cast is justified now that the shape has been validated.\n Right: () => {\n const mode: CalMode = this.config.cal.mode ?? \"prod\";\n const validatedDescriptors = descriptors as Record<\n string,\n CalInstructionDescriptorDto\n >;\n const mapped = Object.fromEntries(\n Object.entries(validatedDescriptors).map(\n ([discriminator, dto]) => [\n discriminator,\n toInstructionInfoPayload(discriminator, dto, mode),\n ],\n ),\n );\n return Right({\n programId,\n descriptors: mapped,\n enumVariants: toProgramEnumVariants(\n validatedDescriptors,\n mode,\n ),\n });\n },\n });\n },\n });\n }\n}\n"],
5
+ "mappings": "okBAAA,IAAAA,EAAA,GAAAC,EAAAD,EAAA,mCAAAE,IAAA,eAAAC,EAAAH,GACA,IAAAI,EAAmC,qBACnCC,EAQO,qBAEPC,EAA4B,mCAE5BC,EAA6B,4CAO7BC,EAGO,gCACPC,EAIO,mCAIP,MAAMC,EAAkC,QAAM,UAAU,CACtD,2BAAyB,UAAO,SAAQ,EAAAC,OAAY,CACtD,CAAC,EAGM,IAAMC,EAAN,KAEP,CACE,YAEmBC,EAEAC,EACjB,CAHiB,YAAAD,EAEA,UAAAC,CAChB,CAEH,MAAa,mBAAmB,CAC9B,UAAAC,EACA,QAAAC,CACF,EAA4E,CAC1E,IAAIC,EACJ,GAAI,CACFA,EAAO,MAAM,KAAK,KAAK,IAAI,GAAG,KAAK,OAAO,IAAI,GAAG,UAAW,CAC1D,OAAQ,CACN,OAAQ,0BACR,QAAAD,EACA,QAASD,EACT,IAAK,UAAU,KAAK,OAAO,IAAI,MAAM,EACvC,CACF,CAAC,CACH,OAASG,EAAO,CACd,MAAMC,EAASD,aAAiB,MAAQA,EAAM,QAAU,OAAOA,CAAK,EACpE,SAAO,QACL,IAAI,MACF,2FAA2FC,CAAM,EACnG,CACF,CACF,CAEA,MAAI,CAAC,MAAM,QAAQF,CAAI,GAAKA,EAAK,SAAW,KACnC,QACL,IAAI,MACF,6EAA6EF,CAAS,EACxF,CACF,EAGKL,EACJ,OAAOO,EAAK,CAAC,CAAC,EACd,OAA6C,CAC5C,KAAOC,MACL,QACE,IAAI,MACF,iFAAiFH,CAAS,KAAKG,CAAK,EACtG,CACF,EACF,MAAQE,GAAa,CACnB,MAAMC,EAAcD,EAAS,wBAAwBL,CAAS,EAC9D,OAAIM,GAAe,MAAQ,OAAOA,GAAgB,YACzC,QACL,IAAI,MACF,6EAA6EN,CAAS,EACxF,CACF,EASK,iCACJ,OAAOM,CAAW,EAClB,OAA6C,CAC5C,KAAOH,MACL,QACE,IAAI,MACF,oFAAoFH,CAAS,KAAKG,CAAK,EACzG,CACF,EAIF,MAAO,IAAM,CACX,MAAMI,EAAgB,KAAK,OAAO,IAAI,MAAQ,OACxCC,EAAuBF,EAIvBG,EAAS,OAAO,YACpB,OAAO,QAAQD,CAAoB,EAAE,IACnC,CAAC,CAACE,EAAeC,CAAG,IAAM,CACxBD,KACA,4BAAyBA,EAAeC,EAAKJ,CAAI,CACnD,CACF,CACF,EACA,SAAO,SAAM,CACX,UAAAP,EACA,YAAaS,EACb,gBAAc,yBACZD,EACAD,CACF,CACF,CAAC,CACH,CACF,CAAC,CACL,CACF,CAAC,CACL,CACF,EAzGaV,EAANe,EAAA,IADN,cAAW,EAKPC,EAAA,eAAO,cAAY,MAAM,GAEzBA,EAAA,eAAO,eAAa,aAAa,IANzBhB",
6
+ "names": ["HttpInstructionInfoDataSource_exports", "__export", "HttpInstructionInfoDataSource", "__toCommonJS", "import_inversify", "import_purify_ts", "import_configTypes", "import_networkTypes", "import_InstructionInfoDto", "import_InstructionInfoMapper", "calInstructionInfoEnvelopeCodec", "unknownCodec", "HttpInstructionInfoDataSource", "config", "http", "programId", "network", "data", "error", "reason", "envelope", "descriptors", "mode", "validatedDescriptors", "mapped", "discriminator", "dto", "__decorateClass", "__decorateParam"]
7
7
  }
@@ -1,2 +1,2 @@
1
- "use strict";var a=require("purify-ts"),t=require("vitest"),u=require("./HttpInstructionInfoDataSource");(0,t.describe)("HttpInstructionInfoDataSource",()=>{let n,r;const e="11111111111111111111111111111111",s="solana-mainnet",p={cal:{url:"https://crypto-assets-service.api.ledger.com/v1",mode:"prod",branch:"main"}},i=[{descriptors_instruction:{[e]:{"00000000":{type:"instruction",network:"solana-mainnet",version:"v1",instruction_info:{version:1,program_id:e,discriminator:"00000000",hash:"deadbeef",descriptor:{data:"00010101",signatures:{prod:"prodsig",test:"testsig"}}},display_fields:[],value_flow_ports:[],hide_rules:[],account_resets:[]}}}}];(0,t.beforeEach)(()=>{t.vi.clearAllMocks(),r={get:t.vi.fn()},n=new u.HttpInstructionInfoDataSource(p,r)}),(0,t.it)("calls CAL with singular program= and ref=branch:<branch>",async()=>{r.get.mockResolvedValue(i),await n.getInstructionInfo({programId:e,network:s}),(0,t.expect)(r.get).toHaveBeenCalledTimes(1),(0,t.expect)(r.get).toHaveBeenCalledWith("https://crypto-assets-service.api.ledger.com/v1/solana",{params:{output:"descriptors_instruction",network:s,program:e,ref:"branch:main"}})}),(0,t.it)("returns Right with the unwrapped descriptors map on success",async()=>{r.get.mockResolvedValue(i);const o=await n.getInstructionInfo({programId:e,network:s}),[c]=i;if(!c)throw new Error("fixture: successResponse must be non-empty");(0,t.expect)(o).toEqual((0,a.Right)({programId:e,descriptors:c.descriptors_instruction[e]}))}),(0,t.it)("returns Left when the response array is empty",async()=>{r.get.mockResolvedValue([]);const o=await n.getInstructionInfo({programId:e,network:s});(0,t.expect)(o).toEqual((0,a.Left)(new Error(`[ContextModule] HttpInstructionInfoDataSource: empty response for program ${e}`)))}),(0,t.it)("returns Left when the envelope is malformed",async()=>{r.get.mockResolvedValue([{foo:"bar"}]);const o=await n.getInstructionInfo({programId:e,network:s});(0,t.expect)(o.isLeft()).toBe(!0),(0,t.expect)(o.extract().message).toMatch(new RegExp(String.raw`\[ContextModule\] HttpInstructionInfoDataSource: malformed response for program ${e}:`))}),(0,t.it)("returns Left when the response doesn't contain the requested programId",async()=>{r.get.mockResolvedValue([{descriptors_instruction:{OtherProgram:{}}}]);const o=await n.getInstructionInfo({programId:e,network:s});(0,t.expect)(o).toEqual((0,a.Left)(new Error(`[ContextModule] HttpInstructionInfoDataSource: no descriptors for program ${e}`)))}),(0,t.it)("returns Left (not a throw) when an inner descriptor is malformed",async()=>{r.get.mockResolvedValue([{descriptors_instruction:{[e]:{"00000000":{type:"instruction",instruction_info:{}}}}}]);const o=await n.getInstructionInfo({programId:e,network:s});(0,t.expect)(o.isLeft()).toBe(!0),(0,t.expect)(o.extract().message).toMatch(new RegExp(String.raw`\[ContextModule\] HttpInstructionInfoDataSource: malformed descriptors for program ${e}:`))}),(0,t.it)("returns Left when the HTTP client throws",async()=>{r.get.mockRejectedValue(new Error("network"));const o=await n.getInstructionInfo({programId:e,network:s});(0,t.expect)(o).toEqual((0,a.Left)(new Error("[ContextModule] HttpInstructionInfoDataSource: Failed to fetch instruction descriptors: network")))})});
1
+ "use strict";var a=require("purify-ts"),t=require("vitest"),c=require("./HttpInstructionInfoDataSource");(0,t.describe)("HttpInstructionInfoDataSource",()=>{let n,r;const e="11111111111111111111111111111111",s="solana-mainnet",u={cal:{url:"https://crypto-assets-service.api.ledger.com/v1",mode:"prod",branch:"main"}},i=[{descriptors_instruction:{[e]:{"00000000":{type:"instruction",network:"solana-mainnet",version:"v1",instruction_info:{version:1,program_id:e,discriminator:"00000000",hash:"deadbeef",descriptor:{data:"00010101",signatures:{prod:"prodsig",test:"testsig"}}},display_fields:[],value_flow_ports:[],hide_rules:[],account_resets:[]}}}}];(0,t.beforeEach)(()=>{t.vi.clearAllMocks(),r={get:t.vi.fn()},n=new c.HttpInstructionInfoDataSource(u,r)}),(0,t.it)("calls CAL with singular program= and ref=branch:<branch>",async()=>{r.get.mockResolvedValue(i),await n.getInstructionInfo({programId:e,network:s}),(0,t.expect)(r.get).toHaveBeenCalledTimes(1),(0,t.expect)(r.get).toHaveBeenCalledWith("https://crypto-assets-service.api.ledger.com/v1/solana",{params:{output:"descriptors_instruction",network:s,program:e,ref:"branch:main"}})}),(0,t.it)("returns Right with each descriptor transformed into the core payload on success",async()=>{r.get.mockResolvedValue(i);const o=await n.getInstructionInfo({programId:e,network:s});(0,t.expect)(o).toEqual((0,a.Right)({programId:e,descriptors:{"00000000":(0,a.Right)({programId:e,discriminator:"00000000",instructionInfo:{data:"00010101",signature:"prodsig"},substructures:[],enumVariants:[],idlDescriptor:{typePool:[],rootType:0},mintAssociations:[],valueFlowPorts:[],accountResets:[],displayFields:[]})},enumVariants:[]}))}),(0,t.it)("returns Left when the response array is empty",async()=>{r.get.mockResolvedValue([]);const o=await n.getInstructionInfo({programId:e,network:s});(0,t.expect)(o).toEqual((0,a.Left)(new Error(`[ContextModule] HttpInstructionInfoDataSource: empty response for program ${e}`)))}),(0,t.it)("returns Left when the envelope is malformed",async()=>{r.get.mockResolvedValue([{foo:"bar"}]);const o=await n.getInstructionInfo({programId:e,network:s});(0,t.expect)(o.isLeft()).toBe(!0),(0,t.expect)(o.extract().message).toMatch(new RegExp(String.raw`\[ContextModule\] HttpInstructionInfoDataSource: malformed response for program ${e}:`))}),(0,t.it)("returns Left when the response doesn't contain the requested programId",async()=>{r.get.mockResolvedValue([{descriptors_instruction:{OtherProgram:{}}}]);const o=await n.getInstructionInfo({programId:e,network:s});(0,t.expect)(o).toEqual((0,a.Left)(new Error(`[ContextModule] HttpInstructionInfoDataSource: no descriptors for program ${e}`)))}),(0,t.it)("returns Left (not a throw) when an inner descriptor is malformed",async()=>{r.get.mockResolvedValue([{descriptors_instruction:{[e]:{"00000000":{type:"instruction",instruction_info:{}}}}}]);const o=await n.getInstructionInfo({programId:e,network:s});(0,t.expect)(o.isLeft()).toBe(!0),(0,t.expect)(o.extract().message).toMatch(new RegExp(String.raw`\[ContextModule\] HttpInstructionInfoDataSource: malformed descriptors for program ${e}:`))}),(0,t.it)("returns Left when the HTTP client throws",async()=>{r.get.mockRejectedValue(new Error("network"));const o=await n.getInstructionInfo({programId:e,network:s});(0,t.expect)(o).toEqual((0,a.Left)(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": ["/* eslint-disable @typescript-eslint/no-explicit-any */\nimport { type DmkNetworkClient } from \"@ledgerhq/device-management-kit\";\nimport { Left, Right } from \"purify-ts\";\nimport { beforeEach, describe, expect, it, vi } from \"vitest\";\n\nimport { type ContextModuleServiceConfig } from \"@/config/model/ContextModuleConfig\";\n\nimport { HttpInstructionInfoDataSource } from \"./HttpInstructionInfoDataSource\";\nimport { type InstructionInfoDataSource } from \"./InstructionInfoDataSource\";\nimport { type CalInstructionInfoResponseDto } from \"./InstructionInfoDto\";\n\ndescribe(\"HttpInstructionInfoDataSource\", () => {\n let datasource: InstructionInfoDataSource;\n let httpMock: { get: ReturnType<typeof vi.fn> };\n const programId = \"11111111111111111111111111111111\";\n const network = \"solana-mainnet\";\n const config: ContextModuleServiceConfig = {\n cal: {\n url: \"https://crypto-assets-service.api.ledger.com/v1\",\n mode: \"prod\",\n branch: \"main\",\n },\n } as ContextModuleServiceConfig;\n\n const successResponse: CalInstructionInfoResponseDto = [\n {\n descriptors_instruction: {\n [programId]: {\n \"00000000\": {\n type: \"instruction\",\n network: \"solana-mainnet\",\n version: \"v1\",\n instruction_info: {\n version: 1,\n program_id: programId,\n discriminator: \"00000000\",\n hash: \"deadbeef\",\n descriptor: {\n data: \"00010101\",\n signatures: { prod: \"prodsig\", test: \"testsig\" },\n },\n },\n display_fields: [],\n value_flow_ports: [],\n hide_rules: [],\n account_resets: [],\n },\n },\n },\n },\n ];\n\n beforeEach(() => {\n vi.clearAllMocks();\n httpMock = { get: vi.fn() };\n datasource = new HttpInstructionInfoDataSource(\n config,\n httpMock as unknown as DmkNetworkClient,\n );\n });\n\n it(\"calls CAL with singular program= and ref=branch:<branch>\", async () => {\n httpMock.get.mockResolvedValue(successResponse);\n\n await datasource.getInstructionInfo({ programId, network });\n\n expect(httpMock.get).toHaveBeenCalledTimes(1);\n expect(httpMock.get).toHaveBeenCalledWith(\n \"https://crypto-assets-service.api.ledger.com/v1/solana\",\n {\n params: {\n output: \"descriptors_instruction\",\n network,\n program: programId,\n ref: \"branch:main\",\n },\n },\n );\n });\n\n it(\"returns Right with the unwrapped descriptors map on success\", async () => {\n httpMock.get.mockResolvedValue(successResponse);\n\n const result = await datasource.getInstructionInfo({ programId, network });\n\n const [firstResponse] = successResponse;\n if (!firstResponse)\n throw new Error(\"fixture: successResponse must be non-empty\");\n expect(result).toEqual(\n Right({\n programId,\n descriptors: (firstResponse.descriptors_instruction as any)[programId],\n }),\n );\n });\n\n it(\"returns Left when the response array is empty\", async () => {\n httpMock.get.mockResolvedValue([]);\n\n const result = await datasource.getInstructionInfo({ programId, network });\n\n expect(result).toEqual(\n Left(\n new Error(\n `[ContextModule] HttpInstructionInfoDataSource: empty response for program ${programId}`,\n ),\n ),\n );\n });\n\n it(\"returns Left when the envelope is malformed\", async () => {\n httpMock.get.mockResolvedValue([{ foo: \"bar\" }]);\n\n const result = await datasource.getInstructionInfo({ programId, network });\n\n expect(result.isLeft()).toBe(true);\n expect((result.extract() as Error).message).toMatch(\n new RegExp(\n String.raw`\\[ContextModule\\] HttpInstructionInfoDataSource: malformed response for program ${programId}:`,\n ),\n );\n });\n\n it(\"returns Left when the response doesn't contain the requested programId\", async () => {\n httpMock.get.mockResolvedValue([\n { descriptors_instruction: { OtherProgram: {} } },\n ]);\n\n const result = await datasource.getInstructionInfo({ programId, network });\n\n expect(result).toEqual(\n Left(\n new Error(\n `[ContextModule] HttpInstructionInfoDataSource: no descriptors for program ${programId}`,\n ),\n ),\n );\n });\n\n it(\"returns Left (not a throw) when an inner descriptor is malformed\", async () => {\n // `instruction_info.descriptor` missing \u2014 would crash the loader if the\n // datasource handed it through unvalidated.\n httpMock.get.mockResolvedValue([\n {\n descriptors_instruction: {\n [programId]: {\n \"00000000\": { type: \"instruction\", instruction_info: {} },\n },\n },\n },\n ]);\n\n const result = await datasource.getInstructionInfo({ programId, network });\n\n expect(result.isLeft()).toBe(true);\n expect((result.extract() as Error).message).toMatch(\n new RegExp(\n String.raw`\\[ContextModule\\] HttpInstructionInfoDataSource: malformed descriptors for program ${programId}:`,\n ),\n );\n });\n\n it(\"returns Left when the HTTP client throws\", async () => {\n httpMock.get.mockRejectedValue(new Error(\"network\"));\n\n const result = await datasource.getInstructionInfo({ programId, network });\n\n expect(result).toEqual(\n Left(\n new Error(\n \"[ContextModule] HttpInstructionInfoDataSource: Failed to fetch instruction descriptors: network\",\n ),\n ),\n );\n });\n});\n"],
5
- "mappings": "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",
6
- "names": ["import_purify_ts", "import_vitest", "import_HttpInstructionInfoDataSource", "datasource", "httpMock", "programId", "network", "config", "successResponse", "result", "firstResponse"]
4
+ "sourcesContent": ["import { type DmkNetworkClient } from \"@ledgerhq/device-management-kit\";\nimport { Left, Right } from \"purify-ts\";\nimport { beforeEach, describe, expect, it, vi } from \"vitest\";\n\nimport { type ContextModuleServiceConfig } from \"@/config/model/ContextModuleConfig\";\n\nimport { HttpInstructionInfoDataSource } from \"./HttpInstructionInfoDataSource\";\nimport { type InstructionInfoDataSource } from \"./InstructionInfoDataSource\";\nimport { type CalInstructionInfoResponseDto } from \"./InstructionInfoDto\";\n\ndescribe(\"HttpInstructionInfoDataSource\", () => {\n let datasource: InstructionInfoDataSource;\n let httpMock: { get: ReturnType<typeof vi.fn> };\n const programId = \"11111111111111111111111111111111\";\n const network = \"solana-mainnet\";\n const config: ContextModuleServiceConfig = {\n cal: {\n url: \"https://crypto-assets-service.api.ledger.com/v1\",\n mode: \"prod\",\n branch: \"main\",\n },\n } as ContextModuleServiceConfig;\n\n const successResponse: CalInstructionInfoResponseDto = [\n {\n descriptors_instruction: {\n [programId]: {\n \"00000000\": {\n type: \"instruction\",\n network: \"solana-mainnet\",\n version: \"v1\",\n instruction_info: {\n version: 1,\n program_id: programId,\n discriminator: \"00000000\",\n hash: \"deadbeef\",\n descriptor: {\n data: \"00010101\",\n signatures: { prod: \"prodsig\", test: \"testsig\" },\n },\n },\n display_fields: [],\n value_flow_ports: [],\n hide_rules: [],\n account_resets: [],\n },\n },\n },\n },\n ];\n\n beforeEach(() => {\n vi.clearAllMocks();\n httpMock = { get: vi.fn() };\n datasource = new HttpInstructionInfoDataSource(\n config,\n httpMock as unknown as DmkNetworkClient,\n );\n });\n\n it(\"calls CAL with singular program= and ref=branch:<branch>\", async () => {\n httpMock.get.mockResolvedValue(successResponse);\n\n await datasource.getInstructionInfo({ programId, network });\n\n expect(httpMock.get).toHaveBeenCalledTimes(1);\n expect(httpMock.get).toHaveBeenCalledWith(\n \"https://crypto-assets-service.api.ledger.com/v1/solana\",\n {\n params: {\n output: \"descriptors_instruction\",\n network,\n program: programId,\n ref: \"branch:main\",\n },\n },\n );\n });\n\n it(\"returns Right with each descriptor transformed into the core payload on success\", async () => {\n httpMock.get.mockResolvedValue(successResponse);\n\n const result = await datasource.getInstructionInfo({ programId, network });\n\n expect(result).toEqual(\n Right({\n programId,\n descriptors: {\n \"00000000\": Right({\n programId,\n discriminator: \"00000000\",\n instructionInfo: { data: \"00010101\", signature: \"prodsig\" },\n substructures: [],\n enumVariants: [],\n idlDescriptor: { typePool: [], rootType: 0 },\n mintAssociations: [],\n valueFlowPorts: [],\n accountResets: [],\n displayFields: [],\n }),\n },\n enumVariants: [],\n }),\n );\n });\n\n it(\"returns Left when the response array is empty\", async () => {\n httpMock.get.mockResolvedValue([]);\n\n const result = await datasource.getInstructionInfo({ programId, network });\n\n expect(result).toEqual(\n Left(\n new Error(\n `[ContextModule] HttpInstructionInfoDataSource: empty response for program ${programId}`,\n ),\n ),\n );\n });\n\n it(\"returns Left when the envelope is malformed\", async () => {\n httpMock.get.mockResolvedValue([{ foo: \"bar\" }]);\n\n const result = await datasource.getInstructionInfo({ programId, network });\n\n expect(result.isLeft()).toBe(true);\n expect((result.extract() as Error).message).toMatch(\n new RegExp(\n String.raw`\\[ContextModule\\] HttpInstructionInfoDataSource: malformed response for program ${programId}:`,\n ),\n );\n });\n\n it(\"returns Left when the response doesn't contain the requested programId\", async () => {\n httpMock.get.mockResolvedValue([\n { descriptors_instruction: { OtherProgram: {} } },\n ]);\n\n const result = await datasource.getInstructionInfo({ programId, network });\n\n expect(result).toEqual(\n Left(\n new Error(\n `[ContextModule] HttpInstructionInfoDataSource: no descriptors for program ${programId}`,\n ),\n ),\n );\n });\n\n it(\"returns Left (not a throw) when an inner descriptor is malformed\", async () => {\n // `instruction_info.descriptor` missing \u2014 would crash the loader if the\n // datasource handed it through unvalidated.\n httpMock.get.mockResolvedValue([\n {\n descriptors_instruction: {\n [programId]: {\n \"00000000\": { type: \"instruction\", instruction_info: {} },\n },\n },\n },\n ]);\n\n const result = await datasource.getInstructionInfo({ programId, network });\n\n expect(result.isLeft()).toBe(true);\n expect((result.extract() as Error).message).toMatch(\n new RegExp(\n String.raw`\\[ContextModule\\] HttpInstructionInfoDataSource: malformed descriptors for program ${programId}:`,\n ),\n );\n });\n\n it(\"returns Left when the HTTP client throws\", async () => {\n httpMock.get.mockRejectedValue(new Error(\"network\"));\n\n const result = await datasource.getInstructionInfo({ programId, network });\n\n expect(result).toEqual(\n Left(\n new Error(\n \"[ContextModule] HttpInstructionInfoDataSource: Failed to fetch instruction descriptors: network\",\n ),\n ),\n );\n });\n});\n"],
5
+ "mappings": "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",
6
+ "names": ["import_purify_ts", "import_vitest", "import_HttpInstructionInfoDataSource", "datasource", "httpMock", "programId", "network", "config", "successResponse", "result"]
7
7
  }
@@ -1,2 +1,2 @@
1
- "use strict";var e=Object.defineProperty;var i=Object.getOwnPropertyDescriptor;var I=Object.getOwnPropertyNames;var p=Object.prototype.hasOwnProperty;var c=(r,t,s,n)=>{if(t&&typeof t=="object"||typeof t=="function")for(let o of I(t))!p.call(r,o)&&o!==s&&e(r,o,{get:()=>t[o],enumerable:!(n=i(t,o))||n.enumerable});return r};var a=r=>c(e({},"__esModule",{value:!0}),r);var u={};module.exports=a(u);
1
+ "use strict";var a=Object.defineProperty;var e=Object.getOwnPropertyDescriptor;var s=Object.getOwnPropertyNames;var I=Object.prototype.hasOwnProperty;var u=(r,t,i,o)=>{if(t&&typeof t=="object"||typeof t=="function")for(let n of s(t))!I.call(r,n)&&n!==i&&a(r,n,{get:()=>t[n],enumerable:!(o=e(t,n))||o.enumerable});return r};var c=r=>u(a({},"__esModule",{value:!0}),r);var p={};module.exports=c(p);
2
2
  //# sourceMappingURL=InstructionInfoDataSource.js.map
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "version": 3,
3
3
  "sources": ["../../../../../../../src/modules/solana/instruction-info/data/InstructionInfoDataSource.ts"],
4
- "sourcesContent": ["import { type Either } from \"purify-ts\";\n\nimport { type CalInstructionDescriptorDto } from \"./InstructionInfoDto\";\n\nexport type GetInstructionInfoParams = {\n programId: string;\n network: string;\n};\n\n/**\n * Result of one CAL call for a single `programId`. Indexed by discriminator\n * hex; multiple entries when a program defines several instructions.\n */\nexport type InstructionInfoResult = {\n programId: string;\n descriptors: Record<string, CalInstructionDescriptorDto>;\n};\n\nexport interface InstructionInfoDataSource {\n /**\n * Fetch all instruction descriptors for one Solana program from CAL.\n * One HTTP call per `programId`; consumers fan out across multiple\n * `programId`s in parallel.\n */\n getInstructionInfo(\n params: GetInstructionInfoParams,\n ): Promise<Either<Error, InstructionInfoResult>>;\n}\n"],
4
+ "sourcesContent": ["import { type Either } from \"purify-ts\";\n\nimport {\n type SolanaInstructionEnumVariant,\n type SolanaInstructionInfoPayload,\n} from \"@/modules/solana/model/SolanaPayloads\";\n\nexport type GetInstructionInfoParams = {\n programId: string;\n network: string;\n};\n\n/**\n * Result of one CAL call for a single `programId`, fully transformed into core\n * models so consumers never see the CAL DTO shapes.\n *\n * - `descriptors` is indexed by discriminator hex (multiple entries when a\n * program defines several instructions). Each is the decoded\n * {@link SolanaInstructionInfoPayload}, or a `Left` when that descriptor could\n * not be decoded (e.g. no signature for the configured CAL mode) so the\n * consumer can surface a per-descriptor error.\n * - `enumVariants` is the program-wide flat list of decoded enum variants,\n * resolved independently of per-descriptor signature validity.\n */\nexport type InstructionInfoResult = {\n programId: string;\n descriptors: Record<string, Either<Error, SolanaInstructionInfoPayload>>;\n enumVariants: SolanaInstructionEnumVariant[];\n};\n\nexport interface InstructionInfoDataSource {\n /**\n * Fetch all instruction descriptors for one Solana program from CAL.\n * One HTTP call per `programId`; consumers fan out across multiple\n * `programId`s in parallel.\n */\n getInstructionInfo(\n params: GetInstructionInfoParams,\n ): Promise<Either<Error, InstructionInfoResult>>;\n}\n"],
5
5
  "mappings": "+WAAA,IAAAA,EAAA,kBAAAC,EAAAD",
6
6
  "names": ["InstructionInfoDataSource_exports", "__toCommonJS"]
7
7
  }
@@ -1,2 +1,2 @@
1
- "use strict";var i=Object.defineProperty;var u=Object.getOwnPropertyDescriptor;var p=Object.getOwnPropertyNames;var d=Object.prototype.hasOwnProperty;var l=(n,r)=>{for(var e in r)i(n,e,{get:r[e],enumerable:!0})},g=(n,r,e,a)=>{if(r&&typeof r=="object"||typeof r=="function")for(let o of p(r))!d.call(n,o)&&o!==e&&i(n,o,{get:()=>r[o],enumerable:!(a=u(r,o))||a.enumerable});return n};var _=n=>g(i({},"__esModule",{value:!0}),n);var S={};l(S,{calInstructionDescriptorsCodec:()=>y});module.exports=_(S);var t=require("purify-ts");const c=t.Codec.interface({prod:(0,t.optional)(t.string),test:(0,t.optional)(t.string)}),C=t.Codec.interface({data:t.string,signatures:c}),D=t.Codec.interface({program_id:t.string,descriptor:C}),f=t.Codec.interface({data:t.string,signatures:c}),s=t.Codec.interface({descriptor:t.string}),m=t.Codec.interface({instruction_info:D,enum_variants:(0,t.optional)((0,t.record)(t.string,(0,t.record)(t.string,f))),display_fields:(0,t.optional)((0,t.array)(s)),value_flow_ports:(0,t.optional)((0,t.array)(s)),hide_rules:(0,t.optional)((0,t.array)(s)),account_resets:(0,t.optional)((0,t.array)(s))}),y=(0,t.record)(t.string,m);0&&(module.exports={calInstructionDescriptorsCodec});
1
+ "use strict";var a=Object.defineProperty;var u=Object.getOwnPropertyDescriptor;var l=Object.getOwnPropertyNames;var p=Object.prototype.hasOwnProperty;var d=(e,r)=>{for(var o in r)a(e,o,{get:r[o],enumerable:!0})},g=(e,r,o,s)=>{if(r&&typeof r=="object"||typeof r=="function")for(let n of l(r))!p.call(e,n)&&n!==o&&a(e,n,{get:()=>r[n],enumerable:!(s=u(r,n))||s.enumerable});return e};var _=e=>g(a({},"__esModule",{value:!0}),e);var x={};d(x,{calInstructionDescriptorsCodec:()=>b});module.exports=_(x);var t=require("purify-ts");const c=t.Codec.interface({prod:(0,t.optional)(t.string),test:(0,t.optional)(t.string)}),C=t.Codec.interface({data:t.string,signatures:c}),D=t.Codec.interface({program_id:t.string,descriptor:C}),m=t.Codec.interface({data:t.string,signatures:c}),i=t.Codec.interface({descriptor:t.string}),y=t.Codec.interface({instruction_info:D,enum_variants:(0,t.optional)((0,t.record)(t.string,(0,t.record)(t.string,m))),display_fields:(0,t.optional)((0,t.array)(i)),value_flow_ports:(0,t.optional)((0,t.array)(i)),hide_rules:(0,t.optional)((0,t.array)(i)),account_resets:(0,t.optional)((0,t.array)(i))}),b=(0,t.record)(t.string,y);0&&(module.exports={calInstructionDescriptorsCodec});
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, 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\nexport type CalInstructionInfoDto = {\n version: number;\n program_id: string;\n discriminator: string;\n hash: string;\n operation_type?: string;\n program_name?: string;\n descriptor: CalSignedDescriptorDto;\n idl_descriptor?: {\n type_pool?: unknown;\n root_type?: number;\n };\n mint_association?: unknown;\n owner_association?: unknown;\n};\n\nexport type CalEnumVariantDto = {\n variant_name: string;\n payload_kind?: string;\n data: string;\n signatures: CalSignatures;\n};\n\nexport type CalSubstructureDto = {\n descriptor: string;\n};\n\nexport type CalInstructionDescriptorDto = {\n type: string;\n source?: string;\n network?: string;\n version?: string;\n instruction_info: CalInstructionInfoDto;\n enum_variants?: Record<string, Record<string, CalEnumVariantDto>>;\n display_fields?: CalSubstructureDto[];\n value_flow_ports?: CalSubstructureDto[];\n hide_rules?: CalSubstructureDto[];\n account_resets?: CalSubstructureDto[];\n};\n\n// Outer shape: array containing one envelope object keyed by program_id\n// then by discriminator hex.\nexport type CalInstructionInfoResponseDto = Array<{\n descriptors_instruction: Record<\n string,\n Record<string, CalInstructionDescriptorDto>\n >;\n}>;\n\n// --- Validation codecs (runtime). Validate only the fields the loaders read;\n// `Codec.interface` ignores unknown extras so CAL can add fields freely. ---\n\nconst calSignaturesCodec = Codec.interface({\n prod: optional(string),\n test: optional(string),\n});\n\nconst calSignedDescriptorCodec = Codec.interface({\n data: string,\n signatures: calSignaturesCodec,\n});\n\nconst calInstructionInfoCodec = Codec.interface({\n program_id: string,\n descriptor: calSignedDescriptorCodec,\n});\n\nconst calEnumVariantCodec = Codec.interface({\n data: string,\n signatures: calSignaturesCodec,\n});\n\nconst calSubstructureCodec = Codec.interface({\n descriptor: string,\n});\n\nconst calInstructionDescriptorCodec = Codec.interface({\n instruction_info: calInstructionInfoCodec,\n enum_variants: optional(record(string, record(string, calEnumVariantCodec))),\n display_fields: optional(array(calSubstructureCodec)),\n value_flow_ports: optional(array(calSubstructureCodec)),\n hide_rules: optional(array(calSubstructureCodec)),\n account_resets: optional(array(calSubstructureCodec)),\n});\n\n/**\n * Codec for the per-program descriptor map (keyed by discriminator hex).\n * Used by the datasource to validate the inner CAL payload before handing\n * it to the loaders. Only loader-consumed fields are validated; unrelated\n * CAL fields (`idl_descriptor`, `mint_association`, \u2026) are ignored.\n */\nexport const calInstructionDescriptorsCodec = record(\n string,\n calInstructionDescriptorCodec,\n);\n"],
5
- "mappings": "yaAAA,IAAAA,EAAA,GAAAC,EAAAD,EAAA,oCAAAE,IAAA,eAAAC,EAAAH,GAQA,IAAAI,EAAuD,qBAgEvD,MAAMC,EAAqB,QAAM,UAAU,CACzC,QAAM,YAAS,QAAM,EACrB,QAAM,YAAS,QAAM,CACvB,CAAC,EAEKC,EAA2B,QAAM,UAAU,CAC/C,KAAM,SACN,WAAYD,CACd,CAAC,EAEKE,EAA0B,QAAM,UAAU,CAC9C,WAAY,SACZ,WAAYD,CACd,CAAC,EAEKE,EAAsB,QAAM,UAAU,CAC1C,KAAM,SACN,WAAYH,CACd,CAAC,EAEKI,EAAuB,QAAM,UAAU,CAC3C,WAAY,QACd,CAAC,EAEKC,EAAgC,QAAM,UAAU,CACpD,iBAAkBH,EAClB,iBAAe,eAAS,UAAO,YAAQ,UAAO,SAAQC,CAAmB,CAAC,CAAC,EAC3E,kBAAgB,eAAS,SAAMC,CAAoB,CAAC,EACpD,oBAAkB,eAAS,SAAMA,CAAoB,CAAC,EACtD,cAAY,eAAS,SAAMA,CAAoB,CAAC,EAChD,kBAAgB,eAAS,SAAMA,CAAoB,CAAC,CACtD,CAAC,EAQYP,KAAiC,UAC5C,SACAQ,CACF",
4
+ "sourcesContent": ["// DTO + codecs for the CAL instruction-descriptors response (one object per\n// `programId`, wrapped in a JSON array).\n//\n// The hand-written types describe the consumed shape (with genuinely optional\n// `?:` fields); the codecs below validate that shape at runtime so\n// `HttpInstructionInfoDataSource` can hand the loaders a payload they can\n// dereference without runtime-throwing on a malformed descriptor.\n\nimport { array, Codec, optional, record, string } from \"purify-ts\";\n\nexport type CalSignatures = {\n prod?: string;\n test?: string;\n};\n\nexport type CalSignedDescriptorDto = {\n data: string;\n signatures: CalSignatures;\n};\n\n// Decoded CAL JSON shapes (snake_case mirrors the CAL response) that drive\n// host-side requirement building.\n\nexport type CalValueDto = {\n source: string;\n account_index?: number;\n data?: string;\n path?: { steps: number[] };\n};\n\nexport type CalTokenValueDto = {\n kind: string;\n value?: CalValueDto;\n account_index?: number;\n};\n\nexport type CalMintAssociationDto = {\n account_index: number;\n mint_index: number;\n};\n\nexport type CalTypePoolEntryDto = {\n index: number;\n kind: string;\n refs?: number[];\n size?: number;\n encoding?: number;\n len_kind?: string;\n flag_kind?: string;\n sentinel?: string;\n disc_kind?: string;\n total_variants?: number;\n enum_id?: string;\n};\n\nexport type CalInstructionInfoDto = {\n version: number;\n program_id: string;\n discriminator: string;\n hash: string;\n operation_type?: string;\n program_name?: string;\n descriptor: CalSignedDescriptorDto;\n idl_descriptor?: {\n type_pool?: CalTypePoolEntryDto[];\n root_type?: number;\n };\n mint_association?: CalMintAssociationDto;\n owner_association?: unknown;\n};\n\nexport type CalEnumVariantDto = {\n variant_name: string;\n payload_kind?: string;\n data: string;\n signatures: CalSignatures;\n};\n\n/** A substructure CAL serves only as opaque TLV (e.g. HIDE_RULE). */\nexport type CalSubstructureDto = {\n descriptor: string;\n};\n\nexport type CalValueFlowPortDto = CalSubstructureDto & {\n account_indices?: number[];\n account_index?: number;\n optional_account_strategy?: string;\n token_value?: CalTokenValueDto;\n};\n\nexport type CalAccountResetDto = CalSubstructureDto & {\n account_index?: number;\n require_pre_balance_zero?: boolean;\n};\n\nexport type CalDisplayFieldDto = CalSubstructureDto & {\n name?: string;\n param?: { type: string; value?: CalValueDto; token?: CalValueDto };\n};\n\nexport type CalInstructionDescriptorDto = {\n type: string;\n source?: string;\n network?: string;\n version?: string;\n instruction_info: CalInstructionInfoDto;\n enum_variants?: Record<string, Record<string, CalEnumVariantDto>>;\n display_fields?: CalDisplayFieldDto[];\n value_flow_ports?: CalValueFlowPortDto[];\n hide_rules?: CalSubstructureDto[];\n account_resets?: CalAccountResetDto[];\n};\n\n// Outer shape: array containing one envelope object keyed by program_id\n// then by discriminator hex.\nexport type CalInstructionInfoResponseDto = Array<{\n descriptors_instruction: Record<\n string,\n Record<string, CalInstructionDescriptorDto>\n >;\n}>;\n\n// --- Validation codecs (runtime). Validate only the fields the loaders read;\n// `Codec.interface` ignores unknown extras so CAL can add fields freely. ---\n\nconst calSignaturesCodec = Codec.interface({\n prod: optional(string),\n test: optional(string),\n});\n\nconst calSignedDescriptorCodec = Codec.interface({\n data: string,\n signatures: calSignaturesCodec,\n});\n\nconst calInstructionInfoCodec = Codec.interface({\n program_id: string,\n descriptor: calSignedDescriptorCodec,\n});\n\nconst calEnumVariantCodec = Codec.interface({\n data: string,\n signatures: calSignaturesCodec,\n});\n\nconst calSubstructureCodec = Codec.interface({\n descriptor: string,\n});\n\nconst calInstructionDescriptorCodec = Codec.interface({\n instruction_info: calInstructionInfoCodec,\n enum_variants: optional(record(string, record(string, calEnumVariantCodec))),\n display_fields: optional(array(calSubstructureCodec)),\n value_flow_ports: optional(array(calSubstructureCodec)),\n hide_rules: optional(array(calSubstructureCodec)),\n account_resets: optional(array(calSubstructureCodec)),\n});\n\n/**\n * Codec for the per-program descriptor map (keyed by discriminator hex).\n * Used by the datasource to validate the inner CAL payload before handing\n * it to the loaders. Only loader-consumed fields are validated; unrelated\n * CAL fields (`idl_descriptor`, `mint_association`, \u2026) are ignored.\n */\nexport const calInstructionDescriptorsCodec = record(\n string,\n calInstructionDescriptorCodec,\n);\n"],
5
+ "mappings": "yaAAA,IAAAA,EAAA,GAAAC,EAAAD,EAAA,oCAAAE,IAAA,eAAAC,EAAAH,GAQA,IAAAI,EAAuD,qBAqHvD,MAAMC,EAAqB,QAAM,UAAU,CACzC,QAAM,YAAS,QAAM,EACrB,QAAM,YAAS,QAAM,CACvB,CAAC,EAEKC,EAA2B,QAAM,UAAU,CAC/C,KAAM,SACN,WAAYD,CACd,CAAC,EAEKE,EAA0B,QAAM,UAAU,CAC9C,WAAY,SACZ,WAAYD,CACd,CAAC,EAEKE,EAAsB,QAAM,UAAU,CAC1C,KAAM,SACN,WAAYH,CACd,CAAC,EAEKI,EAAuB,QAAM,UAAU,CAC3C,WAAY,QACd,CAAC,EAEKC,EAAgC,QAAM,UAAU,CACpD,iBAAkBH,EAClB,iBAAe,eAAS,UAAO,YAAQ,UAAO,SAAQC,CAAmB,CAAC,CAAC,EAC3E,kBAAgB,eAAS,SAAMC,CAAoB,CAAC,EACpD,oBAAkB,eAAS,SAAMA,CAAoB,CAAC,EACtD,cAAY,eAAS,SAAMA,CAAoB,CAAC,EAChD,kBAAgB,eAAS,SAAMA,CAAoB,CAAC,CACtD,CAAC,EAQYP,KAAiC,UAC5C,SACAQ,CACF",
6
6
  "names": ["InstructionInfoDto_exports", "__export", "calInstructionDescriptorsCodec", "__toCommonJS", "import_purify_ts", "calSignaturesCodec", "calSignedDescriptorCodec", "calInstructionInfoCodec", "calEnumVariantCodec", "calSubstructureCodec", "calInstructionDescriptorCodec"]
7
7
  }
@@ -0,0 +1,2 @@
1
+ "use strict";var s=Object.defineProperty;var C=Object.getOwnPropertyDescriptor;var I=Object.getOwnPropertyNames;var D=Object.prototype.hasOwnProperty;var S=(n,t)=>{for(var a in t)s(n,a,{get:t[a],enumerable:!0})},g=(n,t,a,o)=>{if(t&&typeof t=="object"||typeof t=="function")for(let r of I(t))!D.call(n,r)&&r!==a&&s(n,r,{get:()=>t[r],enumerable:!(o=C(t,r))||o.enumerable});return n};var E=n=>g(s({},"__esModule",{value:!0}),n);var P={};S(P,{toAccountResets:()=>_,toDisplayFields:()=>f,toInstructionInfoPayload:()=>V,toProgramEnumVariants:()=>F,toValueFlowPorts:()=>d});module.exports=E(P);var i=require("purify-ts"),e=require("../../../../modules/solana/model/SolanaPayloads"),l=require("../../../../shared/utils/uIntCodec");function p(n,t){return n[t]}function d(n=[]){return n.map(t=>({account_indices:t.account_indices,account_index:t.account_index,optional_account_strategy:t.optional_account_strategy,token_value:t.token_value}))}function _(n=[]){return n.flatMap(t=>t.account_index===void 0?[]:[{account_index:t.account_index,require_pre_balance_zero:t.require_pre_balance_zero}])}function f(n=[]){return n.map(t=>({name:t.name,param:t.param??{type:""}}))}function x(n){return[...(n.display_fields??[]).map(t=>({kind:e.SolanaInstructionSubstructureKind.DISPLAY_FIELD,data:t.descriptor})),...(n.value_flow_ports??[]).map(t=>({kind:e.SolanaInstructionSubstructureKind.VALUE_FLOW_PORT,data:t.descriptor})),...(n.hide_rules??[]).map(t=>({kind:e.SolanaInstructionSubstructureKind.HIDE_RULE,data:t.descriptor})),...(n.account_resets??[]).map(t=>({kind:e.SolanaInstructionSubstructureKind.ACCOUNT_RESET,data:t.descriptor}))]}function m(n,t){const a=[];for(const[o,r]of Object.entries(n.enum_variants??{}))for(const[y,u]of Object.entries(r)){const c=Number(y);l.u16Codec.decode(c).isLeft()||a.push({enumId:o,variantIndex:c,descriptor:{data:u.data,signature:p(u.signatures,t)??""}})}return a}function F(n,t){return Object.values(n).flatMap(a=>m(a,t))}function V(n,t,a){const o=t.instruction_info,r=p(o.descriptor.signatures,a);return r?(0,i.Right)({programId:o.program_id,discriminator:n,instructionInfo:{data:o.descriptor.data,signature:r},substructures:x(t),enumVariants:m(t,a),idlDescriptor:{typePool:o.idl_descriptor?.type_pool??[],rootType:o.idl_descriptor?.root_type??0},mintAssociations:o.mint_association?[o.mint_association]:[],valueFlowPorts:d(t.value_flow_ports),accountResets:_(t.account_resets),displayFields:f(t.display_fields)}):(0,i.Left)(new Error(`[ContextModule] InstructionInfoDataSource: missing '${a}' signature for (${o.program_id}, ${n})`))}0&&(module.exports={toAccountResets,toDisplayFields,toInstructionInfoPayload,toProgramEnumVariants,toValueFlowPorts});
2
+ //# sourceMappingURL=InstructionInfoMapper.js.map
@@ -0,0 +1,7 @@
1
+ {
2
+ "version": 3,
3
+ "sources": ["../../../../../../../src/modules/solana/instruction-info/data/InstructionInfoMapper.ts"],
4
+ "sourcesContent": ["// Maps the validated CAL instruction-descriptor DTOs into the core\n// `SolanaInstructionInfoPayload` model. Keeping this in the data layer means\n// the domain `InstructionInfoContextLoader` never has to know the CAL DTO\n// shapes \u2014 it consumes core models only.\n\nimport { type Either, Left, Right } from \"purify-ts\";\n\nimport {\n type SolanaCalAccountReset,\n type SolanaCalDisplayField,\n type SolanaCalValueFlowPort,\n type SolanaInstructionEnumVariant,\n type SolanaInstructionInfoPayload,\n type SolanaInstructionSubstructure,\n SolanaInstructionSubstructureKind,\n} from \"@/modules/solana/model/SolanaPayloads\";\nimport { u16Codec } from \"@/shared/utils/uIntCodec\";\n\nimport {\n type CalAccountResetDto,\n type CalDisplayFieldDto,\n type CalInstructionDescriptorDto,\n type CalSignatures,\n type CalValueFlowPortDto,\n} from \"./InstructionInfoDto\";\n\nexport type CalMode = \"prod\" | \"test\";\n\nfunction pickSignature(\n signatures: CalSignatures,\n mode: CalMode,\n): string | undefined {\n return signatures[mode];\n}\n\n// --- DTO \u2192 decoded-payload projections. Pick only the fields the host-side\n// requirement builder reads, dropping the signed-TLV `descriptor` carried by\n// the DTO. ---\n\nexport function toValueFlowPorts(\n dtos: CalValueFlowPortDto[] = [],\n): SolanaCalValueFlowPort[] {\n return dtos.map((port) => ({\n account_indices: port.account_indices,\n account_index: port.account_index,\n optional_account_strategy: port.optional_account_strategy,\n token_value: port.token_value,\n }));\n}\n\nexport function toAccountResets(\n dtos: CalAccountResetDto[] = [],\n): SolanaCalAccountReset[] {\n // Drop malformed resets (missing account_index) rather than defaulting to\n // slot 0, which would create an unintended TOKEN_ACCOUNT_STATE requirement.\n return dtos.flatMap((reset) =>\n reset.account_index === undefined\n ? []\n : [\n {\n account_index: reset.account_index,\n require_pre_balance_zero: reset.require_pre_balance_zero,\n },\n ],\n );\n}\n\nexport function toDisplayFields(\n dtos: CalDisplayFieldDto[] = [],\n): SolanaCalDisplayField[] {\n return dtos.map((field) => ({\n name: field.name,\n param: field.param ?? { type: \"\" },\n }));\n}\n\nfunction toSubstructures(\n dto: CalInstructionDescriptorDto,\n): SolanaInstructionSubstructure[] {\n return [\n ...(dto.display_fields ?? []).map((s) => ({\n kind: SolanaInstructionSubstructureKind.DISPLAY_FIELD,\n data: s.descriptor,\n })),\n ...(dto.value_flow_ports ?? []).map((s) => ({\n kind: SolanaInstructionSubstructureKind.VALUE_FLOW_PORT,\n data: s.descriptor,\n })),\n ...(dto.hide_rules ?? []).map((s) => ({\n kind: SolanaInstructionSubstructureKind.HIDE_RULE,\n data: s.descriptor,\n })),\n ...(dto.account_resets ?? []).map((s) => ({\n kind: SolanaInstructionSubstructureKind.ACCOUNT_RESET,\n data: s.descriptor,\n })),\n ];\n}\n\n/**\n * Flatten the CAL-bundled enum variants (keyed enumId \u2192 variantIndex). Keys\n * that don't validate as a u16 are skipped rather than leaking NaN/out-of-range\n * indices into the payload.\n */\nfunction toEnumVariants(\n dto: CalInstructionDescriptorDto,\n mode: CalMode,\n): SolanaInstructionEnumVariant[] {\n const enumVariants: SolanaInstructionEnumVariant[] = [];\n for (const [enumId, variants] of Object.entries(dto.enum_variants ?? {})) {\n for (const [variantIndex, variant] of Object.entries(variants)) {\n const index = Number(variantIndex);\n if (u16Codec.decode(index).isLeft()) {\n continue;\n }\n enumVariants.push({\n enumId,\n variantIndex: index,\n descriptor: {\n data: variant.data,\n signature: pickSignature(variant.signatures, mode) ?? \"\",\n },\n });\n }\n }\n return enumVariants;\n}\n\n/**\n * Flatten the enum variants of every descriptor in a program into a single\n * list. CAL nests `enum_variants` inside each instruction descriptor but\n * guarantees `(enumId, variantIndex)` is unique across a program, so the enum\n * loader resolves a selection against this program-level list \u2014 independently\n * of whether any individual instruction descriptor carried a usable signature.\n */\nexport function toProgramEnumVariants(\n descriptors: Record<string, CalInstructionDescriptorDto>,\n mode: CalMode,\n): SolanaInstructionEnumVariant[] {\n return Object.values(descriptors).flatMap((dto) => toEnumVariants(dto, mode));\n}\n\n/**\n * Transform one validated CAL descriptor DTO into the core\n * {@link SolanaInstructionInfoPayload}. Returns a `Left` when the descriptor is\n * unusable (no signature for the configured `mode`), so the caller can surface\n * a per-descriptor ERROR rather than emitting an empty signature.\n */\nexport function toInstructionInfoPayload(\n discriminator: string,\n dto: CalInstructionDescriptorDto,\n mode: CalMode,\n): Either<Error, SolanaInstructionInfoPayload> {\n const info = dto.instruction_info;\n const signature = pickSignature(info.descriptor.signatures, mode);\n if (!signature) {\n return Left(\n new Error(\n `[ContextModule] InstructionInfoDataSource: missing '${mode}' signature for (${info.program_id}, ${discriminator})`,\n ),\n );\n }\n\n return Right({\n programId: info.program_id,\n discriminator,\n instructionInfo: {\n data: info.descriptor.data,\n signature,\n },\n substructures: toSubstructures(dto),\n enumVariants: toEnumVariants(dto, mode),\n idlDescriptor: {\n typePool: info.idl_descriptor?.type_pool ?? [],\n rootType: info.idl_descriptor?.root_type ?? 0,\n },\n mintAssociations: info.mint_association ? [info.mint_association] : [],\n valueFlowPorts: toValueFlowPorts(dto.value_flow_ports),\n accountResets: toAccountResets(dto.account_resets),\n displayFields: toDisplayFields(dto.display_fields),\n });\n}\n"],
5
+ "mappings": "yaAAA,IAAAA,EAAA,GAAAC,EAAAD,EAAA,qBAAAE,EAAA,oBAAAC,EAAA,6BAAAC,EAAA,0BAAAC,EAAA,qBAAAC,IAAA,eAAAC,EAAAP,GAKA,IAAAQ,EAAyC,qBAEzCC,EAQO,iDACPC,EAAyB,oCAYzB,SAASC,EACPC,EACAC,EACoB,CACpB,OAAOD,EAAWC,CAAI,CACxB,CAMO,SAASP,EACdQ,EAA8B,CAAC,EACL,CAC1B,OAAOA,EAAK,IAAKC,IAAU,CACzB,gBAAiBA,EAAK,gBACtB,cAAeA,EAAK,cACpB,0BAA2BA,EAAK,0BAChC,YAAaA,EAAK,WACpB,EAAE,CACJ,CAEO,SAASb,EACdY,EAA6B,CAAC,EACL,CAGzB,OAAOA,EAAK,QAASE,GACnBA,EAAM,gBAAkB,OACpB,CAAC,EACD,CACE,CACE,cAAeA,EAAM,cACrB,yBAA0BA,EAAM,wBAClC,CACF,CACN,CACF,CAEO,SAASb,EACdW,EAA6B,CAAC,EACL,CACzB,OAAOA,EAAK,IAAKG,IAAW,CAC1B,KAAMA,EAAM,KACZ,MAAOA,EAAM,OAAS,CAAE,KAAM,EAAG,CACnC,EAAE,CACJ,CAEA,SAASC,EACPC,EACiC,CACjC,MAAO,CACL,IAAIA,EAAI,gBAAkB,CAAC,GAAG,IAAKC,IAAO,CACxC,KAAM,oCAAkC,cACxC,KAAMA,EAAE,UACV,EAAE,EACF,IAAID,EAAI,kBAAoB,CAAC,GAAG,IAAKC,IAAO,CAC1C,KAAM,oCAAkC,gBACxC,KAAMA,EAAE,UACV,EAAE,EACF,IAAID,EAAI,YAAc,CAAC,GAAG,IAAKC,IAAO,CACpC,KAAM,oCAAkC,UACxC,KAAMA,EAAE,UACV,EAAE,EACF,IAAID,EAAI,gBAAkB,CAAC,GAAG,IAAKC,IAAO,CACxC,KAAM,oCAAkC,cACxC,KAAMA,EAAE,UACV,EAAE,CACJ,CACF,CAOA,SAASC,EACPF,EACAN,EACgC,CAChC,MAAMS,EAA+C,CAAC,EACtD,SAAW,CAACC,EAAQC,CAAQ,IAAK,OAAO,QAAQL,EAAI,eAAiB,CAAC,CAAC,EACrE,SAAW,CAACM,EAAcC,CAAO,IAAK,OAAO,QAAQF,CAAQ,EAAG,CAC9D,MAAMG,EAAQ,OAAOF,CAAY,EAC7B,WAAS,OAAOE,CAAK,EAAE,OAAO,GAGlCL,EAAa,KAAK,CAChB,OAAAC,EACA,aAAcI,EACd,WAAY,CACV,KAAMD,EAAQ,KACd,UAAWf,EAAce,EAAQ,WAAYb,CAAI,GAAK,EACxD,CACF,CAAC,CACH,CAEF,OAAOS,CACT,CASO,SAASjB,EACduB,EACAf,EACgC,CAChC,OAAO,OAAO,OAAOe,CAAW,EAAE,QAAST,GAAQE,EAAeF,EAAKN,CAAI,CAAC,CAC9E,CAQO,SAAST,EACdyB,EACAV,EACAN,EAC6C,CAC7C,MAAMiB,EAAOX,EAAI,iBACXY,EAAYpB,EAAcmB,EAAK,WAAW,WAAYjB,CAAI,EAChE,OAAKkB,KAQE,SAAM,CACX,UAAWD,EAAK,WAChB,cAAAD,EACA,gBAAiB,CACf,KAAMC,EAAK,WAAW,KACtB,UAAAC,CACF,EACA,cAAeb,EAAgBC,CAAG,EAClC,aAAcE,EAAeF,EAAKN,CAAI,EACtC,cAAe,CACb,SAAUiB,EAAK,gBAAgB,WAAa,CAAC,EAC7C,SAAUA,EAAK,gBAAgB,WAAa,CAC9C,EACA,iBAAkBA,EAAK,iBAAmB,CAACA,EAAK,gBAAgB,EAAI,CAAC,EACrE,eAAgBxB,EAAiBa,EAAI,gBAAgB,EACrD,cAAejB,EAAgBiB,EAAI,cAAc,EACjD,cAAehB,EAAgBgB,EAAI,cAAc,CACnD,CAAC,KAxBQ,QACL,IAAI,MACF,uDAAuDN,CAAI,oBAAoBiB,EAAK,UAAU,KAAKD,CAAa,GAClH,CACF,CAqBJ",
6
+ "names": ["InstructionInfoMapper_exports", "__export", "toAccountResets", "toDisplayFields", "toInstructionInfoPayload", "toProgramEnumVariants", "toValueFlowPorts", "__toCommonJS", "import_purify_ts", "import_SolanaPayloads", "import_uIntCodec", "pickSignature", "signatures", "mode", "dtos", "port", "reset", "field", "toSubstructures", "dto", "s", "toEnumVariants", "enumVariants", "enumId", "variants", "variantIndex", "variant", "index", "descriptors", "discriminator", "info", "signature"]
7
+ }
@@ -0,0 +1,2 @@
1
+ "use strict";var t=require("vitest"),e=require("./InstructionInfoMapper");const o="11111111111111111111111111111111";function r(a={}){return{type:"instruction",instruction_info:{version:1,program_id:o,discriminator:"00000000",hash:"feedface",descriptor:{data:"0001sys_data",signatures:{prod:"prodsig",test:"testsig"}}},...a}}(0,t.describe)("InstructionInfoMapper",()=>{(0,t.describe)("toValueFlowPorts",()=>{(0,t.it)("returns an empty list for undefined input",()=>{(0,t.expect)((0,e.toValueFlowPorts)()).toEqual([])}),(0,t.it)("picks only the decoded fields, dropping the signed-TLV descriptor",()=>{(0,t.expect)((0,e.toValueFlowPorts)([{descriptor:"vfp1",account_indices:[0,1],account_index:0,optional_account_strategy:"OMITTED",token_value:{kind:"NATIVE"}}])).toEqual([{account_indices:[0,1],account_index:0,optional_account_strategy:"OMITTED",token_value:{kind:"NATIVE"}}])}),(0,t.it)("leaves absent optional fields as undefined",()=>{(0,t.expect)((0,e.toValueFlowPorts)([{descriptor:"vfp1"}])).toEqual([{account_indices:void 0,account_index:void 0,optional_account_strategy:void 0,token_value:void 0}])})}),(0,t.describe)("toAccountResets",()=>{(0,t.it)("returns an empty list for undefined input",()=>{(0,t.expect)((0,e.toAccountResets)()).toEqual([])}),(0,t.it)("maps the decoded fields, dropping the signed-TLV descriptor",()=>{(0,t.expect)((0,e.toAccountResets)([{descriptor:"ar1",account_index:2,require_pre_balance_zero:!0}])).toEqual([{account_index:2,require_pre_balance_zero:!0}])}),(0,t.it)("drops entries missing account_index instead of defaulting to slot 0",()=>{(0,t.expect)((0,e.toAccountResets)([{descriptor:"ar0",account_index:0},{descriptor:"arBad"},{descriptor:"ar1",account_index:1}])).toEqual([{account_index:0,require_pre_balance_zero:void 0},{account_index:1,require_pre_balance_zero:void 0}])})}),(0,t.describe)("toDisplayFields",()=>{(0,t.it)("returns an empty list for undefined input",()=>{(0,t.expect)((0,e.toDisplayFields)()).toEqual([])}),(0,t.it)("picks name and param, dropping the signed-TLV descriptor",()=>{(0,t.expect)((0,e.toDisplayFields)([{descriptor:"df1",name:"New Account",param:{type:"ACCOUNT",value:{source:"ACCOUNT_PATH",account_index:1}}}])).toEqual([{name:"New Account",param:{type:"ACCOUNT",value:{source:"ACCOUNT_PATH",account_index:1}}}])}),(0,t.it)("falls back to an empty-type param when param is absent",()=>{(0,t.expect)((0,e.toDisplayFields)([{descriptor:"df1"}])).toEqual([{name:void 0,param:{type:""}}])})}),(0,t.describe)("toInstructionInfoPayload",()=>{(0,t.it)("surfaces CAL's decoded JSON (type pool, mint assoc, ports, resets, fields) and ordered substructures",()=>{const a=r({instruction_info:{version:1,program_id:o,discriminator:"00000000",hash:"feedface",descriptor:{data:"0001sys_data",signatures:{prod:"prodsig",test:"testsig"}},idl_descriptor:{root_type:3,type_pool:[{index:0,kind:"STRUCT",refs:[1]},{index:1,kind:"U64"}]},mint_association:{account_index:1,mint_index:3}},display_fields:[{descriptor:"df1",name:"New Account",param:{type:"ACCOUNT",value:{source:"ACCOUNT_PATH",account_index:1}}}],value_flow_ports:[{descriptor:"vfp1",account_indices:[0],token_value:{kind:"NATIVE"}}],hide_rules:[{descriptor:"hr1"}],account_resets:[{descriptor:"ar1",account_index:1,require_pre_balance_zero:!0}]}),n=(0,e.toInstructionInfoPayload)("00000000",a,"prod").unsafeCoerce();(0,t.expect)(n).toMatchObject({programId:o,discriminator:"00000000",instructionInfo:{data:"0001sys_data",signature:"prodsig"},idlDescriptor:{rootType:3,typePool:[{index:0,kind:"STRUCT",refs:[1]},{index:1,kind:"U64"}]},mintAssociations:[{account_index:1,mint_index:3}],valueFlowPorts:[{account_indices:[0],optional_account_strategy:void 0,token_value:{kind:"NATIVE"}}],accountResets:[{account_index:1,require_pre_balance_zero:!0}],displayFields:[{name:"New Account",param:{type:"ACCOUNT",value:{source:"ACCOUNT_PATH",account_index:1}}}]}),(0,t.expect)(n.substructures).toEqual([{kind:0,data:"df1"},{kind:1,data:"vfp1"},{kind:2,data:"hr1"},{kind:3,data:"ar1"}])}),(0,t.it)("defaults idlDescriptor when CAL omits it",()=>{const a=(0,e.toInstructionInfoPayload)("00000000",r(),"prod").unsafeCoerce();(0,t.expect)(a.idlDescriptor).toEqual({typePool:[],rootType:0}),(0,t.expect)(a.mintAssociations).toEqual([])}),(0,t.it)("bundles CAL enum_variants into the payload with the mode signature",()=>{const a=r({enum_variants:{swap:{46:{variant_name:"raydiumCP",data:"01_raydium_tlv",signatures:{prod:"prodsig_v46",test:"testsig_v46"}}}}}),n=(0,e.toInstructionInfoPayload)("00000000",a,"prod").unsafeCoerce();(0,t.expect)(n.enumVariants).toEqual([{enumId:"swap",variantIndex:46,descriptor:{data:"01_raydium_tlv",signature:"prodsig_v46"}}])}),(0,t.it)("skips enum_variants keyed by a non-u16 index instead of leaking NaN",()=>{const a=r({enum_variants:{swap:{46:{variant_name:"raydiumCP",data:"01_raydium_tlv",signatures:{prod:"prodsig_v46",test:"testsig_v46"}},"7abc":{variant_name:"junk",data:"junk_tlv",signatures:{prod:"x",test:"x"}},7e4:{variant_name:"overflow",data:"overflow_tlv",signatures:{prod:"x",test:"x"}}}}}),n=(0,e.toInstructionInfoPayload)("00000000",a,"prod").unsafeCoerce();(0,t.expect)(n.enumVariants).toEqual([{enumId:"swap",variantIndex:46,descriptor:{data:"01_raydium_tlv",signature:"prodsig_v46"}}])}),(0,t.it)("selects the signature for the configured mode",()=>{const a=(0,e.toInstructionInfoPayload)("00000000",r(),"test").unsafeCoerce();(0,t.expect)(a.instructionInfo.signature).toBe("testsig")}),(0,t.it)("returns Left when the configured mode signature is missing",()=>{const a=r();delete a.instruction_info.descriptor.signatures.test;const n=(0,e.toInstructionInfoPayload)("00000000",a,"test");(0,t.expect)(n.isLeft()).toBe(!0),(0,t.expect)(n.swap().unsafeCoerce().message).toMatch(/missing 'test' signature/)})}),(0,t.describe)("toProgramEnumVariants",()=>{(0,t.it)("flattens enum variants across all descriptors, dropping malformed keys",()=>{const a={"00000000":r({enum_variants:{swap:{46:{variant_name:"raydiumCP",data:"01_raydium_tlv",signatures:{prod:"prodsig_v46",test:"testsig_v46"}},bad:{variant_name:"junk",data:"junk_tlv",signatures:{prod:"x",test:"x"}}}}}),"00000001":r({enum_variants:{route:{12:{variant_name:"orca",data:"02_orca_tlv",signatures:{prod:"prodsig_v12",test:"testsig_v12"}}}}})};(0,t.expect)((0,e.toProgramEnumVariants)(a,"prod")).toEqual([{enumId:"swap",variantIndex:46,descriptor:{data:"01_raydium_tlv",signature:"prodsig_v46"}},{enumId:"route",variantIndex:12,descriptor:{data:"02_orca_tlv",signature:"prodsig_v12"}}])}),(0,t.it)("leaves the signature empty when CAL has none for the configured mode",()=>{const a=r({enum_variants:{swap:{46:{variant_name:"raydiumCP",data:"01_raydium_tlv",signatures:{prod:"prodsig_v46"}}}}});(0,t.expect)((0,e.toProgramEnumVariants)({"00000000":a},"test")).toEqual([{enumId:"swap",variantIndex:46,descriptor:{data:"01_raydium_tlv",signature:""}}])})})});
2
+ //# sourceMappingURL=InstructionInfoMapper.test.js.map