@ledgerhq/context-module 2.3.0 → 2.3.1

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 (53) hide show
  1. package/lib/cjs/package.json +1 -1
  2. package/lib/cjs/src/modules/solana/lifi/domain/LifiContextLoader.js +1 -1
  3. package/lib/cjs/src/modules/solana/lifi/domain/LifiContextLoader.js.map +3 -3
  4. package/lib/cjs/src/modules/solana/lifi/domain/LifiContextLoader.test.js +1 -1
  5. package/lib/cjs/src/modules/solana/lifi/domain/LifiContextLoader.test.js.map +3 -3
  6. package/lib/cjs/src/modules/solana/model/SolanaContextTypes.js.map +1 -1
  7. package/lib/cjs/src/modules/solana/model/SolanaPayloads.js.map +2 -2
  8. package/lib/cjs/src/modules/solana/owner-info/data/HttpOwnerInfoDataSource.js +1 -1
  9. package/lib/cjs/src/modules/solana/owner-info/data/HttpOwnerInfoDataSource.js.map +2 -2
  10. package/lib/cjs/src/modules/solana/owner-info/data/HttpOwnerInfoDataSource.test.js +1 -1
  11. package/lib/cjs/src/modules/solana/owner-info/data/HttpOwnerInfoDataSource.test.js.map +2 -2
  12. package/lib/cjs/src/modules/solana/trusted-name/data/HttpTrustedNameDataSource.js +1 -1
  13. package/lib/cjs/src/modules/solana/trusted-name/data/HttpTrustedNameDataSource.js.map +3 -3
  14. package/lib/cjs/src/modules/solana/trusted-name/data/HttpTrustedNameDataSource.test.js +1 -1
  15. package/lib/cjs/src/modules/solana/trusted-name/data/HttpTrustedNameDataSource.test.js.map +2 -2
  16. package/lib/cjs/src/modules/solana/trusted-name/data/TrustedNameDataSource.js +1 -1
  17. package/lib/cjs/src/modules/solana/trusted-name/data/TrustedNameDataSource.js.map +1 -1
  18. package/lib/cjs/src/modules/solana/trusted-name/domain/TrustedNameContextLoader.js +1 -1
  19. package/lib/cjs/src/modules/solana/trusted-name/domain/TrustedNameContextLoader.js.map +2 -2
  20. package/lib/cjs/src/modules/solana/trusted-name/domain/TrustedNameContextLoader.test.js +1 -1
  21. package/lib/cjs/src/modules/solana/trusted-name/domain/TrustedNameContextLoader.test.js.map +2 -2
  22. package/lib/esm/package.json +1 -1
  23. package/lib/esm/src/modules/solana/lifi/domain/LifiContextLoader.js +1 -1
  24. package/lib/esm/src/modules/solana/lifi/domain/LifiContextLoader.js.map +3 -3
  25. package/lib/esm/src/modules/solana/lifi/domain/LifiContextLoader.test.js +1 -1
  26. package/lib/esm/src/modules/solana/lifi/domain/LifiContextLoader.test.js.map +3 -3
  27. package/lib/esm/src/modules/solana/model/SolanaPayloads.js.map +2 -2
  28. package/lib/esm/src/modules/solana/owner-info/data/HttpOwnerInfoDataSource.js +1 -1
  29. package/lib/esm/src/modules/solana/owner-info/data/HttpOwnerInfoDataSource.js.map +2 -2
  30. package/lib/esm/src/modules/solana/owner-info/data/HttpOwnerInfoDataSource.test.js +1 -1
  31. package/lib/esm/src/modules/solana/owner-info/data/HttpOwnerInfoDataSource.test.js.map +2 -2
  32. package/lib/esm/src/modules/solana/trusted-name/data/HttpTrustedNameDataSource.js +1 -1
  33. package/lib/esm/src/modules/solana/trusted-name/data/HttpTrustedNameDataSource.js.map +3 -3
  34. package/lib/esm/src/modules/solana/trusted-name/data/HttpTrustedNameDataSource.test.js +1 -1
  35. package/lib/esm/src/modules/solana/trusted-name/data/HttpTrustedNameDataSource.test.js.map +2 -2
  36. package/lib/esm/src/modules/solana/trusted-name/domain/TrustedNameContextLoader.js +1 -1
  37. package/lib/esm/src/modules/solana/trusted-name/domain/TrustedNameContextLoader.js.map +2 -2
  38. package/lib/esm/src/modules/solana/trusted-name/domain/TrustedNameContextLoader.test.js +1 -1
  39. package/lib/esm/src/modules/solana/trusted-name/domain/TrustedNameContextLoader.test.js.map +2 -2
  40. package/lib/types/src/modules/solana/lifi/domain/LifiContextLoader.d.ts.map +1 -1
  41. package/lib/types/src/modules/solana/model/SolanaContextTypes.d.ts +5 -1
  42. package/lib/types/src/modules/solana/model/SolanaContextTypes.d.ts.map +1 -1
  43. package/lib/types/src/modules/solana/model/SolanaPayloads.d.ts +3 -1
  44. package/lib/types/src/modules/solana/model/SolanaPayloads.d.ts.map +1 -1
  45. package/lib/types/src/modules/solana/owner-info/data/HttpOwnerInfoDataSource.d.ts.map +1 -1
  46. package/lib/types/src/modules/solana/trusted-name/data/HttpTrustedNameDataSource.d.ts +1 -1
  47. package/lib/types/src/modules/solana/trusted-name/data/HttpTrustedNameDataSource.d.ts.map +1 -1
  48. package/lib/types/src/modules/solana/trusted-name/data/TrustedNameDataSource.d.ts +1 -0
  49. package/lib/types/src/modules/solana/trusted-name/data/TrustedNameDataSource.d.ts.map +1 -1
  50. package/lib/types/src/modules/solana/trusted-name/domain/TrustedNameContextLoader.d.ts +1 -0
  51. package/lib/types/src/modules/solana/trusted-name/domain/TrustedNameContextLoader.d.ts.map +1 -1
  52. package/lib/types/tsconfig.prod.tsbuildinfo +1 -1
  53. package/package.json +4 -4
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "version": 3,
3
3
  "sources": ["../../../../../../../src/modules/solana/trusted-name/data/HttpTrustedNameDataSource.ts"],
4
- "sourcesContent": ["import { DmkNetworkClient } from \"@ledgerhq/device-management-kit\";\nimport { inject, injectable } from \"inversify\";\nimport { Codec, Either, Left, optional, Right, string } from \"purify-ts\";\n\nimport { configTypes } from \"@/config/di/configTypes\";\nimport {\n type ContextModuleCalMode,\n type ContextModuleServiceConfig,\n} from \"@/config/model/ContextModuleConfig\";\nimport { SIGNATURE_TAG } from \"@/shared/model/SignatureTags\";\nimport { networkTypes } from \"@/shared/network/di/networkTypes\";\nimport { HexStringUtils } from \"@/shared/utils/HexStringUtils\";\n\nimport {\n type GetSolanaTrustedNameParams,\n type SolanaTrustedNameDataSource,\n type SolanaTrustedNameResult,\n} from \"./TrustedNameDataSource\";\n\nconst trustedNameResponseCodec = Codec.interface({\n signedDescriptor: Codec.interface({\n data: string,\n signatures: Codec.interface({\n prod: optional(string),\n test: optional(string),\n }),\n }),\n keyId: string,\n keyUsage: string,\n});\n\n@injectable()\nexport class HttpSolanaTrustedNameDataSource\n implements SolanaTrustedNameDataSource\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 getTrustedName({\n address,\n network,\n challenge,\n sources,\n }: GetSolanaTrustedNameParams): Promise<\n Either<Error, SolanaTrustedNameResult>\n > {\n let dto: unknown;\n try {\n dto = await this.http.get(\n `${this.config.metadataServiceDomain.url}/v2/names/solana/${network}/reverse/${address}`,\n {\n params: {\n sources: sources.join(\",\"),\n challenge,\n },\n },\n );\n } catch (error) {\n const reason = error instanceof Error ? error.message : String(error);\n return Left(\n new Error(\n `[ContextModule] HttpSolanaTrustedNameDataSource: Failed to fetch trusted name: ${reason}`,\n ),\n );\n }\n\n return trustedNameResponseCodec\n .decode(dto)\n .caseOf<Either<Error, SolanaTrustedNameResult>>({\n Left: (error) =>\n Left(\n new Error(\n `[ContextModule] HttpSolanaTrustedNameDataSource: malformed response for ${address}: ${error}`,\n ),\n ),\n Right: (validated) => {\n const mode: ContextModuleCalMode = this.config.cal.mode ?? \"prod\";\n const signature = validated.signedDescriptor.signatures[mode];\n if (!signature) {\n return Left(\n new Error(\n `[ContextModule] HttpSolanaTrustedNameDataSource: missing ${mode} signature for ${address}`,\n ),\n );\n }\n\n let descriptor: Uint8Array;\n try {\n descriptor = HexStringUtils.hexToBytes(\n HexStringUtils.appendSignatureToPayload(\n validated.signedDescriptor.data,\n signature,\n SIGNATURE_TAG,\n ),\n );\n } catch (error) {\n return Left(\n new Error(\n `[ContextModule] HttpSolanaTrustedNameDataSource: invalid signed descriptor for ${address}: ${(error as Error).message}`,\n ),\n );\n }\n\n return Right({\n address,\n descriptor,\n keyId: validated.keyId,\n keyUsage: validated.keyUsage,\n });\n },\n });\n }\n}\n"],
5
- "mappings": "okBAAA,IAAAA,EAAA,GAAAC,EAAAD,EAAA,qCAAAE,IAAA,eAAAC,EAAAH,GACA,IAAAI,EAAmC,qBACnCC,EAA6D,qBAE7DC,EAA4B,mCAK5BC,EAA8B,wCAC9BC,EAA6B,4CAC7BC,EAA+B,yCAQ/B,MAAMC,EAA2B,QAAM,UAAU,CAC/C,iBAAkB,QAAM,UAAU,CAChC,KAAM,SACN,WAAY,QAAM,UAAU,CAC1B,QAAM,YAAS,QAAM,EACrB,QAAM,YAAS,QAAM,CACvB,CAAC,CACH,CAAC,EACD,MAAO,SACP,SAAU,QACZ,CAAC,EAGM,IAAMC,EAAN,KAEP,CACE,YAEmBC,EAEAC,EACjB,CAHiB,YAAAD,EAEA,UAAAC,CAChB,CAEH,MAAa,eAAe,CAC1B,QAAAC,EACA,QAAAC,EACA,UAAAC,EACA,QAAAC,CACF,EAEE,CACA,IAAIC,EACJ,GAAI,CACFA,EAAM,MAAM,KAAK,KAAK,IACpB,GAAG,KAAK,OAAO,sBAAsB,GAAG,oBAAoBH,CAAO,YAAYD,CAAO,GACtF,CACE,OAAQ,CACN,QAASG,EAAQ,KAAK,GAAG,EACzB,UAAAD,CACF,CACF,CACF,CACF,OAASG,EAAO,CACd,MAAMC,EAASD,aAAiB,MAAQA,EAAM,QAAU,OAAOA,CAAK,EACpE,SAAO,QACL,IAAI,MACF,kFAAkFC,CAAM,EAC1F,CACF,CACF,CAEA,OAAOV,EACJ,OAAOQ,CAAG,EACV,OAA+C,CAC9C,KAAOC,MACL,QACE,IAAI,MACF,2EAA2EL,CAAO,KAAKK,CAAK,EAC9F,CACF,EACF,MAAQE,GAAc,CACpB,MAAMC,EAA6B,KAAK,OAAO,IAAI,MAAQ,OACrDC,EAAYF,EAAU,iBAAiB,WAAWC,CAAI,EAC5D,GAAI,CAACC,EACH,SAAO,QACL,IAAI,MACF,4DAA4DD,CAAI,kBAAkBR,CAAO,EAC3F,CACF,EAGF,IAAIU,EACJ,GAAI,CACFA,EAAa,iBAAe,WAC1B,iBAAe,yBACbH,EAAU,iBAAiB,KAC3BE,EACA,eACF,CACF,CACF,OAASJ,EAAO,CACd,SAAO,QACL,IAAI,MACF,kFAAkFL,CAAO,KAAMK,EAAgB,OAAO,EACxH,CACF,CACF,CAEA,SAAO,SAAM,CACX,QAAAL,EACA,WAAAU,EACA,MAAOH,EAAU,MACjB,SAAUA,EAAU,QACtB,CAAC,CACH,CACF,CAAC,CACL,CACF,EApFaV,EAANc,EAAA,IADN,cAAW,EAKPC,EAAA,eAAO,cAAY,MAAM,GAEzBA,EAAA,eAAO,eAAa,aAAa,IANzBf",
6
- "names": ["HttpTrustedNameDataSource_exports", "__export", "HttpSolanaTrustedNameDataSource", "__toCommonJS", "import_inversify", "import_purify_ts", "import_configTypes", "import_SignatureTags", "import_networkTypes", "import_HexStringUtils", "trustedNameResponseCodec", "HttpSolanaTrustedNameDataSource", "config", "http", "address", "network", "challenge", "sources", "dto", "error", "reason", "validated", "mode", "signature", "descriptor", "__decorateClass", "__decorateParam"]
4
+ "sourcesContent": ["import { DmkNetworkClient } from \"@ledgerhq/device-management-kit\";\nimport { inject, injectable } from \"inversify\";\nimport { Codec, Either, Left, optional, Right, string } from \"purify-ts\";\n\nimport { configTypes } from \"@/config/di/configTypes\";\nimport {\n type ContextModuleCalMode,\n type ContextModuleServiceConfig,\n} from \"@/config/model/ContextModuleConfig\";\nimport { SIGNATURE_TAG } from \"@/shared/model/SignatureTags\";\nimport { networkTypes } from \"@/shared/network/di/networkTypes\";\nimport { HexStringUtils } from \"@/shared/utils/HexStringUtils\";\n\nimport {\n type GetSolanaTrustedNameParams,\n type SolanaTrustedNameDataSource,\n type SolanaTrustedNameResult,\n} from \"./TrustedNameDataSource\";\n\nconst trustedNameResponseCodec = Codec.interface({\n signedDescriptor: Codec.interface({\n data: string,\n signatures: Codec.interface({\n prod: optional(string),\n test: optional(string),\n }),\n }),\n keyId: string,\n keyUsage: string,\n});\n\n@injectable()\nexport class HttpSolanaTrustedNameDataSource\n implements SolanaTrustedNameDataSource\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 getTrustedName({\n address,\n network,\n challenge,\n types,\n sources,\n }: GetSolanaTrustedNameParams): Promise<\n Either<Error, SolanaTrustedNameResult>\n > {\n let dto: unknown;\n try {\n dto = await this.http.get(\n `${this.config.metadataServiceDomain.url}/v2/names/solana/${network}/reverse/${address}`,\n {\n params: {\n types: types.join(\",\"),\n sources: sources.join(\",\"),\n challenge,\n },\n },\n );\n } catch (error) {\n const reason = error instanceof Error ? error.message : String(error);\n return Left(\n new Error(\n `[ContextModule] HttpSolanaTrustedNameDataSource: Failed to fetch trusted name: ${reason}`,\n ),\n );\n }\n\n return trustedNameResponseCodec\n .decode(dto)\n .caseOf<Either<Error, SolanaTrustedNameResult>>({\n Left: (error) =>\n Left(\n new Error(\n `[ContextModule] HttpSolanaTrustedNameDataSource: malformed response for ${address}: ${error}`,\n ),\n ),\n Right: (validated) => {\n const mode: ContextModuleCalMode = this.config.cal.mode ?? \"prod\";\n const signature = validated.signedDescriptor.signatures[mode];\n if (!signature) {\n return Left(\n new Error(\n `[ContextModule] HttpSolanaTrustedNameDataSource: missing ${mode} signature for ${address}`,\n ),\n );\n }\n\n let descriptor: Uint8Array;\n try {\n descriptor = HexStringUtils.hexToBytes(\n HexStringUtils.appendSignatureToPayload(\n validated.signedDescriptor.data,\n signature,\n SIGNATURE_TAG,\n ),\n );\n } catch (error) {\n return Left(\n new Error(\n `[ContextModule] HttpSolanaTrustedNameDataSource: invalid signed descriptor for ${address}: ${(error as Error).message}`,\n ),\n );\n }\n\n return Right({\n address,\n descriptor,\n keyId: validated.keyId,\n keyUsage: validated.keyUsage,\n });\n },\n });\n }\n}\n"],
5
+ "mappings": "okBAAA,IAAAA,EAAA,GAAAC,EAAAD,EAAA,qCAAAE,IAAA,eAAAC,EAAAH,GACA,IAAAI,EAAmC,qBACnCC,EAA6D,qBAE7DC,EAA4B,mCAK5BC,EAA8B,wCAC9BC,EAA6B,4CAC7BC,EAA+B,yCAQ/B,MAAMC,EAA2B,QAAM,UAAU,CAC/C,iBAAkB,QAAM,UAAU,CAChC,KAAM,SACN,WAAY,QAAM,UAAU,CAC1B,QAAM,YAAS,QAAM,EACrB,QAAM,YAAS,QAAM,CACvB,CAAC,CACH,CAAC,EACD,MAAO,SACP,SAAU,QACZ,CAAC,EAGM,IAAMC,EAAN,KAEP,CACE,YAEmBC,EAEAC,EACjB,CAHiB,YAAAD,EAEA,UAAAC,CAChB,CAEH,MAAa,eAAe,CAC1B,QAAAC,EACA,QAAAC,EACA,UAAAC,EACA,MAAAC,EACA,QAAAC,CACF,EAEE,CACA,IAAIC,EACJ,GAAI,CACFA,EAAM,MAAM,KAAK,KAAK,IACpB,GAAG,KAAK,OAAO,sBAAsB,GAAG,oBAAoBJ,CAAO,YAAYD,CAAO,GACtF,CACE,OAAQ,CACN,MAAOG,EAAM,KAAK,GAAG,EACrB,QAASC,EAAQ,KAAK,GAAG,EACzB,UAAAF,CACF,CACF,CACF,CACF,OAASI,EAAO,CACd,MAAMC,EAASD,aAAiB,MAAQA,EAAM,QAAU,OAAOA,CAAK,EACpE,SAAO,QACL,IAAI,MACF,kFAAkFC,CAAM,EAC1F,CACF,CACF,CAEA,OAAOX,EACJ,OAAOS,CAAG,EACV,OAA+C,CAC9C,KAAOC,MACL,QACE,IAAI,MACF,2EAA2EN,CAAO,KAAKM,CAAK,EAC9F,CACF,EACF,MAAQE,GAAc,CACpB,MAAMC,EAA6B,KAAK,OAAO,IAAI,MAAQ,OACrDC,EAAYF,EAAU,iBAAiB,WAAWC,CAAI,EAC5D,GAAI,CAACC,EACH,SAAO,QACL,IAAI,MACF,4DAA4DD,CAAI,kBAAkBT,CAAO,EAC3F,CACF,EAGF,IAAIW,EACJ,GAAI,CACFA,EAAa,iBAAe,WAC1B,iBAAe,yBACbH,EAAU,iBAAiB,KAC3BE,EACA,eACF,CACF,CACF,OAASJ,EAAO,CACd,SAAO,QACL,IAAI,MACF,kFAAkFN,CAAO,KAAMM,EAAgB,OAAO,EACxH,CACF,CACF,CAEA,SAAO,SAAM,CACX,QAAAN,EACA,WAAAW,EACA,MAAOH,EAAU,MACjB,SAAUA,EAAU,QACtB,CAAC,CACH,CACF,CAAC,CACL,CACF,EAtFaX,EAANe,EAAA,IADN,cAAW,EAKPC,EAAA,eAAO,cAAY,MAAM,GAEzBA,EAAA,eAAO,eAAa,aAAa,IANzBhB",
6
+ "names": ["HttpTrustedNameDataSource_exports", "__export", "HttpSolanaTrustedNameDataSource", "__toCommonJS", "import_inversify", "import_purify_ts", "import_configTypes", "import_SignatureTags", "import_networkTypes", "import_HexStringUtils", "trustedNameResponseCodec", "HttpSolanaTrustedNameDataSource", "config", "http", "address", "network", "challenge", "types", "sources", "dto", "error", "reason", "validated", "mode", "signature", "descriptor", "__decorateClass", "__decorateParam"]
7
7
  }
