@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
package/README.md CHANGED
@@ -55,8 +55,35 @@ observable.subscribe((state) => {
55
55
  });
56
56
  ```
57
57
 
58
- Concrete Contacts operations (Edit Contact Name, Edit Identifier, Edit Scope, Register Ledger
59
- Account, Edit Ledger Account) are added by their dedicated implementation tickets.
58
+ ## Renaming a contact
59
+
60
+ `renameContact` runs the device's EDIT CONTACT NAME operation. Unlike the register operations, this
61
+ is a blockchain-agnostic **dashboard** command served by the device OS: it always navigates to the
62
+ dashboard first (never opens an app), checks only the [minimum OS version](#version-requirements),
63
+ then rotates the contact group's name proof. Pass the current name, the new name, the group's
64
+ `groupHandle`, and the existing `hmacProof`; the op returns the replacement group-level `hmacProof`
65
+ for the host to persist. Per-entry `hmacRest` values are untouched — they never cover the name.
66
+
67
+ ```ts
68
+ const { observable } = contactsManager.renameContact({
69
+ previousContactName: "Alice",
70
+ newContactName: "Bob",
71
+ groupHandle, // 64 bytes, from the group's Register Identity
72
+ hmacProof, // 32 bytes, the current name proof
73
+ });
74
+
75
+ observable.subscribe((state) => {
76
+ // state.intermediateValue.requiredUserInteraction surfaces the go-to-dashboard
77
+ // steps and the on-device validation.
78
+ if (state.status === DeviceActionStatus.Completed) {
79
+ const { contactName, groupHandle, hmacProof } = state.output;
80
+ // persist the new name and the replacement hmacProof.
81
+ }
82
+ });
83
+ ```
84
+
85
+ Concrete Contacts operations (Edit Identifier, Edit Scope, Register Ledger Account, Edit Ledger
86
+ Account) are added by their dedicated implementation tickets.
60
87
 
61
88
  ## Version requirements
62
89
 
@@ -1,2 +1,2 @@
1
- "use strict";var n=Object.defineProperty;var p=Object.getOwnPropertyDescriptor;var a=Object.getOwnPropertyNames;var i=Object.prototype.hasOwnProperty;var A=(r,e,d,s)=>{if(e&&typeof e=="object"||typeof e=="function")for(let t of a(e))!i.call(r,t)&&t!==d&&n(r,t,{get:()=>e[t],enumerable:!(s=p(e,t))||s.enumerable});return r};var g=r=>A(n({},"__esModule",{value:!0}),r);var o={};module.exports=g(o);
1
+ "use strict";var a=Object.defineProperty;var s=Object.getOwnPropertyDescriptor;var o=Object.getOwnPropertyNames;var m=Object.prototype.hasOwnProperty;var i=(t,e,p,n)=>{if(e&&typeof e=="object"||typeof e=="function")for(let r of o(e))!m.call(t,r)&&r!==p&&a(t,r,{get:()=>e[r],enumerable:!(n=s(e,r))||n.enumerable});return t};var R=t=>i(a({},"__esModule",{value:!0}),t);var d={};module.exports=R(d);
2
2
  //# sourceMappingURL=ContactsManager.js.map
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "version": 3,
3
3
  "sources": ["../../../src/api/ContactsManager.ts"],
4
- "sourcesContent": ["import { type RegisterExternalAddressDAReturnType } from \"@api/app-binder/RegisterExternalAddressDeviceActionTypes\";\nimport { type RegisterExternalAddressInput } from \"@api/model/RegisterExternalAddress\";\n\n/**\n * Public, stateless Contacts (Address Book) manager.\n *\n * It only drives device interactions \u2014 taking caller input, running the device\n * operation, and returning the device output (including proof material). It\n * does not store anything, own the address book, or handle persistence; the\n * host is responsible for that.\n */\nexport interface ContactsManager {\n /**\n * Register an external address on the device \u2014 either creating a new contact\n * group or adding the address to an existing one (via\n * `input.existingContactGroup`). Opens the embedded app by default (pass\n * `skipOpenApp: true` to skip only the open-app step; the version guard still\n * runs), checks the Contacts version requirements, then runs REGISTER\n * IDENTITY. Returns the device-issued group handle and proofs to persist.\n */\n registerExternalAddress(\n input: RegisterExternalAddressInput,\n ): RegisterExternalAddressDAReturnType;\n}\n"],
4
+ "sourcesContent": ["import { 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\";\n\n/**\n * Public, stateless Contacts (Address Book) manager.\n *\n * It only drives device interactions \u2014 taking caller input, running the device\n * operation, and returning the device output (including proof material). It\n * does not store anything, own the address book, or handle persistence; the\n * host is responsible for that.\n */\nexport interface ContactsManager {\n /**\n * Register an external address on the device \u2014 either creating a new contact\n * group or adding the address to an existing one (via\n * `input.existingContactGroup`). Opens the embedded app by default (pass\n * `skipOpenApp: true` to skip only the open-app step; the version guard still\n * runs), checks the Contacts version requirements, then runs REGISTER\n * IDENTITY. Returns the device-issued group handle and proofs to persist.\n */\n registerExternalAddress(\n input: RegisterExternalAddressInput,\n ): RegisterExternalAddressDAReturnType;\n\n /**\n * Rename an existing contact group (EDIT CONTACT NAME). This is a\n * blockchain-agnostic dashboard operation served by the device OS: it always\n * navigates to the dashboard first (never opens an app), checks the Contacts\n * minimum OS version, then rotates the group's name proof. Pass the current\n * `previousContactName`, the `newContactName`, the group's `groupHandle`, and\n * the existing `hmacProof`; returns the replacement group-level `hmacProof` to\n * persist.\n */\n renameContact(input: RenameContactInput): RenameContactDAReturnType;\n}\n"],
5
5
  "mappings": "+WAAA,IAAAA,EAAA,kBAAAC,EAAAD",
6
6
  "names": ["ContactsManager_exports", "__toCommonJS"]
7
7
  }
@@ -0,0 +1,2 @@
1
+ "use strict";var n=Object.defineProperty;var c=Object.getOwnPropertyDescriptor;var p=Object.getOwnPropertyNames;var i=Object.prototype.hasOwnProperty;var m=(t,e,a,o)=>{if(e&&typeof e=="object"||typeof e=="function")for(let r of p(e))!i.call(t,r)&&r!==a&&n(t,r,{get:()=>e[r],enumerable:!(o=c(e,r))||o.enumerable});return t};var u=t=>m(n({},"__esModule",{value:!0}),t);var R={};module.exports=u(R);
2
+ //# sourceMappingURL=RenameContactDeviceActionTypes.js.map
@@ -0,0 +1,7 @@
1
+ {
2
+ "version": 3,
3
+ "sources": ["../../../../src/api/app-binder/RenameContactDeviceActionTypes.ts"],
4
+ "sourcesContent": ["import {\n type CommandErrorResult,\n type DeviceActionState,\n type ExecuteDeviceActionReturnType,\n type GoToDashboardDAError,\n type GoToDashboardDARequiredInteraction,\n type UserInteractionRequired,\n} from \"@ledgerhq/device-management-kit\";\n\nimport {\n type RenameContactInput,\n type RenameContactOutput,\n} from \"@api/model/RenameContact\";\nimport {\n type ContactsErrorCodes,\n type ContactsVersionRequirementError,\n} from \"@internal/app-binder/model/contactsErrors\";\nimport { type ContactsValidationError } from \"@internal/app-binder/model/contactsValidation\";\n\n/**\n * Rename is a dashboard operation, so the machine input is exactly the public\n * input \u2014 no embedded-app name is injected (the OS serves the command; there is\n * no app to open).\n */\nexport type RenameContactDAInput = RenameContactInput;\n\nexport type RenameContactDAOutput = RenameContactOutput;\n\nexport type RenameContactDAError =\n | GoToDashboardDAError\n | ContactsValidationError\n | ContactsVersionRequirementError\n | CommandErrorResult<ContactsErrorCodes>[\"error\"];\n\nexport type RenameContactDARequiredInteraction =\n | GoToDashboardDARequiredInteraction\n | UserInteractionRequired.RegisterWallet;\n\nexport type RenameContactDAIntermediateValue = {\n readonly requiredUserInteraction: RenameContactDARequiredInteraction;\n};\n\nexport type RenameContactDAState = DeviceActionState<\n RenameContactDAOutput,\n RenameContactDAError,\n RenameContactDAIntermediateValue\n>;\n\nexport type RenameContactDAInternalState = {\n readonly error: RenameContactDAError | null;\n readonly proof: {\n readonly hmacProof: Uint8Array;\n } | null;\n};\n\nexport type RenameContactDAReturnType = ExecuteDeviceActionReturnType<\n RenameContactDAOutput,\n RenameContactDAError,\n RenameContactDAIntermediateValue\n>;\n"],
5
+ "mappings": "+WAAA,IAAAA,EAAA,kBAAAC,EAAAD",
6
+ "names": ["RenameContactDeviceActionTypes_exports", "__toCommonJS"]
7
+ }
@@ -1,2 +1,2 @@
1
- "use strict";var p=Object.defineProperty;var d=Object.getOwnPropertyDescriptor;var i=Object.getOwnPropertyNames;var A=Object.prototype.hasOwnProperty;var E=(r,t)=>{for(var n in t)p(r,n,{get:t[n],enumerable:!0})},u=(r,t,n,o)=>{if(t&&typeof t=="object"||typeof t=="function")for(let s of i(t))!A.call(r,s)&&s!==n&&p(r,s,{get:()=>t[s],enumerable:!(o=d(t,s))||o.enumerable});return r};var y=r=>u(p({},"__esModule",{value:!0}),r);var R={};E(R,{CONTACTS_VERSION_REQUIREMENTS:()=>e.CONTACTS_VERSION_REQUIREMENTS,ContactsManagerBuilder:()=>a.ContactsManagerBuilder,ETHEREUM_APP_NAME:()=>e.ETHEREUM_APP_NAME,isContactsSupported:()=>e.isContactsSupported,isVersionAtLeast:()=>e.isVersionAtLeast,resolveContactsVersionRequirements:()=>e.resolveContactsVersionRequirements});module.exports=y(R);var a=require("./ContactsManagerBuilder"),e=require("./model/ContactsVersionRequirements");0&&(module.exports={CONTACTS_VERSION_REQUIREMENTS,ContactsManagerBuilder,ETHEREUM_APP_NAME,isContactsSupported,isVersionAtLeast,resolveContactsVersionRequirements});
1
+ "use strict";var a=Object.defineProperty;var d=Object.getOwnPropertyDescriptor;var R=Object.getOwnPropertyNames;var y=Object.prototype.hasOwnProperty;var u=(r,t)=>{for(var p in t)a(r,p,{get:t[p],enumerable:!0})},A=(r,t,p,o)=>{if(t&&typeof t=="object"||typeof t=="function")for(let n of R(t))!y.call(r,n)&&n!==p&&a(r,n,{get:()=>t[n],enumerable:!(o=d(t,n))||o.enumerable});return r};var i=r=>A(a({},"__esModule",{value:!0}),r);var c={};u(c,{CONTACTS_VERSION_REQUIREMENTS:()=>e.CONTACTS_VERSION_REQUIREMENTS,ContactsManagerBuilder:()=>s.ContactsManagerBuilder,ETHEREUM_APP_NAME:()=>e.ETHEREUM_APP_NAME,isContactsSupported:()=>e.isContactsSupported,isVersionAtLeast:()=>e.isVersionAtLeast,resolveContactsVersionRequirements:()=>e.resolveContactsVersionRequirements});module.exports=i(c);var s=require("./ContactsManagerBuilder"),e=require("./model/ContactsVersionRequirements");0&&(module.exports={CONTACTS_VERSION_REQUIREMENTS,ContactsManagerBuilder,ETHEREUM_APP_NAME,isContactsSupported,isVersionAtLeast,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": "yaAAA,IAAAA,EAAA,GAAAC,EAAAD,EAAA,oVAAAE,EAAAF,GAUA,IAAAG,EAAuC,uCACvCC,EAWO",
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": "yaAAA,IAAAA,EAAA,GAAAC,EAAAD,EAAA,oVAAAE,EAAAF,GAmBA,IAAAG,EAAuC,uCACvCC,EAWO",
6
6
  "names": ["api_exports", "__export", "__toCommonJS", "import_ContactsManagerBuilder", "import_ContactsVersionRequirements"]
7
7
  }
@@ -0,0 +1,2 @@
1
+ "use strict";var e=Object.defineProperty;var y=Object.getOwnPropertyDescriptor;var d=Object.getOwnPropertyNames;var i=Object.prototype.hasOwnProperty;var l=(n,a,o,t)=>{if(a&&typeof a=="object"||typeof a=="function")for(let r of d(a))!i.call(n,r)&&r!==o&&e(n,r,{get:()=>a[r],enumerable:!(t=y(a,r))||t.enumerable});return n};var p=n=>l(e({},"__esModule",{value:!0}),n);var c={};module.exports=p(c);
2
+ //# sourceMappingURL=RenameContact.js.map
@@ -0,0 +1,7 @@
1
+ {
2
+ "version": 3,
3
+ "sources": ["../../../../src/api/model/RenameContact.ts"],
4
+ "sourcesContent": ["/**\n * Public input/output types for `ContactsManager.renameContact`.\n *\n * Rename (EDIT CONTACT NAME) is a blockchain-agnostic OS/dashboard operation:\n * it rotates the contact-level `hmacProof` (the device's `hmac_name`) and\n * returns the fresh proof. The per-entry `hmacRest` values are untouched \u2014 they\n * bind scope/identifier/family/chainId, never the name \u2014 so only the group's\n * name proof needs re-persisting.\n *\n * Proof material (`groupHandle`, `hmacProof`) is passed and returned as raw\n * bytes; the host owns persistence and address-book state. `derivationPath` is\n * kit-internal and not exposed: the Ethereum app requires a path on the wire\n * (a default m/44'/60'/0'/0/0 is sent), but the rename itself is name-only.\n */\n\nexport type RenameContactInput = {\n /** The contact's current name, proven to the device via `hmacProof`. */\n readonly previousContactName: string;\n /** The new name to assign to the contact group. */\n readonly newContactName: string;\n /** 64-byte group handle returned by the group's Register Identity. */\n readonly groupHandle: Uint8Array;\n /**\n * The existing 32-byte name proof (device `hmac_name`) bound to the current\n * name \u2014 passed back so the device can verify continuity before approving the\n * rename. Replaced by the returned `hmacProof` on success.\n */\n readonly hmacProof: Uint8Array;\n};\n\nexport type RenameContactOutput = {\n /** Echoed previous name, for the host to locate the entry it is replacing. */\n readonly previousContactName: string;\n /** The new name now bound to the contact group. */\n readonly contactName: string;\n /** Echoed group handle, unchanged by the rename. */\n readonly groupHandle: Uint8Array;\n /** The replacement group-level name proof (rotated `hmac_name`) to persist. */\n readonly hmacProof: Uint8Array;\n};\n"],
5
+ "mappings": "+WAAA,IAAAA,EAAA,kBAAAC,EAAAD",
6
+ "names": ["RenameContact_exports", "__toCommonJS"]
7
+ }
@@ -1,2 +1,2 @@
1
- "use strict";var a=Object.defineProperty;var p=Object.getOwnPropertyDescriptor;var m=Object.getOwnPropertyNames;var d=Object.prototype.hasOwnProperty;var c=(t,e)=>{for(var r in e)a(t,r,{get:e[r],enumerable:!0})},g=(t,e,r,n)=>{if(e&&typeof e=="object"||typeof e=="function")for(let s of m(e))!d.call(t,s)&&s!==r&&a(t,s,{get:()=>e[s],enumerable:!(n=p(e,s))||n.enumerable});return t};var C=t=>g(a({},"__esModule",{value:!0}),t);var u={};c(u,{DefaultContactsManager:()=>l});module.exports=C(u);var o=require("./di"),i=require("./use-cases/di/useCaseTypes");class l{_container;constructor({dmk:e,sessionId:r,appName:n}){this._container=(0,o.makeContainer)({dmk:e,sessionId:r,appName:n})}registerExternalAddress(e){return this._container.get(i.useCaseTypes.RegisterExternalAddressUseCase).execute(e)}get container(){return this._container}}0&&(module.exports={DefaultContactsManager});
1
+ "use strict";var s=Object.defineProperty;var m=Object.getOwnPropertyDescriptor;var p=Object.getOwnPropertyNames;var c=Object.prototype.hasOwnProperty;var C=(t,e)=>{for(var r in e)s(t,r,{get:e[r],enumerable:!0})},d=(t,e,r,a)=>{if(e&&typeof e=="object"||typeof e=="function")for(let n of p(e))!c.call(t,n)&&n!==r&&s(t,n,{get:()=>e[n],enumerable:!(a=m(e,n))||a.enumerable});return t};var g=t=>d(s({},"__esModule",{value:!0}),t);var R={};C(R,{DefaultContactsManager:()=>u});module.exports=g(R);var i=require("./di"),o=require("./use-cases/di/useCaseTypes");class u{_container;constructor({dmk:e,sessionId:r,appName:a}){this._container=(0,i.makeContainer)({dmk:e,sessionId:r,appName:a})}registerExternalAddress(e){return this._container.get(o.useCaseTypes.RegisterExternalAddressUseCase).execute(e)}renameContact(e){return this._container.get(o.useCaseTypes.RenameContactUseCase).execute(e)}get container(){return this._container}}0&&(module.exports={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": "yaAAA,IAAAA,EAAA,GAAAC,EAAAD,EAAA,4BAAAE,IAAA,eAAAC,EAAAH,GASA,IAAAI,EAA8B,wBAC9BC,EAA6B,+CAStB,MAAMH,CAAkD,CAC5C,WAEjB,YAAY,CACV,IAAAI,EACA,UAAAC,EACA,QAAAC,CACF,EAA0C,CACxC,KAAK,cAAa,iBAAc,CAAE,IAAAF,EAAK,UAAAC,EAAW,QAAAC,CAAQ,CAAC,CAC7D,CAEA,wBACEC,EACqC,CACrC,OAAO,KAAK,WACT,IACC,eAAa,8BACf,EACC,QAAQA,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": "yaAAA,IAAAA,EAAA,GAAAC,EAAAD,EAAA,4BAAAE,IAAA,eAAAC,EAAAH,GAWA,IAAAI,EAA8B,wBAC9BC,EAA6B,+CAUtB,MAAMH,CAAkD,CAC5C,WAEjB,YAAY,CACV,IAAAI,EACA,UAAAC,EACA,QAAAC,CACF,EAA0C,CACxC,KAAK,cAAa,iBAAc,CAAE,IAAAF,EAAK,UAAAC,EAAW,QAAAC,CAAQ,CAAC,CAC7D,CAEA,wBACEC,EACqC,CACrC,OAAO,KAAK,WACT,IACC,eAAa,8BACf,EACC,QAAQA,CAAK,CAClB,CAEA,cAAcA,EAAsD,CAClE,OAAO,KAAK,WACT,IAA0B,eAAa,oBAAoB,EAC3D,QAAQA,CAAK,CAClB,CAMA,IAAc,WAAuB,CACnC,OAAO,KAAK,UACd,CACF",
6
6
  "names": ["DefaultContactsManager_exports", "__export", "DefaultContactsManager", "__toCommonJS", "import_di", "import_useCaseTypes", "dmk", "sessionId", "appName", "input"]
7
7
  }
@@ -1,2 +1,2 @@
1
- "use strict";var n=require("./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 n.DefaultContactsManager({dmk:t,sessionId:"session-id",appName:"Ethereum"}).registerExternalAddress(a);expect(e).toHaveBeenCalledTimes(1);const i=e.mock.calls[0][0];expect(i.sessionId).toBe("session-id"),expect(i.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},s=new n.DefaultContactsManager({dmk:t,sessionId:"session-id",appName:"Ethereum"});expect(()=>s.registerExternalAddress({...a,contactName:""})).not.toThrow(),expect(e).toHaveBeenCalledTimes(1)})});
1
+ "use strict";var s=require("./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},i=new s.DefaultContactsManager({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(i).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},a=new s.DefaultContactsManager({dmk:n,sessionId:"session-id",appName:"Ethereum"});expect(()=>a.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},i=new s.DefaultContactsManager({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(i).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,IAAAA,EAAuC,oCAEvC,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,IAAI,yBAAuB,CACzC,IAAAD,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,IAAI,yBAAuB,CACzC,IAAAH,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": ["import_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,IAAAA,EAAuC,oCAEvC,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,IAAI,yBAAuB,CACzC,IAAAD,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,IAAI,yBAAuB,CACzC,IAAAH,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,IAAI,yBAAuB,CACzC,IAAAD,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": ["import_DefaultContactsManager", "VALID_INPUT", "VALID_RENAME_INPUT", "executeDeviceAction", "dmk", "result", "call", "manager"]
7
7
  }
@@ -1,2 +1,2 @@
1
- "use strict";var d=Object.defineProperty;var l=Object.getOwnPropertyDescriptor;var x=Object.getOwnPropertyNames;var A=Object.prototype.hasOwnProperty;var D=(t,e)=>{for(var s in e)d(t,s,{get:e[s],enumerable:!0})},u=(t,e,s,i)=>{if(e&&typeof e=="object"||typeof e=="function")for(let r of x(e))!A.call(t,r)&&r!==s&&d(t,r,{get:()=>e[r],enumerable:!(i=l(e,r))||i.enumerable});return t};var I=t=>u(d({},"__esModule",{value:!0}),t),y=(t,e,s,i)=>{for(var r=i>1?void 0:i?l(e,s):e,a=t.length-1,c;a>=0;a--)(c=t[a])&&(r=(i?c(e,s,r):c(r))||r);return i&&r&&d(e,s,r),r},p=(t,e)=>(s,i)=>e(s,i,t);var v={};D(v,{ContactsAppBinder:()=>o});module.exports=I(v);var n=require("inversify"),g=require("../app-binder/device-action/RegisterExternalAddress/RegisterExternalAddressDeviceAction"),m=require("../externalTypes");let o=class{constructor(e,s,i){this.dmk=e;this.sessionId=s;this.appName=i}registerExternalAddress(e){return this.dmk.executeDeviceAction({sessionId:this.sessionId,deviceAction:new g.RegisterExternalAddressDeviceAction({input:{...e,appName:this.appName}})})}};o=y([(0,n.injectable)(),p(0,(0,n.inject)(m.externalTypes.Dmk)),p(1,(0,n.inject)(m.externalTypes.SessionId)),p(2,(0,n.inject)(m.externalTypes.AppName))],o);0&&(module.exports={ContactsAppBinder});
1
+ "use strict";var m=Object.defineProperty;var u=Object.getOwnPropertyDescriptor;var D=Object.getOwnPropertyNames;var l=Object.prototype.hasOwnProperty;var I=(t,e)=>{for(var n in e)m(t,n,{get:e[n],enumerable:!0})},v=(t,e,n,i)=>{if(e&&typeof e=="object"||typeof e=="function")for(let r of D(e))!l.call(t,r)&&r!==n&&m(t,r,{get:()=>e[r],enumerable:!(i=u(e,r))||i.enumerable});return t};var x=t=>v(m({},"__esModule",{value:!0}),t),y=(t,e,n,i)=>{for(var r=i>1?void 0:i?u(e,n):e,c=t.length-1,d;c>=0;c--)(d=t[c])&&(r=(i?d(e,n,r):d(r))||r);return i&&r&&m(e,n,r),r},a=(t,e)=>(n,i)=>e(n,i,t);var f={};I(f,{ContactsAppBinder:()=>o});module.exports=x(f);var s=require("inversify"),A=require("../app-binder/device-action/RegisterExternalAddress/RegisterExternalAddressDeviceAction"),R=require("../app-binder/device-action/RenameContact/RenameContactDeviceAction"),p=require("../externalTypes");let o=class{constructor(e,n,i){this.dmk=e;this.sessionId=n;this.appName=i}registerExternalAddress(e){return this.dmk.executeDeviceAction({sessionId:this.sessionId,deviceAction:new A.RegisterExternalAddressDeviceAction({input:{...e,appName:this.appName}})})}renameContact(e){return this.dmk.executeDeviceAction({sessionId:this.sessionId,deviceAction:new R.RenameContactDeviceAction({input:e})})}};o=y([(0,s.injectable)(),a(0,(0,s.inject)(p.externalTypes.Dmk)),a(1,(0,s.inject)(p.externalTypes.SessionId)),a(2,(0,s.inject)(p.externalTypes.AppName))],o);0&&(module.exports={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": "okBAAA,IAAAA,EAAA,GAAAC,EAAAD,EAAA,uBAAAE,IAAA,eAAAC,EAAAH,GAIA,IAAAI,EAAmC,qBAInCC,EAAoD,0GACpDC,EAA8B,mCAOvB,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,IAAI,sCAAoC,CACpD,MAAO,CAAE,GAAGA,EAAO,QAAS,KAAK,OAAQ,CAC3C,CAAC,CACH,CAAC,CACH,CACF,EApBaJ,EAANK,EAAA,IADN,cAAW,EAGPC,EAAA,eAAO,gBAAc,GAAG,GAExBA,EAAA,eAAO,gBAAc,SAAS,GAE9BA,EAAA,eAAO,gBAAc,OAAO,IANpBN",
6
- "names": ["ContactsAppBinder_exports", "__export", "ContactsAppBinder", "__toCommonJS", "import_inversify", "import_RegisterExternalAddressDeviceAction", "import_externalTypes", "ContactsAppBinder", "dmk", "sessionId", "appName", "input", "__decorateClass", "__decorateParam"]
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": "okBAAA,IAAAA,EAAA,GAAAC,EAAAD,EAAA,uBAAAE,IAAA,eAAAC,EAAAH,GAIA,IAAAI,EAAmC,qBAMnCC,EAAoD,0GACpDC,EAA0C,sFAC1CC,EAA8B,mCAOvB,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,IAAI,sCAAoC,CACpD,MAAO,CAAE,GAAGA,EAAO,QAAS,KAAK,OAAQ,CAC3C,CAAC,CACH,CAAC,CACH,CAEA,cAAcA,EAAsD,CAGlE,OAAO,KAAK,IAAI,oBAAoB,CAClC,UAAW,KAAK,UAChB,aAAc,IAAI,4BAA0B,CAAE,MAAAA,CAAM,CAAC,CACvD,CAAC,CACH,CACF,EA7BaJ,EAANK,EAAA,IADN,cAAW,EAGPC,EAAA,eAAO,gBAAc,GAAG,GAExBA,EAAA,eAAO,gBAAc,SAAS,GAE9BA,EAAA,eAAO,gBAAc,OAAO,IANpBN",
6
+ "names": ["ContactsAppBinder_exports", "__export", "ContactsAppBinder", "__toCommonJS", "import_inversify", "import_RegisterExternalAddressDeviceAction", "import_RenameContactDeviceAction", "import_externalTypes", "ContactsAppBinder", "dmk", "sessionId", "appName", "input", "__decorateClass", "__decorateParam"]
7
7
  }
@@ -0,0 +1,2 @@
1
+ "use strict";var s=Object.defineProperty;var u=Object.getOwnPropertyDescriptor;var A=Object.getOwnPropertyNames;var R=Object.prototype.hasOwnProperty;var l=(n,r)=>{for(var t in r)s(n,t,{get:r[t],enumerable:!0})},y=(n,r,t,m)=>{if(r&&typeof r=="object"||typeof r=="function")for(let o of A(r))!R.call(n,o)&&o!==t&&s(n,o,{get:()=>r[o],enumerable:!(m=u(r,o))||m.enumerable});return n};var E=n=>y(s({},"__esModule",{value:!0}),n);var _={};l(_,{RenameContactCommand:()=>T});module.exports=E(_);var e=require("@ledgerhq/device-management-kit"),p=require("@ledgerhq/signer-utils"),c=require("purify-ts"),a=require("../../app-binder/model/contactsConstants"),d=require("../../app-binder/model/contactsErrors"),i=require("../../app-binder/services/contactsTlvSerializer");const C=i.STRUCT_TYPE_EDIT_CONTACT_NAME;function f(n,r){const t=n.extractFieldByLength(r);if(!(!t||t.length!==r))return Uint8Array.from(t)}class T{name="renameContact";args;errorHelper=new p.CommandErrorHelper(d.CONTACTS_APP_ERRORS,d.contactsCommandErrorFactory);constructor(r){this.args=r}getApdu(){return new e.ApduBuilder({cla:a.RENAME_CONTACT_APDU_CLA,ins:a.RENAME_CONTACT_APDU_INS,p1:a.RENAME_CONTACT_P1,p2:this.args.p2}).addBufferToData(this.args.data).build()}parseResponse(r){return c.Maybe.fromNullable(this.errorHelper.getError(r)).orDefaultLazy(()=>{if(r.data.length===0)return(0,e.CommandResultFactory)({data:{}});const t=new e.ApduParser(r),m=t.extract8BitUInt();if(m!==C)return(0,e.CommandResultFactory)({error:new e.InvalidStatusWordError(`Expected struct_type 0x${C.toString(16)}, got ${m===void 0?"undefined":`0x${m.toString(16)}`}`)});const o=f(t,a.HMAC_NAME_BYTES);return o?(0,e.CommandResultFactory)({data:{hmacProof:o}}):(0,e.CommandResultFactory)({error:new e.InvalidStatusWordError("hmac_name missing or truncated")})})}}0&&(module.exports={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": "yaAAA,IAAAA,EAAA,GAAAC,EAAAD,EAAA,0BAAAE,IAAA,eAAAC,EAAAH,GAcA,IAAAI,EASO,2CACPC,EAAmC,kCACnCC,EAAsB,qBAEtBC,EAKO,wDACPC,EAIO,qDACPC,EAA8C,+DAkB9C,MAAMC,EAAuB,gCAO7B,SAASC,EACPC,EACAC,EACwB,CACxB,MAAMC,EAAQF,EAAO,qBAAqBC,CAAM,EAChD,GAAI,GAACC,GAASA,EAAM,SAAWD,GAC/B,OAAO,WAAW,KAAKC,CAAK,CAC9B,CAEO,MAAMZ,CAOb,CACW,KAAO,gBACP,KACQ,YAAc,IAAI,qBAGjC,sBAAqB,6BAA2B,EAElD,YAAYa,EAAgC,CAC1C,KAAK,KAAOA,CACd,CAEA,SAAgB,CACd,OAAO,IAAI,cAAY,CACrB,IAAK,0BACL,IAAK,0BACL,GAAI,oBACJ,GAAI,KAAK,KAAK,EAChB,CAAC,EACE,gBAAgB,KAAK,KAAK,IAAI,EAC9B,MAAM,CACX,CAEA,cACEC,EACiE,CACjE,OAAO,QAAM,aACX,KAAK,YAAY,SAASA,CAAQ,CACpC,EAAE,cAAc,IAAM,CACpB,GAAIA,EAAS,KAAK,SAAW,EAE3B,SAAO,wBAAqB,CAAE,KAAM,CAAC,CAAE,CAAC,EAG1C,MAAMJ,EAAS,IAAI,aAAWI,CAAQ,EAEhCC,EAAaL,EAAO,gBAAgB,EAC1C,GAAIK,IAAeP,EACjB,SAAO,wBAAqB,CAC1B,MAAO,IAAI,yBACT,0BAA0BA,EAAqB,SAAS,EAAE,CAAC,SACzDO,IAAe,OACX,YACA,KAAKA,EAAW,SAAS,EAAE,CAAC,EAClC,EACF,CACF,CAAC,EAGH,MAAMC,EAAYP,EAAaC,EAAQ,iBAAe,EACtD,OAAKM,KAME,wBAAqB,CAC1B,KAAM,CAAE,UAAAA,CAAU,CACpB,CAAC,KAPQ,wBAAqB,CAC1B,MAAO,IAAI,yBAAuB,gCAAgC,CACpE,CAAC,CAML,CAAC,CACH,CACF",
6
+ "names": ["RenameContactCommand_exports", "__export", "RenameContactCommand", "__toCommonJS", "import_device_management_kit", "import_signer_utils", "import_purify_ts", "import_contactsConstants", "import_contactsErrors", "import_contactsTlvSerializer", "RESPONSE_STRUCT_TYPE", "extractField", "parser", "length", "field", "args", "response", "structType", "hmacProof"]
7
+ }
@@ -0,0 +1,2 @@
1
+ "use strict";var a=require("@ledgerhq/device-management-kit"),n=require("../../app-binder/model/contactsErrors"),o=require("./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 d=m("dd".repeat(32)),c="2e"+"dd".repeat(32);function s(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.RenameContactCommand({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.RenameContactCommand({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.RenameContactCommand({data:new Uint8Array,p2:0}).parseResponse({data:Buffer.from([]),statusCode:Buffer.from([144,0])});expect(e).toStrictEqual({status:a.CommandResultStatus.Success,data:{}})}),it("extracts the rotated hmac_name from an edit-contact-name response",()=>{const t=new o.RenameContactCommand({data:new Uint8Array,p2:0}).parseResponse(s(c));expect(t).toStrictEqual({status:a.CommandResultStatus.Success,data:{hmacProof:d}})}),it("returns InvalidStatusWordError when struct_type is wrong",()=>{const e="ee"+c.slice(2),r=new o.RenameContactCommand({data:new Uint8Array,p2:0}).parseResponse(s(e));expect(r.status).toBe(a.CommandResultStatus.Error)}),it("returns InvalidStatusWordError when hmac_name is truncated",()=>{const e="2e"+"dd".repeat(16),r=new o.RenameContactCommand({data:new Uint8Array,p2:0}).parseResponse(s(e));expect(r.status).toBe(a.CommandResultStatus.Error)}),it("maps a known SW (0x6985) to a ContactsCommandError",()=>{const t=new o.RenameContactCommand({data:new Uint8Array,p2:0}).parseResponse({data:Buffer.from([]),statusCode:Buffer.from([105,133])});expect(t.status).toBe(a.CommandResultStatus.Error),t.status===a.CommandResultStatus.Error&&(expect(t.error).toBeInstanceOf(n.ContactsCommandError),expect(t.error.errorCode).toBe("6985"))}),it("maps SW=0x6982 to a seed-mismatch ContactsCommandError",()=>{const t=new o.RenameContactCommand({data:new Uint8Array,p2:0}).parseResponse({data:Buffer.from([]),statusCode:Buffer.from([105,130])});expect(t.status).toBe(a.CommandResultStatus.Error),t.status===a.CommandResultStatus.Error&&(expect(t.error).toBeInstanceOf(n.ContactsCommandError),expect(t.error.errorCode).toBe(n.CONTACT_SEED_MISMATCH_ERROR_CODE))})})});
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": ["import_device_management_kit", "import_contactsErrors", "import_RenameContactCommand", "hexToBytes", "hex", "out", "i", "HMAC_PROOF", "RESPONSE_HEX", "makeResponse", "data", "apdu", "result", "wrongType", "truncated"]
7
+ }
@@ -0,0 +1,2 @@
1
+ "use strict";var p=Object.defineProperty;var S=Object.getOwnPropertyDescriptor;var D=Object.getOwnPropertyNames;var g=Object.prototype.hasOwnProperty;var A=(o,e)=>{for(var i in e)p(o,i,{get:e[i],enumerable:!0})},I=(o,e,i,c)=>{if(e&&typeof e=="object"||typeof e=="function")for(let t of D(e))!g.call(o,t)&&t!==i&&p(o,t,{get:()=>e[t],enumerable:!(c=S(e,t))||c.enumerable});return o};var h=o=>I(p({},"__esModule",{value:!0}),o);var E={};A(E,{RenameContactDeviceAction:()=>y});module.exports=h(E);var r=require("@ledgerhq/device-management-kit"),s=require("purify-ts"),n=require("xstate"),l=require("../../../app-binder/isContactsSupportedForSession"),d=require("../../../app-binder/model/contactsErrors"),C=require("../../../app-binder/task/SendRenameContactTask"),R=require("./validateRenameContactInput");class y extends r.XStateDeviceAction{makeStateMachine(e){const{isOsSupported:i,renameContact:c}=this.extractDependencies(e);return(0,n.setup)({types:{input:{},context:{},output:{}},actors:{goToDashboardStateMachine:new r.GoToDashboardDeviceAction({input:{}}).makeStateMachine(e),renameContact:(0,n.fromPromise)(({input:t})=>c(t))},guards:{noInternalError:({context:t})=>t._internalState.error===null,contactsOsSupported:()=>i()},actions:{assignValidationError:(0,n.assign)({_internalState:({context:t})=>{const a=(0,R.validateRenameContactInput)(t.input);return a?{...t._internalState,error:a}:t._internalState}}),assignVersionError:(0,n.assign)({_internalState:({context:t})=>({...t._internalState,error:new d.ContactsVersionRequirementError})}),assignErrorFromEvent:(0,n.assign)({_internalState:({context:t,event:a})=>({...t._internalState,error:new r.UnknownDAError(a.error instanceof Error?a.error.message:String(a.error))})})}}).createMachine({id:"RenameContactDeviceAction",initial:"InitialState",context:({input:t})=>({input:t,intermediateValue:{requiredUserInteraction:r.UserInteractionRequired.None},_internalState:{error:null,proof:null}}),states:{InitialState:{always:{target:"GoToDashboard"}},GoToDashboard:{invoke:{id:"goToDashboard",src:"goToDashboardStateMachine",input:()=>({}),onSnapshot:{actions:(0,n.assign)({intermediateValue:({event:t})=>({requiredUserInteraction:t.snapshot.context.intermediateValue.requiredUserInteraction})})},onDone:{target:"GoToDashboardCheck",actions:(0,n.assign)({_internalState:({event:t,context:a})=>t.output.caseOf({Right:()=>a._internalState,Left:u=>({...a._internalState,error:u})})})},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:(0,n.assign)({intermediateValue:{requiredUserInteraction:r.UserInteractionRequired.RegisterWallet}}),exit:(0,n.assign)({intermediateValue:{requiredUserInteraction:r.UserInteractionRequired.None}}),invoke:{id:"renameContact",src:"renameContact",input:({context:t})=>t.input,onDone:{target:"RenameContactResultCheck",actions:(0,n.assign)({_internalState:({event:t,context:a})=>(0,r.isSuccessCommandResult)(t.output)?{...a._internalState,proof:t.output.data}:{...a._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:a,error:u}=t._internalState;if(a){const{input:m}=t;return(0,s.Right)({previousContactName:m.previousContactName,contactName:m.newContactName,groupHandle:m.groupHandle,hmacProof:a.hmacProof})}return(0,s.Left)(u??new r.UnknownDAError("No error in final state"))}})}extractDependencies(e){return{isOsSupported:()=>(0,l.isContactsOsSupportedForSession)(e),renameContact:t=>new C.SendRenameContactTask(e,{previousContactName:t.previousContactName,newContactName:t.newContactName,groupHandle:t.groupHandle,hmacProof:t.hmacProof}).run()}}}0&&(module.exports={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": "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",
6
+ "names": ["RenameContactDeviceAction_exports", "__export", "RenameContactDeviceAction", "__toCommonJS", "import_device_management_kit", "import_purify_ts", "import_xstate", "import_isContactsSupportedForSession", "import_contactsErrors", "import_SendRenameContactTask", "import_validateRenameContactInput", "internalApi", "isOsSupported", "renameContact", "input", "context", "error", "event", "proof"]
7
+ }
@@ -0,0 +1,2 @@
1
+ "use strict";var e=require("@ledgerhq/device-management-kit"),t=require("vitest"),v=require("../../../app-binder/device-action/__test-utils__/makeInternalApi"),d=require("../../../app-binder/device-action/__test-utils__/setupGoToDashboardDAMock"),u=require("../../../app-binder/device-action/__test-utils__/testDeviceActionStates"),D=require("../../../app-binder/model/contactsErrors"),A=require("./RenameContactDeviceAction"),C=require("./validateRenameContactInput");t.vi.mock("@ledgerhq/device-management-kit",async a=>({...await a(),GoToDashboardDeviceAction:t.vi.fn(()=>({makeStateMachine:t.vi.fn()})),OpenAppDeviceAction:t.vi.fn(()=>({makeStateMachine:t.vi.fn()}))}));const R={hmacProof:new Uint8Array(32).fill(238)},m={previousContactName:"Alice",newContactName:"Bob",groupHandle:new Uint8Array(64).fill(204),hmacProof:new Uint8Array(32).fill(221)},I={previousContactName:"Alice",contactName:"Bob",groupHandle:m.groupHandle,hmacProof:R.hmacProof};(0,t.describe)("RenameContactDeviceAction",()=>{let a,c,s;function f(){return{isOsSupported:c,renameContact:s}}(0,t.beforeEach)(()=>{t.vi.clearAllMocks(),a=(0,v.makeDeviceActionInternalApiMock)(),c=t.vi.fn().mockReturnValue(!0),s=t.vi.fn().mockResolvedValue((0,e.CommandResultFactory)({data:R})),a.getDeviceSessionState.mockReturnValue({sessionStateType:e.DeviceSessionStateType.ReadyWithoutSecureChannel,deviceStatus:e.DeviceStatus.CONNECTED,installedApps:[],currentApp:{name:"BOLOS",version:"1.7.0"},deviceModelId:e.DeviceModelId.FLEX,isSecureConnectionAllowed:!0})});function l(r){const n=new A.RenameContactDeviceAction({input:r});return t.vi.spyOn(n,"extractDependencies").mockReturnValue(f()),n}(0,t.it)("navigates to the dashboard, checks the OS, renames, and completes",()=>new Promise((r,n)=>{(0,d.setupGoToDashboardDAMock)({requiredUserInteraction:e.UserInteractionRequired.UnlockDevice});const o=l(m),i=[{intermediateValue:{requiredUserInteraction:e.UserInteractionRequired.None},status:e.DeviceActionStatus.Pending},{intermediateValue:{requiredUserInteraction:e.UserInteractionRequired.UnlockDevice},status:e.DeviceActionStatus.Pending},{intermediateValue:{requiredUserInteraction:e.UserInteractionRequired.RegisterWallet},status:e.DeviceActionStatus.Pending},{output:I,status:e.DeviceActionStatus.Completed}];(0,u.testDeviceActionStates)(o,i,a,{onDone:()=>{(0,t.expect)(e.GoToDashboardDeviceAction).toHaveBeenCalled(),(0,t.expect)(e.OpenAppDeviceAction).not.toHaveBeenCalled(),r()},onError:n})})),(0,t.it)("rejects on an unsupported OS version without sending the APDU",()=>new Promise((r,n)=>{(0,d.setupGoToDashboardDAMock)({requiredUserInteraction:e.UserInteractionRequired.UnlockDevice}),c.mockReturnValue(!1);const o=l(m),i=[{intermediateValue:{requiredUserInteraction:e.UserInteractionRequired.None},status:e.DeviceActionStatus.Pending},{intermediateValue:{requiredUserInteraction:e.UserInteractionRequired.UnlockDevice},status:e.DeviceActionStatus.Pending},{error:new D.ContactsVersionRequirementError,status:e.DeviceActionStatus.Error}];(0,u.testDeviceActionStates)(o,i,a,{onDone:()=>{(0,t.expect)(s).not.toHaveBeenCalled(),(0,t.expect)(e.OpenAppDeviceAction).not.toHaveBeenCalled(),r()},onError:n})})),(0,t.it)("surfaces a go-to-dashboard failure as the device action error",()=>new Promise((r,n)=>{const o=new e.UnknownDAError("go to dashboard failed");(0,d.setupGoToDashboardDAMock)({error:o,requiredUserInteraction:e.UserInteractionRequired.UnlockDevice});const i=l(m),p=[{intermediateValue:{requiredUserInteraction:e.UserInteractionRequired.None},status:e.DeviceActionStatus.Pending},{intermediateValue:{requiredUserInteraction:e.UserInteractionRequired.UnlockDevice},status:e.DeviceActionStatus.Pending},{error:o,status:e.DeviceActionStatus.Error}];(0,u.testDeviceActionStates)(i,p,a,{onDone:()=>{(0,t.expect)(c).not.toHaveBeenCalled(),(0,t.expect)(s).not.toHaveBeenCalled(),r()},onError:n})})),(0,t.it)("surfaces a rename command error (e.g. seed mismatch)",()=>new Promise((r,n)=>{(0,d.setupGoToDashboardDAMock)({requiredUserInteraction:e.UserInteractionRequired.UnlockDevice});const o=new D.ContactsCommandError({errorCode:"6982",message:"wrong seed"});s.mockResolvedValue((0,e.CommandResultFactory)({error:o}));const i=l(m),p=[{intermediateValue:{requiredUserInteraction:e.UserInteractionRequired.None},status:e.DeviceActionStatus.Pending},{intermediateValue:{requiredUserInteraction:e.UserInteractionRequired.UnlockDevice},status:e.DeviceActionStatus.Pending},{intermediateValue:{requiredUserInteraction:e.UserInteractionRequired.RegisterWallet},status:e.DeviceActionStatus.Pending},{error:o,status:e.DeviceActionStatus.Error}];(0,u.testDeviceActionStates)(i,p,a,{onDone:r,onError:n})})),(0,t.it)("surfaces invalid input as a typed error after reaching the dashboard",()=>new Promise((r,n)=>{(0,d.setupGoToDashboardDAMock)({requiredUserInteraction:e.UserInteractionRequired.UnlockDevice});const o={...m,newContactName:""},i=(0,C.validateRenameContactInput)(o),p=l(o),U=[{intermediateValue:{requiredUserInteraction:e.UserInteractionRequired.None},status:e.DeviceActionStatus.Pending},{intermediateValue:{requiredUserInteraction:e.UserInteractionRequired.UnlockDevice},status:e.DeviceActionStatus.Pending},{error:i,status:e.DeviceActionStatus.Error}];(0,u.testDeviceActionStates)(p,U,a,{onDone:()=>{(0,t.expect)(c).not.toHaveBeenCalled(),(0,t.expect)(s).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": ["import_device_management_kit", "import_vitest", "import_makeInternalApi", "import_setupGoToDashboardDAMock", "import_testDeviceActionStates", "import_contactsErrors", "import_RenameContactDeviceAction", "import_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
+ "use strict";var r=Object.defineProperty;var l=Object.getOwnPropertyDescriptor;var i=Object.getOwnPropertyNames;var f=Object.prototype.hasOwnProperty;var d=(a,t)=>{for(var o in t)r(a,o,{get:t[o],enumerable:!0})},m=(a,t,o,c)=>{if(t&&typeof t=="object"||typeof t=="function")for(let n of i(t))!f.call(a,n)&&n!==o&&r(a,n,{get:()=>t[n],enumerable:!(c=l(t,n))||c.enumerable});return a};var C=a=>m(r({},"__esModule",{value:!0}),a);var p={};d(p,{validateRenameContactInput:()=>u});module.exports=C(p);var e=require("../../../app-binder/model/contactsValidation");function u(a){try{return(0,e.validatePrintableLabel)(a.newContactName,{field:"newContactName",bufferLength:e.CONTACT_NAME_BUFFER_LENGTH}),(0,e.validatePrintableLabel)(a.previousContactName,{field:"previousContactName",bufferLength:e.CONTACT_NAME_BUFFER_LENGTH}),(0,e.validateByteLength)(a.groupHandle,{field:"groupHandle",expectedBytes:e.GROUP_HANDLE_SIZE}),(0,e.validateByteLength)(a.hmacProof,{field:"hmacProof",expectedBytes:e.HMAC_PROOF_LENGTH}),null}catch(t){if(t instanceof e.ContactsValidationError)return t;throw t}}0&&(module.exports={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": "yaAAA,IAAAA,EAAA,GAAAC,EAAAD,EAAA,gCAAAE,IAAA,eAAAC,EAAAH,GACA,IAAAI,EAOO,yDAUA,SAASF,EACdG,EACgC,CAChC,GAAI,CACF,mCAAuBA,EAAM,eAAgB,CAC3C,MAAO,iBACP,aAAc,4BAChB,CAAC,KACD,0BAAuBA,EAAM,oBAAqB,CAChD,MAAO,sBACP,aAAc,4BAChB,CAAC,KACD,sBAAmBA,EAAM,YAAa,CACpC,MAAO,cACP,cAAe,mBACjB,CAAC,KACD,sBAAmBA,EAAM,UAAW,CAClC,MAAO,YACP,cAAe,mBACjB,CAAC,EAEM,IACT,OAASC,EAAO,CACd,GAAIA,aAAiB,0BACnB,OAAOA,EAET,MAAMA,CACR,CACF",
6
+ "names": ["validateRenameContactInput_exports", "__export", "validateRenameContactInput", "__toCommonJS", "import_contactsValidation", "input", "error"]
7
+ }
@@ -0,0 +1,2 @@
1
+ "use strict";var n=require("../../../app-binder/model/contactsValidation"),t=require("./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((0,t.validateRenameContactInput)(e)).toBeNull()}),it("returns a ContactsValidationError for a non-printable new name",()=>{expect((0,t.validateRenameContactInput)({...e,newContactName:"Am\xE9lie"})).toBeInstanceOf(n.ContactsValidationError)}),it("returns a ContactsValidationError for a non-printable previous name",()=>{expect((0,t.validateRenameContactInput)({...e,previousContactName:"Am\xE9lie"})).toBeInstanceOf(n.ContactsValidationError)}),it("returns an error for an empty new name",()=>{expect((0,t.validateRenameContactInput)({...e,newContactName:""})).toBeInstanceOf(n.ContactsValidationError)}),it("returns an error for a group handle of the wrong length",()=>{expect((0,t.validateRenameContactInput)({...e,groupHandle:new Uint8Array(63)})).toBeInstanceOf(n.ContactsValidationError)}),it("returns an error for an hmac proof of the wrong length",()=>{expect((0,t.validateRenameContactInput)({...e,hmacProof:new Uint8Array(31)})).toBeInstanceOf(n.ContactsValidationError)})});
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,IAAAA,EAAwC,yDAExCC,EAA2C,wCAE3C,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,UAAO,8BAA2BA,CAAW,CAAC,EAAE,SAAS,CAC3D,CAAC,EAED,GAAG,iEAAkE,IAAM,CACzE,UACE,8BAA2B,CAAE,GAAGA,EAAa,eAAgB,WAAS,CAAC,CACzE,EAAE,eAAe,yBAAuB,CAC1C,CAAC,EAED,GAAG,sEAAuE,IAAM,CAC9E,UACE,8BAA2B,CACzB,GAAGA,EACH,oBAAqB,WACvB,CAAC,CACH,EAAE,eAAe,yBAAuB,CAC1C,CAAC,EAED,GAAG,yCAA0C,IAAM,CACjD,UACE,8BAA2B,CAAE,GAAGA,EAAa,eAAgB,EAAG,CAAC,CACnE,EAAE,eAAe,yBAAuB,CAC1C,CAAC,EAED,GAAG,0DAA2D,IAAM,CAClE,UACE,8BAA2B,CACzB,GAAGA,EACH,YAAa,IAAI,WAAW,EAAE,CAChC,CAAC,CACH,EAAE,eAAe,yBAAuB,CAC1C,CAAC,EAED,GAAG,yDAA0D,IAAM,CACjE,UACE,8BAA2B,CACzB,GAAGA,EACH,UAAW,IAAI,WAAW,EAAE,CAC9B,CAAC,CACH,EAAE,eAAe,yBAAuB,CAC1C,CAAC,CACH,CAAC",
6
+ "names": ["import_contactsValidation", "import_validateRenameContactInput", "VALID_INPUT"]
7
+ }
@@ -0,0 +1,2 @@
1
+ "use strict";var c=Object.defineProperty;var d=Object.getOwnPropertyDescriptor;var s=Object.getOwnPropertyNames;var p=Object.prototype.hasOwnProperty;var u=(e,r)=>{for(var n in r)c(e,n,{get:r[n],enumerable:!0})},f=(e,r,n,m)=>{if(r&&typeof r=="object"||typeof r=="function")for(let t of s(r))!p.call(e,t)&&t!==n&&c(e,t,{get:()=>r[t],enumerable:!(m=d(r,t))||m.enumerable});return e};var k=e=>f(c({},"__esModule",{value:!0}),e);var h={};u(h,{setupGoToDashboardDAMock:()=>I});module.exports=k(h);var o=require("@ledgerhq/device-management-kit"),i=require("purify-ts"),a=require("xstate");const I=(e={})=>{const r=e.requiredUserInteraction??o.UserInteractionRequired.None;o.GoToDashboardDeviceAction.mockImplementation(()=>({makeStateMachine:vi.fn().mockImplementation(()=>(0,a.createMachine)({initial:"pending",states:{pending:{entry:(0,a.assign)({intermediateValue:{requiredUserInteraction:r}}),after:{0:"done"}},done:{type:"final"}},output:()=>e.error?(0,i.Left)(e.error):(0,i.Right)(void 0)}))}))};0&&(module.exports={setupGoToDashboardDAMock});
2
+ //# sourceMappingURL=setupGoToDashboardDAMock.js.map
@@ -0,0 +1,7 @@
1
+ {
2
+ "version": 3,
3
+ "sources": ["../../../../../../src/internal/app-binder/device-action/__test-utils__/setupGoToDashboardDAMock.ts"],
4
+ "sourcesContent": ["import {\n GoToDashboardDeviceAction,\n UserInteractionRequired,\n} from \"@ledgerhq/device-management-kit\";\nimport { Left, Right } from \"purify-ts\";\nimport { type Mock } from \"vitest\";\nimport { assign, createMachine } from \"xstate\";\n\n/**\n * Mock GoToDashboardDeviceAction to resolve immediately with either success\n * (default) or an error. Emits a single `requiredUserInteraction` snapshot\n * (default `None` \u2014 device assumed unlocked and already ready) so the parent\n * action can surface it, mirroring the real nested device action.\n */\nexport const setupGoToDashboardDAMock = (\n options: {\n error?: unknown;\n requiredUserInteraction?: UserInteractionRequired;\n } = {},\n) => {\n const interaction =\n options.requiredUserInteraction ?? UserInteractionRequired.None;\n (GoToDashboardDeviceAction as Mock).mockImplementation(() => ({\n makeStateMachine: vi.fn().mockImplementation(() =>\n createMachine({\n initial: \"pending\",\n states: {\n pending: {\n entry: assign({\n intermediateValue: {\n requiredUserInteraction: interaction,\n },\n }),\n after: {\n 0: \"done\",\n },\n },\n done: {\n type: \"final\",\n },\n },\n output: () => (options.error ? Left(options.error) : Right(undefined)),\n }),\n ),\n }));\n};\n"],
5
+ "mappings": "yaAAA,IAAAA,EAAA,GAAAC,EAAAD,EAAA,8BAAAE,IAAA,eAAAC,EAAAH,GAAA,IAAAI,EAGO,2CACPC,EAA4B,qBAE5BC,EAAsC,kBAQ/B,MAAMJ,EAA2B,CACtCK,EAGI,CAAC,IACF,CACH,MAAMC,EACJD,EAAQ,yBAA2B,0BAAwB,KAC5D,4BAAmC,mBAAmB,KAAO,CAC5D,iBAAkB,GAAG,GAAG,EAAE,mBAAmB,OAC3C,iBAAc,CACZ,QAAS,UACT,OAAQ,CACN,QAAS,CACP,SAAO,UAAO,CACZ,kBAAmB,CACjB,wBAAyBC,CAC3B,CACF,CAAC,EACD,MAAO,CACL,EAAG,MACL,CACF,EACA,KAAM,CACJ,KAAM,OACR,CACF,EACA,OAAQ,IAAOD,EAAQ,SAAQ,QAAKA,EAAQ,KAAK,KAAI,SAAM,MAAS,CACtE,CAAC,CACH,CACF,EAAE,CACJ",
6
+ "names": ["setupGoToDashboardDAMock_exports", "__export", "setupGoToDashboardDAMock", "__toCommonJS", "import_device_management_kit", "import_purify_ts", "import_xstate", "options", "interaction"]
7
+ }
@@ -1,2 +1,2 @@
1
- "use strict";var s=Object.defineProperty;var f=Object.getOwnPropertyDescriptor;var l=Object.getOwnPropertyNames;var m=Object.prototype.hasOwnProperty;var u=(n,e)=>{for(var i in e)s(n,i,{get:e[i],enumerable:!0})},d=(n,e,i,o)=>{if(e&&typeof e=="object"||typeof e=="function")for(let r of l(e))!m.call(n,r)&&r!==i&&s(n,r,{get:()=>e[r],enumerable:!(o=f(e,r))||o.enumerable});return n};var v=n=>d(s({},"__esModule",{value:!0}),n);var V={};u(V,{isContactsSupportedForSession:()=>A});module.exports=v(V);var a=require("@ledgerhq/device-management-kit"),t=require("../../api/model/ContactsVersionRequirements"),c=require("./ContactsApplicationResolver");function A(n,e){const i=n.getDeviceSessionState(),o=(0,t.resolveContactsVersionRequirements)(i.deviceModelId);if(!o.supported)return!1;const r=o.minAppVersion[e.name];if(r===void 0||!new a.ApplicationChecker(i,{version:e.version},new c.ContactsApplicationResolver).withMinVersionInclusive(r).check())return!1;const p="firmwareVersion"in i?i.firmwareVersion?.os:void 0;return p===void 0?!1:(0,t.isVersionAtLeast)(p,o.minOsVersion)}0&&(module.exports={isContactsSupportedForSession});
1
+ "use strict";var s=Object.defineProperty;var f=Object.getOwnPropertyDescriptor;var u=Object.getOwnPropertyNames;var d=Object.prototype.hasOwnProperty;var l=(i,e)=>{for(var n in e)s(i,n,{get:e[n],enumerable:!0})},m=(i,e,n,r)=>{if(e&&typeof e=="object"||typeof e=="function")for(let o of u(e))!d.call(i,o)&&o!==n&&s(i,o,{get:()=>e[o],enumerable:!(r=f(e,o))||r.enumerable});return i};var V=i=>m(s({},"__esModule",{value:!0}),i);var S={};l(S,{isContactsOsSupportedForSession:()=>A,isContactsSupportedForSession:()=>v});module.exports=V(S);var a=require("@ledgerhq/device-management-kit"),t=require("../../api/model/ContactsVersionRequirements"),c=require("./ContactsApplicationResolver");function v(i,e){const n=i.getDeviceSessionState(),r=(0,t.resolveContactsVersionRequirements)(n.deviceModelId);if(!r.supported)return!1;const o=r.minAppVersion[e.name];if(o===void 0||!new a.ApplicationChecker(n,{version:e.version},new c.ContactsApplicationResolver).withMinVersionInclusive(o).check())return!1;const p="firmwareVersion"in n?n.firmwareVersion?.os:void 0;return p===void 0?!1:(0,t.isVersionAtLeast)(p,r.minOsVersion)}function A(i){const e=i.getDeviceSessionState(),n=(0,t.resolveContactsVersionRequirements)(e.deviceModelId);if(!n.supported)return!1;const r="firmwareVersion"in e?e.firmwareVersion?.os:void 0;return r===void 0?!1:(0,t.isVersionAtLeast)(r,n.minOsVersion)}0&&(module.exports={isContactsOsSupportedForSession,isContactsSupportedForSession});
2
2
  //# sourceMappingURL=isContactsSupportedForSession.js.map
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "version": 3,
3
3
  "sources": ["../../../../src/internal/app-binder/isContactsSupportedForSession.ts"],
4
- "sourcesContent": ["import {\n ApplicationChecker,\n type InternalApi,\n} from \"@ledgerhq/device-management-kit\";\n\nimport {\n isVersionAtLeast,\n resolveContactsVersionRequirements,\n} from \"@api/model/ContactsVersionRequirements\";\n\nimport { ContactsApplicationResolver } from \"./ContactsApplicationResolver\";\n\n/** The running app's identity, read freshly from the device. */\nexport type RunningApp = {\n readonly name: string;\n readonly version: string;\n};\n\n/**\n * Session-aware Contacts support check, for internal consumption by Contacts\n * `DeviceAction`s. Resolves the given running app against the static\n * requirements table:\n * - the device model must be supported;\n * - the running app must be known to Contacts and meet its minimum version;\n * - the device OS must meet its minimum version (a dimension `ApplicationChecker`\n * does not cover, so it is checked separately here).\n *\n * The app `name` and `version` are supplied by the caller so they can come from\n * a fresh `WaitForAppAndVersion` result rather than the (potentially stale)\n * device session state; the model and OS come from the session state, which\n * does not change under the caller's feet the way the running app can.\n *\n * @param internalApi - the DeviceAction's internal API for the current session.\n * @param app - the running app's fresh name and version.\n */\nexport function isContactsSupportedForSession(\n internalApi: InternalApi,\n app: RunningApp,\n): boolean {\n const deviceState = internalApi.getDeviceSessionState();\n const requirement = resolveContactsVersionRequirements(\n deviceState.deviceModelId,\n );\n if (!requirement.supported) return false;\n\n const minAppVersion = requirement.minAppVersion[app.name];\n if (minAppVersion === undefined) return false;\n\n const appCompatible = new ApplicationChecker(\n deviceState,\n { version: app.version },\n new ContactsApplicationResolver(),\n )\n .withMinVersionInclusive(minAppVersion)\n .check();\n if (!appCompatible) return false;\n\n const osVersion =\n \"firmwareVersion\" in deviceState\n ? deviceState.firmwareVersion?.os\n : undefined;\n if (osVersion === undefined) return false;\n\n return isVersionAtLeast(osVersion, requirement.minOsVersion);\n}\n"],
5
- "mappings": "yaAAA,IAAAA,EAAA,GAAAC,EAAAD,EAAA,mCAAAE,IAAA,eAAAC,EAAAH,GAAA,IAAAI,EAGO,2CAEPC,EAGO,kDAEPC,EAA4C,yCAyBrC,SAASJ,EACdK,EACAC,EACS,CACT,MAAMC,EAAcF,EAAY,sBAAsB,EAChDG,KAAc,sCAClBD,EAAY,aACd,EACA,GAAI,CAACC,EAAY,UAAW,MAAO,GAEnC,MAAMC,EAAgBD,EAAY,cAAcF,EAAI,IAAI,EAUxD,GATIG,IAAkB,QASlB,CAPkB,IAAI,qBACxBF,EACA,CAAE,QAASD,EAAI,OAAQ,EACvB,IAAI,6BACN,EACG,wBAAwBG,CAAa,EACrC,MAAM,EACW,MAAO,GAE3B,MAAMC,EACJ,oBAAqBH,EACjBA,EAAY,iBAAiB,GAC7B,OACN,OAAIG,IAAc,OAAkB,MAE7B,oBAAiBA,EAAWF,EAAY,YAAY,CAC7D",
6
- "names": ["isContactsSupportedForSession_exports", "__export", "isContactsSupportedForSession", "__toCommonJS", "import_device_management_kit", "import_ContactsVersionRequirements", "import_ContactsApplicationResolver", "internalApi", "app", "deviceState", "requirement", "minAppVersion", "osVersion"]
4
+ "sourcesContent": ["import {\n ApplicationChecker,\n type InternalApi,\n} from \"@ledgerhq/device-management-kit\";\n\nimport {\n isVersionAtLeast,\n resolveContactsVersionRequirements,\n} from \"@api/model/ContactsVersionRequirements\";\n\nimport { ContactsApplicationResolver } from \"./ContactsApplicationResolver\";\n\n/** The running app's identity, read freshly from the device. */\nexport type RunningApp = {\n readonly name: string;\n readonly version: string;\n};\n\n/**\n * Session-aware Contacts support check, for internal consumption by Contacts\n * `DeviceAction`s. Resolves the given running app against the static\n * requirements table:\n * - the device model must be supported;\n * - the running app must be known to Contacts and meet its minimum version;\n * - the device OS must meet its minimum version (a dimension `ApplicationChecker`\n * does not cover, so it is checked separately here).\n *\n * The app `name` and `version` are supplied by the caller so they can come from\n * a fresh `WaitForAppAndVersion` result rather than the (potentially stale)\n * device session state; the model and OS come from the session state, which\n * does not change under the caller's feet the way the running app can.\n *\n * @param internalApi - the DeviceAction's internal API for the current session.\n * @param app - the running app's fresh name and version.\n */\nexport function isContactsSupportedForSession(\n internalApi: InternalApi,\n app: RunningApp,\n): boolean {\n const deviceState = internalApi.getDeviceSessionState();\n const requirement = resolveContactsVersionRequirements(\n deviceState.deviceModelId,\n );\n if (!requirement.supported) return false;\n\n const minAppVersion = requirement.minAppVersion[app.name];\n if (minAppVersion === undefined) return false;\n\n const appCompatible = new ApplicationChecker(\n deviceState,\n { version: app.version },\n new ContactsApplicationResolver(),\n )\n .withMinVersionInclusive(minAppVersion)\n .check();\n if (!appCompatible) return false;\n\n const osVersion =\n \"firmwareVersion\" in deviceState\n ? deviceState.firmwareVersion?.os\n : undefined;\n if (osVersion === undefined) return false;\n\n return isVersionAtLeast(osVersion, requirement.minOsVersion);\n}\n\n/**\n * OS-only Contacts support check, for internal consumption by dashboard\n * `DeviceAction`s (e.g. Rename Contact, EDIT CONTACT NAME). Dashboard operations\n * are served by the device OS, not the embedded app, so only two dimensions\n * apply:\n * - the device model must be supported;\n * - the device OS must meet its minimum version.\n *\n * The running-app dimension is intentionally skipped: on the dashboard there is\n * no embedded app to gate on (the running \"app\" is BOLOS). The model and OS both\n * come from the session state, which is stable across the operation.\n *\n * @param internalApi - the DeviceAction's internal API for the current session.\n */\nexport function isContactsOsSupportedForSession(\n internalApi: InternalApi,\n): boolean {\n const deviceState = internalApi.getDeviceSessionState();\n const requirement = resolveContactsVersionRequirements(\n deviceState.deviceModelId,\n );\n if (!requirement.supported) return false;\n\n const osVersion =\n \"firmwareVersion\" in deviceState\n ? deviceState.firmwareVersion?.os\n : undefined;\n if (osVersion === undefined) return false;\n\n return isVersionAtLeast(osVersion, requirement.minOsVersion);\n}\n"],
5
+ "mappings": "yaAAA,IAAAA,EAAA,GAAAC,EAAAD,EAAA,qCAAAE,EAAA,kCAAAC,IAAA,eAAAC,EAAAJ,GAAA,IAAAK,EAGO,2CAEPC,EAGO,kDAEPC,EAA4C,yCAyBrC,SAASJ,EACdK,EACAC,EACS,CACT,MAAMC,EAAcF,EAAY,sBAAsB,EAChDG,KAAc,sCAClBD,EAAY,aACd,EACA,GAAI,CAACC,EAAY,UAAW,MAAO,GAEnC,MAAMC,EAAgBD,EAAY,cAAcF,EAAI,IAAI,EAUxD,GATIG,IAAkB,QASlB,CAPkB,IAAI,qBACxBF,EACA,CAAE,QAASD,EAAI,OAAQ,EACvB,IAAI,6BACN,EACG,wBAAwBG,CAAa,EACrC,MAAM,EACW,MAAO,GAE3B,MAAMC,EACJ,oBAAqBH,EACjBA,EAAY,iBAAiB,GAC7B,OACN,OAAIG,IAAc,OAAkB,MAE7B,oBAAiBA,EAAWF,EAAY,YAAY,CAC7D,CAgBO,SAAST,EACdM,EACS,CACT,MAAME,EAAcF,EAAY,sBAAsB,EAChDG,KAAc,sCAClBD,EAAY,aACd,EACA,GAAI,CAACC,EAAY,UAAW,MAAO,GAEnC,MAAME,EACJ,oBAAqBH,EACjBA,EAAY,iBAAiB,GAC7B,OACN,OAAIG,IAAc,OAAkB,MAE7B,oBAAiBA,EAAWF,EAAY,YAAY,CAC7D",
6
+ "names": ["isContactsSupportedForSession_exports", "__export", "isContactsOsSupportedForSession", "isContactsSupportedForSession", "__toCommonJS", "import_device_management_kit", "import_ContactsVersionRequirements", "import_ContactsApplicationResolver", "internalApi", "app", "deviceState", "requirement", "minAppVersion", "osVersion"]
7
7
  }
@@ -1,2 +1,2 @@
1
- "use strict";var e=Object.defineProperty;var r=Object.getOwnPropertyDescriptor;var c=Object.getOwnPropertyNames;var s=Object.prototype.hasOwnProperty;var A=(t,o)=>{for(var _ in o)e(t,_,{get:o[_],enumerable:!0})},T=(t,o,_,n)=>{if(o&&typeof o=="object"||typeof o=="function")for(let x of c(o))!s.call(t,x)&&x!==_&&e(t,x,{get:()=>o[x],enumerable:!(n=r(o,x))||n.enumerable});return t};var C=t=>T(e({},"__esModule",{value:!0}),t);var I={};A(I,{BLOCKCHAIN_FAMILY_BY_NAME:()=>B,CONTACTS_APDU_CLA:()=>E,CONTACTS_APDU_INS:()=>S,GROUP_HANDLE_BYTES:()=>N,HMAC_PROOF_BYTES:()=>R,HMAC_REST_BYTES:()=>a,SUB_CMD_REGISTER_IDENTITY:()=>p});module.exports=C(I);const E=176,S=16,p=1,N=64,R=32,a=32,B={bitcoin:0,ethereum:1,solana:2,polkadot:3,cosmos:4,cardano:5};0&&(module.exports={BLOCKCHAIN_FAMILY_BY_NAME,CONTACTS_APDU_CLA,CONTACTS_APDU_INS,GROUP_HANDLE_BYTES,HMAC_PROOF_BYTES,HMAC_REST_BYTES,SUB_CMD_REGISTER_IDENTITY});
1
+ "use strict";var A=Object.defineProperty;var C=Object.getOwnPropertyDescriptor;var T=Object.getOwnPropertyNames;var n=Object.prototype.hasOwnProperty;var E=(t,o)=>{for(var x in o)A(t,x,{get:o[x],enumerable:!0})},r=(t,o,x,e)=>{if(o&&typeof o=="object"||typeof o=="function")for(let _ of T(o))!n.call(t,_)&&_!==x&&A(t,_,{get:()=>o[_],enumerable:!(e=C(o,_))||e.enumerable});return t};var c=t=>r(A({},"__esModule",{value:!0}),t);var Y={};E(Y,{BLOCKCHAIN_FAMILY_BY_NAME:()=>P,CONTACTS_APDU_CLA:()=>s,CONTACTS_APDU_INS:()=>N,GROUP_HANDLE_BYTES:()=>O,HMAC_NAME_BYTES:()=>I,HMAC_PROOF_BYTES:()=>B,HMAC_REST_BYTES:()=>D,RENAME_CONTACT_APDU_CLA:()=>S,RENAME_CONTACT_APDU_INS:()=>M,RENAME_CONTACT_P1:()=>R,SUB_CMD_REGISTER_IDENTITY:()=>p});module.exports=c(Y);const s=176,N=16,p=1,S=224,M=46,R=0,O=64,B=32,D=32,I=32,P={bitcoin:0,ethereum:1,solana:2,polkadot:3,cosmos:4,cardano:5};0&&(module.exports={BLOCKCHAIN_FAMILY_BY_NAME,CONTACTS_APDU_CLA,CONTACTS_APDU_INS,GROUP_HANDLE_BYTES,HMAC_NAME_BYTES,HMAC_PROOF_BYTES,HMAC_REST_BYTES,RENAME_CONTACT_APDU_CLA,RENAME_CONTACT_APDU_INS,RENAME_CONTACT_P1,SUB_CMD_REGISTER_IDENTITY});
2
2
  //# sourceMappingURL=contactsConstants.js.map
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "version": 3,
3
3
  "sources": ["../../../../../src/internal/app-binder/model/contactsConstants.ts"],
4
- "sourcesContent": ["/**\n * Protocol constants shared by the Contacts (Address Book) operations.\n *\n * Wire format and values follow the BOLOS SDK Address Book specification\n * (ledger-secure-sdk/app_features/address_book). Op-specific sub-command bytes\n * and response field sizes live here; TLV tags and struct-type bytes live in\n * {@link ./../services/contactsTlvSerializer}.\n */\n\n/** APDU class/instruction shared by every Address Book sub-command. */\nexport const CONTACTS_APDU_CLA = 0xb0;\nexport const CONTACTS_APDU_INS = 0x10;\n\n/** P1 sub-command selector for REGISTER IDENTITY (register external address). */\nexport const SUB_CMD_REGISTER_IDENTITY = 0x01;\n\n/** Sizes (bytes) of the fields in the REGISTER IDENTITY final-chunk response. */\nexport const GROUP_HANDLE_BYTES = 64;\nexport const HMAC_PROOF_BYTES = 32;\nexport const HMAC_REST_BYTES = 32;\n\n/**\n * Blockchain-family byte encoded in the `BLOCKCHAIN_FAMILY` TLV, keyed by a\n * lowercase family name. v1 ships Ethereum only; the remaining families are\n * listed for completeness and will be enabled as their chains are supported.\n */\nexport const BLOCKCHAIN_FAMILY_BY_NAME: Readonly<Record<string, number>> = {\n bitcoin: 0x00,\n ethereum: 0x01,\n solana: 0x02,\n polkadot: 0x03,\n cosmos: 0x04,\n cardano: 0x05,\n};\n"],
5
- "mappings": "yaAAA,IAAAA,EAAA,GAAAC,EAAAD,EAAA,+BAAAE,EAAA,sBAAAC,EAAA,sBAAAC,EAAA,uBAAAC,EAAA,qBAAAC,EAAA,oBAAAC,EAAA,8BAAAC,IAAA,eAAAC,EAAAT,GAUO,MAAMG,EAAoB,IACpBC,EAAoB,GAGpBI,EAA4B,EAG5BH,EAAqB,GACrBC,EAAmB,GACnBC,EAAkB,GAOlBL,EAA8D,CACzE,QAAS,EACT,SAAU,EACV,OAAQ,EACR,SAAU,EACV,OAAQ,EACR,QAAS,CACX",
6
- "names": ["contactsConstants_exports", "__export", "BLOCKCHAIN_FAMILY_BY_NAME", "CONTACTS_APDU_CLA", "CONTACTS_APDU_INS", "GROUP_HANDLE_BYTES", "HMAC_PROOF_BYTES", "HMAC_REST_BYTES", "SUB_CMD_REGISTER_IDENTITY", "__toCommonJS"]
4
+ "sourcesContent": ["/**\n * Protocol constants shared by the Contacts (Address Book) operations.\n *\n * Wire format and values follow the BOLOS SDK Address Book specification\n * (ledger-secure-sdk/app_features/address_book). Op-specific sub-command bytes\n * and response field sizes live here; TLV tags and struct-type bytes live in\n * {@link ./../services/contactsTlvSerializer}.\n */\n\n/** APDU class/instruction shared by every Address Book sub-command. */\nexport const CONTACTS_APDU_CLA = 0xb0;\nexport const CONTACTS_APDU_INS = 0x10;\n\n/** P1 sub-command selector for REGISTER IDENTITY (register external address). */\nexport const SUB_CMD_REGISTER_IDENTITY = 0x01;\n\n/**\n * EDIT CONTACT NAME (rename) is a blockchain-agnostic OS/dashboard command with\n * its own CLA/INS \u2014 NOT a sub-command of the address-book app APDU (0xB0/0x10).\n * The OS serves it directly, so it must run on the dashboard. P1 is a fixed\n * 0x00 (there is no sub-command selector for this command); P2 still carries the\n * chunk-continuation flag handled by {@link ./../services/sendFramedContactsPayload}.\n */\nexport const RENAME_CONTACT_APDU_CLA = 0xe0;\nexport const RENAME_CONTACT_APDU_INS = 0x2e;\nexport const RENAME_CONTACT_P1 = 0x00;\n\n/** Sizes (bytes) of the fields in the REGISTER IDENTITY final-chunk response. */\nexport const GROUP_HANDLE_BYTES = 64;\nexport const HMAC_PROOF_BYTES = 32;\nexport const HMAC_REST_BYTES = 32;\n\n/**\n * Size (bytes) of the rotated `hmac_name` returned on the EDIT CONTACT NAME\n * final-chunk response \u2014 the replacement group-level name proof.\n */\nexport const HMAC_NAME_BYTES = 32;\n\n/**\n * Blockchain-family byte encoded in the `BLOCKCHAIN_FAMILY` TLV, keyed by a\n * lowercase family name. v1 ships Ethereum only; the remaining families are\n * listed for completeness and will be enabled as their chains are supported.\n */\nexport const BLOCKCHAIN_FAMILY_BY_NAME: Readonly<Record<string, number>> = {\n bitcoin: 0x00,\n ethereum: 0x01,\n solana: 0x02,\n polkadot: 0x03,\n cosmos: 0x04,\n cardano: 0x05,\n};\n"],
5
+ "mappings": "yaAAA,IAAAA,EAAA,GAAAC,EAAAD,EAAA,+BAAAE,EAAA,sBAAAC,EAAA,sBAAAC,EAAA,uBAAAC,EAAA,oBAAAC,EAAA,qBAAAC,EAAA,oBAAAC,EAAA,4BAAAC,EAAA,4BAAAC,EAAA,sBAAAC,EAAA,8BAAAC,IAAA,eAAAC,EAAAb,GAUO,MAAMG,EAAoB,IACpBC,EAAoB,GAGpBQ,EAA4B,EAS5BH,EAA0B,IAC1BC,EAA0B,GAC1BC,EAAoB,EAGpBN,EAAqB,GACrBE,EAAmB,GACnBC,EAAkB,GAMlBF,EAAkB,GAOlBJ,EAA8D,CACzE,QAAS,EACT,SAAU,EACV,OAAQ,EACR,SAAU,EACV,OAAQ,EACR,QAAS,CACX",
6
+ "names": ["contactsConstants_exports", "__export", "BLOCKCHAIN_FAMILY_BY_NAME", "CONTACTS_APDU_CLA", "CONTACTS_APDU_INS", "GROUP_HANDLE_BYTES", "HMAC_NAME_BYTES", "HMAC_PROOF_BYTES", "HMAC_REST_BYTES", "RENAME_CONTACT_APDU_CLA", "RENAME_CONTACT_APDU_INS", "RENAME_CONTACT_P1", "SUB_CMD_REGISTER_IDENTITY", "__toCommonJS"]
7
7
  }
@@ -0,0 +1,2 @@
1
+ "use strict";var s=Object.defineProperty;var l=Object.getOwnPropertyDescriptor;var T=Object.getOwnPropertyNames;var p=Object.prototype.hasOwnProperty;var y=(t,e)=>{for(var a in e)s(t,a,{get:e[a],enumerable:!0})},u=(t,e,a,m)=>{if(e&&typeof e=="object"||typeof e=="function")for(let n of T(e))!p.call(t,n)&&n!==a&&s(t,n,{get:()=>e[n],enumerable:!(m=l(e,n))||m.enumerable});return t};var A=t=>u(s({},"__esModule",{value:!0}),t);var P={};y(P,{SendRenameContactTask:()=>R});module.exports=A(P);var o=require("@ledgerhq/device-management-kit"),d=require("../../app-binder/command/RenameContactCommand"),i=require("../../app-binder/model/contactsConstants"),r=require("../../app-binder/services/contactsTlvSerializer"),c=require("../../app-binder/services/sendFramedContactsPayload");class R{constructor(e,a){this.api=e;this.args=a}async run(){const e=this.buildPayload(this.args),a=await(0,c.sendFramedContactsPayload)(this.api,{payload:e,p1:i.RENAME_CONTACT_P1,makeCommand:(n,C)=>new d.RenameContactCommand({data:n,p2:C}),logger:this.args.logger,commandTag:"SendRenameContactTask"});if(!(0,o.isSuccessCommandResult)(a))return a;const{hmacProof:m}=a.data;return m?(0,o.DmkResultFactory)({data:{hmacProof:m}}):(0,o.DmkResultFactory)({error:new o.InvalidStatusWordError("RenameContact final-chunk response did not carry hmac_name")})}buildPayload(e){const a=new o.ByteArrayBuilder;return(0,r.encodeTlvUInt8)(a,r.CONTACTS_TLV_TAG.STRUCT_TYPE,r.STRUCT_TYPE_EDIT_CONTACT_NAME),(0,r.encodeTlvUInt8)(a,r.CONTACTS_TLV_TAG.STRUCT_VERSION,r.STRUCT_VERSION_VALUE),(0,r.encodeTlvAscii)(a,r.CONTACTS_TLV_TAG.CONTACT_NAME,e.newContactName),(0,r.encodeTlvAscii)(a,r.CONTACTS_TLV_TAG.PREVIOUS_CONTACT_NAME,e.previousContactName),(0,r.encodeTlvBuffer)(a,r.CONTACTS_TLV_TAG.GROUP_HANDLE,e.groupHandle),(0,r.encodeTlvBuffer)(a,r.CONTACTS_TLV_TAG.DERIVATION_PATH,(0,r.packDerivationPath)([2147483692,2147483708,2147483648,0,0])),(0,r.encodeTlvBuffer)(a,r.CONTACTS_TLV_TAG.HMAC_PROOF,e.hmacProof),a.build()}}0&&(module.exports={SendRenameContactTask});
2
+ //# sourceMappingURL=SendRenameContactTask.js.map