@ledgerhq/device-contacts-kit 0.0.0-develop-20260828024102 → 0.0.0-develop-20260829001241

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 (136) hide show
  1. package/README.md +29 -2
  2. package/lib/cjs/api/ContactsManager.js +1 -1
  3. package/lib/cjs/api/ContactsManager.js.map +1 -1
  4. package/lib/cjs/api/app-binder/RenameContactDeviceActionTypes.js +2 -0
  5. package/lib/cjs/api/app-binder/RenameContactDeviceActionTypes.js.map +7 -0
  6. package/lib/cjs/api/index.js +1 -1
  7. package/lib/cjs/api/index.js.map +2 -2
  8. package/lib/cjs/api/model/RenameContact.js +2 -0
  9. package/lib/cjs/api/model/RenameContact.js.map +7 -0
  10. package/lib/cjs/internal/DefaultContactsManager.js +1 -1
  11. package/lib/cjs/internal/DefaultContactsManager.js.map +2 -2
  12. package/lib/cjs/internal/DefaultContactsManager.test.js +1 -1
  13. package/lib/cjs/internal/DefaultContactsManager.test.js.map +3 -3
  14. package/lib/cjs/internal/app-binder/ContactsAppBinder.js +1 -1
  15. package/lib/cjs/internal/app-binder/ContactsAppBinder.js.map +3 -3
  16. package/lib/cjs/internal/app-binder/command/RenameContactCommand.js +2 -0
  17. package/lib/cjs/internal/app-binder/command/RenameContactCommand.js.map +7 -0
  18. package/lib/cjs/internal/app-binder/command/RenameContactCommand.test.js +2 -0
  19. package/lib/cjs/internal/app-binder/command/RenameContactCommand.test.js.map +7 -0
  20. package/lib/cjs/internal/app-binder/device-action/RenameContact/RenameContactDeviceAction.js +2 -0
  21. package/lib/cjs/internal/app-binder/device-action/RenameContact/RenameContactDeviceAction.js.map +7 -0
  22. package/lib/cjs/internal/app-binder/device-action/RenameContact/RenameContactDeviceAction.test.js +2 -0
  23. package/lib/cjs/internal/app-binder/device-action/RenameContact/RenameContactDeviceAction.test.js.map +7 -0
  24. package/lib/cjs/internal/app-binder/device-action/RenameContact/validateRenameContactInput.js +2 -0
  25. package/lib/cjs/internal/app-binder/device-action/RenameContact/validateRenameContactInput.js.map +7 -0
  26. package/lib/cjs/internal/app-binder/device-action/RenameContact/validateRenameContactInput.test.js +2 -0
  27. package/lib/cjs/internal/app-binder/device-action/RenameContact/validateRenameContactInput.test.js.map +7 -0
  28. package/lib/cjs/internal/app-binder/device-action/__test-utils__/setupGoToDashboardDAMock.js +2 -0
  29. package/lib/cjs/internal/app-binder/device-action/__test-utils__/setupGoToDashboardDAMock.js.map +7 -0
  30. package/lib/cjs/internal/app-binder/isContactsSupportedForSession.js +1 -1
  31. package/lib/cjs/internal/app-binder/isContactsSupportedForSession.js.map +3 -3
  32. package/lib/cjs/internal/app-binder/model/contactsConstants.js +1 -1
  33. package/lib/cjs/internal/app-binder/model/contactsConstants.js.map +3 -3
  34. package/lib/cjs/internal/app-binder/task/SendRenameContactTask.js +2 -0
  35. package/lib/cjs/internal/app-binder/task/SendRenameContactTask.js.map +7 -0
  36. package/lib/cjs/internal/app-binder/task/SendRenameContactTask.test.js +2 -0
  37. package/lib/cjs/internal/app-binder/task/SendRenameContactTask.test.js.map +7 -0
  38. package/lib/cjs/internal/di.test.js +1 -1
  39. package/lib/cjs/internal/di.test.js.map +3 -3
  40. package/lib/cjs/internal/use-cases/RenameContactUseCase.js +2 -0
  41. package/lib/cjs/internal/use-cases/RenameContactUseCase.js.map +7 -0
  42. package/lib/cjs/internal/use-cases/RenameContactUseCase.test.js +2 -0
  43. package/lib/cjs/internal/use-cases/RenameContactUseCase.test.js.map +7 -0
  44. package/lib/cjs/internal/use-cases/di/useCaseModule.js +1 -1
  45. package/lib/cjs/internal/use-cases/di/useCaseModule.js.map +3 -3
  46. package/lib/cjs/internal/use-cases/di/useCaseTypes.js +1 -1
  47. package/lib/cjs/internal/use-cases/di/useCaseTypes.js.map +2 -2
  48. package/lib/cjs/package.json +1 -1
  49. package/lib/esm/api/app-binder/RenameContactDeviceActionTypes.js +1 -0
  50. package/lib/esm/api/app-binder/RenameContactDeviceActionTypes.js.map +7 -0
  51. package/lib/esm/api/index.js +1 -1
  52. package/lib/esm/api/index.js.map +2 -2
  53. package/lib/esm/api/model/RenameContact.js +1 -0
  54. package/lib/esm/api/model/RenameContact.js.map +7 -0
  55. package/lib/esm/internal/DefaultContactsManager.js +1 -1
  56. package/lib/esm/internal/DefaultContactsManager.js.map +2 -2
  57. package/lib/esm/internal/DefaultContactsManager.test.js +1 -1
  58. package/lib/esm/internal/DefaultContactsManager.test.js.map +3 -3
  59. package/lib/esm/internal/app-binder/ContactsAppBinder.js +1 -1
  60. package/lib/esm/internal/app-binder/ContactsAppBinder.js.map +3 -3
  61. package/lib/esm/internal/app-binder/command/RenameContactCommand.js +2 -0
  62. package/lib/esm/internal/app-binder/command/RenameContactCommand.js.map +7 -0
  63. package/lib/esm/internal/app-binder/command/RenameContactCommand.test.js +2 -0
  64. package/lib/esm/internal/app-binder/command/RenameContactCommand.test.js.map +7 -0
  65. package/lib/esm/internal/app-binder/device-action/RenameContact/RenameContactDeviceAction.js +2 -0
  66. package/lib/esm/internal/app-binder/device-action/RenameContact/RenameContactDeviceAction.js.map +7 -0
  67. package/lib/esm/internal/app-binder/device-action/RenameContact/RenameContactDeviceAction.test.js +2 -0
  68. package/lib/esm/internal/app-binder/device-action/RenameContact/RenameContactDeviceAction.test.js.map +7 -0
  69. package/lib/esm/internal/app-binder/device-action/RenameContact/validateRenameContactInput.js +2 -0
  70. package/lib/esm/internal/app-binder/device-action/RenameContact/validateRenameContactInput.js.map +7 -0
  71. package/lib/esm/internal/app-binder/device-action/RenameContact/validateRenameContactInput.test.js +2 -0
  72. package/lib/esm/internal/app-binder/device-action/RenameContact/validateRenameContactInput.test.js.map +7 -0
  73. package/lib/esm/internal/app-binder/device-action/__test-utils__/setupGoToDashboardDAMock.js +2 -0
  74. package/lib/esm/internal/app-binder/device-action/__test-utils__/setupGoToDashboardDAMock.js.map +7 -0
  75. package/lib/esm/internal/app-binder/isContactsSupportedForSession.js +1 -1
  76. package/lib/esm/internal/app-binder/isContactsSupportedForSession.js.map +3 -3
  77. package/lib/esm/internal/app-binder/model/contactsConstants.js +1 -1
  78. package/lib/esm/internal/app-binder/model/contactsConstants.js.map +3 -3
  79. package/lib/esm/internal/app-binder/task/SendRenameContactTask.js +2 -0
  80. package/lib/esm/internal/app-binder/task/SendRenameContactTask.js.map +7 -0
  81. package/lib/esm/internal/app-binder/task/SendRenameContactTask.test.js +2 -0
  82. package/lib/esm/internal/app-binder/task/SendRenameContactTask.test.js.map +7 -0
  83. package/lib/esm/internal/di.test.js +1 -1
  84. package/lib/esm/internal/di.test.js.map +3 -3
  85. package/lib/esm/internal/use-cases/RenameContactUseCase.js +2 -0
  86. package/lib/esm/internal/use-cases/RenameContactUseCase.js.map +7 -0
  87. package/lib/esm/internal/use-cases/RenameContactUseCase.test.js +2 -0
  88. package/lib/esm/internal/use-cases/RenameContactUseCase.test.js.map +7 -0
  89. package/lib/esm/internal/use-cases/di/useCaseModule.js +1 -1
  90. package/lib/esm/internal/use-cases/di/useCaseModule.js.map +3 -3
  91. package/lib/esm/internal/use-cases/di/useCaseTypes.js +1 -1
  92. package/lib/esm/internal/use-cases/di/useCaseTypes.js.map +2 -2
  93. package/lib/esm/package.json +1 -1
  94. package/lib/types/api/ContactsManager.d.ts +12 -0
  95. package/lib/types/api/ContactsManager.d.ts.map +1 -1
  96. package/lib/types/api/app-binder/RenameContactDeviceActionTypes.d.ts +25 -0
  97. package/lib/types/api/app-binder/RenameContactDeviceActionTypes.d.ts.map +1 -0
  98. package/lib/types/api/index.d.ts +2 -0
  99. package/lib/types/api/index.d.ts.map +1 -1
  100. package/lib/types/api/model/RenameContact.d.ts +39 -0
  101. package/lib/types/api/model/RenameContact.d.ts.map +1 -0
  102. package/lib/types/internal/DefaultContactsManager.d.ts +3 -0
  103. package/lib/types/internal/DefaultContactsManager.d.ts.map +1 -1
  104. package/lib/types/internal/app-binder/ContactsAppBinder.d.ts +3 -0
  105. package/lib/types/internal/app-binder/ContactsAppBinder.d.ts.map +1 -1
  106. package/lib/types/internal/app-binder/command/RenameContactCommand.d.ts +25 -0
  107. package/lib/types/internal/app-binder/command/RenameContactCommand.d.ts.map +1 -0
  108. package/lib/types/internal/app-binder/command/RenameContactCommand.test.d.ts +2 -0
  109. package/lib/types/internal/app-binder/command/RenameContactCommand.test.d.ts.map +1 -0
  110. package/lib/types/internal/app-binder/device-action/RenameContact/RenameContactDeviceAction.d.ts +13 -0
  111. package/lib/types/internal/app-binder/device-action/RenameContact/RenameContactDeviceAction.d.ts.map +1 -0
  112. package/lib/types/internal/app-binder/device-action/RenameContact/RenameContactDeviceAction.test.d.ts +2 -0
  113. package/lib/types/internal/app-binder/device-action/RenameContact/RenameContactDeviceAction.test.d.ts.map +1 -0
  114. package/lib/types/internal/app-binder/device-action/RenameContact/validateRenameContactInput.d.ts +12 -0
  115. package/lib/types/internal/app-binder/device-action/RenameContact/validateRenameContactInput.d.ts.map +1 -0
  116. package/lib/types/internal/app-binder/device-action/RenameContact/validateRenameContactInput.test.d.ts +2 -0
  117. package/lib/types/internal/app-binder/device-action/RenameContact/validateRenameContactInput.test.d.ts.map +1 -0
  118. package/lib/types/internal/app-binder/device-action/__test-utils__/setupGoToDashboardDAMock.d.ts +12 -0
  119. package/lib/types/internal/app-binder/device-action/__test-utils__/setupGoToDashboardDAMock.d.ts.map +1 -0
  120. package/lib/types/internal/app-binder/isContactsSupportedForSession.d.ts +15 -0
  121. package/lib/types/internal/app-binder/isContactsSupportedForSession.d.ts.map +1 -1
  122. package/lib/types/internal/app-binder/model/contactsConstants.d.ts +15 -0
  123. package/lib/types/internal/app-binder/model/contactsConstants.d.ts.map +1 -1
  124. package/lib/types/internal/app-binder/task/SendRenameContactTask.d.ts +20 -0
  125. package/lib/types/internal/app-binder/task/SendRenameContactTask.d.ts.map +1 -0
  126. package/lib/types/internal/app-binder/task/SendRenameContactTask.test.d.ts +2 -0
  127. package/lib/types/internal/app-binder/task/SendRenameContactTask.test.d.ts.map +1 -0
  128. package/lib/types/internal/use-cases/RenameContactUseCase.d.ts +19 -0
  129. package/lib/types/internal/use-cases/RenameContactUseCase.d.ts.map +1 -0
  130. package/lib/types/internal/use-cases/RenameContactUseCase.test.d.ts +2 -0
  131. package/lib/types/internal/use-cases/RenameContactUseCase.test.d.ts.map +1 -0
  132. package/lib/types/internal/use-cases/di/useCaseModule.d.ts.map +1 -1
  133. package/lib/types/internal/use-cases/di/useCaseTypes.d.ts +1 -0
  134. package/lib/types/internal/use-cases/di/useCaseTypes.d.ts.map +1 -1
  135. package/lib/types/tsconfig.prod.tsbuildinfo +1 -1
  136. package/package.json +6 -6
