@ledgerhq/device-signer-kit-concordium 0.0.0-develop-20260419002000 → 0.0.0-develop-20260420165047

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (25) hide show
  1. package/lib/cjs/internal/app-binder/command/utils/ConcordiumApplicationErrors.js +1 -1
  2. package/lib/cjs/internal/app-binder/command/utils/ConcordiumApplicationErrors.js.map +2 -2
  3. package/lib/cjs/internal/app-binder/command/utils/TrustedMetadataServiceError.js +2 -0
  4. package/lib/cjs/internal/app-binder/command/utils/TrustedMetadataServiceError.js.map +7 -0
  5. package/lib/cjs/internal/app-binder/task/VerifyAddressTask.js +1 -1
  6. package/lib/cjs/internal/app-binder/task/VerifyAddressTask.js.map +3 -3
  7. package/lib/cjs/internal/app-binder/task/VerifyAddressTask.test.js +1 -1
  8. package/lib/cjs/internal/app-binder/task/VerifyAddressTask.test.js.map +3 -3
  9. package/lib/cjs/package.json +1 -1
  10. package/lib/esm/internal/app-binder/command/utils/ConcordiumApplicationErrors.js +1 -1
  11. package/lib/esm/internal/app-binder/command/utils/ConcordiumApplicationErrors.js.map +2 -2
  12. package/lib/esm/internal/app-binder/command/utils/TrustedMetadataServiceError.js +2 -0
  13. package/lib/esm/internal/app-binder/command/utils/TrustedMetadataServiceError.js.map +7 -0
  14. package/lib/esm/internal/app-binder/task/VerifyAddressTask.js +1 -1
  15. package/lib/esm/internal/app-binder/task/VerifyAddressTask.js.map +3 -3
  16. package/lib/esm/internal/app-binder/task/VerifyAddressTask.test.js +1 -1
  17. package/lib/esm/internal/app-binder/task/VerifyAddressTask.test.js.map +3 -3
  18. package/lib/esm/package.json +1 -1
  19. package/lib/types/internal/app-binder/command/utils/ConcordiumApplicationErrors.d.ts +2 -1
  20. package/lib/types/internal/app-binder/command/utils/ConcordiumApplicationErrors.d.ts.map +1 -1
  21. package/lib/types/internal/app-binder/command/utils/TrustedMetadataServiceError.d.ts +6 -0
  22. package/lib/types/internal/app-binder/command/utils/TrustedMetadataServiceError.d.ts.map +1 -0
  23. package/lib/types/internal/app-binder/task/VerifyAddressTask.d.ts.map +1 -1
  24. package/lib/types/tsconfig.prod.tsbuildinfo +1 -1
  25. package/package.json +6 -6
@@ -1,2 +1,2 @@
1
- "use strict";var o=Object.defineProperty;var _=Object.getOwnPropertyDescriptor;var c=Object.getOwnPropertyNames;var d=Object.prototype.hasOwnProperty;var A=(r,e)=>{for(var a in e)o(r,a,{get:e[a],enumerable:!0})},R=(r,e,a,n)=>{if(e&&typeof e=="object"||typeof e=="function")for(let t of c(e))!d.call(r,t)&&t!==a&&o(r,t,{get:()=>e[t],enumerable:!(n=_(e,t))||n.enumerable});return r};var T=r=>R(o({},"__esModule",{value:!0}),r);var C={};A(C,{CONCORDIUM_APP_ERRORS:()=>g,ConcordiumAppCommandError:()=>E,ConcordiumAppCommandErrorFactory:()=>N,ConcordiumErrorCodes:()=>p});module.exports=T(C);var m=require("@ledgerhq/device-management-kit"),p=(s=>(s.USER_REJECTED="6985",s.LOCKED_DEVICE="5515",s.DATA_INVALID="6a80",s.INS_NOT_SUPPORTED="6d00",s.CLA_NOT_SUPPORTED="6e00",s.UNKNOWN_ERROR="6f00",s.TRUSTED_NAME_MISMATCH="6b0c",s.UNSUPPORTED_TRANSACTION_TYPE="unsupported_transaction_type",s))(p||{});const g={6985:{message:"User rejected"},5515:{message:"Locked device"},"6a80":{message:"Data invalid"},"6d00":{message:"INS not supported"},"6e00":{message:"CLA not supported"},"6f00":{message:"Unknown error"},"6b0c":{message:"Trusted name mismatch"},unsupported_transaction_type:{message:"Unsupported transaction type"}};class E extends m.DeviceExchangeError{constructor(e){super({tag:"ConcordiumAppCommandError",...e})}}const N=r=>new E(r);0&&(module.exports={CONCORDIUM_APP_ERRORS,ConcordiumAppCommandError,ConcordiumAppCommandErrorFactory,ConcordiumErrorCodes});
1
+ "use strict";var m=Object.defineProperty;var E=Object.getOwnPropertyDescriptor;var d=Object.getOwnPropertyNames;var A=Object.prototype.hasOwnProperty;var R=(r,e)=>{for(var s in e)m(r,s,{get:e[s],enumerable:!0})},T=(r,e,s,o)=>{if(e&&typeof e=="object"||typeof e=="function")for(let a of d(e))!A.call(r,a)&&a!==s&&m(r,a,{get:()=>e[a],enumerable:!(o=E(e,a))||o.enumerable});return r};var c=r=>T(m({},"__esModule",{value:!0}),r);var N={};R(N,{CONCORDIUM_APP_ERRORS:()=>g,ConcordiumAppCommandError:()=>_,ConcordiumAppCommandErrorFactory:()=>D,ConcordiumErrorCodes:()=>p});module.exports=c(N);var n=require("@ledgerhq/device-management-kit"),p=(t=>(t.USER_REJECTED="6985",t.LOCKED_DEVICE="5515",t.DATA_INVALID="6a80",t.INS_NOT_SUPPORTED="6d00",t.CLA_NOT_SUPPORTED="6e00",t.UNKNOWN_ERROR="6f00",t.TRUSTED_NAME_MISMATCH="6b0c",t.UNSUPPORTED_TRANSACTION_TYPE="unsupported_transaction_type",t.TRUSTED_METADATA_SERVICE_ERROR="trusted_metadata_service_error",t))(p||{});const g={6985:{message:"User rejected"},5515:{message:"Locked device"},"6a80":{message:"Data invalid"},"6d00":{message:"INS not supported"},"6e00":{message:"CLA not supported"},"6f00":{message:"Unknown error"},"6b0c":{message:"Trusted name mismatch"},unsupported_transaction_type:{message:"Unsupported transaction type"},trusted_metadata_service_error:{message:"Trusted metadata service error"}};class _ extends n.DeviceExchangeError{constructor(e){super({tag:"ConcordiumAppCommandError",...e})}}const D=r=>new _(r);0&&(module.exports={CONCORDIUM_APP_ERRORS,ConcordiumAppCommandError,ConcordiumAppCommandErrorFactory,ConcordiumErrorCodes});
2
2
  //# sourceMappingURL=ConcordiumApplicationErrors.js.map
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "version": 3,
3
3
  "sources": ["../../../../../../src/internal/app-binder/command/utils/ConcordiumApplicationErrors.ts"],
4
- "sourcesContent": ["import {\n type CommandErrorArgs,\n type CommandErrors,\n DeviceExchangeError,\n} from \"@ledgerhq/device-management-kit\";\n\nexport enum ConcordiumErrorCodes {\n USER_REJECTED = \"6985\",\n LOCKED_DEVICE = \"5515\",\n DATA_INVALID = \"6a80\",\n INS_NOT_SUPPORTED = \"6d00\",\n CLA_NOT_SUPPORTED = \"6e00\",\n UNKNOWN_ERROR = \"6f00\",\n TRUSTED_NAME_MISMATCH = \"6b0c\",\n UNSUPPORTED_TRANSACTION_TYPE = \"unsupported_transaction_type\",\n}\n\nexport const CONCORDIUM_APP_ERRORS: CommandErrors<ConcordiumErrorCodes> = {\n \"6985\": { message: \"User rejected\" },\n \"5515\": { message: \"Locked device\" },\n \"6a80\": { message: \"Data invalid\" },\n \"6d00\": { message: \"INS not supported\" },\n \"6e00\": { message: \"CLA not supported\" },\n \"6f00\": { message: \"Unknown error\" },\n \"6b0c\": { message: \"Trusted name mismatch\" },\n unsupported_transaction_type: { message: \"Unsupported transaction type\" },\n};\n\nexport class ConcordiumAppCommandError extends DeviceExchangeError<ConcordiumErrorCodes> {\n constructor(args: CommandErrorArgs<ConcordiumErrorCodes>) {\n super({ tag: \"ConcordiumAppCommandError\", ...args });\n }\n}\n\nexport const ConcordiumAppCommandErrorFactory = (\n args: CommandErrorArgs<ConcordiumErrorCodes>,\n) => new ConcordiumAppCommandError(args);\n"],
5
- "mappings": "yaAAA,IAAAA,EAAA,GAAAC,EAAAD,EAAA,2BAAAE,EAAA,8BAAAC,EAAA,qCAAAC,EAAA,yBAAAC,IAAA,eAAAC,EAAAN,GAAA,IAAAO,EAIO,2CAEKF,OACVA,EAAA,cAAgB,OAChBA,EAAA,cAAgB,OAChBA,EAAA,aAAe,OACfA,EAAA,kBAAoB,OACpBA,EAAA,kBAAoB,OACpBA,EAAA,cAAgB,OAChBA,EAAA,sBAAwB,OACxBA,EAAA,6BAA+B,+BARrBA,OAAA,IAWL,MAAMH,EAA6D,CACxE,KAAQ,CAAE,QAAS,eAAgB,EACnC,KAAQ,CAAE,QAAS,eAAgB,EACnC,OAAQ,CAAE,QAAS,cAAe,EAClC,OAAQ,CAAE,QAAS,mBAAoB,EACvC,OAAQ,CAAE,QAAS,mBAAoB,EACvC,OAAQ,CAAE,QAAS,eAAgB,EACnC,OAAQ,CAAE,QAAS,uBAAwB,EAC3C,6BAA8B,CAAE,QAAS,8BAA+B,CAC1E,EAEO,MAAMC,UAAkC,qBAA0C,CACvF,YAAYK,EAA8C,CACxD,MAAM,CAAE,IAAK,4BAA6B,GAAGA,CAAK,CAAC,CACrD,CACF,CAEO,MAAMJ,EACXI,GACG,IAAIL,EAA0BK,CAAI",
4
+ "sourcesContent": ["import {\n type CommandErrorArgs,\n type CommandErrors,\n DeviceExchangeError,\n} from \"@ledgerhq/device-management-kit\";\n\nexport enum ConcordiumErrorCodes {\n USER_REJECTED = \"6985\",\n LOCKED_DEVICE = \"5515\",\n DATA_INVALID = \"6a80\",\n INS_NOT_SUPPORTED = \"6d00\",\n CLA_NOT_SUPPORTED = \"6e00\",\n UNKNOWN_ERROR = \"6f00\",\n TRUSTED_NAME_MISMATCH = \"6b0c\",\n UNSUPPORTED_TRANSACTION_TYPE = \"unsupported_transaction_type\",\n TRUSTED_METADATA_SERVICE_ERROR = \"trusted_metadata_service_error\",\n}\n\nexport const CONCORDIUM_APP_ERRORS: CommandErrors<ConcordiumErrorCodes> = {\n \"6985\": { message: \"User rejected\" },\n \"5515\": { message: \"Locked device\" },\n \"6a80\": { message: \"Data invalid\" },\n \"6d00\": { message: \"INS not supported\" },\n \"6e00\": { message: \"CLA not supported\" },\n \"6f00\": { message: \"Unknown error\" },\n \"6b0c\": { message: \"Trusted name mismatch\" },\n unsupported_transaction_type: { message: \"Unsupported transaction type\" },\n trusted_metadata_service_error: {\n message: \"Trusted metadata service error\",\n },\n};\n\nexport class ConcordiumAppCommandError extends DeviceExchangeError<ConcordiumErrorCodes> {\n constructor(args: CommandErrorArgs<ConcordiumErrorCodes>) {\n super({ tag: \"ConcordiumAppCommandError\", ...args });\n }\n}\n\nexport const ConcordiumAppCommandErrorFactory = (\n args: CommandErrorArgs<ConcordiumErrorCodes>,\n) => new ConcordiumAppCommandError(args);\n"],
5
+ "mappings": "yaAAA,IAAAA,EAAA,GAAAC,EAAAD,EAAA,2BAAAE,EAAA,8BAAAC,EAAA,qCAAAC,EAAA,yBAAAC,IAAA,eAAAC,EAAAN,GAAA,IAAAO,EAIO,2CAEKF,OACVA,EAAA,cAAgB,OAChBA,EAAA,cAAgB,OAChBA,EAAA,aAAe,OACfA,EAAA,kBAAoB,OACpBA,EAAA,kBAAoB,OACpBA,EAAA,cAAgB,OAChBA,EAAA,sBAAwB,OACxBA,EAAA,6BAA+B,+BAC/BA,EAAA,+BAAiC,iCATvBA,OAAA,IAYL,MAAMH,EAA6D,CACxE,KAAQ,CAAE,QAAS,eAAgB,EACnC,KAAQ,CAAE,QAAS,eAAgB,EACnC,OAAQ,CAAE,QAAS,cAAe,EAClC,OAAQ,CAAE,QAAS,mBAAoB,EACvC,OAAQ,CAAE,QAAS,mBAAoB,EACvC,OAAQ,CAAE,QAAS,eAAgB,EACnC,OAAQ,CAAE,QAAS,uBAAwB,EAC3C,6BAA8B,CAAE,QAAS,8BAA+B,EACxE,+BAAgC,CAC9B,QAAS,gCACX,CACF,EAEO,MAAMC,UAAkC,qBAA0C,CACvF,YAAYK,EAA8C,CACxD,MAAM,CAAE,IAAK,4BAA6B,GAAGA,CAAK,CAAC,CACrD,CACF,CAEO,MAAMJ,EACXI,GACG,IAAIL,EAA0BK,CAAI",
6
6
  "names": ["ConcordiumApplicationErrors_exports", "__export", "CONCORDIUM_APP_ERRORS", "ConcordiumAppCommandError", "ConcordiumAppCommandErrorFactory", "ConcordiumErrorCodes", "__toCommonJS", "import_device_management_kit", "args"]
7
7
  }
