@ledgerhq/context-module 2.7.0 → 2.8.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/lib/cjs/package.json +1 -1
- package/lib/cjs/src/DefaultContextModule.js +1 -1
- package/lib/cjs/src/DefaultContextModule.js.map +2 -2
- package/lib/cjs/src/DefaultContextModule.test.js +1 -1
- package/lib/cjs/src/DefaultContextModule.test.js.map +3 -3
- package/lib/cjs/src/index.js +1 -1
- package/lib/cjs/src/index.js.map +2 -2
- package/lib/cjs/src/modules/solana/enum-variant/domain/EnumVariantContextLoader.test.js +1 -1
- package/lib/cjs/src/modules/solana/enum-variant/domain/EnumVariantContextLoader.test.js.map +2 -2
- package/lib/cjs/src/modules/solana/instruction-info/data/HttpInstructionInfoDataSource.js +1 -1
- package/lib/cjs/src/modules/solana/instruction-info/data/HttpInstructionInfoDataSource.js.map +3 -3
- package/lib/cjs/src/modules/solana/instruction-info/data/HttpInstructionInfoDataSource.test.js +1 -1
- package/lib/cjs/src/modules/solana/instruction-info/data/HttpInstructionInfoDataSource.test.js.map +3 -3
- package/lib/cjs/src/modules/solana/instruction-info/data/InstructionInfoDataSource.js +1 -1
- package/lib/cjs/src/modules/solana/instruction-info/data/InstructionInfoDataSource.js.map +3 -3
- package/lib/cjs/src/modules/solana/instruction-info/data/InstructionInfoDto.js +1 -1
- package/lib/cjs/src/modules/solana/instruction-info/data/InstructionInfoDto.js.map +3 -3
- package/lib/cjs/src/modules/solana/instruction-info/data/InstructionInfoMapper.js +1 -1
- package/lib/cjs/src/modules/solana/instruction-info/data/InstructionInfoMapper.js.map +3 -3
- package/lib/cjs/src/modules/solana/instruction-info/di/instructionInfoModuleFactory.js +1 -1
- package/lib/cjs/src/modules/solana/instruction-info/di/instructionInfoModuleFactory.js.map +3 -3
- package/lib/cjs/src/modules/solana/instruction-info/di/instructionInfoModuleFactory.test.js +2 -0
- package/lib/cjs/src/modules/solana/instruction-info/di/instructionInfoModuleFactory.test.js.map +7 -0
- package/lib/cjs/src/modules/solana/instruction-info/di/instructionInfoTypes.js +1 -1
- package/lib/cjs/src/modules/solana/instruction-info/di/instructionInfoTypes.js.map +2 -2
- package/lib/cjs/src/modules/solana/instruction-info/domain/InstructionInfoContextLoader.test.js +1 -1
- package/lib/cjs/src/modules/solana/instruction-info/domain/InstructionInfoContextLoader.test.js.map +2 -2
- package/lib/cjs/src/modules/solana/instruction-info/domain/SolanaBasicFlowRuleContextLoader.js +2 -0
- package/lib/cjs/src/modules/solana/instruction-info/domain/SolanaBasicFlowRuleContextLoader.js.map +7 -0
- package/lib/cjs/src/modules/solana/instruction-info/domain/SolanaBasicFlowRuleContextLoader.test.js +2 -0
- package/lib/cjs/src/modules/solana/instruction-info/domain/SolanaBasicFlowRuleContextLoader.test.js.map +7 -0
- package/lib/cjs/src/modules/solana/model/SolanaClearSignContext.js +1 -1
- package/lib/cjs/src/modules/solana/model/SolanaClearSignContext.js.map +2 -2
- package/lib/cjs/src/modules/solana/model/SolanaContextTypes.js +1 -1
- package/lib/cjs/src/modules/solana/model/SolanaContextTypes.js.map +1 -1
- package/lib/cjs/src/shared/model/ClearSignContext.js +1 -1
- package/lib/cjs/src/shared/model/ClearSignContext.js.map +2 -2
- package/lib/esm/package.json +1 -1
- package/lib/esm/src/DefaultContextModule.js +1 -1
- package/lib/esm/src/DefaultContextModule.js.map +2 -2
- package/lib/esm/src/DefaultContextModule.test.js +1 -1
- package/lib/esm/src/DefaultContextModule.test.js.map +3 -3
- package/lib/esm/src/index.js +1 -1
- package/lib/esm/src/index.js.map +2 -2
- package/lib/esm/src/modules/solana/enum-variant/domain/EnumVariantContextLoader.test.js +1 -1
- package/lib/esm/src/modules/solana/enum-variant/domain/EnumVariantContextLoader.test.js.map +2 -2
- package/lib/esm/src/modules/solana/instruction-info/data/HttpInstructionInfoDataSource.js +1 -1
- package/lib/esm/src/modules/solana/instruction-info/data/HttpInstructionInfoDataSource.js.map +3 -3
- package/lib/esm/src/modules/solana/instruction-info/data/HttpInstructionInfoDataSource.test.js +1 -1
- package/lib/esm/src/modules/solana/instruction-info/data/HttpInstructionInfoDataSource.test.js.map +3 -3
- package/lib/esm/src/modules/solana/instruction-info/data/InstructionInfoDataSource.js +1 -0
- package/lib/esm/src/modules/solana/instruction-info/data/InstructionInfoDataSource.js.map +4 -4
- package/lib/esm/src/modules/solana/instruction-info/data/InstructionInfoDto.js +1 -1
- package/lib/esm/src/modules/solana/instruction-info/data/InstructionInfoDto.js.map +3 -3
- package/lib/esm/src/modules/solana/instruction-info/data/InstructionInfoMapper.js +1 -1
- package/lib/esm/src/modules/solana/instruction-info/data/InstructionInfoMapper.js.map +3 -3
- package/lib/esm/src/modules/solana/instruction-info/di/instructionInfoModuleFactory.js +1 -1
- package/lib/esm/src/modules/solana/instruction-info/di/instructionInfoModuleFactory.js.map +3 -3
- package/lib/esm/src/modules/solana/instruction-info/di/instructionInfoModuleFactory.test.js +2 -0
- package/lib/esm/src/modules/solana/instruction-info/di/instructionInfoModuleFactory.test.js.map +7 -0
- package/lib/esm/src/modules/solana/instruction-info/di/instructionInfoTypes.js +1 -1
- package/lib/esm/src/modules/solana/instruction-info/di/instructionInfoTypes.js.map +2 -2
- package/lib/esm/src/modules/solana/instruction-info/domain/InstructionInfoContextLoader.test.js +1 -1
- package/lib/esm/src/modules/solana/instruction-info/domain/InstructionInfoContextLoader.test.js.map +2 -2
- package/lib/esm/src/modules/solana/instruction-info/domain/SolanaBasicFlowRuleContextLoader.js +2 -0
- package/lib/esm/src/modules/solana/instruction-info/domain/SolanaBasicFlowRuleContextLoader.js.map +7 -0
- package/lib/esm/src/modules/solana/instruction-info/domain/SolanaBasicFlowRuleContextLoader.test.js +2 -0
- package/lib/esm/src/modules/solana/instruction-info/domain/SolanaBasicFlowRuleContextLoader.test.js.map +7 -0
- package/lib/esm/src/modules/solana/model/SolanaClearSignContext.js +1 -1
- package/lib/esm/src/modules/solana/model/SolanaClearSignContext.js.map +2 -2
- package/lib/esm/src/shared/model/ClearSignContext.js +1 -1
- package/lib/esm/src/shared/model/ClearSignContext.js.map +2 -2
- package/lib/types/src/DefaultContextModule.d.ts.map +1 -1
- package/lib/types/src/index.d.ts +1 -0
- package/lib/types/src/index.d.ts.map +1 -1
- package/lib/types/src/modules/solana/instruction-info/data/HttpInstructionInfoDataSource.d.ts +3 -0
- package/lib/types/src/modules/solana/instruction-info/data/HttpInstructionInfoDataSource.d.ts.map +1 -1
- package/lib/types/src/modules/solana/instruction-info/data/InstructionInfoDataSource.d.ts +20 -0
- package/lib/types/src/modules/solana/instruction-info/data/InstructionInfoDataSource.d.ts.map +1 -1
- package/lib/types/src/modules/solana/instruction-info/data/InstructionInfoDto.d.ts +26 -0
- package/lib/types/src/modules/solana/instruction-info/data/InstructionInfoDto.d.ts.map +1 -1
- package/lib/types/src/modules/solana/instruction-info/data/InstructionInfoMapper.d.ts +9 -0
- package/lib/types/src/modules/solana/instruction-info/data/InstructionInfoMapper.d.ts.map +1 -1
- package/lib/types/src/modules/solana/instruction-info/di/instructionInfoModuleFactory.d.ts.map +1 -1
- package/lib/types/src/modules/solana/instruction-info/di/instructionInfoModuleFactory.test.d.ts +2 -0
- package/lib/types/src/modules/solana/instruction-info/di/instructionInfoModuleFactory.test.d.ts.map +1 -0
- package/lib/types/src/modules/solana/instruction-info/di/instructionInfoTypes.d.ts +1 -0
- package/lib/types/src/modules/solana/instruction-info/di/instructionInfoTypes.d.ts.map +1 -1
- package/lib/types/src/modules/solana/instruction-info/domain/SolanaBasicFlowRuleContextLoader.d.ts +31 -0
- package/lib/types/src/modules/solana/instruction-info/domain/SolanaBasicFlowRuleContextLoader.d.ts.map +1 -0
- package/lib/types/src/modules/solana/instruction-info/domain/SolanaBasicFlowRuleContextLoader.test.d.ts +2 -0
- package/lib/types/src/modules/solana/instruction-info/domain/SolanaBasicFlowRuleContextLoader.test.d.ts.map +1 -0
- package/lib/types/src/modules/solana/model/SolanaClearSignContext.d.ts +4 -0
- package/lib/types/src/modules/solana/model/SolanaClearSignContext.d.ts.map +1 -1
- package/lib/types/src/modules/solana/model/SolanaContextTypes.d.ts +20 -0
- package/lib/types/src/modules/solana/model/SolanaContextTypes.d.ts.map +1 -1
- package/lib/types/src/shared/model/ClearSignContext.d.ts +1 -0
- package/lib/types/src/shared/model/ClearSignContext.d.ts.map +1 -1
- package/lib/types/tsconfig.prod.tsbuildinfo +1 -1
- package/package.json +2 -2
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import{Right as
|
|
1
|
+
import{Right as m}from"purify-ts";import{DefaultSignReporter as y}from"./modules/multichain/sign-reporter/domain/DefaultSignReporter";import{SolanaBasicFlowRuleContextLoader as E}from"./modules/solana/instruction-info/domain/SolanaBasicFlowRuleContextLoader";import{ContextModuleChainID as i}from"./shared/domain/ContextModuleChainID";import{ClearSignContextType as o}from"./shared/model/ClearSignContext";import{DefaultContextModule as d}from"./DefaultContextModule";const C=()=>({debug:vi.fn(),info:vi.fn(),warn:vi.fn(),error:vi.fn(),subscribers:[]}),u=p=>({load:vi.fn(),canHandle:vi.fn().mockReturnValue(p)}),s=()=>({canHandle:vi.fn(),loadField:vi.fn()});describe("DefaultContextModule",()=>{const p={load:vi.fn()},l={customLoaders:[],defaultLoaders:!1,defaultFieldLoaders:!1,customFieldLoaders:[],customTypedDataLoader:p,cal:{url:"https://cal/v1",mode:"prod",branch:"main"},web3checks:{url:"https://web3checks/v3"},metadataServiceDomain:{url:"https://metadata.com"},reporter:{url:"https://reporter.com"},datasource:{proxy:"default"},appSource:"third-party",chain:i.Ethereum,originToken:"originToken",loggerFactory:C};beforeEach(()=>{vi.restoreAllMocks()}),it("should initialize the context module with all the default loaders",async()=>{const t=await new d(l).getContexts({});expect(t).toEqual([])}),it("should return an empty array when no loaders",async()=>{const t=await new d(l).getContexts({});expect(t).toEqual([])}),it("should call all fetch method from metadata fetcher",async()=>{const e=u(!0);await new d({...l,customLoaders:[e,e]}).getContexts({}),expect(e.canHandle).toHaveBeenCalledTimes(2),expect(e.load).toHaveBeenCalledTimes(2)}),it("should return an array of context response",async()=>{const e=u(!0),t=[[{type:o.ETHEREUM_TOKEN,payload:"payload1"}],[{type:o.ETHEREUM_TOKEN,payload:"payload2"},{type:o.ETHEREUM_PLUGIN,payload:"payload3"}]];vi.spyOn(e,"load").mockResolvedValueOnce(t[0]).mockResolvedValueOnce(t[1]);const n=await new d({...l,customLoaders:[e,e]}).getContexts({});expect(e.canHandle).toHaveBeenCalledTimes(2),expect(e.load).toHaveBeenCalledTimes(2),expect(n).toEqual(t.flat())}),it("should only call loaders that can handle the input",async()=>{const e=u(!0),t=u(!0);vi.spyOn(e,"canHandle").mockReturnValue(!0),vi.spyOn(t,"canHandle").mockReturnValue(!1),vi.spyOn(e,"load").mockResolvedValue([{type:o.ETHEREUM_TOKEN,payload:"payload1"}]),vi.spyOn(t,"load").mockResolvedValue([{type:o.ETHEREUM_NFT,payload:"payload2"}]);const a=new d({...l,customLoaders:[e,t]}),n={to:"0x123",selector:"0xabc"},r=await a.getContexts(n);expect(e.canHandle).toHaveBeenCalledWith(n,Object.values(o)),expect(t.canHandle).toHaveBeenCalledWith(n,Object.values(o)),expect(e.load).toHaveBeenCalledWith(n),expect(t.load).not.toHaveBeenCalled(),expect(r).toEqual([{type:"ethereumToken",payload:"payload1"}])}),it("should use expected types if provided",async()=>{const e=u(!0);vi.spyOn(e,"canHandle").mockReturnValue(!0),vi.spyOn(e,"load").mockResolvedValue([{type:o.ETHEREUM_TOKEN,payload:"payload1"}]);const t=new d({...l,customLoaders:[e]}),a={to:"0x123",selector:"0xabc"};await t.getContexts(a,[o.ETHEREUM_TOKEN]),expect(e.canHandle).toHaveBeenCalledWith(a,[o.ETHEREUM_TOKEN])}),it("should call the typed data loader",async()=>{await new d({...l,customTypedDataLoader:p}).getTypedDataFilters({}),expect(p.load).toHaveBeenCalledTimes(1)}),describe("getFieldContext",()=>{it("should return error when no loader can handle the field",async()=>{const e=s();vi.spyOn(e,"canHandle").mockReturnValue(!1);const t=new d({...l,customFieldLoaders:[e]}),a={type:"unknown"},n=await t.getFieldContext(a,o.ETHEREUM_TOKEN);expect(e.canHandle).toHaveBeenCalledWith(a,o.ETHEREUM_TOKEN),expect(e.loadField).not.toHaveBeenCalled(),expect(n).toEqual({type:o.ERROR,error:new Error(`Loader not found for field: ${a} and expected type: ${o.ETHEREUM_TOKEN}`)})}),it("should return context when a loader can handle the field",async()=>{const e=s(),t={type:o.ETHEREUM_TOKEN,payload:"test-payload"};vi.spyOn(e,"canHandle").mockReturnValue(!0),vi.spyOn(e,"loadField").mockResolvedValue(t);const a=new d({...l,customFieldLoaders:[e]}),n={type:"token",address:"0x123"},r=await a.getFieldContext(n,o.ETHEREUM_TOKEN);expect(e.canHandle).toHaveBeenCalledWith(n,o.ETHEREUM_TOKEN),expect(e.loadField).toHaveBeenCalledWith(n),expect(r).toEqual(t)}),it("should return first context when multiple loaders can handle the field",async()=>{const e=s(),t=s(),a={type:o.ETHEREUM_TOKEN,payload:"first-payload"},n={type:o.ETHEREUM_NFT,payload:"second-payload"};vi.spyOn(e,"canHandle").mockReturnValue(!0),vi.spyOn(t,"canHandle").mockReturnValue(!0),vi.spyOn(e,"loadField").mockResolvedValue(a),vi.spyOn(t,"loadField").mockResolvedValue(n);const r=new d({...l,customFieldLoaders:[e,t]}),c={type:"multi",address:"0x123"},x=await r.getFieldContext(c,o.ETHEREUM_TOKEN);expect(e.canHandle).toHaveBeenCalledWith(c,o.ETHEREUM_TOKEN),expect(t.canHandle).toHaveBeenCalledWith(c,o.ETHEREUM_TOKEN),expect(e.loadField).toHaveBeenCalledWith(c),expect(t.loadField).not.toHaveBeenCalled(),expect(x).toEqual(a)}),it("should return second context when first context is an error",async()=>{const e=s(),t=s(),a={type:o.ERROR,error:new Error("first-error")},n={type:o.ETHEREUM_TOKEN,payload:"second-payload"};vi.spyOn(e,"canHandle").mockReturnValue(!0),vi.spyOn(t,"canHandle").mockReturnValue(!0),vi.spyOn(e,"loadField").mockResolvedValue(a),vi.spyOn(t,"loadField").mockResolvedValue(n);const r=new d({...l,customFieldLoaders:[e,t]}),c={type:"error",address:"0x123"},x=await r.getFieldContext(c,o.ETHEREUM_TOKEN);expect(e.canHandle).toHaveBeenCalledWith(c,o.ETHEREUM_TOKEN),expect(t.canHandle).toHaveBeenCalledWith(c,o.ETHEREUM_TOKEN),expect(e.loadField).toHaveBeenCalledWith(c),expect(t.loadField).toHaveBeenCalledWith(c),expect(x).toEqual(n)}),it("should handle loader rejection gracefully",async()=>{const e=s(),t=new Error("Load field failed");vi.spyOn(e,"canHandle").mockReturnValue(!0),vi.spyOn(e,"loadField").mockRejectedValue(t);const a=new d({...l,customFieldLoaders:[e]}),n={type:"error",address:"0x123"};await expect(a.getFieldContext(n,o.ETHEREUM_TOKEN)).rejects.toThrow("Load field failed"),expect(e.canHandle).toHaveBeenCalledWith(n,o.ETHEREUM_TOKEN),expect(e.loadField).toHaveBeenCalledWith(n)})}),describe("signReport",()=>{const e={chain:"ETH"};it.each([i.Ethereum,i.Solana])("should delegate to the bound sign reporter for %s",async t=>{const a=vi.spyOn(y.prototype,"report").mockResolvedValue(m(void 0));await new d({...l,chain:t}).signReport(e),expect(a).toHaveBeenCalledWith(e)}),it("should be a no-op when no sign reporter is bound",async()=>{const t=vi.spyOn(y.prototype,"report");await new d({...l,chain:i.Tron}).signReport(e),expect(t).not.toHaveBeenCalled()})}),describe("Solana basic-flow rules",()=>{const e={programIds:["Stake11111111111111111111111111111111111111"],network:"solana-mainnet"},t=[o.SOLANA_BASIC_FLOW_RULE];it("should load them through getContexts on Solana",async()=>{const a=[{type:o.SOLANA_BASIC_FLOW_RULE,payload:{id:"native-staking",required:[],allowed:[]}}],n=vi.spyOn(E.prototype,"load").mockResolvedValue(a),c=await new d({...l,defaultLoaders:!0,chain:i.Solana}).getContexts(e,t);expect(n).toHaveBeenCalledWith(e),expect(c).toEqual(a)}),it("should return no contexts on a non-Solana chain",async()=>{const a=vi.spyOn(E.prototype,"load"),r=await new d({...l,defaultLoaders:!0,chain:i.Ethereum}).getContexts(e,t);expect(a).not.toHaveBeenCalled(),expect(r).toEqual([])})})});
|
|
2
2
|
//# sourceMappingURL=DefaultContextModule.test.js.map
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"version": 3,
|
|
3
3
|
"sources": ["../../../src/DefaultContextModule.test.ts"],
|
|
4
|
-
"sourcesContent": ["import { Right } from \"purify-ts\";\n\nimport {\n type ContextModuleLoaderConfig,\n type ContextModuleServiceConfig,\n} from \"./config/model/ContextModuleConfig\";\nimport { type TypedDataContext } from \"./modules/ethereum/model/TypedDataContext\";\nimport type { TypedDataContextLoader } from \"./modules/ethereum/typed-data/domain/TypedDataContextLoader\";\nimport { DefaultSignReporter } from \"./modules/multichain/sign-reporter/domain/DefaultSignReporter\";\nimport { type SignReportParams } from \"./modules/multichain/sign-reporter/model/SignReportParams\";\nimport { type ContextFieldLoader } from \"./shared/domain/ContextFieldLoader\";\nimport { type ContextLoader } from \"./shared/domain/ContextLoader\";\nimport { ContextModuleChainID } from \"./shared/domain/ContextModuleChainID\";\nimport {\n type ClearSignContext,\n ClearSignContextType,\n} from \"./shared/model/ClearSignContext\";\nimport { DefaultContextModule } from \"./DefaultContextModule\";\n\nconst mockLoggerFactory = () => ({\n debug: vi.fn(),\n info: vi.fn(),\n warn: vi.fn(),\n error: vi.fn(),\n subscribers: [],\n});\n\nconst contextLoaderStubBuilder = (canHandle: boolean): ContextLoader => {\n return {\n load: vi.fn(),\n canHandle: vi\n .fn()\n .mockReturnValue(canHandle) as unknown as ContextLoader[\"canHandle\"],\n };\n};\n\nconst fieldLoaderStubBuilder = (): ContextFieldLoader => {\n return {\n canHandle: vi.fn() as unknown as ContextFieldLoader[\"canHandle\"],\n loadField: vi.fn(),\n };\n};\n\ndescribe(\"DefaultContextModule\", () => {\n const typedDataLoader: TypedDataContextLoader = { load: vi.fn() };\n const defaultContextModuleConfig: ContextModuleServiceConfig &\n ContextModuleLoaderConfig = {\n customLoaders: [],\n defaultLoaders: false,\n defaultFieldLoaders: false,\n customFieldLoaders: [],\n customTypedDataLoader: typedDataLoader,\n cal: {\n url: \"https://cal/v1\",\n mode: \"prod\",\n branch: \"main\",\n },\n web3checks: {\n url: \"https://web3checks/v3\",\n },\n metadataServiceDomain: {\n url: \"https://metadata.com\",\n },\n reporter: {\n url: \"https://reporter.com\",\n },\n datasource: {\n proxy: \"default\",\n },\n appSource: \"third-party\",\n chain: ContextModuleChainID.Ethereum,\n originToken: \"originToken\",\n loggerFactory: mockLoggerFactory,\n };\n\n beforeEach(() => {\n vi.restoreAllMocks();\n });\n\n it(\"should initialize the context module with all the default loaders\", async () => {\n const contextModule = new DefaultContextModule(defaultContextModuleConfig);\n\n const res = await contextModule.getContexts({});\n\n expect(res).toEqual([]);\n });\n\n it(\"should return an empty array when no loaders\", async () => {\n const contextModule = new DefaultContextModule(defaultContextModuleConfig);\n\n const res = await contextModule.getContexts({});\n\n expect(res).toEqual([]);\n });\n\n it(\"should call all fetch method from metadata fetcher\", async () => {\n const loader = contextLoaderStubBuilder(true);\n const contextModule = new DefaultContextModule({\n ...defaultContextModuleConfig,\n customLoaders: [loader, loader],\n });\n\n await contextModule.getContexts({});\n\n expect(loader.canHandle).toHaveBeenCalledTimes(2);\n expect(loader.load).toHaveBeenCalledTimes(2);\n });\n\n it(\"should return an array of context response\", async () => {\n const loader = contextLoaderStubBuilder(true);\n const responses = [\n [{ type: ClearSignContextType.ETHEREUM_TOKEN, payload: \"payload1\" }],\n [\n { type: ClearSignContextType.ETHEREUM_TOKEN, payload: \"payload2\" },\n { type: ClearSignContextType.ETHEREUM_PLUGIN, payload: \"payload3\" },\n ],\n ] as ClearSignContext[][];\n vi.spyOn(loader, \"load\")\n .mockResolvedValueOnce(responses[0]!)\n .mockResolvedValueOnce(responses[1]!);\n const contextModule = new DefaultContextModule({\n ...defaultContextModuleConfig,\n customLoaders: [loader, loader],\n });\n\n const res = await contextModule.getContexts({});\n\n expect(loader.canHandle).toHaveBeenCalledTimes(2);\n expect(loader.load).toHaveBeenCalledTimes(2);\n expect(res).toEqual(responses.flat());\n });\n\n it(\"should only call loaders that can handle the input\", async () => {\n const loader1 = contextLoaderStubBuilder(true);\n const loader2 = contextLoaderStubBuilder(true);\n\n vi.spyOn(loader1, \"canHandle\").mockReturnValue(true);\n vi.spyOn(loader2, \"canHandle\").mockReturnValue(false);\n vi.spyOn(loader1, \"load\").mockResolvedValue([\n { type: ClearSignContextType.ETHEREUM_TOKEN, payload: \"payload1\" },\n ]);\n vi.spyOn(loader2, \"load\").mockResolvedValue([\n { type: ClearSignContextType.ETHEREUM_NFT, payload: \"payload2\" },\n ]);\n\n const contextModule = new DefaultContextModule({\n ...defaultContextModuleConfig,\n customLoaders: [loader1, loader2],\n });\n\n const testInput = { to: \"0x123\", selector: \"0xabc\" };\n const res = await contextModule.getContexts(testInput);\n\n expect(loader1.canHandle).toHaveBeenCalledWith(\n testInput,\n Object.values(ClearSignContextType),\n );\n expect(loader2.canHandle).toHaveBeenCalledWith(\n testInput,\n Object.values(ClearSignContextType),\n );\n expect(loader1.load).toHaveBeenCalledWith(testInput);\n expect(loader2.load).not.toHaveBeenCalled(); // Should not be called since canHandle returned false\n expect(res).toEqual([{ type: \"ethereumToken\", payload: \"payload1\" }]);\n });\n\n it(\"should use expected types if provided\", async () => {\n const loader = contextLoaderStubBuilder(true);\n\n vi.spyOn(loader, \"canHandle\").mockReturnValue(true);\n\n vi.spyOn(loader, \"load\").mockResolvedValue([\n { type: ClearSignContextType.ETHEREUM_TOKEN, payload: \"payload1\" },\n ]);\n\n const contextModule = new DefaultContextModule({\n ...defaultContextModuleConfig,\n customLoaders: [loader],\n });\n\n const testInput = { to: \"0x123\", selector: \"0xabc\" };\n await contextModule.getContexts(testInput, [\n ClearSignContextType.ETHEREUM_TOKEN,\n ]);\n\n expect(loader.canHandle).toHaveBeenCalledWith(testInput, [\n ClearSignContextType.ETHEREUM_TOKEN,\n ]);\n });\n\n it(\"should call the typed data loader\", async () => {\n const contextModule = new DefaultContextModule({\n ...defaultContextModuleConfig,\n customTypedDataLoader: typedDataLoader,\n });\n\n await contextModule.getTypedDataFilters({} as TypedDataContext);\n\n expect(typedDataLoader.load).toHaveBeenCalledTimes(1);\n });\n\n describe(\"getFieldContext\", () => {\n it(\"should return error when no loader can handle the field\", async () => {\n // GIVEN\n const fieldLoader = fieldLoaderStubBuilder();\n vi.spyOn(fieldLoader, \"canHandle\").mockReturnValue(false);\n\n const contextModule = new DefaultContextModule({\n ...defaultContextModuleConfig,\n customFieldLoaders: [fieldLoader],\n });\n\n const testField = { type: \"unknown\" };\n\n // WHEN\n const result = await contextModule.getFieldContext(\n testField,\n ClearSignContextType.ETHEREUM_TOKEN,\n );\n\n // THEN\n expect(fieldLoader.canHandle).toHaveBeenCalledWith(\n testField,\n ClearSignContextType.ETHEREUM_TOKEN,\n );\n expect(fieldLoader.loadField).not.toHaveBeenCalled();\n expect(result).toEqual({\n type: ClearSignContextType.ERROR,\n error: new Error(\n `Loader not found for field: ${testField} and expected type: ${ClearSignContextType.ETHEREUM_TOKEN}`,\n ),\n });\n });\n\n it(\"should return context when a loader can handle the field\", async () => {\n // GIVEN\n const fieldLoader = fieldLoaderStubBuilder();\n const mockContext: ClearSignContext = {\n type: ClearSignContextType.ETHEREUM_TOKEN,\n payload: \"test-payload\",\n };\n\n vi.spyOn(fieldLoader, \"canHandle\").mockReturnValue(true);\n vi.spyOn(fieldLoader, \"loadField\").mockResolvedValue(mockContext);\n\n const contextModule = new DefaultContextModule({\n ...defaultContextModuleConfig,\n customFieldLoaders: [fieldLoader],\n });\n\n const testField = { type: \"token\", address: \"0x123\" };\n\n // WHEN\n const result = await contextModule.getFieldContext(\n testField,\n ClearSignContextType.ETHEREUM_TOKEN,\n );\n\n // THEN\n expect(fieldLoader.canHandle).toHaveBeenCalledWith(\n testField,\n ClearSignContextType.ETHEREUM_TOKEN,\n );\n expect(fieldLoader.loadField).toHaveBeenCalledWith(testField);\n expect(result).toEqual(mockContext);\n });\n\n it(\"should return first context when multiple loaders can handle the field\", async () => {\n // GIVEN\n const fieldLoader1 = fieldLoaderStubBuilder();\n const fieldLoader2 = fieldLoaderStubBuilder();\n\n const mockContext1: ClearSignContext = {\n type: ClearSignContextType.ETHEREUM_TOKEN,\n payload: \"first-payload\",\n };\n const mockContext2: ClearSignContext = {\n type: ClearSignContextType.ETHEREUM_NFT,\n payload: \"second-payload\",\n };\n\n vi.spyOn(fieldLoader1, \"canHandle\").mockReturnValue(true);\n vi.spyOn(fieldLoader2, \"canHandle\").mockReturnValue(true);\n vi.spyOn(fieldLoader1, \"loadField\").mockResolvedValue(mockContext1);\n vi.spyOn(fieldLoader2, \"loadField\").mockResolvedValue(mockContext2);\n\n const contextModule = new DefaultContextModule({\n ...defaultContextModuleConfig,\n customFieldLoaders: [fieldLoader1, fieldLoader2],\n });\n\n const testField = { type: \"multi\", address: \"0x123\" };\n\n // WHEN\n const result = await contextModule.getFieldContext(\n testField,\n ClearSignContextType.ETHEREUM_TOKEN,\n );\n\n // THEN\n expect(fieldLoader1.canHandle).toHaveBeenCalledWith(\n testField,\n ClearSignContextType.ETHEREUM_TOKEN,\n );\n expect(fieldLoader2.canHandle).toHaveBeenCalledWith(\n testField,\n ClearSignContextType.ETHEREUM_TOKEN,\n );\n expect(fieldLoader1.loadField).toHaveBeenCalledWith(testField);\n expect(fieldLoader2.loadField).not.toHaveBeenCalled();\n expect(result).toEqual(mockContext1); // Should return first context\n });\n\n it(\"should return second context when first context is an error\", async () => {\n // GIVEN\n const fieldLoader1 = fieldLoaderStubBuilder();\n const fieldLoader2 = fieldLoaderStubBuilder();\n const mockContext1: ClearSignContext = {\n type: ClearSignContextType.ERROR,\n error: new Error(\"first-error\"),\n };\n const mockContext2: ClearSignContext = {\n type: ClearSignContextType.ETHEREUM_TOKEN,\n payload: \"second-payload\",\n };\n vi.spyOn(fieldLoader1, \"canHandle\").mockReturnValue(true);\n vi.spyOn(fieldLoader2, \"canHandle\").mockReturnValue(true);\n vi.spyOn(fieldLoader1, \"loadField\").mockResolvedValue(mockContext1);\n vi.spyOn(fieldLoader2, \"loadField\").mockResolvedValue(mockContext2);\n\n const contextModule = new DefaultContextModule({\n ...defaultContextModuleConfig,\n customFieldLoaders: [fieldLoader1, fieldLoader2],\n });\n\n const testField = { type: \"error\", address: \"0x123\" };\n\n // WHEN\n const result = await contextModule.getFieldContext(\n testField,\n ClearSignContextType.ETHEREUM_TOKEN,\n );\n\n // THEN\n expect(fieldLoader1.canHandle).toHaveBeenCalledWith(\n testField,\n ClearSignContextType.ETHEREUM_TOKEN,\n );\n expect(fieldLoader2.canHandle).toHaveBeenCalledWith(\n testField,\n ClearSignContextType.ETHEREUM_TOKEN,\n );\n expect(fieldLoader1.loadField).toHaveBeenCalledWith(testField);\n expect(fieldLoader2.loadField).toHaveBeenCalledWith(testField);\n expect(result).toEqual(mockContext2);\n });\n\n it(\"should handle loader rejection gracefully\", async () => {\n // GIVEN\n const fieldLoader = fieldLoaderStubBuilder();\n const loadError = new Error(\"Load field failed\");\n\n vi.spyOn(fieldLoader, \"canHandle\").mockReturnValue(true);\n vi.spyOn(fieldLoader, \"loadField\").mockRejectedValue(loadError);\n\n const contextModule = new DefaultContextModule({\n ...defaultContextModuleConfig,\n customFieldLoaders: [fieldLoader],\n });\n\n const testField = { type: \"error\", address: \"0x123\" };\n\n // WHEN & THEN\n await expect(\n contextModule.getFieldContext(\n testField,\n ClearSignContextType.ETHEREUM_TOKEN,\n ),\n ).rejects.toThrow(\"Load field failed\");\n\n expect(fieldLoader.canHandle).toHaveBeenCalledWith(\n testField,\n ClearSignContextType.ETHEREUM_TOKEN,\n );\n expect(fieldLoader.loadField).toHaveBeenCalledWith(testField);\n });\n });\n\n describe(\"signReport\", () => {\n const params = { chain: \"ETH\" } as SignReportParams;\n\n it.each([ContextModuleChainID.Ethereum, ContextModuleChainID.Solana])(\n \"should delegate to the bound sign reporter for %s\",\n async (chain) => {\n // GIVEN\n const reportSpy = vi\n .spyOn(DefaultSignReporter.prototype, \"report\")\n .mockResolvedValue(Right(undefined));\n const contextModule = new DefaultContextModule({\n ...defaultContextModuleConfig,\n chain,\n });\n\n // WHEN\n await contextModule.signReport(params);\n\n // THEN\n expect(reportSpy).toHaveBeenCalledWith(params);\n },\n );\n\n it(\"should be a no-op when no sign reporter is bound\", async () => {\n // GIVEN\n const reportSpy = vi.spyOn(DefaultSignReporter.prototype, \"report\");\n const contextModule = new DefaultContextModule({\n ...defaultContextModuleConfig,\n chain: ContextModuleChainID.Tron,\n });\n\n // WHEN\n await contextModule.signReport(params);\n\n // THEN\n expect(reportSpy).not.toHaveBeenCalled();\n });\n });\n});\n"],
|
|
5
|
-
"mappings": "AAAA,OAAS,SAAAA,MAAa,YAQtB,OAAS,uBAAAC,MAA2B,
|
|
6
|
-
"names": ["Right", "DefaultSignReporter", "ContextModuleChainID", "ClearSignContextType", "DefaultContextModule", "mockLoggerFactory", "contextLoaderStubBuilder", "canHandle", "fieldLoaderStubBuilder", "typedDataLoader", "defaultContextModuleConfig", "res", "loader", "responses", "loader1", "loader2", "contextModule", "testInput", "fieldLoader", "testField", "result", "mockContext", "fieldLoader1", "fieldLoader2", "mockContext1", "mockContext2", "loadError", "params", "chain", "reportSpy"]
|
|
4
|
+
"sourcesContent": ["import { Right } from \"purify-ts\";\n\nimport {\n type ContextModuleLoaderConfig,\n type ContextModuleServiceConfig,\n} from \"./config/model/ContextModuleConfig\";\nimport { type TypedDataContext } from \"./modules/ethereum/model/TypedDataContext\";\nimport type { TypedDataContextLoader } from \"./modules/ethereum/typed-data/domain/TypedDataContextLoader\";\nimport { DefaultSignReporter } from \"./modules/multichain/sign-reporter/domain/DefaultSignReporter\";\nimport { type SignReportParams } from \"./modules/multichain/sign-reporter/model/SignReportParams\";\nimport { SolanaBasicFlowRuleContextLoader } from \"./modules/solana/instruction-info/domain/SolanaBasicFlowRuleContextLoader\";\nimport { type ContextFieldLoader } from \"./shared/domain/ContextFieldLoader\";\nimport { type ContextLoader } from \"./shared/domain/ContextLoader\";\nimport { ContextModuleChainID } from \"./shared/domain/ContextModuleChainID\";\nimport {\n type ClearSignContext,\n ClearSignContextType,\n} from \"./shared/model/ClearSignContext\";\nimport { DefaultContextModule } from \"./DefaultContextModule\";\n\nconst mockLoggerFactory = () => ({\n debug: vi.fn(),\n info: vi.fn(),\n warn: vi.fn(),\n error: vi.fn(),\n subscribers: [],\n});\n\nconst contextLoaderStubBuilder = (canHandle: boolean): ContextLoader => {\n return {\n load: vi.fn(),\n canHandle: vi\n .fn()\n .mockReturnValue(canHandle) as unknown as ContextLoader[\"canHandle\"],\n };\n};\n\nconst fieldLoaderStubBuilder = (): ContextFieldLoader => {\n return {\n canHandle: vi.fn() as unknown as ContextFieldLoader[\"canHandle\"],\n loadField: vi.fn(),\n };\n};\n\ndescribe(\"DefaultContextModule\", () => {\n const typedDataLoader: TypedDataContextLoader = { load: vi.fn() };\n const defaultContextModuleConfig: ContextModuleServiceConfig &\n ContextModuleLoaderConfig = {\n customLoaders: [],\n defaultLoaders: false,\n defaultFieldLoaders: false,\n customFieldLoaders: [],\n customTypedDataLoader: typedDataLoader,\n cal: {\n url: \"https://cal/v1\",\n mode: \"prod\",\n branch: \"main\",\n },\n web3checks: {\n url: \"https://web3checks/v3\",\n },\n metadataServiceDomain: {\n url: \"https://metadata.com\",\n },\n reporter: {\n url: \"https://reporter.com\",\n },\n datasource: {\n proxy: \"default\",\n },\n appSource: \"third-party\",\n chain: ContextModuleChainID.Ethereum,\n originToken: \"originToken\",\n loggerFactory: mockLoggerFactory,\n };\n\n beforeEach(() => {\n vi.restoreAllMocks();\n });\n\n it(\"should initialize the context module with all the default loaders\", async () => {\n const contextModule = new DefaultContextModule(defaultContextModuleConfig);\n\n const res = await contextModule.getContexts({});\n\n expect(res).toEqual([]);\n });\n\n it(\"should return an empty array when no loaders\", async () => {\n const contextModule = new DefaultContextModule(defaultContextModuleConfig);\n\n const res = await contextModule.getContexts({});\n\n expect(res).toEqual([]);\n });\n\n it(\"should call all fetch method from metadata fetcher\", async () => {\n const loader = contextLoaderStubBuilder(true);\n const contextModule = new DefaultContextModule({\n ...defaultContextModuleConfig,\n customLoaders: [loader, loader],\n });\n\n await contextModule.getContexts({});\n\n expect(loader.canHandle).toHaveBeenCalledTimes(2);\n expect(loader.load).toHaveBeenCalledTimes(2);\n });\n\n it(\"should return an array of context response\", async () => {\n const loader = contextLoaderStubBuilder(true);\n const responses = [\n [{ type: ClearSignContextType.ETHEREUM_TOKEN, payload: \"payload1\" }],\n [\n { type: ClearSignContextType.ETHEREUM_TOKEN, payload: \"payload2\" },\n { type: ClearSignContextType.ETHEREUM_PLUGIN, payload: \"payload3\" },\n ],\n ] as ClearSignContext[][];\n vi.spyOn(loader, \"load\")\n .mockResolvedValueOnce(responses[0]!)\n .mockResolvedValueOnce(responses[1]!);\n const contextModule = new DefaultContextModule({\n ...defaultContextModuleConfig,\n customLoaders: [loader, loader],\n });\n\n const res = await contextModule.getContexts({});\n\n expect(loader.canHandle).toHaveBeenCalledTimes(2);\n expect(loader.load).toHaveBeenCalledTimes(2);\n expect(res).toEqual(responses.flat());\n });\n\n it(\"should only call loaders that can handle the input\", async () => {\n const loader1 = contextLoaderStubBuilder(true);\n const loader2 = contextLoaderStubBuilder(true);\n\n vi.spyOn(loader1, \"canHandle\").mockReturnValue(true);\n vi.spyOn(loader2, \"canHandle\").mockReturnValue(false);\n vi.spyOn(loader1, \"load\").mockResolvedValue([\n { type: ClearSignContextType.ETHEREUM_TOKEN, payload: \"payload1\" },\n ]);\n vi.spyOn(loader2, \"load\").mockResolvedValue([\n { type: ClearSignContextType.ETHEREUM_NFT, payload: \"payload2\" },\n ]);\n\n const contextModule = new DefaultContextModule({\n ...defaultContextModuleConfig,\n customLoaders: [loader1, loader2],\n });\n\n const testInput = { to: \"0x123\", selector: \"0xabc\" };\n const res = await contextModule.getContexts(testInput);\n\n expect(loader1.canHandle).toHaveBeenCalledWith(\n testInput,\n Object.values(ClearSignContextType),\n );\n expect(loader2.canHandle).toHaveBeenCalledWith(\n testInput,\n Object.values(ClearSignContextType),\n );\n expect(loader1.load).toHaveBeenCalledWith(testInput);\n expect(loader2.load).not.toHaveBeenCalled(); // Should not be called since canHandle returned false\n expect(res).toEqual([{ type: \"ethereumToken\", payload: \"payload1\" }]);\n });\n\n it(\"should use expected types if provided\", async () => {\n const loader = contextLoaderStubBuilder(true);\n\n vi.spyOn(loader, \"canHandle\").mockReturnValue(true);\n\n vi.spyOn(loader, \"load\").mockResolvedValue([\n { type: ClearSignContextType.ETHEREUM_TOKEN, payload: \"payload1\" },\n ]);\n\n const contextModule = new DefaultContextModule({\n ...defaultContextModuleConfig,\n customLoaders: [loader],\n });\n\n const testInput = { to: \"0x123\", selector: \"0xabc\" };\n await contextModule.getContexts(testInput, [\n ClearSignContextType.ETHEREUM_TOKEN,\n ]);\n\n expect(loader.canHandle).toHaveBeenCalledWith(testInput, [\n ClearSignContextType.ETHEREUM_TOKEN,\n ]);\n });\n\n it(\"should call the typed data loader\", async () => {\n const contextModule = new DefaultContextModule({\n ...defaultContextModuleConfig,\n customTypedDataLoader: typedDataLoader,\n });\n\n await contextModule.getTypedDataFilters({} as TypedDataContext);\n\n expect(typedDataLoader.load).toHaveBeenCalledTimes(1);\n });\n\n describe(\"getFieldContext\", () => {\n it(\"should return error when no loader can handle the field\", async () => {\n // GIVEN\n const fieldLoader = fieldLoaderStubBuilder();\n vi.spyOn(fieldLoader, \"canHandle\").mockReturnValue(false);\n\n const contextModule = new DefaultContextModule({\n ...defaultContextModuleConfig,\n customFieldLoaders: [fieldLoader],\n });\n\n const testField = { type: \"unknown\" };\n\n // WHEN\n const result = await contextModule.getFieldContext(\n testField,\n ClearSignContextType.ETHEREUM_TOKEN,\n );\n\n // THEN\n expect(fieldLoader.canHandle).toHaveBeenCalledWith(\n testField,\n ClearSignContextType.ETHEREUM_TOKEN,\n );\n expect(fieldLoader.loadField).not.toHaveBeenCalled();\n expect(result).toEqual({\n type: ClearSignContextType.ERROR,\n error: new Error(\n `Loader not found for field: ${testField} and expected type: ${ClearSignContextType.ETHEREUM_TOKEN}`,\n ),\n });\n });\n\n it(\"should return context when a loader can handle the field\", async () => {\n // GIVEN\n const fieldLoader = fieldLoaderStubBuilder();\n const mockContext: ClearSignContext = {\n type: ClearSignContextType.ETHEREUM_TOKEN,\n payload: \"test-payload\",\n };\n\n vi.spyOn(fieldLoader, \"canHandle\").mockReturnValue(true);\n vi.spyOn(fieldLoader, \"loadField\").mockResolvedValue(mockContext);\n\n const contextModule = new DefaultContextModule({\n ...defaultContextModuleConfig,\n customFieldLoaders: [fieldLoader],\n });\n\n const testField = { type: \"token\", address: \"0x123\" };\n\n // WHEN\n const result = await contextModule.getFieldContext(\n testField,\n ClearSignContextType.ETHEREUM_TOKEN,\n );\n\n // THEN\n expect(fieldLoader.canHandle).toHaveBeenCalledWith(\n testField,\n ClearSignContextType.ETHEREUM_TOKEN,\n );\n expect(fieldLoader.loadField).toHaveBeenCalledWith(testField);\n expect(result).toEqual(mockContext);\n });\n\n it(\"should return first context when multiple loaders can handle the field\", async () => {\n // GIVEN\n const fieldLoader1 = fieldLoaderStubBuilder();\n const fieldLoader2 = fieldLoaderStubBuilder();\n\n const mockContext1: ClearSignContext = {\n type: ClearSignContextType.ETHEREUM_TOKEN,\n payload: \"first-payload\",\n };\n const mockContext2: ClearSignContext = {\n type: ClearSignContextType.ETHEREUM_NFT,\n payload: \"second-payload\",\n };\n\n vi.spyOn(fieldLoader1, \"canHandle\").mockReturnValue(true);\n vi.spyOn(fieldLoader2, \"canHandle\").mockReturnValue(true);\n vi.spyOn(fieldLoader1, \"loadField\").mockResolvedValue(mockContext1);\n vi.spyOn(fieldLoader2, \"loadField\").mockResolvedValue(mockContext2);\n\n const contextModule = new DefaultContextModule({\n ...defaultContextModuleConfig,\n customFieldLoaders: [fieldLoader1, fieldLoader2],\n });\n\n const testField = { type: \"multi\", address: \"0x123\" };\n\n // WHEN\n const result = await contextModule.getFieldContext(\n testField,\n ClearSignContextType.ETHEREUM_TOKEN,\n );\n\n // THEN\n expect(fieldLoader1.canHandle).toHaveBeenCalledWith(\n testField,\n ClearSignContextType.ETHEREUM_TOKEN,\n );\n expect(fieldLoader2.canHandle).toHaveBeenCalledWith(\n testField,\n ClearSignContextType.ETHEREUM_TOKEN,\n );\n expect(fieldLoader1.loadField).toHaveBeenCalledWith(testField);\n expect(fieldLoader2.loadField).not.toHaveBeenCalled();\n expect(result).toEqual(mockContext1); // Should return first context\n });\n\n it(\"should return second context when first context is an error\", async () => {\n // GIVEN\n const fieldLoader1 = fieldLoaderStubBuilder();\n const fieldLoader2 = fieldLoaderStubBuilder();\n const mockContext1: ClearSignContext = {\n type: ClearSignContextType.ERROR,\n error: new Error(\"first-error\"),\n };\n const mockContext2: ClearSignContext = {\n type: ClearSignContextType.ETHEREUM_TOKEN,\n payload: \"second-payload\",\n };\n vi.spyOn(fieldLoader1, \"canHandle\").mockReturnValue(true);\n vi.spyOn(fieldLoader2, \"canHandle\").mockReturnValue(true);\n vi.spyOn(fieldLoader1, \"loadField\").mockResolvedValue(mockContext1);\n vi.spyOn(fieldLoader2, \"loadField\").mockResolvedValue(mockContext2);\n\n const contextModule = new DefaultContextModule({\n ...defaultContextModuleConfig,\n customFieldLoaders: [fieldLoader1, fieldLoader2],\n });\n\n const testField = { type: \"error\", address: \"0x123\" };\n\n // WHEN\n const result = await contextModule.getFieldContext(\n testField,\n ClearSignContextType.ETHEREUM_TOKEN,\n );\n\n // THEN\n expect(fieldLoader1.canHandle).toHaveBeenCalledWith(\n testField,\n ClearSignContextType.ETHEREUM_TOKEN,\n );\n expect(fieldLoader2.canHandle).toHaveBeenCalledWith(\n testField,\n ClearSignContextType.ETHEREUM_TOKEN,\n );\n expect(fieldLoader1.loadField).toHaveBeenCalledWith(testField);\n expect(fieldLoader2.loadField).toHaveBeenCalledWith(testField);\n expect(result).toEqual(mockContext2);\n });\n\n it(\"should handle loader rejection gracefully\", async () => {\n // GIVEN\n const fieldLoader = fieldLoaderStubBuilder();\n const loadError = new Error(\"Load field failed\");\n\n vi.spyOn(fieldLoader, \"canHandle\").mockReturnValue(true);\n vi.spyOn(fieldLoader, \"loadField\").mockRejectedValue(loadError);\n\n const contextModule = new DefaultContextModule({\n ...defaultContextModuleConfig,\n customFieldLoaders: [fieldLoader],\n });\n\n const testField = { type: \"error\", address: \"0x123\" };\n\n // WHEN & THEN\n await expect(\n contextModule.getFieldContext(\n testField,\n ClearSignContextType.ETHEREUM_TOKEN,\n ),\n ).rejects.toThrow(\"Load field failed\");\n\n expect(fieldLoader.canHandle).toHaveBeenCalledWith(\n testField,\n ClearSignContextType.ETHEREUM_TOKEN,\n );\n expect(fieldLoader.loadField).toHaveBeenCalledWith(testField);\n });\n });\n\n describe(\"signReport\", () => {\n const params = { chain: \"ETH\" } as SignReportParams;\n\n it.each([ContextModuleChainID.Ethereum, ContextModuleChainID.Solana])(\n \"should delegate to the bound sign reporter for %s\",\n async (chain) => {\n // GIVEN\n const reportSpy = vi\n .spyOn(DefaultSignReporter.prototype, \"report\")\n .mockResolvedValue(Right(undefined));\n const contextModule = new DefaultContextModule({\n ...defaultContextModuleConfig,\n chain,\n });\n\n // WHEN\n await contextModule.signReport(params);\n\n // THEN\n expect(reportSpy).toHaveBeenCalledWith(params);\n },\n );\n\n it(\"should be a no-op when no sign reporter is bound\", async () => {\n // GIVEN\n const reportSpy = vi.spyOn(DefaultSignReporter.prototype, \"report\");\n const contextModule = new DefaultContextModule({\n ...defaultContextModuleConfig,\n chain: ContextModuleChainID.Tron,\n });\n\n // WHEN\n await contextModule.signReport(params);\n\n // THEN\n expect(reportSpy).not.toHaveBeenCalled();\n });\n });\n\n describe(\"Solana basic-flow rules\", () => {\n const input = {\n programIds: [\"Stake11111111111111111111111111111111111111\"],\n network: \"solana-mainnet\",\n };\n const expectedTypes = [ClearSignContextType.SOLANA_BASIC_FLOW_RULE];\n\n it(\"should load them through getContexts on Solana\", async () => {\n // GIVEN\n const contexts: ClearSignContext[] = [\n {\n type: ClearSignContextType.SOLANA_BASIC_FLOW_RULE,\n payload: { id: \"native-staking\", required: [], allowed: [] },\n },\n ];\n const loadSpy = vi\n .spyOn(SolanaBasicFlowRuleContextLoader.prototype, \"load\")\n .mockResolvedValue(contexts);\n const contextModule = new DefaultContextModule({\n ...defaultContextModuleConfig,\n defaultLoaders: true,\n chain: ContextModuleChainID.Solana,\n });\n\n // WHEN\n const result = await contextModule.getContexts(input, expectedTypes);\n\n // THEN\n expect(loadSpy).toHaveBeenCalledWith(input);\n expect(result).toEqual(contexts);\n });\n\n it(\"should return no contexts on a non-Solana chain\", async () => {\n // GIVEN\n const loadSpy = vi.spyOn(\n SolanaBasicFlowRuleContextLoader.prototype,\n \"load\",\n );\n const contextModule = new DefaultContextModule({\n ...defaultContextModuleConfig,\n defaultLoaders: true,\n chain: ContextModuleChainID.Ethereum,\n });\n\n // WHEN\n const result = await contextModule.getContexts(input, expectedTypes);\n\n // THEN\n expect(loadSpy).not.toHaveBeenCalled();\n expect(result).toEqual([]);\n });\n });\n});\n"],
|
|
5
|
+
"mappings": "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",
|
|
6
|
+
"names": ["Right", "DefaultSignReporter", "SolanaBasicFlowRuleContextLoader", "ContextModuleChainID", "ClearSignContextType", "DefaultContextModule", "mockLoggerFactory", "contextLoaderStubBuilder", "canHandle", "fieldLoaderStubBuilder", "typedDataLoader", "defaultContextModuleConfig", "res", "loader", "responses", "loader1", "loader2", "contextModule", "testInput", "fieldLoader", "testField", "result", "mockContext", "fieldLoader1", "fieldLoader2", "mockContext1", "mockContext2", "loadError", "params", "chain", "reportSpy", "input", "expectedTypes", "contexts", "loadSpy"]
|
|
7
7
|
}
|
package/lib/esm/src/index.js
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
export*from"./ContextModule";export*from"./ContextModuleBuilder";export*from"./DefaultContextModule";export*from"./modules/concordium/account-ownership/data/AccountOwnershipDataSource";export*from"./modules/concordium/account-ownership/data/AccountOwnershipError";export*from"./modules/concordium/account-ownership/data/HttpAccountOwnershipDataSource";export*from"./modules/concordium/account-ownership/domain/AccountOwnershipContextLoader";export*from"./modules/ethereum/calldata/data/CalldataDescriptorDataSource";export*from"./modules/ethereum/calldata/data/HttpCalldataDescriptorDataSource";export*from"./modules/ethereum/calldata/domain/CalldataContextLoader";export*from"./modules/ethereum/dynamic-network/data/DynamicNetworkDataSource";export*from"./modules/ethereum/dynamic-network/data/HttpDynamicNetworkDataSource";export*from"./modules/ethereum/dynamic-network/domain/DynamicNetworkContextLoader";export*from"./modules/ethereum/dynamic-network/model/DynamicNetworkConfiguration";export*from"./modules/ethereum/external-plugin/data/ExternalPluginDataSource";export*from"./modules/ethereum/external-plugin/data/HttpExternalPluginDataSource";export*from"./modules/ethereum/external-plugin/domain/ExternalPluginContextLoader";export*from"./modules/ethereum/gated-signing/data/GatedDescriptorDataSource";export*from"./modules/ethereum/gated-signing/data/HttpGatedDescriptorDataSource";export*from"./modules/ethereum/gated-signing/domain/GatedSigningContextLoader";export*from"./modules/ethereum/gated-signing/domain/GatedSigningTypedDataContextLoader";export*from"./modules/ethereum/model/EthereumClearSignContext";export*from"./modules/ethereum/model/TypedDataClearSignContext";export*from"./modules/ethereum/model/TypedDataContext";export*from"./modules/ethereum/nft/data/HttpNftDataSource";export*from"./modules/ethereum/nft/data/NftDataSource";export*from"./modules/ethereum/nft/domain/NftContextFieldLoader";export*from"./modules/ethereum/nft/domain/NftContextLoader";export*from"./modules/ethereum/proxy/data/HttpProxyDataSource";export*from"./modules/ethereum/proxy/data/HttpSafeProxyDataSource";export*from"./modules/ethereum/proxy/data/ProxyDataSource";export*from"./modules/ethereum/proxy/domain/ProxyContextFieldLoader";export*from"./modules/ethereum/token/data/HttpTokenDataSource";export*from"./modules/ethereum/token/data/TokenDataSource";export*from"./modules/ethereum/token/domain/TokenContextFieldLoader";export*from"./modules/ethereum/token/domain/TokenContextLoader";export*from"./modules/ethereum/trusted-name/data/HttpTrustedNameDataSource";export*from"./modules/ethereum/trusted-name/data/TrustedNameDataSource";export*from"./modules/ethereum/trusted-name/domain/TrustedNameContextFieldLoader";export*from"./modules/ethereum/trusted-name/domain/TrustedNameContextLoader";export*from"./modules/ethereum/typed-data/data/HttpTypedDataDataSource";export*from"./modules/ethereum/typed-data/data/TypedDataDataSource";export*from"./modules/ethereum/typed-data/domain/DefaultTypedDataContextLoader";export*from"./modules/ethereum/typed-data/domain/TypedDataContextLoader";export*from"./modules/ethereum/typed-data/utils/getSchemaHash";export*from"./modules/ethereum/uniswap/data/AbiDecoderDataSource";export*from"./modules/ethereum/uniswap/data/CommandDecoderDataSource";export*from"./modules/ethereum/uniswap/data/DefaultCommandDecoderDataSource";export*from"./modules/ethereum/uniswap/data/EthersAbiDecoderDataSource";export*from"./modules/ethereum/uniswap/domain/UniswapContextLoader";export*from"./modules/multichain/pki/data/HttpPkiCertificateDataSource";export*from"./modules/multichain/pki/data/PkiCertificateDataSource";export*from"./modules/multichain/pki/domain/DefaultPkiCertificateLoader";export*from"./modules/multichain/pki/domain/PkiCertificateLoader";export*from"./modules/multichain/pki/model/KeyId";export*from"./modules/multichain/pki/model/KeyUsage";export*from"./modules/multichain/pki/model/PkiCertificate";export*from"./modules/multichain/pki/model/PkiCertificateInfo";export*from"./modules/multichain/reporter/data/BlindSigningReporterDatasource";export*from"./modules/multichain/reporter/data/HttpBlindSigningReporterDatasource";export*from"./modules/multichain/reporter/domain/BlindSigningReporter";export*from"./modules/multichain/reporter/domain/DefaultBlindSigningReporter";export*from"./modules/multichain/reporter/model/BlindSigningEvent";export*from"./modules/multichain/sign-reporter/model/SignReportParams";export*from"./modules/multichain/transaction-check/utils/constants";export*from"./modules/solana/alt-resolution/data/AltResolutionDataSource";export*from"./modules/solana/alt-resolution/data/HttpAltResolutionDataSource";export*from"./modules/solana/alt-resolution/domain/AltResolutionContextLoader";export*from"./modules/solana/enum-variant/domain/EnumVariantContextLoader";export*from"./modules/solana/instruction-info/data/HttpInstructionInfoDataSource";export*from"./modules/solana/instruction-info/data/InstructionInfoDataSource";export*from"./modules/solana/instruction-info/domain/InstructionInfoContextLoader";export*from"./modules/solana/model/SolanaClearSignContext";export*from"./modules/solana/model/SolanaContextTypes";export*from"./modules/solana/model/SolanaTransactionScanChainId";export*from"./modules/solana/owner-info/data/HttpOwnerInfoDataSource";export*from"./modules/solana/owner-info/data/OwnerInfoDataSource";export*from"./modules/solana/owner-info/domain/OwnerInfoContextLoader";export*from"./modules/solana/owner-info/domain/solanaContextTypes";export*from"./modules/solana/token-account-state/data/HttpTokenAccountStateDataSource";export*from"./modules/solana/token-account-state/data/TokenAccountStateDataSource";export*from"./modules/solana/token-account-state/domain/TokenAccountStateContextLoader";export*from"./modules/solana/token-info/data/HttpTokenInfoDataSource";export*from"./modules/solana/token-info/data/TokenInfoDataSource";export*from"./modules/solana/token-info/domain/TokenInfoContextLoader";export*from"./modules/solana/trusted-name/data/HttpTrustedNameDataSource";export*from"./modules/solana/trusted-name/data/TrustedNameDataSource";export*from"./modules/solana/trusted-name/domain/TrustedNameContextLoader";export*from"./modules/tron/model/TronTransactionContext";export*from"./shared/domain/ContextFieldLoader";export*from"./shared/domain/ContextLoader";export*from"./shared/domain/ContextModuleChainID";export*from"./shared/model/BlindSigningModelId";export*from"./shared/model/ClearSignContext";export*from"./shared/model/GenericPath";export*from"./shared/model/TransactionSubset";
|
|
1
|
+
export*from"./ContextModule";export*from"./ContextModuleBuilder";export*from"./DefaultContextModule";export*from"./modules/concordium/account-ownership/data/AccountOwnershipDataSource";export*from"./modules/concordium/account-ownership/data/AccountOwnershipError";export*from"./modules/concordium/account-ownership/data/HttpAccountOwnershipDataSource";export*from"./modules/concordium/account-ownership/domain/AccountOwnershipContextLoader";export*from"./modules/ethereum/calldata/data/CalldataDescriptorDataSource";export*from"./modules/ethereum/calldata/data/HttpCalldataDescriptorDataSource";export*from"./modules/ethereum/calldata/domain/CalldataContextLoader";export*from"./modules/ethereum/dynamic-network/data/DynamicNetworkDataSource";export*from"./modules/ethereum/dynamic-network/data/HttpDynamicNetworkDataSource";export*from"./modules/ethereum/dynamic-network/domain/DynamicNetworkContextLoader";export*from"./modules/ethereum/dynamic-network/model/DynamicNetworkConfiguration";export*from"./modules/ethereum/external-plugin/data/ExternalPluginDataSource";export*from"./modules/ethereum/external-plugin/data/HttpExternalPluginDataSource";export*from"./modules/ethereum/external-plugin/domain/ExternalPluginContextLoader";export*from"./modules/ethereum/gated-signing/data/GatedDescriptorDataSource";export*from"./modules/ethereum/gated-signing/data/HttpGatedDescriptorDataSource";export*from"./modules/ethereum/gated-signing/domain/GatedSigningContextLoader";export*from"./modules/ethereum/gated-signing/domain/GatedSigningTypedDataContextLoader";export*from"./modules/ethereum/model/EthereumClearSignContext";export*from"./modules/ethereum/model/TypedDataClearSignContext";export*from"./modules/ethereum/model/TypedDataContext";export*from"./modules/ethereum/nft/data/HttpNftDataSource";export*from"./modules/ethereum/nft/data/NftDataSource";export*from"./modules/ethereum/nft/domain/NftContextFieldLoader";export*from"./modules/ethereum/nft/domain/NftContextLoader";export*from"./modules/ethereum/proxy/data/HttpProxyDataSource";export*from"./modules/ethereum/proxy/data/HttpSafeProxyDataSource";export*from"./modules/ethereum/proxy/data/ProxyDataSource";export*from"./modules/ethereum/proxy/domain/ProxyContextFieldLoader";export*from"./modules/ethereum/token/data/HttpTokenDataSource";export*from"./modules/ethereum/token/data/TokenDataSource";export*from"./modules/ethereum/token/domain/TokenContextFieldLoader";export*from"./modules/ethereum/token/domain/TokenContextLoader";export*from"./modules/ethereum/trusted-name/data/HttpTrustedNameDataSource";export*from"./modules/ethereum/trusted-name/data/TrustedNameDataSource";export*from"./modules/ethereum/trusted-name/domain/TrustedNameContextFieldLoader";export*from"./modules/ethereum/trusted-name/domain/TrustedNameContextLoader";export*from"./modules/ethereum/typed-data/data/HttpTypedDataDataSource";export*from"./modules/ethereum/typed-data/data/TypedDataDataSource";export*from"./modules/ethereum/typed-data/domain/DefaultTypedDataContextLoader";export*from"./modules/ethereum/typed-data/domain/TypedDataContextLoader";export*from"./modules/ethereum/typed-data/utils/getSchemaHash";export*from"./modules/ethereum/uniswap/data/AbiDecoderDataSource";export*from"./modules/ethereum/uniswap/data/CommandDecoderDataSource";export*from"./modules/ethereum/uniswap/data/DefaultCommandDecoderDataSource";export*from"./modules/ethereum/uniswap/data/EthersAbiDecoderDataSource";export*from"./modules/ethereum/uniswap/domain/UniswapContextLoader";export*from"./modules/multichain/pki/data/HttpPkiCertificateDataSource";export*from"./modules/multichain/pki/data/PkiCertificateDataSource";export*from"./modules/multichain/pki/domain/DefaultPkiCertificateLoader";export*from"./modules/multichain/pki/domain/PkiCertificateLoader";export*from"./modules/multichain/pki/model/KeyId";export*from"./modules/multichain/pki/model/KeyUsage";export*from"./modules/multichain/pki/model/PkiCertificate";export*from"./modules/multichain/pki/model/PkiCertificateInfo";export*from"./modules/multichain/reporter/data/BlindSigningReporterDatasource";export*from"./modules/multichain/reporter/data/HttpBlindSigningReporterDatasource";export*from"./modules/multichain/reporter/domain/BlindSigningReporter";export*from"./modules/multichain/reporter/domain/DefaultBlindSigningReporter";export*from"./modules/multichain/reporter/model/BlindSigningEvent";export*from"./modules/multichain/sign-reporter/model/SignReportParams";export*from"./modules/multichain/transaction-check/utils/constants";export*from"./modules/solana/alt-resolution/data/AltResolutionDataSource";export*from"./modules/solana/alt-resolution/data/HttpAltResolutionDataSource";export*from"./modules/solana/alt-resolution/domain/AltResolutionContextLoader";export*from"./modules/solana/enum-variant/domain/EnumVariantContextLoader";export*from"./modules/solana/instruction-info/data/HttpInstructionInfoDataSource";export*from"./modules/solana/instruction-info/data/InstructionInfoDataSource";export*from"./modules/solana/instruction-info/domain/InstructionInfoContextLoader";export*from"./modules/solana/instruction-info/domain/SolanaBasicFlowRuleContextLoader";export*from"./modules/solana/model/SolanaClearSignContext";export*from"./modules/solana/model/SolanaContextTypes";export*from"./modules/solana/model/SolanaTransactionScanChainId";export*from"./modules/solana/owner-info/data/HttpOwnerInfoDataSource";export*from"./modules/solana/owner-info/data/OwnerInfoDataSource";export*from"./modules/solana/owner-info/domain/OwnerInfoContextLoader";export*from"./modules/solana/owner-info/domain/solanaContextTypes";export*from"./modules/solana/token-account-state/data/HttpTokenAccountStateDataSource";export*from"./modules/solana/token-account-state/data/TokenAccountStateDataSource";export*from"./modules/solana/token-account-state/domain/TokenAccountStateContextLoader";export*from"./modules/solana/token-info/data/HttpTokenInfoDataSource";export*from"./modules/solana/token-info/data/TokenInfoDataSource";export*from"./modules/solana/token-info/domain/TokenInfoContextLoader";export*from"./modules/solana/trusted-name/data/HttpTrustedNameDataSource";export*from"./modules/solana/trusted-name/data/TrustedNameDataSource";export*from"./modules/solana/trusted-name/domain/TrustedNameContextLoader";export*from"./modules/tron/model/TronTransactionContext";export*from"./shared/domain/ContextFieldLoader";export*from"./shared/domain/ContextLoader";export*from"./shared/domain/ContextModuleChainID";export*from"./shared/model/BlindSigningModelId";export*from"./shared/model/ClearSignContext";export*from"./shared/model/GenericPath";export*from"./shared/model/TransactionSubset";
|
|
2
2
|
//# sourceMappingURL=index.js.map
|
package/lib/esm/src/index.js.map
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"version": 3,
|
|
3
3
|
"sources": ["../../../src/index.ts"],
|
|
4
|
-
"sourcesContent": ["export type {\n ContextModuleCalBranch,\n ContextModuleCalConfig,\n ContextModuleCalMode,\n ContextModuleConfig,\n ContextModuleDatasourceConfig,\n ContextModuleMetadataServiceConfig,\n ContextModuleReporterConfig,\n ContextModuleWeb3ChecksConfig,\n} from \"./config/model/ContextModuleConfig\";\nexport * from \"./ContextModule\";\nexport * from \"./ContextModuleBuilder\";\nexport * from \"./DefaultContextModule\";\nexport * from \"./modules/concordium/account-ownership/data/AccountOwnershipDataSource\";\nexport * from \"./modules/concordium/account-ownership/data/AccountOwnershipError\";\nexport * from \"./modules/concordium/account-ownership/data/HttpAccountOwnershipDataSource\";\nexport * from \"./modules/concordium/account-ownership/domain/AccountOwnershipContextLoader\";\nexport * from \"./modules/ethereum/calldata/data/CalldataDescriptorDataSource\";\nexport * from \"./modules/ethereum/calldata/data/HttpCalldataDescriptorDataSource\";\nexport * from \"./modules/ethereum/calldata/domain/CalldataContextLoader\";\nexport * from \"./modules/ethereum/dynamic-network/data/DynamicNetworkDataSource\";\nexport * from \"./modules/ethereum/dynamic-network/data/HttpDynamicNetworkDataSource\";\nexport * from \"./modules/ethereum/dynamic-network/domain/DynamicNetworkContextLoader\";\nexport * from \"./modules/ethereum/dynamic-network/model/DynamicNetworkConfiguration\";\nexport * from \"./modules/ethereum/external-plugin/data/ExternalPluginDataSource\";\nexport * from \"./modules/ethereum/external-plugin/data/HttpExternalPluginDataSource\";\nexport * from \"./modules/ethereum/external-plugin/domain/ExternalPluginContextLoader\";\nexport * from \"./modules/ethereum/gated-signing/data/GatedDescriptorDataSource\";\nexport * from \"./modules/ethereum/gated-signing/data/HttpGatedDescriptorDataSource\";\nexport * from \"./modules/ethereum/gated-signing/domain/GatedSigningContextLoader\";\nexport * from \"./modules/ethereum/gated-signing/domain/GatedSigningTypedDataContextLoader\";\nexport * from \"./modules/ethereum/model/EthereumClearSignContext\";\nexport * from \"./modules/ethereum/model/TypedDataClearSignContext\";\nexport * from \"./modules/ethereum/model/TypedDataContext\";\nexport * from \"./modules/ethereum/nft/data/HttpNftDataSource\";\nexport * from \"./modules/ethereum/nft/data/NftDataSource\";\nexport * from \"./modules/ethereum/nft/domain/NftContextFieldLoader\";\nexport * from \"./modules/ethereum/nft/domain/NftContextLoader\";\nexport * from \"./modules/ethereum/proxy/data/HttpProxyDataSource\";\nexport * from \"./modules/ethereum/proxy/data/HttpSafeProxyDataSource\";\nexport * from \"./modules/ethereum/proxy/data/ProxyDataSource\";\nexport * from \"./modules/ethereum/proxy/domain/ProxyContextFieldLoader\";\nexport * from \"./modules/ethereum/token/data/HttpTokenDataSource\";\nexport * from \"./modules/ethereum/token/data/TokenDataSource\";\nexport * from \"./modules/ethereum/token/domain/TokenContextFieldLoader\";\nexport * from \"./modules/ethereum/token/domain/TokenContextLoader\";\nexport * from \"./modules/ethereum/trusted-name/data/HttpTrustedNameDataSource\";\nexport * from \"./modules/ethereum/trusted-name/data/TrustedNameDataSource\";\nexport * from \"./modules/ethereum/trusted-name/domain/TrustedNameContextFieldLoader\";\nexport * from \"./modules/ethereum/trusted-name/domain/TrustedNameContextLoader\";\nexport * from \"./modules/ethereum/typed-data/data/HttpTypedDataDataSource\";\nexport * from \"./modules/ethereum/typed-data/data/TypedDataDataSource\";\nexport * from \"./modules/ethereum/typed-data/domain/DefaultTypedDataContextLoader\";\nexport * from \"./modules/ethereum/typed-data/domain/TypedDataContextLoader\";\nexport * from \"./modules/ethereum/typed-data/utils/getSchemaHash\";\nexport * from \"./modules/ethereum/uniswap/data/AbiDecoderDataSource\";\nexport * from \"./modules/ethereum/uniswap/data/CommandDecoderDataSource\";\nexport * from \"./modules/ethereum/uniswap/data/DefaultCommandDecoderDataSource\";\nexport * from \"./modules/ethereum/uniswap/data/EthersAbiDecoderDataSource\";\nexport * from \"./modules/ethereum/uniswap/domain/UniswapContextLoader\";\nexport * from \"./modules/multichain/pki/data/HttpPkiCertificateDataSource\";\nexport * from \"./modules/multichain/pki/data/PkiCertificateDataSource\";\nexport * from \"./modules/multichain/pki/domain/DefaultPkiCertificateLoader\";\nexport * from \"./modules/multichain/pki/domain/PkiCertificateLoader\";\nexport * from \"./modules/multichain/pki/model/KeyId\";\nexport * from \"./modules/multichain/pki/model/KeyUsage\";\nexport * from \"./modules/multichain/pki/model/PkiCertificate\";\nexport * from \"./modules/multichain/pki/model/PkiCertificateInfo\";\nexport * from \"./modules/multichain/reporter/data/BlindSigningReporterDatasource\";\nexport * from \"./modules/multichain/reporter/data/HttpBlindSigningReporterDatasource\";\nexport * from \"./modules/multichain/reporter/domain/BlindSigningReporter\";\nexport * from \"./modules/multichain/reporter/domain/DefaultBlindSigningReporter\";\nexport * from \"./modules/multichain/reporter/model/BlindSigningEvent\";\nexport * from \"./modules/multichain/sign-reporter/model/SignReportParams\";\nexport * from \"./modules/multichain/transaction-check/utils/constants\";\nexport * from \"./modules/solana/alt-resolution/data/AltResolutionDataSource\";\nexport * from \"./modules/solana/alt-resolution/data/HttpAltResolutionDataSource\";\nexport * from \"./modules/solana/alt-resolution/domain/AltResolutionContextLoader\";\nexport * from \"./modules/solana/enum-variant/domain/EnumVariantContextLoader\";\nexport * from \"./modules/solana/instruction-info/data/HttpInstructionInfoDataSource\";\nexport * from \"./modules/solana/instruction-info/data/InstructionInfoDataSource\";\nexport * from \"./modules/solana/instruction-info/domain/InstructionInfoContextLoader\";\nexport * from \"./modules/solana/model/SolanaClearSignContext\";\nexport * from \"./modules/solana/model/SolanaContextTypes\";\nexport * from \"./modules/solana/model/SolanaTransactionScanChainId\";\nexport * from \"./modules/solana/owner-info/data/HttpOwnerInfoDataSource\";\nexport * from \"./modules/solana/owner-info/data/OwnerInfoDataSource\";\nexport * from \"./modules/solana/owner-info/domain/OwnerInfoContextLoader\";\nexport * from \"./modules/solana/owner-info/domain/solanaContextTypes\";\nexport * from \"./modules/solana/token-account-state/data/HttpTokenAccountStateDataSource\";\nexport * from \"./modules/solana/token-account-state/data/TokenAccountStateDataSource\";\nexport * from \"./modules/solana/token-account-state/domain/TokenAccountStateContextLoader\";\nexport * from \"./modules/solana/token-info/data/HttpTokenInfoDataSource\";\nexport * from \"./modules/solana/token-info/data/TokenInfoDataSource\";\nexport * from \"./modules/solana/token-info/domain/TokenInfoContextLoader\";\nexport * from \"./modules/solana/trusted-name/data/HttpTrustedNameDataSource\";\nexport * from \"./modules/solana/trusted-name/data/TrustedNameDataSource\";\nexport * from \"./modules/solana/trusted-name/domain/TrustedNameContextLoader\";\nexport * from \"./modules/tron/model/TronTransactionContext\";\nexport * from \"./shared/domain/ContextFieldLoader\";\nexport * from \"./shared/domain/ContextLoader\";\nexport * from \"./shared/domain/ContextModuleChainID\";\nexport * from \"./shared/model/BlindSigningModelId\";\nexport * from \"./shared/model/ClearSignContext\";\nexport * from \"./shared/model/GenericPath\";\nexport * from \"./shared/model/TransactionSubset\";\n"],
|
|
5
|
-
"mappings": "AAUA,WAAc,kBACd,WAAc,yBACd,WAAc,yBACd,WAAc,yEACd,WAAc,oEACd,WAAc,6EACd,WAAc,8EACd,WAAc,gEACd,WAAc,oEACd,WAAc,2DACd,WAAc,mEACd,WAAc,uEACd,WAAc,wEACd,WAAc,uEACd,WAAc,mEACd,WAAc,uEACd,WAAc,wEACd,WAAc,kEACd,WAAc,sEACd,WAAc,oEACd,WAAc,6EACd,WAAc,oDACd,WAAc,qDACd,WAAc,4CACd,WAAc,gDACd,WAAc,4CACd,WAAc,sDACd,WAAc,iDACd,WAAc,oDACd,WAAc,wDACd,WAAc,gDACd,WAAc,0DACd,WAAc,oDACd,WAAc,gDACd,WAAc,0DACd,WAAc,qDACd,WAAc,iEACd,WAAc,6DACd,WAAc,uEACd,WAAc,kEACd,WAAc,6DACd,WAAc,yDACd,WAAc,qEACd,WAAc,8DACd,WAAc,oDACd,WAAc,uDACd,WAAc,2DACd,WAAc,kEACd,WAAc,6DACd,WAAc,yDACd,WAAc,6DACd,WAAc,yDACd,WAAc,8DACd,WAAc,uDACd,WAAc,uCACd,WAAc,0CACd,WAAc,gDACd,WAAc,oDACd,WAAc,oEACd,WAAc,wEACd,WAAc,4DACd,WAAc,mEACd,WAAc,wDACd,WAAc,4DACd,WAAc,yDACd,WAAc,+DACd,WAAc,mEACd,WAAc,oEACd,WAAc,gEACd,WAAc,uEACd,WAAc,mEACd,WAAc,wEACd,WAAc,gDACd,WAAc,4CACd,WAAc,sDACd,WAAc,2DACd,WAAc,uDACd,WAAc,4DACd,WAAc,wDACd,WAAc,4EACd,WAAc,wEACd,WAAc,6EACd,WAAc,2DACd,WAAc,uDACd,WAAc,4DACd,WAAc,+DACd,WAAc,2DACd,WAAc,gEACd,WAAc,8CACd,WAAc,qCACd,WAAc,gCACd,WAAc,uCACd,WAAc,qCACd,WAAc,kCACd,WAAc,6BACd,WAAc",
|
|
4
|
+
"sourcesContent": ["export type {\n ContextModuleCalBranch,\n ContextModuleCalConfig,\n ContextModuleCalMode,\n ContextModuleConfig,\n ContextModuleDatasourceConfig,\n ContextModuleMetadataServiceConfig,\n ContextModuleReporterConfig,\n ContextModuleWeb3ChecksConfig,\n} from \"./config/model/ContextModuleConfig\";\nexport * from \"./ContextModule\";\nexport * from \"./ContextModuleBuilder\";\nexport * from \"./DefaultContextModule\";\nexport * from \"./modules/concordium/account-ownership/data/AccountOwnershipDataSource\";\nexport * from \"./modules/concordium/account-ownership/data/AccountOwnershipError\";\nexport * from \"./modules/concordium/account-ownership/data/HttpAccountOwnershipDataSource\";\nexport * from \"./modules/concordium/account-ownership/domain/AccountOwnershipContextLoader\";\nexport * from \"./modules/ethereum/calldata/data/CalldataDescriptorDataSource\";\nexport * from \"./modules/ethereum/calldata/data/HttpCalldataDescriptorDataSource\";\nexport * from \"./modules/ethereum/calldata/domain/CalldataContextLoader\";\nexport * from \"./modules/ethereum/dynamic-network/data/DynamicNetworkDataSource\";\nexport * from \"./modules/ethereum/dynamic-network/data/HttpDynamicNetworkDataSource\";\nexport * from \"./modules/ethereum/dynamic-network/domain/DynamicNetworkContextLoader\";\nexport * from \"./modules/ethereum/dynamic-network/model/DynamicNetworkConfiguration\";\nexport * from \"./modules/ethereum/external-plugin/data/ExternalPluginDataSource\";\nexport * from \"./modules/ethereum/external-plugin/data/HttpExternalPluginDataSource\";\nexport * from \"./modules/ethereum/external-plugin/domain/ExternalPluginContextLoader\";\nexport * from \"./modules/ethereum/gated-signing/data/GatedDescriptorDataSource\";\nexport * from \"./modules/ethereum/gated-signing/data/HttpGatedDescriptorDataSource\";\nexport * from \"./modules/ethereum/gated-signing/domain/GatedSigningContextLoader\";\nexport * from \"./modules/ethereum/gated-signing/domain/GatedSigningTypedDataContextLoader\";\nexport * from \"./modules/ethereum/model/EthereumClearSignContext\";\nexport * from \"./modules/ethereum/model/TypedDataClearSignContext\";\nexport * from \"./modules/ethereum/model/TypedDataContext\";\nexport * from \"./modules/ethereum/nft/data/HttpNftDataSource\";\nexport * from \"./modules/ethereum/nft/data/NftDataSource\";\nexport * from \"./modules/ethereum/nft/domain/NftContextFieldLoader\";\nexport * from \"./modules/ethereum/nft/domain/NftContextLoader\";\nexport * from \"./modules/ethereum/proxy/data/HttpProxyDataSource\";\nexport * from \"./modules/ethereum/proxy/data/HttpSafeProxyDataSource\";\nexport * from \"./modules/ethereum/proxy/data/ProxyDataSource\";\nexport * from \"./modules/ethereum/proxy/domain/ProxyContextFieldLoader\";\nexport * from \"./modules/ethereum/token/data/HttpTokenDataSource\";\nexport * from \"./modules/ethereum/token/data/TokenDataSource\";\nexport * from \"./modules/ethereum/token/domain/TokenContextFieldLoader\";\nexport * from \"./modules/ethereum/token/domain/TokenContextLoader\";\nexport * from \"./modules/ethereum/trusted-name/data/HttpTrustedNameDataSource\";\nexport * from \"./modules/ethereum/trusted-name/data/TrustedNameDataSource\";\nexport * from \"./modules/ethereum/trusted-name/domain/TrustedNameContextFieldLoader\";\nexport * from \"./modules/ethereum/trusted-name/domain/TrustedNameContextLoader\";\nexport * from \"./modules/ethereum/typed-data/data/HttpTypedDataDataSource\";\nexport * from \"./modules/ethereum/typed-data/data/TypedDataDataSource\";\nexport * from \"./modules/ethereum/typed-data/domain/DefaultTypedDataContextLoader\";\nexport * from \"./modules/ethereum/typed-data/domain/TypedDataContextLoader\";\nexport * from \"./modules/ethereum/typed-data/utils/getSchemaHash\";\nexport * from \"./modules/ethereum/uniswap/data/AbiDecoderDataSource\";\nexport * from \"./modules/ethereum/uniswap/data/CommandDecoderDataSource\";\nexport * from \"./modules/ethereum/uniswap/data/DefaultCommandDecoderDataSource\";\nexport * from \"./modules/ethereum/uniswap/data/EthersAbiDecoderDataSource\";\nexport * from \"./modules/ethereum/uniswap/domain/UniswapContextLoader\";\nexport * from \"./modules/multichain/pki/data/HttpPkiCertificateDataSource\";\nexport * from \"./modules/multichain/pki/data/PkiCertificateDataSource\";\nexport * from \"./modules/multichain/pki/domain/DefaultPkiCertificateLoader\";\nexport * from \"./modules/multichain/pki/domain/PkiCertificateLoader\";\nexport * from \"./modules/multichain/pki/model/KeyId\";\nexport * from \"./modules/multichain/pki/model/KeyUsage\";\nexport * from \"./modules/multichain/pki/model/PkiCertificate\";\nexport * from \"./modules/multichain/pki/model/PkiCertificateInfo\";\nexport * from \"./modules/multichain/reporter/data/BlindSigningReporterDatasource\";\nexport * from \"./modules/multichain/reporter/data/HttpBlindSigningReporterDatasource\";\nexport * from \"./modules/multichain/reporter/domain/BlindSigningReporter\";\nexport * from \"./modules/multichain/reporter/domain/DefaultBlindSigningReporter\";\nexport * from \"./modules/multichain/reporter/model/BlindSigningEvent\";\nexport * from \"./modules/multichain/sign-reporter/model/SignReportParams\";\nexport * from \"./modules/multichain/transaction-check/utils/constants\";\nexport * from \"./modules/solana/alt-resolution/data/AltResolutionDataSource\";\nexport * from \"./modules/solana/alt-resolution/data/HttpAltResolutionDataSource\";\nexport * from \"./modules/solana/alt-resolution/domain/AltResolutionContextLoader\";\nexport * from \"./modules/solana/enum-variant/domain/EnumVariantContextLoader\";\nexport * from \"./modules/solana/instruction-info/data/HttpInstructionInfoDataSource\";\nexport * from \"./modules/solana/instruction-info/data/InstructionInfoDataSource\";\nexport * from \"./modules/solana/instruction-info/domain/InstructionInfoContextLoader\";\nexport * from \"./modules/solana/instruction-info/domain/SolanaBasicFlowRuleContextLoader\";\nexport * from \"./modules/solana/model/SolanaClearSignContext\";\nexport * from \"./modules/solana/model/SolanaContextTypes\";\nexport * from \"./modules/solana/model/SolanaTransactionScanChainId\";\nexport * from \"./modules/solana/owner-info/data/HttpOwnerInfoDataSource\";\nexport * from \"./modules/solana/owner-info/data/OwnerInfoDataSource\";\nexport * from \"./modules/solana/owner-info/domain/OwnerInfoContextLoader\";\nexport * from \"./modules/solana/owner-info/domain/solanaContextTypes\";\nexport * from \"./modules/solana/token-account-state/data/HttpTokenAccountStateDataSource\";\nexport * from \"./modules/solana/token-account-state/data/TokenAccountStateDataSource\";\nexport * from \"./modules/solana/token-account-state/domain/TokenAccountStateContextLoader\";\nexport * from \"./modules/solana/token-info/data/HttpTokenInfoDataSource\";\nexport * from \"./modules/solana/token-info/data/TokenInfoDataSource\";\nexport * from \"./modules/solana/token-info/domain/TokenInfoContextLoader\";\nexport * from \"./modules/solana/trusted-name/data/HttpTrustedNameDataSource\";\nexport * from \"./modules/solana/trusted-name/data/TrustedNameDataSource\";\nexport * from \"./modules/solana/trusted-name/domain/TrustedNameContextLoader\";\nexport * from \"./modules/tron/model/TronTransactionContext\";\nexport * from \"./shared/domain/ContextFieldLoader\";\nexport * from \"./shared/domain/ContextLoader\";\nexport * from \"./shared/domain/ContextModuleChainID\";\nexport * from \"./shared/model/BlindSigningModelId\";\nexport * from \"./shared/model/ClearSignContext\";\nexport * from \"./shared/model/GenericPath\";\nexport * from \"./shared/model/TransactionSubset\";\n"],
|
|
5
|
+
"mappings": "AAUA,WAAc,kBACd,WAAc,yBACd,WAAc,yBACd,WAAc,yEACd,WAAc,oEACd,WAAc,6EACd,WAAc,8EACd,WAAc,gEACd,WAAc,oEACd,WAAc,2DACd,WAAc,mEACd,WAAc,uEACd,WAAc,wEACd,WAAc,uEACd,WAAc,mEACd,WAAc,uEACd,WAAc,wEACd,WAAc,kEACd,WAAc,sEACd,WAAc,oEACd,WAAc,6EACd,WAAc,oDACd,WAAc,qDACd,WAAc,4CACd,WAAc,gDACd,WAAc,4CACd,WAAc,sDACd,WAAc,iDACd,WAAc,oDACd,WAAc,wDACd,WAAc,gDACd,WAAc,0DACd,WAAc,oDACd,WAAc,gDACd,WAAc,0DACd,WAAc,qDACd,WAAc,iEACd,WAAc,6DACd,WAAc,uEACd,WAAc,kEACd,WAAc,6DACd,WAAc,yDACd,WAAc,qEACd,WAAc,8DACd,WAAc,oDACd,WAAc,uDACd,WAAc,2DACd,WAAc,kEACd,WAAc,6DACd,WAAc,yDACd,WAAc,6DACd,WAAc,yDACd,WAAc,8DACd,WAAc,uDACd,WAAc,uCACd,WAAc,0CACd,WAAc,gDACd,WAAc,oDACd,WAAc,oEACd,WAAc,wEACd,WAAc,4DACd,WAAc,mEACd,WAAc,wDACd,WAAc,4DACd,WAAc,yDACd,WAAc,+DACd,WAAc,mEACd,WAAc,oEACd,WAAc,gEACd,WAAc,uEACd,WAAc,mEACd,WAAc,wEACd,WAAc,4EACd,WAAc,gDACd,WAAc,4CACd,WAAc,sDACd,WAAc,2DACd,WAAc,uDACd,WAAc,4DACd,WAAc,wDACd,WAAc,4EACd,WAAc,wEACd,WAAc,6EACd,WAAc,2DACd,WAAc,uDACd,WAAc,4DACd,WAAc,+DACd,WAAc,2DACd,WAAc,gEACd,WAAc,8CACd,WAAc,qCACd,WAAc,gCACd,WAAc,uCACd,WAAc,qCACd,WAAc,kCACd,WAAc,6BACd,WAAc",
|
|
6
6
|
"names": []
|
|
7
7
|
}
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import{DeviceModelId as d}from"@ledgerhq/device-management-kit";import{Left as f,Right as l}from"purify-ts";import{beforeEach as y,describe as p,expect as a,it as s,vi as n}from"vitest";import{ClearSignContextType as c}from"../../../../shared/model/ClearSignContext";import{EnumVariantContextLoader as R}from"./EnumVariantContextLoader";const N=()=>({debug:n.fn(),info:n.fn(),warn:n.fn(),error:n.fn(),subscribers:[]}),v={keyUsageNumber:8,payload:new Uint8Array([66])},u={cal:{url:"https://global.api.prd.ledger.com/cal/v1",mode:"prod",branch:"main"}},t="JUP6LkbZbjS1jKKwapdHNy74zcZ3tLUZoi5QNyVTaV4",A="OtherProgram111111111111111111111111111111";function I(){return{programId:t,descriptors:{},enumVariants:[{enumId:"swap",variantIndex:46,descriptor:{data:"01_raydium_tlv",signature:"prodsig_v46"}},{enumId:"swap",variantIndex:12,descriptor:{data:"01_orca_tlv",signature:"prodsig_v12"}}]}}p("EnumVariantContextLoader",()=>{let i,m;y(()=>{n.restoreAllMocks(),i={getInstructionInfo:n.fn()},m={loadCertificate:n.fn().mockResolvedValue(v)}});const o=(e=u)=>new R(i,e,m,N);p("canHandle",()=>{s("returns true when SOLANA_ENUM_VARIANT is requested and selections are valid",()=>{a(o().canHandle({deviceModelId:d.NANO_X,selections:[{programId:t,enumId:"swap",variantIndex:46}]},[c.SOLANA_ENUM_VARIANT])).toBe(!0)}),s("returns false when SOLANA_ENUM_VARIANT is not requested",()=>{a(o().canHandle({deviceModelId:d.NANO_X,selections:[{programId:t,enumId:"swap",variantIndex:46}]},[c.SOLANA_INSTRUCTION_INFO])).toBe(!1)}),s.each([-1,65536,1.5,"46",null])("rejects non-u16 variantIndex: %s",e=>{const r=o();a(r.canHandle({deviceModelId:d.NANO_X,selections:[{programId:t,enumId:"swap",variantIndex:e}]},[c.SOLANA_ENUM_VARIANT])).toBe(!1)}),s("rejects empty programId / enumId / selections",()=>{const e=o(),r=[c.SOLANA_ENUM_VARIANT];a(e.canHandle({selections:[]},r)).toBe(!1),a(e.canHandle({selections:[{programId:"",enumId:"swap",variantIndex:1}]},r)).toBe(!1),a(e.canHandle({selections:[{programId:t,enumId:"",variantIndex:1}]},r)).toBe(!1)})}),p("load",()=>{s("emits one SOLANA_ENUM_VARIANT per selection with certificate",async()=>{n.spyOn(i,"getInstructionInfo").mockResolvedValue(l(I()));const e=await o().load({deviceModelId:d.NANO_X,selections:[{programId:t,enumId:"swap",variantIndex:46},{programId:t,enumId:"swap",variantIndex:12}]});a(e).toHaveLength(2),a(e[0]).toMatchObject({type:c.SOLANA_ENUM_VARIANT,payload:{programId:t,enumId:"swap",variantIndex:46,descriptor:{data:"01_raydium_tlv",signature:"prodsig_v46"}},certificate:v}),a(e[1]).toMatchObject({payload:{variantIndex:12,descriptor:{data:"01_orca_tlv",signature:"prodsig_v12"}}})}),s("dedups CAL fetches across selections that share a programId",async()=>{const e=n.spyOn(i,"getInstructionInfo").mockResolvedValue(l(I()));await o().load({deviceModelId:d.NANO_X,selections:[{programId:t,enumId:"swap",variantIndex:46},{programId:t,enumId:"swap",variantIndex:12}]}),a(e).toHaveBeenCalledTimes(1)}),s("resolves a variant index > 255 (u16, disc_kind U16 enums)",async()=>{const e={programId:t,descriptors:{},enumVariants:[{enumId:"swap",variantIndex:300,descriptor:{data:"01_big_tlv",signature:"prodsig_v300"}}]};n.spyOn(i,"getInstructionInfo").mockResolvedValue(l(e));const r=await o().load({deviceModelId:d.NANO_X,selections:[{programId:t,enumId:"swap",variantIndex:300}]});a(r).toHaveLength(1),a(r[0]?.type).toBe(c.SOLANA_ENUM_VARIANT),a(r[0].payload).toMatchObject({variantIndex:300,descriptor:{data:"01_big_tlv",signature:"prodsig_v300"}})}),s("emits ERROR when CAL has no matching variant for a selection",async()=>{n.spyOn(i,"getInstructionInfo").mockResolvedValue(l(I()));const e=await o().load({deviceModelId:d.NANO_X,selections:[{programId:t,enumId:"swap",variantIndex:99}]});a(e).toHaveLength(1),a(e[0]?.type).toBe(c.ERROR),a(e[0].error.message).toMatch(/no enum variant/)}),s("emits ERROR when CAL fetch fails",async()=>{n.spyOn(i,"getInstructionInfo").mockResolvedValue(f(new Error("upstream-500")));const e=await o().load({deviceModelId:d.NANO_X,selections:[{programId:A,enumId:"x",variantIndex:0}]});a(e[0]?.type).toBe(c.ERROR),a(e[0].error.message).toBe("upstream-500")}),s("emits ERROR when configured signature mode is missing",async()=>{const e={programId:t,descriptors:{},enumVariants:[{enumId:"swap",variantIndex:46,descriptor:{data:"01_raydium_tlv",signature:""}}]};n.spyOn(i,"getInstructionInfo").mockResolvedValue(l(e));const g=await o({...u,cal:{...u.cal,mode:"test"}}).load({deviceModelId:d.NANO_X,selections:[{programId:t,enumId:"swap",variantIndex:46}]});a(g[0]?.type).toBe(c.ERROR),a(g[0].error.message).toMatch(/missing 'test' signature/)}),s("degrades every selection to ERROR when certificate loading fails",async()=>{n.spyOn(m,"loadCertificate").mockRejectedValue(new Error("pki-down")),n.spyOn(i,"getInstructionInfo").mockResolvedValue(l(I()));const e=await o().load({deviceModelId:d.NANO_X,selections:[{programId:t,enumId:"swap",variantIndex:46},{programId:t,enumId:"swap",variantIndex:12}]});a(e).toHaveLength(2),a(e.every(r=>r.type===c.ERROR)).toBe(!0)}),s("falls back to default network when input.network is empty / missing",async()=>{const e=n.spyOn(i,"getInstructionInfo").mockResolvedValue(l(I()));await o().load({deviceModelId:d.NANO_X,selections:[{programId:t,enumId:"swap",variantIndex:46}],network:""}),a(e).toHaveBeenCalledWith({programId:t,network:"solana-mainnet"})})})});
|
|
1
|
+
import{DeviceModelId as d}from"@ledgerhq/device-management-kit";import{Left as f,Right as l}from"purify-ts";import{beforeEach as y,describe as p,expect as a,it as s,vi as n}from"vitest";import{ClearSignContextType as c}from"../../../../shared/model/ClearSignContext";import{EnumVariantContextLoader as R}from"./EnumVariantContextLoader";const N=()=>({debug:n.fn(),info:n.fn(),warn:n.fn(),error:n.fn(),subscribers:[]}),v={keyUsageNumber:8,payload:new Uint8Array([66])},u={cal:{url:"https://global.api.prd.ledger.com/cal/v1",mode:"prod",branch:"main"}},t="JUP6LkbZbjS1jKKwapdHNy74zcZ3tLUZoi5QNyVTaV4",A="OtherProgram111111111111111111111111111111";function I(){return{programId:t,descriptors:{},basicFlowTags:[],enumVariants:[{enumId:"swap",variantIndex:46,descriptor:{data:"01_raydium_tlv",signature:"prodsig_v46"}},{enumId:"swap",variantIndex:12,descriptor:{data:"01_orca_tlv",signature:"prodsig_v12"}}]}}p("EnumVariantContextLoader",()=>{let i,m;y(()=>{n.restoreAllMocks(),i={getInstructionInfo:n.fn()},m={loadCertificate:n.fn().mockResolvedValue(v)}});const o=(e=u)=>new R(i,e,m,N);p("canHandle",()=>{s("returns true when SOLANA_ENUM_VARIANT is requested and selections are valid",()=>{a(o().canHandle({deviceModelId:d.NANO_X,selections:[{programId:t,enumId:"swap",variantIndex:46}]},[c.SOLANA_ENUM_VARIANT])).toBe(!0)}),s("returns false when SOLANA_ENUM_VARIANT is not requested",()=>{a(o().canHandle({deviceModelId:d.NANO_X,selections:[{programId:t,enumId:"swap",variantIndex:46}]},[c.SOLANA_INSTRUCTION_INFO])).toBe(!1)}),s.each([-1,65536,1.5,"46",null])("rejects non-u16 variantIndex: %s",e=>{const r=o();a(r.canHandle({deviceModelId:d.NANO_X,selections:[{programId:t,enumId:"swap",variantIndex:e}]},[c.SOLANA_ENUM_VARIANT])).toBe(!1)}),s("rejects empty programId / enumId / selections",()=>{const e=o(),r=[c.SOLANA_ENUM_VARIANT];a(e.canHandle({selections:[]},r)).toBe(!1),a(e.canHandle({selections:[{programId:"",enumId:"swap",variantIndex:1}]},r)).toBe(!1),a(e.canHandle({selections:[{programId:t,enumId:"",variantIndex:1}]},r)).toBe(!1)})}),p("load",()=>{s("emits one SOLANA_ENUM_VARIANT per selection with certificate",async()=>{n.spyOn(i,"getInstructionInfo").mockResolvedValue(l(I()));const e=await o().load({deviceModelId:d.NANO_X,selections:[{programId:t,enumId:"swap",variantIndex:46},{programId:t,enumId:"swap",variantIndex:12}]});a(e).toHaveLength(2),a(e[0]).toMatchObject({type:c.SOLANA_ENUM_VARIANT,payload:{programId:t,enumId:"swap",variantIndex:46,descriptor:{data:"01_raydium_tlv",signature:"prodsig_v46"}},certificate:v}),a(e[1]).toMatchObject({payload:{variantIndex:12,descriptor:{data:"01_orca_tlv",signature:"prodsig_v12"}}})}),s("dedups CAL fetches across selections that share a programId",async()=>{const e=n.spyOn(i,"getInstructionInfo").mockResolvedValue(l(I()));await o().load({deviceModelId:d.NANO_X,selections:[{programId:t,enumId:"swap",variantIndex:46},{programId:t,enumId:"swap",variantIndex:12}]}),a(e).toHaveBeenCalledTimes(1)}),s("resolves a variant index > 255 (u16, disc_kind U16 enums)",async()=>{const e={programId:t,descriptors:{},basicFlowTags:[],enumVariants:[{enumId:"swap",variantIndex:300,descriptor:{data:"01_big_tlv",signature:"prodsig_v300"}}]};n.spyOn(i,"getInstructionInfo").mockResolvedValue(l(e));const r=await o().load({deviceModelId:d.NANO_X,selections:[{programId:t,enumId:"swap",variantIndex:300}]});a(r).toHaveLength(1),a(r[0]?.type).toBe(c.SOLANA_ENUM_VARIANT),a(r[0].payload).toMatchObject({variantIndex:300,descriptor:{data:"01_big_tlv",signature:"prodsig_v300"}})}),s("emits ERROR when CAL has no matching variant for a selection",async()=>{n.spyOn(i,"getInstructionInfo").mockResolvedValue(l(I()));const e=await o().load({deviceModelId:d.NANO_X,selections:[{programId:t,enumId:"swap",variantIndex:99}]});a(e).toHaveLength(1),a(e[0]?.type).toBe(c.ERROR),a(e[0].error.message).toMatch(/no enum variant/)}),s("emits ERROR when CAL fetch fails",async()=>{n.spyOn(i,"getInstructionInfo").mockResolvedValue(f(new Error("upstream-500")));const e=await o().load({deviceModelId:d.NANO_X,selections:[{programId:A,enumId:"x",variantIndex:0}]});a(e[0]?.type).toBe(c.ERROR),a(e[0].error.message).toBe("upstream-500")}),s("emits ERROR when configured signature mode is missing",async()=>{const e={programId:t,descriptors:{},basicFlowTags:[],enumVariants:[{enumId:"swap",variantIndex:46,descriptor:{data:"01_raydium_tlv",signature:""}}]};n.spyOn(i,"getInstructionInfo").mockResolvedValue(l(e));const g=await o({...u,cal:{...u.cal,mode:"test"}}).load({deviceModelId:d.NANO_X,selections:[{programId:t,enumId:"swap",variantIndex:46}]});a(g[0]?.type).toBe(c.ERROR),a(g[0].error.message).toMatch(/missing 'test' signature/)}),s("degrades every selection to ERROR when certificate loading fails",async()=>{n.spyOn(m,"loadCertificate").mockRejectedValue(new Error("pki-down")),n.spyOn(i,"getInstructionInfo").mockResolvedValue(l(I()));const e=await o().load({deviceModelId:d.NANO_X,selections:[{programId:t,enumId:"swap",variantIndex:46},{programId:t,enumId:"swap",variantIndex:12}]});a(e).toHaveLength(2),a(e.every(r=>r.type===c.ERROR)).toBe(!0)}),s("falls back to default network when input.network is empty / missing",async()=>{const e=n.spyOn(i,"getInstructionInfo").mockResolvedValue(l(I()));await o().load({deviceModelId:d.NANO_X,selections:[{programId:t,enumId:"swap",variantIndex:46}],network:""}),a(e).toHaveBeenCalledWith({programId:t,network:"solana-mainnet"})})})});
|
|
2
2
|
//# sourceMappingURL=EnumVariantContextLoader.test.js.map
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"version": 3,
|
|
3
3
|
"sources": ["../../../../../../../src/modules/solana/enum-variant/domain/EnumVariantContextLoader.test.ts"],
|
|
4
|
-
"sourcesContent": ["/* eslint-disable @typescript-eslint/no-explicit-any */\nimport { DeviceModelId } from \"@ledgerhq/device-management-kit\";\nimport { Left, Right } from \"purify-ts\";\nimport { beforeEach, describe, expect, it, vi } from \"vitest\";\n\nimport { type ContextModuleServiceConfig } from \"@/config/model/ContextModuleConfig\";\nimport { type PkiCertificateLoader } from \"@/modules/multichain/pki/domain/PkiCertificateLoader\";\nimport {\n type InstructionInfoDataSource,\n type InstructionInfoResult,\n} from \"@/modules/solana/instruction-info/data/InstructionInfoDataSource\";\nimport { ClearSignContextType } from \"@/shared/model/ClearSignContext\";\n\nimport { EnumVariantContextLoader } from \"./EnumVariantContextLoader\";\n\nconst mockLoggerFactory = () => ({\n debug: vi.fn(),\n info: vi.fn(),\n warn: vi.fn(),\n error: vi.fn(),\n subscribers: [],\n});\n\nconst mockCertificate = {\n keyUsageNumber: 8,\n payload: new Uint8Array([0x42]),\n};\n\nconst mockConfig = {\n cal: {\n url: \"https://global.api.prd.ledger.com/cal/v1\",\n mode: \"prod\",\n branch: \"main\",\n },\n} as ContextModuleServiceConfig;\n\nconst JUPITER_PROGRAM = \"JUP6LkbZbjS1jKKwapdHNy74zcZ3tLUZoi5QNyVTaV4\";\nconst OTHER_PROGRAM = \"OtherProgram111111111111111111111111111111\";\n\n// The data source flattens enum variants into core models, with the signature\n// already picked for the configured mode.\nfunction makeJupiterWithVariants(): InstructionInfoResult {\n return {\n programId: JUPITER_PROGRAM,\n descriptors: {},\n enumVariants: [\n {\n enumId: \"swap\",\n variantIndex: 46,\n descriptor: { data: \"01_raydium_tlv\", signature: \"prodsig_v46\" },\n },\n {\n enumId: \"swap\",\n variantIndex: 12,\n descriptor: { data: \"01_orca_tlv\", signature: \"prodsig_v12\" },\n },\n ],\n };\n}\n\ndescribe(\"EnumVariantContextLoader\", () => {\n let dataSource: InstructionInfoDataSource;\n let certificateLoader: PkiCertificateLoader;\n\n beforeEach(() => {\n vi.restoreAllMocks();\n dataSource = {\n getInstructionInfo: vi.fn(),\n };\n certificateLoader = {\n loadCertificate: vi.fn().mockResolvedValue(mockCertificate),\n };\n });\n\n const makeLoader = (config = mockConfig) =>\n new EnumVariantContextLoader(\n dataSource,\n config,\n certificateLoader,\n mockLoggerFactory,\n );\n\n describe(\"canHandle\", () => {\n it(\"returns true when SOLANA_ENUM_VARIANT is requested and selections are valid\", () => {\n expect(\n makeLoader().canHandle(\n {\n deviceModelId: DeviceModelId.NANO_X,\n selections: [\n {\n programId: JUPITER_PROGRAM,\n enumId: \"swap\",\n variantIndex: 46,\n },\n ],\n },\n [ClearSignContextType.SOLANA_ENUM_VARIANT],\n ),\n ).toBe(true);\n });\n\n it(\"returns false when SOLANA_ENUM_VARIANT is not requested\", () => {\n expect(\n makeLoader().canHandle(\n {\n deviceModelId: DeviceModelId.NANO_X,\n selections: [\n { programId: JUPITER_PROGRAM, enumId: \"swap\", variantIndex: 46 },\n ],\n },\n [ClearSignContextType.SOLANA_INSTRUCTION_INFO],\n ),\n ).toBe(false);\n });\n\n it.each([-1, 65536, 1.5, \"46\", null])(\n \"rejects non-u16 variantIndex: %s\",\n (badIndex) => {\n const loader = makeLoader();\n expect(\n loader.canHandle(\n {\n deviceModelId: DeviceModelId.NANO_X,\n selections: [\n {\n programId: JUPITER_PROGRAM,\n enumId: \"swap\",\n variantIndex: badIndex,\n },\n ],\n } as any,\n [ClearSignContextType.SOLANA_ENUM_VARIANT],\n ),\n ).toBe(false);\n },\n );\n\n it(\"rejects empty programId / enumId / selections\", () => {\n const loader = makeLoader();\n const types = [ClearSignContextType.SOLANA_ENUM_VARIANT];\n expect(loader.canHandle({ selections: [] } as any, types)).toBe(false);\n expect(\n loader.canHandle(\n {\n selections: [{ programId: \"\", enumId: \"swap\", variantIndex: 1 }],\n } as any,\n types,\n ),\n ).toBe(false);\n expect(\n loader.canHandle(\n {\n selections: [\n { programId: JUPITER_PROGRAM, enumId: \"\", variantIndex: 1 },\n ],\n } as any,\n types,\n ),\n ).toBe(false);\n });\n });\n\n describe(\"load\", () => {\n it(\"emits one SOLANA_ENUM_VARIANT per selection with certificate\", async () => {\n vi.spyOn(dataSource, \"getInstructionInfo\").mockResolvedValue(\n Right(makeJupiterWithVariants()),\n );\n\n const result = await makeLoader().load({\n deviceModelId: DeviceModelId.NANO_X,\n selections: [\n { programId: JUPITER_PROGRAM, enumId: \"swap\", variantIndex: 46 },\n { programId: JUPITER_PROGRAM, enumId: \"swap\", variantIndex: 12 },\n ],\n });\n\n expect(result).toHaveLength(2);\n expect(result[0]).toMatchObject({\n type: ClearSignContextType.SOLANA_ENUM_VARIANT,\n payload: {\n programId: JUPITER_PROGRAM,\n enumId: \"swap\",\n variantIndex: 46,\n descriptor: { data: \"01_raydium_tlv\", signature: \"prodsig_v46\" },\n },\n certificate: mockCertificate,\n });\n expect(result[1]).toMatchObject({\n payload: {\n variantIndex: 12,\n descriptor: { data: \"01_orca_tlv\", signature: \"prodsig_v12\" },\n },\n });\n });\n\n it(\"dedups CAL fetches across selections that share a programId\", async () => {\n const spy = vi\n .spyOn(dataSource, \"getInstructionInfo\")\n .mockResolvedValue(Right(makeJupiterWithVariants()));\n\n await makeLoader().load({\n deviceModelId: DeviceModelId.NANO_X,\n selections: [\n { programId: JUPITER_PROGRAM, enumId: \"swap\", variantIndex: 46 },\n { programId: JUPITER_PROGRAM, enumId: \"swap\", variantIndex: 12 },\n ],\n });\n\n expect(spy).toHaveBeenCalledTimes(1);\n });\n\n it(\"resolves a variant index > 255 (u16, disc_kind U16 enums)\", async () => {\n const result: InstructionInfoResult = {\n programId: JUPITER_PROGRAM,\n descriptors: {},\n enumVariants: [\n {\n enumId: \"swap\",\n variantIndex: 300,\n descriptor: { data: \"01_big_tlv\", signature: \"prodsig_v300\" },\n },\n ],\n };\n vi.spyOn(dataSource, \"getInstructionInfo\").mockResolvedValue(\n Right(result),\n );\n\n const out = await makeLoader().load({\n deviceModelId: DeviceModelId.NANO_X,\n selections: [\n { programId: JUPITER_PROGRAM, enumId: \"swap\", variantIndex: 300 },\n ],\n });\n\n expect(out).toHaveLength(1);\n expect(out[0]?.type).toBe(ClearSignContextType.SOLANA_ENUM_VARIANT);\n expect((out[0] as any).payload).toMatchObject({\n variantIndex: 300,\n descriptor: { data: \"01_big_tlv\", signature: \"prodsig_v300\" },\n });\n });\n\n it(\"emits ERROR when CAL has no matching variant for a selection\", async () => {\n vi.spyOn(dataSource, \"getInstructionInfo\").mockResolvedValue(\n Right(makeJupiterWithVariants()),\n );\n\n const result = await makeLoader().load({\n deviceModelId: DeviceModelId.NANO_X,\n selections: [\n { programId: JUPITER_PROGRAM, enumId: \"swap\", variantIndex: 99 },\n ],\n });\n\n expect(result).toHaveLength(1);\n expect(result[0]?.type).toBe(ClearSignContextType.ERROR);\n expect((result[0] as any).error.message).toMatch(/no enum variant/);\n });\n\n it(\"emits ERROR when CAL fetch fails\", async () => {\n vi.spyOn(dataSource, \"getInstructionInfo\").mockResolvedValue(\n Left(new Error(\"upstream-500\")),\n );\n\n const result = await makeLoader().load({\n deviceModelId: DeviceModelId.NANO_X,\n selections: [\n { programId: OTHER_PROGRAM, enumId: \"x\", variantIndex: 0 },\n ],\n });\n\n expect(result[0]?.type).toBe(ClearSignContextType.ERROR);\n expect((result[0] as any).error.message).toBe(\"upstream-500\");\n });\n\n it(\"emits ERROR when configured signature mode is missing\", async () => {\n // The mapper leaves the signature empty when CAL has none for the mode.\n const result: InstructionInfoResult = {\n programId: JUPITER_PROGRAM,\n descriptors: {},\n enumVariants: [\n {\n enumId: \"swap\",\n variantIndex: 46,\n descriptor: { data: \"01_raydium_tlv\", signature: \"\" },\n },\n ],\n };\n vi.spyOn(dataSource, \"getInstructionInfo\").mockResolvedValue(\n Right(result),\n );\n\n const loader = makeLoader({\n ...mockConfig,\n cal: { ...mockConfig.cal, mode: \"test\" },\n } as any);\n\n const out = await loader.load({\n deviceModelId: DeviceModelId.NANO_X,\n selections: [\n { programId: JUPITER_PROGRAM, enumId: \"swap\", variantIndex: 46 },\n ],\n });\n\n expect(out[0]?.type).toBe(ClearSignContextType.ERROR);\n expect((out[0] as any).error.message).toMatch(/missing 'test' signature/);\n });\n\n it(\"degrades every selection to ERROR when certificate loading fails\", async () => {\n vi.spyOn(certificateLoader, \"loadCertificate\").mockRejectedValue(\n new Error(\"pki-down\"),\n );\n // Data fetches run in parallel with cert load; resolve so awaits settle.\n vi.spyOn(dataSource, \"getInstructionInfo\").mockResolvedValue(\n Right(makeJupiterWithVariants()),\n );\n\n const out = await makeLoader().load({\n deviceModelId: DeviceModelId.NANO_X,\n selections: [\n { programId: JUPITER_PROGRAM, enumId: \"swap\", variantIndex: 46 },\n { programId: JUPITER_PROGRAM, enumId: \"swap\", variantIndex: 12 },\n ],\n });\n\n expect(out).toHaveLength(2);\n expect(out.every((c) => c.type === ClearSignContextType.ERROR)).toBe(\n true,\n );\n });\n\n it(\"falls back to default network when input.network is empty / missing\", async () => {\n const spy = vi\n .spyOn(dataSource, \"getInstructionInfo\")\n .mockResolvedValue(Right(makeJupiterWithVariants()));\n\n await makeLoader().load({\n deviceModelId: DeviceModelId.NANO_X,\n selections: [\n { programId: JUPITER_PROGRAM, enumId: \"swap\", variantIndex: 46 },\n ],\n network: \"\",\n });\n\n expect(spy).toHaveBeenCalledWith({\n programId: JUPITER_PROGRAM,\n network: \"solana-mainnet\",\n });\n });\n });\n});\n"],
|
|
5
|
-
"mappings": "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",
|
|
4
|
+
"sourcesContent": ["/* eslint-disable @typescript-eslint/no-explicit-any */\nimport { DeviceModelId } from \"@ledgerhq/device-management-kit\";\nimport { Left, Right } from \"purify-ts\";\nimport { beforeEach, describe, expect, it, vi } from \"vitest\";\n\nimport { type ContextModuleServiceConfig } from \"@/config/model/ContextModuleConfig\";\nimport { type PkiCertificateLoader } from \"@/modules/multichain/pki/domain/PkiCertificateLoader\";\nimport {\n type InstructionInfoDataSource,\n type InstructionInfoResult,\n} from \"@/modules/solana/instruction-info/data/InstructionInfoDataSource\";\nimport { ClearSignContextType } from \"@/shared/model/ClearSignContext\";\n\nimport { EnumVariantContextLoader } from \"./EnumVariantContextLoader\";\n\nconst mockLoggerFactory = () => ({\n debug: vi.fn(),\n info: vi.fn(),\n warn: vi.fn(),\n error: vi.fn(),\n subscribers: [],\n});\n\nconst mockCertificate = {\n keyUsageNumber: 8,\n payload: new Uint8Array([0x42]),\n};\n\nconst mockConfig = {\n cal: {\n url: \"https://global.api.prd.ledger.com/cal/v1\",\n mode: \"prod\",\n branch: \"main\",\n },\n} as ContextModuleServiceConfig;\n\nconst JUPITER_PROGRAM = \"JUP6LkbZbjS1jKKwapdHNy74zcZ3tLUZoi5QNyVTaV4\";\nconst OTHER_PROGRAM = \"OtherProgram111111111111111111111111111111\";\n\n// The data source flattens enum variants into core models, with the signature\n// already picked for the configured mode.\nfunction makeJupiterWithVariants(): InstructionInfoResult {\n return {\n programId: JUPITER_PROGRAM,\n descriptors: {},\n basicFlowTags: [],\n enumVariants: [\n {\n enumId: \"swap\",\n variantIndex: 46,\n descriptor: { data: \"01_raydium_tlv\", signature: \"prodsig_v46\" },\n },\n {\n enumId: \"swap\",\n variantIndex: 12,\n descriptor: { data: \"01_orca_tlv\", signature: \"prodsig_v12\" },\n },\n ],\n };\n}\n\ndescribe(\"EnumVariantContextLoader\", () => {\n let dataSource: InstructionInfoDataSource;\n let certificateLoader: PkiCertificateLoader;\n\n beforeEach(() => {\n vi.restoreAllMocks();\n dataSource = {\n getInstructionInfo: vi.fn(),\n };\n certificateLoader = {\n loadCertificate: vi.fn().mockResolvedValue(mockCertificate),\n };\n });\n\n const makeLoader = (config = mockConfig) =>\n new EnumVariantContextLoader(\n dataSource,\n config,\n certificateLoader,\n mockLoggerFactory,\n );\n\n describe(\"canHandle\", () => {\n it(\"returns true when SOLANA_ENUM_VARIANT is requested and selections are valid\", () => {\n expect(\n makeLoader().canHandle(\n {\n deviceModelId: DeviceModelId.NANO_X,\n selections: [\n {\n programId: JUPITER_PROGRAM,\n enumId: \"swap\",\n variantIndex: 46,\n },\n ],\n },\n [ClearSignContextType.SOLANA_ENUM_VARIANT],\n ),\n ).toBe(true);\n });\n\n it(\"returns false when SOLANA_ENUM_VARIANT is not requested\", () => {\n expect(\n makeLoader().canHandle(\n {\n deviceModelId: DeviceModelId.NANO_X,\n selections: [\n { programId: JUPITER_PROGRAM, enumId: \"swap\", variantIndex: 46 },\n ],\n },\n [ClearSignContextType.SOLANA_INSTRUCTION_INFO],\n ),\n ).toBe(false);\n });\n\n it.each([-1, 65536, 1.5, \"46\", null])(\n \"rejects non-u16 variantIndex: %s\",\n (badIndex) => {\n const loader = makeLoader();\n expect(\n loader.canHandle(\n {\n deviceModelId: DeviceModelId.NANO_X,\n selections: [\n {\n programId: JUPITER_PROGRAM,\n enumId: \"swap\",\n variantIndex: badIndex,\n },\n ],\n } as any,\n [ClearSignContextType.SOLANA_ENUM_VARIANT],\n ),\n ).toBe(false);\n },\n );\n\n it(\"rejects empty programId / enumId / selections\", () => {\n const loader = makeLoader();\n const types = [ClearSignContextType.SOLANA_ENUM_VARIANT];\n expect(loader.canHandle({ selections: [] } as any, types)).toBe(false);\n expect(\n loader.canHandle(\n {\n selections: [{ programId: \"\", enumId: \"swap\", variantIndex: 1 }],\n } as any,\n types,\n ),\n ).toBe(false);\n expect(\n loader.canHandle(\n {\n selections: [\n { programId: JUPITER_PROGRAM, enumId: \"\", variantIndex: 1 },\n ],\n } as any,\n types,\n ),\n ).toBe(false);\n });\n });\n\n describe(\"load\", () => {\n it(\"emits one SOLANA_ENUM_VARIANT per selection with certificate\", async () => {\n vi.spyOn(dataSource, \"getInstructionInfo\").mockResolvedValue(\n Right(makeJupiterWithVariants()),\n );\n\n const result = await makeLoader().load({\n deviceModelId: DeviceModelId.NANO_X,\n selections: [\n { programId: JUPITER_PROGRAM, enumId: \"swap\", variantIndex: 46 },\n { programId: JUPITER_PROGRAM, enumId: \"swap\", variantIndex: 12 },\n ],\n });\n\n expect(result).toHaveLength(2);\n expect(result[0]).toMatchObject({\n type: ClearSignContextType.SOLANA_ENUM_VARIANT,\n payload: {\n programId: JUPITER_PROGRAM,\n enumId: \"swap\",\n variantIndex: 46,\n descriptor: { data: \"01_raydium_tlv\", signature: \"prodsig_v46\" },\n },\n certificate: mockCertificate,\n });\n expect(result[1]).toMatchObject({\n payload: {\n variantIndex: 12,\n descriptor: { data: \"01_orca_tlv\", signature: \"prodsig_v12\" },\n },\n });\n });\n\n it(\"dedups CAL fetches across selections that share a programId\", async () => {\n const spy = vi\n .spyOn(dataSource, \"getInstructionInfo\")\n .mockResolvedValue(Right(makeJupiterWithVariants()));\n\n await makeLoader().load({\n deviceModelId: DeviceModelId.NANO_X,\n selections: [\n { programId: JUPITER_PROGRAM, enumId: \"swap\", variantIndex: 46 },\n { programId: JUPITER_PROGRAM, enumId: \"swap\", variantIndex: 12 },\n ],\n });\n\n expect(spy).toHaveBeenCalledTimes(1);\n });\n\n it(\"resolves a variant index > 255 (u16, disc_kind U16 enums)\", async () => {\n const result: InstructionInfoResult = {\n programId: JUPITER_PROGRAM,\n descriptors: {},\n basicFlowTags: [],\n enumVariants: [\n {\n enumId: \"swap\",\n variantIndex: 300,\n descriptor: { data: \"01_big_tlv\", signature: \"prodsig_v300\" },\n },\n ],\n };\n vi.spyOn(dataSource, \"getInstructionInfo\").mockResolvedValue(\n Right(result),\n );\n\n const out = await makeLoader().load({\n deviceModelId: DeviceModelId.NANO_X,\n selections: [\n { programId: JUPITER_PROGRAM, enumId: \"swap\", variantIndex: 300 },\n ],\n });\n\n expect(out).toHaveLength(1);\n expect(out[0]?.type).toBe(ClearSignContextType.SOLANA_ENUM_VARIANT);\n expect((out[0] as any).payload).toMatchObject({\n variantIndex: 300,\n descriptor: { data: \"01_big_tlv\", signature: \"prodsig_v300\" },\n });\n });\n\n it(\"emits ERROR when CAL has no matching variant for a selection\", async () => {\n vi.spyOn(dataSource, \"getInstructionInfo\").mockResolvedValue(\n Right(makeJupiterWithVariants()),\n );\n\n const result = await makeLoader().load({\n deviceModelId: DeviceModelId.NANO_X,\n selections: [\n { programId: JUPITER_PROGRAM, enumId: \"swap\", variantIndex: 99 },\n ],\n });\n\n expect(result).toHaveLength(1);\n expect(result[0]?.type).toBe(ClearSignContextType.ERROR);\n expect((result[0] as any).error.message).toMatch(/no enum variant/);\n });\n\n it(\"emits ERROR when CAL fetch fails\", async () => {\n vi.spyOn(dataSource, \"getInstructionInfo\").mockResolvedValue(\n Left(new Error(\"upstream-500\")),\n );\n\n const result = await makeLoader().load({\n deviceModelId: DeviceModelId.NANO_X,\n selections: [\n { programId: OTHER_PROGRAM, enumId: \"x\", variantIndex: 0 },\n ],\n });\n\n expect(result[0]?.type).toBe(ClearSignContextType.ERROR);\n expect((result[0] as any).error.message).toBe(\"upstream-500\");\n });\n\n it(\"emits ERROR when configured signature mode is missing\", async () => {\n // The mapper leaves the signature empty when CAL has none for the mode.\n const result: InstructionInfoResult = {\n programId: JUPITER_PROGRAM,\n descriptors: {},\n basicFlowTags: [],\n enumVariants: [\n {\n enumId: \"swap\",\n variantIndex: 46,\n descriptor: { data: \"01_raydium_tlv\", signature: \"\" },\n },\n ],\n };\n vi.spyOn(dataSource, \"getInstructionInfo\").mockResolvedValue(\n Right(result),\n );\n\n const loader = makeLoader({\n ...mockConfig,\n cal: { ...mockConfig.cal, mode: \"test\" },\n } as any);\n\n const out = await loader.load({\n deviceModelId: DeviceModelId.NANO_X,\n selections: [\n { programId: JUPITER_PROGRAM, enumId: \"swap\", variantIndex: 46 },\n ],\n });\n\n expect(out[0]?.type).toBe(ClearSignContextType.ERROR);\n expect((out[0] as any).error.message).toMatch(/missing 'test' signature/);\n });\n\n it(\"degrades every selection to ERROR when certificate loading fails\", async () => {\n vi.spyOn(certificateLoader, \"loadCertificate\").mockRejectedValue(\n new Error(\"pki-down\"),\n );\n // Data fetches run in parallel with cert load; resolve so awaits settle.\n vi.spyOn(dataSource, \"getInstructionInfo\").mockResolvedValue(\n Right(makeJupiterWithVariants()),\n );\n\n const out = await makeLoader().load({\n deviceModelId: DeviceModelId.NANO_X,\n selections: [\n { programId: JUPITER_PROGRAM, enumId: \"swap\", variantIndex: 46 },\n { programId: JUPITER_PROGRAM, enumId: \"swap\", variantIndex: 12 },\n ],\n });\n\n expect(out).toHaveLength(2);\n expect(out.every((c) => c.type === ClearSignContextType.ERROR)).toBe(\n true,\n );\n });\n\n it(\"falls back to default network when input.network is empty / missing\", async () => {\n const spy = vi\n .spyOn(dataSource, \"getInstructionInfo\")\n .mockResolvedValue(Right(makeJupiterWithVariants()));\n\n await makeLoader().load({\n deviceModelId: DeviceModelId.NANO_X,\n selections: [\n { programId: JUPITER_PROGRAM, enumId: \"swap\", variantIndex: 46 },\n ],\n network: \"\",\n });\n\n expect(spy).toHaveBeenCalledWith({\n programId: JUPITER_PROGRAM,\n network: \"solana-mainnet\",\n });\n });\n });\n});\n"],
|
|
5
|
+
"mappings": "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",
|
|
6
6
|
"names": ["DeviceModelId", "Left", "Right", "beforeEach", "describe", "expect", "it", "vi", "ClearSignContextType", "EnumVariantContextLoader", "mockLoggerFactory", "mockCertificate", "mockConfig", "JUPITER_PROGRAM", "OTHER_PROGRAM", "makeJupiterWithVariants", "dataSource", "certificateLoader", "makeLoader", "config", "badIndex", "loader", "types", "result", "spy", "out", "c"]
|
|
7
7
|
}
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
var
|
|
1
|
+
var C=Object.defineProperty;var g=Object.getOwnPropertyDescriptor;var I=(u,t,r,o)=>{for(var e=o>1?void 0:o?g(t,r):t,n=u.length-1,i;n>=0;n--)(i=u[n])&&(e=(o?i(t,r,e):i(e))||e);return o&&e&&C(t,r,e),e},p=(u,t)=>(r,o)=>t(r,o,u);import{inject as E,injectable as y}from"inversify";import{Left as f,Right as w}from"purify-ts";import{configTypes as S}from"../../../../config/di/configTypes";import{SolanaTransactionScanChainId as h}from"../../../../modules/solana/model/SolanaTransactionScanChainId";import{networkTypes as T}from"../../../../shared/network/di/networkTypes";import{SolanaProgramNotFoundError as d}from"./InstructionInfoDataSource";import{calInstructionProgramCodec as D}from"./InstructionInfoDto";import{toBasicFlowTags as v,toInstructionInfoPayload as x,toProgramEnumVariants as M}from"./InstructionInfoMapper";const N={"solana-mainnet":h.MAINNET,"solana-devnet":h.DEVNET,"solana-testnet":h.TESTNET},R=3e4,b=64;let l=class{constructor(t,r){this.config=t;this.http=r}cache=new Map;getInstructionInfo({programId:t,network:r}){const o=N[r]??h.MAINNET,e=`${o}:${t}`,n=Date.now(),i=this.cache.get(e);if(i!==void 0&&i.expiresAt>n)return i.result;const s=this.fetchInstructionInfo(t,o);if(this.cache.delete(e),this.cache.size>=b){const c=this.cache.keys().next();c.done||this.cache.delete(c.value)}return this.cache.set(e,{expiresAt:n+R,result:s}),s.then(c=>{c.caseOf({Left:m=>m instanceof d,Right:()=>!0})||this.evict(e,s)},()=>this.evict(e,s)),s}evict(t,r){this.cache.get(t)?.result===r&&this.cache.delete(t)}async fetchInstructionInfo(t,r){let o;try{o=await this.http.get(`${this.config.cal.url}/solana_programs`,{params:{id:t,chain_id:r,output:"id,chain_id,instructions",ref:`branch:${this.config.cal.branch}`}})}catch(n){const i=n instanceof Error?n.message:String(n);return f(new Error(`[ContextModule] HttpInstructionInfoDataSource: Failed to fetch instruction descriptors: ${i}`))}if(!Array.isArray(o))return f(new Error(`[ContextModule] HttpInstructionInfoDataSource: unexpected response for program ${t}`));if(o.length===0)return f(new d(t,`[ContextModule] HttpInstructionInfoDataSource: empty response for program ${t}`));const e=o.find(n=>n!=null&&typeof n=="object"&&n.id===t);return e===void 0?f(new d(t,`[ContextModule] HttpInstructionInfoDataSource: no descriptors for program ${t}`)):D.decode(e).caseOf({Left:n=>f(new Error(`[ContextModule] HttpInstructionInfoDataSource: malformed descriptors for program ${t}: ${n}`)),Right:()=>{const n=this.config.cal.mode??"prod",i=e.instructions,s=Object.fromEntries(i.map(a=>[a.discriminator_hex??"",a])),c=Object.fromEntries(Object.entries(s).map(([a,m])=>[a,x(t,a,m,n)]));return w({programId:t,descriptors:c,enumVariants:M(s,n),basicFlowTags:v(s)})}})}};l=I([y(),p(0,E(S.Config)),p(1,E(T.NetworkClient))],l);export{l as HttpInstructionInfoDataSource};
|
|
2
2
|
//# sourceMappingURL=HttpInstructionInfoDataSource.js.map
|
package/lib/esm/src/modules/solana/instruction-info/data/HttpInstructionInfoDataSource.js.map
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"version": 3,
|
|
3
3
|
"sources": ["../../../../../../../src/modules/solana/instruction-info/data/HttpInstructionInfoDataSource.ts"],
|
|
4
|
-
"sourcesContent": ["import { DmkNetworkClient } from \"@ledgerhq/device-management-kit\";\nimport { inject, injectable } from \"inversify\";\nimport { Either, Left, Right } from \"purify-ts\";\n\nimport { configTypes } from \"@/config/di/configTypes\";\nimport { type ContextModuleServiceConfig } from \"@/config/model/ContextModuleConfig\";\nimport { SolanaTransactionScanChainId } from \"@/modules/solana/model/SolanaTransactionScanChainId\";\nimport { networkTypes } from \"@/shared/network/di/networkTypes\";\n\nimport {\n GetInstructionInfoParams,\n InstructionInfoDataSource,\n InstructionInfoResult,\n} from \"./InstructionInfoDataSource\";\nimport {\n type CalInstructionDescriptorDto,\n calInstructionProgramCodec,\n type CalInstructionProgramDto,\n} from \"./InstructionInfoDto\";\nimport {\n type CalMode,\n toInstructionInfoPayload,\n toProgramEnumVariants,\n} from \"./InstructionInfoMapper\";\n\n// Maps the DMK network label to the numeric CAL `chain_id` (the extended\n// Solana network ids 900/901/902). Unknown labels fall back to mainnet.\nconst CHAIN_ID_BY_NETWORK: Record<string, SolanaTransactionScanChainId> = {\n \"solana-mainnet\": SolanaTransactionScanChainId.MAINNET,\n \"solana-devnet\": SolanaTransactionScanChainId.DEVNET,\n \"solana-testnet\": SolanaTransactionScanChainId.TESTNET,\n};\n\n@injectable()\nexport class HttpInstructionInfoDataSource\n implements InstructionInfoDataSource\n{\n constructor(\n @inject(configTypes.Config)\n private readonly config: ContextModuleServiceConfig,\n @inject(networkTypes.NetworkClient)\n private readonly http: DmkNetworkClient,\n ) {}\n\n public
|
|
5
|
-
"mappings": "iOACA,OAAS,UAAAA,EAAQ,cAAAC,MAAkB,YACnC,OAAiB,QAAAC,EAAM,SAAAC,MAAa,YAEpC,OAAS,eAAAC,MAAmB,0BAE5B,OAAS,gCAAAC,MAAoC,sDAC7C,OAAS,gBAAAC,MAAoB,
|
|
6
|
-
"names": ["inject", "injectable", "Left", "Right", "configTypes", "SolanaTransactionScanChainId", "networkTypes", "calInstructionProgramCodec", "toInstructionInfoPayload", "toProgramEnumVariants", "CHAIN_ID_BY_NETWORK", "SolanaTransactionScanChainId", "HttpInstructionInfoDataSource", "config", "http", "programId", "network", "chainId", "
|
|
4
|
+
"sourcesContent": ["import { DmkNetworkClient } from \"@ledgerhq/device-management-kit\";\nimport { inject, injectable } from \"inversify\";\nimport { Either, Left, Right } from \"purify-ts\";\n\nimport { configTypes } from \"@/config/di/configTypes\";\nimport { type ContextModuleServiceConfig } from \"@/config/model/ContextModuleConfig\";\nimport { SolanaTransactionScanChainId } from \"@/modules/solana/model/SolanaTransactionScanChainId\";\nimport { networkTypes } from \"@/shared/network/di/networkTypes\";\n\nimport {\n GetInstructionInfoParams,\n InstructionInfoDataSource,\n InstructionInfoResult,\n SolanaProgramNotFoundError,\n} from \"./InstructionInfoDataSource\";\nimport {\n type CalInstructionDescriptorDto,\n calInstructionProgramCodec,\n type CalInstructionProgramDto,\n} from \"./InstructionInfoDto\";\nimport {\n type CalMode,\n toBasicFlowTags,\n toInstructionInfoPayload,\n toProgramEnumVariants,\n} from \"./InstructionInfoMapper\";\n\n// Maps the DMK network label to the numeric CAL `chain_id` (the extended\n// Solana network ids 900/901/902). Unknown labels fall back to mainnet.\nconst CHAIN_ID_BY_NETWORK: Record<string, SolanaTransactionScanChainId> = {\n \"solana-mainnet\": SolanaTransactionScanChainId.MAINNET,\n \"solana-devnet\": SolanaTransactionScanChainId.DEVNET,\n \"solana-testnet\": SolanaTransactionScanChainId.TESTNET,\n};\n\n// One sign looks up the same programs several times (signing-route lookup,\n// instruction-info and enum-variant loaders), so results are memoized for a\n// short time. The TTL only has to cover one sign; the size cap bounds memory.\nconst CACHE_TTL_MS = 30_000;\nconst CACHE_MAX_ENTRIES = 64;\n\ntype InstructionInfoCacheEntry = {\n expiresAt: number;\n result: Promise<Either<Error, InstructionInfoResult>>;\n};\n\n@injectable()\nexport class HttpInstructionInfoDataSource\n implements InstructionInfoDataSource\n{\n // Keyed by `${chainId}:${programId}`. The in-flight promise is stored, so\n // concurrent callers share one HTTP call.\n private readonly cache = new Map<string, InstructionInfoCacheEntry>();\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 getInstructionInfo({\n programId,\n network,\n }: GetInstructionInfoParams): Promise<Either<Error, InstructionInfoResult>> {\n const chainId =\n CHAIN_ID_BY_NETWORK[network] ?? SolanaTransactionScanChainId.MAINNET;\n const key = `${chainId}:${programId}`;\n const now = Date.now();\n\n const cached = this.cache.get(key);\n if (cached !== undefined && cached.expiresAt > now) {\n return cached.result;\n }\n\n const result = this.fetchInstructionInfo(programId, chainId);\n this.cache.delete(key);\n if (this.cache.size >= CACHE_MAX_ENTRIES) {\n // Map iterates in insertion order: evict the oldest entry.\n const oldest = this.cache.keys().next();\n if (!oldest.done) this.cache.delete(oldest.value);\n }\n this.cache.set(key, { expiresAt: now + CACHE_TTL_MS, result });\n\n // Failures are not cached so the next caller retries. \"Program not found\"\n // is a valid CAL answer and stays cached.\n void result.then(\n (either) => {\n const cacheable = either.caseOf({\n Left: (error) => error instanceof SolanaProgramNotFoundError,\n Right: () => true,\n });\n if (!cacheable) this.evict(key, result);\n },\n () => this.evict(key, result),\n );\n\n return result;\n }\n\n private evict(\n key: string,\n result: Promise<Either<Error, InstructionInfoResult>>,\n ): void {\n // Only drop our own entry, not a newer one stored under the same key.\n if (this.cache.get(key)?.result === result) {\n this.cache.delete(key);\n }\n }\n\n private async fetchInstructionInfo(\n programId: string,\n chainId: SolanaTransactionScanChainId,\n ): Promise<Either<Error, InstructionInfoResult>> {\n let data: unknown;\n try {\n data = await this.http.get(`${this.config.cal.url}/solana_programs`, {\n params: {\n id: programId,\n chain_id: chainId,\n output: \"id,chain_id,instructions\",\n ref: `branch:${this.config.cal.branch}`,\n },\n });\n } catch (error) {\n const reason = error instanceof Error ? error.message : String(error);\n return Left(\n new Error(\n `[ContextModule] HttpInstructionInfoDataSource: Failed to fetch instruction descriptors: ${reason}`,\n ),\n );\n }\n\n if (!Array.isArray(data)) {\n return Left(\n new Error(\n `[ContextModule] HttpInstructionInfoDataSource: unexpected response for program ${programId}`,\n ),\n );\n }\n\n // CAL answers with an empty array for a program it doesn't know.\n if (data.length === 0) {\n return Left(\n new SolanaProgramNotFoundError(\n programId,\n `[ContextModule] HttpInstructionInfoDataSource: empty response for program ${programId}`,\n ),\n );\n }\n\n // Select the program object whose `id` matches the requested `programId`\n // (the response is an array, one object per requested id).\n const program = data.find(\n (entry): entry is { id: unknown } =>\n entry != null &&\n typeof entry === \"object\" &&\n (entry as { id?: unknown }).id === programId,\n );\n if (program === undefined) {\n return Left(\n new SolanaProgramNotFoundError(\n programId,\n `[ContextModule] HttpInstructionInfoDataSource: no descriptors for program ${programId}`,\n ),\n );\n }\n\n // Validate the program shape so the mapper can dereference `descriptor` /\n // `enum_variants` without runtime-throwing on a malformed CAL payload. A\n // malformed program degrades to a per-program ERROR rather than rejecting\n // the batch. On success we transform each validated DTO into the core\n // payload so the loader never sees the CAL DTO shapes.\n return calInstructionProgramCodec\n .decode(program)\n .caseOf<Either<Error, InstructionInfoResult>>({\n Left: (error) =>\n Left(\n new Error(\n `[ContextModule] HttpInstructionInfoDataSource: malformed descriptors for program ${programId}: ${error}`,\n ),\n ),\n Right: () => {\n const mode: CalMode = this.config.cal.mode ?? \"prod\";\n // The codec strips undeclared fields, so we key the original\n // (full) instruction objects by `discriminator_hex` \u2014 the cast is\n // justified now that the shape has been validated. A descriptor\n // without a discriminator (single-instruction programs such as SPL\n // Memo) is keyed under the empty string.\n const instructions = (program as CalInstructionProgramDto)\n .instructions;\n const descriptorsByDiscriminator: Record<\n string,\n CalInstructionDescriptorDto\n > = Object.fromEntries(\n instructions.map((dto) => [dto.discriminator_hex ?? \"\", dto]),\n );\n const mapped = Object.fromEntries(\n Object.entries(descriptorsByDiscriminator).map(\n ([discriminator, dto]) => [\n discriminator,\n toInstructionInfoPayload(programId, discriminator, dto, mode),\n ],\n ),\n );\n return Right({\n programId,\n descriptors: mapped,\n enumVariants: toProgramEnumVariants(\n descriptorsByDiscriminator,\n mode,\n ),\n basicFlowTags: toBasicFlowTags(descriptorsByDiscriminator),\n });\n },\n });\n }\n}\n"],
|
|
5
|
+
"mappings": "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",
|
|
6
|
+
"names": ["inject", "injectable", "Left", "Right", "configTypes", "SolanaTransactionScanChainId", "networkTypes", "SolanaProgramNotFoundError", "calInstructionProgramCodec", "toBasicFlowTags", "toInstructionInfoPayload", "toProgramEnumVariants", "CHAIN_ID_BY_NETWORK", "SolanaTransactionScanChainId", "CACHE_TTL_MS", "CACHE_MAX_ENTRIES", "HttpInstructionInfoDataSource", "config", "http", "programId", "network", "chainId", "key", "now", "cached", "result", "oldest", "either", "error", "SolanaProgramNotFoundError", "data", "reason", "Left", "program", "entry", "calInstructionProgramCodec", "mode", "instructions", "descriptorsByDiscriminator", "dto", "mapped", "discriminator", "toInstructionInfoPayload", "Right", "toProgramEnumVariants", "toBasicFlowTags", "__decorateClass", "injectable", "__decorateParam", "inject", "configTypes", "networkTypes"]
|
|
7
7
|
}
|
package/lib/esm/src/modules/solana/instruction-info/data/HttpInstructionInfoDataSource.test.js
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import{Left as d,Right as l}from"purify-ts";import{beforeEach as g,describe as h,expect as e,it as s,vi as p}from"vitest";import{SolanaTransactionScanChainId as i}from"../../../../modules/solana/model/SolanaTransactionScanChainId";import{HttpInstructionInfoDataSource as f}from"./HttpInstructionInfoDataSource";h("HttpInstructionInfoDataSource",()=>{let r,n;const t="11111111111111111111111111111111",a="solana-mainnet",m={cal:{url:"https://global.api.prd.ledger.com/cal/v1",mode:"prod",branch:"main"}},u=[{id:t,chain_id:i.MAINNET,instructions:[{discriminator_hex:"00000000",instruction_name:"createAccount",descriptor:{data:"00010101",signatures:{prod:"prodsig",test:"testsig"}},display_fields:[],value_flow_ports:[],hide_rules:[],account_resets:[]}]}];g(()=>{p.clearAllMocks(),n={get:p.fn()},r=new f(m,n)}),s("calls CAL /solana_programs with id, chain_id and output params",async()=>{n.get.mockResolvedValue(u),await r.getInstructionInfo({programId:t,network:a}),e(n.get).toHaveBeenCalledTimes(1),e(n.get).toHaveBeenCalledWith("https://global.api.prd.ledger.com/cal/v1/solana_programs",{params:{id:t,chain_id:i.MAINNET,output:"id,chain_id,instructions",ref:"branch:main"}})}),s("maps devnet/testnet networks to their numeric chain ids",async()=>{n.get.mockResolvedValue(u),await r.getInstructionInfo({programId:t,network:"solana-devnet"}),e(n.get).toHaveBeenCalledWith("https://global.api.prd.ledger.com/cal/v1/solana_programs",e.objectContaining({params:e.objectContaining({chain_id:901})}))}),s("returns Right with each descriptor transformed into the core payload on success",async()=>{n.get.mockResolvedValue(u);const o=await r.getInstructionInfo({programId:t,network:a});e(o).toEqual(l({programId:t,descriptors:{"00000000":l({programId:t,discriminator:"00000000",instructionName:"createAccount",instructionInfo:{data:"00010101",signature:"prodsig"},substructures:[],enumVariants:[],idlDescriptor:{typePool:[],rootType:0},mintAssociations:[],ownerAssociations:[],valueFlowPorts:[],accountResets:[],displayFields:[],hideRules:[]})},enumVariants:[]}))}),s("keys a descriptor without `discriminator_hex` under the empty string",async()=>{n.get.mockResolvedValue([{id:t,chain_id:i.MAINNET,instructions:[{instruction_name:"addMemo",descriptor:{data:"00010101",signatures:{prod:"prodsig",test:"testsig"}}}]}]);const o=await r.getInstructionInfo({programId:t,network:a});e(o.isRight()).toBe(!0);const{descriptors:c}=o.unsafeCoerce();e(Object.keys(c)).toEqual([""]),e(c[""].unsafeCoerce()).toEqual(e.objectContaining({programId:t,discriminator:"",instructionInfo:{data:"00010101",signature:"prodsig"}}))}),s("returns Left when the response array is empty",async()=>{n.get.mockResolvedValue([]);const o=await r.getInstructionInfo({programId:t,network:a});e(o).toEqual(d(new Error(`[ContextModule] HttpInstructionInfoDataSource: empty response for program ${t}`)))}),s("returns Left when no program object matches the requested programId",async()=>{n.get.mockResolvedValue([{id:"OtherProgram",chain_id:i.MAINNET,instructions:[]}]);const o=await r.getInstructionInfo({programId:t,network:a});e(o).toEqual(d(new Error(`[ContextModule] HttpInstructionInfoDataSource: no descriptors for program ${t}`)))}),s("returns Left (not a throw) when an instruction descriptor is malformed",async()=>{n.get.mockResolvedValue([{id:t,chain_id:i.MAINNET,instructions:[{discriminator_hex:"00000000"}]}]);const o=await r.getInstructionInfo({programId:t,network:a});e(o.isLeft()).toBe(!0),e(o.extract().message).toMatch(new RegExp(String.raw`\[ContextModule\] HttpInstructionInfoDataSource: malformed descriptors for program ${t}:`))}),s("returns Left (not a throw) when account_schema.slots is not an array",async()=>{n.get.mockResolvedValue([{id:t,chain_id:i.MAINNET,instructions:[{discriminator_hex:"00000000",descriptor:{data:"00010101",signatures:{prod:"prodsig",test:"testsig"}},account_schema:{slots:{}}}]}]);const o=await r.getInstructionInfo({programId:t,network:a});e(o.isLeft()).toBe(!0),e(o.extract().message).toMatch(new RegExp(String.raw`\[ContextModule\] HttpInstructionInfoDataSource: malformed descriptors for program ${t}:`))}),s("returns Right with accountSchema mapped through when it is well-formed",async()=>{n.get.mockResolvedValue([{id:t,chain_id:i.MAINNET,instructions:[{discriminator_hex:"00000000",descriptor:{data:"00010101",signatures:{prod:"prodsig",test:"testsig"}},account_schema:{count_min:2,count_max:2,slots:[{signer:"REQUIRED",writable:"EITHER"}]}}]}]);const o=await r.getInstructionInfo({programId:t,network:a});e(o.isRight()).toBe(!0);const{descriptors:c}=o.unsafeCoerce();e(c["00000000"].unsafeCoerce()).toEqual(e.objectContaining({accountSchema:{count_min:2,count_max:2,remaining_policy:{signer:"EITHER",writable:"EITHER"},slots:[{signer:"REQUIRED",writable:"EITHER"}]}}))}),s("returns Left when the HTTP client throws",async()=>{n.get.mockRejectedValue(new Error("network"));const o=await r.getInstructionInfo({programId:t,network:a});e(o).toEqual(d(new Error("[ContextModule] HttpInstructionInfoDataSource: Failed to fetch instruction descriptors: network")))})});
|
|
1
|
+
import{Left as w,Right as v}from"purify-ts";import{afterEach as E,beforeEach as y,describe as h,expect as e,it as s,vi as f}from"vitest";import{SolanaTransactionScanChainId as d}from"../../../../modules/solana/model/SolanaTransactionScanChainId";import{HttpInstructionInfoDataSource as C}from"./HttpInstructionInfoDataSource";import{SolanaProgramNotFoundError as m}from"./InstructionInfoDataSource";h("HttpInstructionInfoDataSource",()=>{let r,n;const t="11111111111111111111111111111111",a="solana-mainnet",_={cal:{url:"https://global.api.prd.ledger.com/cal/v1",mode:"prod",branch:"main"}},u=[{id:t,chain_id:d.MAINNET,instructions:[{discriminator_hex:"00000000",instruction_name:"createAccount",descriptor:{data:"00010101",signatures:{prod:"prodsig",test:"testsig"}},display_fields:[],value_flow_ports:[],hide_rules:[],account_resets:[]}]}];y(()=>{f.clearAllMocks(),n={get:f.fn()},r=new C(_,n)}),s("calls CAL /solana_programs with id, chain_id and output params",async()=>{n.get.mockResolvedValue(u),await r.getInstructionInfo({programId:t,network:a}),e(n.get).toHaveBeenCalledTimes(1),e(n.get).toHaveBeenCalledWith("https://global.api.prd.ledger.com/cal/v1/solana_programs",{params:{id:t,chain_id:d.MAINNET,output:"id,chain_id,instructions",ref:"branch:main"}})}),s("maps devnet/testnet networks to their numeric chain ids",async()=>{n.get.mockResolvedValue(u),await r.getInstructionInfo({programId:t,network:"solana-devnet"}),e(n.get).toHaveBeenCalledWith("https://global.api.prd.ledger.com/cal/v1/solana_programs",e.objectContaining({params:e.objectContaining({chain_id:901})}))}),s("returns Right with each descriptor transformed into the core payload on success",async()=>{n.get.mockResolvedValue(u);const o=await r.getInstructionInfo({programId:t,network:a});e(o).toEqual(v({programId:t,descriptors:{"00000000":v({programId:t,discriminator:"00000000",instructionName:"createAccount",instructionInfo:{data:"00010101",signature:"prodsig"},substructures:[],enumVariants:[],idlDescriptor:{typePool:[],rootType:0},mintAssociations:[],ownerAssociations:[],valueFlowPorts:[],accountResets:[],displayFields:[],hideRules:[]})},enumVariants:[],basicFlowTags:[]}))}),s("keys a descriptor without `discriminator_hex` under the empty string",async()=>{n.get.mockResolvedValue([{id:t,chain_id:d.MAINNET,instructions:[{instruction_name:"addMemo",descriptor:{data:"00010101",signatures:{prod:"prodsig",test:"testsig"}}}]}]);const o=await r.getInstructionInfo({programId:t,network:a});e(o.isRight()).toBe(!0);const{descriptors:i}=o.unsafeCoerce();e(Object.keys(i)).toEqual([""]),e(i[""].unsafeCoerce()).toEqual(e.objectContaining({programId:t,discriminator:"",instructionInfo:{data:"00010101",signature:"prodsig"}}))}),s("returns a SolanaProgramNotFoundError when the response array is empty",async()=>{n.get.mockResolvedValue([]);const o=await r.getInstructionInfo({programId:t,network:a});e(o).toEqual(w(new m(t,`[ContextModule] HttpInstructionInfoDataSource: empty response for program ${t}`))),e(o.extract()).toBeInstanceOf(m)}),s("returns a plain Error, not a not-found, when the response is not an array",async()=>{n.get.mockResolvedValue({unexpected:!0});const o=await r.getInstructionInfo({programId:t,network:a});e(o.isLeft()).toBe(!0),e(o.extract()).not.toBeInstanceOf(m),e(o.extract().message).toBe(`[ContextModule] HttpInstructionInfoDataSource: unexpected response for program ${t}`)}),s("returns a SolanaProgramNotFoundError when no program object matches the requested programId",async()=>{n.get.mockResolvedValue([{id:"OtherProgram",chain_id:d.MAINNET,instructions:[]}]);const o=await r.getInstructionInfo({programId:t,network:a});e(o).toEqual(w(new m(t,`[ContextModule] HttpInstructionInfoDataSource: no descriptors for program ${t}`)))}),s("returns Left (not a throw) when an instruction descriptor is malformed",async()=>{n.get.mockResolvedValue([{id:t,chain_id:d.MAINNET,instructions:[{discriminator_hex:"00000000"}]}]);const o=await r.getInstructionInfo({programId:t,network:a});e(o.isLeft()).toBe(!0),e(o.extract().message).toMatch(new RegExp(String.raw`\[ContextModule\] HttpInstructionInfoDataSource: malformed descriptors for program ${t}:`))}),s("returns Left (not a throw) when account_schema.slots is not an array",async()=>{n.get.mockResolvedValue([{id:t,chain_id:d.MAINNET,instructions:[{discriminator_hex:"00000000",descriptor:{data:"00010101",signatures:{prod:"prodsig",test:"testsig"}},account_schema:{slots:{}}}]}]);const o=await r.getInstructionInfo({programId:t,network:a});e(o.isLeft()).toBe(!0),e(o.extract().message).toMatch(new RegExp(String.raw`\[ContextModule\] HttpInstructionInfoDataSource: malformed descriptors for program ${t}:`))}),s("returns Right with accountSchema mapped through when it is well-formed",async()=>{n.get.mockResolvedValue([{id:t,chain_id:d.MAINNET,instructions:[{discriminator_hex:"00000000",descriptor:{data:"00010101",signatures:{prod:"prodsig",test:"testsig"}},account_schema:{count_min:2,count_max:2,slots:[{signer:"REQUIRED",writable:"EITHER"}]}}]}]);const o=await r.getInstructionInfo({programId:t,network:a});e(o.isRight()).toBe(!0);const{descriptors:i}=o.unsafeCoerce();e(i["00000000"].unsafeCoerce()).toEqual(e.objectContaining({accountSchema:{count_min:2,count_max:2,remaining_policy:{signer:"EITHER",writable:"EITHER"},slots:[{signer:"REQUIRED",writable:"EITHER"}]}}))}),s("returns Left when the HTTP client throws",async()=>{n.get.mockRejectedValue(new Error("network"));const o=await r.getInstructionInfo({programId:t,network:a});e(o).toEqual(w(new Error("[ContextModule] HttpInstructionInfoDataSource: Failed to fetch instruction descriptors: network"))),e(o.extract()).not.toBeInstanceOf(m)}),h("signing_route",()=>{const o="Stake11111111111111111111111111111111111111",i={data:"00010101",signatures:{prod:"prodsig",test:"testsig"}},c=l=>[{id:o,chain_id:d.MAINNET,instructions:Object.entries(l).map(([I,p])=>({discriminator_hex:I,descriptor:i,...p===void 0?{}:{signing_route:p}}))}],g=()=>r.getInstructionInfo({programId:o,network:a});s("maps basic_flow tags to one entry per (discriminator, rule, role)",async()=>{n.get.mockResolvedValue(c({"00000000":{basic_flow:[{rule:"native-staking",role:"allowed"}]},"02000000":{basic_flow:[{rule:"native-staking",role:"required"},{rule:"other-rule",role:"allowed"}]}}));const l=await g();e(l.unsafeCoerce().basicFlowTags).toEqual([{discriminator:"00000000",rule:"native-staking",role:"allowed"},{discriminator:"02000000",rule:"native-staking",role:"required"},{discriminator:"02000000",rule:"other-rule",role:"allowed"}])}),s("returns no tags when CAL doesn't serve signing_route (today's CAL)",async()=>{n.get.mockResolvedValue(c({"00000000":void 0,"02000000":void 0}));const l=await g();e(l.unsafeCoerce().basicFlowTags).toEqual([])}),s("drops unknown roles, empty rule ids and unknown keys",async()=>{n.get.mockResolvedValue(c({"02000000":{basic_flow:[{rule:"native-staking",role:"forbidden"},{rule:"",role:"required"},{rule:"native-staking",role:"required",extra:1}],other_flow:[{rule:"x",role:"required"}]}}));const l=await g();e(l.unsafeCoerce().basicFlowTags).toEqual([{discriminator:"02000000",rule:"native-staking",role:"required"}])}),s.each([["a string","native-staking"],["basic_flow not an array",{basic_flow:{rule:"a"}}],["an entry without role",{basic_flow:[{rule:"native-staking"}]}],["a non-string rule",{basic_flow:[{rule:1,role:"required"}]}]])("drops a malformed signing_route (%s) but keeps the descriptors",async(l,I)=>{n.get.mockResolvedValue(c({"00000000":{basic_flow:[{rule:"native-staking",role:"allowed"}]},"02000000":I}));const p=await g();e(p.isRight()).toBe(!0);const{descriptors:k,basicFlowTags:R}=p.unsafeCoerce();e(Object.keys(k)).toEqual(["00000000","02000000"]),e(k["02000000"].isRight()).toBe(!0),e(R).toEqual([{discriminator:"00000000",rule:"native-staking",role:"allowed"}])}),s("ignores tags on an instruction without discriminator_hex",async()=>{n.get.mockResolvedValue([{id:o,chain_id:d.MAINNET,instructions:[{descriptor:i,signing_route:{basic_flow:[{rule:"native-staking",role:"required"}]}}]}]);const l=await g();e(l.unsafeCoerce().basicFlowTags).toEqual([])})}),h("cache",()=>{y(()=>{f.useFakeTimers()}),E(()=>{f.useRealTimers()}),s("serves a second call for the same program and network from the cache",async()=>{n.get.mockResolvedValue(u);const o=await r.getInstructionInfo({programId:t,network:a}),i=await r.getInstructionInfo({programId:t,network:a});e(n.get).toHaveBeenCalledTimes(1),e(i).toBe(o)}),s("shares one HTTP call between concurrent callers",async()=>{n.get.mockResolvedValue(u),await Promise.all([r.getInstructionInfo({programId:t,network:a}),r.getInstructionInfo({programId:t,network:a})]),e(n.get).toHaveBeenCalledTimes(1)}),s("keys the cache by chain id",async()=>{n.get.mockResolvedValue(u),await r.getInstructionInfo({programId:t,network:a}),await r.getInstructionInfo({programId:t,network:"solana-devnet"}),await r.getInstructionInfo({programId:t,network:"unknown"}),e(n.get).toHaveBeenCalledTimes(2)}),s("fetches again once the entry has expired",async()=>{n.get.mockResolvedValue(u),await r.getInstructionInfo({programId:t,network:a}),f.advanceTimersByTime(30001),await r.getInstructionInfo({programId:t,network:a}),e(n.get).toHaveBeenCalledTimes(2)}),s("evicts the oldest entry beyond the size cap",async()=>{n.get.mockImplementation((i,{params:c})=>Promise.resolve([{...u[0],id:c.id}]));const o=Array.from({length:65},(i,c)=>`program-${c}`);for(const i of o)await r.getInstructionInfo({programId:i,network:a});await r.getInstructionInfo({programId:o[64],network:a}),e(n.get).toHaveBeenCalledTimes(65),await r.getInstructionInfo({programId:o[0],network:a}),e(n.get).toHaveBeenCalledTimes(66)}),s.each([["the HTTP client throws",()=>Promise.reject(new Error("network"))],["the program is malformed",()=>Promise.resolve([{id:t,chain_id:900,instructions:[{}]}])]])("does not cache a failure (%s)",async(o,i)=>{n.get.mockImplementationOnce(i).mockResolvedValue(u);const c=await r.getInstructionInfo({programId:t,network:a}),g=await r.getInstructionInfo({programId:t,network:a});e(c.isLeft()).toBe(!0),e(g.isRight()).toBe(!0),e(n.get).toHaveBeenCalledTimes(2)}),s("caches a program-not-found answer",async()=>{n.get.mockResolvedValue([]),await r.getInstructionInfo({programId:t,network:a});const o=await r.getInstructionInfo({programId:t,network:a});e(o.extract()).toBeInstanceOf(m),e(n.get).toHaveBeenCalledTimes(1)})})});
|
|
2
2
|
//# sourceMappingURL=HttpInstructionInfoDataSource.test.js.map
|