@@ -0,0 +1,7 @@
1
+ {
2
+ "version": 3,
3
+ "sources": ["../../../../../src/internal/app-binder/task/SendRenameContactTask.ts"],
4
+ "sourcesContent": ["// Builds the TLV payload for the Rename Contact (EDIT CONTACT NAME) op and\n// dispatches it via the chunked-framing scheme shared with the other\n// address-book ops (2-byte BE total length + <=255B chunks). Rename is an\n// OS/dashboard command (CLA 0xE0 / INS 0x2E) \u2014 the caller runs this task after\n// navigating to the dashboard (GoToDashboardDeviceAction), never inside an app.\n//\n// The device rotates the contact-level hmac_name and returns the fresh proof on\n// the final chunk; per-entry hmac_rest values are untouched (they bind\n// gid|scope|id|family|chain_id, never the name), so a single APDU regardless of\n// the contact's entry count.\n//\n// Reference: Address Book Final Specifications \u2014 Edit Contact Name. Tag order:\n// STRUCT_TYPE, STRUCT_VERSION, CONTACT_NAME (new), PREVIOUS_CONTACT_NAME\n// (old), GROUP_HANDLE, DERIVATION_PATH, HMAC_PROOF.\nimport {\n ByteArrayBuilder,\n type CommandResult,\n DmkResultFactory,\n type InternalApi,\n InvalidStatusWordError,\n isSuccessCommandResult,\n type LoggerPublisherService,\n} from \"@ledgerhq/device-management-kit\";\n\nimport { RenameContactCommand } from \"@internal/app-binder/command/RenameContactCommand\";\nimport { RENAME_CONTACT_P1 } from \"@internal/app-binder/model/contactsConstants\";\nimport { type ContactsErrorCodes } from \"@internal/app-binder/model/contactsErrors\";\nimport {\n CONTACTS_TLV_TAG,\n encodeTlvAscii,\n encodeTlvBuffer,\n encodeTlvUInt8,\n packDerivationPath,\n STRUCT_TYPE_EDIT_CONTACT_NAME,\n STRUCT_VERSION_VALUE,\n} from \"@internal/app-binder/services/contactsTlvSerializer\";\nimport { sendFramedContactsPayload } from \"@internal/app-binder/services/sendFramedContactsPayload\";\n\nexport type RenameContactProof = {\n readonly hmacProof: Uint8Array;\n};\n\nexport type SendRenameContactTaskArgs = {\n readonly previousContactName: string;\n readonly newContactName: string;\n readonly groupHandle: Uint8Array;\n readonly hmacProof: Uint8Array;\n readonly logger?: LoggerPublisherService;\n};\n\nexport class SendRenameContactTask {\n constructor(\n private readonly api: InternalApi,\n private readonly args: SendRenameContactTaskArgs,\n ) {}\n\n async run(): Promise<CommandResult<RenameContactProof, ContactsErrorCodes>> {\n const payload = this.buildPayload(this.args);\n\n const result = (await sendFramedContactsPayload(this.api, {\n payload,\n p1: RENAME_CONTACT_P1,\n makeCommand: (chunk, p2) => new RenameContactCommand({ data: chunk, p2 }),\n logger: this.args.logger,\n commandTag: \"SendRenameContactTask\",\n })) as CommandResult<\n { readonly hmacProof?: Uint8Array },\n ContactsErrorCodes\n >;\n\n if (!isSuccessCommandResult(result)) {\n return result;\n }\n\n const { hmacProof } = result.data;\n if (!hmacProof) {\n return DmkResultFactory({\n error: new InvalidStatusWordError(\n \"RenameContact final-chunk response did not carry hmac_name\",\n ),\n });\n }\n return DmkResultFactory({ data: { hmacProof } });\n }\n\n private buildPayload(args: SendRenameContactTaskArgs): Uint8Array {\n const builder = new ByteArrayBuilder();\n encodeTlvUInt8(\n builder,\n CONTACTS_TLV_TAG.STRUCT_TYPE,\n STRUCT_TYPE_EDIT_CONTACT_NAME,\n );\n encodeTlvUInt8(\n builder,\n CONTACTS_TLV_TAG.STRUCT_VERSION,\n STRUCT_VERSION_VALUE,\n );\n encodeTlvAscii(builder, CONTACTS_TLV_TAG.CONTACT_NAME, args.newContactName);\n encodeTlvAscii(\n builder,\n CONTACTS_TLV_TAG.PREVIOUS_CONTACT_NAME,\n args.previousContactName,\n );\n encodeTlvBuffer(builder, CONTACTS_TLV_TAG.GROUP_HANDLE, args.groupHandle);\n // The Ethereum app requires DERIVATION_PATH on Edit Contact Name (0x6a80\n // without it), same as Register Identity. Default m/44'/60'/0'/0/0.\n encodeTlvBuffer(\n builder,\n CONTACTS_TLV_TAG.DERIVATION_PATH,\n packDerivationPath([0x8000002c, 0x8000003c, 0x80000000, 0, 0]),\n );\n encodeTlvBuffer(builder, CONTACTS_TLV_TAG.HMAC_PROOF, args.hmacProof);\n\n return builder.build();\n }\n}\n"],
5
+ "mappings": "yaAAA,IAAAA,EAAA,GAAAC,EAAAD,EAAA,2BAAAE,IAAA,eAAAC,EAAAH,GAcA,IAAAI,EAQO,2CAEPC,EAAqC,6DACrCC,EAAkC,wDAElCC,EAQO,+DACPC,EAA0C,mEAcnC,MAAMN,CAAsB,CACjC,YACmBO,EACAC,EACjB,CAFiB,SAAAD,EACA,UAAAC,CAChB,CAEH,MAAM,KAAsE,CAC1E,MAAMC,EAAU,KAAK,aAAa,KAAK,IAAI,EAErCC,EAAU,QAAM,6BAA0B,KAAK,IAAK,CACxD,QAAAD,EACA,GAAI,oBACJ,YAAa,CAACE,EAAOC,IAAO,IAAI,uBAAqB,CAAE,KAAMD,EAAO,GAAAC,CAAG,CAAC,EACxE,OAAQ,KAAK,KAAK,OAClB,WAAY,uBACd,CAAC,EAKD,GAAI,IAAC,0BAAuBF,CAAM,EAChC,OAAOA,EAGT,KAAM,CAAE,UAAAG,CAAU,EAAIH,EAAO,KAC7B,OAAKG,KAOE,oBAAiB,CAAE,KAAM,CAAE,UAAAA,CAAU,CAAE,CAAC,KANtC,oBAAiB,CACtB,MAAO,IAAI,yBACT,4DACF,CACF,CAAC,CAGL,CAEQ,aAAaL,EAA6C,CAChE,MAAMM,EAAU,IAAI,mBACpB,2BACEA,EACA,mBAAiB,YACjB,+BACF,KACA,kBACEA,EACA,mBAAiB,eACjB,sBACF,KACA,kBAAeA,EAAS,mBAAiB,aAAcN,EAAK,cAAc,KAC1E,kBACEM,EACA,mBAAiB,sBACjBN,EAAK,mBACP,KACA,mBAAgBM,EAAS,mBAAiB,aAAcN,EAAK,WAAW,KAGxE,mBACEM,EACA,mBAAiB,mBACjB,sBAAmB,CAAC,WAAY,WAAY,WAAY,EAAG,CAAC,CAAC,CAC/D,KACA,mBAAgBA,EAAS,mBAAiB,WAAYN,EAAK,SAAS,EAE7DM,EAAQ,MAAM,CACvB,CACF",
6
+ "names": ["SendRenameContactTask_exports", "__export", "SendRenameContactTask", "__toCommonJS", "import_device_management_kit", "import_RenameContactCommand", "import_contactsConstants", "import_contactsTlvSerializer", "import_sendFramedContactsPayload", "api", "args", "payload", "result", "chunk", "p2", "hmacProof", "builder"]
7
+ }
@@ -0,0 +1,2 @@
1
+ "use strict";var a=require("@ledgerhq/device-management-kit"),i=require("../../app-binder/command/RenameContactCommand"),o=require("./SendRenameContactTask");function s(e){const n=new Uint8Array(e.length/2);for(let t=0;t<e.length;t+=2)n[t/2]=parseInt(e.slice(t,t+2),16);return n}const r=s("cc".repeat(64)),c=s("dd".repeat(32)),d=s("ee".repeat(32)),l="6915058000002c8000003c800000000000000000000000",p=s("009001012e02010181f003426f6281f305416c69636581f640"+"cc".repeat(64)+l+"2920"+"dd".repeat(32));function m(){return{sendCommand:vi.fn()}}describe("SendRenameContactTask",()=>{it("assembles the rename framed chunk and dispatches RenameContactCommand",async()=>{const e=m();e.sendCommand.mockResolvedValueOnce((0,a.CommandResultFactory)({data:{hmacProof:d}}));const n=await new o.SendRenameContactTask(e,{previousContactName:"Alice",newContactName:"Bob",groupHandle:r,hmacProof:c}).run();expect(e.sendCommand.mock.calls).toHaveLength(1),expect(e.sendCommand.mock.calls[0][0]).toStrictEqual(new i.RenameContactCommand({data:p,p2:0})),expect(n).toStrictEqual((0,a.CommandResultFactory)({data:{hmacProof:d}}))}),it("emits the DERIVATION_PATH tag immediately before HMAC_PROOF",async()=>{const e=m();e.sendCommand.mockResolvedValueOnce((0,a.CommandResultFactory)({data:{hmacProof:d}})),await new o.SendRenameContactTask(e,{previousContactName:"Alice",newContactName:"Bob",groupHandle:r,hmacProof:c}).run();const n=e.sendCommand.mock.calls[0][0],t=Buffer.from(n.args.data).toString("hex");expect(t.endsWith(l+"2920"+"dd".repeat(32))).toBe(!0)}),it("propagates command-level errors",async()=>{const e=m();e.sendCommand.mockResolvedValueOnce((0,a.CommandResultFactory)({error:new a.InvalidStatusWordError("user cancelled")}));const n=await new o.SendRenameContactTask(e,{previousContactName:"Alice",newContactName:"Bob",groupHandle:r,hmacProof:c}).run();expect(n).toStrictEqual((0,a.CommandResultFactory)({error:new a.InvalidStatusWordError("user cancelled")}))}),it("returns InvalidStatusWordError when the final response carries no hmac_name",async()=>{const e=m();e.sendCommand.mockResolvedValueOnce((0,a.CommandResultFactory)({data:{}}));const n=await new o.SendRenameContactTask(e,{previousContactName:"Alice",newContactName:"Bob",groupHandle:r,hmacProof:c}).run();expect(n.status).not.toBe(void 0),"error"in n&&expect(n.error).toBeInstanceOf(a.InvalidStatusWordError)})});
2
+ //# sourceMappingURL=SendRenameContactTask.test.js.map
@@ -0,0 +1,7 @@
1
+ {
2
+ "version": 3,
3
+ "sources": ["../../../../../src/internal/app-binder/task/SendRenameContactTask.test.ts"],
4
+ "sourcesContent": ["// Validates that the TLV serializer + tag ordering + chunk framing produce the\n// expected wire bytes for the Rename Contact (EDIT CONTACT NAME) op. The framed\n// chunk = 2-byte BE total length + TLV. Tag order: STRUCT_TYPE, STRUCT_VERSION,\n// CONTACT_NAME (new), PREVIOUS_CONTACT_NAME (old), GROUP_HANDLE, DERIVATION_PATH,\n// HMAC_PROOF \u2014 with tags >= 0x80 (0xf0/0xf3/0xf6) encoded as the 2-byte DER form\n// [0x81, tag].\nimport {\n CommandResultFactory,\n type InternalApi,\n InvalidStatusWordError,\n} from \"@ledgerhq/device-management-kit\";\n\nimport { RenameContactCommand } from \"@internal/app-binder/command/RenameContactCommand\";\n\nimport { SendRenameContactTask } from \"./SendRenameContactTask\";\n\nfunction hexToBytes(hex: string): Uint8Array {\n const out = new Uint8Array(hex.length / 2);\n for (let i = 0; i < hex.length; i += 2) {\n out[i / 2] = parseInt(hex.slice(i, i + 2), 16);\n }\n return out;\n}\n\nconst GROUP_HANDLE = hexToBytes(\"cc\".repeat(64));\nconst HMAC_PROOF_IN = hexToBytes(\"dd\".repeat(32));\nconst HMAC_PROOF_OUT = hexToBytes(\"ee\".repeat(32));\n\n// Framed chunk = \"00 90\" (2-byte BE total TLV length = 144) + TLV:\n// 01 01 2e STRUCT_TYPE = EDIT_CONTACT_NAME (0x2e)\n// 02 01 01 STRUCT_VERSION = 1\n// 81 f0 03 \"Bob\" CONTACT_NAME (new), tag 0xf0 -> [81 f0]\n// 81 f3 05 \"Alice\" PREVIOUS_CONTACT_NAME (old), tag 0xf3 -> [81 f3]\n// 81 f6 40 <64x cc> GROUP_HANDLE, tag 0xf6 -> [81 f6]\n// 69 15 05 <5x path> DERIVATION_PATH (0x69), m/44'/60'/0'/0/0\n// 29 20 <32x dd> HMAC_PROOF\nconst DERIVATION_PATH_TLV = \"6915058000002c8000003c800000000000000000000000\";\nconst FRAMED_CHUNK = hexToBytes(\n \"0090\" +\n \"01012e\" +\n \"020101\" +\n \"81f003426f62\" +\n \"81f305416c696365\" +\n \"81f640\" +\n \"cc\".repeat(64) +\n DERIVATION_PATH_TLV +\n \"2920\" +\n \"dd\".repeat(32),\n);\n\nfunction makeApiMock(): InternalApi & {\n sendCommand: ReturnType<typeof vi.fn>;\n} {\n return { sendCommand: vi.fn() } as unknown as InternalApi & {\n sendCommand: ReturnType<typeof vi.fn>;\n };\n}\n\ndescribe(\"SendRenameContactTask\", () => {\n it(\"assembles the rename framed chunk and dispatches RenameContactCommand\", async () => {\n const api = makeApiMock();\n api.sendCommand.mockResolvedValueOnce(\n CommandResultFactory({ data: { hmacProof: HMAC_PROOF_OUT } }),\n );\n\n const result = await new SendRenameContactTask(api, {\n previousContactName: \"Alice\",\n newContactName: \"Bob\",\n groupHandle: GROUP_HANDLE,\n hmacProof: HMAC_PROOF_IN,\n }).run();\n\n expect(api.sendCommand.mock.calls).toHaveLength(1);\n expect(api.sendCommand.mock.calls[0]![0]).toStrictEqual(\n new RenameContactCommand({ data: FRAMED_CHUNK, p2: 0x00 }),\n );\n expect(result).toStrictEqual(\n CommandResultFactory({ data: { hmacProof: HMAC_PROOF_OUT } }),\n );\n });\n\n it(\"emits the DERIVATION_PATH tag immediately before HMAC_PROOF\", async () => {\n const api = makeApiMock();\n api.sendCommand.mockResolvedValueOnce(\n CommandResultFactory({ data: { hmacProof: HMAC_PROOF_OUT } }),\n );\n\n await new SendRenameContactTask(api, {\n previousContactName: \"Alice\",\n newContactName: \"Bob\",\n groupHandle: GROUP_HANDLE,\n hmacProof: HMAC_PROOF_IN,\n }).run();\n\n // The Ethereum app requires DERIVATION_PATH (0x69); it sits immediately\n // before HMAC_PROOF (0x29), matching Register Identity.\n const command = api.sendCommand.mock.calls[0]![0] as RenameContactCommand;\n const framedHex = Buffer.from(command.args.data).toString(\"hex\");\n expect(\n framedHex.endsWith(DERIVATION_PATH_TLV + \"2920\" + \"dd\".repeat(32)),\n ).toBe(true);\n });\n\n it(\"propagates command-level errors\", async () => {\n const api = makeApiMock();\n api.sendCommand.mockResolvedValueOnce(\n CommandResultFactory({\n error: new InvalidStatusWordError(\"user cancelled\"),\n }),\n );\n\n const result = await new SendRenameContactTask(api, {\n previousContactName: \"Alice\",\n newContactName: \"Bob\",\n groupHandle: GROUP_HANDLE,\n hmacProof: HMAC_PROOF_IN,\n }).run();\n\n expect(result).toStrictEqual(\n CommandResultFactory({\n error: new InvalidStatusWordError(\"user cancelled\"),\n }),\n );\n });\n\n it(\"returns InvalidStatusWordError when the final response carries no hmac_name\", async () => {\n const api = makeApiMock();\n api.sendCommand.mockResolvedValueOnce(CommandResultFactory({ data: {} }));\n\n const result = await new SendRenameContactTask(api, {\n previousContactName: \"Alice\",\n newContactName: \"Bob\",\n groupHandle: GROUP_HANDLE,\n hmacProof: HMAC_PROOF_IN,\n }).run();\n\n expect(result.status).not.toBe(undefined);\n if (\"error\" in result) {\n expect(result.error).toBeInstanceOf(InvalidStatusWordError);\n }\n });\n});\n"],
5
+ "mappings": "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",
6
+ "names": ["import_device_management_kit", "import_RenameContactCommand", "import_SendRenameContactTask", "hexToBytes", "hex", "out", "i", "GROUP_HANDLE", "HMAC_PROOF_IN", "HMAC_PROOF_OUT", "DERIVATION_PATH_TLV", "FRAMED_CHUNK", "makeApiMock", "api", "result", "command", "framedHex"]
7
+ }
@@ -1,2 +1,2 @@
1
- "use strict";var i=require("./app-binder/ContactsAppBinder"),a=require("./app-binder/di/appBinderTypes"),o=require("./di"),t=require("./externalTypes"),p=require("./use-cases/di/useCaseTypes"),m=require("./use-cases/RegisterExternalAddressUseCase");describe("makeContainer",()=>{const s={},n="session-id",r="Ethereum",e=(0,o.makeContainer)({dmk:s,sessionId:n,appName:r});it("binds dmk, sessionId and appName as external values",()=>{expect(e.get(t.externalTypes.Dmk)).toBe(s),expect(e.get(t.externalTypes.SessionId)).toBe(n),expect(e.get(t.externalTypes.AppName)).toBe(r)}),it("binds the ContactsAppBinder",()=>{expect(e.get(a.appBinderTypes.AppBinder)).toBeInstanceOf(i.ContactsAppBinder)}),it("binds the RegisterExternalAddressUseCase",()=>{expect(e.get(p.useCaseTypes.RegisterExternalAddressUseCase)).toBeInstanceOf(m.RegisterExternalAddressUseCase)})});
1
+ "use strict";var i=require("./app-binder/ContactsAppBinder"),r=require("./app-binder/di/appBinderTypes"),p=require("./di"),t=require("./externalTypes"),s=require("./use-cases/di/useCaseTypes"),m=require("./use-cases/RegisterExternalAddressUseCase"),c=require("./use-cases/RenameContactUseCase");describe("makeContainer",()=>{const n={},a="session-id",o="Ethereum",e=(0,p.makeContainer)({dmk:n,sessionId:a,appName:o});it("binds dmk, sessionId and appName as external values",()=>{expect(e.get(t.externalTypes.Dmk)).toBe(n),expect(e.get(t.externalTypes.SessionId)).toBe(a),expect(e.get(t.externalTypes.AppName)).toBe(o)}),it("binds the ContactsAppBinder",()=>{expect(e.get(r.appBinderTypes.AppBinder)).toBeInstanceOf(i.ContactsAppBinder)}),it("binds the RegisterExternalAddressUseCase",()=>{expect(e.get(s.useCaseTypes.RegisterExternalAddressUseCase)).toBeInstanceOf(m.RegisterExternalAddressUseCase)}),it("binds the RenameContactUseCase",()=>{expect(e.get(s.useCaseTypes.RenameContactUseCase)).toBeInstanceOf(c.RenameContactUseCase)})});
2
2
  //# sourceMappingURL=di.test.js.map
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "version": 3,
3
3
  "sources": ["../../../src/internal/di.test.ts"],
4
- "sourcesContent": ["import { type DeviceManagementKit } from \"@ledgerhq/device-management-kit\";\n\nimport { ContactsAppBinder } from \"@internal/app-binder/ContactsAppBinder\";\nimport { appBinderTypes } from \"@internal/app-binder/di/appBinderTypes\";\nimport { makeContainer } from \"@internal/di\";\nimport { externalTypes } from \"@internal/externalTypes\";\nimport { useCaseTypes } from \"@internal/use-cases/di/useCaseTypes\";\nimport { RegisterExternalAddressUseCase } from \"@internal/use-cases/RegisterExternalAddressUseCase\";\n\ndescribe(\"makeContainer\", () => {\n const dmk = {} as DeviceManagementKit;\n const sessionId = \"session-id\";\n const appName = \"Ethereum\";\n\n const container = makeContainer({ dmk, sessionId, appName });\n\n it(\"binds dmk, sessionId and appName as external values\", () => {\n expect(container.get(externalTypes.Dmk)).toBe(dmk);\n expect(container.get(externalTypes.SessionId)).toBe(sessionId);\n expect(container.get(externalTypes.AppName)).toBe(appName);\n });\n\n it(\"binds the ContactsAppBinder\", () => {\n expect(container.get(appBinderTypes.AppBinder)).toBeInstanceOf(\n ContactsAppBinder,\n );\n });\n\n it(\"binds the RegisterExternalAddressUseCase\", () => {\n expect(\n container.get(useCaseTypes.RegisterExternalAddressUseCase),\n ).toBeInstanceOf(RegisterExternalAddressUseCase);\n });\n});\n"],
5
- "mappings": "aAEA,IAAAA,EAAkC,kDAClCC,EAA+B,kDAC/BC,EAA8B,wBAC9BC,EAA8B,mCAC9BC,EAA6B,+CAC7BC,EAA+C,8DAE/C,SAAS,gBAAiB,IAAM,CAC9B,MAAMC,EAAM,CAAC,EACPC,EAAY,aACZC,EAAU,WAEVC,KAAY,iBAAc,CAAE,IAAAH,EAAK,UAAAC,EAAW,QAAAC,CAAQ,CAAC,EAE3D,GAAG,sDAAuD,IAAM,CAC9D,OAAOC,EAAU,IAAI,gBAAc,GAAG,CAAC,EAAE,KAAKH,CAAG,EACjD,OAAOG,EAAU,IAAI,gBAAc,SAAS,CAAC,EAAE,KAAKF,CAAS,EAC7D,OAAOE,EAAU,IAAI,gBAAc,OAAO,CAAC,EAAE,KAAKD,CAAO,CAC3D,CAAC,EAED,GAAG,8BAA+B,IAAM,CACtC,OAAOC,EAAU,IAAI,iBAAe,SAAS,CAAC,EAAE,eAC9C,mBACF,CACF,CAAC,EAED,GAAG,2CAA4C,IAAM,CACnD,OACEA,EAAU,IAAI,eAAa,8BAA8B,CAC3D,EAAE,eAAe,gCAA8B,CACjD,CAAC,CACH,CAAC",
6
- "names": ["import_ContactsAppBinder", "import_appBinderTypes", "import_di", "import_externalTypes", "import_useCaseTypes", "import_RegisterExternalAddressUseCase", "dmk", "sessionId", "appName", "container"]
4
+ "sourcesContent": ["import { type DeviceManagementKit } from \"@ledgerhq/device-management-kit\";\n\nimport { ContactsAppBinder } from \"@internal/app-binder/ContactsAppBinder\";\nimport { appBinderTypes } from \"@internal/app-binder/di/appBinderTypes\";\nimport { makeContainer } from \"@internal/di\";\nimport { externalTypes } from \"@internal/externalTypes\";\nimport { useCaseTypes } from \"@internal/use-cases/di/useCaseTypes\";\nimport { RegisterExternalAddressUseCase } from \"@internal/use-cases/RegisterExternalAddressUseCase\";\nimport { RenameContactUseCase } from \"@internal/use-cases/RenameContactUseCase\";\n\ndescribe(\"makeContainer\", () => {\n const dmk = {} as DeviceManagementKit;\n const sessionId = \"session-id\";\n const appName = \"Ethereum\";\n\n const container = makeContainer({ dmk, sessionId, appName });\n\n it(\"binds dmk, sessionId and appName as external values\", () => {\n expect(container.get(externalTypes.Dmk)).toBe(dmk);\n expect(container.get(externalTypes.SessionId)).toBe(sessionId);\n expect(container.get(externalTypes.AppName)).toBe(appName);\n });\n\n it(\"binds the ContactsAppBinder\", () => {\n expect(container.get(appBinderTypes.AppBinder)).toBeInstanceOf(\n ContactsAppBinder,\n );\n });\n\n it(\"binds the RegisterExternalAddressUseCase\", () => {\n expect(\n container.get(useCaseTypes.RegisterExternalAddressUseCase),\n ).toBeInstanceOf(RegisterExternalAddressUseCase);\n });\n\n it(\"binds the RenameContactUseCase\", () => {\n expect(container.get(useCaseTypes.RenameContactUseCase)).toBeInstanceOf(\n RenameContactUseCase,\n );\n });\n});\n"],
5
+ "mappings": "aAEA,IAAAA,EAAkC,kDAClCC,EAA+B,kDAC/BC,EAA8B,wBAC9BC,EAA8B,mCAC9BC,EAA6B,+CAC7BC,EAA+C,8DAC/CC,EAAqC,oDAErC,SAAS,gBAAiB,IAAM,CAC9B,MAAMC,EAAM,CAAC,EACPC,EAAY,aACZC,EAAU,WAEVC,KAAY,iBAAc,CAAE,IAAAH,EAAK,UAAAC,EAAW,QAAAC,CAAQ,CAAC,EAE3D,GAAG,sDAAuD,IAAM,CAC9D,OAAOC,EAAU,IAAI,gBAAc,GAAG,CAAC,EAAE,KAAKH,CAAG,EACjD,OAAOG,EAAU,IAAI,gBAAc,SAAS,CAAC,EAAE,KAAKF,CAAS,EAC7D,OAAOE,EAAU,IAAI,gBAAc,OAAO,CAAC,EAAE,KAAKD,CAAO,CAC3D,CAAC,EAED,GAAG,8BAA+B,IAAM,CACtC,OAAOC,EAAU,IAAI,iBAAe,SAAS,CAAC,EAAE,eAC9C,mBACF,CACF,CAAC,EAED,GAAG,2CAA4C,IAAM,CACnD,OACEA,EAAU,IAAI,eAAa,8BAA8B,CAC3D,EAAE,eAAe,gCAA8B,CACjD,CAAC,EAED,GAAG,iCAAkC,IAAM,CACzC,OAAOA,EAAU,IAAI,eAAa,oBAAoB,CAAC,EAAE,eACvD,sBACF,CACF,CAAC,CACH,CAAC",
6
+ "names": ["import_ContactsAppBinder", "import_appBinderTypes", "import_di", "import_externalTypes", "import_useCaseTypes", "import_RegisterExternalAddressUseCase", "import_RenameContactUseCase", "dmk", "sessionId", "appName", "container"]
7
7
  }