@@ -0,0 +1,2 @@
1
+ "use strict";var s=Object.defineProperty;var c=Object.getOwnPropertyDescriptor;var i=Object.getOwnPropertyNames;var m=Object.prototype.hasOwnProperty;var u=(e,r)=>{for(var t in r)s(e,t,{get:r[t],enumerable:!0})},T=(e,r,t,a)=>{if(r&&typeof r=="object"||typeof r=="function")for(let o of i(r))!m.call(e,o)&&o!==t&&s(e,o,{get:()=>r[o],enumerable:!(a=c(r,o))||a.enumerable});return e};var n=e=>T(s({},"__esModule",{value:!0}),e);var R={};u(R,{TrustedMetadataServiceError:()=>C});module.exports=n(R);var d=require("@ledgerhq/device-management-kit"),E=require("../../../app-binder/command/utils/ConcordiumApplicationErrors");class C extends d.DeviceExchangeError{constructor(r){super({tag:"TrustedMetadataServiceError",message:r??"Trusted metadata service error",errorCode:E.ConcordiumErrorCodes.TRUSTED_METADATA_SERVICE_ERROR})}}0&&(module.exports={TrustedMetadataServiceError});
2
+ //# sourceMappingURL=TrustedMetadataServiceError.js.map
@@ -0,0 +1,7 @@
1
+ {
2
+ "version": 3,
3
+ "sources": ["../../../../../../src/internal/app-binder/command/utils/TrustedMetadataServiceError.ts"],
4
+ "sourcesContent": ["import { DeviceExchangeError } from \"@ledgerhq/device-management-kit\";\n\nimport { ConcordiumErrorCodes } from \"@internal/app-binder/command/utils/ConcordiumApplicationErrors\";\n\nexport class TrustedMetadataServiceError extends DeviceExchangeError<ConcordiumErrorCodes> {\n constructor(message?: string) {\n super({\n tag: \"TrustedMetadataServiceError\",\n message: message ?? \"Trusted metadata service error\",\n errorCode: ConcordiumErrorCodes.TRUSTED_METADATA_SERVICE_ERROR,\n });\n }\n}\n"],
5
+ "mappings": "yaAAA,IAAAA,EAAA,GAAAC,EAAAD,EAAA,iCAAAE,IAAA,eAAAC,EAAAH,GAAA,IAAAI,EAAoC,2CAEpCC,EAAqC,0EAE9B,MAAMH,UAAoC,qBAA0C,CACzF,YAAYI,EAAkB,CAC5B,MAAM,CACJ,IAAK,8BACL,QAASA,GAAW,iCACpB,UAAW,uBAAqB,8BAClC,CAAC,CACH,CACF",
6
+ "names": ["TrustedMetadataServiceError_exports", "__export", "TrustedMetadataServiceError", "__toCommonJS", "import_device_management_kit", "import_ConcordiumApplicationErrors", "message"]
7
+ }
@@ -1,2 +1,2 @@
1
- "use strict";var y=Object.defineProperty;var v=Object.getOwnPropertyDescriptor;var k=Object.getOwnPropertyNames;var N=Object.prototype.hasOwnProperty;var T=(o,r)=>{for(var n in r)y(o,n,{get:r[n],enumerable:!0})},O=(o,r,n,i)=>{if(r&&typeof r=="object"||typeof r=="function")for(let a of k(r))!N.call(o,a)&&a!==n&&y(o,a,{get:()=>r[a],enumerable:!(i=v(r,a))||i.enumerable});return o};var P=o=>O(y({},"__esModule",{value:!0}),o);var E={};T(E,{VerifyAddressTask:()=>I});module.exports=P(E);var l=require("@ledgerhq/context-module"),e=require("@ledgerhq/device-management-kit"),h=require("../../app-binder/command/GetChallengeCommand"),C=require("../../app-binder/command/GetPublicKeyCommand"),w=require("../../app-binder/command/SetTrustedNameCommand"),x=require("../../app-binder/command/VerifyAddressCommand");class I{constructor(r,n,i){this.api=r;this.args=n;this.logger=i}async run(){const{derivationPath:r,address:n,network:i,contextModule:a}=this.args;this.logger.debug("[run] Getting public key");const d=await this.api.sendCommand(new C.GetPublicKeyCommand({derivationPath:r,checkOnDevice:!1,skipOpenApp:!0}));if(!(0,e.isSuccessCommandResult)(d))return this.logger.error("[run] Failed to get public key",{data:{error:d.error}}),(0,e.CommandResultFactory)({error:d.error});const f=(0,e.bufferToHexaString)(d.data.publicKey,!1);this.logger.debug("[run] Getting challenge");const c=await this.api.sendCommand(new h.GetChallengeCommand);if(!(0,e.isSuccessCommandResult)(c))return this.logger.error("[run] Failed to get challenge",{data:{error:c.error}}),(0,e.CommandResultFactory)({error:c.error});const b=c.data.challenge;this.logger.debug("[run] Fetching account ownership context",{data:{publicKey:f,address:n,network:i}});const S=this.api.getDeviceModel().id;let u;try{u=await a.getContexts({publicKey:f,address:n,challenge:b,network:i,deviceModelId:S},[l.ClearSignContextType.ACCOUNT_OWNERSHIP])}catch(t){return this.logger.error("[run] Context module error",{data:{error:t}}),(0,e.CommandResultFactory)({error:new e.InvalidStatusWordError(`Failed to fetch account ownership context: ${t instanceof Error?t.message:"unknown error"}`)})}const s=u.find(t=>t.type===l.ClearSignContextType.ACCOUNT_OWNERSHIP);if(!s){const t=u.find(R=>R.type===l.ClearSignContextType.ERROR),A=t&&"error"in t?t.error.message:"No account ownership context returned";return(0,e.CommandResultFactory)({error:new e.InvalidStatusWordError(A)})}if(s.certificate){this.logger.debug("[run] Loading PKI certificate");const t=await this.api.sendCommand(new e.LoadCertificateCommand({keyUsage:s.certificate.keyUsageNumber,certificate:s.certificate.payload}));if(!(0,e.isSuccessCommandResult)(t))return this.logger.error("[run] Failed to load certificate",{data:{error:t.error}}),(0,e.CommandResultFactory)({error:t.error})}this.logger.debug("[run] Setting trusted name descriptor");const g=(0,e.hexaStringToBuffer)(s.payload);if(!g||g.length===0)return(0,e.CommandResultFactory)({error:new e.InvalidStatusWordError("Invalid descriptor payload")});const p=await this.api.sendCommand(new w.SetTrustedNameCommand({payload:g}));if(!(0,e.isSuccessCommandResult)(p))return this.logger.error("[run] Failed to set trusted name",{data:{error:p.error}}),(0,e.CommandResultFactory)({error:p.error});this.logger.debug("[run] Sending verify address command");const m=await this.api.sendCommand(new x.VerifyAddressCommand({derivationPath:r}));return(0,e.isSuccessCommandResult)(m)?(0,e.CommandResultFactory)({data:!0}):(this.logger.error("[run] Failed to verify address",{data:{error:m.error}}),(0,e.CommandResultFactory)({error:m.error}))}}0&&(module.exports={VerifyAddressTask});
1
+ "use strict";var y=Object.defineProperty;var R=Object.getOwnPropertyDescriptor;var k=Object.getOwnPropertyNames;var T=Object.prototype.hasOwnProperty;var N=(o,r)=>{for(var n in r)y(o,n,{get:r[n],enumerable:!0})},O=(o,r,n,i)=>{if(r&&typeof r=="object"||typeof r=="function")for(let a of k(r))!T.call(o,a)&&a!==n&&y(o,a,{get:()=>r[a],enumerable:!(i=R(r,a))||i.enumerable});return o};var P=o=>O(y({},"__esModule",{value:!0}),o);var I={};N(I,{VerifyAddressTask:()=>E});module.exports=P(I);var l=require("@ledgerhq/context-module"),e=require("@ledgerhq/device-management-kit"),h=require("../../app-binder/command/GetChallengeCommand"),C=require("../../app-binder/command/GetPublicKeyCommand"),w=require("../../app-binder/command/SetTrustedNameCommand"),x=require("../../app-binder/command/utils/TrustedMetadataServiceError"),S=require("../../app-binder/command/VerifyAddressCommand");class E{constructor(r,n,i){this.api=r;this.args=n;this.logger=i}async run(){const{derivationPath:r,address:n,network:i,contextModule:a}=this.args;this.logger.debug("[run] Getting public key");const d=await this.api.sendCommand(new C.GetPublicKeyCommand({derivationPath:r,checkOnDevice:!1,skipOpenApp:!0}));if(!(0,e.isSuccessCommandResult)(d))return this.logger.error("[run] Failed to get public key",{data:{error:d.error}}),(0,e.CommandResultFactory)({error:d.error});const f=(0,e.bufferToHexaString)(d.data.publicKey,!1);this.logger.debug("[run] Getting challenge");const c=await this.api.sendCommand(new h.GetChallengeCommand);if(!(0,e.isSuccessCommandResult)(c))return this.logger.error("[run] Failed to get challenge",{data:{error:c.error}}),(0,e.CommandResultFactory)({error:c.error});const b=c.data.challenge;this.logger.debug("[run] Fetching account ownership context",{data:{publicKey:f,address:n,network:i}});const A=this.api.getDeviceModel().id;let u;try{u=await a.getContexts({publicKey:f,address:n,challenge:b,network:i,deviceModelId:A},[l.ClearSignContextType.ACCOUNT_OWNERSHIP])}catch(t){return this.logger.error("[run] Context module error",{data:{error:t}}),(0,e.CommandResultFactory)({error:new e.InvalidStatusWordError(`Failed to fetch account ownership context: ${t instanceof Error?t.message:"unknown error"}`)})}const s=u.find(t=>t.type===l.ClearSignContextType.ACCOUNT_OWNERSHIP);if(!s){const t=u.find(v=>v.type===l.ClearSignContextType.ERROR);return t&&"error"in t?(0,e.CommandResultFactory)({error:new x.TrustedMetadataServiceError(t.error.message)}):(0,e.CommandResultFactory)({error:new e.InvalidStatusWordError("No account ownership context returned")})}if(s.certificate){this.logger.debug("[run] Loading PKI certificate");const t=await this.api.sendCommand(new e.LoadCertificateCommand({keyUsage:s.certificate.keyUsageNumber,certificate:s.certificate.payload}));if(!(0,e.isSuccessCommandResult)(t))return this.logger.error("[run] Failed to load certificate",{data:{error:t.error}}),(0,e.CommandResultFactory)({error:t.error})}this.logger.debug("[run] Setting trusted name descriptor");const g=(0,e.hexaStringToBuffer)(s.payload);if(!g||g.length===0)return(0,e.CommandResultFactory)({error:new e.InvalidStatusWordError("Invalid descriptor payload")});const p=await this.api.sendCommand(new w.SetTrustedNameCommand({payload:g}));if(!(0,e.isSuccessCommandResult)(p))return this.logger.error("[run] Failed to set trusted name",{data:{error:p.error}}),(0,e.CommandResultFactory)({error:p.error});this.logger.debug("[run] Sending verify address command");const m=await this.api.sendCommand(new S.VerifyAddressCommand({derivationPath:r}));return(0,e.isSuccessCommandResult)(m)?(0,e.CommandResultFactory)({data:!0}):(this.logger.error("[run] Failed to verify address",{data:{error:m.error}}),(0,e.CommandResultFactory)({error:m.error}))}}0&&(module.exports={VerifyAddressTask});
2
2
  //# sourceMappingURL=VerifyAddressTask.js.map
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "version": 3,
3
3
  "sources": ["../../../../../src/internal/app-binder/task/VerifyAddressTask.ts"],
4
- "sourcesContent": ["import {\n type AccountOwnershipNetwork,\n type ClearSignContextSuccess,\n ClearSignContextType,\n type ContextModule,\n} from \"@ledgerhq/context-module\";\nimport {\n bufferToHexaString,\n type CommandResult,\n CommandResultFactory,\n hexaStringToBuffer,\n type InternalApi,\n InvalidStatusWordError,\n isSuccessCommandResult,\n LoadCertificateCommand,\n type LoggerPublisherService,\n} from \"@ledgerhq/device-management-kit\";\n\nimport { type VerifyAddressErrorCodes } from \"@api/app-binder/VerifyAddressDeviceActionTypes\";\nimport { GetChallengeCommand } from \"@internal/app-binder/command/GetChallengeCommand\";\nimport { GetPublicKeyCommand } from \"@internal/app-binder/command/GetPublicKeyCommand\";\nimport { SetTrustedNameCommand } from \"@internal/app-binder/command/SetTrustedNameCommand\";\nimport { VerifyAddressCommand } from \"@internal/app-binder/command/VerifyAddressCommand\";\n\nexport type VerifyAddressTaskArgs = {\n readonly derivationPath: string;\n readonly address: string;\n readonly network: AccountOwnershipNetwork;\n readonly contextModule: ContextModule;\n};\n\nexport class VerifyAddressTask {\n constructor(\n private readonly api: InternalApi,\n private readonly args: VerifyAddressTaskArgs,\n private readonly logger: LoggerPublisherService,\n ) {}\n\n async run(): Promise<CommandResult<true, VerifyAddressErrorCodes>> {\n const { derivationPath, address, network, contextModule } = this.args;\n\n // Step 1: Get public key (without device confirmation)\n this.logger.debug(\"[run] Getting public key\");\n const pubKeyResult = await this.api.sendCommand(\n new GetPublicKeyCommand({\n derivationPath,\n checkOnDevice: false,\n skipOpenApp: true,\n }),\n );\n\n if (!isSuccessCommandResult(pubKeyResult)) {\n this.logger.error(\"[run] Failed to get public key\", {\n data: { error: pubKeyResult.error },\n });\n return CommandResultFactory({ error: pubKeyResult.error });\n }\n\n const publicKeyHex = bufferToHexaString(pubKeyResult.data.publicKey, false);\n\n // Step 2: Get challenge from device\n this.logger.debug(\"[run] Getting challenge\");\n const challengeResult = await this.api.sendCommand(\n new GetChallengeCommand(),\n );\n\n if (!isSuccessCommandResult(challengeResult)) {\n this.logger.error(\"[run] Failed to get challenge\", {\n data: { error: challengeResult.error },\n });\n return CommandResultFactory({ error: challengeResult.error });\n }\n\n const challenge = challengeResult.data.challenge;\n\n // Step 3: Fetch account ownership context from trusted metadata service\n this.logger.debug(\"[run] Fetching account ownership context\", {\n data: { publicKey: publicKeyHex, address, network },\n });\n\n const deviceModelId = this.api.getDeviceModel().id;\n let contexts: Awaited<ReturnType<ContextModule[\"getContexts\"]>>;\n try {\n contexts = await contextModule.getContexts(\n {\n publicKey: publicKeyHex,\n address,\n challenge,\n network,\n deviceModelId,\n },\n [ClearSignContextType.ACCOUNT_OWNERSHIP],\n );\n } catch (error) {\n this.logger.error(\"[run] Context module error\", { data: { error } });\n return CommandResultFactory({\n error: new InvalidStatusWordError(\n `Failed to fetch account ownership context: ${error instanceof Error ? error.message : \"unknown error\"}`,\n ),\n });\n }\n\n const ownershipContext = contexts.find(\n (\n c,\n ): c is ClearSignContextSuccess<ClearSignContextType.ACCOUNT_OWNERSHIP> =>\n c.type === ClearSignContextType.ACCOUNT_OWNERSHIP,\n );\n\n if (!ownershipContext) {\n const errorCtx = contexts.find(\n (c) => c.type === ClearSignContextType.ERROR,\n );\n const errorMessage =\n errorCtx && \"error\" in errorCtx\n ? errorCtx.error.message\n : \"No account ownership context returned\";\n return CommandResultFactory({\n error: new InvalidStatusWordError(errorMessage),\n });\n }\n\n // Step 4: Load PKI certificate on device\n if (ownershipContext.certificate) {\n this.logger.debug(\"[run] Loading PKI certificate\");\n const certResult = await this.api.sendCommand(\n new LoadCertificateCommand({\n keyUsage: ownershipContext.certificate.keyUsageNumber,\n certificate: ownershipContext.certificate.payload,\n }),\n );\n\n if (!isSuccessCommandResult(certResult)) {\n this.logger.error(\"[run] Failed to load certificate\", {\n data: { error: certResult.error },\n });\n return CommandResultFactory({ error: certResult.error });\n }\n }\n\n // Step 5: Set trusted name descriptor on device\n this.logger.debug(\"[run] Setting trusted name descriptor\");\n const descriptorBytes = hexaStringToBuffer(ownershipContext.payload);\n\n if (!descriptorBytes || descriptorBytes.length === 0) {\n return CommandResultFactory({\n error: new InvalidStatusWordError(\"Invalid descriptor payload\"),\n });\n }\n\n const trustedNameResult = await this.api.sendCommand(\n new SetTrustedNameCommand({ payload: descriptorBytes }),\n );\n\n if (!isSuccessCommandResult(trustedNameResult)) {\n this.logger.error(\"[run] Failed to set trusted name\", {\n data: { error: trustedNameResult.error },\n });\n return CommandResultFactory({ error: trustedNameResult.error });\n }\n\n // Step 6: Verify address on device (user approval)\n this.logger.debug(\"[run] Sending verify address command\");\n const verifyResult = await this.api.sendCommand(\n new VerifyAddressCommand({ derivationPath }),\n );\n\n if (!isSuccessCommandResult(verifyResult)) {\n this.logger.error(\"[run] Failed to verify address\", {\n data: { error: verifyResult.error },\n });\n return CommandResultFactory({ error: verifyResult.error });\n }\n\n return CommandResultFactory({ data: true as const });\n }\n}\n"],
5
- "mappings": "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",
6
- "names": ["VerifyAddressTask_exports", "__export", "VerifyAddressTask", "__toCommonJS", "import_context_module", "import_device_management_kit", "import_GetChallengeCommand", "import_GetPublicKeyCommand", "import_SetTrustedNameCommand", "import_VerifyAddressCommand", "api", "args", "logger", "derivationPath", "address", "network", "contextModule", "pubKeyResult", "publicKeyHex", "challengeResult", "challenge", "deviceModelId", "contexts", "error", "ownershipContext", "c", "errorCtx", "errorMessage", "certResult", "descriptorBytes", "trustedNameResult", "verifyResult"]
4
+ "sourcesContent": ["import {\n type AccountOwnershipNetwork,\n type ClearSignContextSuccess,\n ClearSignContextType,\n type ContextModule,\n} from \"@ledgerhq/context-module\";\nimport {\n bufferToHexaString,\n type CommandResult,\n CommandResultFactory,\n hexaStringToBuffer,\n type InternalApi,\n InvalidStatusWordError,\n isSuccessCommandResult,\n LoadCertificateCommand,\n type LoggerPublisherService,\n} from \"@ledgerhq/device-management-kit\";\n\nimport { type VerifyAddressErrorCodes } from \"@api/app-binder/VerifyAddressDeviceActionTypes\";\nimport { GetChallengeCommand } from \"@internal/app-binder/command/GetChallengeCommand\";\nimport { GetPublicKeyCommand } from \"@internal/app-binder/command/GetPublicKeyCommand\";\nimport { SetTrustedNameCommand } from \"@internal/app-binder/command/SetTrustedNameCommand\";\nimport { TrustedMetadataServiceError } from \"@internal/app-binder/command/utils/TrustedMetadataServiceError\";\nimport { VerifyAddressCommand } from \"@internal/app-binder/command/VerifyAddressCommand\";\n\nexport type VerifyAddressTaskArgs = {\n readonly derivationPath: string;\n readonly address: string;\n readonly network: AccountOwnershipNetwork;\n readonly contextModule: ContextModule;\n};\n\nexport class VerifyAddressTask {\n constructor(\n private readonly api: InternalApi,\n private readonly args: VerifyAddressTaskArgs,\n private readonly logger: LoggerPublisherService,\n ) {}\n\n async run(): Promise<CommandResult<true, VerifyAddressErrorCodes>> {\n const { derivationPath, address, network, contextModule } = this.args;\n\n // Step 1: Get public key (without device confirmation)\n this.logger.debug(\"[run] Getting public key\");\n const pubKeyResult = await this.api.sendCommand(\n new GetPublicKeyCommand({\n derivationPath,\n checkOnDevice: false,\n skipOpenApp: true,\n }),\n );\n\n if (!isSuccessCommandResult(pubKeyResult)) {\n this.logger.error(\"[run] Failed to get public key\", {\n data: { error: pubKeyResult.error },\n });\n return CommandResultFactory({ error: pubKeyResult.error });\n }\n\n const publicKeyHex = bufferToHexaString(pubKeyResult.data.publicKey, false);\n\n // Step 2: Get challenge from device\n this.logger.debug(\"[run] Getting challenge\");\n const challengeResult = await this.api.sendCommand(\n new GetChallengeCommand(),\n );\n\n if (!isSuccessCommandResult(challengeResult)) {\n this.logger.error(\"[run] Failed to get challenge\", {\n data: { error: challengeResult.error },\n });\n return CommandResultFactory({ error: challengeResult.error });\n }\n\n const challenge = challengeResult.data.challenge;\n\n // Step 3: Fetch account ownership context from trusted metadata service\n this.logger.debug(\"[run] Fetching account ownership context\", {\n data: { publicKey: publicKeyHex, address, network },\n });\n\n const deviceModelId = this.api.getDeviceModel().id;\n let contexts: Awaited<ReturnType<ContextModule[\"getContexts\"]>>;\n try {\n contexts = await contextModule.getContexts(\n {\n publicKey: publicKeyHex,\n address,\n challenge,\n network,\n deviceModelId,\n },\n [ClearSignContextType.ACCOUNT_OWNERSHIP],\n );\n } catch (error) {\n this.logger.error(\"[run] Context module error\", { data: { error } });\n return CommandResultFactory({\n error: new InvalidStatusWordError(\n `Failed to fetch account ownership context: ${error instanceof Error ? error.message : \"unknown error\"}`,\n ),\n });\n }\n\n const ownershipContext = contexts.find(\n (\n c,\n ): c is ClearSignContextSuccess<ClearSignContextType.ACCOUNT_OWNERSHIP> =>\n c.type === ClearSignContextType.ACCOUNT_OWNERSHIP,\n );\n\n if (!ownershipContext) {\n const errorCtx = contexts.find(\n (c) => c.type === ClearSignContextType.ERROR,\n );\n if (errorCtx && \"error\" in errorCtx) {\n return CommandResultFactory({\n error: new TrustedMetadataServiceError(errorCtx.error.message),\n });\n }\n return CommandResultFactory({\n error: new InvalidStatusWordError(\n \"No account ownership context returned\",\n ),\n });\n }\n\n // Step 4: Load PKI certificate on device\n if (ownershipContext.certificate) {\n this.logger.debug(\"[run] Loading PKI certificate\");\n const certResult = await this.api.sendCommand(\n new LoadCertificateCommand({\n keyUsage: ownershipContext.certificate.keyUsageNumber,\n certificate: ownershipContext.certificate.payload,\n }),\n );\n\n if (!isSuccessCommandResult(certResult)) {\n this.logger.error(\"[run] Failed to load certificate\", {\n data: { error: certResult.error },\n });\n return CommandResultFactory({ error: certResult.error });\n }\n }\n\n // Step 5: Set trusted name descriptor on device\n this.logger.debug(\"[run] Setting trusted name descriptor\");\n const descriptorBytes = hexaStringToBuffer(ownershipContext.payload);\n\n if (!descriptorBytes || descriptorBytes.length === 0) {\n return CommandResultFactory({\n error: new InvalidStatusWordError(\"Invalid descriptor payload\"),\n });\n }\n\n const trustedNameResult = await this.api.sendCommand(\n new SetTrustedNameCommand({ payload: descriptorBytes }),\n );\n\n if (!isSuccessCommandResult(trustedNameResult)) {\n this.logger.error(\"[run] Failed to set trusted name\", {\n data: { error: trustedNameResult.error },\n });\n return CommandResultFactory({ error: trustedNameResult.error });\n }\n\n // Step 6: Verify address on device (user approval)\n this.logger.debug(\"[run] Sending verify address command\");\n const verifyResult = await this.api.sendCommand(\n new VerifyAddressCommand({ derivationPath }),\n );\n\n if (!isSuccessCommandResult(verifyResult)) {\n this.logger.error(\"[run] Failed to verify address\", {\n data: { error: verifyResult.error },\n });\n return CommandResultFactory({ error: verifyResult.error });\n }\n\n return CommandResultFactory({ data: true as const });\n }\n}\n"],
5
+ "mappings": "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",
6
+ "names": ["VerifyAddressTask_exports", "__export", "VerifyAddressTask", "__toCommonJS", "import_context_module", "import_device_management_kit", "import_GetChallengeCommand", "import_GetPublicKeyCommand", "import_SetTrustedNameCommand", "import_TrustedMetadataServiceError", "import_VerifyAddressCommand", "api", "args", "logger", "derivationPath", "address", "network", "contextModule", "pubKeyResult", "publicKeyHex", "challengeResult", "challenge", "deviceModelId", "contexts", "error", "ownershipContext", "c", "errorCtx", "certResult", "descriptorBytes", "trustedNameResult", "verifyResult"]
7
7
  }