@@ -1,2 +1,2 @@
1
- "use strict";var c=require("purify-ts"),e=require("vitest"),o=require("../../../../modules/solana/model/SolanaTransactionScanChainId"),u=require("./HttpTrustedNameDataSource");(0,e.describe)("HttpSolanaTrustedNameDataSource",()=>{let a,s;const r="vitalik.sol",n="deadbeef",l=(t="prod")=>({metadataServiceDomain:{url:"https://nft.api.ledger.com"},cal:{mode:t}}),d=(t="prod")=>new u.HttpSolanaTrustedNameDataSource(l(t),s),i=(t,m="ff00")=>({descriptorType:"name",descriptorVersion:"2",signedDescriptor:{data:m,signatures:t},keyId:"cal_trusted_name",keyUsage:"trusted_name"});(0,e.beforeEach)(()=>{e.vi.clearAllMocks(),s={get:e.vi.fn()},a=d()}),(0,e.it)("calls the names endpoint with network, sources and challenge (no types)",async()=>{s.get.mockResolvedValue(i({prod:"aabb"})),await a.getTrustedName({address:r,network:String(o.SolanaTransactionScanChainId.MAINNET),challenge:n,sources:["crypto_asset_list"]}),(0,e.expect)(s.get).toHaveBeenCalledWith(`https://nft.api.ledger.com/v2/names/solana/${o.SolanaTransactionScanChainId.MAINNET}/reverse/${r}`,{params:{sources:"crypto_asset_list",challenge:n}})}),(0,e.it)("appends the prod signature TLV and decodes into a Uint8Array",async()=>{s.get.mockResolvedValue(i({prod:"aabb",test:"cc"}));const t=await a.getTrustedName({address:r,network:String(o.SolanaTransactionScanChainId.MAINNET),challenge:n,sources:["crypto_asset_list"]});(0,e.expect)(t).toEqual((0,c.Right)({address:r,descriptor:new Uint8Array([255,0,21,2,170,187]),keyId:"cal_trusted_name",keyUsage:"trusted_name"}))}),(0,e.it)("selects the test signature when cal.mode is test",async()=>{a=d("test"),s.get.mockResolvedValue(i({prod:"aabb",test:"cc"}));const t=await a.getTrustedName({address:r,network:String(o.SolanaTransactionScanChainId.MAINNET),challenge:n,sources:["crypto_asset_list"]});(0,e.expect)(t).toEqual((0,c.Right)({address:r,descriptor:new Uint8Array([255,0,21,1,204]),keyId:"cal_trusted_name",keyUsage:"trusted_name"}))}),(0,e.it)("returns Left when the signature for the active mode is missing",async()=>{a=d("prod"),s.get.mockResolvedValue(i({test:"cc"}));const t=await a.getTrustedName({address:r,network:String(o.SolanaTransactionScanChainId.MAINNET),challenge:n,sources:["crypto_asset_list"]});(0,e.expect)(t.isLeft()).toBe(!0),(0,e.expect)(t.extract().message).toMatch(new RegExp(String.raw`\[ContextModule\] HttpSolanaTrustedNameDataSource: missing prod signature for ${r}`))}),(0,e.it)("returns Left on malformed response (hex-string signedDescriptor)",async()=>{s.get.mockResolvedValue({signedDescriptor:"01020304",keyId:"k",keyUsage:"u"});const t=await a.getTrustedName({address:r,network:String(o.SolanaTransactionScanChainId.MAINNET),challenge:n,sources:[]});(0,e.expect)(t.isLeft()).toBe(!0),(0,e.expect)(t.extract().message).toMatch(new RegExp(String.raw`\[ContextModule\] HttpSolanaTrustedNameDataSource: malformed response for ${r}:`))}),(0,e.it)("returns Left when HTTP client throws",async()=>{s.get.mockRejectedValue(new Error("net"));const t=await a.getTrustedName({address:r,network:String(o.SolanaTransactionScanChainId.MAINNET),challenge:n,sources:[]});(0,e.expect)(t).toEqual((0,c.Left)(new Error("[ContextModule] HttpSolanaTrustedNameDataSource: Failed to fetch trusted name: net")))})});
1
+ "use strict";var c=require("purify-ts"),e=require("vitest"),o=require("../../../../modules/solana/model/SolanaTransactionScanChainId"),u=require("./HttpTrustedNameDataSource");(0,e.describe)("HttpSolanaTrustedNameDataSource",()=>{let a,s;const r="vitalik.sol",n="deadbeef",l=(t="prod")=>({metadataServiceDomain:{url:"https://nft.api.ledger.com"},cal:{mode:t}}),d=(t="prod")=>new u.HttpSolanaTrustedNameDataSource(l(t),s),i=(t,m="ff00")=>({descriptorType:"name",descriptorVersion:"2",signedDescriptor:{data:m,signatures:t},keyId:"cal_trusted_name",keyUsage:"trusted_name"});(0,e.beforeEach)(()=>{e.vi.clearAllMocks(),s={get:e.vi.fn()},a=d()}),(0,e.it)("calls the names endpoint with network, types, sources and challenge",async()=>{s.get.mockResolvedValue(i({prod:"aabb"})),await a.getTrustedName({address:r,network:String(o.SolanaTransactionScanChainId.MAINNET),challenge:n,types:["token","smart_contract"],sources:["crypto_asset_list"]}),(0,e.expect)(s.get).toHaveBeenCalledWith(`https://nft.api.ledger.com/v2/names/solana/${o.SolanaTransactionScanChainId.MAINNET}/reverse/${r}`,{params:{types:"token,smart_contract",sources:"crypto_asset_list",challenge:n}})}),(0,e.it)("appends the prod signature TLV and decodes into a Uint8Array",async()=>{s.get.mockResolvedValue(i({prod:"aabb",test:"cc"}));const t=await a.getTrustedName({address:r,network:String(o.SolanaTransactionScanChainId.MAINNET),challenge:n,types:["token","smart_contract"],sources:["crypto_asset_list"]});(0,e.expect)(t).toEqual((0,c.Right)({address:r,descriptor:new Uint8Array([255,0,21,2,170,187]),keyId:"cal_trusted_name",keyUsage:"trusted_name"}))}),(0,e.it)("selects the test signature when cal.mode is test",async()=>{a=d("test"),s.get.mockResolvedValue(i({prod:"aabb",test:"cc"}));const t=await a.getTrustedName({address:r,network:String(o.SolanaTransactionScanChainId.MAINNET),challenge:n,types:["token","smart_contract"],sources:["crypto_asset_list"]});(0,e.expect)(t).toEqual((0,c.Right)({address:r,descriptor:new Uint8Array([255,0,21,1,204]),keyId:"cal_trusted_name",keyUsage:"trusted_name"}))}),(0,e.it)("returns Left when the signature for the active mode is missing",async()=>{a=d("prod"),s.get.mockResolvedValue(i({test:"cc"}));const t=await a.getTrustedName({address:r,network:String(o.SolanaTransactionScanChainId.MAINNET),challenge:n,types:["token","smart_contract"],sources:["crypto_asset_list"]});(0,e.expect)(t.isLeft()).toBe(!0),(0,e.expect)(t.extract().message).toMatch(new RegExp(String.raw`\[ContextModule\] HttpSolanaTrustedNameDataSource: missing prod signature for ${r}`))}),(0,e.it)("returns Left on malformed response (hex-string signedDescriptor)",async()=>{s.get.mockResolvedValue({signedDescriptor:"01020304",keyId:"k",keyUsage:"u"});const t=await a.getTrustedName({address:r,network:String(o.SolanaTransactionScanChainId.MAINNET),challenge:n,types:[],sources:[]});(0,e.expect)(t.isLeft()).toBe(!0),(0,e.expect)(t.extract().message).toMatch(new RegExp(String.raw`\[ContextModule\] HttpSolanaTrustedNameDataSource: malformed response for ${r}:`))}),(0,e.it)("returns Left when HTTP client throws",async()=>{s.get.mockRejectedValue(new Error("net"));const t=await a.getTrustedName({address:r,network:String(o.SolanaTransactionScanChainId.MAINNET),challenge:n,types:[],sources:[]});(0,e.expect)(t).toEqual((0,c.Left)(new Error("[ContextModule] HttpSolanaTrustedNameDataSource: Failed to fetch trusted name: net")))})});
2
2
  //# sourceMappingURL=HttpTrustedNameDataSource.test.js.map
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "version": 3,
3
3
  "sources": ["../../../../../../../src/modules/solana/trusted-name/data/HttpTrustedNameDataSource.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\";\nimport { SolanaTransactionScanChainId } from \"@/modules/solana/model/SolanaTransactionScanChainId\";\n\nimport { HttpSolanaTrustedNameDataSource } from \"./HttpTrustedNameDataSource\";\nimport { type SolanaTrustedNameDataSource } from \"./TrustedNameDataSource\";\n\ndescribe(\"HttpSolanaTrustedNameDataSource\", () => {\n let datasource: SolanaTrustedNameDataSource;\n let httpMock: { get: ReturnType<typeof vi.fn> };\n const address = \"vitalik.sol\";\n const challenge = \"deadbeef\";\n\n const makeConfig = (mode: \"prod\" | \"test\" = \"prod\") =>\n ({\n metadataServiceDomain: { url: \"https://nft.api.ledger.com\" },\n cal: { mode },\n }) as ContextModuleServiceConfig;\n\n const makeDatasource = (mode: \"prod\" | \"test\" = \"prod\") =>\n new HttpSolanaTrustedNameDataSource(\n makeConfig(mode),\n httpMock as unknown as DmkNetworkClient,\n );\n\n const objectResponse = (\n signatures: { prod?: string; test?: string },\n data = \"ff00\",\n ) => ({\n descriptorType: \"name\",\n descriptorVersion: \"2\",\n signedDescriptor: { data, signatures },\n keyId: \"cal_trusted_name\",\n keyUsage: \"trusted_name\",\n });\n\n beforeEach(() => {\n vi.clearAllMocks();\n httpMock = { get: vi.fn() };\n datasource = makeDatasource();\n });\n\n it(\"calls the names endpoint with network, sources and challenge (no types)\", async () => {\n httpMock.get.mockResolvedValue(objectResponse({ prod: \"aabb\" }));\n\n await datasource.getTrustedName({\n address,\n network: String(SolanaTransactionScanChainId.MAINNET),\n challenge,\n sources: [\"crypto_asset_list\"],\n });\n\n expect(httpMock.get).toHaveBeenCalledWith(\n `https://nft.api.ledger.com/v2/names/solana/${SolanaTransactionScanChainId.MAINNET}/reverse/${address}`,\n {\n params: {\n sources: \"crypto_asset_list\",\n challenge,\n },\n },\n );\n });\n\n it(\"appends the prod signature TLV and decodes into a Uint8Array\", async () => {\n httpMock.get.mockResolvedValue(\n objectResponse({ prod: \"aabb\", test: \"cc\" }),\n );\n\n const result = await datasource.getTrustedName({\n address,\n network: String(SolanaTransactionScanChainId.MAINNET),\n challenge,\n sources: [\"crypto_asset_list\"],\n });\n\n // data(ff00) + SIGNATURE_TAG(15) + len(02) + sig(aabb)\n expect(result).toEqual(\n Right({\n address,\n descriptor: new Uint8Array([0xff, 0x00, 0x15, 0x02, 0xaa, 0xbb]),\n keyId: \"cal_trusted_name\",\n keyUsage: \"trusted_name\",\n }),\n );\n });\n\n it(\"selects the test signature when cal.mode is test\", async () => {\n datasource = makeDatasource(\"test\");\n httpMock.get.mockResolvedValue(\n objectResponse({ prod: \"aabb\", test: \"cc\" }),\n );\n\n const result = await datasource.getTrustedName({\n address,\n network: String(SolanaTransactionScanChainId.MAINNET),\n challenge,\n sources: [\"crypto_asset_list\"],\n });\n\n // data(ff00) + SIGNATURE_TAG(15) + len(01) + sig(cc)\n expect(result).toEqual(\n Right({\n address,\n descriptor: new Uint8Array([0xff, 0x00, 0x15, 0x01, 0xcc]),\n keyId: \"cal_trusted_name\",\n keyUsage: \"trusted_name\",\n }),\n );\n });\n\n it(\"returns Left when the signature for the active mode is missing\", async () => {\n datasource = makeDatasource(\"prod\");\n httpMock.get.mockResolvedValue(objectResponse({ test: \"cc\" }));\n\n const result = await datasource.getTrustedName({\n address,\n network: String(SolanaTransactionScanChainId.MAINNET),\n challenge,\n sources: [\"crypto_asset_list\"],\n });\n\n expect(result.isLeft()).toBe(true);\n expect((result.extract() as Error).message).toMatch(\n new RegExp(\n String.raw`\\[ContextModule\\] HttpSolanaTrustedNameDataSource: missing prod signature for ${address}`,\n ),\n );\n });\n\n it(\"returns Left on malformed response (hex-string signedDescriptor)\", async () => {\n httpMock.get.mockResolvedValue({\n signedDescriptor: \"01020304\",\n keyId: \"k\",\n keyUsage: \"u\",\n } as any);\n\n const result = await datasource.getTrustedName({\n address,\n network: String(SolanaTransactionScanChainId.MAINNET),\n challenge,\n sources: [],\n });\n\n expect(result.isLeft()).toBe(true);\n expect((result.extract() as Error).message).toMatch(\n new RegExp(\n String.raw`\\[ContextModule\\] HttpSolanaTrustedNameDataSource: malformed response for ${address}:`,\n ),\n );\n });\n\n it(\"returns Left when HTTP client throws\", async () => {\n httpMock.get.mockRejectedValue(new Error(\"net\"));\n\n const result = await datasource.getTrustedName({\n address,\n network: String(SolanaTransactionScanChainId.MAINNET),\n challenge,\n sources: [],\n });\n\n expect(result).toEqual(\n Left(\n new Error(\n \"[ContextModule] HttpSolanaTrustedNameDataSource: Failed to fetch trusted name: net\",\n ),\n ),\n );\n });\n});\n"],