@@ -0,0 +1,2 @@
1
+ "use strict";var i=Object.defineProperty;var d=Object.getOwnPropertyDescriptor;var f=Object.getOwnPropertyNames;var A=Object.prototype.hasOwnProperty;var l=(p,t)=>{for(var e in t)i(p,e,{get:t[e],enumerable:!0})},R=(p,t,e,n)=>{if(t&&typeof t=="object"||typeof t=="function")for(let r of f(t))!A.call(p,r)&&r!==e&&i(p,r,{get:()=>t[r],enumerable:!(n=d(t,r))||n.enumerable});return p};var T=p=>R(i({},"__esModule",{value:!0}),p),u=(p,t,e,n)=>{for(var r=n>1?void 0:n?d(t,e):t,a=p.length-1,c;a>=0;a--)(c=p[a])&&(r=(n?c(t,e,r):c(r))||r);return n&&r&&i(t,e,r),r},y=(p,t)=>(e,n)=>t(e,n,p);var j={};l(j,{RenameContactUseCase:()=>o});module.exports=T(j);var m=require("inversify"),B=require("../app-binder/di/appBinderTypes");let o=class{constructor(t){this.appBinder=t}execute(t){return this.appBinder.renameContact(t)}};o=u([(0,m.injectable)(),y(0,(0,m.inject)(B.appBinderTypes.AppBinder))],o);0&&(module.exports={RenameContactUseCase});
2
+ //# sourceMappingURL=RenameContactUseCase.js.map
@@ -0,0 +1,7 @@
1
+ {
2
+ "version": 3,
3
+ "sources": ["../../../../src/internal/use-cases/RenameContactUseCase.ts"],
4
+ "sourcesContent": ["import { inject, injectable } from \"inversify\";\n\nimport { type RenameContactDAReturnType } from \"@api/app-binder/RenameContactDeviceActionTypes\";\nimport { type RenameContactInput } from \"@api/model/RenameContact\";\nimport { ContactsAppBinder } from \"@internal/app-binder/ContactsAppBinder\";\nimport { appBinderTypes } from \"@internal/app-binder/di/appBinderTypes\";\n\n/**\n * Delegates to `ContactsAppBinder`, which uses its injected `dmk` and\n * `sessionId` to construct and execute the `RenameContactDeviceAction`. The\n * injected `appName` is not used: rename is a dashboard operation served by the\n * device OS, not the embedded app.\n *\n * Caller-input validation is intentionally NOT done here: the public API returns\n * a device action, so validation lives inside the device action and surfaces as\n * a typed terminal error state on the observable rather than a synchronous throw.\n */\n@injectable()\nexport class RenameContactUseCase {\n constructor(\n @inject(appBinderTypes.AppBinder)\n private readonly appBinder: ContactsAppBinder,\n ) {}\n\n execute(input: RenameContactInput): RenameContactDAReturnType {\n return this.appBinder.renameContact(input);\n }\n}\n"],
5
+ "mappings": "okBAAA,IAAAA,EAAA,GAAAC,EAAAD,EAAA,0BAAAE,IAAA,eAAAC,EAAAH,GAAA,IAAAI,EAAmC,qBAKnCC,EAA+B,kDAaxB,IAAMC,EAAN,KAA2B,CAChC,YAEmBC,EACjB,CADiB,eAAAA,CAChB,CAEH,QAAQC,EAAsD,CAC5D,OAAO,KAAK,UAAU,cAAcA,CAAK,CAC3C,CACF,EATaF,EAANG,EAAA,IADN,cAAW,EAGPC,EAAA,eAAO,iBAAe,SAAS,IAFvBJ",
6
+ "names": ["RenameContactUseCase_exports", "__export", "RenameContactUseCase", "__toCommonJS", "import_inversify", "import_appBinderTypes", "RenameContactUseCase", "appBinder", "input", "__decorateClass", "__decorateParam"]
7
+ }
@@ -0,0 +1,2 @@
1
+ "use strict";var c=require("./RenameContactUseCase");function o(){const e=vi.fn().mockReturnValue("DA_RETURN"),t={renameContact:e};return{useCase:new c.RenameContactUseCase(t),renameContact:e}}const a={previousContactName:"Alice",newContactName:"Bob",groupHandle:new Uint8Array(64).fill(204),hmacProof:new Uint8Array(32).fill(221)};describe("RenameContactUseCase",()=>{it("delegates to the app binder",()=>{const{useCase:e,renameContact:t}=o(),n=e.execute(a);expect(t).toHaveBeenCalledWith(a),expect(n).toBe("DA_RETURN")}),it("does not validate \u2014 invalid input is forwarded, not thrown",()=>{const{useCase:e,renameContact:t}=o(),n={...a,newContactName:""};expect(()=>e.execute(n)).not.toThrow(),expect(t).toHaveBeenCalledWith(n)})});
2
+ //# sourceMappingURL=RenameContactUseCase.test.js.map
@@ -0,0 +1,7 @@
1
+ {
2
+ "version": 3,
3
+ "sources": ["../../../../src/internal/use-cases/RenameContactUseCase.test.ts"],
4
+ "sourcesContent": ["import { type RenameContactInput } from \"@api/model/RenameContact\";\nimport { type ContactsAppBinder } from \"@internal/app-binder/ContactsAppBinder\";\n\nimport { RenameContactUseCase } from \"./RenameContactUseCase\";\n\nfunction makeUseCase() {\n const renameContact = vi.fn().mockReturnValue(\"DA_RETURN\");\n const appBinder = { renameContact } as unknown as ContactsAppBinder;\n return {\n useCase: new RenameContactUseCase(appBinder),\n renameContact,\n };\n}\n\nconst VALID_INPUT: RenameContactInput = {\n previousContactName: \"Alice\",\n newContactName: \"Bob\",\n groupHandle: new Uint8Array(64).fill(0xcc),\n hmacProof: new Uint8Array(32).fill(0xdd),\n};\n\ndescribe(\"RenameContactUseCase\", () => {\n it(\"delegates to the app binder\", () => {\n const { useCase, renameContact } = makeUseCase();\n\n const result = useCase.execute(VALID_INPUT);\n\n expect(renameContact).toHaveBeenCalledWith(VALID_INPUT);\n expect(result).toBe(\"DA_RETURN\");\n });\n\n it(\"does not validate \u2014 invalid input is forwarded, not thrown\", () => {\n // Validation lives in the device action and surfaces as a typed DA error\n // state; the use case must never throw for bad input.\n const { useCase, renameContact } = makeUseCase();\n\n const invalidInput = { ...VALID_INPUT, newContactName: \"\" };\n expect(() => useCase.execute(invalidInput)).not.toThrow();\n expect(renameContact).toHaveBeenCalledWith(invalidInput);\n });\n});\n"],
5
+ "mappings": "aAGA,IAAAA,EAAqC,kCAErC,SAASC,GAAc,CACrB,MAAMC,EAAgB,GAAG,GAAG,EAAE,gBAAgB,WAAW,EACnDC,EAAY,CAAE,cAAAD,CAAc,EAClC,MAAO,CACL,QAAS,IAAI,uBAAqBC,CAAS,EAC3C,cAAAD,CACF,CACF,CAEA,MAAME,EAAkC,CACtC,oBAAqB,QACrB,eAAgB,MAChB,YAAa,IAAI,WAAW,EAAE,EAAE,KAAK,GAAI,EACzC,UAAW,IAAI,WAAW,EAAE,EAAE,KAAK,GAAI,CACzC,EAEA,SAAS,uBAAwB,IAAM,CACrC,GAAG,8BAA+B,IAAM,CACtC,KAAM,CAAE,QAAAC,EAAS,cAAAH,CAAc,EAAID,EAAY,EAEzCK,EAASD,EAAQ,QAAQD,CAAW,EAE1C,OAAOF,CAAa,EAAE,qBAAqBE,CAAW,EACtD,OAAOE,CAAM,EAAE,KAAK,WAAW,CACjC,CAAC,EAED,GAAG,kEAA8D,IAAM,CAGrE,KAAM,CAAE,QAAAD,EAAS,cAAAH,CAAc,EAAID,EAAY,EAEzCM,EAAe,CAAE,GAAGH,EAAa,eAAgB,EAAG,EAC1D,OAAO,IAAMC,EAAQ,QAAQE,CAAY,CAAC,EAAE,IAAI,QAAQ,EACxD,OAAOL,CAAa,EAAE,qBAAqBK,CAAY,CACzD,CAAC,CACH,CAAC",
6
+ "names": ["import_RenameContactUseCase", "makeUseCase", "renameContact", "appBinder", "VALID_INPUT", "useCase", "result", "invalidInput"]
7
+ }
@@ -1,2 +1,2 @@
1
- "use strict";var t=Object.defineProperty;var n=Object.getOwnPropertyDescriptor;var p=Object.getOwnPropertyNames;var C=Object.prototype.hasOwnProperty;var l=(e,s)=>{for(var o in s)t(e,o,{get:s[o],enumerable:!0})},u=(e,s,o,a)=>{if(s&&typeof s=="object"||typeof s=="function")for(let r of p(s))!C.call(e,r)&&r!==o&&t(e,r,{get:()=>s[r],enumerable:!(a=n(s,r))||a.enumerable});return e};var f=e=>u(t({},"__esModule",{value:!0}),e);var c={};l(c,{useCaseModuleFactory:()=>x});module.exports=f(c);var d=require("inversify"),i=require("../../use-cases/RegisterExternalAddressUseCase"),m=require("./useCaseTypes");const x=()=>new d.ContainerModule(({bind:e})=>{e(m.useCaseTypes.RegisterExternalAddressUseCase).to(i.RegisterExternalAddressUseCase)});0&&(module.exports={useCaseModuleFactory});
1
+ "use strict";var r=Object.defineProperty;var p=Object.getOwnPropertyDescriptor;var d=Object.getOwnPropertyNames;var c=Object.prototype.hasOwnProperty;var f=(e,s)=>{for(var t in s)r(e,t,{get:s[t],enumerable:!0})},l=(e,s,t,m)=>{if(s&&typeof s=="object"||typeof s=="function")for(let o of d(s))!c.call(e,o)&&o!==t&&r(e,o,{get:()=>s[o],enumerable:!(m=p(s,o))||m.enumerable});return e};var u=e=>l(r({},"__esModule",{value:!0}),e);var U={};f(U,{useCaseModuleFactory:()=>R});module.exports=u(U);var n=require("inversify"),C=require("../../use-cases/RegisterExternalAddressUseCase"),i=require("../../use-cases/RenameContactUseCase"),a=require("./useCaseTypes");const R=()=>new n.ContainerModule(({bind:e})=>{e(a.useCaseTypes.RegisterExternalAddressUseCase).to(C.RegisterExternalAddressUseCase),e(a.useCaseTypes.RenameContactUseCase).to(i.RenameContactUseCase)});0&&(module.exports={useCaseModuleFactory});
2
2
  //# sourceMappingURL=useCaseModule.js.map
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "version": 3,
3
3
  "sources": ["../../../../../src/internal/use-cases/di/useCaseModule.ts"],
4
- "sourcesContent": ["import { ContainerModule } from \"inversify\";\n\nimport { RegisterExternalAddressUseCase } from \"@internal/use-cases/RegisterExternalAddressUseCase\";\n\nimport { useCaseTypes } from \"./useCaseTypes\";\n\nexport const useCaseModuleFactory = () =>\n new ContainerModule(({ bind }) => {\n bind(useCaseTypes.RegisterExternalAddressUseCase).to(\n RegisterExternalAddressUseCase,\n );\n });\n"],
5
- "mappings": "yaAAA,IAAAA,EAAA,GAAAC,EAAAD,EAAA,0BAAAE,IAAA,eAAAC,EAAAH,GAAA,IAAAI,EAAgC,qBAEhCC,EAA+C,8DAE/CC,EAA6B,0BAEtB,MAAMJ,EAAuB,IAClC,IAAI,kBAAgB,CAAC,CAAE,KAAAK,CAAK,IAAM,CAChCA,EAAK,eAAa,8BAA8B,EAAE,GAChD,gCACF,CACF,CAAC",
6
- "names": ["useCaseModule_exports", "__export", "useCaseModuleFactory", "__toCommonJS", "import_inversify", "import_RegisterExternalAddressUseCase", "import_useCaseTypes", "bind"]
4
+ "sourcesContent": ["import { ContainerModule } from \"inversify\";\n\nimport { RegisterExternalAddressUseCase } from \"@internal/use-cases/RegisterExternalAddressUseCase\";\nimport { RenameContactUseCase } from \"@internal/use-cases/RenameContactUseCase\";\n\nimport { useCaseTypes } from \"./useCaseTypes\";\n\nexport const useCaseModuleFactory = () =>\n new ContainerModule(({ bind }) => {\n bind(useCaseTypes.RegisterExternalAddressUseCase).to(\n RegisterExternalAddressUseCase,\n );\n bind(useCaseTypes.RenameContactUseCase).to(RenameContactUseCase);\n });\n"],
5
+ "mappings": "yaAAA,IAAAA,EAAA,GAAAC,EAAAD,EAAA,0BAAAE,IAAA,eAAAC,EAAAH,GAAA,IAAAI,EAAgC,qBAEhCC,EAA+C,8DAC/CC,EAAqC,oDAErCC,EAA6B,0BAEtB,MAAML,EAAuB,IAClC,IAAI,kBAAgB,CAAC,CAAE,KAAAM,CAAK,IAAM,CAChCA,EAAK,eAAa,8BAA8B,EAAE,GAChD,gCACF,EACAA,EAAK,eAAa,oBAAoB,EAAE,GAAG,sBAAoB,CACjE,CAAC",
6
+ "names": ["useCaseModule_exports", "__export", "useCaseModuleFactory", "__toCommonJS", "import_inversify", "import_RegisterExternalAddressUseCase", "import_RenameContactUseCase", "import_useCaseTypes", "bind"]
7
7
  }
@@ -1,2 +1,2 @@
1
- "use strict";var a=Object.defineProperty;var d=Object.getOwnPropertyDescriptor;var n=Object.getOwnPropertyNames;var l=Object.prototype.hasOwnProperty;var x=(s,e)=>{for(var t in e)a(s,t,{get:e[t],enumerable:!0})},C=(s,e,t,o)=>{if(e&&typeof e=="object"||typeof e=="function")for(let r of n(e))!l.call(s,r)&&r!==t&&a(s,r,{get:()=>e[r],enumerable:!(o=d(e,r))||o.enumerable});return s};var c=s=>C(a({},"__esModule",{value:!0}),s);var i={};x(i,{useCaseTypes:()=>g});module.exports=c(i);const g={RegisterExternalAddressUseCase:Symbol.for("RegisterExternalAddressUseCase")};0&&(module.exports={useCaseTypes});
1
+ "use strict";var o=Object.defineProperty;var n=Object.getOwnPropertyDescriptor;var C=Object.getOwnPropertyNames;var c=Object.prototype.hasOwnProperty;var d=(s,e)=>{for(var t in e)o(s,t,{get:e[t],enumerable:!0})},l=(s,e,t,r)=>{if(e&&typeof e=="object"||typeof e=="function")for(let a of C(e))!c.call(s,a)&&a!==t&&o(s,a,{get:()=>e[a],enumerable:!(r=n(e,a))||r.enumerable});return s};var m=s=>l(o({},"__esModule",{value:!0}),s);var U={};d(U,{useCaseTypes:()=>R});module.exports=m(U);const R={RegisterExternalAddressUseCase:Symbol.for("RegisterExternalAddressUseCase"),RenameContactUseCase:Symbol.for("RenameContactUseCase")};0&&(module.exports={useCaseTypes});
2
2
  //# sourceMappingURL=useCaseTypes.js.map
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "version": 3,
3
3
  "sources": ["../../../../../src/internal/use-cases/di/useCaseTypes.ts"],
4
- "sourcesContent": ["export const useCaseTypes = {\n RegisterExternalAddressUseCase: Symbol.for(\"RegisterExternalAddressUseCase\"),\n} as const;\n"],
5
- "mappings": "yaAAA,IAAAA,EAAA,GAAAC,EAAAD,EAAA,kBAAAE,IAAA,eAAAC,EAAAH,GAAO,MAAME,EAAe,CAC1B,+BAAgC,OAAO,IAAI,gCAAgC,CAC7E",
4
+ "sourcesContent": ["export const useCaseTypes = {\n RegisterExternalAddressUseCase: Symbol.for(\"RegisterExternalAddressUseCase\"),\n RenameContactUseCase: Symbol.for(\"RenameContactUseCase\"),\n} as const;\n"],
5
+ "mappings": "yaAAA,IAAAA,EAAA,GAAAC,EAAAD,EAAA,kBAAAE,IAAA,eAAAC,EAAAH,GAAO,MAAME,EAAe,CAC1B,+BAAgC,OAAO,IAAI,gCAAgC,EAC3E,qBAAsB,OAAO,IAAI,sBAAsB,CACzD",
6
6
  "names": ["useCaseTypes_exports", "__export", "useCaseTypes", "__toCommonJS"]
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-20260828024102"
61
+ "version": "0.0.0-develop-20260829001241"
62
62
  }
@@ -0,0 +1 @@
1
+ //# sourceMappingURL=RenameContactDeviceActionTypes.js.map
@@ -0,0 +1,7 @@
1
+ {
2
+ "version": 3,
3
+ "sources": [],
4
+ "sourcesContent": [],
5
+ "mappings": "",
6
+ "names": []
7
+ }
@@ -1,2 +1,2 @@
1
- import{ContactsManagerBuilder as r}from"./ContactsManagerBuilder";import{CONTACTS_VERSION_REQUIREMENTS as n,ETHEREUM_APP_NAME as p,isContactsSupported as o,isVersionAtLeast as a,resolveContactsVersionRequirements as d}from"./model/ContactsVersionRequirements";export{n as CONTACTS_VERSION_REQUIREMENTS,r as ContactsManagerBuilder,p as ETHEREUM_APP_NAME,o as isContactsSupported,a as isVersionAtLeast,d as resolveContactsVersionRequirements};
1
+ import{ContactsManagerBuilder as r}from"./ContactsManagerBuilder";import{CONTACTS_VERSION_REQUIREMENTS as p,ETHEREUM_APP_NAME as a,isContactsSupported as o,isVersionAtLeast as s,resolveContactsVersionRequirements as d}from"./model/ContactsVersionRequirements";export{p as CONTACTS_VERSION_REQUIREMENTS,r as ContactsManagerBuilder,a as ETHEREUM_APP_NAME,o as isContactsSupported,s as isVersionAtLeast,d as resolveContactsVersionRequirements};
2
2
  //# sourceMappingURL=index.js.map
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "version": 3,
3
3
  "sources": ["../../../src/api/index.ts"],