@@ -1,2 +1,2 @@
1
- "use strict";var p=require("@ledgerhq/context-module"),e=require("@ledgerhq/device-management-kit"),o=require("vitest"),r=require("../../app-binder/command/utils/ConcordiumApplicationErrors"),h=require("../../app-binder/task/VerifyAddressTask");const w="44'/919'/0'/0'/0'",x="3kFkntk2H5FGMzeR3GjQKPhdZK9LShKdPHsj2fiGKCdmDXj2WB",y="mainnet",l=new Uint8Array(32).fill(171),d="aabbccdd11223344",E="0102030405",g={keyUsageNumber:4,payload:new Uint8Array([16,32,48])};function u(a=!0){return[{type:p.ClearSignContextType.ACCOUNT_OWNERSHIP,payload:E,certificate:a?g:void 0}]}function R(a){return[{type:p.ClearSignContextType.ERROR,error:new Error(a)}]}describe("VerifyAddressTask",()=>{let a,m,C,s;beforeEach(()=>{a=o.vi.fn(),m={sendCommand:a,getDeviceModel:()=>({id:e.DeviceModelId.NANO_SP})},C={debug:o.vi.fn(),error:o.vi.fn()},s={getContexts:o.vi.fn()}});function c(){return new h.VerifyAddressTask(m,{derivationPath:w,address:x,network:y,contextModule:s},C)}function i(...t){let n=0;a.mockImplementation(()=>Promise.resolve(t[n++]))}describe("success path",()=>{it("should complete the full flow with certificate",async()=>{i((0,e.CommandResultFactory)({data:{publicKey:l}}),(0,e.CommandResultFactory)({data:{challenge:d}}),(0,e.CommandResultFactory)({data:void 0}),(0,e.CommandResultFactory)({data:void 0}),(0,e.CommandResultFactory)({data:void 0})),o.vi.spyOn(s,"getContexts").mockResolvedValue(u(!0));const t=await c().run();expect((0,e.isSuccessCommandResult)(t)).toBe(!0),(0,e.isSuccessCommandResult)(t)&&expect(t.data).toBe(!0),expect(a).toHaveBeenCalledTimes(5),expect(s.getContexts).toHaveBeenCalledWith(expect.objectContaining({publicKey:"ab".repeat(32),address:x,challenge:d,network:y,deviceModelId:e.DeviceModelId.NANO_SP}),[p.ClearSignContextType.ACCOUNT_OWNERSHIP])}),it("should skip LoadCertificate when context has no certificate",async()=>{i((0,e.CommandResultFactory)({data:{publicKey:l}}),(0,e.CommandResultFactory)({data:{challenge:d}}),(0,e.CommandResultFactory)({data:void 0}),(0,e.CommandResultFactory)({data:void 0})),o.vi.spyOn(s,"getContexts").mockResolvedValue(u(!1));const t=await c().run();expect((0,e.isSuccessCommandResult)(t)).toBe(!0),expect(a).toHaveBeenCalledTimes(4)})}),describe("failure cases",()=>{it("should fail when GetPublicKey fails",async()=>{const t=new r.ConcordiumAppCommandError({message:"User rejected",errorCode:r.ConcordiumErrorCodes.USER_REJECTED});a.mockResolvedValueOnce((0,e.CommandResultFactory)({error:t}));const n=await c().run();expect((0,e.isSuccessCommandResult)(n)).toBe(!1),expect(a).toHaveBeenCalledTimes(1)}),it("should fail when GetChallenge fails",async()=>{const t=new r.ConcordiumAppCommandError({message:"INS not supported",errorCode:r.ConcordiumErrorCodes.INS_NOT_SUPPORTED});a.mockResolvedValueOnce((0,e.CommandResultFactory)({data:{publicKey:l}})).mockResolvedValueOnce((0,e.CommandResultFactory)({error:t}));const n=await c().run();expect((0,e.isSuccessCommandResult)(n)).toBe(!1),expect(a).toHaveBeenCalledTimes(2)}),it("should fail when context module returns error context",async()=>{i((0,e.CommandResultFactory)({data:{publicKey:l}}),(0,e.CommandResultFactory)({data:{challenge:d}})),o.vi.spyOn(s,"getContexts").mockResolvedValue(R("Backend unavailable"));const t=await c().run();expect((0,e.isSuccessCommandResult)(t)).toBe(!1),(0,e.isSuccessCommandResult)(t)||expect(t.error).toBeInstanceOf(e.InvalidStatusWordError)}),it("should fail when context module returns empty contexts",async()=>{i((0,e.CommandResultFactory)({data:{publicKey:l}}),(0,e.CommandResultFactory)({data:{challenge:d}})),o.vi.spyOn(s,"getContexts").mockResolvedValue([]);const t=await c().run();expect((0,e.isSuccessCommandResult)(t)).toBe(!1),(0,e.isSuccessCommandResult)(t)||expect(t.error).toBeInstanceOf(e.InvalidStatusWordError)}),it("should fail when context module throws",async()=>{i((0,e.CommandResultFactory)({data:{publicKey:l}}),(0,e.CommandResultFactory)({data:{challenge:d}})),o.vi.spyOn(s,"getContexts").mockRejectedValue(new Error("Network timeout"));const t=await c().run();expect((0,e.isSuccessCommandResult)(t)).toBe(!1),(0,e.isSuccessCommandResult)(t)||expect(t.error).toBeInstanceOf(e.InvalidStatusWordError)}),it("should fail when LoadCertificate fails",async()=>{i((0,e.CommandResultFactory)({data:{publicKey:l}}),(0,e.CommandResultFactory)({data:{challenge:d}}),(0,e.CommandResultFactory)({error:new e.InvalidStatusWordError("cert error")})),o.vi.spyOn(s,"getContexts").mockResolvedValue(u(!0));const t=await c().run();expect((0,e.isSuccessCommandResult)(t)).toBe(!1),(0,e.isSuccessCommandResult)(t)||expect(t.error).toBeInstanceOf(e.InvalidStatusWordError),expect(a).toHaveBeenCalledTimes(3)}),it("should fail when descriptor payload is empty",async()=>{i((0,e.CommandResultFactory)({data:{publicKey:l}}),(0,e.CommandResultFactory)({data:{challenge:d}}),(0,e.CommandResultFactory)({data:void 0})),o.vi.spyOn(s,"getContexts").mockResolvedValue([{type:p.ClearSignContextType.ACCOUNT_OWNERSHIP,payload:"",certificate:g}]);const t=await c().run();expect((0,e.isSuccessCommandResult)(t)).toBe(!1),(0,e.isSuccessCommandResult)(t)||expect(t.error).toBeInstanceOf(e.InvalidStatusWordError)}),it("should fail when SetTrustedName fails",async()=>{const t=new r.ConcordiumAppCommandError({message:"Data invalid",errorCode:r.ConcordiumErrorCodes.DATA_INVALID});i((0,e.CommandResultFactory)({data:{publicKey:l}}),(0,e.CommandResultFactory)({data:{challenge:d}}),(0,e.CommandResultFactory)({data:void 0}),(0,e.CommandResultFactory)({error:t})),o.vi.spyOn(s,"getContexts").mockResolvedValue(u(!0));const n=await c().run();expect((0,e.isSuccessCommandResult)(n)).toBe(!1),expect(a).toHaveBeenCalledTimes(4)}),it("should fail when VerifyAddress is rejected by user",async()=>{const t=new r.ConcordiumAppCommandError({message:"User rejected",errorCode:r.ConcordiumErrorCodes.USER_REJECTED});i((0,e.CommandResultFactory)({data:{publicKey:l}}),(0,e.CommandResultFactory)({data:{challenge:d}}),(0,e.CommandResultFactory)({data:void 0}),(0,e.CommandResultFactory)({data:void 0}),(0,e.CommandResultFactory)({error:t})),o.vi.spyOn(s,"getContexts").mockResolvedValue(u(!0));const n=await c().run();if(expect((0,e.isSuccessCommandResult)(n)).toBe(!1),!(0,e.isSuccessCommandResult)(n)){const f=n.error;expect(f.errorCode).toBe(r.ConcordiumErrorCodes.USER_REJECTED)}expect(a).toHaveBeenCalledTimes(5)}),it("should fail when VerifyAddress returns trusted name mismatch",async()=>{const t=new r.ConcordiumAppCommandError({message:"Trusted name mismatch",errorCode:r.ConcordiumErrorCodes.TRUSTED_NAME_MISMATCH});i((0,e.CommandResultFactory)({data:{publicKey:l}}),(0,e.CommandResultFactory)({data:{challenge:d}}),(0,e.CommandResultFactory)({data:void 0}),(0,e.CommandResultFactory)({data:void 0}),(0,e.CommandResultFactory)({error:t})),o.vi.spyOn(s,"getContexts").mockResolvedValue(u(!0));const n=await c().run();if(expect((0,e.isSuccessCommandResult)(n)).toBe(!1),!(0,e.isSuccessCommandResult)(n)){const f=n.error;expect(f.errorCode).toBe(r.ConcordiumErrorCodes.TRUSTED_NAME_MISMATCH)}})})});
1
+ "use strict";var p=require("@ledgerhq/context-module"),e=require("@ledgerhq/device-management-kit"),r=require("vitest"),n=require("../../app-binder/command/utils/ConcordiumApplicationErrors"),h=require("../../app-binder/command/utils/TrustedMetadataServiceError"),E=require("../../app-binder/task/VerifyAddressTask");const R="44'/919'/0'/0'/0'",x="3kFkntk2H5FGMzeR3GjQKPhdZK9LShKdPHsj2fiGKCdmDXj2WB",y="mainnet",l=new Uint8Array(32).fill(171),d="aabbccdd11223344",w="0102030405",g={keyUsageNumber:4,payload:new Uint8Array([16,32,48])};function u(a=!0){return[{type:p.ClearSignContextType.ACCOUNT_OWNERSHIP,payload:w,certificate:a?g:void 0}]}function T(a){return[{type:p.ClearSignContextType.ERROR,error:new Error(a)}]}describe("VerifyAddressTask",()=>{let a,m,C,s;beforeEach(()=>{a=r.vi.fn(),m={sendCommand:a,getDeviceModel:()=>({id:e.DeviceModelId.NANO_SP})},C={debug:r.vi.fn(),error:r.vi.fn()},s={getContexts:r.vi.fn()}});function c(){return new E.VerifyAddressTask(m,{derivationPath:R,address:x,network:y,contextModule:s},C)}function i(...t){let o=0;a.mockImplementation(()=>Promise.resolve(t[o++]))}describe("success path",()=>{it("should complete the full flow with certificate",async()=>{i((0,e.CommandResultFactory)({data:{publicKey:l}}),(0,e.CommandResultFactory)({data:{challenge:d}}),(0,e.CommandResultFactory)({data:void 0}),(0,e.CommandResultFactory)({data:void 0}),(0,e.CommandResultFactory)({data:void 0})),r.vi.spyOn(s,"getContexts").mockResolvedValue(u(!0));const t=await c().run();expect((0,e.isSuccessCommandResult)(t)).toBe(!0),(0,e.isSuccessCommandResult)(t)&&expect(t.data).toBe(!0),expect(a).toHaveBeenCalledTimes(5),expect(s.getContexts).toHaveBeenCalledWith(expect.objectContaining({publicKey:"ab".repeat(32),address:x,challenge:d,network:y,deviceModelId:e.DeviceModelId.NANO_SP}),[p.ClearSignContextType.ACCOUNT_OWNERSHIP])}),it("should skip LoadCertificate when context has no certificate",async()=>{i((0,e.CommandResultFactory)({data:{publicKey:l}}),(0,e.CommandResultFactory)({data:{challenge:d}}),(0,e.CommandResultFactory)({data:void 0}),(0,e.CommandResultFactory)({data:void 0})),r.vi.spyOn(s,"getContexts").mockResolvedValue(u(!1));const t=await c().run();expect((0,e.isSuccessCommandResult)(t)).toBe(!0),expect(a).toHaveBeenCalledTimes(4)})}),describe("failure cases",()=>{it("should fail when GetPublicKey fails",async()=>{const t=new n.ConcordiumAppCommandError({message:"User rejected",errorCode:n.ConcordiumErrorCodes.USER_REJECTED});a.mockResolvedValueOnce((0,e.CommandResultFactory)({error:t}));const o=await c().run();expect((0,e.isSuccessCommandResult)(o)).toBe(!1),expect(a).toHaveBeenCalledTimes(1)}),it("should fail when GetChallenge fails",async()=>{const t=new n.ConcordiumAppCommandError({message:"INS not supported",errorCode:n.ConcordiumErrorCodes.INS_NOT_SUPPORTED});a.mockResolvedValueOnce((0,e.CommandResultFactory)({data:{publicKey:l}})).mockResolvedValueOnce((0,e.CommandResultFactory)({error:t}));const o=await c().run();expect((0,e.isSuccessCommandResult)(o)).toBe(!1),expect(a).toHaveBeenCalledTimes(2)}),it("should fail with TrustedMetadataServiceError when context module returns error context",async()=>{i((0,e.CommandResultFactory)({data:{publicKey:l}}),(0,e.CommandResultFactory)({data:{challenge:d}})),r.vi.spyOn(s,"getContexts").mockResolvedValue(T("Backend unavailable"));const t=await c().run();expect((0,e.isSuccessCommandResult)(t)).toBe(!1),(0,e.isSuccessCommandResult)(t)||(expect(t.error).toBeInstanceOf(h.TrustedMetadataServiceError),expect(t.error).toHaveProperty("errorCode",n.ConcordiumErrorCodes.TRUSTED_METADATA_SERVICE_ERROR))}),it("should fail when context module returns empty contexts",async()=>{i((0,e.CommandResultFactory)({data:{publicKey:l}}),(0,e.CommandResultFactory)({data:{challenge:d}})),r.vi.spyOn(s,"getContexts").mockResolvedValue([]);const t=await c().run();expect((0,e.isSuccessCommandResult)(t)).toBe(!1),(0,e.isSuccessCommandResult)(t)||expect(t.error).toBeInstanceOf(e.InvalidStatusWordError)}),it("should fail when context module throws",async()=>{i((0,e.CommandResultFactory)({data:{publicKey:l}}),(0,e.CommandResultFactory)({data:{challenge:d}})),r.vi.spyOn(s,"getContexts").mockRejectedValue(new Error("Network timeout"));const t=await c().run();expect((0,e.isSuccessCommandResult)(t)).toBe(!1),(0,e.isSuccessCommandResult)(t)||expect(t.error).toBeInstanceOf(e.InvalidStatusWordError)}),it("should fail when LoadCertificate fails",async()=>{i((0,e.CommandResultFactory)({data:{publicKey:l}}),(0,e.CommandResultFactory)({data:{challenge:d}}),(0,e.CommandResultFactory)({error:new e.InvalidStatusWordError("cert error")})),r.vi.spyOn(s,"getContexts").mockResolvedValue(u(!0));const t=await c().run();expect((0,e.isSuccessCommandResult)(t)).toBe(!1),(0,e.isSuccessCommandResult)(t)||expect(t.error).toBeInstanceOf(e.InvalidStatusWordError),expect(a).toHaveBeenCalledTimes(3)}),it("should fail when descriptor payload is empty",async()=>{i((0,e.CommandResultFactory)({data:{publicKey:l}}),(0,e.CommandResultFactory)({data:{challenge:d}}),(0,e.CommandResultFactory)({data:void 0})),r.vi.spyOn(s,"getContexts").mockResolvedValue([{type:p.ClearSignContextType.ACCOUNT_OWNERSHIP,payload:"",certificate:g}]);const t=await c().run();expect((0,e.isSuccessCommandResult)(t)).toBe(!1),(0,e.isSuccessCommandResult)(t)||expect(t.error).toBeInstanceOf(e.InvalidStatusWordError)}),it("should fail when SetTrustedName fails",async()=>{const t=new n.ConcordiumAppCommandError({message:"Data invalid",errorCode:n.ConcordiumErrorCodes.DATA_INVALID});i((0,e.CommandResultFactory)({data:{publicKey:l}}),(0,e.CommandResultFactory)({data:{challenge:d}}),(0,e.CommandResultFactory)({data:void 0}),(0,e.CommandResultFactory)({error:t})),r.vi.spyOn(s,"getContexts").mockResolvedValue(u(!0));const o=await c().run();expect((0,e.isSuccessCommandResult)(o)).toBe(!1),expect(a).toHaveBeenCalledTimes(4)}),it("should fail when VerifyAddress is rejected by user",async()=>{const t=new n.ConcordiumAppCommandError({message:"User rejected",errorCode:n.ConcordiumErrorCodes.USER_REJECTED});i((0,e.CommandResultFactory)({data:{publicKey:l}}),(0,e.CommandResultFactory)({data:{challenge:d}}),(0,e.CommandResultFactory)({data:void 0}),(0,e.CommandResultFactory)({data:void 0}),(0,e.CommandResultFactory)({error:t})),r.vi.spyOn(s,"getContexts").mockResolvedValue(u(!0));const o=await c().run();if(expect((0,e.isSuccessCommandResult)(o)).toBe(!1),!(0,e.isSuccessCommandResult)(o)){const f=o.error;expect(f.errorCode).toBe(n.ConcordiumErrorCodes.USER_REJECTED)}expect(a).toHaveBeenCalledTimes(5)}),it("should fail when VerifyAddress returns trusted name mismatch",async()=>{const t=new n.ConcordiumAppCommandError({message:"Trusted name mismatch",errorCode:n.ConcordiumErrorCodes.TRUSTED_NAME_MISMATCH});i((0,e.CommandResultFactory)({data:{publicKey:l}}),(0,e.CommandResultFactory)({data:{challenge:d}}),(0,e.CommandResultFactory)({data:void 0}),(0,e.CommandResultFactory)({data:void 0}),(0,e.CommandResultFactory)({error:t})),r.vi.spyOn(s,"getContexts").mockResolvedValue(u(!0));const o=await c().run();if(expect((0,e.isSuccessCommandResult)(o)).toBe(!1),!(0,e.isSuccessCommandResult)(o)){const f=o.error;expect(f.errorCode).toBe(n.ConcordiumErrorCodes.TRUSTED_NAME_MISMATCH)}})})});
2
2
  //# sourceMappingURL=VerifyAddressTask.test.js.map
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "version": 3,
3
3
  "sources": ["../../../../../src/internal/app-binder/task/VerifyAddressTask.test.ts"],