5
- "mappings": "aAEA,IAAAA,EAA4B,qBAC5BC,EAAqD,kBAGrDC,EAA6C,+DAE7CC,EAAgD,0CAGhD,YAAS,kCAAmC,IAAM,CAChD,IAAIC,EACAC,EACJ,MAAMC,EAAU,cACVC,EAAY,WAEZC,EAAa,CAACC,EAAwB,UACzC,CACC,sBAAuB,CAAE,IAAK,4BAA6B,EAC3D,IAAK,CAAE,KAAAA,CAAK,CACd,GAEIC,EAAiB,CAACD,EAAwB,SAC9C,IAAI,kCACFD,EAAWC,CAAI,EACfJ,CACF,EAEIM,EAAiB,CACrBC,EACAC,EAAO,UACH,CACJ,eAAgB,OAChB,kBAAmB,IACnB,iBAAkB,CAAE,KAAAA,EAAM,WAAAD,CAAW,EACrC,MAAO,mBACP,SAAU,cACZ,MAEA,cAAW,IAAM,CACf,KAAG,cAAc,EACjBP,EAAW,CAAE,IAAK,KAAG,GAAG,CAAE,EAC1BD,EAAaM,EAAe,CAC9B,CAAC,KAED,MAAG,0EAA2E,SAAY,CACxFL,EAAS,IAAI,kBAAkBM,EAAe,CAAE,KAAM,MAAO,CAAC,CAAC,EAE/D,MAAMP,EAAW,eAAe,CAC9B,QAAAE,EACA,QAAS,OAAO,+BAA6B,OAAO,EACpD,UAAAC,EACA,QAAS,CAAC,mBAAmB,CAC/B,CAAC,KAED,UAAOF,EAAS,GAAG,EAAE,qBACnB,8CAA8C,+BAA6B,OAAO,YAAYC,CAAO,GACrG,CACE,OAAQ,CACN,QAAS,oBACT,UAAAC,CACF,CACF,CACF,CACF,CAAC,KAED,MAAG,+DAAgE,SAAY,CAC7EF,EAAS,IAAI,kBACXM,EAAe,CAAE,KAAM,OAAQ,KAAM,IAAK,CAAC,CAC7C,EAEA,MAAMG,EAAS,MAAMV,EAAW,eAAe,CAC7C,QAAAE,EACA,QAAS,OAAO,+BAA6B,OAAO,EACpD,UAAAC,EACA,QAAS,CAAC,mBAAmB,CAC/B,CAAC,KAGD,UAAOO,CAAM,EAAE,WACb,SAAM,CACJ,QAAAR,EACA,WAAY,IAAI,WAAW,CAAC,IAAM,EAAM,GAAM,EAAM,IAAM,GAAI,CAAC,EAC/D,MAAO,mBACP,SAAU,cACZ,CAAC,CACH,CACF,CAAC,KAED,MAAG,mDAAoD,SAAY,CACjEF,EAAaM,EAAe,MAAM,EAClCL,EAAS,IAAI,kBACXM,EAAe,CAAE,KAAM,OAAQ,KAAM,IAAK,CAAC,CAC7C,EAEA,MAAMG,EAAS,MAAMV,EAAW,eAAe,CAC7C,QAAAE,EACA,QAAS,OAAO,+BAA6B,OAAO,EACpD,UAAAC,EACA,QAAS,CAAC,mBAAmB,CAC/B,CAAC,KAGD,UAAOO,CAAM,EAAE,WACb,SAAM,CACJ,QAAAR,EACA,WAAY,IAAI,WAAW,CAAC,IAAM,EAAM,GAAM,EAAM,GAAI,CAAC,EACzD,MAAO,mBACP,SAAU,cACZ,CAAC,CACH,CACF,CAAC,KAED,MAAG,iEAAkE,SAAY,CAC/EF,EAAaM,EAAe,MAAM,EAClCL,EAAS,IAAI,kBAAkBM,EAAe,CAAE,KAAM,IAAK,CAAC,CAAC,EAE7D,MAAMG,EAAS,MAAMV,EAAW,eAAe,CAC7C,QAAAE,EACA,QAAS,OAAO,+BAA6B,OAAO,EACpD,UAAAC,EACA,QAAS,CAAC,mBAAmB,CAC/B,CAAC,KAED,UAAOO,EAAO,OAAO,CAAC,EAAE,KAAK,EAAI,KACjC,UAAQA,EAAO,QAAQ,EAAY,OAAO,EAAE,QAC1C,IAAI,OACF,OAAO,oFAAoFR,CAAO,EACpG,CACF,CACF,CAAC,KAED,MAAG,mEAAoE,SAAY,CACjFD,EAAS,IAAI,kBAAkB,CAC7B,iBAAkB,WAClB,MAAO,IACP,SAAU,GACZ,CAAQ,EAER,MAAMS,EAAS,MAAMV,EAAW,eAAe,CAC7C,QAAAE,EACA,QAAS,OAAO,+BAA6B,OAAO,EACpD,UAAAC,EACA,QAAS,CAAC,CACZ,CAAC,KAED,UAAOO,EAAO,OAAO,CAAC,EAAE,KAAK,EAAI,KACjC,UAAQA,EAAO,QAAQ,EAAY,OAAO,EAAE,QAC1C,IAAI,OACF,OAAO,gFAAgFR,CAAO,GAChG,CACF,CACF,CAAC,KAED,MAAG,uCAAwC,SAAY,CACrDD,EAAS,IAAI,kBAAkB,IAAI,MAAM,KAAK,CAAC,EAE/C,MAAMS,EAAS,MAAMV,EAAW,eAAe,CAC7C,QAAAE,EACA,QAAS,OAAO,+BAA6B,OAAO,EACpD,UAAAC,EACA,QAAS,CAAC,CACZ,CAAC,KAED,UAAOO,CAAM,EAAE,WACb,QACE,IAAI,MACF,oFACF,CACF,CACF,CACF,CAAC,CACH,CAAC",
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\";\nimport { SolanaTransactionScanChainId } from \"@/modules/solana/model/SolanaTransactionScanChainId\";\n\nimport { HttpSolanaTrustedNameDataSource } from \"./HttpTrustedNameDataSource\";\nimport { type SolanaTrustedNameDataSource } from \"./TrustedNameDataSource\";\n\ndescribe(\"HttpSolanaTrustedNameDataSource\", () => {\n let datasource: SolanaTrustedNameDataSource;\n let httpMock: { get: ReturnType<typeof vi.fn> };\n const address = \"vitalik.sol\";\n const challenge = \"deadbeef\";\n\n const makeConfig = (mode: \"prod\" | \"test\" = \"prod\") =>\n ({\n metadataServiceDomain: { url: \"https://nft.api.ledger.com\" },\n cal: { mode },\n }) as ContextModuleServiceConfig;\n\n const makeDatasource = (mode: \"prod\" | \"test\" = \"prod\") =>\n new HttpSolanaTrustedNameDataSource(\n makeConfig(mode),\n httpMock as unknown as DmkNetworkClient,\n );\n\n const objectResponse = (\n signatures: { prod?: string; test?: string },\n data = \"ff00\",\n ) => ({\n descriptorType: \"name\",\n descriptorVersion: \"2\",\n signedDescriptor: { data, signatures },\n keyId: \"cal_trusted_name\",\n keyUsage: \"trusted_name\",\n });\n\n beforeEach(() => {\n vi.clearAllMocks();\n httpMock = { get: vi.fn() };\n datasource = makeDatasource();\n });\n\n it(\"calls the names endpoint with network, types, sources and challenge\", async () => {\n httpMock.get.mockResolvedValue(objectResponse({ prod: \"aabb\" }));\n\n await datasource.getTrustedName({\n address,\n network: String(SolanaTransactionScanChainId.MAINNET),\n challenge,\n types: [\"token\", \"smart_contract\"],\n sources: [\"crypto_asset_list\"],\n });\n\n expect(httpMock.get).toHaveBeenCalledWith(\n `https://nft.api.ledger.com/v2/names/solana/${SolanaTransactionScanChainId.MAINNET}/reverse/${address}`,\n {\n params: {\n types: \"token,smart_contract\",\n sources: \"crypto_asset_list\",\n challenge,\n },\n },\n );\n });\n\n it(\"appends the prod signature TLV and decodes into a Uint8Array\", async () => {\n httpMock.get.mockResolvedValue(\n objectResponse({ prod: \"aabb\", test: \"cc\" }),\n );\n\n const result = await datasource.getTrustedName({\n address,\n network: String(SolanaTransactionScanChainId.MAINNET),\n challenge,\n types: [\"token\", \"smart_contract\"],\n sources: [\"crypto_asset_list\"],\n });\n\n // data(ff00) + SIGNATURE_TAG(15) + len(02) + sig(aabb)\n expect(result).toEqual(\n Right({\n address,\n descriptor: new Uint8Array([0xff, 0x00, 0x15, 0x02, 0xaa, 0xbb]),\n keyId: \"cal_trusted_name\",\n keyUsage: \"trusted_name\",\n }),\n );\n });\n\n it(\"selects the test signature when cal.mode is test\", async () => {\n datasource = makeDatasource(\"test\");\n httpMock.get.mockResolvedValue(\n objectResponse({ prod: \"aabb\", test: \"cc\" }),\n );\n\n const result = await datasource.getTrustedName({\n address,\n network: String(SolanaTransactionScanChainId.MAINNET),\n challenge,\n types: [\"token\", \"smart_contract\"],\n sources: [\"crypto_asset_list\"],\n });\n\n // data(ff00) + SIGNATURE_TAG(15) + len(01) + sig(cc)\n expect(result).toEqual(\n Right({\n address,\n descriptor: new Uint8Array([0xff, 0x00, 0x15, 0x01, 0xcc]),\n keyId: \"cal_trusted_name\",\n keyUsage: \"trusted_name\",\n }),\n );\n });\n\n it(\"returns Left when the signature for the active mode is missing\", async () => {\n datasource = makeDatasource(\"prod\");\n httpMock.get.mockResolvedValue(objectResponse({ test: \"cc\" }));\n\n const result = await datasource.getTrustedName({\n address,\n network: String(SolanaTransactionScanChainId.MAINNET),\n challenge,\n types: [\"token\", \"smart_contract\"],\n sources: [\"crypto_asset_list\"],\n });\n\n expect(result.isLeft()).toBe(true);\n expect((result.extract() as Error).message).toMatch(\n new RegExp(\n String.raw`\\[ContextModule\\] HttpSolanaTrustedNameDataSource: missing prod signature for ${address}`,\n ),\n );\n });\n\n it(\"returns Left on malformed response (hex-string signedDescriptor)\", async () => {\n httpMock.get.mockResolvedValue({\n signedDescriptor: \"01020304\",\n keyId: \"k\",\n keyUsage: \"u\",\n } as any);\n\n const result = await datasource.getTrustedName({\n address,\n network: String(SolanaTransactionScanChainId.MAINNET),\n challenge,\n types: [],\n sources: [],\n });\n\n expect(result.isLeft()).toBe(true);\n expect((result.extract() as Error).message).toMatch(\n new RegExp(\n String.raw`\\[ContextModule\\] HttpSolanaTrustedNameDataSource: malformed response for ${address}:`,\n ),\n );\n });\n\n it(\"returns Left when HTTP client throws\", async () => {\n httpMock.get.mockRejectedValue(new Error(\"net\"));\n\n const result = await datasource.getTrustedName({\n address,\n network: String(SolanaTransactionScanChainId.MAINNET),\n challenge,\n types: [],\n sources: [],\n });\n\n expect(result).toEqual(\n Left(\n new Error(\n \"[ContextModule] HttpSolanaTrustedNameDataSource: Failed to fetch trusted name: net\",\n ),\n ),\n );\n });\n});\n"],
5
+ "mappings": "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",
6
6
  "names": ["import_purify_ts", "import_vitest", "import_SolanaTransactionScanChainId", "import_HttpTrustedNameDataSource", "datasource", "httpMock", "address", "challenge", "makeConfig", "mode", "makeDatasource", "objectResponse", "signatures", "data", "result"]
7
7
  }
@@ -1,2 +1,2 @@
1
- "use strict";var s=Object.defineProperty;var o=Object.getOwnPropertyDescriptor;var i=Object.getOwnPropertyNames;var d=Object.prototype.hasOwnProperty;var m=(r,e,n,a)=>{if(e&&typeof e=="object"||typeof e=="function")for(let t of i(e))!d.call(r,t)&&t!==n&&s(r,t,{get:()=>e[t],enumerable:!(a=o(e,t))||a.enumerable});return r};var g=r=>m(s({},"__esModule",{value:!0}),r);var u={};module.exports=g(u);
1
+ "use strict";var s=Object.defineProperty;var o=Object.getOwnPropertyDescriptor;var i=Object.getOwnPropertyNames;var d=Object.prototype.hasOwnProperty;var m=(r,e,n,a)=>{if(e&&typeof e=="object"||typeof e=="function")for(let t of i(e))!d.call(r,t)&&t!==n&&s(r,t,{get:()=>e[t],enumerable:!(a=o(e,t))||a.enumerable});return r};var g=r=>m(s({},"__esModule",{value:!0}),r);var p={};module.exports=g(p);
2
2
  //# sourceMappingURL=TrustedNameDataSource.js.map
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "version": 3,
3
3
  "sources": ["../../../../../../../src/modules/solana/trusted-name/data/TrustedNameDataSource.ts"],
4
- "sourcesContent": ["import { type Either } from \"purify-ts\";\n\nexport type GetSolanaTrustedNameParams = {\n address: string;\n network: string;\n challenge: string;\n sources: string[];\n};\n\nexport type SolanaTrustedNameResult = {\n address: string;\n // Raw signed TLV bytes decoded from the backend response.\n descriptor: Uint8Array;\n keyId: string;\n keyUsage: string;\n};\n\nexport interface SolanaTrustedNameDataSource {\n getTrustedName(\n params: GetSolanaTrustedNameParams,\n ): Promise<Either<Error, SolanaTrustedNameResult>>;\n}\n"],
4
+ "sourcesContent": ["import { type Either } from \"purify-ts\";\n\nexport type GetSolanaTrustedNameParams = {\n address: string;\n network: string;\n challenge: string;\n types: string[];\n sources: string[];\n};\n\nexport type SolanaTrustedNameResult = {\n address: string;\n // Raw signed TLV bytes decoded from the backend response.\n descriptor: Uint8Array;\n keyId: string;\n keyUsage: string;\n};\n\nexport interface SolanaTrustedNameDataSource {\n getTrustedName(\n params: GetSolanaTrustedNameParams,\n ): Promise<Either<Error, SolanaTrustedNameResult>>;\n}\n"],
5
5
  "mappings": "+WAAA,IAAAA,EAAA,kBAAAC,EAAAD",
6
6
  "names": ["TrustedNameDataSource_exports", "__toCommonJS"]
7
7
  }
@@ -1,2 +1,2 @@
1
- "use strict";var l=Object.defineProperty;var u=Object.getOwnPropertyDescriptor;var I=Object.getOwnPropertyNames;var E=Object.prototype.hasOwnProperty;var v=(a,e)=>{for(var o in e)l(a,o,{get:e[o],enumerable:!0})},x=(a,e,o,r)=>{if(e&&typeof e=="object"||typeof e=="function")for(let t of I(e))!E.call(a,t)&&t!==o&&l(a,t,{get:()=>e[t],enumerable:!(r=u(e,t))||r.enumerable});return a};var L=a=>x(l({},"__esModule",{value:!0}),a),T=(a,e,o,r)=>{for(var t=r>1?void 0:r?u(e,o):e,i=a.length-1,g;i>=0;i--)(g=a[i])&&(t=(r?g(e,o,t):g(t))||t);return r&&t&&l(e,o,t),t},p=(a,e)=>(o,r)=>e(o,r,a);var k={};v(k,{SolanaTrustedNameContextLoader:()=>d});module.exports=L(k);var s=require("inversify"),n=require("purify-ts"),f=require("../../../../config/di/configTypes"),C=require("../../../../modules/multichain/pki/di/pkiTypes"),c=require("../../../../modules/solana/model/SolanaTransactionScanChainId"),N=require("../../../../modules/solana/trusted-name/di/trustedNameTypes"),m=require("../../../../shared/model/ClearSignContext"),y=require("../../../../shared/utils/challengeBoundLoader"),h=require("../../../../shared/utils/deviceModelIdCodec");const M=[m.ClearSignContextType.SOLANA_TRUSTED_NAME],D={"solana-mainnet":c.SolanaTransactionScanChainId.MAINNET,"solana-devnet":c.SolanaTransactionScanChainId.DEVNET,"solana-testnet":c.SolanaTransactionScanChainId.TESTNET},S=c.SolanaTransactionScanChainId.MAINNET,A=n.Codec.interface({address:n.string,challenge:n.string,sources:(0,n.array)(n.string)}),R=n.Codec.interface({deviceModelId:h.deviceModelIdCodec,network:(0,n.optional)(n.string),requests:(0,n.array)(A)});let d=class{constructor(e,o,r){this.dataSource=e;this.certificateLoader=o;this.logger=r("SolanaTrustedNameContextLoader")}logger;canHandle(e,o){return M.every(r=>o.includes(r))?R.decode(e).caseOf({Left:()=>!1,Right:({requests:r})=>r.length>0&&r.every(t=>t.address.length>0&&t.challenge.length>0)}):!1}async load(e){const o=e.network?D[e.network]??S:S,r=String(o);return(0,y.loadChallengeBoundContexts)({requests:e.requests,deviceModelId:e.deviceModelId,certificateLoader:this.certificateLoader,logger:this.logger,label:"TRUSTED_NAME",fetch:t=>this.dataSource.getTrustedName({address:t.address,challenge:t.challenge,sources:t.sources,network:r}),toContext:(t,i)=>({type:m.ClearSignContextType.SOLANA_TRUSTED_NAME,payload:t.descriptor,certificate:i}),describe:t=>({address:t.address})})}};d=T([(0,s.injectable)(),p(0,(0,s.inject)(N.solanaTrustedNameTypes.SolanaTrustedNameDataSource)),p(1,(0,s.inject)(C.pkiTypes.PkiCertificateLoader)),p(2,(0,s.inject)(f.configTypes.ContextModuleLoggerFactory))],d);0&&(module.exports={SolanaTrustedNameContextLoader});
1
+ "use strict";var l=Object.defineProperty;var u=Object.getOwnPropertyDescriptor;var I=Object.getOwnPropertyNames;var E=Object.prototype.hasOwnProperty;var v=(n,t)=>{for(var o in t)l(n,o,{get:t[o],enumerable:!0})},x=(n,t,o,r)=>{if(t&&typeof t=="object"||typeof t=="function")for(let e of I(t))!E.call(n,e)&&e!==o&&l(n,e,{get:()=>t[e],enumerable:!(r=u(t,e))||r.enumerable});return n};var L=n=>x(l({},"__esModule",{value:!0}),n),T=(n,t,o,r)=>{for(var e=r>1?void 0:r?u(t,o):t,i=n.length-1,g;i>=0;i--)(g=n[i])&&(e=(r?g(t,o,e):g(e))||e);return r&&e&&l(t,o,e),e},p=(n,t)=>(o,r)=>t(o,r,n);var k={};v(k,{SolanaTrustedNameContextLoader:()=>d});module.exports=L(k);var s=require("inversify"),a=require("purify-ts"),f=require("../../../../config/di/configTypes"),y=require("../../../../modules/multichain/pki/di/pkiTypes"),c=require("../../../../modules/solana/model/SolanaTransactionScanChainId"),C=require("../../../../modules/solana/trusted-name/di/trustedNameTypes"),m=require("../../../../shared/model/ClearSignContext"),N=require("../../../../shared/utils/challengeBoundLoader"),h=require("../../../../shared/utils/deviceModelIdCodec");const M=[m.ClearSignContextType.SOLANA_TRUSTED_NAME],D={"solana-mainnet":c.SolanaTransactionScanChainId.MAINNET,"solana-devnet":c.SolanaTransactionScanChainId.DEVNET,"solana-testnet":c.SolanaTransactionScanChainId.TESTNET},S=c.SolanaTransactionScanChainId.MAINNET,A=a.Codec.interface({address:a.string,challenge:a.string,types:(0,a.array)(a.string),sources:(0,a.array)(a.string)}),R=a.Codec.interface({deviceModelId:h.deviceModelIdCodec,network:(0,a.optional)(a.string),requests:(0,a.array)(A)});let d=class{constructor(t,o,r){this.dataSource=t;this.certificateLoader=o;this.logger=r("SolanaTrustedNameContextLoader")}logger;canHandle(t,o){return M.every(r=>o.includes(r))?R.decode(t).caseOf({Left:()=>!1,Right:({requests:r})=>r.length>0&&r.every(e=>e.address.length>0&&e.challenge.length>0)}):!1}async load(t){const o=t.network?D[t.network]??S:S,r=String(o);return(0,N.loadChallengeBoundContexts)({requests:t.requests,deviceModelId:t.deviceModelId,certificateLoader:this.certificateLoader,logger:this.logger,label:"TRUSTED_NAME",fetch:e=>this.dataSource.getTrustedName({address:e.address,challenge:e.challenge,types:e.types,sources:e.sources,network:r}),toContext:(e,i)=>({type:m.ClearSignContextType.SOLANA_TRUSTED_NAME,payload:e.descriptor,certificate:i}),describe:e=>({address:e.address})})}};d=T([(0,s.injectable)(),p(0,(0,s.inject)(C.solanaTrustedNameTypes.SolanaTrustedNameDataSource)),p(1,(0,s.inject)(y.pkiTypes.PkiCertificateLoader)),p(2,(0,s.inject)(f.configTypes.ContextModuleLoggerFactory))],d);0&&(module.exports={SolanaTrustedNameContextLoader});
2
2
  //# sourceMappingURL=TrustedNameContextLoader.js.map
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "version": 3,
3
3
  "sources": ["../../../../../../../src/modules/solana/trusted-name/domain/TrustedNameContextLoader.ts"],