4
- "sourcesContent": ["export {\n type RegisterExternalAddressDAError,\n type RegisterExternalAddressDAInput,\n type RegisterExternalAddressDAIntermediateValue,\n type RegisterExternalAddressDAOutput,\n type RegisterExternalAddressDARequiredInteraction,\n type RegisterExternalAddressDAReturnType,\n type RegisterExternalAddressDAState,\n} from \"@api/app-binder/RegisterExternalAddressDeviceActionTypes\";\nexport { type ContactsManager } from \"@api/ContactsManager\";\nexport { ContactsManagerBuilder } from \"@api/ContactsManagerBuilder\";\nexport {\n CONTACTS_VERSION_REQUIREMENTS,\n type ContactsModelRequirement,\n type ContactsModelSupport,\n type ContactsModelUnsupported,\n type ContactsSupportQuery,\n type ContactsVersionRequirements,\n ETHEREUM_APP_NAME,\n isContactsSupported,\n isVersionAtLeast,\n resolveContactsVersionRequirements,\n} from \"@api/model/ContactsVersionRequirements\";\nexport {\n type ExistingContactGroup,\n type RegisterExternalAddressInput,\n type RegisterExternalAddressMode,\n type RegisterExternalAddressOutput,\n} from \"@api/model/RegisterExternalAddress\";\n"],
5
- "mappings": "AAUA,OAAS,0BAAAA,MAA8B,8BACvC,OACE,iCAAAC,EAMA,qBAAAC,EACA,uBAAAC,EACA,oBAAAC,EACA,sCAAAC,MACK",
4
+ "sourcesContent": ["export {\n type RegisterExternalAddressDAError,\n type RegisterExternalAddressDAInput,\n type RegisterExternalAddressDAIntermediateValue,\n type RegisterExternalAddressDAOutput,\n type RegisterExternalAddressDARequiredInteraction,\n type RegisterExternalAddressDAReturnType,\n type RegisterExternalAddressDAState,\n} from \"@api/app-binder/RegisterExternalAddressDeviceActionTypes\";\nexport {\n type RenameContactDAError,\n type RenameContactDAInput,\n type RenameContactDAIntermediateValue,\n type RenameContactDAOutput,\n type RenameContactDARequiredInteraction,\n type RenameContactDAReturnType,\n type RenameContactDAState,\n} from \"@api/app-binder/RenameContactDeviceActionTypes\";\nexport { type ContactsManager } from \"@api/ContactsManager\";\nexport { ContactsManagerBuilder } from \"@api/ContactsManagerBuilder\";\nexport {\n CONTACTS_VERSION_REQUIREMENTS,\n type ContactsModelRequirement,\n type ContactsModelSupport,\n type ContactsModelUnsupported,\n type ContactsSupportQuery,\n type ContactsVersionRequirements,\n ETHEREUM_APP_NAME,\n isContactsSupported,\n isVersionAtLeast,\n resolveContactsVersionRequirements,\n} from \"@api/model/ContactsVersionRequirements\";\nexport {\n type ExistingContactGroup,\n type RegisterExternalAddressInput,\n type RegisterExternalAddressMode,\n type RegisterExternalAddressOutput,\n} from \"@api/model/RegisterExternalAddress\";\nexport {\n type RenameContactInput,\n type RenameContactOutput,\n} from \"@api/model/RenameContact\";\n"],
5
+ "mappings": "AAmBA,OAAS,0BAAAA,MAA8B,8BACvC,OACE,iCAAAC,EAMA,qBAAAC,EACA,uBAAAC,EACA,oBAAAC,EACA,sCAAAC,MACK",
6
6
  "names": ["ContactsManagerBuilder", "CONTACTS_VERSION_REQUIREMENTS", "ETHEREUM_APP_NAME", "isContactsSupported", "isVersionAtLeast", "resolveContactsVersionRequirements"]
7
7
  }
@@ -0,0 +1 @@
1
+ //# sourceMappingURL=RenameContact.js.map
@@ -0,0 +1,7 @@
1
+ {
2
+ "version": 3,
3
+ "sources": [],
4
+ "sourcesContent": [],
5
+ "mappings": "",
6
+ "names": []
7
+ }
@@ -1,2 +1,2 @@
1
- import{makeContainer as s}from"./di";import{useCaseTypes as n}from"./use-cases/di/useCaseTypes";class p{_container;constructor({dmk:e,sessionId:t,appName:r}){this._container=s({dmk:e,sessionId:t,appName:r})}registerExternalAddress(e){return this._container.get(n.RegisterExternalAddressUseCase).execute(e)}get container(){return this._container}}export{p as DefaultContactsManager};
1
+ import{makeContainer as a}from"./di";import{useCaseTypes as t}from"./use-cases/di/useCaseTypes";class m{_container;constructor({dmk:e,sessionId:r,appName:n}){this._container=a({dmk:e,sessionId:r,appName:n})}registerExternalAddress(e){return this._container.get(t.RegisterExternalAddressUseCase).execute(e)}renameContact(e){return this._container.get(t.RenameContactUseCase).execute(e)}get container(){return this._container}}export{m as DefaultContactsManager};
2
2
  //# sourceMappingURL=DefaultContactsManager.js.map
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "version": 3,
3
3
  "sources": ["../../../src/internal/DefaultContactsManager.ts"],
4
- "sourcesContent": ["import {\n type DeviceManagementKit,\n type DeviceSessionId,\n} from \"@ledgerhq/device-management-kit\";\nimport { type Container } from \"inversify\";\n\nimport { type RegisterExternalAddressDAReturnType } from \"@api/app-binder/RegisterExternalAddressDeviceActionTypes\";\nimport { type ContactsManager } from \"@api/ContactsManager\";\nimport { type RegisterExternalAddressInput } from \"@api/model/RegisterExternalAddress\";\nimport { makeContainer } from \"@internal/di\";\nimport { useCaseTypes } from \"@internal/use-cases/di/useCaseTypes\";\nimport { type RegisterExternalAddressUseCase } from \"@internal/use-cases/RegisterExternalAddressUseCase\";\n\ntype DefaultContactsManagerConstructorArgs = {\n dmk: DeviceManagementKit;\n sessionId: DeviceSessionId;\n appName: string;\n};\n\nexport class DefaultContactsManager implements ContactsManager {\n private readonly _container: Container;\n\n constructor({\n dmk,\n sessionId,\n appName,\n }: DefaultContactsManagerConstructorArgs) {\n this._container = makeContainer({ dmk, sessionId, appName });\n }\n\n registerExternalAddress(\n input: RegisterExternalAddressInput,\n ): RegisterExternalAddressDAReturnType {\n return this._container\n .get<RegisterExternalAddressUseCase>(\n useCaseTypes.RegisterExternalAddressUseCase,\n )\n .execute(input);\n }\n\n /**\n * Exposes the DI container so future operation methods can resolve their\n * `UseCase`. Not part of the public API.\n */\n protected get container(): Container {\n return this._container;\n }\n}\n"],
5
- "mappings": "AASA,OAAS,iBAAAA,MAAqB,eAC9B,OAAS,gBAAAC,MAAoB,sCAStB,MAAMC,CAAkD,CAC5C,WAEjB,YAAY,CACV,IAAAC,EACA,UAAAC,EACA,QAAAC,CACF,EAA0C,CACxC,KAAK,WAAaL,EAAc,CAAE,IAAAG,EAAK,UAAAC,EAAW,QAAAC,CAAQ,CAAC,CAC7D,CAEA,wBACEC,EACqC,CACrC,OAAO,KAAK,WACT,IACCL,EAAa,8BACf,EACC,QAAQK,CAAK,CAClB,CAMA,IAAc,WAAuB,CACnC,OAAO,KAAK,UACd,CACF",
4
+ "sourcesContent": ["import {\n type DeviceManagementKit,\n type DeviceSessionId,\n} from \"@ledgerhq/device-management-kit\";\nimport { type Container } from \"inversify\";\n\nimport { type RegisterExternalAddressDAReturnType } from \"@api/app-binder/RegisterExternalAddressDeviceActionTypes\";\nimport { type RenameContactDAReturnType } from \"@api/app-binder/RenameContactDeviceActionTypes\";\nimport { type ContactsManager } from \"@api/ContactsManager\";\nimport { type RegisterExternalAddressInput } from \"@api/model/RegisterExternalAddress\";\nimport { type RenameContactInput } from \"@api/model/RenameContact\";\nimport { makeContainer } from \"@internal/di\";\nimport { useCaseTypes } from \"@internal/use-cases/di/useCaseTypes\";\nimport { type RegisterExternalAddressUseCase } from \"@internal/use-cases/RegisterExternalAddressUseCase\";\nimport { type RenameContactUseCase } from \"@internal/use-cases/RenameContactUseCase\";\n\ntype DefaultContactsManagerConstructorArgs = {\n dmk: DeviceManagementKit;\n sessionId: DeviceSessionId;\n appName: string;\n};\n\nexport class DefaultContactsManager implements ContactsManager {\n private readonly _container: Container;\n\n constructor({\n dmk,\n sessionId,\n appName,\n }: DefaultContactsManagerConstructorArgs) {\n this._container = makeContainer({ dmk, sessionId, appName });\n }\n\n registerExternalAddress(\n input: RegisterExternalAddressInput,\n ): RegisterExternalAddressDAReturnType {\n return this._container\n .get<RegisterExternalAddressUseCase>(\n useCaseTypes.RegisterExternalAddressUseCase,\n )\n .execute(input);\n }\n\n renameContact(input: RenameContactInput): RenameContactDAReturnType {\n return this._container\n .get<RenameContactUseCase>(useCaseTypes.RenameContactUseCase)\n .execute(input);\n }\n\n /**\n * Exposes the DI container so future operation methods can resolve their\n * `UseCase`. Not part of the public API.\n */\n protected get container(): Container {\n return this._container;\n }\n}\n"],
5
+ "mappings": "AAWA,OAAS,iBAAAA,MAAqB,eAC9B,OAAS,gBAAAC,MAAoB,sCAUtB,MAAMC,CAAkD,CAC5C,WAEjB,YAAY,CACV,IAAAC,EACA,UAAAC,EACA,QAAAC,CACF,EAA0C,CACxC,KAAK,WAAaL,EAAc,CAAE,IAAAG,EAAK,UAAAC,EAAW,QAAAC,CAAQ,CAAC,CAC7D,CAEA,wBACEC,EACqC,CACrC,OAAO,KAAK,WACT,IACCL,EAAa,8BACf,EACC,QAAQK,CAAK,CAClB,CAEA,cAAcA,EAAsD,CAClE,OAAO,KAAK,WACT,IAA0BL,EAAa,oBAAoB,EAC3D,QAAQK,CAAK,CAClB,CAMA,IAAc,WAAuB,CACnC,OAAO,KAAK,UACd,CACF",
6
6
  "names": ["makeContainer", "useCaseTypes", "DefaultContactsManager", "dmk", "sessionId", "appName", "input"]
7
7
  }
@@ -1,2 +1,2 @@
1
- import{DefaultContactsManager as i}from"./DefaultContactsManager";const a={contactName:"Alice",scope:"Eth main",identifier:new Uint8Array(20).fill(17),blockchainFamily:"ethereum",chainId:1n};describe("DefaultContactsManager",()=>{it("registerExternalAddress flows manager -> use-case -> binder -> dmk.executeDeviceAction",()=>{const e=vi.fn().mockReturnValue("DA_RETURN"),t={executeDeviceAction:e},c=new i({dmk:t,sessionId:"session-id",appName:"Ethereum"}).registerExternalAddress(a);expect(e).toHaveBeenCalledTimes(1);const s=e.mock.calls[0][0];expect(s.sessionId).toBe("session-id"),expect(s.deviceAction).toBeDefined(),expect(c).toBe("DA_RETURN")}),it("does not throw on invalid input \u2014 it dispatches the device action, which surfaces the error",()=>{const e=vi.fn().mockReturnValue("DA_RETURN"),t={executeDeviceAction:e},n=new i({dmk:t,sessionId:"session-id",appName:"Ethereum"});expect(()=>n.registerExternalAddress({...a,contactName:""})).not.toThrow(),expect(e).toHaveBeenCalledTimes(1)})});
1
+ import{DefaultContactsManager as i}from"./DefaultContactsManager";const o={contactName:"Alice",scope:"Eth main",identifier:new Uint8Array(20).fill(17),blockchainFamily:"ethereum",chainId:1n},c={previousContactName:"Alice",newContactName:"Bob",groupHandle:new Uint8Array(64).fill(204),hmacProof:new Uint8Array(32).fill(221)};describe("DefaultContactsManager",()=>{it("registerExternalAddress flows manager -> use-case -> binder -> dmk.executeDeviceAction",()=>{const e=vi.fn().mockReturnValue("DA_RETURN"),n={executeDeviceAction:e},a=new i({dmk:n,sessionId:"session-id",appName:"Ethereum"}).registerExternalAddress(o);expect(e).toHaveBeenCalledTimes(1);const t=e.mock.calls[0][0];expect(t.sessionId).toBe("session-id"),expect(t.deviceAction).toBeDefined(),expect(a).toBe("DA_RETURN")}),it("does not throw on invalid input \u2014 it dispatches the device action, which surfaces the error",()=>{const e=vi.fn().mockReturnValue("DA_RETURN"),n={executeDeviceAction:e},s=new i({dmk:n,sessionId:"session-id",appName:"Ethereum"});expect(()=>s.registerExternalAddress({...o,contactName:""})).not.toThrow(),expect(e).toHaveBeenCalledTimes(1)}),it("renameContact flows manager -> use-case -> binder -> dmk.executeDeviceAction",()=>{const e=vi.fn().mockReturnValue("DA_RETURN"),n={executeDeviceAction:e},a=new i({dmk:n,sessionId:"session-id",appName:"Ethereum"}).renameContact(c);expect(e).toHaveBeenCalledTimes(1);const t=e.mock.calls[0][0];expect(t.sessionId).toBe("session-id"),expect(t.deviceAction).toBeDefined(),expect(a).toBe("DA_RETURN")})});
2
2
  //# sourceMappingURL=DefaultContactsManager.test.js.map
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "version": 3,
3
3
  "sources": ["../../../src/internal/DefaultContactsManager.test.ts"],
4
- "sourcesContent": ["import { type DeviceManagementKit } from \"@ledgerhq/device-management-kit\";\n\nimport { type RegisterExternalAddressInput } from \"@api/model/RegisterExternalAddress\";\n\nimport { DefaultContactsManager } from \"./DefaultContactsManager\";\n\nconst VALID_INPUT: RegisterExternalAddressInput = {\n contactName: \"Alice\",\n scope: \"Eth main\",\n identifier: new Uint8Array(20).fill(0x11),\n blockchainFamily: \"ethereum\",\n chainId: 1n,\n};\n\ndescribe(\"DefaultContactsManager\", () => {\n it(\"registerExternalAddress flows manager -> use-case -> binder -> dmk.executeDeviceAction\", () => {\n const executeDeviceAction = vi.fn().mockReturnValue(\"DA_RETURN\");\n const dmk = { executeDeviceAction } as unknown as DeviceManagementKit;\n\n const manager = new DefaultContactsManager({\n dmk,\n sessionId: \"session-id\",\n appName: \"Ethereum\",\n });\n\n const result = manager.registerExternalAddress(VALID_INPUT);\n\n expect(executeDeviceAction).toHaveBeenCalledTimes(1);\n const call = executeDeviceAction.mock.calls[0]![0] as {\n sessionId: string;\n deviceAction: unknown;\n };\n expect(call.sessionId).toBe(\"session-id\");\n expect(call.deviceAction).toBeDefined();\n expect(result).toBe(\"DA_RETURN\");\n });\n\n it(\"does not throw on invalid input \u2014 it dispatches the device action, which surfaces the error\", () => {\n // The public API returns a device action; invalid caller input must reach\n // the observable as a typed error state rather than throwing synchronously.\n const executeDeviceAction = vi.fn().mockReturnValue(\"DA_RETURN\");\n const dmk = { executeDeviceAction } as unknown as DeviceManagementKit;\n\n const manager = new DefaultContactsManager({\n dmk,\n sessionId: \"session-id\",\n appName: \"Ethereum\",\n });\n\n expect(() =>\n manager.registerExternalAddress({\n ...VALID_INPUT,\n contactName: \"\",\n }),\n ).not.toThrow();\n expect(executeDeviceAction).toHaveBeenCalledTimes(1);\n });\n});\n"],
5
- "mappings": "AAIA,OAAS,0BAAAA,MAA8B,2BAEvC,MAAMC,EAA4C,CAChD,YAAa,QACb,MAAO,WACP,WAAY,IAAI,WAAW,EAAE,EAAE,KAAK,EAAI,EACxC,iBAAkB,WAClB,QAAS,EACX,EAEA,SAAS,yBAA0B,IAAM,CACvC,GAAG,yFAA0F,IAAM,CACjG,MAAMC,EAAsB,GAAG,GAAG,EAAE,gBAAgB,WAAW,EACzDC,EAAM,CAAE,oBAAAD,CAAoB,EAQ5BE,EANU,IAAIJ,EAAuB,CACzC,IAAAG,EACA,UAAW,aACX,QAAS,UACX,CAAC,EAEsB,wBAAwBF,CAAW,EAE1D,OAAOC,CAAmB,EAAE,sBAAsB,CAAC,EACnD,MAAMG,EAAOH,EAAoB,KAAK,MAAM,CAAC,EAAG,CAAC,EAIjD,OAAOG,EAAK,SAAS,EAAE,KAAK,YAAY,EACxC,OAAOA,EAAK,YAAY,EAAE,YAAY,EACtC,OAAOD,CAAM,EAAE,KAAK,WAAW,CACjC,CAAC,EAED,GAAG,mGAA+F,IAAM,CAGtG,MAAMF,EAAsB,GAAG,GAAG,EAAE,gBAAgB,WAAW,EACzDC,EAAM,CAAE,oBAAAD,CAAoB,EAE5BI,EAAU,IAAIN,EAAuB,CACzC,IAAAG,EACA,UAAW,aACX,QAAS,UACX,CAAC,EAED,OAAO,IACLG,EAAQ,wBAAwB,CAC9B,GAAGL,EACH,YAAa,EACf,CAAC,CACH,EAAE,IAAI,QAAQ,EACd,OAAOC,CAAmB,EAAE,sBAAsB,CAAC,CACrD,CAAC,CACH,CAAC",
6
- "names": ["DefaultContactsManager", "VALID_INPUT", "executeDeviceAction", "dmk", "result", "call", "manager"]
4
+ "sourcesContent": ["import { type DeviceManagementKit } from \"@ledgerhq/device-management-kit\";\n\nimport { type RegisterExternalAddressInput } from \"@api/model/RegisterExternalAddress\";\nimport { type RenameContactInput } from \"@api/model/RenameContact\";\n\nimport { DefaultContactsManager } from \"./DefaultContactsManager\";\n\nconst VALID_INPUT: RegisterExternalAddressInput = {\n contactName: \"Alice\",\n scope: \"Eth main\",\n identifier: new Uint8Array(20).fill(0x11),\n blockchainFamily: \"ethereum\",\n chainId: 1n,\n};\n\nconst VALID_RENAME_INPUT: RenameContactInput = {\n previousContactName: \"Alice\",\n newContactName: \"Bob\",\n groupHandle: new Uint8Array(64).fill(0xcc),\n hmacProof: new Uint8Array(32).fill(0xdd),\n};\n\ndescribe(\"DefaultContactsManager\", () => {\n it(\"registerExternalAddress flows manager -> use-case -> binder -> dmk.executeDeviceAction\", () => {\n const executeDeviceAction = vi.fn().mockReturnValue(\"DA_RETURN\");\n const dmk = { executeDeviceAction } as unknown as DeviceManagementKit;\n\n const manager = new DefaultContactsManager({\n dmk,\n sessionId: \"session-id\",\n appName: \"Ethereum\",\n });\n\n const result = manager.registerExternalAddress(VALID_INPUT);\n\n expect(executeDeviceAction).toHaveBeenCalledTimes(1);\n const call = executeDeviceAction.mock.calls[0]![0] as {\n sessionId: string;\n deviceAction: unknown;\n };\n expect(call.sessionId).toBe(\"session-id\");\n expect(call.deviceAction).toBeDefined();\n expect(result).toBe(\"DA_RETURN\");\n });\n\n it(\"does not throw on invalid input \u2014 it dispatches the device action, which surfaces the error\", () => {\n // The public API returns a device action; invalid caller input must reach\n // the observable as a typed error state rather than throwing synchronously.\n const executeDeviceAction = vi.fn().mockReturnValue(\"DA_RETURN\");\n const dmk = { executeDeviceAction } as unknown as DeviceManagementKit;\n\n const manager = new DefaultContactsManager({\n dmk,\n sessionId: \"session-id\",\n appName: \"Ethereum\",\n });\n\n expect(() =>\n manager.registerExternalAddress({\n ...VALID_INPUT,\n contactName: \"\",\n }),\n ).not.toThrow();\n expect(executeDeviceAction).toHaveBeenCalledTimes(1);\n });\n\n it(\"renameContact flows manager -> use-case -> binder -> dmk.executeDeviceAction\", () => {\n const executeDeviceAction = vi.fn().mockReturnValue(\"DA_RETURN\");\n const dmk = { executeDeviceAction } as unknown as DeviceManagementKit;\n\n const manager = new DefaultContactsManager({\n dmk,\n sessionId: \"session-id\",\n appName: \"Ethereum\",\n });\n\n const result = manager.renameContact(VALID_RENAME_INPUT);\n\n expect(executeDeviceAction).toHaveBeenCalledTimes(1);\n const call = executeDeviceAction.mock.calls[0]![0] as {\n sessionId: string;\n deviceAction: unknown;\n };\n expect(call.sessionId).toBe(\"session-id\");\n expect(call.deviceAction).toBeDefined();\n expect(result).toBe(\"DA_RETURN\");\n });\n});\n"],
5
+ "mappings": "AAKA,OAAS,0BAAAA,MAA8B,2BAEvC,MAAMC,EAA4C,CAChD,YAAa,QACb,MAAO,WACP,WAAY,IAAI,WAAW,EAAE,EAAE,KAAK,EAAI,EACxC,iBAAkB,WAClB,QAAS,EACX,EAEMC,EAAyC,CAC7C,oBAAqB,QACrB,eAAgB,MAChB,YAAa,IAAI,WAAW,EAAE,EAAE,KAAK,GAAI,EACzC,UAAW,IAAI,WAAW,EAAE,EAAE,KAAK,GAAI,CACzC,EAEA,SAAS,yBAA0B,IAAM,CACvC,GAAG,yFAA0F,IAAM,CACjG,MAAMC,EAAsB,GAAG,GAAG,EAAE,gBAAgB,WAAW,EACzDC,EAAM,CAAE,oBAAAD,CAAoB,EAQ5BE,EANU,IAAIL,EAAuB,CACzC,IAAAI,EACA,UAAW,aACX,QAAS,UACX,CAAC,EAEsB,wBAAwBH,CAAW,EAE1D,OAAOE,CAAmB,EAAE,sBAAsB,CAAC,EACnD,MAAMG,EAAOH,EAAoB,KAAK,MAAM,CAAC,EAAG,CAAC,EAIjD,OAAOG,EAAK,SAAS,EAAE,KAAK,YAAY,EACxC,OAAOA,EAAK,YAAY,EAAE,YAAY,EACtC,OAAOD,CAAM,EAAE,KAAK,WAAW,CACjC,CAAC,EAED,GAAG,mGAA+F,IAAM,CAGtG,MAAMF,EAAsB,GAAG,GAAG,EAAE,gBAAgB,WAAW,EACzDC,EAAM,CAAE,oBAAAD,CAAoB,EAE5BI,EAAU,IAAIP,EAAuB,CACzC,IAAAI,EACA,UAAW,aACX,QAAS,UACX,CAAC,EAED,OAAO,IACLG,EAAQ,wBAAwB,CAC9B,GAAGN,EACH,YAAa,EACf,CAAC,CACH,EAAE,IAAI,QAAQ,EACd,OAAOE,CAAmB,EAAE,sBAAsB,CAAC,CACrD,CAAC,EAED,GAAG,+EAAgF,IAAM,CACvF,MAAMA,EAAsB,GAAG,GAAG,EAAE,gBAAgB,WAAW,EACzDC,EAAM,CAAE,oBAAAD,CAAoB,EAQ5BE,EANU,IAAIL,EAAuB,CACzC,IAAAI,EACA,UAAW,aACX,QAAS,UACX,CAAC,EAEsB,cAAcF,CAAkB,EAEvD,OAAOC,CAAmB,EAAE,sBAAsB,CAAC,EACnD,MAAMG,EAAOH,EAAoB,KAAK,MAAM,CAAC,EAAG,CAAC,EAIjD,OAAOG,EAAK,SAAS,EAAE,KAAK,YAAY,EACxC,OAAOA,EAAK,YAAY,EAAE,YAAY,EACtC,OAAOD,CAAM,EAAE,KAAK,WAAW,CACjC,CAAC,CACH,CAAC",
6
+ "names": ["DefaultContactsManager", "VALID_INPUT", "VALID_RENAME_INPUT", "executeDeviceAction", "dmk", "result", "call", "manager"]
7
7
  }
