@ledgerhq/device-signer-kit-solana 1.9.0 → 1.9.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/lib/cjs/internal/app-binder/task/BuildTransactionContextTask.js +1 -1
- package/lib/cjs/internal/app-binder/task/BuildTransactionContextTask.js.map +3 -3
- package/lib/cjs/internal/app-binder/task/BuildTransactionContextTask.test.js +1 -1
- package/lib/cjs/internal/app-binder/task/BuildTransactionContextTask.test.js.map +2 -2
- package/lib/cjs/internal/app-binder/task/context-providers/loadCertificate.js +1 -1
- package/lib/cjs/internal/app-binder/task/context-providers/loadCertificate.js.map +2 -2
- package/lib/cjs/internal/app-binder/task/context-providers/provideTransactionCheckContext.js +1 -1
- package/lib/cjs/internal/app-binder/task/context-providers/provideTransactionCheckContext.js.map +3 -3
- package/lib/cjs/internal/app-binder/task/context-providers/provideTransactionCheckContext.test.js +1 -1
- package/lib/cjs/internal/app-binder/task/context-providers/provideTransactionCheckContext.test.js.map +2 -2
- package/lib/cjs/package.json +1 -1
- package/lib/esm/internal/app-binder/task/BuildTransactionContextTask.js +1 -1
- package/lib/esm/internal/app-binder/task/BuildTransactionContextTask.js.map +3 -3
- package/lib/esm/internal/app-binder/task/BuildTransactionContextTask.test.js +1 -1
- package/lib/esm/internal/app-binder/task/BuildTransactionContextTask.test.js.map +2 -2
- package/lib/esm/internal/app-binder/task/context-providers/loadCertificate.js +1 -1
- package/lib/esm/internal/app-binder/task/context-providers/loadCertificate.js.map +2 -2
- package/lib/esm/internal/app-binder/task/context-providers/provideTransactionCheckContext.js +1 -1
- package/lib/esm/internal/app-binder/task/context-providers/provideTransactionCheckContext.js.map +3 -3
- package/lib/esm/internal/app-binder/task/context-providers/provideTransactionCheckContext.test.js +1 -1
- package/lib/esm/internal/app-binder/task/context-providers/provideTransactionCheckContext.test.js.map +2 -2
- package/lib/esm/package.json +1 -1
- package/lib/types/internal/app-binder/task/BuildTransactionContextTask.d.ts.map +1 -1
- package/lib/types/tsconfig.prod.tsbuildinfo +1 -1
- package/package.json +5 -5
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
"use strict";var
|
|
1
|
+
"use strict";var c=Object.defineProperty;var x=Object.getOwnPropertyDescriptor;var h=Object.getOwnPropertyNames;var R=Object.prototype.hasOwnProperty;var f=(o,t)=>{for(var e in t)c(o,e,{get:t[e],enumerable:!0})},m=(o,t,e,s)=>{if(t&&typeof t=="object"||typeof t=="function")for(let r of h(t))!R.call(o,r)&&r!==e&&c(o,r,{get:()=>t[r],enumerable:!(s=x(t,r))||s.enumerable});return o};var I=o=>m(c({},"__esModule",{value:!0}),o);var _={};f(_,{BuildTransactionContextTask:()=>N});module.exports=I(_);var n=require("@ledgerhq/context-module"),u=require("@ledgerhq/device-management-kit"),A=require("../../app-binder/command/GetChallengeCommand");class N{constructor(t,e){this.api=t;this.args=e;this._logger=e.loggerFactory("BuildTransactionContextTask")}_logger;async run(){this._logger.debug("[run] Starting BuildTransactionContextTask");const{contextModule:t,options:e}=this.args,s=this.api.getDeviceSessionState();let r;const d=await this.api.sendCommand(new A.GetChallengeCommand);if((0,u.isSuccessCommandResult)(d))r=d.data.challenge;else throw new Error("Failed to get challenge from device");const S=this.args.signerAddress?{from:this.args.signerAddress,transactionBytes:this.args.transactionBytes,chain:n.SolanaTransactionScanChainId.MAINNET}:void 0,g={deviceModelId:s.deviceModelId,tokenAddress:e.tokenAddress,challenge:r,createATA:e.createATA,tokenInternalId:e.tokenInternalId,templateId:e.templateId,transactionCheck:S};this._logger.debug("[run] Calling contextModule.getContexts for Solana",{data:{args:g}});const i=await t.getContexts(g,[n.ClearSignContextType.SOLANA_TOKEN,n.ClearSignContextType.SOLANA_LIFI,n.ClearSignContextType.SOLANA_TRUSTED_NAME]);this._logger.debug("[run] Solana context result",{data:{contexts:i}});const C=i.filter(a=>a.type===n.ClearSignContextType.ERROR).length,l=i.find(a=>a.type===n.ClearSignContextType.SOLANA_TRUSTED_NAME),p=l?.certificate,T=l?.payload;if(!!(e.tokenAddress||e.createATA)&&l===void 0)throw new Error("[SignerSolana] BuildTransactionContextTask: owner info was required but could not be resolved");const y=i.filter(a=>a.type===n.ClearSignContextType.ERROR||a.type===n.ClearSignContextType.SOLANA_TOKEN||a.type===n.ClearSignContextType.SOLANA_LIFI||a.type===n.ClearSignContextType.SOLANA_TRANSACTION_CHECK);return{trustedNamePKICertificate:p,tlvDescriptor:T,loadersResults:y,contextErrorCount:C}}}0&&(module.exports={BuildTransactionContextTask});
|
|
2
2
|
//# sourceMappingURL=BuildTransactionContextTask.js.map
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"version": 3,
|
|
3
3
|
"sources": ["../../../../../src/internal/app-binder/task/BuildTransactionContextTask.ts"],
|
|
4
|
-
"sourcesContent": ["import {\n type ClearSignContextSuccess,\n ClearSignContextType,\n type ContextModule,\n type LoaderResult,\n type SolanaTransactionContextResultSuccess,\n SolanaTransactionScanChainId,\n} from \"@ledgerhq/context-module\";\nimport {\n type InternalApi,\n isSuccessCommandResult,\n type LoggerPublisherService,\n} from \"@ledgerhq/device-management-kit\";\n\nimport { type TransactionResolutionContext } from \"@api/model/TransactionResolutionContext\";\nimport { GetChallengeCommand } from \"@internal/app-binder/command/GetChallengeCommand\";\
|
|
5
|
-
"mappings": "yaAAA,IAAAA,EAAA,GAAAC,EAAAD,EAAA,iCAAAE,IAAA,eAAAC,EAAAH,GAAA,IAAAI,EAOO,oCACPC,EAIO,2CAGPC,EAAoC,
|
|
6
|
-
"names": ["BuildTransactionContextTask_exports", "__export", "BuildTransactionContextTask", "__toCommonJS", "import_context_module", "import_device_management_kit", "import_GetChallengeCommand", "
|
|
4
|
+
"sourcesContent": ["import {\n type ClearSignContextSuccess,\n ClearSignContextType,\n type ContextModule,\n type LoaderResult,\n type SolanaTransactionContextResultSuccess,\n SolanaTransactionScanChainId,\n} from \"@ledgerhq/context-module\";\nimport {\n type InternalApi,\n isSuccessCommandResult,\n type LoggerPublisherService,\n} from \"@ledgerhq/device-management-kit\";\n\nimport { type TransactionResolutionContext } from \"@api/model/TransactionResolutionContext\";\nimport { GetChallengeCommand } from \"@internal/app-binder/command/GetChallengeCommand\";\n\nexport type { SolanaTransactionContextResultSuccess as SolanaBuildContextResult };\n\nexport type BuildTransactionContextTaskArgs = {\n readonly contextModule: ContextModule;\n readonly options: TransactionResolutionContext;\n readonly transactionBytes: Uint8Array;\n readonly signerAddress: string | null;\n readonly loggerFactory: (tag: string) => LoggerPublisherService;\n};\n\nexport class BuildTransactionContextTask {\n private readonly _logger: LoggerPublisherService;\n constructor(\n private readonly api: InternalApi,\n private readonly args: BuildTransactionContextTaskArgs,\n ) {\n this._logger = args.loggerFactory(\"BuildTransactionContextTask\");\n }\n\n async run(): Promise<SolanaTransactionContextResultSuccess> {\n this._logger.debug(\"[run] Starting BuildTransactionContextTask\");\n const { contextModule, options } = this.args;\n const deviceState = this.api.getDeviceSessionState();\n\n // get challenge\n let challenge: string | undefined;\n const challengeRes = await this.api.sendCommand(new GetChallengeCommand());\n if (isSuccessCommandResult(challengeRes)) {\n challenge = challengeRes.data.challenge;\n } else {\n throw new Error(\"Failed to get challenge from device\");\n }\n\n const transactionCheck = this.args.signerAddress\n ? {\n from: this.args.signerAddress,\n transactionBytes: this.args.transactionBytes,\n chain: SolanaTransactionScanChainId.MAINNET,\n }\n : undefined;\n\n const contextModuleGetSolanaContextArgs = {\n deviceModelId: deviceState.deviceModelId,\n tokenAddress: options.tokenAddress,\n challenge,\n createATA: options.createATA,\n tokenInternalId: options.tokenInternalId,\n templateId: options.templateId,\n transactionCheck,\n };\n // get Solana context\n this._logger.debug(\"[run] Calling contextModule.getContexts for Solana\", {\n data: {\n args: contextModuleGetSolanaContextArgs,\n },\n });\n\n const contexts = await contextModule.getContexts(\n contextModuleGetSolanaContextArgs,\n [\n ClearSignContextType.SOLANA_TOKEN,\n ClearSignContextType.SOLANA_LIFI,\n ClearSignContextType.SOLANA_TRUSTED_NAME,\n // !! TODO-WEB3CHECK FLIP THIS BACK ONCE TRANSACTION CHECK IS READY,\n // TO BE KEEPT OFF FOR NOW\n //ClearSignContextType.SOLANA_TRANSACTION_CHECK,\n ],\n );\n\n this._logger.debug(\"[run] Solana context result\", {\n data: { contexts },\n });\n\n const contextErrorCount = contexts.filter(\n (contextResponseItem) =>\n contextResponseItem.type === ClearSignContextType.ERROR,\n ).length;\n\n const trustedNameCtx = contexts.find(\n (\n contextResponseItem,\n ): contextResponseItem is ClearSignContextSuccess<ClearSignContextType.SOLANA_TRUSTED_NAME> =>\n contextResponseItem.type === ClearSignContextType.SOLANA_TRUSTED_NAME,\n );\n const trustedNamePKICertificate = trustedNameCtx?.certificate;\n const tlvDescriptor = trustedNameCtx?.payload;\n\n const ownerInfoRequired = !!(options.tokenAddress || options.createATA);\n if (ownerInfoRequired && trustedNameCtx === undefined) {\n throw new Error(\n \"[SignerSolana] BuildTransactionContextTask: owner info was required but could not be resolved\",\n );\n }\n\n const loadersResults = contexts.filter(\n (contextResponseItem): contextResponseItem is LoaderResult =>\n contextResponseItem.type === ClearSignContextType.ERROR ||\n contextResponseItem.type === ClearSignContextType.SOLANA_TOKEN ||\n contextResponseItem.type === ClearSignContextType.SOLANA_LIFI ||\n contextResponseItem.type ===\n ClearSignContextType.SOLANA_TRANSACTION_CHECK,\n );\n\n return {\n trustedNamePKICertificate,\n tlvDescriptor,\n loadersResults,\n contextErrorCount,\n };\n }\n}\n"],
|
|
5
|
+
"mappings": "yaAAA,IAAAA,EAAA,GAAAC,EAAAD,EAAA,iCAAAE,IAAA,eAAAC,EAAAH,GAAA,IAAAI,EAOO,oCACPC,EAIO,2CAGPC,EAAoC,4DAY7B,MAAMJ,CAA4B,CAEvC,YACmBK,EACAC,EACjB,CAFiB,SAAAD,EACA,UAAAC,EAEjB,KAAK,QAAUA,EAAK,cAAc,6BAA6B,CACjE,CANiB,QAQjB,MAAM,KAAsD,CAC1D,KAAK,QAAQ,MAAM,4CAA4C,EAC/D,KAAM,CAAE,cAAAC,EAAe,QAAAC,CAAQ,EAAI,KAAK,KAClCC,EAAc,KAAK,IAAI,sBAAsB,EAGnD,IAAIC,EACJ,MAAMC,EAAe,MAAM,KAAK,IAAI,YAAY,IAAI,qBAAqB,EACzE,MAAI,0BAAuBA,CAAY,EACrCD,EAAYC,EAAa,KAAK,cAE9B,OAAM,IAAI,MAAM,qCAAqC,EAGvD,MAAMC,EAAmB,KAAK,KAAK,cAC/B,CACE,KAAM,KAAK,KAAK,cAChB,iBAAkB,KAAK,KAAK,iBAC5B,MAAO,+BAA6B,OACtC,EACA,OAEEC,EAAoC,CACxC,cAAeJ,EAAY,cAC3B,aAAcD,EAAQ,aACtB,UAAAE,EACA,UAAWF,EAAQ,UACnB,gBAAiBA,EAAQ,gBACzB,WAAYA,EAAQ,WACpB,iBAAAI,CACF,EAEA,KAAK,QAAQ,MAAM,qDAAsD,CACvE,KAAM,CACJ,KAAMC,CACR,CACF,CAAC,EAED,MAAMC,EAAW,MAAMP,EAAc,YACnCM,EACA,CACE,uBAAqB,aACrB,uBAAqB,YACrB,uBAAqB,mBAIvB,CACF,EAEA,KAAK,QAAQ,MAAM,8BAA+B,CAChD,KAAM,CAAE,SAAAC,CAAS,CACnB,CAAC,EAED,MAAMC,EAAoBD,EAAS,OAChCE,GACCA,EAAoB,OAAS,uBAAqB,KACtD,EAAE,OAEIC,EAAiBH,EAAS,KAE5BE,GAEAA,EAAoB,OAAS,uBAAqB,mBACtD,EACME,EAA4BD,GAAgB,YAC5CE,EAAgBF,GAAgB,QAGtC,GAD0B,CAAC,EAAET,EAAQ,cAAgBA,EAAQ,YACpCS,IAAmB,OAC1C,MAAM,IAAI,MACR,+FACF,EAGF,MAAMG,EAAiBN,EAAS,OAC7BE,GACCA,EAAoB,OAAS,uBAAqB,OAClDA,EAAoB,OAAS,uBAAqB,cAClDA,EAAoB,OAAS,uBAAqB,aAClDA,EAAoB,OAClB,uBAAqB,wBAC3B,EAEA,MAAO,CACL,0BAAAE,EACA,cAAAC,EACA,eAAAC,EACA,kBAAAL,CACF,CACF,CACF",
|
|
6
|
+
"names": ["BuildTransactionContextTask_exports", "__export", "BuildTransactionContextTask", "__toCommonJS", "import_context_module", "import_device_management_kit", "import_GetChallengeCommand", "api", "args", "contextModule", "options", "deviceState", "challenge", "challengeRes", "transactionCheck", "contextModuleGetSolanaContextArgs", "contexts", "contextErrorCount", "contextResponseItem", "trustedNameCtx", "trustedNamePKICertificate", "tlvDescriptor", "loadersResults"]
|
|
7
7
|
}
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
"use strict";var n=require("@ledgerhq/context-module"),u=require("@ledgerhq/device-management-kit"),e=require("vitest"),
|
|
1
|
+
"use strict";var n=require("@ledgerhq/context-module"),u=require("@ledgerhq/device-management-kit"),e=require("vitest"),m=require("../../app-binder/command/GetChallengeCommand"),r=require("./BuildTransactionContextTask");const A=()=>({debug:e.vi.fn(),info:e.vi.fn(),warn:e.vi.fn(),error:e.vi.fn(),subscribers:[]}),o={getContexts:e.vi.fn()},y=new Uint8Array([1,2,3]),C={payload:new Uint8Array([170,187]),keyUsageNumber:1},s={contextModule:o,loggerFactory:A,transactionBytes:new Uint8Array([222,173,190,239]),signerAddress:null,options:{tokenAddress:"someAddress",createATA:void 0}},l={type:n.ClearSignContextType.SOLANA_TRUSTED_NAME,payload:y,certificate:C};let a;(0,e.describe)("BuildTransactionContextTask",()=>{(0,e.beforeEach)(()=>{e.vi.resetAllMocks(),a={getDeviceSessionState:e.vi.fn().mockReturnValue({deviceModelId:u.DeviceModelId.NANO_X}),sendCommand:e.vi.fn().mockResolvedValue((0,u.CommandResultFactory)({data:{challenge:"someChallenge"}}))}}),(0,e.it)("requests the challenge from the device",async()=>{o.getContexts.mockResolvedValue([l]),await new r.BuildTransactionContextTask(a,s).run(),(0,e.expect)(a.sendCommand).toHaveBeenCalledWith(e.expect.any(m.GetChallengeCommand))}),(0,e.it)("calls contextModule.getContexts with the active Solana context types (transaction-check temporarily disabled)",async()=>{o.getContexts.mockResolvedValue([l]),await new r.BuildTransactionContextTask(a,s).run(),(0,e.expect)(o.getContexts).toHaveBeenCalledWith({deviceModelId:u.DeviceModelId.NANO_X,tokenAddress:"someAddress",challenge:"someChallenge",createATA:void 0,tokenInternalId:void 0,templateId:void 0,transactionCheck:void 0},[n.ClearSignContextType.SOLANA_TOKEN,n.ClearSignContextType.SOLANA_LIFI,n.ClearSignContextType.SOLANA_TRUSTED_NAME])}),(0,e.it)("derives transactionCheck from signerAddress and transactionBytes when address is provided",async()=>{o.getContexts.mockResolvedValue([l]);const t={...s,signerAddress:"So1anaSignerPubKey111111111111111111111111111"};await new r.BuildTransactionContextTask(a,t).run(),(0,e.expect)(o.getContexts).toHaveBeenCalledWith(e.expect.objectContaining({transactionCheck:{from:"So1anaSignerPubKey111111111111111111111111111",transactionBytes:s.transactionBytes,chain:n.SolanaTransactionScanChainId.MAINNET}}),e.expect.any(Array))}),(0,e.it)("returns trustedName cert + tlvDescriptor when SOLANA_TRUSTED_NAME context is present",async()=>{o.getContexts.mockResolvedValue([l]);const c=await new r.BuildTransactionContextTask(a,s).run();(0,e.expect)(c).toEqual({tlvDescriptor:y,trustedNamePKICertificate:C,loadersResults:[],contextErrorCount:0})}),(0,e.it)("includes SOLANA_TRANSACTION_CHECK results in loadersResults",async()=>{const t={type:n.ClearSignContextType.SOLANA_TRANSACTION_CHECK,payload:{descriptor:"aabbccdd"},certificate:{payload:new Uint8Array([153]),keyUsageNumber:14}};o.getContexts.mockResolvedValue([l,t]);const d=await new r.BuildTransactionContextTask(a,s).run();(0,e.expect)(d.loadersResults).toEqual([t]),(0,e.expect)(d.contextErrorCount).toBe(0)}),(0,e.it)("includes SOLANA_TOKEN and SOLANA_LIFI results in loadersResults",async()=>{const t={type:n.ClearSignContextType.SOLANA_TOKEN,payload:{solanaTokenDescriptor:{data:"aa",signature:"bb"}},certificate:void 0},c={type:n.ClearSignContextType.SOLANA_LIFI,payload:{descriptors:{},instructions:[]},certificate:void 0};o.getContexts.mockResolvedValue([l,t,c]);const i=await new r.BuildTransactionContextTask(a,s).run();(0,e.expect)(i.loadersResults).toEqual([t,c])}),(0,e.it)("throws when challenge command fails",async()=>{a.sendCommand.mockResolvedValue((0,u.CommandResultFactory)({error:{_tag:"SomeError",errorCode:27264,message:"bad"}}));const t=new r.BuildTransactionContextTask(a,s);await(0,e.expect)(t.run()).rejects.toThrow("Failed to get challenge from device")}),(0,e.it)("counts ERROR contexts and surfaces them via contextErrorCount and loadersResults",async()=>{const t=new Error("token loader failure");o.getContexts.mockResolvedValue([l,{type:n.ClearSignContextType.ERROR,error:t}]);const d=await new r.BuildTransactionContextTask(a,s).run();(0,e.expect)(d.trustedNamePKICertificate).toEqual(C),(0,e.expect)(d.tlvDescriptor).toEqual(y),(0,e.expect)(d.contextErrorCount).toBe(1),(0,e.expect)(d.loadersResults).toEqual([{type:n.ClearSignContextType.ERROR,error:t}])}),(0,e.it)("returns empty trusted-name fields when owner info is not required and only errors are returned",async()=>{const t=new Error("solana context failure"),c={...s,options:{tokenAddress:void 0,createATA:void 0}};o.getContexts.mockResolvedValue([{type:n.ClearSignContextType.ERROR,error:t}]);const i=await new r.BuildTransactionContextTask(a,c).run();(0,e.expect)(i.trustedNamePKICertificate).toBeUndefined(),(0,e.expect)(i.tlvDescriptor).toBeUndefined(),(0,e.expect)(i.contextErrorCount).toBe(1),(0,e.expect)(i.loadersResults).toEqual([{type:n.ClearSignContextType.ERROR,error:t}])}),(0,e.it)("throws when owner info is required but no SOLANA_TRUSTED_NAME context was returned",async()=>{o.getContexts.mockResolvedValue([{type:n.ClearSignContextType.ERROR,error:new Error("PKI cert load failure")}]);const t=new r.BuildTransactionContextTask(a,s);await(0,e.expect)(t.run()).rejects.toThrow("[SignerSolana] BuildTransactionContextTask: owner info was required but could not be resolved")}),(0,e.it)("throws when owner info is required but contextModule returns an empty array",async()=>{o.getContexts.mockResolvedValue([]);const t=new r.BuildTransactionContextTask(a,s);await(0,e.expect)(t.run()).rejects.toThrow("[SignerSolana] BuildTransactionContextTask: owner info was required but could not be resolved")})});
|
|
2
2
|
//# sourceMappingURL=BuildTransactionContextTask.test.js.map
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"version": 3,
|
|
3
3
|
"sources": ["../../../../../src/internal/app-binder/task/BuildTransactionContextTask.test.ts"],
|
|
4
|
-
"sourcesContent": ["/* eslint-disable @typescript-eslint/no-explicit-any */\nimport {\n ClearSignContextType,\n type ContextModule,\n SolanaTransactionScanChainId,\n} from \"@ledgerhq/context-module\";\nimport {\n CommandResultFactory,\n DeviceModelId,\n type InternalApi,\n} from \"@ledgerhq/device-management-kit\";\nimport { beforeEach, describe, expect, it, vi } from \"vitest\";\n\nimport { GetChallengeCommand } from \"@internal/app-binder/command/GetChallengeCommand\";\n\nimport {\n BuildTransactionContextTask,\n type SolanaBuildContextResult,\n} from \"./BuildTransactionContextTask\";\n\nconst mockLoggerFactory = () => ({\n debug: vi.fn(),\n info: vi.fn(),\n warn: vi.fn(),\n error: vi.fn(),\n subscribers: [],\n});\n\nconst contextModuleMock: ContextModule = {\n getContexts: vi.fn(),\n} as unknown as ContextModule;\n\nconst trustedNamePayload = new Uint8Array([1, 2, 3]);\nconst trustedNameCert = {\n payload: new Uint8Array([0xaa, 0xbb]),\n keyUsageNumber: 1,\n};\n\nconst defaultArgs = {\n contextModule: contextModuleMock,\n loggerFactory: mockLoggerFactory,\n transactionBytes: new Uint8Array([0xde, 0xad, 0xbe, 0xef]),\n signerAddress: null,\n options: {\n tokenAddress: \"someAddress\",\n createATA: undefined,\n },\n};\n\nconst trustedNameSuccessContext = {\n type: ClearSignContextType.SOLANA_TRUSTED_NAME as const,\n payload: trustedNamePayload,\n certificate: trustedNameCert,\n};\n\nlet apiMock: InternalApi;\n\ndescribe(\"BuildTransactionContextTask\", () => {\n beforeEach(() => {\n vi.resetAllMocks();\n\n apiMock = {\n getDeviceSessionState: vi\n .fn()\n .mockReturnValue({ deviceModelId: DeviceModelId.NANO_X }),\n sendCommand: vi\n .fn()\n .mockResolvedValue(\n CommandResultFactory({ data: { challenge: \"someChallenge\" } }),\n ),\n } as unknown as InternalApi;\n });\n\n it(\"requests the challenge from the device\", async () => {\n (contextModuleMock.getContexts as any).mockResolvedValue([\n trustedNameSuccessContext,\n ]);\n\n const task = new BuildTransactionContextTask(apiMock, defaultArgs);\n await task.run();\n\n expect(apiMock.sendCommand).toHaveBeenCalledWith(\n expect.any(GetChallengeCommand),\n );\n });\n\n
|
|
5
|
-
"mappings": "aACA,IAAAA,EAIO,oCACPC,EAIO,2CACPC,EAAqD,kBAErDC,EAAoC,4DAEpCC,EAGO,yCAEP,MAAMC,EAAoB,KAAO,CAC/B,MAAO,KAAG,GAAG,EACb,KAAM,KAAG,GAAG,EACZ,KAAM,KAAG,GAAG,EACZ,MAAO,KAAG,GAAG,EACb,YAAa,CAAC,CAChB,GAEMC,EAAmC,CACvC,YAAa,KAAG,GAAG,CACrB,EAEMC,EAAqB,IAAI,WAAW,CAAC,EAAG,EAAG,CAAC,CAAC,EAC7CC,EAAkB,CACtB,QAAS,IAAI,WAAW,CAAC,IAAM,GAAI,CAAC,EACpC,eAAgB,CAClB,EAEMC,EAAc,CAClB,cAAeH,EACf,cAAeD,EACf,iBAAkB,IAAI,WAAW,CAAC,IAAM,IAAM,IAAM,GAAI,CAAC,EACzD,cAAe,KACf,QAAS,CACP,aAAc,cACd,UAAW,MACb,CACF,EAEMK,EAA4B,CAChC,KAAM,uBAAqB,oBAC3B,QAASH,EACT,YAAaC,CACf,EAEA,IAAIG,KAEJ,YAAS,8BAA+B,IAAM,IAC5C,cAAW,IAAM,CACf,KAAG,cAAc,EAEjBA,EAAU,CACR,sBAAuB,KACpB,GAAG,EACH,gBAAgB,CAAE,cAAe,gBAAc,MAAO,CAAC,EAC1D,YAAa,KACV,GAAG,EACH,qBACC,wBAAqB,CAAE,KAAM,CAAE,UAAW,eAAgB,CAAE,CAAC,CAC/D,CACJ,CACF,CAAC,KAED,MAAG,yCAA0C,SAAY,CACtDL,EAAkB,YAAoB,kBAAkB,CACvDI,CACF,CAAC,EAGD,MADa,IAAI,8BAA4BC,EAASF,CAAW,EACtD,IAAI,KAEf,UAAOE,EAAQ,WAAW,EAAE,qBAC1B,SAAO,IAAI,qBAAmB,CAChC,CACF,CAAC,
|
|
4
|
+
"sourcesContent": ["/* eslint-disable @typescript-eslint/no-explicit-any */\nimport {\n ClearSignContextType,\n type ContextModule,\n SolanaTransactionScanChainId,\n} from \"@ledgerhq/context-module\";\nimport {\n CommandResultFactory,\n DeviceModelId,\n type InternalApi,\n} from \"@ledgerhq/device-management-kit\";\nimport { beforeEach, describe, expect, it, vi } from \"vitest\";\n\nimport { GetChallengeCommand } from \"@internal/app-binder/command/GetChallengeCommand\";\n\nimport {\n BuildTransactionContextTask,\n type SolanaBuildContextResult,\n} from \"./BuildTransactionContextTask\";\n\nconst mockLoggerFactory = () => ({\n debug: vi.fn(),\n info: vi.fn(),\n warn: vi.fn(),\n error: vi.fn(),\n subscribers: [],\n});\n\nconst contextModuleMock: ContextModule = {\n getContexts: vi.fn(),\n} as unknown as ContextModule;\n\nconst trustedNamePayload = new Uint8Array([1, 2, 3]);\nconst trustedNameCert = {\n payload: new Uint8Array([0xaa, 0xbb]),\n keyUsageNumber: 1,\n};\n\nconst defaultArgs = {\n contextModule: contextModuleMock,\n loggerFactory: mockLoggerFactory,\n transactionBytes: new Uint8Array([0xde, 0xad, 0xbe, 0xef]),\n signerAddress: null,\n options: {\n tokenAddress: \"someAddress\",\n createATA: undefined,\n },\n};\n\nconst trustedNameSuccessContext = {\n type: ClearSignContextType.SOLANA_TRUSTED_NAME as const,\n payload: trustedNamePayload,\n certificate: trustedNameCert,\n};\n\nlet apiMock: InternalApi;\n\ndescribe(\"BuildTransactionContextTask\", () => {\n beforeEach(() => {\n vi.resetAllMocks();\n\n apiMock = {\n getDeviceSessionState: vi\n .fn()\n .mockReturnValue({ deviceModelId: DeviceModelId.NANO_X }),\n sendCommand: vi\n .fn()\n .mockResolvedValue(\n CommandResultFactory({ data: { challenge: \"someChallenge\" } }),\n ),\n } as unknown as InternalApi;\n });\n\n it(\"requests the challenge from the device\", async () => {\n (contextModuleMock.getContexts as any).mockResolvedValue([\n trustedNameSuccessContext,\n ]);\n\n const task = new BuildTransactionContextTask(apiMock, defaultArgs);\n await task.run();\n\n expect(apiMock.sendCommand).toHaveBeenCalledWith(\n expect.any(GetChallengeCommand),\n );\n });\n\n it(\"calls contextModule.getContexts with the active Solana context types (transaction-check temporarily disabled)\", async () => {\n (contextModuleMock.getContexts as any).mockResolvedValue([\n trustedNameSuccessContext,\n ]);\n\n const task = new BuildTransactionContextTask(apiMock, defaultArgs);\n await task.run();\n\n expect(contextModuleMock.getContexts).toHaveBeenCalledWith(\n {\n deviceModelId: DeviceModelId.NANO_X,\n tokenAddress: \"someAddress\",\n challenge: \"someChallenge\",\n createATA: undefined,\n tokenInternalId: undefined,\n templateId: undefined,\n transactionCheck: undefined,\n },\n [\n ClearSignContextType.SOLANA_TOKEN,\n ClearSignContextType.SOLANA_LIFI,\n ClearSignContextType.SOLANA_TRUSTED_NAME,\n ],\n );\n });\n\n it(\"derives transactionCheck from signerAddress and transactionBytes when address is provided\", async () => {\n (contextModuleMock.getContexts as any).mockResolvedValue([\n trustedNameSuccessContext,\n ]);\n\n const argsWithSigner = {\n ...defaultArgs,\n signerAddress: \"So1anaSignerPubKey111111111111111111111111111\",\n };\n\n const task = new BuildTransactionContextTask(apiMock, argsWithSigner);\n await task.run();\n\n expect(contextModuleMock.getContexts).toHaveBeenCalledWith(\n expect.objectContaining({\n transactionCheck: {\n from: \"So1anaSignerPubKey111111111111111111111111111\",\n transactionBytes: defaultArgs.transactionBytes,\n chain: SolanaTransactionScanChainId.MAINNET,\n },\n }),\n expect.any(Array),\n );\n });\n\n it(\"returns trustedName cert + tlvDescriptor when SOLANA_TRUSTED_NAME context is present\", async () => {\n (contextModuleMock.getContexts as any).mockResolvedValue([\n trustedNameSuccessContext,\n ]);\n\n const task = new BuildTransactionContextTask(apiMock, defaultArgs);\n const result = await task.run();\n\n expect(result).toEqual<SolanaBuildContextResult>({\n tlvDescriptor: trustedNamePayload,\n trustedNamePKICertificate: trustedNameCert,\n loadersResults: [],\n contextErrorCount: 0,\n });\n });\n\n it(\"includes SOLANA_TRANSACTION_CHECK results in loadersResults\", async () => {\n const txCheckContext = {\n type: ClearSignContextType.SOLANA_TRANSACTION_CHECK as const,\n payload: { descriptor: \"aabbccdd\" },\n certificate: { payload: new Uint8Array([0x99]), keyUsageNumber: 14 },\n };\n (contextModuleMock.getContexts as any).mockResolvedValue([\n trustedNameSuccessContext,\n txCheckContext,\n ]);\n\n const task = new BuildTransactionContextTask(apiMock, defaultArgs);\n const result = await task.run();\n\n expect(result.loadersResults).toEqual([txCheckContext]);\n expect(result.contextErrorCount).toBe(0);\n });\n\n it(\"includes SOLANA_TOKEN and SOLANA_LIFI results in loadersResults\", async () => {\n const tokenContext = {\n type: ClearSignContextType.SOLANA_TOKEN as const,\n payload: { solanaTokenDescriptor: { data: \"aa\", signature: \"bb\" } },\n certificate: undefined,\n };\n const lifiContext = {\n type: ClearSignContextType.SOLANA_LIFI as const,\n payload: { descriptors: {}, instructions: [] },\n certificate: undefined,\n };\n (contextModuleMock.getContexts as any).mockResolvedValue([\n trustedNameSuccessContext,\n tokenContext,\n lifiContext,\n ]);\n\n const task = new BuildTransactionContextTask(apiMock, defaultArgs);\n const result = await task.run();\n\n expect(result.loadersResults).toEqual([tokenContext, lifiContext]);\n });\n\n it(\"throws when challenge command fails\", async () => {\n (apiMock.sendCommand as any).mockResolvedValue(\n CommandResultFactory({\n error: { _tag: \"SomeError\", errorCode: 0x6a80, message: \"bad\" } as any,\n }),\n );\n\n const task = new BuildTransactionContextTask(apiMock, defaultArgs);\n\n await expect(task.run()).rejects.toThrow(\n \"Failed to get challenge from device\",\n );\n });\n\n it(\"counts ERROR contexts and surfaces them via contextErrorCount and loadersResults\", async () => {\n const error = new Error(\"token loader failure\");\n (contextModuleMock.getContexts as any).mockResolvedValue([\n trustedNameSuccessContext,\n { type: ClearSignContextType.ERROR, error },\n ]);\n\n const task = new BuildTransactionContextTask(apiMock, defaultArgs);\n const result = await task.run();\n\n expect(result.trustedNamePKICertificate).toEqual(trustedNameCert);\n expect(result.tlvDescriptor).toEqual(trustedNamePayload);\n expect(result.contextErrorCount).toBe(1);\n expect(result.loadersResults).toEqual([\n { type: ClearSignContextType.ERROR, error },\n ]);\n });\n\n it(\"returns empty trusted-name fields when owner info is not required and only errors are returned\", async () => {\n const error = new Error(\"solana context failure\");\n const argsWithoutOwnerInfo = {\n ...defaultArgs,\n options: { tokenAddress: undefined, createATA: undefined },\n };\n (contextModuleMock.getContexts as any).mockResolvedValue([\n { type: ClearSignContextType.ERROR, error },\n ]);\n\n const task = new BuildTransactionContextTask(apiMock, argsWithoutOwnerInfo);\n const result = await task.run();\n\n expect(result.trustedNamePKICertificate).toBeUndefined();\n expect(result.tlvDescriptor).toBeUndefined();\n expect(result.contextErrorCount).toBe(1);\n expect(result.loadersResults).toEqual([\n { type: ClearSignContextType.ERROR, error },\n ]);\n });\n\n it(\"throws when owner info is required but no SOLANA_TRUSTED_NAME context was returned\", async () => {\n (contextModuleMock.getContexts as any).mockResolvedValue([\n {\n type: ClearSignContextType.ERROR,\n error: new Error(\"PKI cert load failure\"),\n },\n ]);\n\n const task = new BuildTransactionContextTask(apiMock, defaultArgs);\n\n await expect(task.run()).rejects.toThrow(\n \"[SignerSolana] BuildTransactionContextTask: owner info was required but could not be resolved\",\n );\n });\n\n it(\"throws when owner info is required but contextModule returns an empty array\", async () => {\n (contextModuleMock.getContexts as any).mockResolvedValue([]);\n\n const task = new BuildTransactionContextTask(apiMock, defaultArgs);\n\n await expect(task.run()).rejects.toThrow(\n \"[SignerSolana] BuildTransactionContextTask: owner info was required but could not be resolved\",\n );\n });\n});\n"],
|
|
5
|
+
"mappings": "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",
|
|
6
6
|
"names": ["import_context_module", "import_device_management_kit", "import_vitest", "import_GetChallengeCommand", "import_BuildTransactionContextTask", "mockLoggerFactory", "contextModuleMock", "trustedNamePayload", "trustedNameCert", "defaultArgs", "trustedNameSuccessContext", "apiMock", "argsWithSigner", "result", "txCheckContext", "tokenContext", "lifiContext", "task", "error", "argsWithoutOwnerInfo"]
|
|
7
7
|
}
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
"use strict";var n=Object.defineProperty;var
|
|
1
|
+
"use strict";var n=Object.defineProperty;var s=Object.getOwnPropertyDescriptor;var m=Object.getOwnPropertyNames;var d=Object.prototype.hasOwnProperty;var p=(t,e)=>{for(var a in e)n(t,a,{get:e[a],enumerable:!0})},y=(t,e,a,r)=>{if(e&&typeof e=="object"||typeof e=="function")for(let i of m(e))!d.call(t,i)&&i!==a&&n(t,i,{get:()=>e[i],enumerable:!(r=s(e,i))||r.enumerable});return t};var c=t=>y(n({},"__esModule",{value:!0}),t);var C={};p(C,{loadCertificate:()=>f});module.exports=c(C);var o=require("@ledgerhq/device-management-kit");async function f(t,e,a){const r=await t.sendCommand(new o.LoadCertificateCommand({certificate:e.payload,keyUsage:e.keyUsageNumber}));if(!(0,o.isSuccessCommandResult)(r))throw new Error(`${a} (keyUsage=${e.keyUsageNumber})`)}0&&(module.exports={loadCertificate});
|
|
2
2
|
//# sourceMappingURL=loadCertificate.js.map
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"version": 3,
|
|
3
3
|
"sources": ["../../../../../../src/internal/app-binder/task/context-providers/loadCertificate.ts"],
|
|
4
|
-
"sourcesContent": ["import { type PkiCertificate } from \"@ledgerhq/context-module\";\nimport {\n type InternalApi,\n isSuccessCommandResult,\n LoadCertificateCommand,\n} from \"@ledgerhq/device-management-kit\";\n\nexport async function loadCertificate(\n api: InternalApi,\n certificate: PkiCertificate,\n errorMessage: string,\n): Promise<void> {\n const result = await api.sendCommand(\n new LoadCertificateCommand({\n certificate: certificate.payload,\n keyUsage: certificate.keyUsageNumber,\n }),\n );\n if (!isSuccessCommandResult(result)) {\n throw new Error(errorMessage);\n }\n}\n"],
|
|
5
|
-
"mappings": "yaAAA,IAAAA,EAAA,GAAAC,EAAAD,EAAA,qBAAAE,IAAA,eAAAC,EAAAH,GACA,IAAAI,EAIO,2CAEP,eAAsBF,EACpBG,EACAC,EACAC,EACe,CACf,MAAMC,EAAS,MAAMH,EAAI,YACvB,IAAI,yBAAuB,CACzB,YAAaC,EAAY,QACzB,SAAUA,EAAY,cACxB,CAAC,CACH,EACA,GAAI,IAAC,0BAAuBE,CAAM,EAChC,MAAM,IAAI,
|
|
4
|
+
"sourcesContent": ["import { type PkiCertificate } from \"@ledgerhq/context-module\";\nimport {\n type InternalApi,\n isSuccessCommandResult,\n LoadCertificateCommand,\n} from \"@ledgerhq/device-management-kit\";\n\nexport async function loadCertificate(\n api: InternalApi,\n certificate: PkiCertificate,\n errorMessage: string,\n): Promise<void> {\n const result = await api.sendCommand(\n new LoadCertificateCommand({\n certificate: certificate.payload,\n keyUsage: certificate.keyUsageNumber,\n }),\n );\n if (!isSuccessCommandResult(result)) {\n throw new Error(`${errorMessage} (keyUsage=${certificate.keyUsageNumber})`);\n }\n}\n"],
|
|
5
|
+
"mappings": "yaAAA,IAAAA,EAAA,GAAAC,EAAAD,EAAA,qBAAAE,IAAA,eAAAC,EAAAH,GACA,IAAAI,EAIO,2CAEP,eAAsBF,EACpBG,EACAC,EACAC,EACe,CACf,MAAMC,EAAS,MAAMH,EAAI,YACvB,IAAI,yBAAuB,CACzB,YAAaC,EAAY,QACzB,SAAUA,EAAY,cACxB,CAAC,CACH,EACA,GAAI,IAAC,0BAAuBE,CAAM,EAChC,MAAM,IAAI,MAAM,GAAGD,CAAY,cAAcD,EAAY,cAAc,GAAG,CAE9E",
|
|
6
6
|
"names": ["loadCertificate_exports", "__export", "loadCertificate", "__toCommonJS", "import_device_management_kit", "api", "certificate", "errorMessage", "result"]
|
|
7
7
|
}
|
package/lib/cjs/internal/app-binder/task/context-providers/provideTransactionCheckContext.js
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
"use strict";var s=Object.defineProperty;var h=Object.getOwnPropertyDescriptor;var l=Object.getOwnPropertyNames;var k=Object.prototype.hasOwnProperty;var
|
|
1
|
+
"use strict";var s=Object.defineProperty;var h=Object.getOwnPropertyDescriptor;var l=Object.getOwnPropertyNames;var k=Object.prototype.hasOwnProperty;var f=(t,e)=>{for(var n in e)s(t,n,{get:e[n],enumerable:!0})},S=(t,e,n,r)=>{if(e&&typeof e=="object"||typeof e=="function")for(let o of l(e))!k.call(t,o)&&o!==n&&s(t,o,{get:()=>e[o],enumerable:!(r=h(e,o))||r.enumerable});return t};var u=t=>S(s({},"__esModule",{value:!0}),t);var T={};f(T,{provideTransactionCheckContext:()=>x});module.exports=u(T);var a=require("@ledgerhq/device-management-kit"),d=require("../../../app-binder/command/ProvideWeb3CheckCommand"),C=require("../../../app-binder/task/SendCommandInChunksTask"),p=require("./loadCertificate");const x=async(t,{api:e,logger:n})=>{const{payload:r,certificate:o}=t;o&&await(0,p.loadCertificate)(e,o,"[SignerSolana] provideTransactionCheckContext: Failed to send web3-check certificate to device");const i=(0,a.hexaStringToBuffer)(r.descriptor);if(!i||i.length===0){n.warn("[provideTransactionCheckContext] descriptor could not be parsed, skipping");return}const m=await new C.SendCommandInChunksTask(e,{data:i,commandFactory:c=>new d.ProvideWeb3CheckCommand({payload:c.chunkedData,isFirstChunk:!c.extend,hasMore:c.more})}).run();if(!(0,a.isSuccessCommandResult)(m))throw new Error("[SignerSolana] provideTransactionCheckContext: Failed to send transaction-check descriptor to device")};0&&(module.exports={provideTransactionCheckContext});
|
|
2
2
|
//# sourceMappingURL=provideTransactionCheckContext.js.map
|
package/lib/cjs/internal/app-binder/task/context-providers/provideTransactionCheckContext.js.map
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"version": 3,
|
|
3
3
|
"sources": ["../../../../../../src/internal/app-binder/task/context-providers/provideTransactionCheckContext.ts"],
|
|
4
|
-
"sourcesContent": ["import {\n type ClearSignContextType,\n type SolanaTransactionCheckContextSuccess,\n} from \"@ledgerhq/context-module\";\nimport {\n hexaStringToBuffer,\n isSuccessCommandResult,\n} from \"@ledgerhq/device-management-kit\";\n\nimport { ProvideWeb3CheckCommand } from \"@internal/app-binder/command/ProvideWeb3CheckCommand\";\nimport { SendCommandInChunksTask } from \"@internal/app-binder/task/SendCommandInChunksTask\";\n\nimport { loadCertificate } from \"./loadCertificate\";\nimport { type ProvideContextHandler } from \"./provideContextTypes\";\n\nexport const provideTransactionCheckContext: ProvideContextHandler<\n ClearSignContextType.SOLANA_TRANSACTION_CHECK\n> = async (result: SolanaTransactionCheckContextSuccess, { api, logger }) => {\n const { payload, certificate } = result;\n\n if (
|
|
5
|
-
"mappings": "yaAAA,IAAAA,EAAA,GAAAC,EAAAD,EAAA,oCAAAE,IAAA,eAAAC,EAAAH,GAIA,IAAAI,EAGO,2CAEPC,EAAwC,gEACxCC,EAAwC,6DAExCC,EAAgC,6BAGzB,MAAML,EAET,MAAOM,EAA8C,CAAE,IAAAC,EAAK,OAAAC,CAAO,IAAM,CAC3E,KAAM,CAAE,QAAAC,EAAS,
|
|
6
|
-
"names": ["provideTransactionCheckContext_exports", "__export", "provideTransactionCheckContext", "__toCommonJS", "import_device_management_kit", "import_ProvideWeb3CheckCommand", "import_SendCommandInChunksTask", "import_loadCertificate", "result", "api", "logger", "payload", "
|
|
4
|
+
"sourcesContent": ["import {\n type ClearSignContextType,\n type SolanaTransactionCheckContextSuccess,\n} from \"@ledgerhq/context-module\";\nimport {\n hexaStringToBuffer,\n isSuccessCommandResult,\n} from \"@ledgerhq/device-management-kit\";\n\nimport { ProvideWeb3CheckCommand } from \"@internal/app-binder/command/ProvideWeb3CheckCommand\";\nimport { SendCommandInChunksTask } from \"@internal/app-binder/task/SendCommandInChunksTask\";\n\nimport { loadCertificate } from \"./loadCertificate\";\nimport { type ProvideContextHandler } from \"./provideContextTypes\";\n\nexport const provideTransactionCheckContext: ProvideContextHandler<\n ClearSignContextType.SOLANA_TRANSACTION_CHECK\n> = async (result: SolanaTransactionCheckContextSuccess, { api, logger }) => {\n const { payload, certificate: web3CheckCertificate } = result;\n\n if (web3CheckCertificate) {\n await loadCertificate(\n api,\n web3CheckCertificate,\n \"[SignerSolana] provideTransactionCheckContext: Failed to send web3-check certificate to device\",\n );\n }\n\n const descriptorBytes = hexaStringToBuffer(payload.descriptor);\n if (!descriptorBytes || descriptorBytes.length === 0) {\n logger.warn(\n \"[provideTransactionCheckContext] descriptor could not be parsed, skipping\",\n );\n return;\n }\n\n const chunkResult = await new SendCommandInChunksTask(api, {\n data: descriptorBytes,\n commandFactory: (args) =>\n new ProvideWeb3CheckCommand({\n payload: args.chunkedData,\n isFirstChunk: !args.extend,\n hasMore: args.more,\n }),\n }).run();\n\n if (!isSuccessCommandResult(chunkResult)) {\n throw new Error(\n \"[SignerSolana] provideTransactionCheckContext: Failed to send transaction-check descriptor to device\",\n );\n }\n};\n"],
|
|
5
|
+
"mappings": "yaAAA,IAAAA,EAAA,GAAAC,EAAAD,EAAA,oCAAAE,IAAA,eAAAC,EAAAH,GAIA,IAAAI,EAGO,2CAEPC,EAAwC,gEACxCC,EAAwC,6DAExCC,EAAgC,6BAGzB,MAAML,EAET,MAAOM,EAA8C,CAAE,IAAAC,EAAK,OAAAC,CAAO,IAAM,CAC3E,KAAM,CAAE,QAAAC,EAAS,YAAaC,CAAqB,EAAIJ,EAEnDI,GACF,QAAM,mBACJH,EACAG,EACA,gGACF,EAGF,MAAMC,KAAkB,sBAAmBF,EAAQ,UAAU,EAC7D,GAAI,CAACE,GAAmBA,EAAgB,SAAW,EAAG,CACpDH,EAAO,KACL,2EACF,EACA,MACF,CAEA,MAAMI,EAAc,MAAM,IAAI,0BAAwBL,EAAK,CACzD,KAAMI,EACN,eAAiBE,GACf,IAAI,0BAAwB,CAC1B,QAASA,EAAK,YACd,aAAc,CAACA,EAAK,OACpB,QAASA,EAAK,IAChB,CAAC,CACL,CAAC,EAAE,IAAI,EAEP,GAAI,IAAC,0BAAuBD,CAAW,EACrC,MAAM,IAAI,MACR,sGACF,CAEJ",
|
|
6
|
+
"names": ["provideTransactionCheckContext_exports", "__export", "provideTransactionCheckContext", "__toCommonJS", "import_device_management_kit", "import_ProvideWeb3CheckCommand", "import_SendCommandInChunksTask", "import_loadCertificate", "result", "api", "logger", "payload", "web3CheckCertificate", "descriptorBytes", "chunkResult", "args"]
|
|
7
7
|
}
|
package/lib/cjs/internal/app-binder/task/context-providers/provideTransactionCheckContext.test.js
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
"use strict";var r=require("@ledgerhq/context-module"),n=require("@ledgerhq/device-management-kit"),e=require("vitest"),m=require("../../../app-binder/command/ProvideWeb3CheckCommand"),c=require("./provideTransactionCheckContext");const p={debug:e.vi.fn(),info:e.vi.fn(),warn:e.vi.fn(),error:e.vi.fn(),subscribers:[]};(0,e.describe)("provideTransactionCheckContext",()=>{let a,s;const d=(0,n.CommandResultFactory)({data:void 0}),i={payload:new Uint8Array([222,173]),keyUsageNumber:14};(0,e.beforeEach)(()=>{e.vi.resetAllMocks(),a={sendCommand:e.vi.fn()},s={api:a,logger:p,normaliser:{},transactionBytes:new Uint8Array([240])}}),(0,e.it)("sends certificate then ProvideWeb3CheckCommand",async()=>{a.sendCommand.mockResolvedValueOnce(d).mockResolvedValueOnce(d);const t={type:r.ClearSignContextType.SOLANA_TRANSACTION_CHECK,payload:{descriptor:"aabbccdd"},certificate:i};await(0,c.provideTransactionCheckContext)(t,s),(0,e.expect)(a.sendCommand).toHaveBeenCalledTimes(2);const o=a.sendCommand.mock.calls[0][0];(0,e.expect)(o).toBeInstanceOf(n.LoadCertificateCommand),(0,e.expect)(o.args.certificate).toStrictEqual(i.payload),(0,e.expect)(o.args.keyUsage).toBe(i.keyUsageNumber);const l=a.sendCommand.mock.calls[1][0];(0,e.expect)(l).toBeInstanceOf(m.ProvideWeb3CheckCommand)}),(0,e.it)("throws when certificate load fails",async()=>{const t=(0,n.CommandResultFactory)({error:{_tag:"SomeError",errorCode:27264,message:"bad"}});a.sendCommand.mockResolvedValueOnce(t);const o={type:r.ClearSignContextType.SOLANA_TRANSACTION_CHECK,payload:{descriptor:"aabbccdd"},certificate:i};await(0,e.expect)((0,c.provideTransactionCheckContext)(o,s)).rejects.toThrow("Failed to send
|
|
1
|
+
"use strict";var r=require("@ledgerhq/context-module"),n=require("@ledgerhq/device-management-kit"),e=require("vitest"),m=require("../../../app-binder/command/ProvideWeb3CheckCommand"),c=require("./provideTransactionCheckContext");const p={debug:e.vi.fn(),info:e.vi.fn(),warn:e.vi.fn(),error:e.vi.fn(),subscribers:[]};(0,e.describe)("provideTransactionCheckContext",()=>{let a,s;const d=(0,n.CommandResultFactory)({data:void 0}),i={payload:new Uint8Array([222,173]),keyUsageNumber:14};(0,e.beforeEach)(()=>{e.vi.resetAllMocks(),a={sendCommand:e.vi.fn()},s={api:a,logger:p,normaliser:{},transactionBytes:new Uint8Array([240])}}),(0,e.it)("sends certificate then ProvideWeb3CheckCommand",async()=>{a.sendCommand.mockResolvedValueOnce(d).mockResolvedValueOnce(d);const t={type:r.ClearSignContextType.SOLANA_TRANSACTION_CHECK,payload:{descriptor:"aabbccdd"},certificate:i};await(0,c.provideTransactionCheckContext)(t,s),(0,e.expect)(a.sendCommand).toHaveBeenCalledTimes(2);const o=a.sendCommand.mock.calls[0][0];(0,e.expect)(o).toBeInstanceOf(n.LoadCertificateCommand),(0,e.expect)(o.args.certificate).toStrictEqual(i.payload),(0,e.expect)(o.args.keyUsage).toBe(i.keyUsageNumber);const l=a.sendCommand.mock.calls[1][0];(0,e.expect)(l).toBeInstanceOf(m.ProvideWeb3CheckCommand)}),(0,e.it)("throws when certificate load fails",async()=>{const t=(0,n.CommandResultFactory)({error:{_tag:"SomeError",errorCode:27264,message:"bad"}});a.sendCommand.mockResolvedValueOnce(t);const o={type:r.ClearSignContextType.SOLANA_TRANSACTION_CHECK,payload:{descriptor:"aabbccdd"},certificate:i};await(0,e.expect)((0,c.provideTransactionCheckContext)(o,s)).rejects.toThrow("Failed to send web3-check certificate to device")}),(0,e.it)("sends descriptor without certificate when certificate is absent",async()=>{a.sendCommand.mockResolvedValueOnce(d);const t={type:r.ClearSignContextType.SOLANA_TRANSACTION_CHECK,payload:{descriptor:"aabbccdd"},certificate:void 0};await(0,c.provideTransactionCheckContext)(t,s),(0,e.expect)(a.sendCommand).toHaveBeenCalledTimes(1);const o=a.sendCommand.mock.calls[0][0];(0,e.expect)(o).toBeInstanceOf(m.ProvideWeb3CheckCommand)}),(0,e.it)("chunks large descriptors across multiple APDU calls",async()=>{a.sendCommand.mockResolvedValue(d);const t="aa".repeat(n.APDU_MAX_PAYLOAD+10).padEnd((n.APDU_MAX_PAYLOAD+10)*2,"bb"),o={type:r.ClearSignContextType.SOLANA_TRANSACTION_CHECK,payload:{descriptor:t},certificate:void 0};await(0,c.provideTransactionCheckContext)(o,s),(0,e.expect)(a.sendCommand.mock.calls.length).toBeGreaterThanOrEqual(2);const l=a.sendCommand.mock.calls.map(C=>C[0]);(0,e.expect)(l.every(C=>C instanceof m.ProvideWeb3CheckCommand)).toBe(!0)}),(0,e.it)("throws when descriptor sending fails",async()=>{a.sendCommand.mockResolvedValueOnce((0,n.CommandResultFactory)({error:{_tag:"SomeError",errorCode:27264,message:"bad"}}));const t={type:r.ClearSignContextType.SOLANA_TRANSACTION_CHECK,payload:{descriptor:"aabbccdd"},certificate:void 0};await(0,e.expect)((0,c.provideTransactionCheckContext)(t,s)).rejects.toThrow("Failed to send transaction-check descriptor to device")}),(0,e.it)("warns and returns when descriptor is unparseable",async()=>{const t={type:r.ClearSignContextType.SOLANA_TRANSACTION_CHECK,payload:{descriptor:""},certificate:void 0};await(0,c.provideTransactionCheckContext)(t,s),(0,e.expect)(a.sendCommand).not.toHaveBeenCalled(),(0,e.expect)(p.warn).toHaveBeenCalledWith(e.expect.stringContaining("descriptor could not be parsed"))})});
|
|
2
2
|
//# sourceMappingURL=provideTransactionCheckContext.test.js.map
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"version": 3,
|
|
3
3
|
"sources": ["../../../../../../src/internal/app-binder/task/context-providers/provideTransactionCheckContext.test.ts"],
|
|
4
|
-
"sourcesContent": ["/* eslint-disable @typescript-eslint/no-explicit-any */\n\nimport { ClearSignContextType } from \"@ledgerhq/context-module\";\nimport {\n APDU_MAX_PAYLOAD,\n CommandResultFactory,\n LoadCertificateCommand,\n} from \"@ledgerhq/device-management-kit\";\nimport { beforeEach, describe, expect, it, type Mock, vi } from \"vitest\";\n\nimport { ProvideWeb3CheckCommand } from \"@internal/app-binder/command/ProvideWeb3CheckCommand\";\n\nimport { type ProvideContextDeps } from \"./provideContextTypes\";\nimport { provideTransactionCheckContext } from \"./provideTransactionCheckContext\";\n\nconst mockLogger = {\n debug: vi.fn(),\n info: vi.fn(),\n warn: vi.fn(),\n error: vi.fn(),\n subscribers: [],\n};\n\ndescribe(\"provideTransactionCheckContext\", () => {\n let api: { sendCommand: Mock };\n let deps: ProvideContextDeps;\n const success = CommandResultFactory({ data: undefined });\n\n const txCheckCert = {\n payload: new Uint8Array([0xde, 0xad]),\n keyUsageNumber: 14,\n } as const;\n\n beforeEach(() => {\n vi.resetAllMocks();\n api = { sendCommand: vi.fn() };\n deps = {\n api: api as any,\n logger: mockLogger as any,\n normaliser: {} as any,\n transactionBytes: new Uint8Array([0xf0]),\n };\n });\n\n it(\"sends certificate then ProvideWeb3CheckCommand\", async () => {\n api.sendCommand\n .mockResolvedValueOnce(success)\n .mockResolvedValueOnce(success);\n\n const result = {\n type: ClearSignContextType.SOLANA_TRANSACTION_CHECK as const,\n payload: { descriptor: \"aabbccdd\" },\n certificate: txCheckCert,\n };\n\n await provideTransactionCheckContext(result, deps);\n\n expect(api.sendCommand).toHaveBeenCalledTimes(2);\n\n const certCmd = api.sendCommand.mock.calls[0]![0]!;\n expect(certCmd).toBeInstanceOf(LoadCertificateCommand);\n expect(certCmd.args.certificate).toStrictEqual(txCheckCert.payload);\n expect(certCmd.args.keyUsage).toBe(txCheckCert.keyUsageNumber);\n\n const web3Cmd = api.sendCommand.mock.calls[1]![0]!;\n expect(web3Cmd).toBeInstanceOf(ProvideWeb3CheckCommand);\n });\n\n it(\"throws when certificate load fails\", async () => {\n const errorResult = CommandResultFactory({\n error: { _tag: \"SomeError\", errorCode: 0x6a80, message: \"bad\" },\n });\n api.sendCommand.mockResolvedValueOnce(errorResult);\n\n const result = {\n type: ClearSignContextType.SOLANA_TRANSACTION_CHECK as const,\n payload: { descriptor: \"aabbccdd\" },\n certificate: txCheckCert,\n };\n\n await expect(provideTransactionCheckContext(result, deps)).rejects.toThrow(\n \"Failed to send
|
|
5
|
-
"mappings": "aAEA,IAAAA,EAAqC,oCACrCC,EAIO,2CACPC,EAAgE,kBAEhEC,EAAwC,gEAGxCC,EAA+C,4CAE/C,MAAMC,EAAa,CACjB,MAAO,KAAG,GAAG,EACb,KAAM,KAAG,GAAG,EACZ,KAAM,KAAG,GAAG,EACZ,MAAO,KAAG,GAAG,EACb,YAAa,CAAC,CAChB,KAEA,YAAS,iCAAkC,IAAM,CAC/C,IAAIC,EACAC,EACJ,MAAMC,KAAU,wBAAqB,CAAE,KAAM,MAAU,CAAC,EAElDC,EAAc,CAClB,QAAS,IAAI,WAAW,CAAC,IAAM,GAAI,CAAC,EACpC,eAAgB,EAClB,KAEA,cAAW,IAAM,CACf,KAAG,cAAc,EACjBH,EAAM,CAAE,YAAa,KAAG,GAAG,CAAE,EAC7BC,EAAO,CACL,IAAKD,EACL,OAAQD,EACR,WAAY,CAAC,EACb,iBAAkB,IAAI,WAAW,CAAC,GAAI,CAAC,CACzC,CACF,CAAC,KAED,MAAG,iDAAkD,SAAY,CAC/DC,EAAI,YACD,sBAAsBE,CAAO,EAC7B,sBAAsBA,CAAO,EAEhC,MAAME,EAAS,CACb,KAAM,uBAAqB,yBAC3B,QAAS,CAAE,WAAY,UAAW,EAClC,YAAaD,CACf,EAEA,QAAM,kCAA+BC,EAAQH,CAAI,KAEjD,UAAOD,EAAI,WAAW,EAAE,sBAAsB,CAAC,EAE/C,MAAMK,EAAUL,EAAI,YAAY,KAAK,MAAM,CAAC,EAAG,CAAC,KAChD,UAAOK,CAAO,EAAE,eAAe,wBAAsB,KACrD,UAAOA,EAAQ,KAAK,WAAW,EAAE,cAAcF,EAAY,OAAO,KAClE,UAAOE,EAAQ,KAAK,QAAQ,EAAE,KAAKF,EAAY,cAAc,EAE7D,MAAMG,EAAUN,EAAI,YAAY,KAAK,MAAM,CAAC,EAAG,CAAC,KAChD,UAAOM,CAAO,EAAE,eAAe,yBAAuB,CACxD,CAAC,KAED,MAAG,qCAAsC,SAAY,CACnD,MAAMC,KAAc,wBAAqB,CACvC,MAAO,CAAE,KAAM,YAAa,UAAW,MAAQ,QAAS,KAAM,CAChE,CAAC,EACDP,EAAI,YAAY,sBAAsBO,CAAW,EAEjD,MAAMH,EAAS,CACb,KAAM,uBAAqB,yBAC3B,QAAS,CAAE,WAAY,UAAW,EAClC,YAAaD,CACf,EAEA,QAAM,aAAO,kCAA+BC,EAAQH,CAAI,CAAC,EAAE,QAAQ,QACjE,
|
|
4
|
+
"sourcesContent": ["/* eslint-disable @typescript-eslint/no-explicit-any */\n\nimport { ClearSignContextType } from \"@ledgerhq/context-module\";\nimport {\n APDU_MAX_PAYLOAD,\n CommandResultFactory,\n LoadCertificateCommand,\n} from \"@ledgerhq/device-management-kit\";\nimport { beforeEach, describe, expect, it, type Mock, vi } from \"vitest\";\n\nimport { ProvideWeb3CheckCommand } from \"@internal/app-binder/command/ProvideWeb3CheckCommand\";\n\nimport { type ProvideContextDeps } from \"./provideContextTypes\";\nimport { provideTransactionCheckContext } from \"./provideTransactionCheckContext\";\n\nconst mockLogger = {\n debug: vi.fn(),\n info: vi.fn(),\n warn: vi.fn(),\n error: vi.fn(),\n subscribers: [],\n};\n\ndescribe(\"provideTransactionCheckContext\", () => {\n let api: { sendCommand: Mock };\n let deps: ProvideContextDeps;\n const success = CommandResultFactory({ data: undefined });\n\n const txCheckCert = {\n payload: new Uint8Array([0xde, 0xad]),\n keyUsageNumber: 14,\n } as const;\n\n beforeEach(() => {\n vi.resetAllMocks();\n api = { sendCommand: vi.fn() };\n deps = {\n api: api as any,\n logger: mockLogger as any,\n normaliser: {} as any,\n transactionBytes: new Uint8Array([0xf0]),\n };\n });\n\n it(\"sends certificate then ProvideWeb3CheckCommand\", async () => {\n api.sendCommand\n .mockResolvedValueOnce(success)\n .mockResolvedValueOnce(success);\n\n const result = {\n type: ClearSignContextType.SOLANA_TRANSACTION_CHECK as const,\n payload: { descriptor: \"aabbccdd\" },\n certificate: txCheckCert,\n };\n\n await provideTransactionCheckContext(result, deps);\n\n expect(api.sendCommand).toHaveBeenCalledTimes(2);\n\n const certCmd = api.sendCommand.mock.calls[0]![0]!;\n expect(certCmd).toBeInstanceOf(LoadCertificateCommand);\n expect(certCmd.args.certificate).toStrictEqual(txCheckCert.payload);\n expect(certCmd.args.keyUsage).toBe(txCheckCert.keyUsageNumber);\n\n const web3Cmd = api.sendCommand.mock.calls[1]![0]!;\n expect(web3Cmd).toBeInstanceOf(ProvideWeb3CheckCommand);\n });\n\n it(\"throws when certificate load fails\", async () => {\n const errorResult = CommandResultFactory({\n error: { _tag: \"SomeError\", errorCode: 0x6a80, message: \"bad\" },\n });\n api.sendCommand.mockResolvedValueOnce(errorResult);\n\n const result = {\n type: ClearSignContextType.SOLANA_TRANSACTION_CHECK as const,\n payload: { descriptor: \"aabbccdd\" },\n certificate: txCheckCert,\n };\n\n await expect(provideTransactionCheckContext(result, deps)).rejects.toThrow(\n \"Failed to send web3-check certificate to device\",\n );\n });\n\n it(\"sends descriptor without certificate when certificate is absent\", async () => {\n api.sendCommand.mockResolvedValueOnce(success);\n\n const result = {\n type: ClearSignContextType.SOLANA_TRANSACTION_CHECK as const,\n payload: { descriptor: \"aabbccdd\" },\n certificate: undefined,\n };\n\n await provideTransactionCheckContext(result as any, deps);\n\n expect(api.sendCommand).toHaveBeenCalledTimes(1);\n\n const web3Cmd = api.sendCommand.mock.calls[0]![0]!;\n expect(web3Cmd).toBeInstanceOf(ProvideWeb3CheckCommand);\n });\n\n it(\"chunks large descriptors across multiple APDU calls\", async () => {\n api.sendCommand.mockResolvedValue(success);\n\n const largeDescriptorHex = \"aa\"\n .repeat(APDU_MAX_PAYLOAD + 10)\n .padEnd((APDU_MAX_PAYLOAD + 10) * 2, \"bb\");\n const result = {\n type: ClearSignContextType.SOLANA_TRANSACTION_CHECK as const,\n payload: { descriptor: largeDescriptorHex },\n certificate: undefined,\n };\n\n await provideTransactionCheckContext(result as any, deps);\n\n expect(api.sendCommand.mock.calls.length).toBeGreaterThanOrEqual(2);\n\n const allCmds = api.sendCommand.mock.calls.map(\n (c: any[]) => c[0] as ProvideWeb3CheckCommand,\n );\n expect(allCmds.every((cmd) => cmd instanceof ProvideWeb3CheckCommand)).toBe(\n true,\n );\n });\n\n it(\"throws when descriptor sending fails\", async () => {\n api.sendCommand.mockResolvedValueOnce(\n CommandResultFactory({\n error: { _tag: \"SomeError\", errorCode: 0x6a80, message: \"bad\" },\n }),\n );\n\n const result = {\n type: ClearSignContextType.SOLANA_TRANSACTION_CHECK as const,\n payload: { descriptor: \"aabbccdd\" },\n certificate: undefined,\n };\n\n await expect(\n provideTransactionCheckContext(result as any, deps),\n ).rejects.toThrow(\"Failed to send transaction-check descriptor to device\");\n });\n\n it(\"warns and returns when descriptor is unparseable\", async () => {\n const result = {\n type: ClearSignContextType.SOLANA_TRANSACTION_CHECK as const,\n payload: { descriptor: \"\" },\n certificate: undefined,\n };\n\n await provideTransactionCheckContext(result as any, deps);\n\n expect(api.sendCommand).not.toHaveBeenCalled();\n expect(mockLogger.warn).toHaveBeenCalledWith(\n expect.stringContaining(\"descriptor could not be parsed\"),\n );\n });\n});\n"],
|
|
5
|
+
"mappings": "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",
|
|
6
6
|
"names": ["import_context_module", "import_device_management_kit", "import_vitest", "import_ProvideWeb3CheckCommand", "import_provideTransactionCheckContext", "mockLogger", "api", "deps", "success", "txCheckCert", "result", "certCmd", "web3Cmd", "errorResult", "largeDescriptorHex", "allCmds", "c", "cmd"]
|
|
7
7
|
}
|
package/lib/cjs/package.json
CHANGED
|
@@ -64,5 +64,5 @@
|
|
|
64
64
|
"watch:builds": "pnpm ldmk-tool watch --entryPoints src/index.ts,src/**/*.ts --tsconfig tsconfig.prod.json",
|
|
65
65
|
"watch:types": "concurrently \"tsc --watch -p tsconfig.prod.json\" \"tsc-alias --watch -p tsconfig.prod.json\""
|
|
66
66
|
},
|
|
67
|
-
"version": "1.9.
|
|
67
|
+
"version": "1.9.1"
|
|
68
68
|
}
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import{ClearSignContextType as e,SolanaTransactionScanChainId as
|
|
1
|
+
import{ClearSignContextType as e,SolanaTransactionScanChainId as C}from"@ledgerhq/context-module";import{isSuccessCommandResult as p}from"@ledgerhq/device-management-kit";import{GetChallengeCommand as T}from"../../app-binder/command/GetChallengeCommand";class m{constructor(a,t){this.api=a;this.args=t;this._logger=t.loggerFactory("BuildTransactionContextTask")}_logger;async run(){this._logger.debug("[run] Starting BuildTransactionContextTask");const{contextModule:a,options:t}=this.args,c=this.api.getDeviceSessionState();let s;const i=await this.api.sendCommand(new T);if(p(i))s=i.data.challenge;else throw new Error("Failed to get challenge from device");const d=this.args.signerAddress?{from:this.args.signerAddress,transactionBytes:this.args.transactionBytes,chain:C.MAINNET}:void 0,l={deviceModelId:c.deviceModelId,tokenAddress:t.tokenAddress,challenge:s,createATA:t.createATA,tokenInternalId:t.tokenInternalId,templateId:t.templateId,transactionCheck:d};this._logger.debug("[run] Calling contextModule.getContexts for Solana",{data:{args:l}});const o=await a.getContexts(l,[e.SOLANA_TOKEN,e.SOLANA_LIFI,e.SOLANA_TRUSTED_NAME]);this._logger.debug("[run] Solana context result",{data:{contexts:o}});const g=o.filter(n=>n.type===e.ERROR).length,r=o.find(n=>n.type===e.SOLANA_TRUSTED_NAME),u=r?.certificate,A=r?.payload;if(!!(t.tokenAddress||t.createATA)&&r===void 0)throw new Error("[SignerSolana] BuildTransactionContextTask: owner info was required but could not be resolved");const S=o.filter(n=>n.type===e.ERROR||n.type===e.SOLANA_TOKEN||n.type===e.SOLANA_LIFI||n.type===e.SOLANA_TRANSACTION_CHECK);return{trustedNamePKICertificate:u,tlvDescriptor:A,loadersResults:S,contextErrorCount:g}}}export{m as BuildTransactionContextTask};
|
|
2
2
|
//# sourceMappingURL=BuildTransactionContextTask.js.map
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"version": 3,
|
|
3
3
|
"sources": ["../../../../../src/internal/app-binder/task/BuildTransactionContextTask.ts"],
|
|
4
|
-
"sourcesContent": ["import {\n type ClearSignContextSuccess,\n ClearSignContextType,\n type ContextModule,\n type LoaderResult,\n type SolanaTransactionContextResultSuccess,\n SolanaTransactionScanChainId,\n} from \"@ledgerhq/context-module\";\nimport {\n type InternalApi,\n isSuccessCommandResult,\n type LoggerPublisherService,\n} from \"@ledgerhq/device-management-kit\";\n\nimport { type TransactionResolutionContext } from \"@api/model/TransactionResolutionContext\";\nimport { GetChallengeCommand } from \"@internal/app-binder/command/GetChallengeCommand\";\
|
|
5
|
-
"mappings": "AAAA,OAEE,wBAAAA,EAIA,gCAAAC,MACK,2BACP,OAEE,0BAAAC,MAEK,kCAGP,OAAS,uBAAAC,MAA2B,
|
|
6
|
-
"names": ["ClearSignContextType", "SolanaTransactionScanChainId", "isSuccessCommandResult", "GetChallengeCommand", "
|
|
4
|
+
"sourcesContent": ["import {\n type ClearSignContextSuccess,\n ClearSignContextType,\n type ContextModule,\n type LoaderResult,\n type SolanaTransactionContextResultSuccess,\n SolanaTransactionScanChainId,\n} from \"@ledgerhq/context-module\";\nimport {\n type InternalApi,\n isSuccessCommandResult,\n type LoggerPublisherService,\n} from \"@ledgerhq/device-management-kit\";\n\nimport { type TransactionResolutionContext } from \"@api/model/TransactionResolutionContext\";\nimport { GetChallengeCommand } from \"@internal/app-binder/command/GetChallengeCommand\";\n\nexport type { SolanaTransactionContextResultSuccess as SolanaBuildContextResult };\n\nexport type BuildTransactionContextTaskArgs = {\n readonly contextModule: ContextModule;\n readonly options: TransactionResolutionContext;\n readonly transactionBytes: Uint8Array;\n readonly signerAddress: string | null;\n readonly loggerFactory: (tag: string) => LoggerPublisherService;\n};\n\nexport class BuildTransactionContextTask {\n private readonly _logger: LoggerPublisherService;\n constructor(\n private readonly api: InternalApi,\n private readonly args: BuildTransactionContextTaskArgs,\n ) {\n this._logger = args.loggerFactory(\"BuildTransactionContextTask\");\n }\n\n async run(): Promise<SolanaTransactionContextResultSuccess> {\n this._logger.debug(\"[run] Starting BuildTransactionContextTask\");\n const { contextModule, options } = this.args;\n const deviceState = this.api.getDeviceSessionState();\n\n // get challenge\n let challenge: string | undefined;\n const challengeRes = await this.api.sendCommand(new GetChallengeCommand());\n if (isSuccessCommandResult(challengeRes)) {\n challenge = challengeRes.data.challenge;\n } else {\n throw new Error(\"Failed to get challenge from device\");\n }\n\n const transactionCheck = this.args.signerAddress\n ? {\n from: this.args.signerAddress,\n transactionBytes: this.args.transactionBytes,\n chain: SolanaTransactionScanChainId.MAINNET,\n }\n : undefined;\n\n const contextModuleGetSolanaContextArgs = {\n deviceModelId: deviceState.deviceModelId,\n tokenAddress: options.tokenAddress,\n challenge,\n createATA: options.createATA,\n tokenInternalId: options.tokenInternalId,\n templateId: options.templateId,\n transactionCheck,\n };\n // get Solana context\n this._logger.debug(\"[run] Calling contextModule.getContexts for Solana\", {\n data: {\n args: contextModuleGetSolanaContextArgs,\n },\n });\n\n const contexts = await contextModule.getContexts(\n contextModuleGetSolanaContextArgs,\n [\n ClearSignContextType.SOLANA_TOKEN,\n ClearSignContextType.SOLANA_LIFI,\n ClearSignContextType.SOLANA_TRUSTED_NAME,\n // !! TODO-WEB3CHECK FLIP THIS BACK ONCE TRANSACTION CHECK IS READY,\n // TO BE KEEPT OFF FOR NOW\n //ClearSignContextType.SOLANA_TRANSACTION_CHECK,\n ],\n );\n\n this._logger.debug(\"[run] Solana context result\", {\n data: { contexts },\n });\n\n const contextErrorCount = contexts.filter(\n (contextResponseItem) =>\n contextResponseItem.type === ClearSignContextType.ERROR,\n ).length;\n\n const trustedNameCtx = contexts.find(\n (\n contextResponseItem,\n ): contextResponseItem is ClearSignContextSuccess<ClearSignContextType.SOLANA_TRUSTED_NAME> =>\n contextResponseItem.type === ClearSignContextType.SOLANA_TRUSTED_NAME,\n );\n const trustedNamePKICertificate = trustedNameCtx?.certificate;\n const tlvDescriptor = trustedNameCtx?.payload;\n\n const ownerInfoRequired = !!(options.tokenAddress || options.createATA);\n if (ownerInfoRequired && trustedNameCtx === undefined) {\n throw new Error(\n \"[SignerSolana] BuildTransactionContextTask: owner info was required but could not be resolved\",\n );\n }\n\n const loadersResults = contexts.filter(\n (contextResponseItem): contextResponseItem is LoaderResult =>\n contextResponseItem.type === ClearSignContextType.ERROR ||\n contextResponseItem.type === ClearSignContextType.SOLANA_TOKEN ||\n contextResponseItem.type === ClearSignContextType.SOLANA_LIFI ||\n contextResponseItem.type ===\n ClearSignContextType.SOLANA_TRANSACTION_CHECK,\n );\n\n return {\n trustedNamePKICertificate,\n tlvDescriptor,\n loadersResults,\n contextErrorCount,\n };\n }\n}\n"],
|
|
5
|
+
"mappings": "AAAA,OAEE,wBAAAA,EAIA,gCAAAC,MACK,2BACP,OAEE,0BAAAC,MAEK,kCAGP,OAAS,uBAAAC,MAA2B,mDAY7B,MAAMC,CAA4B,CAEvC,YACmBC,EACAC,EACjB,CAFiB,SAAAD,EACA,UAAAC,EAEjB,KAAK,QAAUA,EAAK,cAAc,6BAA6B,CACjE,CANiB,QAQjB,MAAM,KAAsD,CAC1D,KAAK,QAAQ,MAAM,4CAA4C,EAC/D,KAAM,CAAE,cAAAC,EAAe,QAAAC,CAAQ,EAAI,KAAK,KAClCC,EAAc,KAAK,IAAI,sBAAsB,EAGnD,IAAIC,EACJ,MAAMC,EAAe,MAAM,KAAK,IAAI,YAAY,IAAIR,CAAqB,EACzE,GAAID,EAAuBS,CAAY,EACrCD,EAAYC,EAAa,KAAK,cAE9B,OAAM,IAAI,MAAM,qCAAqC,EAGvD,MAAMC,EAAmB,KAAK,KAAK,cAC/B,CACE,KAAM,KAAK,KAAK,cAChB,iBAAkB,KAAK,KAAK,iBAC5B,MAAOX,EAA6B,OACtC,EACA,OAEEY,EAAoC,CACxC,cAAeJ,EAAY,cAC3B,aAAcD,EAAQ,aACtB,UAAAE,EACA,UAAWF,EAAQ,UACnB,gBAAiBA,EAAQ,gBACzB,WAAYA,EAAQ,WACpB,iBAAAI,CACF,EAEA,KAAK,QAAQ,MAAM,qDAAsD,CACvE,KAAM,CACJ,KAAMC,CACR,CACF,CAAC,EAED,MAAMC,EAAW,MAAMP,EAAc,YACnCM,EACA,CACEb,EAAqB,aACrBA,EAAqB,YACrBA,EAAqB,mBAIvB,CACF,EAEA,KAAK,QAAQ,MAAM,8BAA+B,CAChD,KAAM,CAAE,SAAAc,CAAS,CACnB,CAAC,EAED,MAAMC,EAAoBD,EAAS,OAChCE,GACCA,EAAoB,OAAShB,EAAqB,KACtD,EAAE,OAEIiB,EAAiBH,EAAS,KAE5BE,GAEAA,EAAoB,OAAShB,EAAqB,mBACtD,EACMkB,EAA4BD,GAAgB,YAC5CE,EAAgBF,GAAgB,QAGtC,GAD0B,CAAC,EAAET,EAAQ,cAAgBA,EAAQ,YACpCS,IAAmB,OAC1C,MAAM,IAAI,MACR,+FACF,EAGF,MAAMG,EAAiBN,EAAS,OAC7BE,GACCA,EAAoB,OAAShB,EAAqB,OAClDgB,EAAoB,OAAShB,EAAqB,cAClDgB,EAAoB,OAAShB,EAAqB,aAClDgB,EAAoB,OAClBhB,EAAqB,wBAC3B,EAEA,MAAO,CACL,0BAAAkB,EACA,cAAAC,EACA,eAAAC,EACA,kBAAAL,CACF,CACF,CACF",
|
|
6
|
+
"names": ["ClearSignContextType", "SolanaTransactionScanChainId", "isSuccessCommandResult", "GetChallengeCommand", "BuildTransactionContextTask", "api", "args", "contextModule", "options", "deviceState", "challenge", "challengeRes", "transactionCheck", "contextModuleGetSolanaContextArgs", "contexts", "contextErrorCount", "contextResponseItem", "trustedNameCtx", "trustedNamePKICertificate", "tlvDescriptor", "loadersResults"]
|
|
7
7
|
}
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import{ClearSignContextType as
|
|
1
|
+
import{ClearSignContextType as s,SolanaTransactionScanChainId as w}from"@ledgerhq/context-module";import{CommandResultFactory as A,DeviceModelId as k}from"@ledgerhq/device-management-kit";import{beforeEach as x,describe as f,expect as t,it as r,vi as i}from"vitest";import{GetChallengeCommand as R}from"../../app-binder/command/GetChallengeCommand";import{BuildTransactionContextTask as c}from"./BuildTransactionContextTask";const g=()=>({debug:i.fn(),info:i.fn(),warn:i.fn(),error:i.fn(),subscribers:[]}),a={getContexts:i.fn()},C=new Uint8Array([1,2,3]),m={payload:new Uint8Array([170,187]),keyUsageNumber:1},o={contextModule:a,loggerFactory:g,transactionBytes:new Uint8Array([222,173,190,239]),signerAddress:null,options:{tokenAddress:"someAddress",createATA:void 0}},u={type:s.SOLANA_TRUSTED_NAME,payload:C,certificate:m};let n;f("BuildTransactionContextTask",()=>{x(()=>{i.resetAllMocks(),n={getDeviceSessionState:i.fn().mockReturnValue({deviceModelId:k.NANO_X}),sendCommand:i.fn().mockResolvedValue(A({data:{challenge:"someChallenge"}}))}}),r("requests the challenge from the device",async()=>{a.getContexts.mockResolvedValue([u]),await new c(n,o).run(),t(n.sendCommand).toHaveBeenCalledWith(t.any(R))}),r("calls contextModule.getContexts with the active Solana context types (transaction-check temporarily disabled)",async()=>{a.getContexts.mockResolvedValue([u]),await new c(n,o).run(),t(a.getContexts).toHaveBeenCalledWith({deviceModelId:k.NANO_X,tokenAddress:"someAddress",challenge:"someChallenge",createATA:void 0,tokenInternalId:void 0,templateId:void 0,transactionCheck:void 0},[s.SOLANA_TOKEN,s.SOLANA_LIFI,s.SOLANA_TRUSTED_NAME])}),r("derives transactionCheck from signerAddress and transactionBytes when address is provided",async()=>{a.getContexts.mockResolvedValue([u]);const e={...o,signerAddress:"So1anaSignerPubKey111111111111111111111111111"};await new c(n,e).run(),t(a.getContexts).toHaveBeenCalledWith(t.objectContaining({transactionCheck:{from:"So1anaSignerPubKey111111111111111111111111111",transactionBytes:o.transactionBytes,chain:w.MAINNET}}),t.any(Array))}),r("returns trustedName cert + tlvDescriptor when SOLANA_TRUSTED_NAME context is present",async()=>{a.getContexts.mockResolvedValue([u]);const d=await new c(n,o).run();t(d).toEqual({tlvDescriptor:C,trustedNamePKICertificate:m,loadersResults:[],contextErrorCount:0})}),r("includes SOLANA_TRANSACTION_CHECK results in loadersResults",async()=>{const e={type:s.SOLANA_TRANSACTION_CHECK,payload:{descriptor:"aabbccdd"},certificate:{payload:new Uint8Array([153]),keyUsageNumber:14}};a.getContexts.mockResolvedValue([u,e]);const l=await new c(n,o).run();t(l.loadersResults).toEqual([e]),t(l.contextErrorCount).toBe(0)}),r("includes SOLANA_TOKEN and SOLANA_LIFI results in loadersResults",async()=>{const e={type:s.SOLANA_TOKEN,payload:{solanaTokenDescriptor:{data:"aa",signature:"bb"}},certificate:void 0},d={type:s.SOLANA_LIFI,payload:{descriptors:{},instructions:[]},certificate:void 0};a.getContexts.mockResolvedValue([u,e,d]);const y=await new c(n,o).run();t(y.loadersResults).toEqual([e,d])}),r("throws when challenge command fails",async()=>{n.sendCommand.mockResolvedValue(A({error:{_tag:"SomeError",errorCode:27264,message:"bad"}}));const e=new c(n,o);await t(e.run()).rejects.toThrow("Failed to get challenge from device")}),r("counts ERROR contexts and surfaces them via contextErrorCount and loadersResults",async()=>{const e=new Error("token loader failure");a.getContexts.mockResolvedValue([u,{type:s.ERROR,error:e}]);const l=await new c(n,o).run();t(l.trustedNamePKICertificate).toEqual(m),t(l.tlvDescriptor).toEqual(C),t(l.contextErrorCount).toBe(1),t(l.loadersResults).toEqual([{type:s.ERROR,error:e}])}),r("returns empty trusted-name fields when owner info is not required and only errors are returned",async()=>{const e=new Error("solana context failure"),d={...o,options:{tokenAddress:void 0,createATA:void 0}};a.getContexts.mockResolvedValue([{type:s.ERROR,error:e}]);const y=await new c(n,d).run();t(y.trustedNamePKICertificate).toBeUndefined(),t(y.tlvDescriptor).toBeUndefined(),t(y.contextErrorCount).toBe(1),t(y.loadersResults).toEqual([{type:s.ERROR,error:e}])}),r("throws when owner info is required but no SOLANA_TRUSTED_NAME context was returned",async()=>{a.getContexts.mockResolvedValue([{type:s.ERROR,error:new Error("PKI cert load failure")}]);const e=new c(n,o);await t(e.run()).rejects.toThrow("[SignerSolana] BuildTransactionContextTask: owner info was required but could not be resolved")}),r("throws when owner info is required but contextModule returns an empty array",async()=>{a.getContexts.mockResolvedValue([]);const e=new c(n,o);await t(e.run()).rejects.toThrow("[SignerSolana] BuildTransactionContextTask: owner info was required but could not be resolved")})});
|
|
2
2
|
//# sourceMappingURL=BuildTransactionContextTask.test.js.map
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"version": 3,
|
|
3
3
|
"sources": ["../../../../../src/internal/app-binder/task/BuildTransactionContextTask.test.ts"],
|
|
4
|
-
"sourcesContent": ["/* eslint-disable @typescript-eslint/no-explicit-any */\nimport {\n ClearSignContextType,\n type ContextModule,\n SolanaTransactionScanChainId,\n} from \"@ledgerhq/context-module\";\nimport {\n CommandResultFactory,\n DeviceModelId,\n type InternalApi,\n} from \"@ledgerhq/device-management-kit\";\nimport { beforeEach, describe, expect, it, vi } from \"vitest\";\n\nimport { GetChallengeCommand } from \"@internal/app-binder/command/GetChallengeCommand\";\n\nimport {\n BuildTransactionContextTask,\n type SolanaBuildContextResult,\n} from \"./BuildTransactionContextTask\";\n\nconst mockLoggerFactory = () => ({\n debug: vi.fn(),\n info: vi.fn(),\n warn: vi.fn(),\n error: vi.fn(),\n subscribers: [],\n});\n\nconst contextModuleMock: ContextModule = {\n getContexts: vi.fn(),\n} as unknown as ContextModule;\n\nconst trustedNamePayload = new Uint8Array([1, 2, 3]);\nconst trustedNameCert = {\n payload: new Uint8Array([0xaa, 0xbb]),\n keyUsageNumber: 1,\n};\n\nconst defaultArgs = {\n contextModule: contextModuleMock,\n loggerFactory: mockLoggerFactory,\n transactionBytes: new Uint8Array([0xde, 0xad, 0xbe, 0xef]),\n signerAddress: null,\n options: {\n tokenAddress: \"someAddress\",\n createATA: undefined,\n },\n};\n\nconst trustedNameSuccessContext = {\n type: ClearSignContextType.SOLANA_TRUSTED_NAME as const,\n payload: trustedNamePayload,\n certificate: trustedNameCert,\n};\n\nlet apiMock: InternalApi;\n\ndescribe(\"BuildTransactionContextTask\", () => {\n beforeEach(() => {\n vi.resetAllMocks();\n\n apiMock = {\n getDeviceSessionState: vi\n .fn()\n .mockReturnValue({ deviceModelId: DeviceModelId.NANO_X }),\n sendCommand: vi\n .fn()\n .mockResolvedValue(\n CommandResultFactory({ data: { challenge: \"someChallenge\" } }),\n ),\n } as unknown as InternalApi;\n });\n\n it(\"requests the challenge from the device\", async () => {\n (contextModuleMock.getContexts as any).mockResolvedValue([\n trustedNameSuccessContext,\n ]);\n\n const task = new BuildTransactionContextTask(apiMock, defaultArgs);\n await task.run();\n\n expect(apiMock.sendCommand).toHaveBeenCalledWith(\n expect.any(GetChallengeCommand),\n );\n });\n\n
|
|
5
|
-
"mappings": "AACA,OACE,wBAAAA,EAEA,gCAAAC,MACK,2BACP,OACE,wBAAAC,EACA,iBAAAC,MAEK,kCACP,OAAS,cAAAC,EAAY,YAAAC,EAAU,UAAAC,EAAQ,MAAAC,EAAI,MAAAC,MAAU,SAErD,OAAS,uBAAAC,MAA2B,mDAEpC,OACE,+BAAAC,MAEK,gCAEP,MAAMC,EAAoB,KAAO,CAC/B,MAAOH,EAAG,GAAG,EACb,KAAMA,EAAG,GAAG,EACZ,KAAMA,EAAG,GAAG,EACZ,MAAOA,EAAG,GAAG,EACb,YAAa,CAAC,CAChB,GAEMI,EAAmC,CACvC,YAAaJ,EAAG,GAAG,CACrB,EAEMK,EAAqB,IAAI,WAAW,CAAC,EAAG,EAAG,CAAC,CAAC,EAC7CC,EAAkB,CACtB,QAAS,IAAI,WAAW,CAAC,IAAM,GAAI,CAAC,EACpC,eAAgB,CAClB,EAEMC,EAAc,CAClB,cAAeH,EACf,cAAeD,EACf,iBAAkB,IAAI,WAAW,CAAC,IAAM,IAAM,IAAM,GAAI,CAAC,EACzD,cAAe,KACf,QAAS,CACP,aAAc,cACd,UAAW,MACb,CACF,EAEMK,EAA4B,CAChC,KAAMhB,EAAqB,oBAC3B,QAASa,EACT,YAAaC,CACf,EAEA,IAAIG,EAEJZ,EAAS,8BAA+B,IAAM,CAC5CD,EAAW,IAAM,CACfI,EAAG,cAAc,EAEjBS,EAAU,CACR,sBAAuBT,EACpB,GAAG,EACH,gBAAgB,CAAE,cAAeL,EAAc,MAAO,CAAC,EAC1D,YAAaK,EACV,GAAG,EACH,kBACCN,EAAqB,CAAE,KAAM,CAAE,UAAW,eAAgB,CAAE,CAAC,CAC/D,CACJ,CACF,CAAC,EAEDK,EAAG,yCAA0C,SAAY,CACtDK,EAAkB,YAAoB,kBAAkB,CACvDI,CACF,CAAC,EAGD,MADa,IAAIN,EAA4BO,EAASF,CAAW,EACtD,IAAI,EAEfT,EAAOW,EAAQ,WAAW,EAAE,qBAC1BX,EAAO,IAAIG,CAAmB,CAChC,CACF,CAAC,
|
|
4
|
+
"sourcesContent": ["/* eslint-disable @typescript-eslint/no-explicit-any */\nimport {\n ClearSignContextType,\n type ContextModule,\n SolanaTransactionScanChainId,\n} from \"@ledgerhq/context-module\";\nimport {\n CommandResultFactory,\n DeviceModelId,\n type InternalApi,\n} from \"@ledgerhq/device-management-kit\";\nimport { beforeEach, describe, expect, it, vi } from \"vitest\";\n\nimport { GetChallengeCommand } from \"@internal/app-binder/command/GetChallengeCommand\";\n\nimport {\n BuildTransactionContextTask,\n type SolanaBuildContextResult,\n} from \"./BuildTransactionContextTask\";\n\nconst mockLoggerFactory = () => ({\n debug: vi.fn(),\n info: vi.fn(),\n warn: vi.fn(),\n error: vi.fn(),\n subscribers: [],\n});\n\nconst contextModuleMock: ContextModule = {\n getContexts: vi.fn(),\n} as unknown as ContextModule;\n\nconst trustedNamePayload = new Uint8Array([1, 2, 3]);\nconst trustedNameCert = {\n payload: new Uint8Array([0xaa, 0xbb]),\n keyUsageNumber: 1,\n};\n\nconst defaultArgs = {\n contextModule: contextModuleMock,\n loggerFactory: mockLoggerFactory,\n transactionBytes: new Uint8Array([0xde, 0xad, 0xbe, 0xef]),\n signerAddress: null,\n options: {\n tokenAddress: \"someAddress\",\n createATA: undefined,\n },\n};\n\nconst trustedNameSuccessContext = {\n type: ClearSignContextType.SOLANA_TRUSTED_NAME as const,\n payload: trustedNamePayload,\n certificate: trustedNameCert,\n};\n\nlet apiMock: InternalApi;\n\ndescribe(\"BuildTransactionContextTask\", () => {\n beforeEach(() => {\n vi.resetAllMocks();\n\n apiMock = {\n getDeviceSessionState: vi\n .fn()\n .mockReturnValue({ deviceModelId: DeviceModelId.NANO_X }),\n sendCommand: vi\n .fn()\n .mockResolvedValue(\n CommandResultFactory({ data: { challenge: \"someChallenge\" } }),\n ),\n } as unknown as InternalApi;\n });\n\n it(\"requests the challenge from the device\", async () => {\n (contextModuleMock.getContexts as any).mockResolvedValue([\n trustedNameSuccessContext,\n ]);\n\n const task = new BuildTransactionContextTask(apiMock, defaultArgs);\n await task.run();\n\n expect(apiMock.sendCommand).toHaveBeenCalledWith(\n expect.any(GetChallengeCommand),\n );\n });\n\n it(\"calls contextModule.getContexts with the active Solana context types (transaction-check temporarily disabled)\", async () => {\n (contextModuleMock.getContexts as any).mockResolvedValue([\n trustedNameSuccessContext,\n ]);\n\n const task = new BuildTransactionContextTask(apiMock, defaultArgs);\n await task.run();\n\n expect(contextModuleMock.getContexts).toHaveBeenCalledWith(\n {\n deviceModelId: DeviceModelId.NANO_X,\n tokenAddress: \"someAddress\",\n challenge: \"someChallenge\",\n createATA: undefined,\n tokenInternalId: undefined,\n templateId: undefined,\n transactionCheck: undefined,\n },\n [\n ClearSignContextType.SOLANA_TOKEN,\n ClearSignContextType.SOLANA_LIFI,\n ClearSignContextType.SOLANA_TRUSTED_NAME,\n ],\n );\n });\n\n it(\"derives transactionCheck from signerAddress and transactionBytes when address is provided\", async () => {\n (contextModuleMock.getContexts as any).mockResolvedValue([\n trustedNameSuccessContext,\n ]);\n\n const argsWithSigner = {\n ...defaultArgs,\n signerAddress: \"So1anaSignerPubKey111111111111111111111111111\",\n };\n\n const task = new BuildTransactionContextTask(apiMock, argsWithSigner);\n await task.run();\n\n expect(contextModuleMock.getContexts).toHaveBeenCalledWith(\n expect.objectContaining({\n transactionCheck: {\n from: \"So1anaSignerPubKey111111111111111111111111111\",\n transactionBytes: defaultArgs.transactionBytes,\n chain: SolanaTransactionScanChainId.MAINNET,\n },\n }),\n expect.any(Array),\n );\n });\n\n it(\"returns trustedName cert + tlvDescriptor when SOLANA_TRUSTED_NAME context is present\", async () => {\n (contextModuleMock.getContexts as any).mockResolvedValue([\n trustedNameSuccessContext,\n ]);\n\n const task = new BuildTransactionContextTask(apiMock, defaultArgs);\n const result = await task.run();\n\n expect(result).toEqual<SolanaBuildContextResult>({\n tlvDescriptor: trustedNamePayload,\n trustedNamePKICertificate: trustedNameCert,\n loadersResults: [],\n contextErrorCount: 0,\n });\n });\n\n it(\"includes SOLANA_TRANSACTION_CHECK results in loadersResults\", async () => {\n const txCheckContext = {\n type: ClearSignContextType.SOLANA_TRANSACTION_CHECK as const,\n payload: { descriptor: \"aabbccdd\" },\n certificate: { payload: new Uint8Array([0x99]), keyUsageNumber: 14 },\n };\n (contextModuleMock.getContexts as any).mockResolvedValue([\n trustedNameSuccessContext,\n txCheckContext,\n ]);\n\n const task = new BuildTransactionContextTask(apiMock, defaultArgs);\n const result = await task.run();\n\n expect(result.loadersResults).toEqual([txCheckContext]);\n expect(result.contextErrorCount).toBe(0);\n });\n\n it(\"includes SOLANA_TOKEN and SOLANA_LIFI results in loadersResults\", async () => {\n const tokenContext = {\n type: ClearSignContextType.SOLANA_TOKEN as const,\n payload: { solanaTokenDescriptor: { data: \"aa\", signature: \"bb\" } },\n certificate: undefined,\n };\n const lifiContext = {\n type: ClearSignContextType.SOLANA_LIFI as const,\n payload: { descriptors: {}, instructions: [] },\n certificate: undefined,\n };\n (contextModuleMock.getContexts as any).mockResolvedValue([\n trustedNameSuccessContext,\n tokenContext,\n lifiContext,\n ]);\n\n const task = new BuildTransactionContextTask(apiMock, defaultArgs);\n const result = await task.run();\n\n expect(result.loadersResults).toEqual([tokenContext, lifiContext]);\n });\n\n it(\"throws when challenge command fails\", async () => {\n (apiMock.sendCommand as any).mockResolvedValue(\n CommandResultFactory({\n error: { _tag: \"SomeError\", errorCode: 0x6a80, message: \"bad\" } as any,\n }),\n );\n\n const task = new BuildTransactionContextTask(apiMock, defaultArgs);\n\n await expect(task.run()).rejects.toThrow(\n \"Failed to get challenge from device\",\n );\n });\n\n it(\"counts ERROR contexts and surfaces them via contextErrorCount and loadersResults\", async () => {\n const error = new Error(\"token loader failure\");\n (contextModuleMock.getContexts as any).mockResolvedValue([\n trustedNameSuccessContext,\n { type: ClearSignContextType.ERROR, error },\n ]);\n\n const task = new BuildTransactionContextTask(apiMock, defaultArgs);\n const result = await task.run();\n\n expect(result.trustedNamePKICertificate).toEqual(trustedNameCert);\n expect(result.tlvDescriptor).toEqual(trustedNamePayload);\n expect(result.contextErrorCount).toBe(1);\n expect(result.loadersResults).toEqual([\n { type: ClearSignContextType.ERROR, error },\n ]);\n });\n\n it(\"returns empty trusted-name fields when owner info is not required and only errors are returned\", async () => {\n const error = new Error(\"solana context failure\");\n const argsWithoutOwnerInfo = {\n ...defaultArgs,\n options: { tokenAddress: undefined, createATA: undefined },\n };\n (contextModuleMock.getContexts as any).mockResolvedValue([\n { type: ClearSignContextType.ERROR, error },\n ]);\n\n const task = new BuildTransactionContextTask(apiMock, argsWithoutOwnerInfo);\n const result = await task.run();\n\n expect(result.trustedNamePKICertificate).toBeUndefined();\n expect(result.tlvDescriptor).toBeUndefined();\n expect(result.contextErrorCount).toBe(1);\n expect(result.loadersResults).toEqual([\n { type: ClearSignContextType.ERROR, error },\n ]);\n });\n\n it(\"throws when owner info is required but no SOLANA_TRUSTED_NAME context was returned\", async () => {\n (contextModuleMock.getContexts as any).mockResolvedValue([\n {\n type: ClearSignContextType.ERROR,\n error: new Error(\"PKI cert load failure\"),\n },\n ]);\n\n const task = new BuildTransactionContextTask(apiMock, defaultArgs);\n\n await expect(task.run()).rejects.toThrow(\n \"[SignerSolana] BuildTransactionContextTask: owner info was required but could not be resolved\",\n );\n });\n\n it(\"throws when owner info is required but contextModule returns an empty array\", async () => {\n (contextModuleMock.getContexts as any).mockResolvedValue([]);\n\n const task = new BuildTransactionContextTask(apiMock, defaultArgs);\n\n await expect(task.run()).rejects.toThrow(\n \"[SignerSolana] BuildTransactionContextTask: owner info was required but could not be resolved\",\n );\n });\n});\n"],
|
|
5
|
+
"mappings": "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",
|
|
6
6
|
"names": ["ClearSignContextType", "SolanaTransactionScanChainId", "CommandResultFactory", "DeviceModelId", "beforeEach", "describe", "expect", "it", "vi", "GetChallengeCommand", "BuildTransactionContextTask", "mockLoggerFactory", "contextModuleMock", "trustedNamePayload", "trustedNameCert", "defaultArgs", "trustedNameSuccessContext", "apiMock", "argsWithSigner", "result", "txCheckContext", "tokenContext", "lifiContext", "task", "error", "argsWithoutOwnerInfo"]
|
|
7
7
|
}
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import{isSuccessCommandResult as
|
|
1
|
+
import{isSuccessCommandResult as r,LoadCertificateCommand as o}from"@ledgerhq/device-management-kit";async function s(t,e,a){const i=await t.sendCommand(new o({certificate:e.payload,keyUsage:e.keyUsageNumber}));if(!r(i))throw new Error(`${a} (keyUsage=${e.keyUsageNumber})`)}export{s as loadCertificate};
|
|
2
2
|
//# sourceMappingURL=loadCertificate.js.map
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"version": 3,
|
|
3
3
|
"sources": ["../../../../../../src/internal/app-binder/task/context-providers/loadCertificate.ts"],
|
|
4
|
-
"sourcesContent": ["import { type PkiCertificate } from \"@ledgerhq/context-module\";\nimport {\n type InternalApi,\n isSuccessCommandResult,\n LoadCertificateCommand,\n} from \"@ledgerhq/device-management-kit\";\n\nexport async function loadCertificate(\n api: InternalApi,\n certificate: PkiCertificate,\n errorMessage: string,\n): Promise<void> {\n const result = await api.sendCommand(\n new LoadCertificateCommand({\n certificate: certificate.payload,\n keyUsage: certificate.keyUsageNumber,\n }),\n );\n if (!isSuccessCommandResult(result)) {\n throw new Error(errorMessage);\n }\n}\n"],
|
|
5
|
-
"mappings": "AACA,OAEE,0BAAAA,EACA,0BAAAC,MACK,kCAEP,eAAsBC,EACpBC,EACAC,EACAC,EACe,CACf,MAAMC,EAAS,MAAMH,EAAI,YACvB,IAAIF,EAAuB,CACzB,YAAaG,EAAY,QACzB,SAAUA,EAAY,cACxB,CAAC,CACH,EACA,GAAI,CAACJ,EAAuBM,CAAM,EAChC,MAAM,IAAI,
|
|
4
|
+
"sourcesContent": ["import { type PkiCertificate } from \"@ledgerhq/context-module\";\nimport {\n type InternalApi,\n isSuccessCommandResult,\n LoadCertificateCommand,\n} from \"@ledgerhq/device-management-kit\";\n\nexport async function loadCertificate(\n api: InternalApi,\n certificate: PkiCertificate,\n errorMessage: string,\n): Promise<void> {\n const result = await api.sendCommand(\n new LoadCertificateCommand({\n certificate: certificate.payload,\n keyUsage: certificate.keyUsageNumber,\n }),\n );\n if (!isSuccessCommandResult(result)) {\n throw new Error(`${errorMessage} (keyUsage=${certificate.keyUsageNumber})`);\n }\n}\n"],
|
|
5
|
+
"mappings": "AACA,OAEE,0BAAAA,EACA,0BAAAC,MACK,kCAEP,eAAsBC,EACpBC,EACAC,EACAC,EACe,CACf,MAAMC,EAAS,MAAMH,EAAI,YACvB,IAAIF,EAAuB,CACzB,YAAaG,EAAY,QACzB,SAAUA,EAAY,cACxB,CAAC,CACH,EACA,GAAI,CAACJ,EAAuBM,CAAM,EAChC,MAAM,IAAI,MAAM,GAAGD,CAAY,cAAcD,EAAY,cAAc,GAAG,CAE9E",
|
|
6
6
|
"names": ["isSuccessCommandResult", "LoadCertificateCommand", "loadCertificate", "api", "certificate", "errorMessage", "result"]
|
|
7
7
|
}
|
package/lib/esm/internal/app-binder/task/context-providers/provideTransactionCheckContext.js
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import{hexaStringToBuffer as s,isSuccessCommandResult as d}from"@ledgerhq/device-management-kit";import{ProvideWeb3CheckCommand as C}from"../../../app-binder/command/ProvideWeb3CheckCommand";import{SendCommandInChunksTask as p}from"../../../app-binder/task/SendCommandInChunksTask";import{loadCertificate as m}from"./loadCertificate";const
|
|
1
|
+
import{hexaStringToBuffer as s,isSuccessCommandResult as d}from"@ledgerhq/device-management-kit";import{ProvideWeb3CheckCommand as C}from"../../../app-binder/command/ProvideWeb3CheckCommand";import{SendCommandInChunksTask as p}from"../../../app-binder/task/SendCommandInChunksTask";import{loadCertificate as m}from"./loadCertificate";const S=async(r,{api:o,logger:a})=>{const{payload:i,certificate:n}=r;n&&await m(o,n,"[SignerSolana] provideTransactionCheckContext: Failed to send web3-check certificate to device");const e=s(i.descriptor);if(!e||e.length===0){a.warn("[provideTransactionCheckContext] descriptor could not be parsed, skipping");return}const c=await new p(o,{data:e,commandFactory:t=>new C({payload:t.chunkedData,isFirstChunk:!t.extend,hasMore:t.more})}).run();if(!d(c))throw new Error("[SignerSolana] provideTransactionCheckContext: Failed to send transaction-check descriptor to device")};export{S as provideTransactionCheckContext};
|
|
2
2
|
//# sourceMappingURL=provideTransactionCheckContext.js.map
|
package/lib/esm/internal/app-binder/task/context-providers/provideTransactionCheckContext.js.map
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"version": 3,
|
|
3
3
|
"sources": ["../../../../../../src/internal/app-binder/task/context-providers/provideTransactionCheckContext.ts"],
|
|
4
|
-
"sourcesContent": ["import {\n type ClearSignContextType,\n type SolanaTransactionCheckContextSuccess,\n} from \"@ledgerhq/context-module\";\nimport {\n hexaStringToBuffer,\n isSuccessCommandResult,\n} from \"@ledgerhq/device-management-kit\";\n\nimport { ProvideWeb3CheckCommand } from \"@internal/app-binder/command/ProvideWeb3CheckCommand\";\nimport { SendCommandInChunksTask } from \"@internal/app-binder/task/SendCommandInChunksTask\";\n\nimport { loadCertificate } from \"./loadCertificate\";\nimport { type ProvideContextHandler } from \"./provideContextTypes\";\n\nexport const provideTransactionCheckContext: ProvideContextHandler<\n ClearSignContextType.SOLANA_TRANSACTION_CHECK\n> = async (result: SolanaTransactionCheckContextSuccess, { api, logger }) => {\n const { payload, certificate } = result;\n\n if (
|
|
5
|
-
"mappings": "AAIA,OACE,sBAAAA,EACA,0BAAAC,MACK,kCAEP,OAAS,2BAAAC,MAA+B,uDACxC,OAAS,2BAAAC,MAA+B,oDAExC,OAAS,mBAAAC,MAAuB,oBAGzB,MAAMC,EAET,MAAOC,EAA8C,CAAE,IAAAC,EAAK,OAAAC,CAAO,IAAM,CAC3E,KAAM,CAAE,QAAAC,EAAS,
|
|
6
|
-
"names": ["hexaStringToBuffer", "isSuccessCommandResult", "ProvideWeb3CheckCommand", "SendCommandInChunksTask", "loadCertificate", "provideTransactionCheckContext", "result", "api", "logger", "payload", "
|
|
4
|
+
"sourcesContent": ["import {\n type ClearSignContextType,\n type SolanaTransactionCheckContextSuccess,\n} from \"@ledgerhq/context-module\";\nimport {\n hexaStringToBuffer,\n isSuccessCommandResult,\n} from \"@ledgerhq/device-management-kit\";\n\nimport { ProvideWeb3CheckCommand } from \"@internal/app-binder/command/ProvideWeb3CheckCommand\";\nimport { SendCommandInChunksTask } from \"@internal/app-binder/task/SendCommandInChunksTask\";\n\nimport { loadCertificate } from \"./loadCertificate\";\nimport { type ProvideContextHandler } from \"./provideContextTypes\";\n\nexport const provideTransactionCheckContext: ProvideContextHandler<\n ClearSignContextType.SOLANA_TRANSACTION_CHECK\n> = async (result: SolanaTransactionCheckContextSuccess, { api, logger }) => {\n const { payload, certificate: web3CheckCertificate } = result;\n\n if (web3CheckCertificate) {\n await loadCertificate(\n api,\n web3CheckCertificate,\n \"[SignerSolana] provideTransactionCheckContext: Failed to send web3-check certificate to device\",\n );\n }\n\n const descriptorBytes = hexaStringToBuffer(payload.descriptor);\n if (!descriptorBytes || descriptorBytes.length === 0) {\n logger.warn(\n \"[provideTransactionCheckContext] descriptor could not be parsed, skipping\",\n );\n return;\n }\n\n const chunkResult = await new SendCommandInChunksTask(api, {\n data: descriptorBytes,\n commandFactory: (args) =>\n new ProvideWeb3CheckCommand({\n payload: args.chunkedData,\n isFirstChunk: !args.extend,\n hasMore: args.more,\n }),\n }).run();\n\n if (!isSuccessCommandResult(chunkResult)) {\n throw new Error(\n \"[SignerSolana] provideTransactionCheckContext: Failed to send transaction-check descriptor to device\",\n );\n }\n};\n"],
|
|
5
|
+
"mappings": "AAIA,OACE,sBAAAA,EACA,0BAAAC,MACK,kCAEP,OAAS,2BAAAC,MAA+B,uDACxC,OAAS,2BAAAC,MAA+B,oDAExC,OAAS,mBAAAC,MAAuB,oBAGzB,MAAMC,EAET,MAAOC,EAA8C,CAAE,IAAAC,EAAK,OAAAC,CAAO,IAAM,CAC3E,KAAM,CAAE,QAAAC,EAAS,YAAaC,CAAqB,EAAIJ,EAEnDI,GACF,MAAMN,EACJG,EACAG,EACA,gGACF,EAGF,MAAMC,EAAkBX,EAAmBS,EAAQ,UAAU,EAC7D,GAAI,CAACE,GAAmBA,EAAgB,SAAW,EAAG,CACpDH,EAAO,KACL,2EACF,EACA,MACF,CAEA,MAAMI,EAAc,MAAM,IAAIT,EAAwBI,EAAK,CACzD,KAAMI,EACN,eAAiBE,GACf,IAAIX,EAAwB,CAC1B,QAASW,EAAK,YACd,aAAc,CAACA,EAAK,OACpB,QAASA,EAAK,IAChB,CAAC,CACL,CAAC,EAAE,IAAI,EAEP,GAAI,CAACZ,EAAuBW,CAAW,EACrC,MAAM,IAAI,MACR,sGACF,CAEJ",
|
|
6
|
+
"names": ["hexaStringToBuffer", "isSuccessCommandResult", "ProvideWeb3CheckCommand", "SendCommandInChunksTask", "loadCertificate", "provideTransactionCheckContext", "result", "api", "logger", "payload", "web3CheckCertificate", "descriptorBytes", "chunkResult", "args"]
|
|
7
7
|
}
|
package/lib/esm/internal/app-binder/task/context-providers/provideTransactionCheckContext.test.js
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import{ClearSignContextType as s}from"@ledgerhq/context-module";import{APDU_MAX_PAYLOAD as f,CommandResultFactory as p,LoadCertificateCommand as A}from"@ledgerhq/device-management-kit";import{beforeEach as b,describe as k,expect as a,it as r,vi as d}from"vitest";import{ProvideWeb3CheckCommand as y}from"../../../app-binder/command/ProvideWeb3CheckCommand";import{provideTransactionCheckContext as c}from"./provideTransactionCheckContext";const u={debug:d.fn(),info:d.fn(),warn:d.fn(),error:d.fn(),subscribers:[]};k("provideTransactionCheckContext",()=>{let e,n;const i=p({data:void 0}),m={payload:new Uint8Array([222,173]),keyUsageNumber:14};b(()=>{d.resetAllMocks(),e={sendCommand:d.fn()},n={api:e,logger:u,normaliser:{},transactionBytes:new Uint8Array([240])}}),r("sends certificate then ProvideWeb3CheckCommand",async()=>{e.sendCommand.mockResolvedValueOnce(i).mockResolvedValueOnce(i);const t={type:s.SOLANA_TRANSACTION_CHECK,payload:{descriptor:"aabbccdd"},certificate:m};await c(t,n),a(e.sendCommand).toHaveBeenCalledTimes(2);const o=e.sendCommand.mock.calls[0][0];a(o).toBeInstanceOf(A),a(o.args.certificate).toStrictEqual(m.payload),a(o.args.keyUsage).toBe(m.keyUsageNumber);const l=e.sendCommand.mock.calls[1][0];a(l).toBeInstanceOf(y)}),r("throws when certificate load fails",async()=>{const t=p({error:{_tag:"SomeError",errorCode:27264,message:"bad"}});e.sendCommand.mockResolvedValueOnce(t);const o={type:s.SOLANA_TRANSACTION_CHECK,payload:{descriptor:"aabbccdd"},certificate:m};await a(c(o,n)).rejects.toThrow("Failed to send
|
|
1
|
+
import{ClearSignContextType as s}from"@ledgerhq/context-module";import{APDU_MAX_PAYLOAD as f,CommandResultFactory as p,LoadCertificateCommand as A}from"@ledgerhq/device-management-kit";import{beforeEach as b,describe as k,expect as a,it as r,vi as d}from"vitest";import{ProvideWeb3CheckCommand as y}from"../../../app-binder/command/ProvideWeb3CheckCommand";import{provideTransactionCheckContext as c}from"./provideTransactionCheckContext";const u={debug:d.fn(),info:d.fn(),warn:d.fn(),error:d.fn(),subscribers:[]};k("provideTransactionCheckContext",()=>{let e,n;const i=p({data:void 0}),m={payload:new Uint8Array([222,173]),keyUsageNumber:14};b(()=>{d.resetAllMocks(),e={sendCommand:d.fn()},n={api:e,logger:u,normaliser:{},transactionBytes:new Uint8Array([240])}}),r("sends certificate then ProvideWeb3CheckCommand",async()=>{e.sendCommand.mockResolvedValueOnce(i).mockResolvedValueOnce(i);const t={type:s.SOLANA_TRANSACTION_CHECK,payload:{descriptor:"aabbccdd"},certificate:m};await c(t,n),a(e.sendCommand).toHaveBeenCalledTimes(2);const o=e.sendCommand.mock.calls[0][0];a(o).toBeInstanceOf(A),a(o.args.certificate).toStrictEqual(m.payload),a(o.args.keyUsage).toBe(m.keyUsageNumber);const l=e.sendCommand.mock.calls[1][0];a(l).toBeInstanceOf(y)}),r("throws when certificate load fails",async()=>{const t=p({error:{_tag:"SomeError",errorCode:27264,message:"bad"}});e.sendCommand.mockResolvedValueOnce(t);const o={type:s.SOLANA_TRANSACTION_CHECK,payload:{descriptor:"aabbccdd"},certificate:m};await a(c(o,n)).rejects.toThrow("Failed to send web3-check certificate to device")}),r("sends descriptor without certificate when certificate is absent",async()=>{e.sendCommand.mockResolvedValueOnce(i);const t={type:s.SOLANA_TRANSACTION_CHECK,payload:{descriptor:"aabbccdd"},certificate:void 0};await c(t,n),a(e.sendCommand).toHaveBeenCalledTimes(1);const o=e.sendCommand.mock.calls[0][0];a(o).toBeInstanceOf(y)}),r("chunks large descriptors across multiple APDU calls",async()=>{e.sendCommand.mockResolvedValue(i);const t="aa".repeat(f+10).padEnd((f+10)*2,"bb"),o={type:s.SOLANA_TRANSACTION_CHECK,payload:{descriptor:t},certificate:void 0};await c(o,n),a(e.sendCommand.mock.calls.length).toBeGreaterThanOrEqual(2);const l=e.sendCommand.mock.calls.map(C=>C[0]);a(l.every(C=>C instanceof y)).toBe(!0)}),r("throws when descriptor sending fails",async()=>{e.sendCommand.mockResolvedValueOnce(p({error:{_tag:"SomeError",errorCode:27264,message:"bad"}}));const t={type:s.SOLANA_TRANSACTION_CHECK,payload:{descriptor:"aabbccdd"},certificate:void 0};await a(c(t,n)).rejects.toThrow("Failed to send transaction-check descriptor to device")}),r("warns and returns when descriptor is unparseable",async()=>{const t={type:s.SOLANA_TRANSACTION_CHECK,payload:{descriptor:""},certificate:void 0};await c(t,n),a(e.sendCommand).not.toHaveBeenCalled(),a(u.warn).toHaveBeenCalledWith(a.stringContaining("descriptor could not be parsed"))})});
|
|
2
2
|
//# sourceMappingURL=provideTransactionCheckContext.test.js.map
|