4
- "sourcesContent": ["import {\n type DeviceModelId,\n type LoggerPublisherService,\n} from \"@ledgerhq/device-management-kit\";\nimport { inject, injectable } from \"inversify\";\nimport { array, Codec, optional, string } from \"purify-ts\";\n\nimport { configTypes } from \"@/config/di/configTypes\";\nimport { pkiTypes } from \"@/modules/multichain/pki/di/pkiTypes\";\nimport { type PkiCertificateLoader } from \"@/modules/multichain/pki/domain/PkiCertificateLoader\";\nimport { SolanaTransactionScanChainId } from \"@/modules/solana/model/SolanaTransactionScanChainId\";\nimport { type SolanaTrustedNameDataSource } from \"@/modules/solana/trusted-name/data/TrustedNameDataSource\";\nimport { solanaTrustedNameTypes } from \"@/modules/solana/trusted-name/di/trustedNameTypes\";\nimport { type ContextLoader } from \"@/shared/domain/ContextLoader\";\nimport {\n type ClearSignContext,\n ClearSignContextType,\n} from \"@/shared/model/ClearSignContext\";\nimport { loadChallengeBoundContexts } from \"@/shared/utils/challengeBoundLoader\";\nimport { deviceModelIdCodec } from \"@/shared/utils/deviceModelIdCodec\";\n\nconst SUPPORTED_TYPES: ClearSignContextType[] = [\n ClearSignContextType.SOLANA_TRUSTED_NAME,\n];\n\nconst CHAIN_ID_BY_NETWORK: Record<string, SolanaTransactionScanChainId> = {\n \"solana-mainnet\": SolanaTransactionScanChainId.MAINNET,\n \"solana-devnet\": SolanaTransactionScanChainId.DEVNET,\n \"solana-testnet\": SolanaTransactionScanChainId.TESTNET,\n};\n\nconst NETWORK_DEFAULT = SolanaTransactionScanChainId.MAINNET;\n\n/**\n * One trusted-name request, resolved to a Uint8Array TLV descriptor. The\n * caller must obtain a fresh challenge immediately before each fetch.\n */\nexport type SolanaTrustedNameRequest = {\n address: string;\n challenge: string;\n sources: string[];\n};\n\nexport type SolanaTrustedNameContextInput = {\n deviceModelId: DeviceModelId;\n network?: string; // \"mainnet\" | \"devnet\" | \"testnet\"; defaults to mainnet\n requests: SolanaTrustedNameRequest[];\n};\n\nconst trustedNameRequestCodec = Codec.interface({\n address: string,\n challenge: string,\n sources: array(string),\n});\n\nconst solanaTrustedNameInputCodec = Codec.interface({\n deviceModelId: deviceModelIdCodec,\n network: optional(string),\n requests: array(trustedNameRequestCodec),\n});\n\n@injectable()\nexport class SolanaTrustedNameContextLoader\n implements ContextLoader<SolanaTrustedNameContextInput>\n{\n private readonly logger: LoggerPublisherService;\n\n constructor(\n @inject(solanaTrustedNameTypes.SolanaTrustedNameDataSource)\n private readonly dataSource: SolanaTrustedNameDataSource,\n @inject(pkiTypes.PkiCertificateLoader)\n private readonly certificateLoader: PkiCertificateLoader,\n @inject(configTypes.ContextModuleLoggerFactory)\n loggerFactory: (tag: string) => LoggerPublisherService,\n ) {\n this.logger = loggerFactory(\"SolanaTrustedNameContextLoader\");\n }\n\n public canHandle(\n input: unknown,\n expectedTypes: ClearSignContextType[],\n ): input is SolanaTrustedNameContextInput {\n if (!SUPPORTED_TYPES.every((t) => expectedTypes.includes(t))) return false;\n return solanaTrustedNameInputCodec.decode(input).caseOf({\n Left: () => false,\n Right: ({ requests }) =>\n requests.length > 0 &&\n requests.every((r) => r.address.length > 0 && r.challenge.length > 0),\n });\n }\n\n public async load(\n input: SolanaTrustedNameContextInput,\n ): Promise<ClearSignContext[]> {\n const chainId = input.network\n ? (CHAIN_ID_BY_NETWORK[input.network] ?? NETWORK_DEFAULT)\n : NETWORK_DEFAULT;\n const network = String(chainId);\n\n return loadChallengeBoundContexts({\n requests: input.requests,\n deviceModelId: input.deviceModelId,\n certificateLoader: this.certificateLoader,\n logger: this.logger,\n label: \"TRUSTED_NAME\",\n fetch: (request) =>\n this.dataSource.getTrustedName({\n address: request.address,\n challenge: request.challenge,\n sources: request.sources,\n network,\n }),\n toContext: (value, certificate) => ({\n type: ClearSignContextType.SOLANA_TRUSTED_NAME,\n payload: value.descriptor,\n certificate,\n }),\n describe: (request) => ({ address: request.address }),\n });\n }\n}\n"],
5
- "mappings": "okBAAA,IAAAA,EAAA,GAAAC,EAAAD,EAAA,oCAAAE,IAAA,eAAAC,EAAAH,GAIA,IAAAI,EAAmC,qBACnCC,EAA+C,qBAE/CC,EAA4B,mCAC5BC,EAAyB,gDAEzBC,EAA6C,+DAE7CC,EAAuC,6DAEvCC,EAGO,2CACPC,EAA2C,+CAC3CC,EAAmC,6CAEnC,MAAMC,EAA0C,CAC9C,uBAAqB,mBACvB,EAEMC,EAAoE,CACxE,iBAAkB,+BAA6B,QAC/C,gBAAiB,+BAA6B,OAC9C,iBAAkB,+BAA6B,OACjD,EAEMC,EAAkB,+BAA6B,QAkB/CC,EAA0B,QAAM,UAAU,CAC9C,QAAS,SACT,UAAW,SACX,WAAS,SAAM,QAAM,CACvB,CAAC,EAEKC,EAA8B,QAAM,UAAU,CAClD,cAAe,qBACf,WAAS,YAAS,QAAM,EACxB,YAAU,SAAMD,CAAuB,CACzC,CAAC,EAGM,IAAME,EAAN,KAEP,CAGE,YAEmBC,EAEAC,EAEjBC,EACA,CALiB,gBAAAF,EAEA,uBAAAC,EAIjB,KAAK,OAASC,EAAc,gCAAgC,CAC9D,CAXiB,OAaV,UACLC,EACAC,EACwC,CACxC,OAAKV,EAAgB,MAAOW,GAAMD,EAAc,SAASC,CAAC,CAAC,EACpDP,EAA4B,OAAOK,CAAK,EAAE,OAAO,CACtD,KAAM,IAAM,GACZ,MAAO,CAAC,CAAE,SAAAG,CAAS,IACjBA,EAAS,OAAS,GAClBA,EAAS,MAAOC,GAAMA,EAAE,QAAQ,OAAS,GAAKA,EAAE,UAAU,OAAS,CAAC,CACxE,CAAC,EANoE,EAOvE,CAEA,MAAa,KACXJ,EAC6B,CAC7B,MAAMK,EAAUL,EAAM,QACjBR,EAAoBQ,EAAM,OAAO,GAAKP,EACvCA,EACEa,EAAU,OAAOD,CAAO,EAE9B,SAAO,8BAA2B,CAChC,SAAUL,EAAM,SAChB,cAAeA,EAAM,cACrB,kBAAmB,KAAK,kBACxB,OAAQ,KAAK,OACb,MAAO,eACP,MAAQO,GACN,KAAK,WAAW,eAAe,CAC7B,QAASA,EAAQ,QACjB,UAAWA,EAAQ,UACnB,QAASA,EAAQ,QACjB,QAAAD,CACF,CAAC,EACH,UAAW,CAACE,EAAOC,KAAiB,CAClC,KAAM,uBAAqB,oBAC3B,QAASD,EAAM,WACf,YAAAC,CACF,GACA,SAAWF,IAAa,CAAE,QAASA,EAAQ,OAAQ,EACrD,CAAC,CACH,CACF,EA1DaX,EAANc,EAAA,IADN,cAAW,EAOPC,EAAA,eAAO,yBAAuB,2BAA2B,GAEzDA,EAAA,eAAO,WAAS,oBAAoB,GAEpCA,EAAA,eAAO,cAAY,0BAA0B,IAVrCf",
4
+ "sourcesContent": ["import {\n type DeviceModelId,\n type LoggerPublisherService,\n} from \"@ledgerhq/device-management-kit\";\nimport { inject, injectable } from \"inversify\";\nimport { array, Codec, optional, string } from \"purify-ts\";\n\nimport { configTypes } from \"@/config/di/configTypes\";\nimport { pkiTypes } from \"@/modules/multichain/pki/di/pkiTypes\";\nimport { type PkiCertificateLoader } from \"@/modules/multichain/pki/domain/PkiCertificateLoader\";\nimport { SolanaTransactionScanChainId } from \"@/modules/solana/model/SolanaTransactionScanChainId\";\nimport { type SolanaTrustedNameDataSource } from \"@/modules/solana/trusted-name/data/TrustedNameDataSource\";\nimport { solanaTrustedNameTypes } from \"@/modules/solana/trusted-name/di/trustedNameTypes\";\nimport { type ContextLoader } from \"@/shared/domain/ContextLoader\";\nimport {\n type ClearSignContext,\n ClearSignContextType,\n} from \"@/shared/model/ClearSignContext\";\nimport { loadChallengeBoundContexts } from \"@/shared/utils/challengeBoundLoader\";\nimport { deviceModelIdCodec } from \"@/shared/utils/deviceModelIdCodec\";\n\nconst SUPPORTED_TYPES: ClearSignContextType[] = [\n ClearSignContextType.SOLANA_TRUSTED_NAME,\n];\n\nconst CHAIN_ID_BY_NETWORK: Record<string, SolanaTransactionScanChainId> = {\n \"solana-mainnet\": SolanaTransactionScanChainId.MAINNET,\n \"solana-devnet\": SolanaTransactionScanChainId.DEVNET,\n \"solana-testnet\": SolanaTransactionScanChainId.TESTNET,\n};\n\nconst NETWORK_DEFAULT = SolanaTransactionScanChainId.MAINNET;\n\n/**\n * One trusted-name request, resolved to a Uint8Array TLV descriptor. The\n * caller must obtain a fresh challenge immediately before each fetch.\n */\nexport type SolanaTrustedNameRequest = {\n address: string;\n challenge: string;\n types: string[];\n sources: string[];\n};\n\nexport type SolanaTrustedNameContextInput = {\n deviceModelId: DeviceModelId;\n network?: string; // \"mainnet\" | \"devnet\" | \"testnet\"; defaults to mainnet\n requests: SolanaTrustedNameRequest[];\n};\n\nconst trustedNameRequestCodec = Codec.interface({\n address: string,\n challenge: string,\n types: array(string),\n sources: array(string),\n});\n\nconst solanaTrustedNameInputCodec = Codec.interface({\n deviceModelId: deviceModelIdCodec,\n network: optional(string),\n requests: array(trustedNameRequestCodec),\n});\n\n@injectable()\nexport class SolanaTrustedNameContextLoader\n implements ContextLoader<SolanaTrustedNameContextInput>\n{\n private readonly logger: LoggerPublisherService;\n\n constructor(\n @inject(solanaTrustedNameTypes.SolanaTrustedNameDataSource)\n private readonly dataSource: SolanaTrustedNameDataSource,\n @inject(pkiTypes.PkiCertificateLoader)\n private readonly certificateLoader: PkiCertificateLoader,\n @inject(configTypes.ContextModuleLoggerFactory)\n loggerFactory: (tag: string) => LoggerPublisherService,\n ) {\n this.logger = loggerFactory(\"SolanaTrustedNameContextLoader\");\n }\n\n public canHandle(\n input: unknown,\n expectedTypes: ClearSignContextType[],\n ): input is SolanaTrustedNameContextInput {\n if (!SUPPORTED_TYPES.every((t) => expectedTypes.includes(t))) return false;\n return solanaTrustedNameInputCodec.decode(input).caseOf({\n Left: () => false,\n Right: ({ requests }) =>\n requests.length > 0 &&\n requests.every((r) => r.address.length > 0 && r.challenge.length > 0),\n });\n }\n\n public async load(\n input: SolanaTrustedNameContextInput,\n ): Promise<ClearSignContext[]> {\n const chainId = input.network\n ? (CHAIN_ID_BY_NETWORK[input.network] ?? NETWORK_DEFAULT)\n : NETWORK_DEFAULT;\n const network = String(chainId);\n\n return loadChallengeBoundContexts({\n requests: input.requests,\n deviceModelId: input.deviceModelId,\n certificateLoader: this.certificateLoader,\n logger: this.logger,\n label: \"TRUSTED_NAME\",\n fetch: (request) =>\n this.dataSource.getTrustedName({\n address: request.address,\n challenge: request.challenge,\n types: request.types,\n sources: request.sources,\n network,\n }),\n toContext: (value, certificate) => ({\n type: ClearSignContextType.SOLANA_TRUSTED_NAME,\n payload: value.descriptor,\n certificate,\n }),\n describe: (request) => ({ address: request.address }),\n });\n }\n}\n"],
5
+ "mappings": "okBAAA,IAAAA,EAAA,GAAAC,EAAAD,EAAA,oCAAAE,IAAA,eAAAC,EAAAH,GAIA,IAAAI,EAAmC,qBACnCC,EAA+C,qBAE/CC,EAA4B,mCAC5BC,EAAyB,gDAEzBC,EAA6C,+DAE7CC,EAAuC,6DAEvCC,EAGO,2CACPC,EAA2C,+CAC3CC,EAAmC,6CAEnC,MAAMC,EAA0C,CAC9C,uBAAqB,mBACvB,EAEMC,EAAoE,CACxE,iBAAkB,+BAA6B,QAC/C,gBAAiB,+BAA6B,OAC9C,iBAAkB,+BAA6B,OACjD,EAEMC,EAAkB,+BAA6B,QAmB/CC,EAA0B,QAAM,UAAU,CAC9C,QAAS,SACT,UAAW,SACX,SAAO,SAAM,QAAM,EACnB,WAAS,SAAM,QAAM,CACvB,CAAC,EAEKC,EAA8B,QAAM,UAAU,CAClD,cAAe,qBACf,WAAS,YAAS,QAAM,EACxB,YAAU,SAAMD,CAAuB,CACzC,CAAC,EAGM,IAAME,EAAN,KAEP,CAGE,YAEmBC,EAEAC,EAEjBC,EACA,CALiB,gBAAAF,EAEA,uBAAAC,EAIjB,KAAK,OAASC,EAAc,gCAAgC,CAC9D,CAXiB,OAaV,UACLC,EACAC,EACwC,CACxC,OAAKV,EAAgB,MAAOW,GAAMD,EAAc,SAASC,CAAC,CAAC,EACpDP,EAA4B,OAAOK,CAAK,EAAE,OAAO,CACtD,KAAM,IAAM,GACZ,MAAO,CAAC,CAAE,SAAAG,CAAS,IACjBA,EAAS,OAAS,GAClBA,EAAS,MAAOC,GAAMA,EAAE,QAAQ,OAAS,GAAKA,EAAE,UAAU,OAAS,CAAC,CACxE,CAAC,EANoE,EAOvE,CAEA,MAAa,KACXJ,EAC6B,CAC7B,MAAMK,EAAUL,EAAM,QACjBR,EAAoBQ,EAAM,OAAO,GAAKP,EACvCA,EACEa,EAAU,OAAOD,CAAO,EAE9B,SAAO,8BAA2B,CAChC,SAAUL,EAAM,SAChB,cAAeA,EAAM,cACrB,kBAAmB,KAAK,kBACxB,OAAQ,KAAK,OACb,MAAO,eACP,MAAQO,GACN,KAAK,WAAW,eAAe,CAC7B,QAASA,EAAQ,QACjB,UAAWA,EAAQ,UACnB,MAAOA,EAAQ,MACf,QAASA,EAAQ,QACjB,QAAAD,CACF,CAAC,EACH,UAAW,CAACE,EAAOC,KAAiB,CAClC,KAAM,uBAAqB,oBAC3B,QAASD,EAAM,WACf,YAAAC,CACF,GACA,SAAWF,IAAa,CAAE,QAASA,EAAQ,OAAQ,EACrD,CAAC,CACH,CACF,EA3DaX,EAANc,EAAA,IADN,cAAW,EAOPC,EAAA,eAAO,yBAAuB,2BAA2B,GAEzDA,EAAA,eAAO,WAAS,oBAAoB,GAEpCA,EAAA,eAAO,cAAY,0BAA0B,IAVrCf",
6
6
  "names": ["TrustedNameContextLoader_exports", "__export", "SolanaTrustedNameContextLoader", "__toCommonJS", "import_inversify", "import_purify_ts", "import_configTypes", "import_pkiTypes", "import_SolanaTransactionScanChainId", "import_trustedNameTypes", "import_ClearSignContext", "import_challengeBoundLoader", "import_deviceModelIdCodec", "SUPPORTED_TYPES", "CHAIN_ID_BY_NETWORK", "NETWORK_DEFAULT", "trustedNameRequestCodec", "solanaTrustedNameInputCodec", "SolanaTrustedNameContextLoader", "dataSource", "certificateLoader", "loggerFactory", "input", "expectedTypes", "t", "requests", "r", "chainId", "network", "request", "value", "certificate", "__decorateClass", "__decorateParam"]
7
7
  }