4
- "sourcesContent": ["import {\n type ClearSignContext,\n ClearSignContextType,\n type ContextModule,\n} from \"@ledgerhq/context-module\";\nimport {\n CommandResultFactory,\n DeviceModelId,\n type InternalApi,\n InvalidStatusWordError,\n isSuccessCommandResult,\n type LoggerPublisherService,\n} from \"@ledgerhq/device-management-kit\";\nimport { vi } from \"vitest\";\n\nimport {\n ConcordiumAppCommandError,\n ConcordiumErrorCodes,\n} from \"@internal/app-binder/command/utils/ConcordiumApplicationErrors\";\nimport { VerifyAddressTask } from \"@internal/app-binder/task/VerifyAddressTask\";\n\nconst DERIVATION_PATH = \"44'/919'/0'/0'/0'\";\nconst ADDRESS = \"3kFkntk2H5FGMzeR3GjQKPhdZK9LShKdPHsj2fiGKCdmDXj2WB\";\nconst NETWORK = \"mainnet\" as const;\nconst PUBLIC_KEY = new Uint8Array(32).fill(0xab);\nconst CHALLENGE = \"aabbccdd11223344\";\nconst DESCRIPTOR_HEX = \"0102030405\";\nconst CERTIFICATE = {\n keyUsageNumber: 4,\n payload: new Uint8Array([0x10, 0x20, 0x30]),\n};\n\nfunction makeSuccessContext(withCertificate = true): ClearSignContext[] {\n return [\n {\n type: ClearSignContextType.ACCOUNT_OWNERSHIP,\n payload: DESCRIPTOR_HEX,\n certificate: withCertificate ? CERTIFICATE : undefined,\n },\n ];\n}\n\nfunction makeErrorContext(message: string): ClearSignContext[] {\n return [\n {\n type: ClearSignContextType.ERROR,\n error: new Error(message),\n },\n ];\n}\n\ndescribe(\"VerifyAddressTask\", () => {\n let sendCommandMock: ReturnType<typeof vi.fn>;\n let apiMock: InternalApi;\n let loggerMock: LoggerPublisherService;\n let contextModuleMock: ContextModule;\n\n beforeEach(() => {\n sendCommandMock = vi.fn();\n apiMock = {\n sendCommand: sendCommandMock,\n getDeviceModel: () => ({ id: DeviceModelId.NANO_SP }),\n } as unknown as InternalApi;\n loggerMock = {\n debug: vi.fn(),\n error: vi.fn(),\n } as unknown as LoggerPublisherService;\n contextModuleMock = {\n getContexts: vi.fn(),\n } as unknown as ContextModule;\n });\n\n function createTask() {\n return new VerifyAddressTask(\n apiMock,\n {\n derivationPath: DERIVATION_PATH,\n address: ADDRESS,\n network: NETWORK,\n contextModule: contextModuleMock,\n },\n loggerMock,\n );\n }\n\n function mockSendCommandSequence(\n ...results: ReturnType<typeof CommandResultFactory>[]\n ) {\n let callIndex = 0;\n sendCommandMock.mockImplementation(() =>\n Promise.resolve(results[callIndex++]),\n );\n }\n\n describe(\"success path\", () => {\n it(\"should complete the full flow with certificate\", async () => {\n // GetPublicKey \u2192 GetChallenge \u2192 LoadCertificate \u2192 SetTrustedName \u2192 VerifyAddress\n mockSendCommandSequence(\n CommandResultFactory({ data: { publicKey: PUBLIC_KEY } }),\n CommandResultFactory({ data: { challenge: CHALLENGE } }),\n CommandResultFactory({ data: undefined }), // LoadCertificate\n CommandResultFactory({ data: undefined }), // SetTrustedName\n CommandResultFactory({ data: undefined }), // VerifyAddress\n );\n vi.spyOn(contextModuleMock, \"getContexts\").mockResolvedValue(\n makeSuccessContext(true),\n );\n\n const result = await createTask().run();\n\n expect(isSuccessCommandResult(result)).toBe(true);\n if (isSuccessCommandResult(result)) {\n expect(result.data).toBe(true);\n }\n expect(sendCommandMock).toHaveBeenCalledTimes(5);\n expect(contextModuleMock.getContexts).toHaveBeenCalledWith(\n expect.objectContaining({\n publicKey: \"ab\".repeat(32),\n address: ADDRESS,\n challenge: CHALLENGE,\n network: NETWORK,\n deviceModelId: DeviceModelId.NANO_SP,\n }),\n [ClearSignContextType.ACCOUNT_OWNERSHIP],\n );\n });\n\n it(\"should skip LoadCertificate when context has no certificate\", async () => {\n // GetPublicKey \u2192 GetChallenge \u2192 SetTrustedName \u2192 VerifyAddress (no LoadCert)\n mockSendCommandSequence(\n CommandResultFactory({ data: { publicKey: PUBLIC_KEY } }),\n CommandResultFactory({ data: { challenge: CHALLENGE } }),\n CommandResultFactory({ data: undefined }), // SetTrustedName\n CommandResultFactory({ data: undefined }), // VerifyAddress\n );\n vi.spyOn(contextModuleMock, \"getContexts\").mockResolvedValue(\n makeSuccessContext(false),\n );\n\n const result = await createTask().run();\n\n expect(isSuccessCommandResult(result)).toBe(true);\n expect(sendCommandMock).toHaveBeenCalledTimes(4);\n });\n });\n\n describe(\"failure cases\", () => {\n it(\"should fail when GetPublicKey fails\", async () => {\n const error = new ConcordiumAppCommandError({\n message: \"User rejected\",\n errorCode: ConcordiumErrorCodes.USER_REJECTED,\n });\n sendCommandMock.mockResolvedValueOnce(CommandResultFactory({ error }));\n\n const result = await createTask().run();\n\n expect(isSuccessCommandResult(result)).toBe(false);\n expect(sendCommandMock).toHaveBeenCalledTimes(1);\n });\n\n it(\"should fail when GetChallenge fails\", async () => {\n const error = new ConcordiumAppCommandError({\n message: \"INS not supported\",\n errorCode: ConcordiumErrorCodes.INS_NOT_SUPPORTED,\n });\n sendCommandMock\n .mockResolvedValueOnce(\n CommandResultFactory({ data: { publicKey: PUBLIC_KEY } }),\n )\n .mockResolvedValueOnce(CommandResultFactory({ error }));\n\n const result = await createTask().run();\n\n expect(isSuccessCommandResult(result)).toBe(false);\n expect(sendCommandMock).toHaveBeenCalledTimes(2);\n });\n\n it(\"should fail when context module returns error context\", async () => {\n mockSendCommandSequence(\n CommandResultFactory({ data: { publicKey: PUBLIC_KEY } }),\n CommandResultFactory({ data: { challenge: CHALLENGE } }),\n );\n vi.spyOn(contextModuleMock, \"getContexts\").mockResolvedValue(\n makeErrorContext(\"Backend unavailable\"),\n );\n\n const result = await createTask().run();\n\n expect(isSuccessCommandResult(result)).toBe(false);\n if (!isSuccessCommandResult(result)) {\n expect(result.error).toBeInstanceOf(InvalidStatusWordError);\n }\n });\n\n it(\"should fail when context module returns empty contexts\", async () => {\n mockSendCommandSequence(\n CommandResultFactory({ data: { publicKey: PUBLIC_KEY } }),\n CommandResultFactory({ data: { challenge: CHALLENGE } }),\n );\n vi.spyOn(contextModuleMock, \"getContexts\").mockResolvedValue([]);\n\n const result = await createTask().run();\n\n expect(isSuccessCommandResult(result)).toBe(false);\n if (!isSuccessCommandResult(result)) {\n expect(result.error).toBeInstanceOf(InvalidStatusWordError);\n }\n });\n\n it(\"should fail when context module throws\", async () => {\n mockSendCommandSequence(\n CommandResultFactory({ data: { publicKey: PUBLIC_KEY } }),\n CommandResultFactory({ data: { challenge: CHALLENGE } }),\n );\n vi.spyOn(contextModuleMock, \"getContexts\").mockRejectedValue(\n new Error(\"Network timeout\"),\n );\n\n const result = await createTask().run();\n\n expect(isSuccessCommandResult(result)).toBe(false);\n if (!isSuccessCommandResult(result)) {\n expect(result.error).toBeInstanceOf(InvalidStatusWordError);\n }\n });\n\n it(\"should fail when LoadCertificate fails\", async () => {\n mockSendCommandSequence(\n CommandResultFactory({ data: { publicKey: PUBLIC_KEY } }),\n CommandResultFactory({ data: { challenge: CHALLENGE } }),\n CommandResultFactory({\n error: new InvalidStatusWordError(\"cert error\"),\n }),\n );\n vi.spyOn(contextModuleMock, \"getContexts\").mockResolvedValue(\n makeSuccessContext(true),\n );\n\n const result = await createTask().run();\n\n expect(isSuccessCommandResult(result)).toBe(false);\n if (!isSuccessCommandResult(result)) {\n expect(result.error).toBeInstanceOf(InvalidStatusWordError);\n }\n expect(sendCommandMock).toHaveBeenCalledTimes(3);\n });\n\n it(\"should fail when descriptor payload is empty\", async () => {\n mockSendCommandSequence(\n CommandResultFactory({ data: { publicKey: PUBLIC_KEY } }),\n CommandResultFactory({ data: { challenge: CHALLENGE } }),\n CommandResultFactory({ data: undefined }), // LoadCertificate\n );\n vi.spyOn(contextModuleMock, \"getContexts\").mockResolvedValue([\n {\n type: ClearSignContextType.ACCOUNT_OWNERSHIP,\n payload: \"\",\n certificate: CERTIFICATE,\n },\n ]);\n\n const result = await createTask().run();\n\n expect(isSuccessCommandResult(result)).toBe(false);\n if (!isSuccessCommandResult(result)) {\n expect(result.error).toBeInstanceOf(InvalidStatusWordError);\n }\n });\n\n it(\"should fail when SetTrustedName fails\", async () => {\n const error = new ConcordiumAppCommandError({\n message: \"Data invalid\",\n errorCode: ConcordiumErrorCodes.DATA_INVALID,\n });\n mockSendCommandSequence(\n CommandResultFactory({ data: { publicKey: PUBLIC_KEY } }),\n CommandResultFactory({ data: { challenge: CHALLENGE } }),\n CommandResultFactory({ data: undefined }), // LoadCertificate\n CommandResultFactory({ error }),\n );\n vi.spyOn(contextModuleMock, \"getContexts\").mockResolvedValue(\n makeSuccessContext(true),\n );\n\n const result = await createTask().run();\n\n expect(isSuccessCommandResult(result)).toBe(false);\n expect(sendCommandMock).toHaveBeenCalledTimes(4);\n });\n\n it(\"should fail when VerifyAddress is rejected by user\", async () => {\n const error = new ConcordiumAppCommandError({\n message: \"User rejected\",\n errorCode: ConcordiumErrorCodes.USER_REJECTED,\n });\n mockSendCommandSequence(\n CommandResultFactory({ data: { publicKey: PUBLIC_KEY } }),\n CommandResultFactory({ data: { challenge: CHALLENGE } }),\n CommandResultFactory({ data: undefined }), // LoadCertificate\n CommandResultFactory({ data: undefined }), // SetTrustedName\n CommandResultFactory({ error }),\n );\n vi.spyOn(contextModuleMock, \"getContexts\").mockResolvedValue(\n makeSuccessContext(true),\n );\n\n const result = await createTask().run();\n\n expect(isSuccessCommandResult(result)).toBe(false);\n if (!isSuccessCommandResult(result)) {\n const err = result.error as ConcordiumAppCommandError;\n expect(err.errorCode).toBe(ConcordiumErrorCodes.USER_REJECTED);\n }\n expect(sendCommandMock).toHaveBeenCalledTimes(5);\n });\n\n it(\"should fail when VerifyAddress returns trusted name mismatch\", async () => {\n const error = new ConcordiumAppCommandError({\n message: \"Trusted name mismatch\",\n errorCode: ConcordiumErrorCodes.TRUSTED_NAME_MISMATCH,\n });\n mockSendCommandSequence(\n CommandResultFactory({ data: { publicKey: PUBLIC_KEY } }),\n CommandResultFactory({ data: { challenge: CHALLENGE } }),\n CommandResultFactory({ data: undefined }), // LoadCertificate\n CommandResultFactory({ data: undefined }), // SetTrustedName\n CommandResultFactory({ error }),\n );\n vi.spyOn(contextModuleMock, \"getContexts\").mockResolvedValue(\n makeSuccessContext(true),\n );\n\n const result = await createTask().run();\n\n expect(isSuccessCommandResult(result)).toBe(false);\n if (!isSuccessCommandResult(result)) {\n const err = result.error as ConcordiumAppCommandError;\n expect(err.errorCode).toBe(ConcordiumErrorCodes.TRUSTED_NAME_MISMATCH);\n }\n });\n });\n});\n"],
5
- "mappings": "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",
6
- "names": ["import_context_module", "import_device_management_kit", "import_vitest", "import_ConcordiumApplicationErrors", "import_VerifyAddressTask", "DERIVATION_PATH", "ADDRESS", "NETWORK", "PUBLIC_KEY", "CHALLENGE", "DESCRIPTOR_HEX", "CERTIFICATE", "makeSuccessContext", "withCertificate", "makeErrorContext", "message", "sendCommandMock", "apiMock", "loggerMock", "contextModuleMock", "createTask", "mockSendCommandSequence", "results", "callIndex", "result", "error", "err"]
4
+ "sourcesContent": ["import {\n type ClearSignContext,\n ClearSignContextType,\n type ContextModule,\n} from \"@ledgerhq/context-module\";\nimport {\n CommandResultFactory,\n DeviceModelId,\n type InternalApi,\n InvalidStatusWordError,\n isSuccessCommandResult,\n type LoggerPublisherService,\n} from \"@ledgerhq/device-management-kit\";\nimport { vi } from \"vitest\";\n\nimport {\n ConcordiumAppCommandError,\n ConcordiumErrorCodes,\n} from \"@internal/app-binder/command/utils/ConcordiumApplicationErrors\";\nimport { TrustedMetadataServiceError } from \"@internal/app-binder/command/utils/TrustedMetadataServiceError\";\nimport { VerifyAddressTask } from \"@internal/app-binder/task/VerifyAddressTask\";\n\nconst DERIVATION_PATH = \"44'/919'/0'/0'/0'\";\nconst ADDRESS = \"3kFkntk2H5FGMzeR3GjQKPhdZK9LShKdPHsj2fiGKCdmDXj2WB\";\nconst NETWORK = \"mainnet\" as const;\nconst PUBLIC_KEY = new Uint8Array(32).fill(0xab);\nconst CHALLENGE = \"aabbccdd11223344\";\nconst DESCRIPTOR_HEX = \"0102030405\";\nconst CERTIFICATE = {\n keyUsageNumber: 4,\n payload: new Uint8Array([0x10, 0x20, 0x30]),\n};\n\nfunction makeSuccessContext(withCertificate = true): ClearSignContext[] {\n return [\n {\n type: ClearSignContextType.ACCOUNT_OWNERSHIP,\n payload: DESCRIPTOR_HEX,\n certificate: withCertificate ? CERTIFICATE : undefined,\n },\n ];\n}\n\nfunction makeErrorContext(message: string): ClearSignContext[] {\n return [\n {\n type: ClearSignContextType.ERROR,\n error: new Error(message),\n },\n ];\n}\n\ndescribe(\"VerifyAddressTask\", () => {\n let sendCommandMock: ReturnType<typeof vi.fn>;\n let apiMock: InternalApi;\n let loggerMock: LoggerPublisherService;\n let contextModuleMock: ContextModule;\n\n beforeEach(() => {\n sendCommandMock = vi.fn();\n apiMock = {\n sendCommand: sendCommandMock,\n getDeviceModel: () => ({ id: DeviceModelId.NANO_SP }),\n } as unknown as InternalApi;\n loggerMock = {\n debug: vi.fn(),\n error: vi.fn(),\n } as unknown as LoggerPublisherService;\n contextModuleMock = {\n getContexts: vi.fn(),\n } as unknown as ContextModule;\n });\n\n function createTask() {\n return new VerifyAddressTask(\n apiMock,\n {\n derivationPath: DERIVATION_PATH,\n address: ADDRESS,\n network: NETWORK,\n contextModule: contextModuleMock,\n },\n loggerMock,\n );\n }\n\n function mockSendCommandSequence(\n ...results: ReturnType<typeof CommandResultFactory>[]\n ) {\n let callIndex = 0;\n sendCommandMock.mockImplementation(() =>\n Promise.resolve(results[callIndex++]),\n );\n }\n\n describe(\"success path\", () => {\n it(\"should complete the full flow with certificate\", async () => {\n // GetPublicKey \u2192 GetChallenge \u2192 LoadCertificate \u2192 SetTrustedName \u2192 VerifyAddress\n mockSendCommandSequence(\n CommandResultFactory({ data: { publicKey: PUBLIC_KEY } }),\n CommandResultFactory({ data: { challenge: CHALLENGE } }),\n CommandResultFactory({ data: undefined }), // LoadCertificate\n CommandResultFactory({ data: undefined }), // SetTrustedName\n CommandResultFactory({ data: undefined }), // VerifyAddress\n );\n vi.spyOn(contextModuleMock, \"getContexts\").mockResolvedValue(\n makeSuccessContext(true),\n );\n\n const result = await createTask().run();\n\n expect(isSuccessCommandResult(result)).toBe(true);\n if (isSuccessCommandResult(result)) {\n expect(result.data).toBe(true);\n }\n expect(sendCommandMock).toHaveBeenCalledTimes(5);\n expect(contextModuleMock.getContexts).toHaveBeenCalledWith(\n expect.objectContaining({\n publicKey: \"ab\".repeat(32),\n address: ADDRESS,\n challenge: CHALLENGE,\n network: NETWORK,\n deviceModelId: DeviceModelId.NANO_SP,\n }),\n [ClearSignContextType.ACCOUNT_OWNERSHIP],\n );\n });\n\n it(\"should skip LoadCertificate when context has no certificate\", async () => {\n // GetPublicKey \u2192 GetChallenge \u2192 SetTrustedName \u2192 VerifyAddress (no LoadCert)\n mockSendCommandSequence(\n CommandResultFactory({ data: { publicKey: PUBLIC_KEY } }),\n CommandResultFactory({ data: { challenge: CHALLENGE } }),\n CommandResultFactory({ data: undefined }), // SetTrustedName\n CommandResultFactory({ data: undefined }), // VerifyAddress\n );\n vi.spyOn(contextModuleMock, \"getContexts\").mockResolvedValue(\n makeSuccessContext(false),\n );\n\n const result = await createTask().run();\n\n expect(isSuccessCommandResult(result)).toBe(true);\n expect(sendCommandMock).toHaveBeenCalledTimes(4);\n });\n });\n\n describe(\"failure cases\", () => {\n it(\"should fail when GetPublicKey fails\", async () => {\n const error = new ConcordiumAppCommandError({\n message: \"User rejected\",\n errorCode: ConcordiumErrorCodes.USER_REJECTED,\n });\n sendCommandMock.mockResolvedValueOnce(CommandResultFactory({ error }));\n\n const result = await createTask().run();\n\n expect(isSuccessCommandResult(result)).toBe(false);\n expect(sendCommandMock).toHaveBeenCalledTimes(1);\n });\n\n it(\"should fail when GetChallenge fails\", async () => {\n const error = new ConcordiumAppCommandError({\n message: \"INS not supported\",\n errorCode: ConcordiumErrorCodes.INS_NOT_SUPPORTED,\n });\n sendCommandMock\n .mockResolvedValueOnce(\n CommandResultFactory({ data: { publicKey: PUBLIC_KEY } }),\n )\n .mockResolvedValueOnce(CommandResultFactory({ error }));\n\n const result = await createTask().run();\n\n expect(isSuccessCommandResult(result)).toBe(false);\n expect(sendCommandMock).toHaveBeenCalledTimes(2);\n });\n\n it(\"should fail with TrustedMetadataServiceError when context module returns error context\", async () => {\n mockSendCommandSequence(\n CommandResultFactory({ data: { publicKey: PUBLIC_KEY } }),\n CommandResultFactory({ data: { challenge: CHALLENGE } }),\n );\n vi.spyOn(contextModuleMock, \"getContexts\").mockResolvedValue(\n makeErrorContext(\"Backend unavailable\"),\n );\n\n const result = await createTask().run();\n\n expect(isSuccessCommandResult(result)).toBe(false);\n if (!isSuccessCommandResult(result)) {\n expect(result.error).toBeInstanceOf(TrustedMetadataServiceError);\n expect(result.error).toHaveProperty(\n \"errorCode\",\n ConcordiumErrorCodes.TRUSTED_METADATA_SERVICE_ERROR,\n );\n }\n });\n\n it(\"should fail when context module returns empty contexts\", async () => {\n mockSendCommandSequence(\n CommandResultFactory({ data: { publicKey: PUBLIC_KEY } }),\n CommandResultFactory({ data: { challenge: CHALLENGE } }),\n );\n vi.spyOn(contextModuleMock, \"getContexts\").mockResolvedValue([]);\n\n const result = await createTask().run();\n\n expect(isSuccessCommandResult(result)).toBe(false);\n if (!isSuccessCommandResult(result)) {\n expect(result.error).toBeInstanceOf(InvalidStatusWordError);\n }\n });\n\n it(\"should fail when context module throws\", async () => {\n mockSendCommandSequence(\n CommandResultFactory({ data: { publicKey: PUBLIC_KEY } }),\n CommandResultFactory({ data: { challenge: CHALLENGE } }),\n );\n vi.spyOn(contextModuleMock, \"getContexts\").mockRejectedValue(\n new Error(\"Network timeout\"),\n );\n\n const result = await createTask().run();\n\n expect(isSuccessCommandResult(result)).toBe(false);\n if (!isSuccessCommandResult(result)) {\n expect(result.error).toBeInstanceOf(InvalidStatusWordError);\n }\n });\n\n it(\"should fail when LoadCertificate fails\", async () => {\n mockSendCommandSequence(\n CommandResultFactory({ data: { publicKey: PUBLIC_KEY } }),\n CommandResultFactory({ data: { challenge: CHALLENGE } }),\n CommandResultFactory({\n error: new InvalidStatusWordError(\"cert error\"),\n }),\n );\n vi.spyOn(contextModuleMock, \"getContexts\").mockResolvedValue(\n makeSuccessContext(true),\n );\n\n const result = await createTask().run();\n\n expect(isSuccessCommandResult(result)).toBe(false);\n if (!isSuccessCommandResult(result)) {\n expect(result.error).toBeInstanceOf(InvalidStatusWordError);\n }\n expect(sendCommandMock).toHaveBeenCalledTimes(3);\n });\n\n it(\"should fail when descriptor payload is empty\", async () => {\n mockSendCommandSequence(\n CommandResultFactory({ data: { publicKey: PUBLIC_KEY } }),\n CommandResultFactory({ data: { challenge: CHALLENGE } }),\n CommandResultFactory({ data: undefined }), // LoadCertificate\n );\n vi.spyOn(contextModuleMock, \"getContexts\").mockResolvedValue([\n {\n type: ClearSignContextType.ACCOUNT_OWNERSHIP,\n payload: \"\",\n certificate: CERTIFICATE,\n },\n ]);\n\n const result = await createTask().run();\n\n expect(isSuccessCommandResult(result)).toBe(false);\n if (!isSuccessCommandResult(result)) {\n expect(result.error).toBeInstanceOf(InvalidStatusWordError);\n }\n });\n\n it(\"should fail when SetTrustedName fails\", async () => {\n const error = new ConcordiumAppCommandError({\n message: \"Data invalid\",\n errorCode: ConcordiumErrorCodes.DATA_INVALID,\n });\n mockSendCommandSequence(\n CommandResultFactory({ data: { publicKey: PUBLIC_KEY } }),\n CommandResultFactory({ data: { challenge: CHALLENGE } }),\n CommandResultFactory({ data: undefined }), // LoadCertificate\n CommandResultFactory({ error }),\n );\n vi.spyOn(contextModuleMock, \"getContexts\").mockResolvedValue(\n makeSuccessContext(true),\n );\n\n const result = await createTask().run();\n\n expect(isSuccessCommandResult(result)).toBe(false);\n expect(sendCommandMock).toHaveBeenCalledTimes(4);\n });\n\n it(\"should fail when VerifyAddress is rejected by user\", async () => {\n const error = new ConcordiumAppCommandError({\n message: \"User rejected\",\n errorCode: ConcordiumErrorCodes.USER_REJECTED,\n });\n mockSendCommandSequence(\n CommandResultFactory({ data: { publicKey: PUBLIC_KEY } }),\n CommandResultFactory({ data: { challenge: CHALLENGE } }),\n CommandResultFactory({ data: undefined }), // LoadCertificate\n CommandResultFactory({ data: undefined }), // SetTrustedName\n CommandResultFactory({ error }),\n );\n vi.spyOn(contextModuleMock, \"getContexts\").mockResolvedValue(\n makeSuccessContext(true),\n );\n\n const result = await createTask().run();\n\n expect(isSuccessCommandResult(result)).toBe(false);\n if (!isSuccessCommandResult(result)) {\n const err = result.error as ConcordiumAppCommandError;\n expect(err.errorCode).toBe(ConcordiumErrorCodes.USER_REJECTED);\n }\n expect(sendCommandMock).toHaveBeenCalledTimes(5);\n });\n\n it(\"should fail when VerifyAddress returns trusted name mismatch\", async () => {\n const error = new ConcordiumAppCommandError({\n message: \"Trusted name mismatch\",\n errorCode: ConcordiumErrorCodes.TRUSTED_NAME_MISMATCH,\n });\n mockSendCommandSequence(\n CommandResultFactory({ data: { publicKey: PUBLIC_KEY } }),\n CommandResultFactory({ data: { challenge: CHALLENGE } }),\n CommandResultFactory({ data: undefined }), // LoadCertificate\n CommandResultFactory({ data: undefined }), // SetTrustedName\n CommandResultFactory({ error }),\n );\n vi.spyOn(contextModuleMock, \"getContexts\").mockResolvedValue(\n makeSuccessContext(true),\n );\n\n const result = await createTask().run();\n\n expect(isSuccessCommandResult(result)).toBe(false);\n if (!isSuccessCommandResult(result)) {\n const err = result.error as ConcordiumAppCommandError;\n expect(err.errorCode).toBe(ConcordiumErrorCodes.TRUSTED_NAME_MISMATCH);\n }\n });\n });\n});\n"],
5
+ "mappings": "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",
6
+ "names": ["import_context_module", "import_device_management_kit", "import_vitest", "import_ConcordiumApplicationErrors", "import_TrustedMetadataServiceError", "import_VerifyAddressTask", "DERIVATION_PATH", "ADDRESS", "NETWORK", "PUBLIC_KEY", "CHALLENGE", "DESCRIPTOR_HEX", "CERTIFICATE", "makeSuccessContext", "withCertificate", "makeErrorContext", "message", "sendCommandMock", "apiMock", "loggerMock", "contextModuleMock", "createTask", "mockSendCommandSequence", "results", "callIndex", "result", "error", "err"]
7
7
  }