@@ -1,2 +1,2 @@
1
- var l=Object.defineProperty;var y=Object.getOwnPropertyDescriptor;var c=(i,e,s,t)=>{for(var r=t>1?void 0:t?y(e,s):e,d=i.length-1,p;d>=0;d--)(p=i[d])&&(r=(t?p(e,s,r):p(r))||r);return t&&r&&l(e,s,r),r},n=(i,e)=>(s,t)=>e(s,t,i);import{inject as m,injectable as g}from"inversify";import{RegisterExternalAddressDeviceAction as x}from"../app-binder/device-action/RegisterExternalAddress/RegisterExternalAddressDeviceAction";import{externalTypes as a}from"../externalTypes";let o=class{constructor(e,s,t){this.dmk=e;this.sessionId=s;this.appName=t}registerExternalAddress(e){return this.dmk.executeDeviceAction({sessionId:this.sessionId,deviceAction:new x({input:{...e,appName:this.appName}})})}};o=c([g(),n(0,m(a.Dmk)),n(1,m(a.SessionId)),n(2,m(a.AppName))],o);export{o as ContactsAppBinder};
1
+ var u=Object.defineProperty;var y=Object.getOwnPropertyDescriptor;var d=(i,e,n,t)=>{for(var r=t>1?void 0:t?y(e,n):e,m=i.length-1,a;m>=0;m--)(a=i[m])&&(r=(t?a(e,n,r):a(r))||r);return t&&r&&u(e,n,r),r},s=(i,e)=>(n,t)=>e(n,t,i);import{inject as p,injectable as A}from"inversify";import{RegisterExternalAddressDeviceAction as R}from"../app-binder/device-action/RegisterExternalAddress/RegisterExternalAddressDeviceAction";import{RenameContactDeviceAction as D}from"../app-binder/device-action/RenameContact/RenameContactDeviceAction";import{externalTypes as c}from"../externalTypes";let o=class{constructor(e,n,t){this.dmk=e;this.sessionId=n;this.appName=t}registerExternalAddress(e){return this.dmk.executeDeviceAction({sessionId:this.sessionId,deviceAction:new R({input:{...e,appName:this.appName}})})}renameContact(e){return this.dmk.executeDeviceAction({sessionId:this.sessionId,deviceAction:new D({input:e})})}};o=d([A(),s(0,p(c.Dmk)),s(1,p(c.SessionId)),s(2,p(c.AppName))],o);export{o as ContactsAppBinder};
2
2
  //# sourceMappingURL=ContactsAppBinder.js.map
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "version": 3,
3
3
  "sources": ["../../../../src/internal/app-binder/ContactsAppBinder.ts"],
4
- "sourcesContent": ["import {\n type DeviceManagementKit,\n type DeviceSessionId,\n} from \"@ledgerhq/device-management-kit\";\nimport { inject, injectable } from \"inversify\";\n\nimport { type RegisterExternalAddressDAReturnType } from \"@api/app-binder/RegisterExternalAddressDeviceActionTypes\";\nimport { type RegisterExternalAddressInput } from \"@api/model/RegisterExternalAddress\";\nimport { RegisterExternalAddressDeviceAction } from \"@internal/app-binder/device-action/RegisterExternalAddress/RegisterExternalAddressDeviceAction\";\nimport { externalTypes } from \"@internal/externalTypes\";\n\n/**\n * Constructs and executes Contacts `DeviceAction`s using the injected `dmk`,\n * `sessionId`, and `appName`. Each Address Book operation gets one method here.\n */\n@injectable()\nexport class ContactsAppBinder {\n constructor(\n @inject(externalTypes.Dmk)\n protected readonly dmk: DeviceManagementKit,\n @inject(externalTypes.SessionId)\n protected readonly sessionId: DeviceSessionId,\n @inject(externalTypes.AppName)\n protected readonly appName: string,\n ) {}\n\n registerExternalAddress(\n input: RegisterExternalAddressInput,\n ): RegisterExternalAddressDAReturnType {\n return this.dmk.executeDeviceAction({\n sessionId: this.sessionId,\n deviceAction: new RegisterExternalAddressDeviceAction({\n input: { ...input, appName: this.appName },\n }),\n });\n }\n}\n"],
5
- "mappings": "iOAIA,OAAS,UAAAA,EAAQ,cAAAC,MAAkB,YAInC,OAAS,uCAAAC,MAA2C,iGACpD,OAAS,iBAAAC,MAAqB,0BAOvB,IAAMC,EAAN,KAAwB,CAC7B,YAEqBC,EAEAC,EAEAC,EACnB,CALmB,SAAAF,EAEA,eAAAC,EAEA,aAAAC,CAClB,CAEH,wBACEC,EACqC,CACrC,OAAO,KAAK,IAAI,oBAAoB,CAClC,UAAW,KAAK,UAChB,aAAc,IAAIC,EAAoC,CACpD,MAAO,CAAE,GAAGD,EAAO,QAAS,KAAK,OAAQ,CAC3C,CAAC,CACH,CAAC,CACH,CACF,EApBaJ,EAANM,EAAA,CADNC,EAAW,EAGPC,EAAA,EAAAC,EAAOC,EAAc,GAAG,GAExBF,EAAA,EAAAC,EAAOC,EAAc,SAAS,GAE9BF,EAAA,EAAAC,EAAOC,EAAc,OAAO,IANpBV",
6
- "names": ["inject", "injectable", "RegisterExternalAddressDeviceAction", "externalTypes", "ContactsAppBinder", "dmk", "sessionId", "appName", "input", "RegisterExternalAddressDeviceAction", "__decorateClass", "injectable", "__decorateParam", "inject", "externalTypes"]
4
+ "sourcesContent": ["import {\n type DeviceManagementKit,\n type DeviceSessionId,\n} from \"@ledgerhq/device-management-kit\";\nimport { inject, injectable } from \"inversify\";\n\nimport { type RegisterExternalAddressDAReturnType } from \"@api/app-binder/RegisterExternalAddressDeviceActionTypes\";\nimport { type RenameContactDAReturnType } from \"@api/app-binder/RenameContactDeviceActionTypes\";\nimport { type RegisterExternalAddressInput } from \"@api/model/RegisterExternalAddress\";\nimport { type RenameContactInput } from \"@api/model/RenameContact\";\nimport { RegisterExternalAddressDeviceAction } from \"@internal/app-binder/device-action/RegisterExternalAddress/RegisterExternalAddressDeviceAction\";\nimport { RenameContactDeviceAction } from \"@internal/app-binder/device-action/RenameContact/RenameContactDeviceAction\";\nimport { externalTypes } from \"@internal/externalTypes\";\n\n/**\n * Constructs and executes Contacts `DeviceAction`s using the injected `dmk`,\n * `sessionId`, and `appName`. Each Address Book operation gets one method here.\n */\n@injectable()\nexport class ContactsAppBinder {\n constructor(\n @inject(externalTypes.Dmk)\n protected readonly dmk: DeviceManagementKit,\n @inject(externalTypes.SessionId)\n protected readonly sessionId: DeviceSessionId,\n @inject(externalTypes.AppName)\n protected readonly appName: string,\n ) {}\n\n registerExternalAddress(\n input: RegisterExternalAddressInput,\n ): RegisterExternalAddressDAReturnType {\n return this.dmk.executeDeviceAction({\n sessionId: this.sessionId,\n deviceAction: new RegisterExternalAddressDeviceAction({\n input: { ...input, appName: this.appName },\n }),\n });\n }\n\n renameContact(input: RenameContactInput): RenameContactDAReturnType {\n // Rename is a dashboard operation: `appName` is intentionally not passed \u2014\n // the OS serves the command and there is no app to open.\n return this.dmk.executeDeviceAction({\n sessionId: this.sessionId,\n deviceAction: new RenameContactDeviceAction({ input }),\n });\n }\n}\n"],
5
+ "mappings": "iOAIA,OAAS,UAAAA,EAAQ,cAAAC,MAAkB,YAMnC,OAAS,uCAAAC,MAA2C,iGACpD,OAAS,6BAAAC,MAAiC,6EAC1C,OAAS,iBAAAC,MAAqB,0BAOvB,IAAMC,EAAN,KAAwB,CAC7B,YAEqBC,EAEAC,EAEAC,EACnB,CALmB,SAAAF,EAEA,eAAAC,EAEA,aAAAC,CAClB,CAEH,wBACEC,EACqC,CACrC,OAAO,KAAK,IAAI,oBAAoB,CAClC,UAAW,KAAK,UAChB,aAAc,IAAIC,EAAoC,CACpD,MAAO,CAAE,GAAGD,EAAO,QAAS,KAAK,OAAQ,CAC3C,CAAC,CACH,CAAC,CACH,CAEA,cAAcA,EAAsD,CAGlE,OAAO,KAAK,IAAI,oBAAoB,CAClC,UAAW,KAAK,UAChB,aAAc,IAAIE,EAA0B,CAAE,MAAAF,CAAM,CAAC,CACvD,CAAC,CACH,CACF,EA7BaJ,EAANO,EAAA,CADNC,EAAW,EAGPC,EAAA,EAAAC,EAAOC,EAAc,GAAG,GAExBF,EAAA,EAAAC,EAAOC,EAAc,SAAS,GAE9BF,EAAA,EAAAC,EAAOC,EAAc,OAAO,IANpBX",
6
+ "names": ["inject", "injectable", "RegisterExternalAddressDeviceAction", "RenameContactDeviceAction", "externalTypes", "ContactsAppBinder", "dmk", "sessionId", "appName", "input", "RegisterExternalAddressDeviceAction", "RenameContactDeviceAction", "__decorateClass", "injectable", "__decorateParam", "inject", "externalTypes"]
7
7
  }