@@ -1,2 +1,2 @@
1
- "use strict";var c=require("@ledgerhq/device-management-kit"),o=require("purify-ts"),e=require("vitest"),m=require("../../../../modules/solana/model/SolanaTransactionScanChainId"),r=require("../../../../shared/model/ClearSignContext"),y=require("./TrustedNameContextLoader");const A=()=>({debug:e.vi.fn(),info:e.vi.fn(),warn:e.vi.fn(),error:e.vi.fn(),subscribers:[]}),l={keyUsageNumber:4,payload:new Uint8Array([7])},t="Addr11111111111111111111111111111111111111",u="Addr22222222222222222222222222222222222222";(0,e.describe)("SolanaTrustedNameContextLoader",()=>{let d,i;(0,e.beforeEach)(()=>{e.vi.restoreAllMocks(),d={getTrustedName:e.vi.fn()},i={loadCertificate:e.vi.fn().mockResolvedValue(l)}});const n=()=>new y.SolanaTrustedNameContextLoader(d,i,A);(0,e.describe)("canHandle",()=>{(0,e.it)("returns true when SOLANA_TRUSTED_NAME is requested with valid requests",()=>{(0,e.expect)(n().canHandle({deviceModelId:c.DeviceModelId.NANO_X,requests:[{address:t,challenge:"c",sources:["sns"]}]},[r.ClearSignContextType.SOLANA_TRUSTED_NAME])).toBe(!0)}),(0,e.it)("returns false when SOLANA_TRUSTED_NAME is not requested",()=>{(0,e.expect)(n().canHandle({requests:[{address:t,challenge:"c",sources:["sns"]}]},[r.ClearSignContextType.SOLANA_TOKEN])).toBe(!1)}),(0,e.it)("returns false on malformed input",()=>{const a=n(),s=[r.ClearSignContextType.SOLANA_TRUSTED_NAME];(0,e.expect)(a.canHandle({requests:[]},s)).toBe(!1),(0,e.expect)(a.canHandle({requests:[{address:"",challenge:"c",sources:[]}]},s)).toBe(!1),(0,e.expect)(a.canHandle({requests:[{address:t,challenge:"",sources:[]}]},s)).toBe(!1)})}),(0,e.describe)("load",()=>{(0,e.it)("emits one SOLANA_TRUSTED_NAME per request with Uint8Array payload",async()=>{e.vi.spyOn(d,"getTrustedName").mockImplementation(async({address:s})=>(0,o.Right)({address:s,descriptor:new Uint8Array([s===t?170:187]),keyId:"name_key",keyUsage:"trusted_name"}));const a=await n().load({deviceModelId:c.DeviceModelId.NANO_X,requests:[{address:t,challenge:"c1",sources:["sns"]},{address:u,challenge:"c2",sources:["cal"]}]});(0,e.expect)(a).toHaveLength(2),(0,e.expect)(a[0]).toMatchObject({type:r.ClearSignContextType.SOLANA_TRUSTED_NAME,payload:new Uint8Array([170]),certificate:l}),(0,e.expect)(a[1]).toMatchObject({type:r.ClearSignContextType.SOLANA_TRUSTED_NAME,payload:new Uint8Array([187])})}),(0,e.it)("emits an ERROR per failing request and keeps the others",async()=>{e.vi.spyOn(d,"getTrustedName").mockImplementation(async({address:s})=>s===t?(0,o.Right)({address:s,descriptor:new Uint8Array([170]),keyId:"k",keyUsage:"u"}):(0,o.Left)(new Error("upstream-404")));const a=await n().load({deviceModelId:c.DeviceModelId.NANO_X,requests:[{address:t,challenge:"c1",sources:[]},{address:u,challenge:"c2",sources:[]}]});(0,e.expect)(a[0]?.type).toBe(r.ClearSignContextType.SOLANA_TRUSTED_NAME),(0,e.expect)(a[1]?.type).toBe(r.ClearSignContextType.ERROR)}),(0,e.it)("forwards default chain id 900 when input.network is omitted",async()=>{const a=e.vi.spyOn(d,"getTrustedName").mockResolvedValue((0,o.Right)({address:t,descriptor:new Uint8Array([1]),keyId:"k",keyUsage:"u"}));await n().load({deviceModelId:c.DeviceModelId.NANO_X,requests:[{address:t,challenge:"c",sources:[]}]}),(0,e.expect)(a).toHaveBeenCalledWith(e.expect.objectContaining({network:String(m.SolanaTransactionScanChainId.MAINNET)}))}),(0,e.it)("maps a cluster name to its numeric chain id",async()=>{const a=e.vi.spyOn(d,"getTrustedName").mockResolvedValue((0,o.Right)({address:t,descriptor:new Uint8Array([1]),keyId:"k",keyUsage:"u"}));await n().load({deviceModelId:c.DeviceModelId.NANO_X,network:"solana-devnet",requests:[{address:t,challenge:"c",sources:[]}]}),(0,e.expect)(a).toHaveBeenCalledWith(e.expect.objectContaining({network:"901"}))})})});
1
+ "use strict";var d=require("@ledgerhq/device-management-kit"),o=require("purify-ts"),e=require("vitest"),y=require("../../../../modules/solana/model/SolanaTransactionScanChainId"),r=require("../../../../shared/model/ClearSignContext"),m=require("./TrustedNameContextLoader");const p=()=>({debug:e.vi.fn(),info:e.vi.fn(),warn:e.vi.fn(),error:e.vi.fn(),subscribers:[]}),l={keyUsageNumber:4,payload:new Uint8Array([7])},a="Addr11111111111111111111111111111111111111",u="Addr22222222222222222222222222222222222222";(0,e.describe)("SolanaTrustedNameContextLoader",()=>{let c,i;(0,e.beforeEach)(()=>{e.vi.restoreAllMocks(),c={getTrustedName:e.vi.fn()},i={loadCertificate:e.vi.fn().mockResolvedValue(l)}});const n=()=>new m.SolanaTrustedNameContextLoader(c,i,p);(0,e.describe)("canHandle",()=>{(0,e.it)("returns true when SOLANA_TRUSTED_NAME is requested with valid requests",()=>{(0,e.expect)(n().canHandle({deviceModelId:d.DeviceModelId.NANO_X,requests:[{address:a,challenge:"c",types:["token","smart_contract"],sources:["sns"]}]},[r.ClearSignContextType.SOLANA_TRUSTED_NAME])).toBe(!0)}),(0,e.it)("returns false when SOLANA_TRUSTED_NAME is not requested",()=>{(0,e.expect)(n().canHandle({requests:[{address:a,challenge:"c",types:["token","smart_contract"],sources:["sns"]}]},[r.ClearSignContextType.SOLANA_TOKEN])).toBe(!1)}),(0,e.it)("returns false on malformed input",()=>{const t=n(),s=[r.ClearSignContextType.SOLANA_TRUSTED_NAME];(0,e.expect)(t.canHandle({requests:[]},s)).toBe(!1),(0,e.expect)(t.canHandle({requests:[{address:"",challenge:"c",types:[],sources:[]}]},s)).toBe(!1),(0,e.expect)(t.canHandle({requests:[{address:a,challenge:"",types:[],sources:[]}]},s)).toBe(!1)})}),(0,e.describe)("load",()=>{(0,e.it)("emits one SOLANA_TRUSTED_NAME per request with Uint8Array payload",async()=>{e.vi.spyOn(c,"getTrustedName").mockImplementation(async({address:s})=>(0,o.Right)({address:s,descriptor:new Uint8Array([s===a?170:187]),keyId:"name_key",keyUsage:"trusted_name"}));const t=await n().load({deviceModelId:d.DeviceModelId.NANO_X,requests:[{address:a,challenge:"c1",types:["token","smart_contract"],sources:["sns"]},{address:u,challenge:"c2",types:["token","smart_contract"],sources:["cal"]}]});(0,e.expect)(t).toHaveLength(2),(0,e.expect)(t[0]).toMatchObject({type:r.ClearSignContextType.SOLANA_TRUSTED_NAME,payload:new Uint8Array([170]),certificate:l}),(0,e.expect)(t[1]).toMatchObject({type:r.ClearSignContextType.SOLANA_TRUSTED_NAME,payload:new Uint8Array([187])})}),(0,e.it)("emits an ERROR per failing request and keeps the others",async()=>{e.vi.spyOn(c,"getTrustedName").mockImplementation(async({address:s})=>s===a?(0,o.Right)({address:s,descriptor:new Uint8Array([170]),keyId:"k",keyUsage:"u"}):(0,o.Left)(new Error("upstream-404")));const t=await n().load({deviceModelId:d.DeviceModelId.NANO_X,requests:[{address:a,challenge:"c1",types:[],sources:[]},{address:u,challenge:"c2",types:[],sources:[]}]});(0,e.expect)(t[0]?.type).toBe(r.ClearSignContextType.SOLANA_TRUSTED_NAME),(0,e.expect)(t[1]?.type).toBe(r.ClearSignContextType.ERROR)}),(0,e.it)("forwards default chain id 900 when input.network is omitted",async()=>{const t=e.vi.spyOn(c,"getTrustedName").mockResolvedValue((0,o.Right)({address:a,descriptor:new Uint8Array([1]),keyId:"k",keyUsage:"u"}));await n().load({deviceModelId:d.DeviceModelId.NANO_X,requests:[{address:a,challenge:"c",types:[],sources:[]}]}),(0,e.expect)(t).toHaveBeenCalledWith(e.expect.objectContaining({network:String(y.SolanaTransactionScanChainId.MAINNET)}))}),(0,e.it)("maps a cluster name to its numeric chain id",async()=>{const t=e.vi.spyOn(c,"getTrustedName").mockResolvedValue((0,o.Right)({address:a,descriptor:new Uint8Array([1]),keyId:"k",keyUsage:"u"}));await n().load({deviceModelId:d.DeviceModelId.NANO_X,network:"solana-devnet",requests:[{address:a,challenge:"c",types:[],sources:[]}]}),(0,e.expect)(t).toHaveBeenCalledWith(e.expect.objectContaining({network:"901"}))})})});
2
2
  //# sourceMappingURL=TrustedNameContextLoader.test.js.map
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "version": 3,
3
3
  "sources": ["../../../../../../../src/modules/solana/trusted-name/domain/TrustedNameContextLoader.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 PkiCertificateLoader } from \"@/modules/multichain/pki/domain/PkiCertificateLoader\";\nimport { SolanaTransactionScanChainId } from \"@/modules/solana/model/SolanaTransactionScanChainId\";\nimport { type SolanaTrustedNameDataSource } from \"@/modules/solana/trusted-name/data/TrustedNameDataSource\";\nimport { ClearSignContextType } from \"@/shared/model/ClearSignContext\";\n\nimport { SolanaTrustedNameContextLoader } from \"./TrustedNameContextLoader\";\n\nconst mockLoggerFactory = () => ({\n debug: vi.fn(),\n info: vi.fn(),\n warn: vi.fn(),\n error: vi.fn(),\n subscribers: [],\n});\n\nconst mockCertificate = { keyUsageNumber: 4, payload: new Uint8Array([7]) };\nconst ADDR_A = \"Addr11111111111111111111111111111111111111\";\nconst ADDR_B = \"Addr22222222222222222222222222222222222222\";\n\ndescribe(\"SolanaTrustedNameContextLoader\", () => {\n let dataSource: SolanaTrustedNameDataSource;\n let certificateLoader: PkiCertificateLoader;\n\n beforeEach(() => {\n vi.restoreAllMocks();\n dataSource = {\n getTrustedName: vi.fn(),\n };\n certificateLoader = {\n loadCertificate: vi.fn().mockResolvedValue(mockCertificate),\n };\n });\n\n const makeLoader = () =>\n new SolanaTrustedNameContextLoader(\n dataSource,\n certificateLoader,\n mockLoggerFactory,\n );\n\n describe(\"canHandle\", () => {\n it(\"returns true when SOLANA_TRUSTED_NAME is requested with valid requests\", () => {\n expect(\n makeLoader().canHandle(\n {\n deviceModelId: DeviceModelId.NANO_X,\n requests: [\n {\n address: ADDR_A,\n challenge: \"c\",\n sources: [\"sns\"],\n },\n ],\n },\n [ClearSignContextType.SOLANA_TRUSTED_NAME],\n ),\n ).toBe(true);\n });\n\n it(\"returns false when SOLANA_TRUSTED_NAME is not requested\", () => {\n expect(\n makeLoader().canHandle(\n {\n requests: [\n {\n address: ADDR_A,\n challenge: \"c\",\n sources: [\"sns\"],\n },\n ],\n } as any,\n [ClearSignContextType.SOLANA_TOKEN],\n ),\n ).toBe(false);\n });\n\n it(\"returns false on malformed input\", () => {\n const loader = makeLoader();\n const types = [ClearSignContextType.SOLANA_TRUSTED_NAME];\n expect(loader.canHandle({ requests: [] } as any, types)).toBe(false);\n expect(\n loader.canHandle(\n {\n requests: [{ address: \"\", challenge: \"c\", sources: [] }],\n } as any,\n types,\n ),\n ).toBe(false);\n expect(\n loader.canHandle(\n {\n requests: [{ address: ADDR_A, challenge: \"\", sources: [] }],\n } as any,\n types,\n ),\n ).toBe(false);\n });\n });\n\n describe(\"load\", () => {\n it(\"emits one SOLANA_TRUSTED_NAME per request with Uint8Array payload\", async () => {\n vi.spyOn(dataSource, \"getTrustedName\").mockImplementation(\n async ({ address }) =>\n Right({\n address,\n descriptor: new Uint8Array([address === ADDR_A ? 0xaa : 0xbb]),\n keyId: \"name_key\",\n keyUsage: \"trusted_name\",\n }),\n );\n\n const result = await makeLoader().load({\n deviceModelId: DeviceModelId.NANO_X,\n requests: [\n {\n address: ADDR_A,\n challenge: \"c1\",\n sources: [\"sns\"],\n },\n {\n address: ADDR_B,\n challenge: \"c2\",\n sources: [\"cal\"],\n },\n ],\n });\n\n expect(result).toHaveLength(2);\n expect(result[0]).toMatchObject({\n type: ClearSignContextType.SOLANA_TRUSTED_NAME,\n payload: new Uint8Array([0xaa]),\n certificate: mockCertificate,\n });\n expect(result[1]).toMatchObject({\n type: ClearSignContextType.SOLANA_TRUSTED_NAME,\n payload: new Uint8Array([0xbb]),\n });\n });\n\n it(\"emits an ERROR per failing request and keeps the others\", async () => {\n vi.spyOn(dataSource, \"getTrustedName\").mockImplementation(\n async ({ address }) => {\n if (address === ADDR_A) {\n return Right({\n address,\n descriptor: new Uint8Array([0xaa]),\n keyId: \"k\",\n keyUsage: \"u\",\n });\n }\n return Left(new Error(\"upstream-404\"));\n },\n );\n\n const out = await makeLoader().load({\n deviceModelId: DeviceModelId.NANO_X,\n requests: [\n { address: ADDR_A, challenge: \"c1\", sources: [] },\n { address: ADDR_B, challenge: \"c2\", sources: [] },\n ],\n });\n\n expect(out[0]?.type).toBe(ClearSignContextType.SOLANA_TRUSTED_NAME);\n expect(out[1]?.type).toBe(ClearSignContextType.ERROR);\n });\n\n it(\"forwards default chain id 900 when input.network is omitted\", async () => {\n const spy = vi.spyOn(dataSource, \"getTrustedName\").mockResolvedValue(\n Right({\n address: ADDR_A,\n descriptor: new Uint8Array([1]),\n keyId: \"k\",\n keyUsage: \"u\",\n }),\n );\n\n await makeLoader().load({\n deviceModelId: DeviceModelId.NANO_X,\n requests: [{ address: ADDR_A, challenge: \"c\", sources: [] }],\n });\n\n expect(spy).toHaveBeenCalledWith(\n expect.objectContaining({\n network: String(SolanaTransactionScanChainId.MAINNET),\n }),\n );\n });\n\n it(\"maps a cluster name to its numeric chain id\", async () => {\n const spy = vi.spyOn(dataSource, \"getTrustedName\").mockResolvedValue(\n Right({\n address: ADDR_A,\n descriptor: new Uint8Array([1]),\n keyId: \"k\",\n keyUsage: \"u\",\n }),\n );\n\n await makeLoader().load({\n deviceModelId: DeviceModelId.NANO_X,\n network: \"solana-devnet\",\n requests: [{ address: ADDR_A, challenge: \"c\", sources: [] }],\n });\n\n expect(spy).toHaveBeenCalledWith(\n expect.objectContaining({ network: \"901\" }),\n );\n });\n });\n});\n"],
5
- "mappings": "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",
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 PkiCertificateLoader } from \"@/modules/multichain/pki/domain/PkiCertificateLoader\";\nimport { SolanaTransactionScanChainId } from \"@/modules/solana/model/SolanaTransactionScanChainId\";\nimport { type SolanaTrustedNameDataSource } from \"@/modules/solana/trusted-name/data/TrustedNameDataSource\";\nimport { ClearSignContextType } from \"@/shared/model/ClearSignContext\";\n\nimport { SolanaTrustedNameContextLoader } from \"./TrustedNameContextLoader\";\n\nconst mockLoggerFactory = () => ({\n debug: vi.fn(),\n info: vi.fn(),\n warn: vi.fn(),\n error: vi.fn(),\n subscribers: [],\n});\n\nconst mockCertificate = { keyUsageNumber: 4, payload: new Uint8Array([7]) };\nconst ADDR_A = \"Addr11111111111111111111111111111111111111\";\nconst ADDR_B = \"Addr22222222222222222222222222222222222222\";\n\ndescribe(\"SolanaTrustedNameContextLoader\", () => {\n let dataSource: SolanaTrustedNameDataSource;\n let certificateLoader: PkiCertificateLoader;\n\n beforeEach(() => {\n vi.restoreAllMocks();\n dataSource = {\n getTrustedName: vi.fn(),\n };\n certificateLoader = {\n loadCertificate: vi.fn().mockResolvedValue(mockCertificate),\n };\n });\n\n const makeLoader = () =>\n new SolanaTrustedNameContextLoader(\n dataSource,\n certificateLoader,\n mockLoggerFactory,\n );\n\n describe(\"canHandle\", () => {\n it(\"returns true when SOLANA_TRUSTED_NAME is requested with valid requests\", () => {\n expect(\n makeLoader().canHandle(\n {\n deviceModelId: DeviceModelId.NANO_X,\n requests: [\n {\n address: ADDR_A,\n challenge: \"c\",\n types: [\"token\", \"smart_contract\"],\n sources: [\"sns\"],\n },\n ],\n },\n [ClearSignContextType.SOLANA_TRUSTED_NAME],\n ),\n ).toBe(true);\n });\n\n it(\"returns false when SOLANA_TRUSTED_NAME is not requested\", () => {\n expect(\n makeLoader().canHandle(\n {\n requests: [\n {\n address: ADDR_A,\n challenge: \"c\",\n types: [\"token\", \"smart_contract\"],\n sources: [\"sns\"],\n },\n ],\n } as any,\n [ClearSignContextType.SOLANA_TOKEN],\n ),\n ).toBe(false);\n });\n\n it(\"returns false on malformed input\", () => {\n const loader = makeLoader();\n const types = [ClearSignContextType.SOLANA_TRUSTED_NAME];\n expect(loader.canHandle({ requests: [] } as any, types)).toBe(false);\n expect(\n loader.canHandle(\n {\n requests: [{ address: \"\", challenge: \"c\", types: [], sources: [] }],\n } as any,\n types,\n ),\n ).toBe(false);\n expect(\n loader.canHandle(\n {\n requests: [\n { address: ADDR_A, challenge: \"\", types: [], sources: [] },\n ],\n } as any,\n types,\n ),\n ).toBe(false);\n });\n });\n\n describe(\"load\", () => {\n it(\"emits one SOLANA_TRUSTED_NAME per request with Uint8Array payload\", async () => {\n vi.spyOn(dataSource, \"getTrustedName\").mockImplementation(\n async ({ address }) =>\n Right({\n address,\n descriptor: new Uint8Array([address === ADDR_A ? 0xaa : 0xbb]),\n keyId: \"name_key\",\n keyUsage: \"trusted_name\",\n }),\n );\n\n const result = await makeLoader().load({\n deviceModelId: DeviceModelId.NANO_X,\n requests: [\n {\n address: ADDR_A,\n challenge: \"c1\",\n types: [\"token\", \"smart_contract\"],\n sources: [\"sns\"],\n },\n {\n address: ADDR_B,\n challenge: \"c2\",\n types: [\"token\", \"smart_contract\"],\n sources: [\"cal\"],\n },\n ],\n });\n\n expect(result).toHaveLength(2);\n expect(result[0]).toMatchObject({\n type: ClearSignContextType.SOLANA_TRUSTED_NAME,\n payload: new Uint8Array([0xaa]),\n certificate: mockCertificate,\n });\n expect(result[1]).toMatchObject({\n type: ClearSignContextType.SOLANA_TRUSTED_NAME,\n payload: new Uint8Array([0xbb]),\n });\n });\n\n it(\"emits an ERROR per failing request and keeps the others\", async () => {\n vi.spyOn(dataSource, \"getTrustedName\").mockImplementation(\n async ({ address }) => {\n if (address === ADDR_A) {\n return Right({\n address,\n descriptor: new Uint8Array([0xaa]),\n keyId: \"k\",\n keyUsage: \"u\",\n });\n }\n return Left(new Error(\"upstream-404\"));\n },\n );\n\n const out = await makeLoader().load({\n deviceModelId: DeviceModelId.NANO_X,\n requests: [\n { address: ADDR_A, challenge: \"c1\", types: [], sources: [] },\n { address: ADDR_B, challenge: \"c2\", types: [], sources: [] },\n ],\n });\n\n expect(out[0]?.type).toBe(ClearSignContextType.SOLANA_TRUSTED_NAME);\n expect(out[1]?.type).toBe(ClearSignContextType.ERROR);\n });\n\n it(\"forwards default chain id 900 when input.network is omitted\", async () => {\n const spy = vi.spyOn(dataSource, \"getTrustedName\").mockResolvedValue(\n Right({\n address: ADDR_A,\n descriptor: new Uint8Array([1]),\n keyId: \"k\",\n keyUsage: \"u\",\n }),\n );\n\n await makeLoader().load({\n deviceModelId: DeviceModelId.NANO_X,\n requests: [{ address: ADDR_A, challenge: \"c\", types: [], sources: [] }],\n });\n\n expect(spy).toHaveBeenCalledWith(\n expect.objectContaining({\n network: String(SolanaTransactionScanChainId.MAINNET),\n }),\n );\n });\n\n it(\"maps a cluster name to its numeric chain id\", async () => {\n const spy = vi.spyOn(dataSource, \"getTrustedName\").mockResolvedValue(\n Right({\n address: ADDR_A,\n descriptor: new Uint8Array([1]),\n keyId: \"k\",\n keyUsage: \"u\",\n }),\n );\n\n await makeLoader().load({\n deviceModelId: DeviceModelId.NANO_X,\n network: \"solana-devnet\",\n requests: [{ address: ADDR_A, challenge: \"c\", types: [], sources: [] }],\n });\n\n expect(spy).toHaveBeenCalledWith(\n expect.objectContaining({ network: \"901\" }),\n );\n });\n });\n});\n"],
5
+ "mappings": "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",
6
6
  "names": ["import_device_management_kit", "import_purify_ts", "import_vitest", "import_SolanaTransactionScanChainId", "import_ClearSignContext", "import_TrustedNameContextLoader", "mockLoggerFactory", "mockCertificate", "ADDR_A", "ADDR_B", "dataSource", "certificateLoader", "makeLoader", "loader", "types", "address", "result", "out", "spy"]