@@ -58,5 +58,5 @@
58
58
  "watch:builds": "pnpm ldmk-tool watch --entryPoints src/index.ts,src/**/*.ts --tsconfig tsconfig.prod.json",
59
59
  "watch:types": "concurrently \"tsc --watch -p tsconfig.prod.json\" \"tsc-alias --watch -p tsconfig.prod.json\""
60
60
  },
61
- "version": "0.0.0-develop-20260419002000"
61
+ "version": "0.0.0-develop-20260420165047"
62
62
  }
@@ -1,2 +1,2 @@
1
- import{DeviceExchangeError as t}from"@ledgerhq/device-management-kit";var a=(e=>(e.USER_REJECTED="6985",e.LOCKED_DEVICE="5515",e.DATA_INVALID="6a80",e.INS_NOT_SUPPORTED="6d00",e.CLA_NOT_SUPPORTED="6e00",e.UNKNOWN_ERROR="6f00",e.TRUSTED_NAME_MISMATCH="6b0c",e.UNSUPPORTED_TRANSACTION_TYPE="unsupported_transaction_type",e))(a||{});const m={6985:{message:"User rejected"},5515:{message:"Locked device"},"6a80":{message:"Data invalid"},"6d00":{message:"INS not supported"},"6e00":{message:"CLA not supported"},"6f00":{message:"Unknown error"},"6b0c":{message:"Trusted name mismatch"},unsupported_transaction_type:{message:"Unsupported transaction type"}};class o extends t{constructor(s){super({tag:"ConcordiumAppCommandError",...s})}}const p=r=>new o(r);export{m as CONCORDIUM_APP_ERRORS,o as ConcordiumAppCommandError,p as ConcordiumAppCommandErrorFactory,a as ConcordiumErrorCodes};
1
+ import{DeviceExchangeError as a}from"@ledgerhq/device-management-kit";var s=(e=>(e.USER_REJECTED="6985",e.LOCKED_DEVICE="5515",e.DATA_INVALID="6a80",e.INS_NOT_SUPPORTED="6d00",e.CLA_NOT_SUPPORTED="6e00",e.UNKNOWN_ERROR="6f00",e.TRUSTED_NAME_MISMATCH="6b0c",e.UNSUPPORTED_TRANSACTION_TYPE="unsupported_transaction_type",e.TRUSTED_METADATA_SERVICE_ERROR="trusted_metadata_service_error",e))(s||{});const n={6985:{message:"User rejected"},5515:{message:"Locked device"},"6a80":{message:"Data invalid"},"6d00":{message:"INS not supported"},"6e00":{message:"CLA not supported"},"6f00":{message:"Unknown error"},"6b0c":{message:"Trusted name mismatch"},unsupported_transaction_type:{message:"Unsupported transaction type"},trusted_metadata_service_error:{message:"Trusted metadata service error"}};class m extends a{constructor(t){super({tag:"ConcordiumAppCommandError",...t})}}const p=r=>new m(r);export{n as CONCORDIUM_APP_ERRORS,m as ConcordiumAppCommandError,p as ConcordiumAppCommandErrorFactory,s as ConcordiumErrorCodes};
2
2
  //# sourceMappingURL=ConcordiumApplicationErrors.js.map
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "version": 3,
3
3
  "sources": ["../../../../../../src/internal/app-binder/command/utils/ConcordiumApplicationErrors.ts"],
4
- "sourcesContent": ["import {\n type CommandErrorArgs,\n type CommandErrors,\n DeviceExchangeError,\n} from \"@ledgerhq/device-management-kit\";\n\nexport enum ConcordiumErrorCodes {\n USER_REJECTED = \"6985\",\n LOCKED_DEVICE = \"5515\",\n DATA_INVALID = \"6a80\",\n INS_NOT_SUPPORTED = \"6d00\",\n CLA_NOT_SUPPORTED = \"6e00\",\n UNKNOWN_ERROR = \"6f00\",\n TRUSTED_NAME_MISMATCH = \"6b0c\",\n UNSUPPORTED_TRANSACTION_TYPE = \"unsupported_transaction_type\",\n}\n\nexport const CONCORDIUM_APP_ERRORS: CommandErrors<ConcordiumErrorCodes> = {\n \"6985\": { message: \"User rejected\" },\n \"5515\": { message: \"Locked device\" },\n \"6a80\": { message: \"Data invalid\" },\n \"6d00\": { message: \"INS not supported\" },\n \"6e00\": { message: \"CLA not supported\" },\n \"6f00\": { message: \"Unknown error\" },\n \"6b0c\": { message: \"Trusted name mismatch\" },\n unsupported_transaction_type: { message: \"Unsupported transaction type\" },\n};\n\nexport class ConcordiumAppCommandError extends DeviceExchangeError<ConcordiumErrorCodes> {\n constructor(args: CommandErrorArgs<ConcordiumErrorCodes>) {\n super({ tag: \"ConcordiumAppCommandError\", ...args });\n }\n}\n\nexport const ConcordiumAppCommandErrorFactory = (\n args: CommandErrorArgs<ConcordiumErrorCodes>,\n) => new ConcordiumAppCommandError(args);\n"],
5
- "mappings": "AAAA,OAGE,uBAAAA,MACK,kCAEA,IAAKC,OACVA,EAAA,cAAgB,OAChBA,EAAA,cAAgB,OAChBA,EAAA,aAAe,OACfA,EAAA,kBAAoB,OACpBA,EAAA,kBAAoB,OACpBA,EAAA,cAAgB,OAChBA,EAAA,sBAAwB,OACxBA,EAAA,6BAA+B,+BARrBA,OAAA,IAWL,MAAMC,EAA6D,CACxE,KAAQ,CAAE,QAAS,eAAgB,EACnC,KAAQ,CAAE,QAAS,eAAgB,EACnC,OAAQ,CAAE,QAAS,cAAe,EAClC,OAAQ,CAAE,QAAS,mBAAoB,EACvC,OAAQ,CAAE,QAAS,mBAAoB,EACvC,OAAQ,CAAE,QAAS,eAAgB,EACnC,OAAQ,CAAE,QAAS,uBAAwB,EAC3C,6BAA8B,CAAE,QAAS,8BAA+B,CAC1E,EAEO,MAAMC,UAAkCH,CAA0C,CACvF,YAAYI,EAA8C,CACxD,MAAM,CAAE,IAAK,4BAA6B,GAAGA,CAAK,CAAC,CACrD,CACF,CAEO,MAAMC,EACXD,GACG,IAAID,EAA0BC,CAAI",
4
+ "sourcesContent": ["import {\n type CommandErrorArgs,\n type CommandErrors,\n DeviceExchangeError,\n} from \"@ledgerhq/device-management-kit\";\n\nexport enum ConcordiumErrorCodes {\n USER_REJECTED = \"6985\",\n LOCKED_DEVICE = \"5515\",\n DATA_INVALID = \"6a80\",\n INS_NOT_SUPPORTED = \"6d00\",\n CLA_NOT_SUPPORTED = \"6e00\",\n UNKNOWN_ERROR = \"6f00\",\n TRUSTED_NAME_MISMATCH = \"6b0c\",\n UNSUPPORTED_TRANSACTION_TYPE = \"unsupported_transaction_type\",\n TRUSTED_METADATA_SERVICE_ERROR = \"trusted_metadata_service_error\",\n}\n\nexport const CONCORDIUM_APP_ERRORS: CommandErrors<ConcordiumErrorCodes> = {\n \"6985\": { message: \"User rejected\" },\n \"5515\": { message: \"Locked device\" },\n \"6a80\": { message: \"Data invalid\" },\n \"6d00\": { message: \"INS not supported\" },\n \"6e00\": { message: \"CLA not supported\" },\n \"6f00\": { message: \"Unknown error\" },\n \"6b0c\": { message: \"Trusted name mismatch\" },\n unsupported_transaction_type: { message: \"Unsupported transaction type\" },\n trusted_metadata_service_error: {\n message: \"Trusted metadata service error\",\n },\n};\n\nexport class ConcordiumAppCommandError extends DeviceExchangeError<ConcordiumErrorCodes> {\n constructor(args: CommandErrorArgs<ConcordiumErrorCodes>) {\n super({ tag: \"ConcordiumAppCommandError\", ...args });\n }\n}\n\nexport const ConcordiumAppCommandErrorFactory = (\n args: CommandErrorArgs<ConcordiumErrorCodes>,\n) => new ConcordiumAppCommandError(args);\n"],
5
+ "mappings": "AAAA,OAGE,uBAAAA,MACK,kCAEA,IAAKC,OACVA,EAAA,cAAgB,OAChBA,EAAA,cAAgB,OAChBA,EAAA,aAAe,OACfA,EAAA,kBAAoB,OACpBA,EAAA,kBAAoB,OACpBA,EAAA,cAAgB,OAChBA,EAAA,sBAAwB,OACxBA,EAAA,6BAA+B,+BAC/BA,EAAA,+BAAiC,iCATvBA,OAAA,IAYL,MAAMC,EAA6D,CACxE,KAAQ,CAAE,QAAS,eAAgB,EACnC,KAAQ,CAAE,QAAS,eAAgB,EACnC,OAAQ,CAAE,QAAS,cAAe,EAClC,OAAQ,CAAE,QAAS,mBAAoB,EACvC,OAAQ,CAAE,QAAS,mBAAoB,EACvC,OAAQ,CAAE,QAAS,eAAgB,EACnC,OAAQ,CAAE,QAAS,uBAAwB,EAC3C,6BAA8B,CAAE,QAAS,8BAA+B,EACxE,+BAAgC,CAC9B,QAAS,gCACX,CACF,EAEO,MAAMC,UAAkCH,CAA0C,CACvF,YAAYI,EAA8C,CACxD,MAAM,CAAE,IAAK,4BAA6B,GAAGA,CAAK,CAAC,CACrD,CACF,CAEO,MAAMC,EACXD,GACG,IAAID,EAA0BC,CAAI",
6
6
  "names": ["DeviceExchangeError", "ConcordiumErrorCodes", "CONCORDIUM_APP_ERRORS", "ConcordiumAppCommandError", "args", "ConcordiumAppCommandErrorFactory"]
7
7
  }