@@ -0,0 +1,2 @@
1
+ import{ApduBuilder as s,ApduParser as C,CommandResultFactory as t,InvalidStatusWordError as m}from"@ledgerhq/device-management-kit";import{CommandErrorHelper as p}from"@ledgerhq/signer-utils";import{Maybe as c}from"purify-ts";import{HMAC_NAME_BYTES as i,RENAME_CONTACT_APDU_CLA as u,RENAME_CONTACT_APDU_INS as A,RENAME_CONTACT_P1 as R}from"../../app-binder/model/contactsConstants";import{CONTACTS_APP_ERRORS as l,contactsCommandErrorFactory as y}from"../../app-binder/model/contactsErrors";import{STRUCT_TYPE_EDIT_CONTACT_NAME as E}from"../../app-binder/services/contactsTlvSerializer";const d=E;function f(o,r){const e=o.extractFieldByLength(r);if(!(!e||e.length!==r))return Uint8Array.from(e)}class h{name="renameContact";args;errorHelper=new p(l,y);constructor(r){this.args=r}getApdu(){return new s({cla:u,ins:A,p1:R,p2:this.args.p2}).addBufferToData(this.args.data).build()}parseResponse(r){return c.fromNullable(this.errorHelper.getError(r)).orDefaultLazy(()=>{if(r.data.length===0)return t({data:{}});const e=new C(r),n=e.extract8BitUInt();if(n!==d)return t({error:new m(`Expected struct_type 0x${d.toString(16)}, got ${n===void 0?"undefined":`0x${n.toString(16)}`}`)});const a=f(e,i);return a?t({data:{hmacProof:a}}):t({error:new m("hmac_name missing or truncated")})})}}export{h as RenameContactCommand};
2
+ //# sourceMappingURL=RenameContactCommand.js.map
@@ -0,0 +1,7 @@
1
+ {
2
+ "version": 3,
3
+ "sources": ["../../../../../src/internal/app-binder/command/RenameContactCommand.ts"],
4
+ "sourcesContent": ["// Rename Contact (EDIT CONTACT NAME) \u2014 the blockchain-agnostic address-book\n// rename. It is dispatched as an OS/dashboard command (CLA 0xE0 / INS 0x2E /\n// P1 0x00), NOT through the embedded app: the caller navigates to the dashboard\n// first (GoToDashboardDeviceAction) so the OS handles it directly.\n// SendRenameContactTask + sendFramedContactsPayload assemble the TLV, prepend\n// the 2-byte BE total length and slice into <=255B chunks; this command frames\n// one chunk and, on the final chunk, parses the 33-byte response:\n// struct_type(0x2e) + rotated hmac_name(32). Intermediate chunks ack with\n// SW=0x9000 and no data.\n//\n// The device is stateless: it verifies the supplied group handle + old-name\n// proof against the seed-derived key (SW 0x6982 on a seed mismatch, before any\n// UI) and, on approval, returns a fresh proof for the new name.\n// Protocol: Address Book Final Specifications \u2014 Edit Contact Name.\nimport {\n type Apdu,\n ApduBuilder,\n ApduParser,\n type ApduResponse,\n type Command,\n type CommandResult,\n CommandResultFactory,\n InvalidStatusWordError,\n} from \"@ledgerhq/device-management-kit\";\nimport { CommandErrorHelper } from \"@ledgerhq/signer-utils\";\nimport { Maybe } from \"purify-ts\";\n\nimport {\n HMAC_NAME_BYTES,\n RENAME_CONTACT_APDU_CLA,\n RENAME_CONTACT_APDU_INS,\n RENAME_CONTACT_P1,\n} from \"@internal/app-binder/model/contactsConstants\";\nimport {\n CONTACTS_APP_ERRORS,\n contactsCommandErrorFactory,\n type ContactsErrorCodes,\n} from \"@internal/app-binder/model/contactsErrors\";\nimport { STRUCT_TYPE_EDIT_CONTACT_NAME } from \"@internal/app-binder/services/contactsTlvSerializer\";\n\nexport type RenameContactCommandArgs = {\n /** One framed chunk built by sendFramedContactsPayload. */\n readonly data: Uint8Array;\n /** 0x00 for the first/only chunk, 0x80 for continuation chunks. */\n readonly p2: number;\n};\n\nexport type RenameContactCommandResponse = {\n /**\n * Present only on the final chunk \u2014 the device returns struct_type(0x2e) +\n * rotated hmac_name(32) there. Intermediate chunks return SW=0x9000 with no\n * data. This is the replacement group-level name proof.\n */\n readonly hmacProof?: Uint8Array;\n};\n\nconst RESPONSE_STRUCT_TYPE = STRUCT_TYPE_EDIT_CONTACT_NAME;\n\n/**\n * Extract `length` bytes as a freshly-owned plain `Uint8Array` (the parser may\n * hand back a `Buffer` view backed by the response), or `undefined` if the\n * response is too short.\n */\nfunction extractField(\n parser: ApduParser,\n length: number,\n): Uint8Array | undefined {\n const field = parser.extractFieldByLength(length);\n if (!field || field.length !== length) return undefined;\n return Uint8Array.from(field);\n}\n\nexport class RenameContactCommand\n implements\n Command<\n RenameContactCommandResponse,\n RenameContactCommandArgs,\n ContactsErrorCodes\n >\n{\n readonly name = \"renameContact\";\n readonly args: RenameContactCommandArgs;\n private readonly errorHelper = new CommandErrorHelper<\n RenameContactCommandResponse,\n ContactsErrorCodes\n >(CONTACTS_APP_ERRORS, contactsCommandErrorFactory);\n\n constructor(args: RenameContactCommandArgs) {\n this.args = args;\n }\n\n getApdu(): Apdu {\n return new ApduBuilder({\n cla: RENAME_CONTACT_APDU_CLA,\n ins: RENAME_CONTACT_APDU_INS,\n p1: RENAME_CONTACT_P1,\n p2: this.args.p2,\n })\n .addBufferToData(this.args.data)\n .build();\n }\n\n parseResponse(\n response: ApduResponse,\n ): CommandResult<RenameContactCommandResponse, ContactsErrorCodes> {\n return Maybe.fromNullable(\n this.errorHelper.getError(response),\n ).orDefaultLazy(() => {\n if (response.data.length === 0) {\n // Intermediate chunk \u2014 device acks with SW=0x9000 and no payload.\n return CommandResultFactory({ data: {} });\n }\n\n const parser = new ApduParser(response);\n\n const structType = parser.extract8BitUInt();\n if (structType !== RESPONSE_STRUCT_TYPE) {\n return CommandResultFactory({\n error: new InvalidStatusWordError(\n `Expected struct_type 0x${RESPONSE_STRUCT_TYPE.toString(16)}, got ${\n structType === undefined\n ? \"undefined\"\n : `0x${structType.toString(16)}`\n }`,\n ),\n });\n }\n\n const hmacProof = extractField(parser, HMAC_NAME_BYTES);\n if (!hmacProof) {\n return CommandResultFactory({\n error: new InvalidStatusWordError(\"hmac_name missing or truncated\"),\n });\n }\n\n return CommandResultFactory({\n data: { hmacProof },\n });\n });\n }\n}\n"],
5
+ "mappings": "AAcA,OAEE,eAAAA,EACA,cAAAC,EAIA,wBAAAC,EACA,0BAAAC,MACK,kCACP,OAAS,sBAAAC,MAA0B,yBACnC,OAAS,SAAAC,MAAa,YAEtB,OACE,mBAAAC,EACA,2BAAAC,EACA,2BAAAC,EACA,qBAAAC,MACK,+CACP,OACE,uBAAAC,EACA,+BAAAC,MAEK,4CACP,OAAS,iCAAAC,MAAqC,sDAkB9C,MAAMC,EAAuBD,EAO7B,SAASE,EACPC,EACAC,EACwB,CACxB,MAAMC,EAAQF,EAAO,qBAAqBC,CAAM,EAChD,GAAI,GAACC,GAASA,EAAM,SAAWD,GAC/B,OAAO,WAAW,KAAKC,CAAK,CAC9B,CAEO,MAAMC,CAOb,CACW,KAAO,gBACP,KACQ,YAAc,IAAId,EAGjCM,EAAqBC,CAA2B,EAElD,YAAYQ,EAAgC,CAC1C,KAAK,KAAOA,CACd,CAEA,SAAgB,CACd,OAAO,IAAInB,EAAY,CACrB,IAAKO,EACL,IAAKC,EACL,GAAIC,EACJ,GAAI,KAAK,KAAK,EAChB,CAAC,EACE,gBAAgB,KAAK,KAAK,IAAI,EAC9B,MAAM,CACX,CAEA,cACEW,EACiE,CACjE,OAAOf,EAAM,aACX,KAAK,YAAY,SAASe,CAAQ,CACpC,EAAE,cAAc,IAAM,CACpB,GAAIA,EAAS,KAAK,SAAW,EAE3B,OAAOlB,EAAqB,CAAE,KAAM,CAAC,CAAE,CAAC,EAG1C,MAAMa,EAAS,IAAId,EAAWmB,CAAQ,EAEhCC,EAAaN,EAAO,gBAAgB,EAC1C,GAAIM,IAAeR,EACjB,OAAOX,EAAqB,CAC1B,MAAO,IAAIC,EACT,0BAA0BU,EAAqB,SAAS,EAAE,CAAC,SACzDQ,IAAe,OACX,YACA,KAAKA,EAAW,SAAS,EAAE,CAAC,EAClC,EACF,CACF,CAAC,EAGH,MAAMC,EAAYR,EAAaC,EAAQT,CAAe,EACtD,OAAKgB,EAMEpB,EAAqB,CAC1B,KAAM,CAAE,UAAAoB,CAAU,CACpB,CAAC,EAPQpB,EAAqB,CAC1B,MAAO,IAAIC,EAAuB,gCAAgC,CACpE,CAAC,CAML,CAAC,CACH,CACF",
6
+ "names": ["ApduBuilder", "ApduParser", "CommandResultFactory", "InvalidStatusWordError", "CommandErrorHelper", "Maybe", "HMAC_NAME_BYTES", "RENAME_CONTACT_APDU_CLA", "RENAME_CONTACT_APDU_INS", "RENAME_CONTACT_P1", "CONTACTS_APP_ERRORS", "contactsCommandErrorFactory", "STRUCT_TYPE_EDIT_CONTACT_NAME", "RESPONSE_STRUCT_TYPE", "extractField", "parser", "length", "field", "RenameContactCommand", "args", "response", "structType", "hmacProof"]
7
+ }
@@ -0,0 +1,2 @@
1
+ import{CommandResultStatus as a}from"@ledgerhq/device-management-kit";import{CONTACT_SEED_MISMATCH_ERROR_CODE as d,ContactsCommandError as s}from"../../app-binder/model/contactsErrors";import{RenameContactCommand as o}from"./RenameContactCommand";function m(e){const t=new Uint8Array(e.length/2);for(let r=0;r<e.length;r+=2)t[r/2]=parseInt(e.slice(r,r+2),16);return t}const u=m("dd".repeat(32)),c="2e"+"dd".repeat(32);function n(e){return{data:Buffer.from(m(e)),statusCode:Buffer.from([144,0])}}describe("RenameContactCommand",()=>{describe("getApdu",()=>{it("wraps the framed chunk under E0 2E 00 with P2=0x00 for the first/only chunk",()=>{const e=Uint8Array.from([0,3,170,187,204]),t=new o({data:e,p2:0}).getApdu();expect(t.getRawApdu()).toStrictEqual(Uint8Array.from([224,46,0,0,5,0,3,170,187,204]))}),it("uses P2=0x80 for continuation chunks",()=>{const e=Uint8Array.from([170,187]),t=new o({data:e,p2:128}).getApdu();expect(t.getRawApdu()).toStrictEqual(Uint8Array.from([224,46,0,128,2,170,187]))})}),describe("parseResponse",()=>{it("returns an empty payload for an intermediate chunk (SW=0x9000, no data)",()=>{const e=new o({data:new Uint8Array,p2:0}).parseResponse({data:Buffer.from([]),statusCode:Buffer.from([144,0])});expect(e).toStrictEqual({status:a.Success,data:{}})}),it("extracts the rotated hmac_name from an edit-contact-name response",()=>{const t=new o({data:new Uint8Array,p2:0}).parseResponse(n(c));expect(t).toStrictEqual({status:a.Success,data:{hmacProof:u}})}),it("returns InvalidStatusWordError when struct_type is wrong",()=>{const e="ee"+c.slice(2),r=new o({data:new Uint8Array,p2:0}).parseResponse(n(e));expect(r.status).toBe(a.Error)}),it("returns InvalidStatusWordError when hmac_name is truncated",()=>{const e="2e"+"dd".repeat(16),r=new o({data:new Uint8Array,p2:0}).parseResponse(n(e));expect(r.status).toBe(a.Error)}),it("maps a known SW (0x6985) to a ContactsCommandError",()=>{const t=new o({data:new Uint8Array,p2:0}).parseResponse({data:Buffer.from([]),statusCode:Buffer.from([105,133])});expect(t.status).toBe(a.Error),t.status===a.Error&&(expect(t.error).toBeInstanceOf(s),expect(t.error.errorCode).toBe("6985"))}),it("maps SW=0x6982 to a seed-mismatch ContactsCommandError",()=>{const t=new o({data:new Uint8Array,p2:0}).parseResponse({data:Buffer.from([]),statusCode:Buffer.from([105,130])});expect(t.status).toBe(a.Error),t.status===a.Error&&(expect(t.error).toBeInstanceOf(s),expect(t.error.errorCode).toBe(d))})})});
2
+ //# sourceMappingURL=RenameContactCommand.test.js.map
@@ -0,0 +1,7 @@
1
+ {
2
+ "version": 3,
3
+ "sources": ["../../../../../src/internal/app-binder/command/RenameContactCommand.test.ts"],
4
+ "sourcesContent": ["// RenameContactCommand is a thin chunk-framer for the OS/dashboard EDIT CONTACT\n// NAME command: it wraps a pre-framed chunk (2-byte BE length prefix + TLV,\n// assembled by SendRenameContactTask + sendFramedContactsPayload) under\n// E0 2E 00 <P2>, and parses the 33-byte response on the final chunk. TLV\n// byte-parity is asserted in SendRenameContactTask.test.ts.\nimport {\n type ApduResponse,\n CommandResultStatus,\n} from \"@ledgerhq/device-management-kit\";\n\nimport {\n CONTACT_SEED_MISMATCH_ERROR_CODE,\n ContactsCommandError,\n} from \"@internal/app-binder/model/contactsErrors\";\n\nimport { RenameContactCommand } from \"./RenameContactCommand\";\n\nfunction hexToBytes(hex: string): Uint8Array {\n const out = new Uint8Array(hex.length / 2);\n for (let i = 0; i < hex.length; i += 2) {\n out[i / 2] = parseInt(hex.slice(i, i + 2), 16);\n }\n return out;\n}\n\n// Device response: struct_type(0x2e) + rotated hmac_name(32).\nconst HMAC_PROOF = hexToBytes(\"dd\".repeat(32));\nconst RESPONSE_HEX = \"2e\" + \"dd\".repeat(32);\n\nfunction makeResponse(hex: string): ApduResponse {\n return {\n data: Buffer.from(hexToBytes(hex)),\n statusCode: Buffer.from([0x90, 0x00]),\n };\n}\n\ndescribe(\"RenameContactCommand\", () => {\n describe(\"getApdu\", () => {\n it(\"wraps the framed chunk under E0 2E 00 with P2=0x00 for the first/only chunk\", () => {\n const data = Uint8Array.from([0x00, 0x03, 0xaa, 0xbb, 0xcc]);\n\n const apdu = new RenameContactCommand({ data, p2: 0x00 }).getApdu();\n\n expect(apdu.getRawApdu()).toStrictEqual(\n Uint8Array.from([\n 0xe0, 0x2e, 0x00, 0x00, 0x05, 0x00, 0x03, 0xaa, 0xbb, 0xcc,\n ]),\n );\n });\n\n it(\"uses P2=0x80 for continuation chunks\", () => {\n const data = Uint8Array.from([0xaa, 0xbb]);\n\n const apdu = new RenameContactCommand({ data, p2: 0x80 }).getApdu();\n\n expect(apdu.getRawApdu()).toStrictEqual(\n Uint8Array.from([0xe0, 0x2e, 0x00, 0x80, 0x02, 0xaa, 0xbb]),\n );\n });\n });\n\n describe(\"parseResponse\", () => {\n it(\"returns an empty payload for an intermediate chunk (SW=0x9000, no data)\", () => {\n const result = new RenameContactCommand({\n data: new Uint8Array(),\n p2: 0x00,\n }).parseResponse({\n data: Buffer.from([]),\n statusCode: Buffer.from([0x90, 0x00]),\n });\n\n expect(result).toStrictEqual({\n status: CommandResultStatus.Success,\n data: {},\n });\n });\n\n it(\"extracts the rotated hmac_name from an edit-contact-name response\", () => {\n const command = new RenameContactCommand({\n data: new Uint8Array(),\n p2: 0x00,\n });\n\n const result = command.parseResponse(makeResponse(RESPONSE_HEX));\n\n expect(result).toStrictEqual({\n status: CommandResultStatus.Success,\n data: { hmacProof: HMAC_PROOF },\n });\n });\n\n it(\"returns InvalidStatusWordError when struct_type is wrong\", () => {\n const wrongType = \"ee\" + RESPONSE_HEX.slice(2); // replace 0x2e with 0xee\n const command = new RenameContactCommand({\n data: new Uint8Array(),\n p2: 0x00,\n });\n\n const result = command.parseResponse(makeResponse(wrongType));\n\n expect(result.status).toBe(CommandResultStatus.Error);\n });\n\n it(\"returns InvalidStatusWordError when hmac_name is truncated\", () => {\n const truncated = \"2e\" + \"dd\".repeat(16); // only 16 of 32 bytes\n const command = new RenameContactCommand({\n data: new Uint8Array(),\n p2: 0x00,\n });\n\n const result = command.parseResponse(makeResponse(truncated));\n\n expect(result.status).toBe(CommandResultStatus.Error);\n });\n\n it(\"maps a known SW (0x6985) to a ContactsCommandError\", () => {\n const command = new RenameContactCommand({\n data: new Uint8Array(),\n p2: 0x00,\n });\n\n const result = command.parseResponse({\n data: Buffer.from([]),\n statusCode: Buffer.from([0x69, 0x85]),\n });\n\n expect(result.status).toBe(CommandResultStatus.Error);\n if (result.status === CommandResultStatus.Error) {\n expect(result.error).toBeInstanceOf(ContactsCommandError);\n expect((result.error as ContactsCommandError).errorCode).toBe(\"6985\");\n }\n });\n\n it(\"maps SW=0x6982 to a seed-mismatch ContactsCommandError\", () => {\n // The device verifies the supplied group handle + old-name proof against\n // the seed-derived key before any UI, and returns 0x6982 on a mismatch.\n const command = new RenameContactCommand({\n data: new Uint8Array(),\n p2: 0x00,\n });\n\n const result = command.parseResponse({\n data: Buffer.from([]),\n statusCode: Buffer.from([0x69, 0x82]),\n });\n\n expect(result.status).toBe(CommandResultStatus.Error);\n if (result.status === CommandResultStatus.Error) {\n expect(result.error).toBeInstanceOf(ContactsCommandError);\n expect((result.error as ContactsCommandError).errorCode).toBe(\n CONTACT_SEED_MISMATCH_ERROR_CODE,\n );\n }\n });\n });\n});\n"],
5
+ "mappings": "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",
6
+ "names": ["CommandResultStatus", "CONTACT_SEED_MISMATCH_ERROR_CODE", "ContactsCommandError", "RenameContactCommand", "hexToBytes", "hex", "out", "i", "HMAC_PROOF", "RESPONSE_HEX", "makeResponse", "data", "apdu", "result", "wrongType", "truncated"]
7
+ }
@@ -0,0 +1,2 @@
1
+ import{GoToDashboardDeviceAction as m,isSuccessCommandResult as p,UnknownDAError as u,UserInteractionRequired as i,XStateDeviceAction as l}from"@ledgerhq/device-management-kit";import{Left as d,Right as C}from"purify-ts";import{assign as a,fromPromise as R,setup as S}from"xstate";import{isContactsOsSupportedForSession as D}from"../../../app-binder/isContactsSupportedForSession";import{ContactsVersionRequirementError as g}from"../../../app-binder/model/contactsErrors";import{SendRenameContactTask as A}from"../../../app-binder/task/SendRenameContactTask";import{validateRenameContactInput as I}from"./validateRenameContactInput";class k extends l{makeStateMachine(n){const{isOsSupported:c,renameContact:s}=this.extractDependencies(n);return S({types:{input:{},context:{},output:{}},actors:{goToDashboardStateMachine:new m({input:{}}).makeStateMachine(n),renameContact:R(({input:t})=>s(t))},guards:{noInternalError:({context:t})=>t._internalState.error===null,contactsOsSupported:()=>c()},actions:{assignValidationError:a({_internalState:({context:t})=>{const e=I(t.input);return e?{...t._internalState,error:e}:t._internalState}}),assignVersionError:a({_internalState:({context:t})=>({...t._internalState,error:new g})}),assignErrorFromEvent:a({_internalState:({context:t,event:e})=>({...t._internalState,error:new u(e.error instanceof Error?e.error.message:String(e.error))})})}}).createMachine({id:"RenameContactDeviceAction",initial:"InitialState",context:({input:t})=>({input:t,intermediateValue:{requiredUserInteraction:i.None},_internalState:{error:null,proof:null}}),states:{InitialState:{always:{target:"GoToDashboard"}},GoToDashboard:{invoke:{id:"goToDashboard",src:"goToDashboardStateMachine",input:()=>({}),onSnapshot:{actions:a({intermediateValue:({event:t})=>({requiredUserInteraction:t.snapshot.context.intermediateValue.requiredUserInteraction})})},onDone:{target:"GoToDashboardCheck",actions:a({_internalState:({event:t,context:e})=>t.output.caseOf({Right:()=>e._internalState,Left:r=>({...e._internalState,error:r})})})},onError:{target:"Error",actions:"assignErrorFromEvent"}}},GoToDashboardCheck:{always:[{target:"ValidateInput",guard:"noInternalError"},{target:"Error"}]},ValidateInput:{entry:"assignValidationError",always:[{target:"VersionGuard",guard:"noInternalError"},{target:"Error"}]},VersionGuard:{always:[{target:"RenameContact",guard:"contactsOsSupported"},{target:"Error",actions:"assignVersionError"}]},RenameContact:{entry:a({intermediateValue:{requiredUserInteraction:i.RegisterWallet}}),exit:a({intermediateValue:{requiredUserInteraction:i.None}}),invoke:{id:"renameContact",src:"renameContact",input:({context:t})=>t.input,onDone:{target:"RenameContactResultCheck",actions:a({_internalState:({event:t,context:e})=>p(t.output)?{...e._internalState,proof:t.output.data}:{...e._internalState,error:t.output.error}})},onError:{target:"Error",actions:"assignErrorFromEvent"}}},RenameContactResultCheck:{always:[{target:"Success",guard:"noInternalError"},{target:"Error"}]},Success:{type:"final"},Error:{type:"final"}},output:({context:t})=>{const{proof:e,error:r}=t._internalState;if(e){const{input:o}=t;return C({previousContactName:o.previousContactName,contactName:o.newContactName,groupHandle:o.groupHandle,hmacProof:e.hmacProof})}return d(r??new u("No error in final state"))}})}extractDependencies(n){return{isOsSupported:()=>D(n),renameContact:t=>new A(n,{previousContactName:t.previousContactName,newContactName:t.newContactName,groupHandle:t.groupHandle,hmacProof:t.hmacProof}).run()}}}export{k as RenameContactDeviceAction};
2
+ //# sourceMappingURL=RenameContactDeviceAction.js.map
@@ -0,0 +1,7 @@
1
+ {
2
+ "version": 3,
3
+ "sources": ["../../../../../../src/internal/app-binder/device-action/RenameContact/RenameContactDeviceAction.ts"],
4
+ "sourcesContent": ["import {\n type DeviceActionStateMachine,\n GoToDashboardDeviceAction,\n type InternalApi,\n isSuccessCommandResult,\n type StateMachineTypes,\n UnknownDAError,\n UserInteractionRequired,\n XStateDeviceAction,\n} from \"@ledgerhq/device-management-kit\";\nimport { Left, Right } from \"purify-ts\";\nimport { assign, fromPromise, setup } from \"xstate\";\n\nimport {\n type RenameContactDAError,\n type RenameContactDAInput,\n type RenameContactDAIntermediateValue,\n type RenameContactDAInternalState,\n type RenameContactDAOutput,\n} from \"@api/app-binder/RenameContactDeviceActionTypes\";\nimport { isContactsOsSupportedForSession } from \"@internal/app-binder/isContactsSupportedForSession\";\nimport { ContactsVersionRequirementError } from \"@internal/app-binder/model/contactsErrors\";\nimport {\n type RenameContactProof,\n SendRenameContactTask,\n} from \"@internal/app-binder/task/SendRenameContactTask\";\n\nimport { validateRenameContactInput } from \"./validateRenameContactInput\";\n\nexport type RenameContactMachineDependencies = {\n readonly isOsSupported: () => boolean;\n readonly renameContact: (\n input: RenameContactDAInput,\n ) => Promise<Awaited<ReturnType<SendRenameContactTask[\"run\"]>>>;\n};\n\nexport class RenameContactDeviceAction extends XStateDeviceAction<\n RenameContactDAOutput,\n RenameContactDAInput,\n RenameContactDAError,\n RenameContactDAIntermediateValue,\n RenameContactDAInternalState\n> {\n makeStateMachine(\n internalApi: InternalApi,\n ): DeviceActionStateMachine<\n RenameContactDAOutput,\n RenameContactDAInput,\n RenameContactDAError,\n RenameContactDAIntermediateValue,\n RenameContactDAInternalState\n > {\n type types = StateMachineTypes<\n RenameContactDAOutput,\n RenameContactDAInput,\n RenameContactDAError,\n RenameContactDAIntermediateValue,\n RenameContactDAInternalState\n >;\n\n const { isOsSupported, renameContact } =\n this.extractDependencies(internalApi);\n\n return setup({\n types: {\n input: {} as types[\"input\"],\n context: {} as types[\"context\"],\n output: {} as types[\"output\"],\n },\n actors: {\n // Rename is an OS/dashboard command: navigate to the dashboard (which\n // closes any running app) instead of opening an embedded app. There is\n // no OpenAppDeviceAction here by design.\n goToDashboardStateMachine: new GoToDashboardDeviceAction({\n input: {},\n }).makeStateMachine(internalApi),\n renameContact: fromPromise(\n ({ input }: { input: RenameContactDAInput }) => renameContact(input),\n ),\n },\n guards: {\n noInternalError: ({ context }) => context._internalState.error === null,\n contactsOsSupported: () => isOsSupported(),\n },\n actions: {\n assignValidationError: assign({\n _internalState: ({ context }) => {\n const error = validateRenameContactInput(context.input);\n return error\n ? { ...context._internalState, error }\n : context._internalState;\n },\n }),\n assignVersionError: assign({\n _internalState: ({ context }) => ({\n ...context._internalState,\n error: new ContactsVersionRequirementError(),\n }),\n }),\n assignErrorFromEvent: assign({\n _internalState: ({ context, event }) => ({\n ...context._internalState,\n error: new UnknownDAError(\n event[\"error\"] instanceof Error\n ? event[\"error\"].message\n : String(event[\"error\"]),\n ),\n }),\n }),\n },\n }).createMachine({\n id: \"RenameContactDeviceAction\",\n initial: \"InitialState\",\n context: ({ input }) => ({\n input,\n intermediateValue: {\n requiredUserInteraction: UserInteractionRequired.None,\n },\n _internalState: {\n error: null,\n proof: null,\n },\n }),\n states: {\n InitialState: {\n always: { target: \"GoToDashboard\" },\n },\n // Always navigate to the dashboard first \u2014 rename is an OS command and\n // must not run inside an app. Closing any running app happens here.\n GoToDashboard: {\n invoke: {\n id: \"goToDashboard\",\n src: \"goToDashboardStateMachine\",\n input: () => ({}),\n onSnapshot: {\n actions: assign({\n // The child surfaces both requiredUserInteraction and a step;\n // only the interaction is part of this action's contract.\n intermediateValue: ({ event }) => ({\n requiredUserInteraction:\n event.snapshot.context.intermediateValue\n .requiredUserInteraction,\n }),\n }),\n },\n onDone: {\n target: \"GoToDashboardCheck\",\n actions: assign({\n _internalState: ({ event, context }) =>\n event.output.caseOf<RenameContactDAInternalState>({\n Right: () => context._internalState,\n Left: (error) => ({ ...context._internalState, error }),\n }),\n }),\n },\n onError: {\n target: \"Error\",\n actions: \"assignErrorFromEvent\",\n },\n },\n },\n GoToDashboardCheck: {\n always: [\n { target: \"ValidateInput\", guard: \"noInternalError\" },\n { target: \"Error\" },\n ],\n },\n // Input validation runs inside the device action so invalid caller input\n // surfaces as a typed terminal error state on the observable instead of\n // a synchronous throw.\n ValidateInput: {\n entry: \"assignValidationError\",\n always: [\n { target: \"VersionGuard\", guard: \"noInternalError\" },\n { target: \"Error\" },\n ],\n },\n // OS-only version guard: rename is served by the device OS, so only the\n // device model and OS version are checked (no embedded-app version).\n VersionGuard: {\n always: [\n { target: \"RenameContact\", guard: \"contactsOsSupported\" },\n { target: \"Error\", actions: \"assignVersionError\" },\n ],\n },\n RenameContact: {\n entry: assign({\n intermediateValue: {\n requiredUserInteraction: UserInteractionRequired.RegisterWallet,\n },\n }),\n exit: assign({\n intermediateValue: {\n requiredUserInteraction: UserInteractionRequired.None,\n },\n }),\n invoke: {\n id: \"renameContact\",\n src: \"renameContact\",\n input: ({ context }) => context.input,\n onDone: {\n target: \"RenameContactResultCheck\",\n actions: assign({\n _internalState: ({ event, context }) =>\n isSuccessCommandResult(event.output)\n ? { ...context._internalState, proof: event.output.data }\n : {\n ...context._internalState,\n error: event.output.error,\n },\n }),\n },\n onError: {\n target: \"Error\",\n actions: \"assignErrorFromEvent\",\n },\n },\n },\n RenameContactResultCheck: {\n always: [\n { target: \"Success\", guard: \"noInternalError\" },\n { target: \"Error\" },\n ],\n },\n Success: { type: \"final\" },\n Error: { type: \"final\" },\n },\n output: ({ context }) => {\n const { proof, error } = context._internalState;\n if (proof) {\n const { input } = context;\n return Right({\n previousContactName: input.previousContactName,\n contactName: input.newContactName,\n groupHandle: input.groupHandle,\n hmacProof: proof.hmacProof,\n });\n }\n return Left(error ?? new UnknownDAError(\"No error in final state\"));\n },\n });\n }\n\n extractDependencies(\n internalApi: InternalApi,\n ): RenameContactMachineDependencies {\n const isOsSupported = () => isContactsOsSupportedForSession(internalApi);\n\n const renameContact = (\n input: RenameContactDAInput,\n ): Promise<Awaited<ReturnType<SendRenameContactTask[\"run\"]>>> =>\n new SendRenameContactTask(internalApi, {\n previousContactName: input.previousContactName,\n newContactName: input.newContactName,\n groupHandle: input.groupHandle,\n hmacProof: input.hmacProof,\n }).run();\n\n return { isOsSupported, renameContact };\n }\n}\n\nexport type { RenameContactProof };\n"],
5
+ "mappings": "AAAA,OAEE,6BAAAA,EAEA,0BAAAC,EAEA,kBAAAC,EACA,2BAAAC,EACA,sBAAAC,MACK,kCACP,OAAS,QAAAC,EAAM,SAAAC,MAAa,YAC5B,OAAS,UAAAC,EAAQ,eAAAC,EAAa,SAAAC,MAAa,SAS3C,OAAS,mCAAAC,MAAuC,qDAChD,OAAS,mCAAAC,MAAuC,4CAChD,OAEE,yBAAAC,MACK,kDAEP,OAAS,8BAAAC,MAAkC,+BASpC,MAAMC,UAAkCV,CAM7C,CACA,iBACEW,EAOA,CASA,KAAM,CAAE,cAAAC,EAAe,cAAAC,CAAc,EACnC,KAAK,oBAAoBF,CAAW,EAEtC,OAAON,EAAM,CACX,MAAO,CACL,MAAO,CAAC,EACR,QAAS,CAAC,EACV,OAAQ,CAAC,CACX,EACA,OAAQ,CAIN,0BAA2B,IAAIT,EAA0B,CACvD,MAAO,CAAC,CACV,CAAC,EAAE,iBAAiBe,CAAW,EAC/B,cAAeP,EACb,CAAC,CAAE,MAAAU,CAAM,IAAuCD,EAAcC,CAAK,CACrE,CACF,EACA,OAAQ,CACN,gBAAiB,CAAC,CAAE,QAAAC,CAAQ,IAAMA,EAAQ,eAAe,QAAU,KACnE,oBAAqB,IAAMH,EAAc,CAC3C,EACA,QAAS,CACP,sBAAuBT,EAAO,CAC5B,eAAgB,CAAC,CAAE,QAAAY,CAAQ,IAAM,CAC/B,MAAMC,EAAQP,EAA2BM,EAAQ,KAAK,EACtD,OAAOC,EACH,CAAE,GAAGD,EAAQ,eAAgB,MAAAC,CAAM,EACnCD,EAAQ,cACd,CACF,CAAC,EACD,mBAAoBZ,EAAO,CACzB,eAAgB,CAAC,CAAE,QAAAY,CAAQ,KAAO,CAChC,GAAGA,EAAQ,eACX,MAAO,IAAIR,CACb,EACF,CAAC,EACD,qBAAsBJ,EAAO,CAC3B,eAAgB,CAAC,CAAE,QAAAY,EAAS,MAAAE,CAAM,KAAO,CACvC,GAAGF,EAAQ,eACX,MAAO,IAAIjB,EACTmB,EAAM,iBAAoB,MACtBA,EAAM,MAAS,QACf,OAAOA,EAAM,KAAQ,CAC3B,CACF,EACF,CAAC,CACH,CACF,CAAC,EAAE,cAAc,CACf,GAAI,4BACJ,QAAS,eACT,QAAS,CAAC,CAAE,MAAAH,CAAM,KAAO,CACvB,MAAAA,EACA,kBAAmB,CACjB,wBAAyBf,EAAwB,IACnD,EACA,eAAgB,CACd,MAAO,KACP,MAAO,IACT,CACF,GACA,OAAQ,CACN,aAAc,CACZ,OAAQ,CAAE,OAAQ,eAAgB,CACpC,EAGA,cAAe,CACb,OAAQ,CACN,GAAI,gBACJ,IAAK,4BACL,MAAO,KAAO,CAAC,GACf,WAAY,CACV,QAASI,EAAO,CAGd,kBAAmB,CAAC,CAAE,MAAAc,CAAM,KAAO,CACjC,wBACEA,EAAM,SAAS,QAAQ,kBACpB,uBACP,EACF,CAAC,CACH,EACA,OAAQ,CACN,OAAQ,qBACR,QAASd,EAAO,CACd,eAAgB,CAAC,CAAE,MAAAc,EAAO,QAAAF,CAAQ,IAChCE,EAAM,OAAO,OAAqC,CAChD,MAAO,IAAMF,EAAQ,eACrB,KAAOC,IAAW,CAAE,GAAGD,EAAQ,eAAgB,MAAAC,CAAM,EACvD,CAAC,CACL,CAAC,CACH,EACA,QAAS,CACP,OAAQ,QACR,QAAS,sBACX,CACF,CACF,EACA,mBAAoB,CAClB,OAAQ,CACN,CAAE,OAAQ,gBAAiB,MAAO,iBAAkB,EACpD,CAAE,OAAQ,OAAQ,CACpB,CACF,EAIA,cAAe,CACb,MAAO,wBACP,OAAQ,CACN,CAAE,OAAQ,eAAgB,MAAO,iBAAkB,EACnD,CAAE,OAAQ,OAAQ,CACpB,CACF,EAGA,aAAc,CACZ,OAAQ,CACN,CAAE,OAAQ,gBAAiB,MAAO,qBAAsB,EACxD,CAAE,OAAQ,QAAS,QAAS,oBAAqB,CACnD,CACF,EACA,cAAe,CACb,MAAOb,EAAO,CACZ,kBAAmB,CACjB,wBAAyBJ,EAAwB,cACnD,CACF,CAAC,EACD,KAAMI,EAAO,CACX,kBAAmB,CACjB,wBAAyBJ,EAAwB,IACnD,CACF,CAAC,EACD,OAAQ,CACN,GAAI,gBACJ,IAAK,gBACL,MAAO,CAAC,CAAE,QAAAgB,CAAQ,IAAMA,EAAQ,MAChC,OAAQ,CACN,OAAQ,2BACR,QAASZ,EAAO,CACd,eAAgB,CAAC,CAAE,MAAAc,EAAO,QAAAF,CAAQ,IAChClB,EAAuBoB,EAAM,MAAM,EAC/B,CAAE,GAAGF,EAAQ,eAAgB,MAAOE,EAAM,OAAO,IAAK,EACtD,CACE,GAAGF,EAAQ,eACX,MAAOE,EAAM,OAAO,KACtB,CACR,CAAC,CACH,EACA,QAAS,CACP,OAAQ,QACR,QAAS,sBACX,CACF,CACF,EACA,yBAA0B,CACxB,OAAQ,CACN,CAAE,OAAQ,UAAW,MAAO,iBAAkB,EAC9C,CAAE,OAAQ,OAAQ,CACpB,CACF,EACA,QAAS,CAAE,KAAM,OAAQ,EACzB,MAAO,CAAE,KAAM,OAAQ,CACzB,EACA,OAAQ,CAAC,CAAE,QAAAF,CAAQ,IAAM,CACvB,KAAM,CAAE,MAAAG,EAAO,MAAAF,CAAM,EAAID,EAAQ,eACjC,GAAIG,EAAO,CACT,KAAM,CAAE,MAAAJ,CAAM,EAAIC,EAClB,OAAOb,EAAM,CACX,oBAAqBY,EAAM,oBAC3B,YAAaA,EAAM,eACnB,YAAaA,EAAM,YACnB,UAAWI,EAAM,SACnB,CAAC,CACH,CACA,OAAOjB,EAAKe,GAAS,IAAIlB,EAAe,yBAAyB,CAAC,CACpE,CACF,CAAC,CACH,CAEA,oBACEa,EACkC,CAalC,MAAO,CAAE,cAZa,IAAML,EAAgCK,CAAW,EAY/C,cATtBG,GAEA,IAAIN,EAAsBG,EAAa,CACrC,oBAAqBG,EAAM,oBAC3B,eAAgBA,EAAM,eACtB,YAAaA,EAAM,YACnB,UAAWA,EAAM,SACnB,CAAC,EAAE,IAAI,CAE6B,CACxC,CACF",
6
+ "names": ["GoToDashboardDeviceAction", "isSuccessCommandResult", "UnknownDAError", "UserInteractionRequired", "XStateDeviceAction", "Left", "Right", "assign", "fromPromise", "setup", "isContactsOsSupportedForSession", "ContactsVersionRequirementError", "SendRenameContactTask", "validateRenameContactInput", "RenameContactDeviceAction", "internalApi", "isOsSupported", "renameContact", "input", "context", "error", "event", "proof"]
7
+ }
@@ -0,0 +1,2 @@
1
+ import{CommandResultFactory as C,DeviceActionStatus as e,DeviceModelId as k,DeviceSessionStateType as g,DeviceStatus as E,GoToDashboardDeviceAction as h,OpenAppDeviceAction as R,UnknownDAError as P,UserInteractionRequired as t}from"@ledgerhq/device-management-kit";import{beforeEach as S,describe as V,expect as s,it as D,vi as c}from"vitest";import{makeDeviceActionInternalApiMock as y}from"../../../app-binder/device-action/__test-utils__/makeInternalApi";import{setupGoToDashboardDAMock as v}from"../../../app-binder/device-action/__test-utils__/setupGoToDashboardDAMock";import{testDeviceActionStates as A}from"../../../app-binder/device-action/__test-utils__/testDeviceActionStates";import{ContactsCommandError as q,ContactsVersionRequirementError as O}from"../../../app-binder/model/contactsErrors";import{RenameContactDeviceAction as w}from"./RenameContactDeviceAction";import{validateRenameContactInput as N}from"./validateRenameContactInput";c.mock("@ledgerhq/device-management-kit",async a=>({...await a(),GoToDashboardDeviceAction:c.fn(()=>({makeStateMachine:c.fn()})),OpenAppDeviceAction:c.fn(()=>({makeStateMachine:c.fn()}))}));const f={hmacProof:new Uint8Array(32).fill(238)},m={previousContactName:"Alice",newContactName:"Bob",groupHandle:new Uint8Array(64).fill(204),hmacProof:new Uint8Array(32).fill(221)},T={previousContactName:"Alice",contactName:"Bob",groupHandle:m.groupHandle,hmacProof:f.hmacProof};V("RenameContactDeviceAction",()=>{let a,d,u;function U(){return{isOsSupported:d,renameContact:u}}S(()=>{c.clearAllMocks(),a=y(),d=c.fn().mockReturnValue(!0),u=c.fn().mockResolvedValue(C({data:f})),a.getDeviceSessionState.mockReturnValue({sessionStateType:g.ReadyWithoutSecureChannel,deviceStatus:E.CONNECTED,installedApps:[],currentApp:{name:"BOLOS",version:"1.7.0"},deviceModelId:k.FLEX,isSecureConnectionAllowed:!0})});function l(r){const n=new w({input:r});return c.spyOn(n,"extractDependencies").mockReturnValue(U()),n}D("navigates to the dashboard, checks the OS, renames, and completes",()=>new Promise((r,n)=>{v({requiredUserInteraction:t.UnlockDevice});const o=l(m),i=[{intermediateValue:{requiredUserInteraction:t.None},status:e.Pending},{intermediateValue:{requiredUserInteraction:t.UnlockDevice},status:e.Pending},{intermediateValue:{requiredUserInteraction:t.RegisterWallet},status:e.Pending},{output:T,status:e.Completed}];A(o,i,a,{onDone:()=>{s(h).toHaveBeenCalled(),s(R).not.toHaveBeenCalled(),r()},onError:n})})),D("rejects on an unsupported OS version without sending the APDU",()=>new Promise((r,n)=>{v({requiredUserInteraction:t.UnlockDevice}),d.mockReturnValue(!1);const o=l(m),i=[{intermediateValue:{requiredUserInteraction:t.None},status:e.Pending},{intermediateValue:{requiredUserInteraction:t.UnlockDevice},status:e.Pending},{error:new O,status:e.Error}];A(o,i,a,{onDone:()=>{s(u).not.toHaveBeenCalled(),s(R).not.toHaveBeenCalled(),r()},onError:n})})),D("surfaces a go-to-dashboard failure as the device action error",()=>new Promise((r,n)=>{const o=new P("go to dashboard failed");v({error:o,requiredUserInteraction:t.UnlockDevice});const i=l(m),p=[{intermediateValue:{requiredUserInteraction:t.None},status:e.Pending},{intermediateValue:{requiredUserInteraction:t.UnlockDevice},status:e.Pending},{error:o,status:e.Error}];A(i,p,a,{onDone:()=>{s(d).not.toHaveBeenCalled(),s(u).not.toHaveBeenCalled(),r()},onError:n})})),D("surfaces a rename command error (e.g. seed mismatch)",()=>new Promise((r,n)=>{v({requiredUserInteraction:t.UnlockDevice});const o=new q({errorCode:"6982",message:"wrong seed"});u.mockResolvedValue(C({error:o}));const i=l(m),p=[{intermediateValue:{requiredUserInteraction:t.None},status:e.Pending},{intermediateValue:{requiredUserInteraction:t.UnlockDevice},status:e.Pending},{intermediateValue:{requiredUserInteraction:t.RegisterWallet},status:e.Pending},{error:o,status:e.Error}];A(i,p,a,{onDone:r,onError:n})})),D("surfaces invalid input as a typed error after reaching the dashboard",()=>new Promise((r,n)=>{v({requiredUserInteraction:t.UnlockDevice});const o={...m,newContactName:""},i=N(o),p=l(o),I=[{intermediateValue:{requiredUserInteraction:t.None},status:e.Pending},{intermediateValue:{requiredUserInteraction:t.UnlockDevice},status:e.Pending},{error:i,status:e.Error}];A(p,I,a,{onDone:()=>{s(d).not.toHaveBeenCalled(),s(u).not.toHaveBeenCalled(),r()},onError:n})}))});
2
+ //# sourceMappingURL=RenameContactDeviceAction.test.js.map
@@ -0,0 +1,7 @@
1
+ {
2
+ "version": 3,
3
+ "sources": ["../../../../../../src/internal/app-binder/device-action/RenameContact/RenameContactDeviceAction.test.ts"],
4
+ "sourcesContent": ["import {\n CommandResultFactory,\n type DeviceActionState,\n DeviceActionStatus,\n DeviceModelId,\n DeviceSessionStateType,\n DeviceStatus,\n GoToDashboardDeviceAction,\n OpenAppDeviceAction,\n UnknownDAError,\n UserInteractionRequired,\n} from \"@ledgerhq/device-management-kit\";\nimport { beforeEach, describe, expect, it, vi } from \"vitest\";\n\nimport {\n type RenameContactDAError,\n type RenameContactDAInput,\n type RenameContactDAIntermediateValue,\n type RenameContactDAOutput,\n} from \"@api/app-binder/RenameContactDeviceActionTypes\";\nimport { makeDeviceActionInternalApiMock } from \"@internal/app-binder/device-action/__test-utils__/makeInternalApi\";\nimport { setupGoToDashboardDAMock } from \"@internal/app-binder/device-action/__test-utils__/setupGoToDashboardDAMock\";\nimport { testDeviceActionStates } from \"@internal/app-binder/device-action/__test-utils__/testDeviceActionStates\";\nimport {\n ContactsCommandError,\n ContactsVersionRequirementError,\n} from \"@internal/app-binder/model/contactsErrors\";\n\nimport { RenameContactDeviceAction } from \"./RenameContactDeviceAction\";\nimport { validateRenameContactInput } from \"./validateRenameContactInput\";\n\nvi.mock(\"@ledgerhq/device-management-kit\", async (importOriginal) => {\n const original =\n // eslint-disable-next-line @typescript-eslint/consistent-type-imports\n await importOriginal<typeof import(\"@ledgerhq/device-management-kit\")>();\n return {\n ...original,\n GoToDashboardDeviceAction: vi.fn(() => ({\n makeStateMachine: vi.fn(),\n })),\n OpenAppDeviceAction: vi.fn(() => ({\n makeStateMachine: vi.fn(),\n })),\n };\n});\n\nconst OK_PROOF = { hmacProof: new Uint8Array(32).fill(0xee) };\n\nconst BASE_INPUT: RenameContactDAInput = {\n previousContactName: \"Alice\",\n newContactName: \"Bob\",\n groupHandle: new Uint8Array(64).fill(0xcc),\n hmacProof: new Uint8Array(32).fill(0xdd),\n};\n\nconst EXPECTED_OUTPUT: RenameContactDAOutput = {\n previousContactName: \"Alice\",\n contactName: \"Bob\",\n groupHandle: BASE_INPUT.groupHandle,\n hmacProof: OK_PROOF.hmacProof,\n};\n\ndescribe(\"RenameContactDeviceAction\", () => {\n let apiMock: ReturnType<typeof makeDeviceActionInternalApiMock>;\n let isOsSupportedMock: ReturnType<typeof vi.fn>;\n let renameContactMock: ReturnType<typeof vi.fn>;\n\n function extractDeps() {\n return {\n isOsSupported: isOsSupportedMock,\n renameContact: renameContactMock,\n };\n }\n\n beforeEach(() => {\n vi.clearAllMocks();\n apiMock = makeDeviceActionInternalApiMock();\n isOsSupportedMock = vi.fn().mockReturnValue(true);\n renameContactMock = vi\n .fn()\n .mockResolvedValue(CommandResultFactory({ data: OK_PROOF }));\n apiMock.getDeviceSessionState.mockReturnValue({\n sessionStateType: DeviceSessionStateType.ReadyWithoutSecureChannel,\n deviceStatus: DeviceStatus.CONNECTED,\n installedApps: [],\n currentApp: { name: \"BOLOS\", version: \"1.7.0\" },\n deviceModelId: DeviceModelId.FLEX,\n isSecureConnectionAllowed: true,\n });\n });\n\n function makeAction(input: RenameContactDAInput) {\n const action = new RenameContactDeviceAction({ input });\n vi.spyOn(action, \"extractDependencies\").mockReturnValue(extractDeps());\n return action;\n }\n\n it(\"navigates to the dashboard, checks the OS, renames, and completes\", () =>\n new Promise<void>((resolve, reject) => {\n setupGoToDashboardDAMock({\n requiredUserInteraction: UserInteractionRequired.UnlockDevice,\n });\n const action = makeAction(BASE_INPUT);\n\n const expected = [\n {\n intermediateValue: {\n requiredUserInteraction: UserInteractionRequired.None,\n },\n status: DeviceActionStatus.Pending,\n },\n {\n intermediateValue: {\n requiredUserInteraction: UserInteractionRequired.UnlockDevice,\n },\n status: DeviceActionStatus.Pending,\n },\n {\n intermediateValue: {\n requiredUserInteraction: UserInteractionRequired.RegisterWallet,\n },\n status: DeviceActionStatus.Pending,\n },\n {\n output: EXPECTED_OUTPUT,\n status: DeviceActionStatus.Completed,\n },\n ] as DeviceActionState<\n RenameContactDAOutput,\n RenameContactDAError,\n RenameContactDAIntermediateValue\n >[];\n\n testDeviceActionStates(action, expected, apiMock, {\n onDone: () => {\n // Rename is a dashboard op: it navigates to the dashboard and never\n // opens an app.\n expect(GoToDashboardDeviceAction).toHaveBeenCalled();\n expect(OpenAppDeviceAction).not.toHaveBeenCalled();\n resolve();\n },\n onError: reject,\n });\n }));\n\n it(\"rejects on an unsupported OS version without sending the APDU\", () =>\n new Promise<void>((resolve, reject) => {\n setupGoToDashboardDAMock({\n requiredUserInteraction: UserInteractionRequired.UnlockDevice,\n });\n isOsSupportedMock.mockReturnValue(false);\n const action = makeAction(BASE_INPUT);\n\n const expected = [\n {\n intermediateValue: {\n requiredUserInteraction: UserInteractionRequired.None,\n },\n status: DeviceActionStatus.Pending,\n },\n {\n intermediateValue: {\n requiredUserInteraction: UserInteractionRequired.UnlockDevice,\n },\n status: DeviceActionStatus.Pending,\n },\n {\n error: new ContactsVersionRequirementError(),\n status: DeviceActionStatus.Error,\n },\n ] as DeviceActionState<\n RenameContactDAOutput,\n RenameContactDAError,\n RenameContactDAIntermediateValue\n >[];\n\n testDeviceActionStates(action, expected, apiMock, {\n onDone: () => {\n expect(renameContactMock).not.toHaveBeenCalled();\n expect(OpenAppDeviceAction).not.toHaveBeenCalled();\n resolve();\n },\n onError: reject,\n });\n }));\n\n it(\"surfaces a go-to-dashboard failure as the device action error\", () =>\n new Promise<void>((resolve, reject) => {\n const dashboardError = new UnknownDAError(\"go to dashboard failed\");\n setupGoToDashboardDAMock({\n error: dashboardError,\n requiredUserInteraction: UserInteractionRequired.UnlockDevice,\n });\n const action = makeAction(BASE_INPUT);\n\n const expected = [\n {\n intermediateValue: {\n requiredUserInteraction: UserInteractionRequired.None,\n },\n status: DeviceActionStatus.Pending,\n },\n {\n intermediateValue: {\n requiredUserInteraction: UserInteractionRequired.UnlockDevice,\n },\n status: DeviceActionStatus.Pending,\n },\n {\n error: dashboardError,\n status: DeviceActionStatus.Error,\n },\n ] as DeviceActionState<\n RenameContactDAOutput,\n RenameContactDAError,\n RenameContactDAIntermediateValue\n >[];\n\n testDeviceActionStates(action, expected, apiMock, {\n onDone: () => {\n expect(isOsSupportedMock).not.toHaveBeenCalled();\n expect(renameContactMock).not.toHaveBeenCalled();\n resolve();\n },\n onError: reject,\n });\n }));\n\n it(\"surfaces a rename command error (e.g. seed mismatch)\", () =>\n new Promise<void>((resolve, reject) => {\n setupGoToDashboardDAMock({\n requiredUserInteraction: UserInteractionRequired.UnlockDevice,\n });\n const commandError = new ContactsCommandError({\n errorCode: \"6982\",\n message: \"wrong seed\",\n });\n renameContactMock.mockResolvedValue(\n CommandResultFactory({ error: commandError }),\n );\n const action = makeAction(BASE_INPUT);\n\n const expected = [\n {\n intermediateValue: {\n requiredUserInteraction: UserInteractionRequired.None,\n },\n status: DeviceActionStatus.Pending,\n },\n {\n intermediateValue: {\n requiredUserInteraction: UserInteractionRequired.UnlockDevice,\n },\n status: DeviceActionStatus.Pending,\n },\n {\n intermediateValue: {\n requiredUserInteraction: UserInteractionRequired.RegisterWallet,\n },\n status: DeviceActionStatus.Pending,\n },\n {\n error: commandError,\n status: DeviceActionStatus.Error,\n },\n ] as DeviceActionState<\n RenameContactDAOutput,\n RenameContactDAError,\n RenameContactDAIntermediateValue\n >[];\n\n testDeviceActionStates(action, expected, apiMock, {\n onDone: resolve,\n onError: reject,\n });\n }));\n\n it(\"surfaces invalid input as a typed error after reaching the dashboard\", () =>\n new Promise<void>((resolve, reject) => {\n setupGoToDashboardDAMock({\n requiredUserInteraction: UserInteractionRequired.UnlockDevice,\n });\n const invalidInput = { ...BASE_INPUT, newContactName: \"\" };\n const validationError = validateRenameContactInput(invalidInput);\n const action = makeAction(invalidInput);\n\n const expected = [\n {\n intermediateValue: {\n requiredUserInteraction: UserInteractionRequired.None,\n },\n status: DeviceActionStatus.Pending,\n },\n {\n intermediateValue: {\n requiredUserInteraction: UserInteractionRequired.UnlockDevice,\n },\n status: DeviceActionStatus.Pending,\n },\n {\n error: validationError,\n status: DeviceActionStatus.Error,\n },\n ] as DeviceActionState<\n RenameContactDAOutput,\n RenameContactDAError,\n RenameContactDAIntermediateValue\n >[];\n\n testDeviceActionStates(action, expected, apiMock, {\n onDone: () => {\n // Validation fails before the version guard and before any APDU.\n expect(isOsSupportedMock).not.toHaveBeenCalled();\n expect(renameContactMock).not.toHaveBeenCalled();\n resolve();\n },\n onError: reject,\n });\n }));\n});\n"],
5
+ "mappings": "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",
6
+ "names": ["CommandResultFactory", "DeviceActionStatus", "DeviceModelId", "DeviceSessionStateType", "DeviceStatus", "GoToDashboardDeviceAction", "OpenAppDeviceAction", "UnknownDAError", "UserInteractionRequired", "beforeEach", "describe", "expect", "it", "vi", "makeDeviceActionInternalApiMock", "setupGoToDashboardDAMock", "testDeviceActionStates", "ContactsCommandError", "ContactsVersionRequirementError", "RenameContactDeviceAction", "validateRenameContactInput", "importOriginal", "OK_PROOF", "BASE_INPUT", "EXPECTED_OUTPUT", "apiMock", "isOsSupportedMock", "renameContactMock", "extractDeps", "makeAction", "input", "action", "resolve", "reject", "expected", "dashboardError", "commandError", "invalidInput", "validationError"]
7
+ }
@@ -0,0 +1,2 @@
1
+ import{CONTACT_NAME_BUFFER_LENGTH as a,ContactsValidationError as r,GROUP_HANDLE_SIZE as c,HMAC_PROOF_LENGTH as l,validateByteLength as n,validatePrintableLabel as o}from"../../../app-binder/model/contactsValidation";function f(e){try{return o(e.newContactName,{field:"newContactName",bufferLength:a}),o(e.previousContactName,{field:"previousContactName",bufferLength:a}),n(e.groupHandle,{field:"groupHandle",expectedBytes:c}),n(e.hmacProof,{field:"hmacProof",expectedBytes:l}),null}catch(t){if(t instanceof r)return t;throw t}}export{f as validateRenameContactInput};
2
+ //# sourceMappingURL=validateRenameContactInput.js.map
@@ -0,0 +1,7 @@
1
+ {
2
+ "version": 3,
3
+ "sources": ["../../../../../../src/internal/app-binder/device-action/RenameContact/validateRenameContactInput.ts"],
4
+ "sourcesContent": ["import { type RenameContactInput } from \"@api/model/RenameContact\";\nimport {\n CONTACT_NAME_BUFFER_LENGTH,\n ContactsValidationError,\n GROUP_HANDLE_SIZE,\n HMAC_PROOF_LENGTH,\n validateByteLength,\n validatePrintableLabel,\n} from \"@internal/app-binder/model/contactsValidation\";\n\n/**\n * Validate the caller input for Rename Contact. Returns the first\n * `ContactsValidationError` found, or `null` when the input is valid.\n *\n * Non-throwing by design: the device action calls this so an invalid input is\n * surfaced as a typed terminal error state on the observable, keeping the public\n * `ContactsManager.renameContact` free of synchronous throws.\n */\nexport function validateRenameContactInput(\n input: RenameContactInput,\n): ContactsValidationError | null {\n try {\n validatePrintableLabel(input.newContactName, {\n field: \"newContactName\",\n bufferLength: CONTACT_NAME_BUFFER_LENGTH,\n });\n validatePrintableLabel(input.previousContactName, {\n field: \"previousContactName\",\n bufferLength: CONTACT_NAME_BUFFER_LENGTH,\n });\n validateByteLength(input.groupHandle, {\n field: \"groupHandle\",\n expectedBytes: GROUP_HANDLE_SIZE,\n });\n validateByteLength(input.hmacProof, {\n field: \"hmacProof\",\n expectedBytes: HMAC_PROOF_LENGTH,\n });\n\n return null;\n } catch (error) {\n if (error instanceof ContactsValidationError) {\n return error;\n }\n throw error;\n }\n}\n"],
5
+ "mappings": "AACA,OACE,8BAAAA,EACA,2BAAAC,EACA,qBAAAC,EACA,qBAAAC,EACA,sBAAAC,EACA,0BAAAC,MACK,gDAUA,SAASC,EACdC,EACgC,CAChC,GAAI,CACF,OAAAF,EAAuBE,EAAM,eAAgB,CAC3C,MAAO,iBACP,aAAcP,CAChB,CAAC,EACDK,EAAuBE,EAAM,oBAAqB,CAChD,MAAO,sBACP,aAAcP,CAChB,CAAC,EACDI,EAAmBG,EAAM,YAAa,CACpC,MAAO,cACP,cAAeL,CACjB,CAAC,EACDE,EAAmBG,EAAM,UAAW,CAClC,MAAO,YACP,cAAeJ,CACjB,CAAC,EAEM,IACT,OAASK,EAAO,CACd,GAAIA,aAAiBP,EACnB,OAAOO,EAET,MAAMA,CACR,CACF",
6
+ "names": ["CONTACT_NAME_BUFFER_LENGTH", "ContactsValidationError", "GROUP_HANDLE_SIZE", "HMAC_PROOF_LENGTH", "validateByteLength", "validatePrintableLabel", "validateRenameContactInput", "input", "error"]
7
+ }
@@ -0,0 +1,2 @@
1
+ import{ContactsValidationError as n}from"../../../app-binder/model/contactsValidation";import{validateRenameContactInput as t}from"./validateRenameContactInput";const e={previousContactName:"Alice",newContactName:"Bob",groupHandle:new Uint8Array(64).fill(204),hmacProof:new Uint8Array(32).fill(221)};describe("validateRenameContactInput",()=>{it("returns null for valid input",()=>{expect(t(e)).toBeNull()}),it("returns a ContactsValidationError for a non-printable new name",()=>{expect(t({...e,newContactName:"Am\xE9lie"})).toBeInstanceOf(n)}),it("returns a ContactsValidationError for a non-printable previous name",()=>{expect(t({...e,previousContactName:"Am\xE9lie"})).toBeInstanceOf(n)}),it("returns an error for an empty new name",()=>{expect(t({...e,newContactName:""})).toBeInstanceOf(n)}),it("returns an error for a group handle of the wrong length",()=>{expect(t({...e,groupHandle:new Uint8Array(63)})).toBeInstanceOf(n)}),it("returns an error for an hmac proof of the wrong length",()=>{expect(t({...e,hmacProof:new Uint8Array(31)})).toBeInstanceOf(n)})});
2
+ //# sourceMappingURL=validateRenameContactInput.test.js.map
@@ -0,0 +1,7 @@
1
+ {
2
+ "version": 3,
3
+ "sources": ["../../../../../../src/internal/app-binder/device-action/RenameContact/validateRenameContactInput.test.ts"],
4
+ "sourcesContent": ["import { type RenameContactInput } from \"@api/model/RenameContact\";\nimport { ContactsValidationError } from \"@internal/app-binder/model/contactsValidation\";\n\nimport { validateRenameContactInput } from \"./validateRenameContactInput\";\n\nconst VALID_INPUT: RenameContactInput = {\n previousContactName: \"Alice\",\n newContactName: \"Bob\",\n groupHandle: new Uint8Array(64).fill(0xcc),\n hmacProof: new Uint8Array(32).fill(0xdd),\n};\n\ndescribe(\"validateRenameContactInput\", () => {\n it(\"returns null for valid input\", () => {\n expect(validateRenameContactInput(VALID_INPUT)).toBeNull();\n });\n\n it(\"returns a ContactsValidationError for a non-printable new name\", () => {\n expect(\n validateRenameContactInput({ ...VALID_INPUT, newContactName: \"Am\u00E9lie\" }),\n ).toBeInstanceOf(ContactsValidationError);\n });\n\n it(\"returns a ContactsValidationError for a non-printable previous name\", () => {\n expect(\n validateRenameContactInput({\n ...VALID_INPUT,\n previousContactName: \"Am\u00E9lie\",\n }),\n ).toBeInstanceOf(ContactsValidationError);\n });\n\n it(\"returns an error for an empty new name\", () => {\n expect(\n validateRenameContactInput({ ...VALID_INPUT, newContactName: \"\" }),\n ).toBeInstanceOf(ContactsValidationError);\n });\n\n it(\"returns an error for a group handle of the wrong length\", () => {\n expect(\n validateRenameContactInput({\n ...VALID_INPUT,\n groupHandle: new Uint8Array(63),\n }),\n ).toBeInstanceOf(ContactsValidationError);\n });\n\n it(\"returns an error for an hmac proof of the wrong length\", () => {\n expect(\n validateRenameContactInput({\n ...VALID_INPUT,\n hmacProof: new Uint8Array(31),\n }),\n ).toBeInstanceOf(ContactsValidationError);\n });\n});\n"],
5
+ "mappings": "AACA,OAAS,2BAAAA,MAA+B,gDAExC,OAAS,8BAAAC,MAAkC,+BAE3C,MAAMC,EAAkC,CACtC,oBAAqB,QACrB,eAAgB,MAChB,YAAa,IAAI,WAAW,EAAE,EAAE,KAAK,GAAI,EACzC,UAAW,IAAI,WAAW,EAAE,EAAE,KAAK,GAAI,CACzC,EAEA,SAAS,6BAA8B,IAAM,CAC3C,GAAG,+BAAgC,IAAM,CACvC,OAAOD,EAA2BC,CAAW,CAAC,EAAE,SAAS,CAC3D,CAAC,EAED,GAAG,iEAAkE,IAAM,CACzE,OACED,EAA2B,CAAE,GAAGC,EAAa,eAAgB,WAAS,CAAC,CACzE,EAAE,eAAeF,CAAuB,CAC1C,CAAC,EAED,GAAG,sEAAuE,IAAM,CAC9E,OACEC,EAA2B,CACzB,GAAGC,EACH,oBAAqB,WACvB,CAAC,CACH,EAAE,eAAeF,CAAuB,CAC1C,CAAC,EAED,GAAG,yCAA0C,IAAM,CACjD,OACEC,EAA2B,CAAE,GAAGC,EAAa,eAAgB,EAAG,CAAC,CACnE,EAAE,eAAeF,CAAuB,CAC1C,CAAC,EAED,GAAG,0DAA2D,IAAM,CAClE,OACEC,EAA2B,CACzB,GAAGC,EACH,YAAa,IAAI,WAAW,EAAE,CAChC,CAAC,CACH,EAAE,eAAeF,CAAuB,CAC1C,CAAC,EAED,GAAG,yDAA0D,IAAM,CACjE,OACEC,EAA2B,CACzB,GAAGC,EACH,UAAW,IAAI,WAAW,EAAE,CAC9B,CAAC,CACH,EAAE,eAAeF,CAAuB,CAC1C,CAAC,CACH,CAAC",
6
+ "names": ["ContactsValidationError", "validateRenameContactInput", "VALID_INPUT"]
7
+ }
@@ -0,0 +1,2 @@
1
+ import{GoToDashboardDeviceAction as t,UserInteractionRequired as n}from"@ledgerhq/device-management-kit";import{Left as o,Right as i}from"purify-ts";import{assign as a,createMachine as c}from"xstate";const p=(e={})=>{const r=e.requiredUserInteraction??n.None;t.mockImplementation(()=>({makeStateMachine:vi.fn().mockImplementation(()=>c({initial:"pending",states:{pending:{entry:a({intermediateValue:{requiredUserInteraction:r}}),after:{0:"done"}},done:{type:"final"}},output:()=>e.error?o(e.error):i(void 0)}))}))};export{p as setupGoToDashboardDAMock};
2
+ //# sourceMappingURL=setupGoToDashboardDAMock.js.map