7
7
  }
@@ -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": "2.3.0"
61
+ "version": "2.3.1"
62
62
  }
@@ -1,2 +1,2 @@
1
- var m=Object.defineProperty;var f=Object.getOwnPropertyDescriptor;var g=(s,t,a,e)=>{for(var r=e>1?void 0:e?f(t,a):t,o=s.length-1,i;o>=0;o--)(i=s[o])&&(r=(e?i(t,a,r):i(r))||r);return e&&r&&m(t,a,r),r},c=(s,t)=>(a,e)=>t(a,e,s);import{inject as d,injectable as y}from"inversify";import{configTypes as u}from"../../../../config/di/configTypes";import{pkiTypes as S}from"../../../../modules/multichain/pki/di/pkiTypes";import{KeyId as C}from"../../../../modules/multichain/pki/model/KeyId";import{KeyUsage as x}from"../../../../modules/multichain/pki/model/KeyUsage";import{lifiTypes as L}from"../../../../modules/solana/lifi/di/lifiTypes";import{ClearSignContextType as n}from"../../../../shared/model/ClearSignContext";const h=[n.SOLANA_LIFI];let l=class{constructor(t,a,e,r){this.dataSource=t;this.config=a;this._certificateLoader=e;this.logger=r("LifiContextLoader")}logger;canHandle(t,a){if(!h.every(e=>a.includes(e)))return this.logger.debug("[canHandle] Skipping, expected type does not match",{data:{expectedTypes:a,required:n.SOLANA_LIFI}}),!1;if(typeof t=="object"&&t!==null&&"templateId"in t){const e=t.templateId,r=typeof e=="string"&&e.length>0;return this.logger.debug("[canHandle] Field validation result",{data:{templateId:e,isValid:r}}),r}return this.logger.debug("[canHandle] Field does not contain a valid templateId",{data:{input:t}}),!1}async load(t){this.logger.debug("[load] Loading solana Lifi context",{data:{input:t}});const a=await this._loadInternal(t);if(a.type===n.ERROR)return[{type:n.ERROR,error:a.error}];const e=a;return[{type:n.SOLANA_LIFI,payload:e.payload,certificate:e.certificate}]}async _loadInternal(t){this.logger.debug("[_loadInternal] Loading solana Lifi context",{data:{input:t}});const{templateId:a,deviceModelId:e}=t;if(!a)return{type:n.ERROR,error:new Error("[ContextModule] LifiContextLoader: templateId is missing")};const r=await this.dataSource.getTransactionDescriptorsPayload({templateId:a}),o=await this._certificateLoader.loadCertificate({keyId:C.SwapTemplateKey,keyUsage:x.SwapTemplate,targetDevice:e});return r.caseOf({Left:i=>(this.logger.error("[_loadInternal] Error loading solana Lifi context",{data:{error:i}}),{type:n.ERROR,error:i}),Right:i=>{const p=this.buildPayload(i);return this.logger.debug("[_loadInternal] Successfully loaded solana Lifi context",{data:{descriptors:p.descriptors,instructionsCount:p.instructions.length,certificate:o}}),{type:n.SOLANA_LIFI,payload:p,certificate:o}}})}buildPayload(t){return{descriptors:this.pluckTransactionData(t),instructions:this.extractInstructionsMeta(t)}}pluckTransactionData(t){const a=this.config.cal.mode||"prod",e={},r=t.descriptors??[];this.logger.debug("[pluckTransactionData] Processing descriptors",{data:{descriptorsCount:r.length,signatureKind:a}});for(const o of r){const i=`${o.program_id}:${o.discriminator_hex??""}`;e[i]={data:o.descriptor.data,descriptorType:o.descriptor.descriptorType,descriptorVersion:o.descriptor.descriptorVersion,signature:o.descriptor.signatures[a]??""},this.logger.debug("[pluckTransactionData] Mapped program descriptor",{data:{programId:o.program_id,discriminatorHex:o.discriminator_hex??"",key:i}})}return this.logger.debug("[pluckTransactionData] Completed processing",{data:{outputKeys:Object.keys(e)}}),e}extractInstructionsMeta(t){const a=t.instructions??[];this.logger.debug("[extractInstructionsMeta] Extracting instructions metadata",{data:{instructionsCount:a.length}});const e=a.map(r=>({program_id:r.program_id,...r.discriminator_hex!==void 0&&{discriminator_hex:r.discriminator_hex}}));return this.logger.debug("[extractInstructionsMeta] Completed extracting instructions metadata",{data:{meta:e.map(r=>({programId:r.program_id,discriminatorHex:r.discriminator_hex}))}}),e}};l=g([y(),c(0,d(L.LifiDataSource)),c(1,d(u.Config)),c(2,d(S.PkiCertificateLoader)),c(3,d(u.ContextModuleLoggerFactory))],l);export{l as LifiContextLoader};
1
+ var m=Object.defineProperty;var f=Object.getOwnPropertyDescriptor;var g=(s,t,r,a)=>{for(var e=a>1?void 0:a?f(t,r):t,o=s.length-1,i;o>=0;o--)(i=s[o])&&(e=(a?i(t,r,e):i(e))||e);return a&&e&&m(t,r,e),e},d=(s,t)=>(r,a)=>t(r,a,s);import{inject as p,injectable as y}from"inversify";import{configTypes as u}from"../../../../config/di/configTypes";import{pkiTypes as S}from"../../../../modules/multichain/pki/di/pkiTypes";import{KeyId as C}from"../../../../modules/multichain/pki/model/KeyId";import{KeyUsage as h}from"../../../../modules/multichain/pki/model/KeyUsage";import{lifiTypes as x}from"../../../../modules/solana/lifi/di/lifiTypes";import{ClearSignContextType as n}from"../../../../shared/model/ClearSignContext";const L=[n.SOLANA_LIFI];let l=class{constructor(t,r,a,e){this.dataSource=t;this.config=r;this._certificateLoader=a;this.logger=e("LifiContextLoader")}logger;canHandle(t,r){if(!L.every(a=>r.includes(a)))return this.logger.debug("[canHandle] Skipping, expected type does not match",{data:{expectedTypes:r,required:n.SOLANA_LIFI}}),!1;if(typeof t=="object"&&t!==null&&"templateId"in t){const a=t.templateId,e=typeof a=="string"&&a.length>0;return this.logger.debug("[canHandle] Field validation result",{data:{templateId:a,isValid:e}}),e}return this.logger.debug("[canHandle] Field does not contain a valid templateId",{data:{input:t}}),!1}async load(t){this.logger.debug("[load] Loading solana Lifi context",{data:{input:t}});const r=await this._loadInternal(t);if(r.type===n.ERROR)return[{type:n.ERROR,error:r.error}];const a=r;return[{type:n.SOLANA_LIFI,payload:a.payload,certificate:a.certificate}]}async _loadInternal(t){this.logger.debug("[_loadInternal] Loading solana Lifi context",{data:{input:t}});const{templateId:r,deviceModelId:a}=t;if(!r)return{type:n.ERROR,error:new Error("[ContextModule] LifiContextLoader: templateId is missing")};const e=await this.dataSource.getTransactionDescriptorsPayload({templateId:r}),o=await this._certificateLoader.loadCertificate({keyId:C.SwapTemplateKey,keyUsage:h.SwapTemplate,targetDevice:a});return e.caseOf({Left:i=>(this.logger.error("[_loadInternal] Error loading solana Lifi context",{data:{error:i}}),{type:n.ERROR,error:i}),Right:i=>{const c=this.buildPayload(i);return this.logger.debug("[_loadInternal] Successfully loaded solana Lifi context",{data:{descriptors:c.descriptors,instructionsCount:c.instructions.length,certificate:o}}),{type:n.SOLANA_LIFI,payload:c,certificate:o}}})}buildPayload(t){return{descriptors:this.pluckTransactionData(t),instructions:this.extractInstructionsMeta(t)}}pluckTransactionData(t){const r=this.config.cal.mode||"prod",a={},e=t.descriptors??[];this.logger.debug("[pluckTransactionData] Processing descriptors",{data:{descriptorsCount:e.length,signatureKind:r}});for(const o of e){const i=`${o.program_id}:${o.discriminator_hex??""}`,c={data:o.descriptor.data,descriptorType:o.descriptor.descriptorType,descriptorVersion:o.descriptor.descriptorVersion,signature:o.descriptor.signatures[r]??"",...o.has_basis_point!==void 0&&{has_basis_point:o.has_basis_point}};(a[i]??=[]).push(c),this.logger.debug("[pluckTransactionData] Mapped program descriptor",{data:{programId:o.program_id,discriminatorHex:o.discriminator_hex??"",key:i}})}return this.logger.debug("[pluckTransactionData] Completed processing",{data:{outputKeys:Object.keys(a)}}),a}extractInstructionsMeta(t){const r=t.instructions??[];this.logger.debug("[extractInstructionsMeta] Extracting instructions metadata",{data:{instructionsCount:r.length}});const a=r.map(e=>({program_id:e.program_id,...e.discriminator_hex!==void 0&&{discriminator_hex:e.discriminator_hex},...e.amount!==void 0&&{has_basis_point:e.amount.capped_bps!==void 0}}));return this.logger.debug("[extractInstructionsMeta] Completed extracting instructions metadata",{data:{meta:a.map(e=>({programId:e.program_id,discriminatorHex:e.discriminator_hex}))}}),a}};l=g([y(),d(0,p(x.LifiDataSource)),d(1,p(u.Config)),d(2,p(S.PkiCertificateLoader)),d(3,p(u.ContextModuleLoggerFactory))],l);export{l as LifiContextLoader};
2
2
  //# sourceMappingURL=LifiContextLoader.js.map
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "version": 3,
3
3
  "sources": ["../../../../../../../src/modules/solana/lifi/domain/LifiContextLoader.ts"],