@@ -0,0 +1,2 @@
1
+ import{DeviceExchangeError as e}from"@ledgerhq/device-management-kit";import{ConcordiumErrorCodes as o}from"../../../app-binder/command/utils/ConcordiumApplicationErrors";class d extends e{constructor(r){super({tag:"TrustedMetadataServiceError",message:r??"Trusted metadata service error",errorCode:o.TRUSTED_METADATA_SERVICE_ERROR})}}export{d as TrustedMetadataServiceError};
2
+ //# sourceMappingURL=TrustedMetadataServiceError.js.map
@@ -0,0 +1,7 @@
1
+ {
2
+ "version": 3,
3
+ "sources": ["../../../../../../src/internal/app-binder/command/utils/TrustedMetadataServiceError.ts"],
4
+ "sourcesContent": ["import { DeviceExchangeError } from \"@ledgerhq/device-management-kit\";\n\nimport { ConcordiumErrorCodes } from \"@internal/app-binder/command/utils/ConcordiumApplicationErrors\";\n\nexport class TrustedMetadataServiceError extends DeviceExchangeError<ConcordiumErrorCodes> {\n constructor(message?: string) {\n super({\n tag: \"TrustedMetadataServiceError\",\n message: message ?? \"Trusted metadata service error\",\n errorCode: ConcordiumErrorCodes.TRUSTED_METADATA_SERVICE_ERROR,\n });\n }\n}\n"],
5
+ "mappings": "AAAA,OAAS,uBAAAA,MAA2B,kCAEpC,OAAS,wBAAAC,MAA4B,iEAE9B,MAAMC,UAAoCF,CAA0C,CACzF,YAAYG,EAAkB,CAC5B,MAAM,CACJ,IAAK,8BACL,QAASA,GAAW,iCACpB,UAAWF,EAAqB,8BAClC,CAAC,CACH,CACF",
6
+ "names": ["DeviceExchangeError", "ConcordiumErrorCodes", "TrustedMetadataServiceError", "message"]
7
+ }
@@ -1,2 +1,2 @@
1
- import{ClearSignContextType as p}from"@ledgerhq/context-module";import{bufferToHexaString as b,CommandResultFactory as r,hexaStringToBuffer as S,InvalidStatusWordError as m,isSuccessCommandResult as o,LoadCertificateCommand as A}from"@ledgerhq/device-management-kit";import{GetChallengeCommand as R}from"../../app-binder/command/GetChallengeCommand";import{GetPublicKeyCommand as v}from"../../app-binder/command/GetPublicKeyCommand";import{SetTrustedNameCommand as k}from"../../app-binder/command/SetTrustedNameCommand";import{VerifyAddressCommand as N}from"../../app-binder/command/VerifyAddressCommand";class K{constructor(i,s,d){this.api=i;this.args=s;this.logger=d}async run(){const{derivationPath:i,address:s,network:d,contextModule:f}=this.args;this.logger.debug("[run] Getting public key");const n=await this.api.sendCommand(new v({derivationPath:i,checkOnDevice:!1,skipOpenApp:!0}));if(!o(n))return this.logger.error("[run] Failed to get public key",{data:{error:n.error}}),r({error:n.error});const y=b(n.data.publicKey,!1);this.logger.debug("[run] Getting challenge");const a=await this.api.sendCommand(new R);if(!o(a))return this.logger.error("[run] Failed to get challenge",{data:{error:a.error}}),r({error:a.error});const h=a.data.challenge;this.logger.debug("[run] Fetching account ownership context",{data:{publicKey:y,address:s,network:d}});const C=this.api.getDeviceModel().id;let c;try{c=await f.getContexts({publicKey:y,address:s,challenge:h,network:d,deviceModelId:C},[p.ACCOUNT_OWNERSHIP])}catch(e){return this.logger.error("[run] Context module error",{data:{error:e}}),r({error:new m(`Failed to fetch account ownership context: ${e instanceof Error?e.message:"unknown error"}`)})}const t=c.find(e=>e.type===p.ACCOUNT_OWNERSHIP);if(!t){const e=c.find(x=>x.type===p.ERROR),w=e&&"error"in e?e.error.message:"No account ownership context returned";return r({error:new m(w)})}if(t.certificate){this.logger.debug("[run] Loading PKI certificate");const e=await this.api.sendCommand(new A({keyUsage:t.certificate.keyUsageNumber,certificate:t.certificate.payload}));if(!o(e))return this.logger.error("[run] Failed to load certificate",{data:{error:e.error}}),r({error:e.error})}this.logger.debug("[run] Setting trusted name descriptor");const l=S(t.payload);if(!l||l.length===0)return r({error:new m("Invalid descriptor payload")});const u=await this.api.sendCommand(new k({payload:l}));if(!o(u))return this.logger.error("[run] Failed to set trusted name",{data:{error:u.error}}),r({error:u.error});this.logger.debug("[run] Sending verify address command");const g=await this.api.sendCommand(new N({derivationPath:i}));return o(g)?r({data:!0}):(this.logger.error("[run] Failed to verify address",{data:{error:g.error}}),r({error:g.error}))}}export{K as VerifyAddressTask};
1
+ import{ClearSignContextType as p}from"@ledgerhq/context-module";import{bufferToHexaString as x,CommandResultFactory as r,hexaStringToBuffer as S,InvalidStatusWordError as m,isSuccessCommandResult as o,LoadCertificateCommand as b}from"@ledgerhq/device-management-kit";import{GetChallengeCommand as A}from"../../app-binder/command/GetChallengeCommand";import{GetPublicKeyCommand as v}from"../../app-binder/command/GetPublicKeyCommand";import{SetTrustedNameCommand as R}from"../../app-binder/command/SetTrustedNameCommand";import{TrustedMetadataServiceError as k}from"../../app-binder/command/utils/TrustedMetadataServiceError";import{VerifyAddressCommand as T}from"../../app-binder/command/VerifyAddressCommand";class V{constructor(i,s,d){this.api=i;this.args=s;this.logger=d}async run(){const{derivationPath:i,address:s,network:d,contextModule:f}=this.args;this.logger.debug("[run] Getting public key");const n=await this.api.sendCommand(new v({derivationPath:i,checkOnDevice:!1,skipOpenApp:!0}));if(!o(n))return this.logger.error("[run] Failed to get public key",{data:{error:n.error}}),r({error:n.error});const y=x(n.data.publicKey,!1);this.logger.debug("[run] Getting challenge");const a=await this.api.sendCommand(new A);if(!o(a))return this.logger.error("[run] Failed to get challenge",{data:{error:a.error}}),r({error:a.error});const h=a.data.challenge;this.logger.debug("[run] Fetching account ownership context",{data:{publicKey:y,address:s,network:d}});const C=this.api.getDeviceModel().id;let c;try{c=await f.getContexts({publicKey:y,address:s,challenge:h,network:d,deviceModelId:C},[p.ACCOUNT_OWNERSHIP])}catch(e){return this.logger.error("[run] Context module error",{data:{error:e}}),r({error:new m(`Failed to fetch account ownership context: ${e instanceof Error?e.message:"unknown error"}`)})}const t=c.find(e=>e.type===p.ACCOUNT_OWNERSHIP);if(!t){const e=c.find(w=>w.type===p.ERROR);return e&&"error"in e?r({error:new k(e.error.message)}):r({error:new m("No account ownership context returned")})}if(t.certificate){this.logger.debug("[run] Loading PKI certificate");const e=await this.api.sendCommand(new b({keyUsage:t.certificate.keyUsageNumber,certificate:t.certificate.payload}));if(!o(e))return this.logger.error("[run] Failed to load certificate",{data:{error:e.error}}),r({error:e.error})}this.logger.debug("[run] Setting trusted name descriptor");const l=S(t.payload);if(!l||l.length===0)return r({error:new m("Invalid descriptor payload")});const u=await this.api.sendCommand(new R({payload:l}));if(!o(u))return this.logger.error("[run] Failed to set trusted name",{data:{error:u.error}}),r({error:u.error});this.logger.debug("[run] Sending verify address command");const g=await this.api.sendCommand(new T({derivationPath:i}));return o(g)?r({data:!0}):(this.logger.error("[run] Failed to verify address",{data:{error:g.error}}),r({error:g.error}))}}export{V as VerifyAddressTask};
2
2
  //# sourceMappingURL=VerifyAddressTask.js.map
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "version": 3,
3
3
  "sources": ["../../../../../src/internal/app-binder/task/VerifyAddressTask.ts"],
4
- "sourcesContent": ["import {\n type AccountOwnershipNetwork,\n type ClearSignContextSuccess,\n ClearSignContextType,\n type ContextModule,\n} from \"@ledgerhq/context-module\";\nimport {\n bufferToHexaString,\n type CommandResult,\n CommandResultFactory,\n hexaStringToBuffer,\n type InternalApi,\n InvalidStatusWordError,\n isSuccessCommandResult,\n LoadCertificateCommand,\n type LoggerPublisherService,\n} from \"@ledgerhq/device-management-kit\";\n\nimport { type VerifyAddressErrorCodes } from \"@api/app-binder/VerifyAddressDeviceActionTypes\";\nimport { GetChallengeCommand } from \"@internal/app-binder/command/GetChallengeCommand\";\nimport { GetPublicKeyCommand } from \"@internal/app-binder/command/GetPublicKeyCommand\";\nimport { SetTrustedNameCommand } from \"@internal/app-binder/command/SetTrustedNameCommand\";\nimport { VerifyAddressCommand } from \"@internal/app-binder/command/VerifyAddressCommand\";\n\nexport type VerifyAddressTaskArgs = {\n readonly derivationPath: string;\n readonly address: string;\n readonly network: AccountOwnershipNetwork;\n readonly contextModule: ContextModule;\n};\n\nexport class VerifyAddressTask {\n constructor(\n private readonly api: InternalApi,\n private readonly args: VerifyAddressTaskArgs,\n private readonly logger: LoggerPublisherService,\n ) {}\n\n async run(): Promise<CommandResult<true, VerifyAddressErrorCodes>> {\n const { derivationPath, address, network, contextModule } = this.args;\n\n // Step 1: Get public key (without device confirmation)\n this.logger.debug(\"[run] Getting public key\");\n const pubKeyResult = await this.api.sendCommand(\n new GetPublicKeyCommand({\n derivationPath,\n checkOnDevice: false,\n skipOpenApp: true,\n }),\n );\n\n if (!isSuccessCommandResult(pubKeyResult)) {\n this.logger.error(\"[run] Failed to get public key\", {\n data: { error: pubKeyResult.error },\n });\n return CommandResultFactory({ error: pubKeyResult.error });\n }\n\n const publicKeyHex = bufferToHexaString(pubKeyResult.data.publicKey, false);\n\n // Step 2: Get challenge from device\n this.logger.debug(\"[run] Getting challenge\");\n const challengeResult = await this.api.sendCommand(\n new GetChallengeCommand(),\n );\n\n if (!isSuccessCommandResult(challengeResult)) {\n this.logger.error(\"[run] Failed to get challenge\", {\n data: { error: challengeResult.error },\n });\n return CommandResultFactory({ error: challengeResult.error });\n }\n\n const challenge = challengeResult.data.challenge;\n\n // Step 3: Fetch account ownership context from trusted metadata service\n this.logger.debug(\"[run] Fetching account ownership context\", {\n data: { publicKey: publicKeyHex, address, network },\n });\n\n const deviceModelId = this.api.getDeviceModel().id;\n let contexts: Awaited<ReturnType<ContextModule[\"getContexts\"]>>;\n try {\n contexts = await contextModule.getContexts(\n {\n publicKey: publicKeyHex,\n address,\n challenge,\n network,\n deviceModelId,\n },\n [ClearSignContextType.ACCOUNT_OWNERSHIP],\n );\n } catch (error) {\n this.logger.error(\"[run] Context module error\", { data: { error } });\n return CommandResultFactory({\n error: new InvalidStatusWordError(\n `Failed to fetch account ownership context: ${error instanceof Error ? error.message : \"unknown error\"}`,\n ),\n });\n }\n\n const ownershipContext = contexts.find(\n (\n c,\n ): c is ClearSignContextSuccess<ClearSignContextType.ACCOUNT_OWNERSHIP> =>\n c.type === ClearSignContextType.ACCOUNT_OWNERSHIP,\n );\n\n if (!ownershipContext) {\n const errorCtx = contexts.find(\n (c) => c.type === ClearSignContextType.ERROR,\n );\n const errorMessage =\n errorCtx && \"error\" in errorCtx\n ? errorCtx.error.message\n : \"No account ownership context returned\";\n return CommandResultFactory({\n error: new InvalidStatusWordError(errorMessage),\n });\n }\n\n // Step 4: Load PKI certificate on device\n if (ownershipContext.certificate) {\n this.logger.debug(\"[run] Loading PKI certificate\");\n const certResult = await this.api.sendCommand(\n new LoadCertificateCommand({\n keyUsage: ownershipContext.certificate.keyUsageNumber,\n certificate: ownershipContext.certificate.payload,\n }),\n );\n\n if (!isSuccessCommandResult(certResult)) {\n this.logger.error(\"[run] Failed to load certificate\", {\n data: { error: certResult.error },\n });\n return CommandResultFactory({ error: certResult.error });\n }\n }\n\n // Step 5: Set trusted name descriptor on device\n this.logger.debug(\"[run] Setting trusted name descriptor\");\n const descriptorBytes = hexaStringToBuffer(ownershipContext.payload);\n\n if (!descriptorBytes || descriptorBytes.length === 0) {\n return CommandResultFactory({\n error: new InvalidStatusWordError(\"Invalid descriptor payload\"),\n });\n }\n\n const trustedNameResult = await this.api.sendCommand(\n new SetTrustedNameCommand({ payload: descriptorBytes }),\n );\n\n if (!isSuccessCommandResult(trustedNameResult)) {\n this.logger.error(\"[run] Failed to set trusted name\", {\n data: { error: trustedNameResult.error },\n });\n return CommandResultFactory({ error: trustedNameResult.error });\n }\n\n // Step 6: Verify address on device (user approval)\n this.logger.debug(\"[run] Sending verify address command\");\n const verifyResult = await this.api.sendCommand(\n new VerifyAddressCommand({ derivationPath }),\n );\n\n if (!isSuccessCommandResult(verifyResult)) {\n this.logger.error(\"[run] Failed to verify address\", {\n data: { error: verifyResult.error },\n });\n return CommandResultFactory({ error: verifyResult.error });\n }\n\n return CommandResultFactory({ data: true as const });\n }\n}\n"],
5
- "mappings": "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",
6
- "names": ["ClearSignContextType", "bufferToHexaString", "CommandResultFactory", "hexaStringToBuffer", "InvalidStatusWordError", "isSuccessCommandResult", "LoadCertificateCommand", "GetChallengeCommand", "GetPublicKeyCommand", "SetTrustedNameCommand", "VerifyAddressCommand", "VerifyAddressTask", "api", "args", "logger", "derivationPath", "address", "network", "contextModule", "pubKeyResult", "publicKeyHex", "challengeResult", "challenge", "deviceModelId", "contexts", "error", "ownershipContext", "c", "errorCtx", "errorMessage", "certResult", "descriptorBytes", "trustedNameResult", "verifyResult"]
4
+ "sourcesContent": ["import {\n type AccountOwnershipNetwork,\n type ClearSignContextSuccess,\n ClearSignContextType,\n type ContextModule,\n} from \"@ledgerhq/context-module\";\nimport {\n bufferToHexaString,\n type CommandResult,\n CommandResultFactory,\n hexaStringToBuffer,\n type InternalApi,\n InvalidStatusWordError,\n isSuccessCommandResult,\n LoadCertificateCommand,\n type LoggerPublisherService,\n} from \"@ledgerhq/device-management-kit\";\n\nimport { type VerifyAddressErrorCodes } from \"@api/app-binder/VerifyAddressDeviceActionTypes\";\nimport { GetChallengeCommand } from \"@internal/app-binder/command/GetChallengeCommand\";\nimport { GetPublicKeyCommand } from \"@internal/app-binder/command/GetPublicKeyCommand\";\nimport { SetTrustedNameCommand } from \"@internal/app-binder/command/SetTrustedNameCommand\";\nimport { TrustedMetadataServiceError } from \"@internal/app-binder/command/utils/TrustedMetadataServiceError\";\nimport { VerifyAddressCommand } from \"@internal/app-binder/command/VerifyAddressCommand\";\n\nexport type VerifyAddressTaskArgs = {\n readonly derivationPath: string;\n readonly address: string;\n readonly network: AccountOwnershipNetwork;\n readonly contextModule: ContextModule;\n};\n\nexport class VerifyAddressTask {\n constructor(\n private readonly api: InternalApi,\n private readonly args: VerifyAddressTaskArgs,\n private readonly logger: LoggerPublisherService,\n ) {}\n\n async run(): Promise<CommandResult<true, VerifyAddressErrorCodes>> {\n const { derivationPath, address, network, contextModule } = this.args;\n\n // Step 1: Get public key (without device confirmation)\n this.logger.debug(\"[run] Getting public key\");\n const pubKeyResult = await this.api.sendCommand(\n new GetPublicKeyCommand({\n derivationPath,\n checkOnDevice: false,\n skipOpenApp: true,\n }),\n );\n\n if (!isSuccessCommandResult(pubKeyResult)) {\n this.logger.error(\"[run] Failed to get public key\", {\n data: { error: pubKeyResult.error },\n });\n return CommandResultFactory({ error: pubKeyResult.error });\n }\n\n const publicKeyHex = bufferToHexaString(pubKeyResult.data.publicKey, false);\n\n // Step 2: Get challenge from device\n this.logger.debug(\"[run] Getting challenge\");\n const challengeResult = await this.api.sendCommand(\n new GetChallengeCommand(),\n );\n\n if (!isSuccessCommandResult(challengeResult)) {\n this.logger.error(\"[run] Failed to get challenge\", {\n data: { error: challengeResult.error },\n });\n return CommandResultFactory({ error: challengeResult.error });\n }\n\n const challenge = challengeResult.data.challenge;\n\n // Step 3: Fetch account ownership context from trusted metadata service\n this.logger.debug(\"[run] Fetching account ownership context\", {\n data: { publicKey: publicKeyHex, address, network },\n });\n\n const deviceModelId = this.api.getDeviceModel().id;\n let contexts: Awaited<ReturnType<ContextModule[\"getContexts\"]>>;\n try {\n contexts = await contextModule.getContexts(\n {\n publicKey: publicKeyHex,\n address,\n challenge,\n network,\n deviceModelId,\n },\n [ClearSignContextType.ACCOUNT_OWNERSHIP],\n );\n } catch (error) {\n this.logger.error(\"[run] Context module error\", { data: { error } });\n return CommandResultFactory({\n error: new InvalidStatusWordError(\n `Failed to fetch account ownership context: ${error instanceof Error ? error.message : \"unknown error\"}`,\n ),\n });\n }\n\n const ownershipContext = contexts.find(\n (\n c,\n ): c is ClearSignContextSuccess<ClearSignContextType.ACCOUNT_OWNERSHIP> =>\n c.type === ClearSignContextType.ACCOUNT_OWNERSHIP,\n );\n\n if (!ownershipContext) {\n const errorCtx = contexts.find(\n (c) => c.type === ClearSignContextType.ERROR,\n );\n if (errorCtx && \"error\" in errorCtx) {\n return CommandResultFactory({\n error: new TrustedMetadataServiceError(errorCtx.error.message),\n });\n }\n return CommandResultFactory({\n error: new InvalidStatusWordError(\n \"No account ownership context returned\",\n ),\n });\n }\n\n // Step 4: Load PKI certificate on device\n if (ownershipContext.certificate) {\n this.logger.debug(\"[run] Loading PKI certificate\");\n const certResult = await this.api.sendCommand(\n new LoadCertificateCommand({\n keyUsage: ownershipContext.certificate.keyUsageNumber,\n certificate: ownershipContext.certificate.payload,\n }),\n );\n\n if (!isSuccessCommandResult(certResult)) {\n this.logger.error(\"[run] Failed to load certificate\", {\n data: { error: certResult.error },\n });\n return CommandResultFactory({ error: certResult.error });\n }\n }\n\n // Step 5: Set trusted name descriptor on device\n this.logger.debug(\"[run] Setting trusted name descriptor\");\n const descriptorBytes = hexaStringToBuffer(ownershipContext.payload);\n\n if (!descriptorBytes || descriptorBytes.length === 0) {\n return CommandResultFactory({\n error: new InvalidStatusWordError(\"Invalid descriptor payload\"),\n });\n }\n\n const trustedNameResult = await this.api.sendCommand(\n new SetTrustedNameCommand({ payload: descriptorBytes }),\n );\n\n if (!isSuccessCommandResult(trustedNameResult)) {\n this.logger.error(\"[run] Failed to set trusted name\", {\n data: { error: trustedNameResult.error },\n });\n return CommandResultFactory({ error: trustedNameResult.error });\n }\n\n // Step 6: Verify address on device (user approval)\n this.logger.debug(\"[run] Sending verify address command\");\n const verifyResult = await this.api.sendCommand(\n new VerifyAddressCommand({ derivationPath }),\n );\n\n if (!isSuccessCommandResult(verifyResult)) {\n this.logger.error(\"[run] Failed to verify address\", {\n data: { error: verifyResult.error },\n });\n return CommandResultFactory({ error: verifyResult.error });\n }\n\n return CommandResultFactory({ data: true as const });\n }\n}\n"],
5
+ "mappings": "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",
6
+ "names": ["ClearSignContextType", "bufferToHexaString", "CommandResultFactory", "hexaStringToBuffer", "InvalidStatusWordError", "isSuccessCommandResult", "LoadCertificateCommand", "GetChallengeCommand", "GetPublicKeyCommand", "SetTrustedNameCommand", "TrustedMetadataServiceError", "VerifyAddressCommand", "VerifyAddressTask", "api", "args", "logger", "derivationPath", "address", "network", "contextModule", "pubKeyResult", "publicKeyHex", "challengeResult", "challenge", "deviceModelId", "contexts", "error", "ownershipContext", "c", "errorCtx", "certResult", "descriptorBytes", "trustedNameResult", "verifyResult"]
7
7
  }