4
- "sourcesContent": ["import { LoggerPublisherService } from \"@ledgerhq/device-management-kit\";\nimport { inject, injectable } from \"inversify\";\n\nimport { configTypes } from \"@/config/di/configTypes\";\nimport { type ContextModuleServiceConfig } from \"@/config/model/ContextModuleConfig\";\nimport { pkiTypes } from \"@/modules/multichain/pki/di/pkiTypes\";\nimport { type PkiCertificateLoader } from \"@/modules/multichain/pki/domain/PkiCertificateLoader\";\nimport { KeyId } from \"@/modules/multichain/pki/model/KeyId\";\nimport { KeyUsage } from \"@/modules/multichain/pki/model/KeyUsage\";\nimport { type PkiCertificate } from \"@/modules/multichain/pki/model/PkiCertificate\";\nimport {\n GetTransactionDescriptorsResponse,\n type LifiDataSource,\n} from \"@/modules/solana/lifi/data/LifiDataSource\";\nimport { lifiTypes } from \"@/modules/solana/lifi/di/lifiTypes\";\nimport {\n type SolanaContextError,\n type SolanaLifiContextSuccess,\n type SolanaTransactionDescriptorList,\n} from \"@/modules/solana/model/SolanaContextTypes\";\nimport {\n type SolanaLifiInstructionMeta,\n type SolanaLifiPayload,\n} from \"@/modules/solana/model/SolanaPayloads\";\nimport { type SolanaTransactionContext } from \"@/modules/solana/model/SolanaTransactionContext\";\nimport { type ContextLoader } from \"@/shared/domain/ContextLoader\";\nimport {\n type ClearSignContext,\n ClearSignContextType,\n} from \"@/shared/model/ClearSignContext\";\n\nconst SUPPORTED_TYPES: ClearSignContextType[] = [\n ClearSignContextType.SOLANA_LIFI,\n];\n\n@injectable()\nexport class LifiContextLoader\n implements ContextLoader<SolanaTransactionContext>\n{\n private logger: LoggerPublisherService;\n\n constructor(\n @inject(lifiTypes.LifiDataSource)\n private readonly dataSource: LifiDataSource,\n @inject(configTypes.Config)\n private readonly config: ContextModuleServiceConfig,\n @inject(pkiTypes.PkiCertificateLoader)\n private readonly _certificateLoader: PkiCertificateLoader,\n @inject(configTypes.ContextModuleLoggerFactory)\n loggerFactory: (tag: string) => LoggerPublisherService,\n ) {\n this.logger = loggerFactory(\"LifiContextLoader\");\n }\n\n public canHandle(\n input: unknown,\n expectedTypes: ClearSignContextType[],\n ): input is SolanaTransactionContext {\n if (!SUPPORTED_TYPES.every((t) => expectedTypes.includes(t))) {\n this.logger.debug(\"[canHandle] Skipping, expected type does not match\", {\n data: { expectedTypes, required: ClearSignContextType.SOLANA_LIFI },\n });\n return false;\n }\n\n if (typeof input === \"object\" && input !== null && \"templateId\" in input) {\n const templateId = (input as { templateId: unknown }).templateId;\n const isValid = typeof templateId === \"string\" && templateId.length > 0;\n this.logger.debug(\"[canHandle] Field validation result\", {\n data: { templateId, isValid },\n });\n return isValid;\n }\n\n this.logger.debug(\"[canHandle] Field does not contain a valid templateId\", {\n data: { input },\n });\n return false;\n }\n\n public async load(\n solanaLifiContextInput: SolanaTransactionContext,\n ): Promise<ClearSignContext[]> {\n this.logger.debug(\"[load] Loading solana Lifi context\", {\n data: { input: solanaLifiContextInput },\n });\n const result = await this._loadInternal(solanaLifiContextInput);\n if (result.type === ClearSignContextType.ERROR) {\n return [{ type: ClearSignContextType.ERROR, error: result.error }];\n }\n const r = result as SolanaLifiContextSuccess;\n return [\n {\n type: ClearSignContextType.SOLANA_LIFI,\n payload: r.payload,\n certificate: r.certificate,\n },\n ];\n }\n\n private async _loadInternal(\n solanaLifiContextInput: SolanaTransactionContext,\n ): Promise<SolanaLifiContextSuccess | SolanaContextError> {\n this.logger.debug(\"[_loadInternal] Loading solana Lifi context\", {\n data: { input: solanaLifiContextInput },\n });\n const { templateId, deviceModelId } = solanaLifiContextInput;\n\n if (!templateId) {\n return {\n type: ClearSignContextType.ERROR,\n error: new Error(\n \"[ContextModule] LifiContextLoader: templateId is missing\",\n ),\n };\n }\n\n const payload = await this.dataSource.getTransactionDescriptorsPayload({\n templateId,\n });\n\n const certificate: PkiCertificate | undefined =\n await this._certificateLoader.loadCertificate({\n keyId: KeyId.SwapTemplateKey,\n keyUsage: KeyUsage.SwapTemplate,\n targetDevice: deviceModelId,\n });\n\n return payload.caseOf({\n Left: (error): SolanaLifiContextSuccess | SolanaContextError => {\n this.logger.error(\"[_loadInternal] Error loading solana Lifi context\", {\n data: { error },\n });\n\n return {\n type: ClearSignContextType.ERROR,\n error,\n };\n },\n Right: (value): SolanaLifiContextSuccess | SolanaContextError => {\n const lifiPayload = this.buildPayload(value);\n this.logger.debug(\n \"[_loadInternal] Successfully loaded solana Lifi context\",\n {\n data: {\n descriptors: lifiPayload.descriptors,\n instructionsCount: lifiPayload.instructions.length,\n certificate,\n },\n },\n );\n\n return {\n type: ClearSignContextType.SOLANA_LIFI,\n payload: lifiPayload,\n certificate,\n };\n },\n });\n }\n\n private buildPayload(\n response: GetTransactionDescriptorsResponse,\n ): SolanaLifiPayload {\n return {\n descriptors: this.pluckTransactionData(response),\n instructions: this.extractInstructionsMeta(response),\n };\n }\n\n private pluckTransactionData(\n tokenData: GetTransactionDescriptorsResponse,\n ): SolanaTransactionDescriptorList {\n const signatureKind = this.config.cal.mode || \"prod\";\n const output: SolanaTransactionDescriptorList = {};\n const descriptors = tokenData.descriptors ?? [];\n\n this.logger.debug(\"[pluckTransactionData] Processing descriptors\", {\n data: { descriptorsCount: descriptors.length, signatureKind },\n });\n\n for (const item of descriptors) {\n const key = `${item.program_id}:${item.discriminator_hex ?? \"\"}`;\n output[key] = {\n data: item.descriptor.data,\n descriptorType: item.descriptor.descriptorType,\n descriptorVersion: item.descriptor.descriptorVersion,\n signature: item.descriptor.signatures[signatureKind] ?? \"\",\n };\n this.logger.debug(\"[pluckTransactionData] Mapped program descriptor\", {\n data: {\n programId: item.program_id,\n discriminatorHex: item.discriminator_hex ?? \"\",\n key,\n },\n });\n }\n\n this.logger.debug(\"[pluckTransactionData] Completed processing\", {\n data: { outputKeys: Object.keys(output) },\n });\n\n return output;\n }\n\n private extractInstructionsMeta(\n response: GetTransactionDescriptorsResponse,\n ): SolanaLifiInstructionMeta[] {\n const instructions = response.instructions ?? [];\n\n this.logger.debug(\n \"[extractInstructionsMeta] Extracting instructions metadata\",\n {\n data: { instructionsCount: instructions.length },\n },\n );\n\n const meta = instructions.map((ix) => ({\n program_id: ix.program_id,\n ...(ix.discriminator_hex !== undefined && {\n discriminator_hex: ix.discriminator_hex,\n }),\n }));\n\n this.logger.debug(\n \"[extractInstructionsMeta] Completed extracting instructions metadata\",\n {\n data: {\n meta: meta.map((m) => ({\n programId: m.program_id,\n discriminatorHex: m.discriminator_hex,\n })),\n },\n },\n );\n\n return meta;\n }\n}\n"],
5
- "mappings": "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",
6
- "names": ["inject", "injectable", "configTypes", "pkiTypes", "KeyId", "KeyUsage", "lifiTypes", "ClearSignContextType", "SUPPORTED_TYPES", "ClearSignContextType", "LifiContextLoader", "dataSource", "config", "_certificateLoader", "loggerFactory", "input", "expectedTypes", "t", "templateId", "isValid", "solanaLifiContextInput", "result", "r", "deviceModelId", "payload", "certificate", "KeyId", "KeyUsage", "error", "value", "lifiPayload", "response", "tokenData", "signatureKind", "output", "descriptors", "item", "key", "instructions", "meta", "ix", "m", "__decorateClass", "injectable", "__decorateParam", "inject", "lifiTypes", "configTypes", "pkiTypes"]
4
+ "sourcesContent": ["import { LoggerPublisherService } from \"@ledgerhq/device-management-kit\";\nimport { inject, injectable } from \"inversify\";\n\nimport { configTypes } from \"@/config/di/configTypes\";\nimport { type ContextModuleServiceConfig } from \"@/config/model/ContextModuleConfig\";\nimport { pkiTypes } from \"@/modules/multichain/pki/di/pkiTypes\";\nimport { type PkiCertificateLoader } from \"@/modules/multichain/pki/domain/PkiCertificateLoader\";\nimport { KeyId } from \"@/modules/multichain/pki/model/KeyId\";\nimport { KeyUsage } from \"@/modules/multichain/pki/model/KeyUsage\";\nimport { type PkiCertificate } from \"@/modules/multichain/pki/model/PkiCertificate\";\nimport {\n GetTransactionDescriptorsResponse,\n type LifiDataSource,\n} from \"@/modules/solana/lifi/data/LifiDataSource\";\nimport { lifiTypes } from \"@/modules/solana/lifi/di/lifiTypes\";\nimport {\n type SolanaContextError,\n type SolanaLifiContextSuccess,\n type SolanaTransactionDescriptorList,\n} from \"@/modules/solana/model/SolanaContextTypes\";\nimport {\n type SolanaLifiInstructionMeta,\n type SolanaLifiPayload,\n} from \"@/modules/solana/model/SolanaPayloads\";\nimport { type SolanaTransactionContext } from \"@/modules/solana/model/SolanaTransactionContext\";\nimport { type ContextLoader } from \"@/shared/domain/ContextLoader\";\nimport {\n type ClearSignContext,\n ClearSignContextType,\n} from \"@/shared/model/ClearSignContext\";\n\nconst SUPPORTED_TYPES: ClearSignContextType[] = [\n ClearSignContextType.SOLANA_LIFI,\n];\n\n@injectable()\nexport class LifiContextLoader\n implements ContextLoader<SolanaTransactionContext>\n{\n private logger: LoggerPublisherService;\n\n constructor(\n @inject(lifiTypes.LifiDataSource)\n private readonly dataSource: LifiDataSource,\n @inject(configTypes.Config)\n private readonly config: ContextModuleServiceConfig,\n @inject(pkiTypes.PkiCertificateLoader)\n private readonly _certificateLoader: PkiCertificateLoader,\n @inject(configTypes.ContextModuleLoggerFactory)\n loggerFactory: (tag: string) => LoggerPublisherService,\n ) {\n this.logger = loggerFactory(\"LifiContextLoader\");\n }\n\n public canHandle(\n input: unknown,\n expectedTypes: ClearSignContextType[],\n ): input is SolanaTransactionContext {\n if (!SUPPORTED_TYPES.every((t) => expectedTypes.includes(t))) {\n this.logger.debug(\"[canHandle] Skipping, expected type does not match\", {\n data: { expectedTypes, required: ClearSignContextType.SOLANA_LIFI },\n });\n return false;\n }\n\n if (typeof input === \"object\" && input !== null && \"templateId\" in input) {\n const templateId = (input as { templateId: unknown }).templateId;\n const isValid = typeof templateId === \"string\" && templateId.length > 0;\n this.logger.debug(\"[canHandle] Field validation result\", {\n data: { templateId, isValid },\n });\n return isValid;\n }\n\n this.logger.debug(\"[canHandle] Field does not contain a valid templateId\", {\n data: { input },\n });\n return false;\n }\n\n public async load(\n solanaLifiContextInput: SolanaTransactionContext,\n ): Promise<ClearSignContext[]> {\n this.logger.debug(\"[load] Loading solana Lifi context\", {\n data: { input: solanaLifiContextInput },\n });\n const result = await this._loadInternal(solanaLifiContextInput);\n if (result.type === ClearSignContextType.ERROR) {\n return [{ type: ClearSignContextType.ERROR, error: result.error }];\n }\n const r = result as SolanaLifiContextSuccess;\n return [\n {\n type: ClearSignContextType.SOLANA_LIFI,\n payload: r.payload,\n certificate: r.certificate,\n },\n ];\n }\n\n private async _loadInternal(\n solanaLifiContextInput: SolanaTransactionContext,\n ): Promise<SolanaLifiContextSuccess | SolanaContextError> {\n this.logger.debug(\"[_loadInternal] Loading solana Lifi context\", {\n data: { input: solanaLifiContextInput },\n });\n const { templateId, deviceModelId } = solanaLifiContextInput;\n\n if (!templateId) {\n return {\n type: ClearSignContextType.ERROR,\n error: new Error(\n \"[ContextModule] LifiContextLoader: templateId is missing\",\n ),\n };\n }\n\n const payload = await this.dataSource.getTransactionDescriptorsPayload({\n templateId,\n });\n\n const certificate: PkiCertificate | undefined =\n await this._certificateLoader.loadCertificate({\n keyId: KeyId.SwapTemplateKey,\n keyUsage: KeyUsage.SwapTemplate,\n targetDevice: deviceModelId,\n });\n\n return payload.caseOf({\n Left: (error): SolanaLifiContextSuccess | SolanaContextError => {\n this.logger.error(\"[_loadInternal] Error loading solana Lifi context\", {\n data: { error },\n });\n\n return {\n type: ClearSignContextType.ERROR,\n error,\n };\n },\n Right: (value): SolanaLifiContextSuccess | SolanaContextError => {\n const lifiPayload = this.buildPayload(value);\n this.logger.debug(\n \"[_loadInternal] Successfully loaded solana Lifi context\",\n {\n data: {\n descriptors: lifiPayload.descriptors,\n instructionsCount: lifiPayload.instructions.length,\n certificate,\n },\n },\n );\n\n return {\n type: ClearSignContextType.SOLANA_LIFI,\n payload: lifiPayload,\n certificate,\n };\n },\n });\n }\n\n private buildPayload(\n response: GetTransactionDescriptorsResponse,\n ): SolanaLifiPayload {\n return {\n descriptors: this.pluckTransactionData(response),\n instructions: this.extractInstructionsMeta(response),\n };\n }\n\n private pluckTransactionData(\n tokenData: GetTransactionDescriptorsResponse,\n ): SolanaTransactionDescriptorList {\n const signatureKind = this.config.cal.mode || \"prod\";\n const output: SolanaTransactionDescriptorList = {};\n const descriptors = tokenData.descriptors ?? [];\n\n this.logger.debug(\"[pluckTransactionData] Processing descriptors\", {\n data: { descriptorsCount: descriptors.length, signatureKind },\n });\n\n for (const item of descriptors) {\n const key = `${item.program_id}:${item.discriminator_hex ?? \"\"}`;\n const descriptor = {\n data: item.descriptor.data,\n descriptorType: item.descriptor.descriptorType,\n descriptorVersion: item.descriptor.descriptorVersion,\n signature: item.descriptor.signatures[signatureKind] ?? \"\",\n ...(item.has_basis_point !== undefined && {\n has_basis_point: item.has_basis_point,\n }),\n };\n (output[key] ??= []).push(descriptor);\n this.logger.debug(\"[pluckTransactionData] Mapped program descriptor\", {\n data: {\n programId: item.program_id,\n discriminatorHex: item.discriminator_hex ?? \"\",\n key,\n },\n });\n }\n\n this.logger.debug(\"[pluckTransactionData] Completed processing\", {\n data: { outputKeys: Object.keys(output) },\n });\n\n return output;\n }\n\n private extractInstructionsMeta(\n response: GetTransactionDescriptorsResponse,\n ): SolanaLifiInstructionMeta[] {\n const instructions = response.instructions ?? [];\n\n this.logger.debug(\n \"[extractInstructionsMeta] Extracting instructions metadata\",\n {\n data: { instructionsCount: instructions.length },\n },\n );\n\n const meta = instructions.map((ix) => ({\n program_id: ix.program_id,\n ...(ix.discriminator_hex !== undefined && {\n discriminator_hex: ix.discriminator_hex,\n }),\n ...(ix.amount !== undefined && {\n has_basis_point: ix.amount.capped_bps !== undefined,\n }),\n }));\n\n this.logger.debug(\n \"[extractInstructionsMeta] Completed extracting instructions metadata\",\n {\n data: {\n meta: meta.map((m) => ({\n programId: m.program_id,\n discriminatorHex: m.discriminator_hex,\n })),\n },\n },\n );\n\n return meta;\n }\n}\n"],
5
+ "mappings": "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",
6
+ "names": ["inject", "injectable", "configTypes", "pkiTypes", "KeyId", "KeyUsage", "lifiTypes", "ClearSignContextType", "SUPPORTED_TYPES", "ClearSignContextType", "LifiContextLoader", "dataSource", "config", "_certificateLoader", "loggerFactory", "input", "expectedTypes", "t", "templateId", "isValid", "solanaLifiContextInput", "result", "r", "deviceModelId", "payload", "certificate", "KeyId", "KeyUsage", "error", "value", "lifiPayload", "response", "tokenData", "signatureKind", "output", "descriptors", "item", "key", "descriptor", "instructions", "meta", "ix", "m", "__decorateClass", "injectable", "__decorateParam", "inject", "lifiTypes", "configTypes", "pkiTypes"]
7
7
  }