@@ -1,2 +1,2 @@
1
- import{ClearSignContextType as C}from"@ledgerhq/context-module";import{CommandResultFactory as e,DeviceModelId as g,InvalidStatusWordError as p,isSuccessCommandResult as a}from"@ledgerhq/device-management-kit";import{vi as r}from"vitest";import{ConcordiumAppCommandError as m,ConcordiumErrorCodes as u}from"../../app-binder/command/utils/ConcordiumApplicationErrors";import{VerifyAddressTask as k}from"../../app-binder/task/VerifyAddressTask";const T="44'/919'/0'/0'/0'",w="3kFkntk2H5FGMzeR3GjQKPhdZK9LShKdPHsj2fiGKCdmDXj2WB",E="mainnet",l=new Uint8Array(32).fill(171),d="aabbccdd11223344",v="0102030405",R={keyUsageNumber:4,payload:new Uint8Array([16,32,48])};function f(n=!0){return[{type:C.ACCOUNT_OWNERSHIP,payload:v,certificate:n?R:void 0}]}function O(n){return[{type:C.ERROR,error:new Error(n)}]}describe("VerifyAddressTask",()=>{let n,y,h,s;beforeEach(()=>{n=r.fn(),y={sendCommand:n,getDeviceModel:()=>({id:g.NANO_SP})},h={debug:r.fn(),error:r.fn()},s={getContexts:r.fn()}});function c(){return new k(y,{derivationPath:T,address:w,network:E,contextModule:s},h)}function i(...t){let o=0;n.mockImplementation(()=>Promise.resolve(t[o++]))}describe("success path",()=>{it("should complete the full flow with certificate",async()=>{i(e({data:{publicKey:l}}),e({data:{challenge:d}}),e({data:void 0}),e({data:void 0}),e({data:void 0})),r.spyOn(s,"getContexts").mockResolvedValue(f(!0));const t=await c().run();expect(a(t)).toBe(!0),a(t)&&expect(t.data).toBe(!0),expect(n).toHaveBeenCalledTimes(5),expect(s.getContexts).toHaveBeenCalledWith(expect.objectContaining({publicKey:"ab".repeat(32),address:w,challenge:d,network:E,deviceModelId:g.NANO_SP}),[C.ACCOUNT_OWNERSHIP])}),it("should skip LoadCertificate when context has no certificate",async()=>{i(e({data:{publicKey:l}}),e({data:{challenge:d}}),e({data:void 0}),e({data:void 0})),r.spyOn(s,"getContexts").mockResolvedValue(f(!1));const t=await c().run();expect(a(t)).toBe(!0),expect(n).toHaveBeenCalledTimes(4)})}),describe("failure cases",()=>{it("should fail when GetPublicKey fails",async()=>{const t=new m({message:"User rejected",errorCode:u.USER_REJECTED});n.mockResolvedValueOnce(e({error:t}));const o=await c().run();expect(a(o)).toBe(!1),expect(n).toHaveBeenCalledTimes(1)}),it("should fail when GetChallenge fails",async()=>{const t=new m({message:"INS not supported",errorCode:u.INS_NOT_SUPPORTED});n.mockResolvedValueOnce(e({data:{publicKey:l}})).mockResolvedValueOnce(e({error:t}));const o=await c().run();expect(a(o)).toBe(!1),expect(n).toHaveBeenCalledTimes(2)}),it("should fail when context module returns error context",async()=>{i(e({data:{publicKey:l}}),e({data:{challenge:d}})),r.spyOn(s,"getContexts").mockResolvedValue(O("Backend unavailable"));const t=await c().run();expect(a(t)).toBe(!1),a(t)||expect(t.error).toBeInstanceOf(p)}),it("should fail when context module returns empty contexts",async()=>{i(e({data:{publicKey:l}}),e({data:{challenge:d}})),r.spyOn(s,"getContexts").mockResolvedValue([]);const t=await c().run();expect(a(t)).toBe(!1),a(t)||expect(t.error).toBeInstanceOf(p)}),it("should fail when context module throws",async()=>{i(e({data:{publicKey:l}}),e({data:{challenge:d}})),r.spyOn(s,"getContexts").mockRejectedValue(new Error("Network timeout"));const t=await c().run();expect(a(t)).toBe(!1),a(t)||expect(t.error).toBeInstanceOf(p)}),it("should fail when LoadCertificate fails",async()=>{i(e({data:{publicKey:l}}),e({data:{challenge:d}}),e({error:new p("cert error")})),r.spyOn(s,"getContexts").mockResolvedValue(f(!0));const t=await c().run();expect(a(t)).toBe(!1),a(t)||expect(t.error).toBeInstanceOf(p),expect(n).toHaveBeenCalledTimes(3)}),it("should fail when descriptor payload is empty",async()=>{i(e({data:{publicKey:l}}),e({data:{challenge:d}}),e({data:void 0})),r.spyOn(s,"getContexts").mockResolvedValue([{type:C.ACCOUNT_OWNERSHIP,payload:"",certificate:R}]);const t=await c().run();expect(a(t)).toBe(!1),a(t)||expect(t.error).toBeInstanceOf(p)}),it("should fail when SetTrustedName fails",async()=>{const t=new m({message:"Data invalid",errorCode:u.DATA_INVALID});i(e({data:{publicKey:l}}),e({data:{challenge:d}}),e({data:void 0}),e({error:t})),r.spyOn(s,"getContexts").mockResolvedValue(f(!0));const o=await c().run();expect(a(o)).toBe(!1),expect(n).toHaveBeenCalledTimes(4)}),it("should fail when VerifyAddress is rejected by user",async()=>{const t=new m({message:"User rejected",errorCode:u.USER_REJECTED});i(e({data:{publicKey:l}}),e({data:{challenge:d}}),e({data:void 0}),e({data:void 0}),e({error:t})),r.spyOn(s,"getContexts").mockResolvedValue(f(!0));const o=await c().run();if(expect(a(o)).toBe(!1),!a(o)){const x=o.error;expect(x.errorCode).toBe(u.USER_REJECTED)}expect(n).toHaveBeenCalledTimes(5)}),it("should fail when VerifyAddress returns trusted name mismatch",async()=>{const t=new m({message:"Trusted name mismatch",errorCode:u.TRUSTED_NAME_MISMATCH});i(e({data:{publicKey:l}}),e({data:{challenge:d}}),e({data:void 0}),e({data:void 0}),e({error:t})),r.spyOn(s,"getContexts").mockResolvedValue(f(!0));const o=await c().run();if(expect(a(o)).toBe(!1),!a(o)){const x=o.error;expect(x.errorCode).toBe(u.TRUSTED_NAME_MISMATCH)}})})});
1
+ import{ClearSignContextType as C}from"@ledgerhq/context-module";import{CommandResultFactory as t,DeviceModelId as E,InvalidStatusWordError as f,isSuccessCommandResult as a}from"@ledgerhq/device-management-kit";import{vi as n}from"vitest";import{ConcordiumAppCommandError as m,ConcordiumErrorCodes as u}from"../../app-binder/command/utils/ConcordiumApplicationErrors";import{TrustedMetadataServiceError as T}from"../../app-binder/command/utils/TrustedMetadataServiceError";import{VerifyAddressTask as k}from"../../app-binder/task/VerifyAddressTask";const v="44'/919'/0'/0'/0'",g="3kFkntk2H5FGMzeR3GjQKPhdZK9LShKdPHsj2fiGKCdmDXj2WB",R="mainnet",l=new Uint8Array(32).fill(171),d="aabbccdd11223344",S="0102030405",w={keyUsageNumber:4,payload:new Uint8Array([16,32,48])};function p(o=!0){return[{type:C.ACCOUNT_OWNERSHIP,payload:S,certificate:o?w:void 0}]}function O(o){return[{type:C.ERROR,error:new Error(o)}]}describe("VerifyAddressTask",()=>{let o,y,h,s;beforeEach(()=>{o=n.fn(),y={sendCommand:o,getDeviceModel:()=>({id:E.NANO_SP})},h={debug:n.fn(),error:n.fn()},s={getContexts:n.fn()}});function c(){return new k(y,{derivationPath:v,address:g,network:R,contextModule:s},h)}function i(...e){let r=0;o.mockImplementation(()=>Promise.resolve(e[r++]))}describe("success path",()=>{it("should complete the full flow with certificate",async()=>{i(t({data:{publicKey:l}}),t({data:{challenge:d}}),t({data:void 0}),t({data:void 0}),t({data:void 0})),n.spyOn(s,"getContexts").mockResolvedValue(p(!0));const e=await c().run();expect(a(e)).toBe(!0),a(e)&&expect(e.data).toBe(!0),expect(o).toHaveBeenCalledTimes(5),expect(s.getContexts).toHaveBeenCalledWith(expect.objectContaining({publicKey:"ab".repeat(32),address:g,challenge:d,network:R,deviceModelId:E.NANO_SP}),[C.ACCOUNT_OWNERSHIP])}),it("should skip LoadCertificate when context has no certificate",async()=>{i(t({data:{publicKey:l}}),t({data:{challenge:d}}),t({data:void 0}),t({data:void 0})),n.spyOn(s,"getContexts").mockResolvedValue(p(!1));const e=await c().run();expect(a(e)).toBe(!0),expect(o).toHaveBeenCalledTimes(4)})}),describe("failure cases",()=>{it("should fail when GetPublicKey fails",async()=>{const e=new m({message:"User rejected",errorCode:u.USER_REJECTED});o.mockResolvedValueOnce(t({error:e}));const r=await c().run();expect(a(r)).toBe(!1),expect(o).toHaveBeenCalledTimes(1)}),it("should fail when GetChallenge fails",async()=>{const e=new m({message:"INS not supported",errorCode:u.INS_NOT_SUPPORTED});o.mockResolvedValueOnce(t({data:{publicKey:l}})).mockResolvedValueOnce(t({error:e}));const r=await c().run();expect(a(r)).toBe(!1),expect(o).toHaveBeenCalledTimes(2)}),it("should fail with TrustedMetadataServiceError when context module returns error context",async()=>{i(t({data:{publicKey:l}}),t({data:{challenge:d}})),n.spyOn(s,"getContexts").mockResolvedValue(O("Backend unavailable"));const e=await c().run();expect(a(e)).toBe(!1),a(e)||(expect(e.error).toBeInstanceOf(T),expect(e.error).toHaveProperty("errorCode",u.TRUSTED_METADATA_SERVICE_ERROR))}),it("should fail when context module returns empty contexts",async()=>{i(t({data:{publicKey:l}}),t({data:{challenge:d}})),n.spyOn(s,"getContexts").mockResolvedValue([]);const e=await c().run();expect(a(e)).toBe(!1),a(e)||expect(e.error).toBeInstanceOf(f)}),it("should fail when context module throws",async()=>{i(t({data:{publicKey:l}}),t({data:{challenge:d}})),n.spyOn(s,"getContexts").mockRejectedValue(new Error("Network timeout"));const e=await c().run();expect(a(e)).toBe(!1),a(e)||expect(e.error).toBeInstanceOf(f)}),it("should fail when LoadCertificate fails",async()=>{i(t({data:{publicKey:l}}),t({data:{challenge:d}}),t({error:new f("cert error")})),n.spyOn(s,"getContexts").mockResolvedValue(p(!0));const e=await c().run();expect(a(e)).toBe(!1),a(e)||expect(e.error).toBeInstanceOf(f),expect(o).toHaveBeenCalledTimes(3)}),it("should fail when descriptor payload is empty",async()=>{i(t({data:{publicKey:l}}),t({data:{challenge:d}}),t({data:void 0})),n.spyOn(s,"getContexts").mockResolvedValue([{type:C.ACCOUNT_OWNERSHIP,payload:"",certificate:w}]);const e=await c().run();expect(a(e)).toBe(!1),a(e)||expect(e.error).toBeInstanceOf(f)}),it("should fail when SetTrustedName fails",async()=>{const e=new m({message:"Data invalid",errorCode:u.DATA_INVALID});i(t({data:{publicKey:l}}),t({data:{challenge:d}}),t({data:void 0}),t({error:e})),n.spyOn(s,"getContexts").mockResolvedValue(p(!0));const r=await c().run();expect(a(r)).toBe(!1),expect(o).toHaveBeenCalledTimes(4)}),it("should fail when VerifyAddress is rejected by user",async()=>{const e=new m({message:"User rejected",errorCode:u.USER_REJECTED});i(t({data:{publicKey:l}}),t({data:{challenge:d}}),t({data:void 0}),t({data:void 0}),t({error:e})),n.spyOn(s,"getContexts").mockResolvedValue(p(!0));const r=await c().run();if(expect(a(r)).toBe(!1),!a(r)){const x=r.error;expect(x.errorCode).toBe(u.USER_REJECTED)}expect(o).toHaveBeenCalledTimes(5)}),it("should fail when VerifyAddress returns trusted name mismatch",async()=>{const e=new m({message:"Trusted name mismatch",errorCode:u.TRUSTED_NAME_MISMATCH});i(t({data:{publicKey:l}}),t({data:{challenge:d}}),t({data:void 0}),t({data:void 0}),t({error:e})),n.spyOn(s,"getContexts").mockResolvedValue(p(!0));const r=await c().run();if(expect(a(r)).toBe(!1),!a(r)){const x=r.error;expect(x.errorCode).toBe(u.TRUSTED_NAME_MISMATCH)}})})});
2
2
  //# sourceMappingURL=VerifyAddressTask.test.js.map
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "version": 3,
3
3
  "sources": ["../../../../../src/internal/app-binder/task/VerifyAddressTask.test.ts"],
4
- "sourcesContent": ["import {\n type ClearSignContext,\n ClearSignContextType,\n type ContextModule,\n} from \"@ledgerhq/context-module\";\nimport {\n CommandResultFactory,\n DeviceModelId,\n type InternalApi,\n InvalidStatusWordError,\n isSuccessCommandResult,\n type LoggerPublisherService,\n} from \"@ledgerhq/device-management-kit\";\nimport { vi } from \"vitest\";\n\nimport {\n ConcordiumAppCommandError,\n ConcordiumErrorCodes,\n} from \"@internal/app-binder/command/utils/ConcordiumApplicationErrors\";\nimport { VerifyAddressTask } from \"@internal/app-binder/task/VerifyAddressTask\";\n\nconst DERIVATION_PATH = \"44'/919'/0'/0'/0'\";\nconst ADDRESS = \"3kFkntk2H5FGMzeR3GjQKPhdZK9LShKdPHsj2fiGKCdmDXj2WB\";\nconst NETWORK = \"mainnet\" as const;\nconst PUBLIC_KEY = new Uint8Array(32).fill(0xab);\nconst CHALLENGE = \"aabbccdd11223344\";\nconst DESCRIPTOR_HEX = \"0102030405\";\nconst CERTIFICATE = {\n keyUsageNumber: 4,\n payload: new Uint8Array([0x10, 0x20, 0x30]),\n};\n\nfunction makeSuccessContext(withCertificate = true): ClearSignContext[] {\n return [\n {\n type: ClearSignContextType.ACCOUNT_OWNERSHIP,\n payload: DESCRIPTOR_HEX,\n certificate: withCertificate ? CERTIFICATE : undefined,\n },\n ];\n}\n\nfunction makeErrorContext(message: string): ClearSignContext[] {\n return [\n {\n type: ClearSignContextType.ERROR,\n error: new Error(message),\n },\n ];\n}\n\ndescribe(\"VerifyAddressTask\", () => {\n let sendCommandMock: ReturnType<typeof vi.fn>;\n let apiMock: InternalApi;\n let loggerMock: LoggerPublisherService;\n let contextModuleMock: ContextModule;\n\n beforeEach(() => {\n sendCommandMock = vi.fn();\n apiMock = {\n sendCommand: sendCommandMock,\n getDeviceModel: () => ({ id: DeviceModelId.NANO_SP }),\n } as unknown as InternalApi;\n loggerMock = {\n debug: vi.fn(),\n error: vi.fn(),\n } as unknown as LoggerPublisherService;\n contextModuleMock = {\n getContexts: vi.fn(),\n } as unknown as ContextModule;\n });\n\n function createTask() {\n return new VerifyAddressTask(\n apiMock,\n {\n derivationPath: DERIVATION_PATH,\n address: ADDRESS,\n network: NETWORK,\n contextModule: contextModuleMock,\n },\n loggerMock,\n );\n }\n\n function mockSendCommandSequence(\n ...results: ReturnType<typeof CommandResultFactory>[]\n ) {\n let callIndex = 0;\n sendCommandMock.mockImplementation(() =>\n Promise.resolve(results[callIndex++]),\n );\n }\n\n describe(\"success path\", () => {\n it(\"should complete the full flow with certificate\", async () => {\n // GetPublicKey \u2192 GetChallenge \u2192 LoadCertificate \u2192 SetTrustedName \u2192 VerifyAddress\n mockSendCommandSequence(\n CommandResultFactory({ data: { publicKey: PUBLIC_KEY } }),\n CommandResultFactory({ data: { challenge: CHALLENGE } }),\n CommandResultFactory({ data: undefined }), // LoadCertificate\n CommandResultFactory({ data: undefined }), // SetTrustedName\n CommandResultFactory({ data: undefined }), // VerifyAddress\n );\n vi.spyOn(contextModuleMock, \"getContexts\").mockResolvedValue(\n makeSuccessContext(true),\n );\n\n const result = await createTask().run();\n\n expect(isSuccessCommandResult(result)).toBe(true);\n if (isSuccessCommandResult(result)) {\n expect(result.data).toBe(true);\n }\n expect(sendCommandMock).toHaveBeenCalledTimes(5);\n expect(contextModuleMock.getContexts).toHaveBeenCalledWith(\n expect.objectContaining({\n publicKey: \"ab\".repeat(32),\n address: ADDRESS,\n challenge: CHALLENGE,\n network: NETWORK,\n deviceModelId: DeviceModelId.NANO_SP,\n }),\n [ClearSignContextType.ACCOUNT_OWNERSHIP],\n );\n });\n\n it(\"should skip LoadCertificate when context has no certificate\", async () => {\n // GetPublicKey \u2192 GetChallenge \u2192 SetTrustedName \u2192 VerifyAddress (no LoadCert)\n mockSendCommandSequence(\n CommandResultFactory({ data: { publicKey: PUBLIC_KEY } }),\n CommandResultFactory({ data: { challenge: CHALLENGE } }),\n CommandResultFactory({ data: undefined }), // SetTrustedName\n CommandResultFactory({ data: undefined }), // VerifyAddress\n );\n vi.spyOn(contextModuleMock, \"getContexts\").mockResolvedValue(\n makeSuccessContext(false),\n );\n\n const result = await createTask().run();\n\n expect(isSuccessCommandResult(result)).toBe(true);\n expect(sendCommandMock).toHaveBeenCalledTimes(4);\n });\n });\n\n describe(\"failure cases\", () => {\n it(\"should fail when GetPublicKey fails\", async () => {\n const error = new ConcordiumAppCommandError({\n message: \"User rejected\",\n errorCode: ConcordiumErrorCodes.USER_REJECTED,\n });\n sendCommandMock.mockResolvedValueOnce(CommandResultFactory({ error }));\n\n const result = await createTask().run();\n\n expect(isSuccessCommandResult(result)).toBe(false);\n expect(sendCommandMock).toHaveBeenCalledTimes(1);\n });\n\n it(\"should fail when GetChallenge fails\", async () => {\n const error = new ConcordiumAppCommandError({\n message: \"INS not supported\",\n errorCode: ConcordiumErrorCodes.INS_NOT_SUPPORTED,\n });\n sendCommandMock\n .mockResolvedValueOnce(\n CommandResultFactory({ data: { publicKey: PUBLIC_KEY } }),\n )\n .mockResolvedValueOnce(CommandResultFactory({ error }));\n\n const result = await createTask().run();\n\n expect(isSuccessCommandResult(result)).toBe(false);\n expect(sendCommandMock).toHaveBeenCalledTimes(2);\n });\n\n it(\"should fail when context module returns error context\", async () => {\n mockSendCommandSequence(\n CommandResultFactory({ data: { publicKey: PUBLIC_KEY } }),\n CommandResultFactory({ data: { challenge: CHALLENGE } }),\n );\n vi.spyOn(contextModuleMock, \"getContexts\").mockResolvedValue(\n makeErrorContext(\"Backend unavailable\"),\n );\n\n const result = await createTask().run();\n\n expect(isSuccessCommandResult(result)).toBe(false);\n if (!isSuccessCommandResult(result)) {\n expect(result.error).toBeInstanceOf(InvalidStatusWordError);\n }\n });\n\n it(\"should fail when context module returns empty contexts\", async () => {\n mockSendCommandSequence(\n CommandResultFactory({ data: { publicKey: PUBLIC_KEY } }),\n CommandResultFactory({ data: { challenge: CHALLENGE } }),\n );\n vi.spyOn(contextModuleMock, \"getContexts\").mockResolvedValue([]);\n\n const result = await createTask().run();\n\n expect(isSuccessCommandResult(result)).toBe(false);\n if (!isSuccessCommandResult(result)) {\n expect(result.error).toBeInstanceOf(InvalidStatusWordError);\n }\n });\n\n it(\"should fail when context module throws\", async () => {\n mockSendCommandSequence(\n CommandResultFactory({ data: { publicKey: PUBLIC_KEY } }),\n CommandResultFactory({ data: { challenge: CHALLENGE } }),\n );\n vi.spyOn(contextModuleMock, \"getContexts\").mockRejectedValue(\n new Error(\"Network timeout\"),\n );\n\n const result = await createTask().run();\n\n expect(isSuccessCommandResult(result)).toBe(false);\n if (!isSuccessCommandResult(result)) {\n expect(result.error).toBeInstanceOf(InvalidStatusWordError);\n }\n });\n\n it(\"should fail when LoadCertificate fails\", async () => {\n mockSendCommandSequence(\n CommandResultFactory({ data: { publicKey: PUBLIC_KEY } }),\n CommandResultFactory({ data: { challenge: CHALLENGE } }),\n CommandResultFactory({\n error: new InvalidStatusWordError(\"cert error\"),\n }),\n );\n vi.spyOn(contextModuleMock, \"getContexts\").mockResolvedValue(\n makeSuccessContext(true),\n );\n\n const result = await createTask().run();\n\n expect(isSuccessCommandResult(result)).toBe(false);\n if (!isSuccessCommandResult(result)) {\n expect(result.error).toBeInstanceOf(InvalidStatusWordError);\n }\n expect(sendCommandMock).toHaveBeenCalledTimes(3);\n });\n\n it(\"should fail when descriptor payload is empty\", async () => {\n mockSendCommandSequence(\n CommandResultFactory({ data: { publicKey: PUBLIC_KEY } }),\n CommandResultFactory({ data: { challenge: CHALLENGE } }),\n CommandResultFactory({ data: undefined }), // LoadCertificate\n );\n vi.spyOn(contextModuleMock, \"getContexts\").mockResolvedValue([\n {\n type: ClearSignContextType.ACCOUNT_OWNERSHIP,\n payload: \"\",\n certificate: CERTIFICATE,\n },\n ]);\n\n const result = await createTask().run();\n\n expect(isSuccessCommandResult(result)).toBe(false);\n if (!isSuccessCommandResult(result)) {\n expect(result.error).toBeInstanceOf(InvalidStatusWordError);\n }\n });\n\n it(\"should fail when SetTrustedName fails\", async () => {\n const error = new ConcordiumAppCommandError({\n message: \"Data invalid\",\n errorCode: ConcordiumErrorCodes.DATA_INVALID,\n });\n mockSendCommandSequence(\n CommandResultFactory({ data: { publicKey: PUBLIC_KEY } }),\n CommandResultFactory({ data: { challenge: CHALLENGE } }),\n CommandResultFactory({ data: undefined }), // LoadCertificate\n CommandResultFactory({ error }),\n );\n vi.spyOn(contextModuleMock, \"getContexts\").mockResolvedValue(\n makeSuccessContext(true),\n );\n\n const result = await createTask().run();\n\n expect(isSuccessCommandResult(result)).toBe(false);\n expect(sendCommandMock).toHaveBeenCalledTimes(4);\n });\n\n it(\"should fail when VerifyAddress is rejected by user\", async () => {\n const error = new ConcordiumAppCommandError({\n message: \"User rejected\",\n errorCode: ConcordiumErrorCodes.USER_REJECTED,\n });\n mockSendCommandSequence(\n CommandResultFactory({ data: { publicKey: PUBLIC_KEY } }),\n CommandResultFactory({ data: { challenge: CHALLENGE } }),\n CommandResultFactory({ data: undefined }), // LoadCertificate\n CommandResultFactory({ data: undefined }), // SetTrustedName\n CommandResultFactory({ error }),\n );\n vi.spyOn(contextModuleMock, \"getContexts\").mockResolvedValue(\n makeSuccessContext(true),\n );\n\n const result = await createTask().run();\n\n expect(isSuccessCommandResult(result)).toBe(false);\n if (!isSuccessCommandResult(result)) {\n const err = result.error as ConcordiumAppCommandError;\n expect(err.errorCode).toBe(ConcordiumErrorCodes.USER_REJECTED);\n }\n expect(sendCommandMock).toHaveBeenCalledTimes(5);\n });\n\n it(\"should fail when VerifyAddress returns trusted name mismatch\", async () => {\n const error = new ConcordiumAppCommandError({\n message: \"Trusted name mismatch\",\n errorCode: ConcordiumErrorCodes.TRUSTED_NAME_MISMATCH,\n });\n mockSendCommandSequence(\n CommandResultFactory({ data: { publicKey: PUBLIC_KEY } }),\n CommandResultFactory({ data: { challenge: CHALLENGE } }),\n CommandResultFactory({ data: undefined }), // LoadCertificate\n CommandResultFactory({ data: undefined }), // SetTrustedName\n CommandResultFactory({ error }),\n );\n vi.spyOn(contextModuleMock, \"getContexts\").mockResolvedValue(\n makeSuccessContext(true),\n );\n\n const result = await createTask().run();\n\n expect(isSuccessCommandResult(result)).toBe(false);\n if (!isSuccessCommandResult(result)) {\n const err = result.error as ConcordiumAppCommandError;\n expect(err.errorCode).toBe(ConcordiumErrorCodes.TRUSTED_NAME_MISMATCH);\n }\n });\n });\n});\n"],
5
- "mappings": "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",
6
- "names": ["ClearSignContextType", "CommandResultFactory", "DeviceModelId", "InvalidStatusWordError", "isSuccessCommandResult", "vi", "ConcordiumAppCommandError", "ConcordiumErrorCodes", "VerifyAddressTask", "DERIVATION_PATH", "ADDRESS", "NETWORK", "PUBLIC_KEY", "CHALLENGE", "DESCRIPTOR_HEX", "CERTIFICATE", "makeSuccessContext", "withCertificate", "makeErrorContext", "message", "sendCommandMock", "apiMock", "loggerMock", "contextModuleMock", "createTask", "mockSendCommandSequence", "results", "callIndex", "result", "error", "err"]
4
+ "sourcesContent": ["import {\n type ClearSignContext,\n ClearSignContextType,\n type ContextModule,\n} from \"@ledgerhq/context-module\";\nimport {\n CommandResultFactory,\n DeviceModelId,\n type InternalApi,\n InvalidStatusWordError,\n isSuccessCommandResult,\n type LoggerPublisherService,\n} from \"@ledgerhq/device-management-kit\";\nimport { vi } from \"vitest\";\n\nimport {\n ConcordiumAppCommandError,\n ConcordiumErrorCodes,\n} from \"@internal/app-binder/command/utils/ConcordiumApplicationErrors\";\nimport { TrustedMetadataServiceError } from \"@internal/app-binder/command/utils/TrustedMetadataServiceError\";\nimport { VerifyAddressTask } from \"@internal/app-binder/task/VerifyAddressTask\";\n\nconst DERIVATION_PATH = \"44'/919'/0'/0'/0'\";\nconst ADDRESS = \"3kFkntk2H5FGMzeR3GjQKPhdZK9LShKdPHsj2fiGKCdmDXj2WB\";\nconst NETWORK = \"mainnet\" as const;\nconst PUBLIC_KEY = new Uint8Array(32).fill(0xab);\nconst CHALLENGE = \"aabbccdd11223344\";\nconst DESCRIPTOR_HEX = \"0102030405\";\nconst CERTIFICATE = {\n keyUsageNumber: 4,\n payload: new Uint8Array([0x10, 0x20, 0x30]),\n};\n\nfunction makeSuccessContext(withCertificate = true): ClearSignContext[] {\n return [\n {\n type: ClearSignContextType.ACCOUNT_OWNERSHIP,\n payload: DESCRIPTOR_HEX,\n certificate: withCertificate ? CERTIFICATE : undefined,\n },\n ];\n}\n\nfunction makeErrorContext(message: string): ClearSignContext[] {\n return [\n {\n type: ClearSignContextType.ERROR,\n error: new Error(message),\n },\n ];\n}\n\ndescribe(\"VerifyAddressTask\", () => {\n let sendCommandMock: ReturnType<typeof vi.fn>;\n let apiMock: InternalApi;\n let loggerMock: LoggerPublisherService;\n let contextModuleMock: ContextModule;\n\n beforeEach(() => {\n sendCommandMock = vi.fn();\n apiMock = {\n sendCommand: sendCommandMock,\n getDeviceModel: () => ({ id: DeviceModelId.NANO_SP }),\n } as unknown as InternalApi;\n loggerMock = {\n debug: vi.fn(),\n error: vi.fn(),\n } as unknown as LoggerPublisherService;\n contextModuleMock = {\n getContexts: vi.fn(),\n } as unknown as ContextModule;\n });\n\n function createTask() {\n return new VerifyAddressTask(\n apiMock,\n {\n derivationPath: DERIVATION_PATH,\n address: ADDRESS,\n network: NETWORK,\n contextModule: contextModuleMock,\n },\n loggerMock,\n );\n }\n\n function mockSendCommandSequence(\n ...results: ReturnType<typeof CommandResultFactory>[]\n ) {\n let callIndex = 0;\n sendCommandMock.mockImplementation(() =>\n Promise.resolve(results[callIndex++]),\n );\n }\n\n describe(\"success path\", () => {\n it(\"should complete the full flow with certificate\", async () => {\n // GetPublicKey \u2192 GetChallenge \u2192 LoadCertificate \u2192 SetTrustedName \u2192 VerifyAddress\n mockSendCommandSequence(\n CommandResultFactory({ data: { publicKey: PUBLIC_KEY } }),\n CommandResultFactory({ data: { challenge: CHALLENGE } }),\n CommandResultFactory({ data: undefined }), // LoadCertificate\n CommandResultFactory({ data: undefined }), // SetTrustedName\n CommandResultFactory({ data: undefined }), // VerifyAddress\n );\n vi.spyOn(contextModuleMock, \"getContexts\").mockResolvedValue(\n makeSuccessContext(true),\n );\n\n const result = await createTask().run();\n\n expect(isSuccessCommandResult(result)).toBe(true);\n if (isSuccessCommandResult(result)) {\n expect(result.data).toBe(true);\n }\n expect(sendCommandMock).toHaveBeenCalledTimes(5);\n expect(contextModuleMock.getContexts).toHaveBeenCalledWith(\n expect.objectContaining({\n publicKey: \"ab\".repeat(32),\n address: ADDRESS,\n challenge: CHALLENGE,\n network: NETWORK,\n deviceModelId: DeviceModelId.NANO_SP,\n }),\n [ClearSignContextType.ACCOUNT_OWNERSHIP],\n );\n });\n\n it(\"should skip LoadCertificate when context has no certificate\", async () => {\n // GetPublicKey \u2192 GetChallenge \u2192 SetTrustedName \u2192 VerifyAddress (no LoadCert)\n mockSendCommandSequence(\n CommandResultFactory({ data: { publicKey: PUBLIC_KEY } }),\n CommandResultFactory({ data: { challenge: CHALLENGE } }),\n CommandResultFactory({ data: undefined }), // SetTrustedName\n CommandResultFactory({ data: undefined }), // VerifyAddress\n );\n vi.spyOn(contextModuleMock, \"getContexts\").mockResolvedValue(\n makeSuccessContext(false),\n );\n\n const result = await createTask().run();\n\n expect(isSuccessCommandResult(result)).toBe(true);\n expect(sendCommandMock).toHaveBeenCalledTimes(4);\n });\n });\n\n describe(\"failure cases\", () => {\n it(\"should fail when GetPublicKey fails\", async () => {\n const error = new ConcordiumAppCommandError({\n message: \"User rejected\",\n errorCode: ConcordiumErrorCodes.USER_REJECTED,\n });\n sendCommandMock.mockResolvedValueOnce(CommandResultFactory({ error }));\n\n const result = await createTask().run();\n\n expect(isSuccessCommandResult(result)).toBe(false);\n expect(sendCommandMock).toHaveBeenCalledTimes(1);\n });\n\n it(\"should fail when GetChallenge fails\", async () => {\n const error = new ConcordiumAppCommandError({\n message: \"INS not supported\",\n errorCode: ConcordiumErrorCodes.INS_NOT_SUPPORTED,\n });\n sendCommandMock\n .mockResolvedValueOnce(\n CommandResultFactory({ data: { publicKey: PUBLIC_KEY } }),\n )\n .mockResolvedValueOnce(CommandResultFactory({ error }));\n\n const result = await createTask().run();\n\n expect(isSuccessCommandResult(result)).toBe(false);\n expect(sendCommandMock).toHaveBeenCalledTimes(2);\n });\n\n it(\"should fail with TrustedMetadataServiceError when context module returns error context\", async () => {\n mockSendCommandSequence(\n CommandResultFactory({ data: { publicKey: PUBLIC_KEY } }),\n CommandResultFactory({ data: { challenge: CHALLENGE } }),\n );\n vi.spyOn(contextModuleMock, \"getContexts\").mockResolvedValue(\n makeErrorContext(\"Backend unavailable\"),\n );\n\n const result = await createTask().run();\n\n expect(isSuccessCommandResult(result)).toBe(false);\n if (!isSuccessCommandResult(result)) {\n expect(result.error).toBeInstanceOf(TrustedMetadataServiceError);\n expect(result.error).toHaveProperty(\n \"errorCode\",\n ConcordiumErrorCodes.TRUSTED_METADATA_SERVICE_ERROR,\n );\n }\n });\n\n it(\"should fail when context module returns empty contexts\", async () => {\n mockSendCommandSequence(\n CommandResultFactory({ data: { publicKey: PUBLIC_KEY } }),\n CommandResultFactory({ data: { challenge: CHALLENGE } }),\n );\n vi.spyOn(contextModuleMock, \"getContexts\").mockResolvedValue([]);\n\n const result = await createTask().run();\n\n expect(isSuccessCommandResult(result)).toBe(false);\n if (!isSuccessCommandResult(result)) {\n expect(result.error).toBeInstanceOf(InvalidStatusWordError);\n }\n });\n\n it(\"should fail when context module throws\", async () => {\n mockSendCommandSequence(\n CommandResultFactory({ data: { publicKey: PUBLIC_KEY } }),\n CommandResultFactory({ data: { challenge: CHALLENGE } }),\n );\n vi.spyOn(contextModuleMock, \"getContexts\").mockRejectedValue(\n new Error(\"Network timeout\"),\n );\n\n const result = await createTask().run();\n\n expect(isSuccessCommandResult(result)).toBe(false);\n if (!isSuccessCommandResult(result)) {\n expect(result.error).toBeInstanceOf(InvalidStatusWordError);\n }\n });\n\n it(\"should fail when LoadCertificate fails\", async () => {\n mockSendCommandSequence(\n CommandResultFactory({ data: { publicKey: PUBLIC_KEY } }),\n CommandResultFactory({ data: { challenge: CHALLENGE } }),\n CommandResultFactory({\n error: new InvalidStatusWordError(\"cert error\"),\n }),\n );\n vi.spyOn(contextModuleMock, \"getContexts\").mockResolvedValue(\n makeSuccessContext(true),\n );\n\n const result = await createTask().run();\n\n expect(isSuccessCommandResult(result)).toBe(false);\n if (!isSuccessCommandResult(result)) {\n expect(result.error).toBeInstanceOf(InvalidStatusWordError);\n }\n expect(sendCommandMock).toHaveBeenCalledTimes(3);\n });\n\n it(\"should fail when descriptor payload is empty\", async () => {\n mockSendCommandSequence(\n CommandResultFactory({ data: { publicKey: PUBLIC_KEY } }),\n CommandResultFactory({ data: { challenge: CHALLENGE } }),\n CommandResultFactory({ data: undefined }), // LoadCertificate\n );\n vi.spyOn(contextModuleMock, \"getContexts\").mockResolvedValue([\n {\n type: ClearSignContextType.ACCOUNT_OWNERSHIP,\n payload: \"\",\n certificate: CERTIFICATE,\n },\n ]);\n\n const result = await createTask().run();\n\n expect(isSuccessCommandResult(result)).toBe(false);\n if (!isSuccessCommandResult(result)) {\n expect(result.error).toBeInstanceOf(InvalidStatusWordError);\n }\n });\n\n it(\"should fail when SetTrustedName fails\", async () => {\n const error = new ConcordiumAppCommandError({\n message: \"Data invalid\",\n errorCode: ConcordiumErrorCodes.DATA_INVALID,\n });\n mockSendCommandSequence(\n CommandResultFactory({ data: { publicKey: PUBLIC_KEY } }),\n CommandResultFactory({ data: { challenge: CHALLENGE } }),\n CommandResultFactory({ data: undefined }), // LoadCertificate\n CommandResultFactory({ error }),\n );\n vi.spyOn(contextModuleMock, \"getContexts\").mockResolvedValue(\n makeSuccessContext(true),\n );\n\n const result = await createTask().run();\n\n expect(isSuccessCommandResult(result)).toBe(false);\n expect(sendCommandMock).toHaveBeenCalledTimes(4);\n });\n\n it(\"should fail when VerifyAddress is rejected by user\", async () => {\n const error = new ConcordiumAppCommandError({\n message: \"User rejected\",\n errorCode: ConcordiumErrorCodes.USER_REJECTED,\n });\n mockSendCommandSequence(\n CommandResultFactory({ data: { publicKey: PUBLIC_KEY } }),\n CommandResultFactory({ data: { challenge: CHALLENGE } }),\n CommandResultFactory({ data: undefined }), // LoadCertificate\n CommandResultFactory({ data: undefined }), // SetTrustedName\n CommandResultFactory({ error }),\n );\n vi.spyOn(contextModuleMock, \"getContexts\").mockResolvedValue(\n makeSuccessContext(true),\n );\n\n const result = await createTask().run();\n\n expect(isSuccessCommandResult(result)).toBe(false);\n if (!isSuccessCommandResult(result)) {\n const err = result.error as ConcordiumAppCommandError;\n expect(err.errorCode).toBe(ConcordiumErrorCodes.USER_REJECTED);\n }\n expect(sendCommandMock).toHaveBeenCalledTimes(5);\n });\n\n it(\"should fail when VerifyAddress returns trusted name mismatch\", async () => {\n const error = new ConcordiumAppCommandError({\n message: \"Trusted name mismatch\",\n errorCode: ConcordiumErrorCodes.TRUSTED_NAME_MISMATCH,\n });\n mockSendCommandSequence(\n CommandResultFactory({ data: { publicKey: PUBLIC_KEY } }),\n CommandResultFactory({ data: { challenge: CHALLENGE } }),\n CommandResultFactory({ data: undefined }), // LoadCertificate\n CommandResultFactory({ data: undefined }), // SetTrustedName\n CommandResultFactory({ error }),\n );\n vi.spyOn(contextModuleMock, \"getContexts\").mockResolvedValue(\n makeSuccessContext(true),\n );\n\n const result = await createTask().run();\n\n expect(isSuccessCommandResult(result)).toBe(false);\n if (!isSuccessCommandResult(result)) {\n const err = result.error as ConcordiumAppCommandError;\n expect(err.errorCode).toBe(ConcordiumErrorCodes.TRUSTED_NAME_MISMATCH);\n }\n });\n });\n});\n"],
5
+ "mappings": "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",
6
+ "names": ["ClearSignContextType", "CommandResultFactory", "DeviceModelId", "InvalidStatusWordError", "isSuccessCommandResult", "vi", "ConcordiumAppCommandError", "ConcordiumErrorCodes", "TrustedMetadataServiceError", "VerifyAddressTask", "DERIVATION_PATH", "ADDRESS", "NETWORK", "PUBLIC_KEY", "CHALLENGE", "DESCRIPTOR_HEX", "CERTIFICATE", "makeSuccessContext", "withCertificate", "makeErrorContext", "message", "sendCommandMock", "apiMock", "loggerMock", "contextModuleMock", "createTask", "mockSendCommandSequence", "results", "callIndex", "result", "error", "err"]
7
7
  }
@@ -58,5 +58,5 @@
58
58
  "watch:builds": "pnpm ldmk-tool watch --entryPoints src/index.ts,src/**/*.ts --tsconfig tsconfig.prod.json",
59
59
  "watch:types": "concurrently \"tsc --watch -p tsconfig.prod.json\" \"tsc-alias --watch -p tsconfig.prod.json\""
60
60
  },
61
- "version": "0.0.0-develop-20260419002000"
61
+ "version": "0.0.0-develop-20260420165047"
62
62
  }