@@ -1,2 +1,2 @@
1
- import{Left as L,Right as _}from"purify-ts";import{beforeEach as x,describe as m,expect as e,it as n,vi as c}from"vitest";import{ClearSignContextType as d}from"../../../../shared/model/ClearSignContext";import{LifiContextLoader as T}from"./LifiContextLoader";const h=()=>({debug:c.fn(),info:c.fn(),warn:c.fn(),error:c.fn(),subscribers:[]}),y={keyUsageNumber:13,payload:new Uint8Array([1,2])},N={cal:{url:"https://global.api.prd.ledger.com/cal/v1",mode:"test",branch:"main"}};m("LifiContextLoader",()=>{let p,u;const i=(r,a="deadbeef")=>({data:r,descriptorType:"swap_template",descriptorVersion:"v1",signatures:{test:a,prod:`prod_${a}`}}),g=(r,a="deadbeef")=>({data:r,descriptorType:"swap_template",descriptorVersion:"v1",signature:a}),k=[{program_id:"SomeProgram",discriminator_hex:"1",descriptor:i("abc123")},{program_id:"AnotherProgram",descriptor:i("def456")}],b={"SomeProgram:1":g("abc123"),"AnotherProgram:":g("def456")},l={id:"tpl-1",chain_id:101,instructions:[{program_id:"SomeProgram",discriminator:1,discriminator_hex:"1"},{program_id:"AnotherProgram"}],descriptors:k};x(()=>{c.restoreAllMocks(),p={getTransactionDescriptorsPayload:c.fn()},u={loadCertificate:c.fn().mockResolvedValue(y)}});const s=()=>new T(p,N,u,h);m("canHandle",()=>{n("returns true when templateId is provided and SOLANA_LIFI is in expectedTypes",()=>{const r=s();e(r.canHandle({templateId:"tpl-123",deviceModelId:"nanoS"},[d.SOLANA_LIFI])).toBe(!0)}),n("returns false when SOLANA_LIFI is not in expectedTypes",()=>{const r=s();e(r.canHandle({templateId:"tpl-123"},[d.SOLANA_TOKEN])).toBe(!1)}),n("returns false when templateId is missing or falsy",()=>{const r=s();e(r.canHandle({templateId:""},[d.SOLANA_LIFI])).toBe(!1),e(r.canHandle({templateId:void 0},[d.SOLANA_LIFI])).toBe(!1),e(r.canHandle({},[d.SOLANA_LIFI])).toBe(!1)})}),m("load",()=>{n("returns an array with an error when datasource returns Left(error)",async()=>{const r=s(),a=new Error("boom");c.spyOn(p,"getTransactionDescriptorsPayload").mockResolvedValue(L(a));const o={templateId:"tpl-err",deviceModelId:"nanoS"},t=await r.load(o);e(p.getTransactionDescriptorsPayload).toHaveBeenCalledWith({templateId:"tpl-err"}),e(t).toEqual([{type:d.ERROR,error:a}])}),n("returns SOLANA_LIFI array with plucked descriptors and certificate when datasource returns Right(value)",async()=>{const r=s();c.spyOn(p,"getTransactionDescriptorsPayload").mockResolvedValue(_(l));const a={templateId:"tpl-ok",deviceModelId:"nanoS"},o=await r.load(a);e(p.getTransactionDescriptorsPayload).toHaveBeenCalledWith({templateId:"tpl-ok"}),e(u.loadCertificate).toHaveBeenCalledWith({keyId:"swap_template_key",keyUsage:"swap_template",targetDevice:"nanoS"}),e(o).toEqual([{type:d.SOLANA_LIFI,payload:{descriptors:b,instructions:[{program_id:"SomeProgram",discriminator_hex:"1"},{program_id:"AnotherProgram"}]},certificate:y}])})}),m("pluckTransactionData (private)",()=>{n("returns a map keyed by `${program_id}:${discriminator_hex ?? '0'}`",()=>{const r=s(),o=r.pluckTransactionData.bind(r)(l);e(o).toEqual(b)})}),m("extractInstructionsMeta (private)",()=>{n("returns instruction metadata from the API response",()=>{const r=s(),o=r.extractInstructionsMeta.bind(r)(l);e(o).toEqual([{program_id:"SomeProgram",discriminator_hex:"1"},{program_id:"AnotherProgram"}])}),n("returns empty array when instructions are missing",()=>{const r=s(),o=r.extractInstructionsMeta.bind(r)({...l,instructions:void 0});e(o).toEqual([])})}),m("pluckTransactionData mode resolution (private)",()=>{n("resolves signature using config.cal.mode",()=>{const r=s(),o=r.pluckTransactionData.bind(r)(l);e(o["SomeProgram:1"]?.signature).toBe("deadbeef")})}),m("real CAL payload (LiFi template 4c694669)",()=>{const r={id:"4c694669",chain_id:101,instructions:[{program_id:"ATokenGPvbdGVxr1b2hvZbsiqW5xWH25efTNsLJA8knL",discriminator:1,discriminator_hex:"1"},{program_id:"11111111111111111111111111111111",discriminator:2,discriminator_hex:"2"},{program_id:"JUP6LkbZbjS1jKKwapdHNy74zcZ3tLUZoi5QNyVTaV4",discriminator:0x2aade37a97cb1800,discriminator_hex:"2aade37a97cb17e0"},{program_id:"JUP6LkbZbjS1jKKwapdHNy74zcZ3tLUZoi5QNyVTaV4",discriminator:9339575302786589e3,discriminator_hex:"819cd641339b2148"},{program_id:"MemoSq4gqABAXKb96qnH8TysNcWxMyWCqXgDLGmfcHr"},{program_id:"ATokenGPvbdGVxr1b2hvZbsiqW5xWH25efTNsLJA8knL",discriminator:1,discriminator_hex:"1"},{program_id:"3i5JeuZuUxeKtVysUnwQNGerJP2bSMX9fTFfS4Nxe3Br"},{program_id:"ComputeBudget111111111111111111111111111111",discriminator:2,discriminator_hex:"2"},{program_id:"ComputeBudget111111111111111111111111111111",discriminator:3,discriminator_hex:"3"},{program_id:"TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA",discriminator:3,discriminator_hex:"3"},{program_id:"TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA",discriminator:17,discriminator_hex:"11"},{program_id:"BrdgN2RPzEMWF96ZbnnJaUtQDQx7VRXYaHHbYCBvceWB"}],descriptors:[{program_id:"ATokenGPvbdGVxr1b2hvZbsiqW5xWH25efTNsLJA8knL",discriminator_hex:"1",descriptor:i("atoken_1","sig_atoken")},{program_id:"11111111111111111111111111111111",discriminator_hex:"2",descriptor:i("system_2","sig_system")},{program_id:"JUP6LkbZbjS1jKKwapdHNy74zcZ3tLUZoi5QNyVTaV4",discriminator_hex:"2aade37a97cb17e0",descriptor:i("jup_route","sig_jup_route")},{program_id:"JUP6LkbZbjS1jKKwapdHNy74zcZ3tLUZoi5QNyVTaV4",discriminator_hex:"819cd641339b2148",descriptor:i("jup_shared","sig_jup_shared")},{program_id:"MemoSq4gqABAXKb96qnH8TysNcWxMyWCqXgDLGmfcHr",descriptor:i("memo","sig_memo")},{program_id:"ATokenGPvbdGVxr1b2hvZbsiqW5xWH25efTNsLJA8knL",discriminator_hex:"1",descriptor:i("atoken_1","sig_atoken")},{program_id:"3i5JeuZuUxeKtVysUnwQNGerJP2bSMX9fTFfS4Nxe3Br",descriptor:i("3i5jeu","sig_3i5jeu")},{program_id:"ComputeBudget111111111111111111111111111111",discriminator_hex:"2",descriptor:i("cb_2","sig_cb2")},{program_id:"ComputeBudget111111111111111111111111111111",discriminator_hex:"3",descriptor:i("cb_3","sig_cb3")},{program_id:"TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA",discriminator_hex:"3",descriptor:i("tokenkeg_3","sig_tk3")},{program_id:"TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA",discriminator_hex:"11",descriptor:i("tokenkeg_11","sig_tk11")},{program_id:"BrdgN2RPzEMWF96ZbnnJaUtQDQx7VRXYaHHbYCBvceWB",descriptor:i("brdg","sig_brdg")}]};n("produces 11 unique descriptor keys (ATokenGP:1 appears twice but deduplicates)",()=>{const a=s(),t=a.pluckTransactionData.bind(a)(r),f=Object.keys(t);e(f).toHaveLength(11)}),n("creates distinct keys for same program_id with different discriminators",()=>{const a=s(),t=a.pluckTransactionData.bind(a)(r);e(t["JUP6LkbZbjS1jKKwapdHNy74zcZ3tLUZoi5QNyVTaV4:2aade37a97cb17e0"]?.data).toBe("jup_route"),e(t["JUP6LkbZbjS1jKKwapdHNy74zcZ3tLUZoi5QNyVTaV4:819cd641339b2148"]?.data).toBe("jup_shared"),e(t["ComputeBudget111111111111111111111111111111:2"]?.data).toBe("cb_2"),e(t["ComputeBudget111111111111111111111111111111:3"]?.data).toBe("cb_3"),e(t["TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA:3"]?.data).toBe("tokenkeg_3"),e(t["TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA:11"]?.data).toBe("tokenkeg_11")}),n("uses :0 suffix for programs without a discriminator",()=>{const a=s(),t=a.pluckTransactionData.bind(a)(r);e(t["MemoSq4gqABAXKb96qnH8TysNcWxMyWCqXgDLGmfcHr:"]?.data).toBe("memo"),e(t["3i5JeuZuUxeKtVysUnwQNGerJP2bSMX9fTFfS4Nxe3Br:"]?.data).toBe("3i5jeu"),e(t["BrdgN2RPzEMWF96ZbnnJaUtQDQx7VRXYaHHbYCBvceWB:"]?.data).toBe("brdg")}),n("extracts 12 instruction metadata entries preserving order and discriminators",()=>{const a=s(),t=a.extractInstructionsMeta.bind(a)(r);e(t).toHaveLength(12),e(t[0]).toEqual({program_id:"ATokenGPvbdGVxr1b2hvZbsiqW5xWH25efTNsLJA8knL",discriminator_hex:"1"}),e(t[2]).toEqual({program_id:"JUP6LkbZbjS1jKKwapdHNy74zcZ3tLUZoi5QNyVTaV4",discriminator_hex:"2aade37a97cb17e0"}),e(t[3]).toEqual({program_id:"JUP6LkbZbjS1jKKwapdHNy74zcZ3tLUZoi5QNyVTaV4",discriminator_hex:"819cd641339b2148"}),e(t[4]).toEqual({program_id:"MemoSq4gqABAXKb96qnH8TysNcWxMyWCqXgDLGmfcHr"}),e(t[11]).toEqual({program_id:"BrdgN2RPzEMWF96ZbnnJaUtQDQx7VRXYaHHbYCBvceWB"})}),n("load returns full payload with descriptors and instructions from real API response",async()=>{const a=s();c.spyOn(p,"getTransactionDescriptorsPayload").mockResolvedValue(_(r));const o={templateId:"4c694669",deviceModelId:"nanoS"},t=await a.load(o);e(t).toHaveLength(1),e(t[0]).toMatchObject({type:d.SOLANA_LIFI,payload:{descriptors:e.objectContaining({"JUP6LkbZbjS1jKKwapdHNy74zcZ3tLUZoi5QNyVTaV4:2aade37a97cb17e0":e.objectContaining({data:"jup_route"}),"JUP6LkbZbjS1jKKwapdHNy74zcZ3tLUZoi5QNyVTaV4:819cd641339b2148":e.objectContaining({data:"jup_shared"})}),instructions:e.arrayContaining([e.objectContaining({program_id:"JUP6LkbZbjS1jKKwapdHNy74zcZ3tLUZoi5QNyVTaV4",discriminator_hex:"2aade37a97cb17e0"}),e.objectContaining({program_id:"JUP6LkbZbjS1jKKwapdHNy74zcZ3tLUZoi5QNyVTaV4",discriminator_hex:"819cd641339b2148"})])}}),e(Object.keys(t[0].payload.descriptors)).toHaveLength(11),e(t[0].payload.instructions).toHaveLength(12)})})});
1
+ import{Left as L,Right as b}from"purify-ts";import{beforeEach as h,describe as d,expect as r,it as n,vi as c}from"vitest";import{ClearSignContextType as p}from"../../../../shared/model/ClearSignContext";import{LifiContextLoader as x}from"./LifiContextLoader";const T=()=>({debug:c.fn(),info:c.fn(),warn:c.fn(),error:c.fn(),subscribers:[]}),y={keyUsageNumber:13,payload:new Uint8Array([1,2])},N={cal:{url:"https://global.api.prd.ledger.com/cal/v1",mode:"test",branch:"main"}};d("LifiContextLoader",()=>{let m,u;const i=(e,t="deadbeef")=>({data:e,descriptorType:"swap_template",descriptorVersion:"v1",signatures:{test:t,prod:`prod_${t}`}}),g=(e,t="deadbeef")=>({data:e,descriptorType:"swap_template",descriptorVersion:"v1",signature:t}),k=[{program_id:"SomeProgram",discriminator_hex:"1",descriptor:i("abc123")},{program_id:"AnotherProgram",descriptor:i("def456")}],_={"SomeProgram:1":[g("abc123")],"AnotherProgram:":[g("def456")]},l={id:"tpl-1",chain_id:101,instructions:[{program_id:"SomeProgram",discriminator:1,discriminator_hex:"1"},{program_id:"AnotherProgram"}],descriptors:k};h(()=>{c.restoreAllMocks(),m={getTransactionDescriptorsPayload:c.fn()},u={loadCertificate:c.fn().mockResolvedValue(y)}});const s=()=>new x(m,N,u,T);d("canHandle",()=>{n("returns true when templateId is provided and SOLANA_LIFI is in expectedTypes",()=>{const e=s();r(e.canHandle({templateId:"tpl-123",deviceModelId:"nanoS"},[p.SOLANA_LIFI])).toBe(!0)}),n("returns false when SOLANA_LIFI is not in expectedTypes",()=>{const e=s();r(e.canHandle({templateId:"tpl-123"},[p.SOLANA_TOKEN])).toBe(!1)}),n("returns false when templateId is missing or falsy",()=>{const e=s();r(e.canHandle({templateId:""},[p.SOLANA_LIFI])).toBe(!1),r(e.canHandle({templateId:void 0},[p.SOLANA_LIFI])).toBe(!1),r(e.canHandle({},[p.SOLANA_LIFI])).toBe(!1)})}),d("load",()=>{n("returns an array with an error when datasource returns Left(error)",async()=>{const e=s(),t=new Error("boom");c.spyOn(m,"getTransactionDescriptorsPayload").mockResolvedValue(L(t));const o={templateId:"tpl-err",deviceModelId:"nanoS"},a=await e.load(o);r(m.getTransactionDescriptorsPayload).toHaveBeenCalledWith({templateId:"tpl-err"}),r(a).toEqual([{type:p.ERROR,error:t}])}),n("returns SOLANA_LIFI array with plucked descriptors and certificate when datasource returns Right(value)",async()=>{const e=s();c.spyOn(m,"getTransactionDescriptorsPayload").mockResolvedValue(b(l));const t={templateId:"tpl-ok",deviceModelId:"nanoS"},o=await e.load(t);r(m.getTransactionDescriptorsPayload).toHaveBeenCalledWith({templateId:"tpl-ok"}),r(u.loadCertificate).toHaveBeenCalledWith({keyId:"swap_template_key",keyUsage:"swap_template",targetDevice:"nanoS"}),r(o).toEqual([{type:p.SOLANA_LIFI,payload:{descriptors:_,instructions:[{program_id:"SomeProgram",discriminator_hex:"1"},{program_id:"AnotherProgram"}]},certificate:y}])})}),d("pluckTransactionData (private)",()=>{n("returns a map keyed by `${program_id}:${discriminator_hex ?? '0'}`",()=>{const e=s(),o=e.pluckTransactionData.bind(e)(l);r(o).toEqual(_)})}),d("extractInstructionsMeta (private)",()=>{n("returns instruction metadata from the API response",()=>{const e=s(),o=e.extractInstructionsMeta.bind(e)(l);r(o).toEqual([{program_id:"SomeProgram",discriminator_hex:"1"},{program_id:"AnotherProgram"}])}),n("returns empty array when instructions are missing",()=>{const e=s(),o=e.extractInstructionsMeta.bind(e)({...l,instructions:void 0});r(o).toEqual([])})}),d("pluckTransactionData mode resolution (private)",()=>{n("resolves signature using config.cal.mode",()=>{const e=s(),o=e.pluckTransactionData.bind(e)(l);r(o["SomeProgram:1"]?.[0]?.signature).toBe("deadbeef")})}),d("duplicate discriminator handling (private)",()=>{n("collects both descriptors into an array when same (program_id, discriminator_hex) appears twice",()=>{const e=s(),t=e.pluckTransactionData.bind(e),o={id:"dup-test",chain_id:101,instructions:[{program_id:"11111111111111111111111111111111",discriminator:2,discriminator_hex:"02"},{program_id:"11111111111111111111111111111111",discriminator:2,discriminator_hex:"02"}],descriptors:[{program_id:"11111111111111111111111111111111",discriminator_hex:"02",has_basis_point:!1,descriptor:i("transfer_descriptor","sig_transfer")},{program_id:"11111111111111111111111111111111",discriminator_hex:"02",has_basis_point:!0,descriptor:i("fee_descriptor","sig_fee")}]},a=t(o);r(Object.keys(a)).toHaveLength(1),r(a["11111111111111111111111111111111:02"]).toHaveLength(2),r(a["11111111111111111111111111111111:02"]?.[0]?.data).toBe("transfer_descriptor"),r(a["11111111111111111111111111111111:02"]?.[0]?.has_basis_point).toBe(!1),r(a["11111111111111111111111111111111:02"]?.[1]?.data).toBe("fee_descriptor"),r(a["11111111111111111111111111111111:02"]?.[1]?.has_basis_point).toBe(!0)})}),d("real CAL payload (LiFi template 4c694669)",()=>{const e={id:"4c694669",chain_id:101,instructions:[{program_id:"ATokenGPvbdGVxr1b2hvZbsiqW5xWH25efTNsLJA8knL",discriminator:1,discriminator_hex:"1"},{program_id:"11111111111111111111111111111111",discriminator:2,discriminator_hex:"2"},{program_id:"JUP6LkbZbjS1jKKwapdHNy74zcZ3tLUZoi5QNyVTaV4",discriminator:0x2aade37a97cb1800,discriminator_hex:"2aade37a97cb17e0"},{program_id:"JUP6LkbZbjS1jKKwapdHNy74zcZ3tLUZoi5QNyVTaV4",discriminator:9339575302786589e3,discriminator_hex:"819cd641339b2148"},{program_id:"MemoSq4gqABAXKb96qnH8TysNcWxMyWCqXgDLGmfcHr"},{program_id:"ATokenGPvbdGVxr1b2hvZbsiqW5xWH25efTNsLJA8knL",discriminator:1,discriminator_hex:"1"},{program_id:"3i5JeuZuUxeKtVysUnwQNGerJP2bSMX9fTFfS4Nxe3Br"},{program_id:"ComputeBudget111111111111111111111111111111",discriminator:2,discriminator_hex:"2"},{program_id:"ComputeBudget111111111111111111111111111111",discriminator:3,discriminator_hex:"3"},{program_id:"TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA",discriminator:3,discriminator_hex:"3"},{program_id:"TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA",discriminator:17,discriminator_hex:"11"},{program_id:"BrdgN2RPzEMWF96ZbnnJaUtQDQx7VRXYaHHbYCBvceWB"}],descriptors:[{program_id:"ATokenGPvbdGVxr1b2hvZbsiqW5xWH25efTNsLJA8knL",discriminator_hex:"1",descriptor:i("atoken_1","sig_atoken")},{program_id:"11111111111111111111111111111111",discriminator_hex:"2",descriptor:i("system_2","sig_system")},{program_id:"JUP6LkbZbjS1jKKwapdHNy74zcZ3tLUZoi5QNyVTaV4",discriminator_hex:"2aade37a97cb17e0",descriptor:i("jup_route","sig_jup_route")},{program_id:"JUP6LkbZbjS1jKKwapdHNy74zcZ3tLUZoi5QNyVTaV4",discriminator_hex:"819cd641339b2148",descriptor:i("jup_shared","sig_jup_shared")},{program_id:"MemoSq4gqABAXKb96qnH8TysNcWxMyWCqXgDLGmfcHr",descriptor:i("memo","sig_memo")},{program_id:"ATokenGPvbdGVxr1b2hvZbsiqW5xWH25efTNsLJA8knL",discriminator_hex:"1",descriptor:i("atoken_1","sig_atoken")},{program_id:"3i5JeuZuUxeKtVysUnwQNGerJP2bSMX9fTFfS4Nxe3Br",descriptor:i("3i5jeu","sig_3i5jeu")},{program_id:"ComputeBudget111111111111111111111111111111",discriminator_hex:"2",descriptor:i("cb_2","sig_cb2")},{program_id:"ComputeBudget111111111111111111111111111111",discriminator_hex:"3",descriptor:i("cb_3","sig_cb3")},{program_id:"TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA",discriminator_hex:"3",descriptor:i("tokenkeg_3","sig_tk3")},{program_id:"TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA",discriminator_hex:"11",descriptor:i("tokenkeg_11","sig_tk11")},{program_id:"BrdgN2RPzEMWF96ZbnnJaUtQDQx7VRXYaHHbYCBvceWB",descriptor:i("brdg","sig_brdg")}]};n("produces 11 unique descriptor keys (ATokenGP:1 appears twice -> array of 2)",()=>{const t=s(),a=t.pluckTransactionData.bind(t)(e),f=Object.keys(a);r(f).toHaveLength(11),r(a["ATokenGPvbdGVxr1b2hvZbsiqW5xWH25efTNsLJA8knL:1"]).toHaveLength(2)}),n("creates distinct keys for same program_id with different discriminators",()=>{const t=s(),a=t.pluckTransactionData.bind(t)(e);r(a["JUP6LkbZbjS1jKKwapdHNy74zcZ3tLUZoi5QNyVTaV4:2aade37a97cb17e0"]?.[0]?.data).toBe("jup_route"),r(a["JUP6LkbZbjS1jKKwapdHNy74zcZ3tLUZoi5QNyVTaV4:819cd641339b2148"]?.[0]?.data).toBe("jup_shared"),r(a["ComputeBudget111111111111111111111111111111:2"]?.[0]?.data).toBe("cb_2"),r(a["ComputeBudget111111111111111111111111111111:3"]?.[0]?.data).toBe("cb_3"),r(a["TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA:3"]?.[0]?.data).toBe("tokenkeg_3"),r(a["TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA:11"]?.[0]?.data).toBe("tokenkeg_11")}),n("uses :0 suffix for programs without a discriminator",()=>{const t=s(),a=t.pluckTransactionData.bind(t)(e);r(a["MemoSq4gqABAXKb96qnH8TysNcWxMyWCqXgDLGmfcHr:"]?.[0]?.data).toBe("memo"),r(a["3i5JeuZuUxeKtVysUnwQNGerJP2bSMX9fTFfS4Nxe3Br:"]?.[0]?.data).toBe("3i5jeu"),r(a["BrdgN2RPzEMWF96ZbnnJaUtQDQx7VRXYaHHbYCBvceWB:"]?.[0]?.data).toBe("brdg")}),n("extracts 12 instruction metadata entries preserving order and discriminators",()=>{const t=s(),a=t.extractInstructionsMeta.bind(t)(e);r(a).toHaveLength(12),r(a[0]).toEqual({program_id:"ATokenGPvbdGVxr1b2hvZbsiqW5xWH25efTNsLJA8knL",discriminator_hex:"1"}),r(a[2]).toEqual({program_id:"JUP6LkbZbjS1jKKwapdHNy74zcZ3tLUZoi5QNyVTaV4",discriminator_hex:"2aade37a97cb17e0"}),r(a[3]).toEqual({program_id:"JUP6LkbZbjS1jKKwapdHNy74zcZ3tLUZoi5QNyVTaV4",discriminator_hex:"819cd641339b2148"}),r(a[4]).toEqual({program_id:"MemoSq4gqABAXKb96qnH8TysNcWxMyWCqXgDLGmfcHr"}),r(a[11]).toEqual({program_id:"BrdgN2RPzEMWF96ZbnnJaUtQDQx7VRXYaHHbYCBvceWB"})}),n("load returns full payload with descriptors and instructions from real API response",async()=>{const t=s();c.spyOn(m,"getTransactionDescriptorsPayload").mockResolvedValue(b(e));const o={templateId:"4c694669",deviceModelId:"nanoS"},a=await t.load(o);r(a).toHaveLength(1),r(a[0]).toMatchObject({type:p.SOLANA_LIFI,payload:{descriptors:r.objectContaining({"JUP6LkbZbjS1jKKwapdHNy74zcZ3tLUZoi5QNyVTaV4:2aade37a97cb17e0":r.arrayContaining([r.objectContaining({data:"jup_route"})]),"JUP6LkbZbjS1jKKwapdHNy74zcZ3tLUZoi5QNyVTaV4:819cd641339b2148":r.arrayContaining([r.objectContaining({data:"jup_shared"})])}),instructions:r.arrayContaining([r.objectContaining({program_id:"JUP6LkbZbjS1jKKwapdHNy74zcZ3tLUZoi5QNyVTaV4",discriminator_hex:"2aade37a97cb17e0"}),r.objectContaining({program_id:"JUP6LkbZbjS1jKKwapdHNy74zcZ3tLUZoi5QNyVTaV4",discriminator_hex:"819cd641339b2148"})])}}),r(Object.keys(a[0].payload.descriptors)).toHaveLength(11),r(a[0].payload.instructions).toHaveLength(12)})})});
2
2
  //# sourceMappingURL=LifiContextLoader.test.js.map