@ledgerhq/device-contacts-kit 0.0.0-develop-20260827155839 → 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 (286) hide show
  1. package/README.md +57 -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/RegisterExternalAddressDeviceActionTypes.js +2 -0
  5. package/lib/cjs/api/app-binder/RegisterExternalAddressDeviceActionTypes.js.map +7 -0
  6. package/lib/cjs/api/app-binder/RenameContactDeviceActionTypes.js +2 -0
  7. package/lib/cjs/api/app-binder/RenameContactDeviceActionTypes.js.map +7 -0
  8. package/lib/cjs/api/index.js +1 -1
  9. package/lib/cjs/api/index.js.map +2 -2
  10. package/lib/cjs/api/model/RegisterExternalAddress.js +2 -0
  11. package/lib/cjs/api/model/RegisterExternalAddress.js.map +7 -0
  12. package/lib/cjs/api/model/RenameContact.js +2 -0
  13. package/lib/cjs/api/model/RenameContact.js.map +7 -0
  14. package/lib/cjs/internal/DefaultContactsManager.js +1 -1
  15. package/lib/cjs/internal/DefaultContactsManager.js.map +3 -3
  16. package/lib/cjs/internal/DefaultContactsManager.test.js +2 -0
  17. package/lib/cjs/internal/DefaultContactsManager.test.js.map +7 -0
  18. package/lib/cjs/internal/app-binder/ContactsAppBinder.js +1 -1
  19. package/lib/cjs/internal/app-binder/ContactsAppBinder.js.map +3 -3
  20. package/lib/cjs/internal/app-binder/command/RegisterIdentityCommand.js +2 -0
  21. package/lib/cjs/internal/app-binder/command/RegisterIdentityCommand.js.map +7 -0
  22. package/lib/cjs/internal/app-binder/command/RegisterIdentityCommand.test.js +2 -0
  23. package/lib/cjs/internal/app-binder/command/RegisterIdentityCommand.test.js.map +7 -0
  24. package/lib/cjs/internal/app-binder/command/RenameContactCommand.js +2 -0
  25. package/lib/cjs/internal/app-binder/command/RenameContactCommand.js.map +7 -0
  26. package/lib/cjs/internal/app-binder/command/RenameContactCommand.test.js +2 -0
  27. package/lib/cjs/internal/app-binder/command/RenameContactCommand.test.js.map +7 -0
  28. package/lib/cjs/internal/app-binder/device-action/RegisterExternalAddress/RegisterExternalAddressDeviceAction.js +2 -0
  29. package/lib/cjs/internal/app-binder/device-action/RegisterExternalAddress/RegisterExternalAddressDeviceAction.js.map +7 -0
  30. package/lib/cjs/internal/app-binder/device-action/RegisterExternalAddress/RegisterExternalAddressDeviceAction.test.js +2 -0
  31. package/lib/cjs/internal/app-binder/device-action/RegisterExternalAddress/RegisterExternalAddressDeviceAction.test.js.map +7 -0
  32. package/lib/cjs/internal/app-binder/device-action/RegisterExternalAddress/validateRegisterExternalAddressInput.js +2 -0
  33. package/lib/cjs/internal/app-binder/device-action/RegisterExternalAddress/validateRegisterExternalAddressInput.js.map +7 -0
  34. package/lib/cjs/internal/app-binder/device-action/RegisterExternalAddress/validateRegisterExternalAddressInput.test.js +2 -0
  35. package/lib/cjs/internal/app-binder/device-action/RegisterExternalAddress/validateRegisterExternalAddressInput.test.js.map +7 -0
  36. package/lib/cjs/internal/app-binder/device-action/RenameContact/RenameContactDeviceAction.js +2 -0
  37. package/lib/cjs/internal/app-binder/device-action/RenameContact/RenameContactDeviceAction.js.map +7 -0
  38. package/lib/cjs/internal/app-binder/device-action/RenameContact/RenameContactDeviceAction.test.js +2 -0
  39. package/lib/cjs/internal/app-binder/device-action/RenameContact/RenameContactDeviceAction.test.js.map +7 -0
  40. package/lib/cjs/internal/app-binder/device-action/RenameContact/validateRenameContactInput.js +2 -0
  41. package/lib/cjs/internal/app-binder/device-action/RenameContact/validateRenameContactInput.js.map +7 -0
  42. package/lib/cjs/internal/app-binder/device-action/RenameContact/validateRenameContactInput.test.js +2 -0
  43. package/lib/cjs/internal/app-binder/device-action/RenameContact/validateRenameContactInput.test.js.map +7 -0
  44. package/lib/cjs/internal/app-binder/device-action/__test-utils__/makeInternalApi.js +2 -0
  45. package/lib/cjs/internal/app-binder/device-action/__test-utils__/makeInternalApi.js.map +7 -0
  46. package/lib/cjs/internal/app-binder/device-action/__test-utils__/setupGoToDashboardDAMock.js +2 -0
  47. package/lib/cjs/internal/app-binder/device-action/__test-utils__/setupGoToDashboardDAMock.js.map +7 -0
  48. package/lib/cjs/internal/app-binder/device-action/__test-utils__/setupOpenAppDAMock.js +2 -0
  49. package/lib/cjs/internal/app-binder/device-action/__test-utils__/setupOpenAppDAMock.js.map +7 -0
  50. package/lib/cjs/internal/app-binder/device-action/__test-utils__/setupWaitForAppAndVersionDAMock.js +2 -0
  51. package/lib/cjs/internal/app-binder/device-action/__test-utils__/setupWaitForAppAndVersionDAMock.js.map +7 -0
  52. package/lib/cjs/internal/app-binder/device-action/__test-utils__/testDeviceActionStates.js +2 -0
  53. package/lib/cjs/internal/app-binder/device-action/__test-utils__/testDeviceActionStates.js.map +7 -0
  54. package/lib/cjs/internal/app-binder/isContactsSupportedForSession.js +1 -1
  55. package/lib/cjs/internal/app-binder/isContactsSupportedForSession.js.map +3 -3
  56. package/lib/cjs/internal/app-binder/isContactsSupportedForSession.test.js +1 -1
  57. package/lib/cjs/internal/app-binder/isContactsSupportedForSession.test.js.map +3 -3
  58. package/lib/cjs/internal/app-binder/model/contactsConstants.js +2 -0
  59. package/lib/cjs/internal/app-binder/model/contactsConstants.js.map +7 -0
  60. package/lib/cjs/internal/app-binder/model/contactsErrors.js +2 -0
  61. package/lib/cjs/internal/app-binder/model/contactsErrors.js.map +7 -0
  62. package/lib/cjs/internal/app-binder/model/contactsValidation.js +2 -0
  63. package/lib/cjs/internal/app-binder/model/contactsValidation.js.map +7 -0
  64. package/lib/cjs/internal/app-binder/model/contactsValidation.test.js +2 -0
  65. package/lib/cjs/internal/app-binder/model/contactsValidation.test.js.map +7 -0
  66. package/lib/cjs/internal/app-binder/services/contactsTlvSerializer.js +2 -0
  67. package/lib/cjs/internal/app-binder/services/contactsTlvSerializer.js.map +7 -0
  68. package/lib/cjs/internal/app-binder/services/contactsTlvSerializer.test.js +2 -0
  69. package/lib/cjs/internal/app-binder/services/contactsTlvSerializer.test.js.map +7 -0
  70. package/lib/cjs/internal/app-binder/services/sendFramedContactsPayload.js +2 -0
  71. package/lib/cjs/internal/app-binder/services/sendFramedContactsPayload.js.map +7 -0
  72. package/lib/cjs/internal/app-binder/services/sendFramedContactsPayload.test.js +2 -0
  73. package/lib/cjs/internal/app-binder/services/sendFramedContactsPayload.test.js.map +7 -0
  74. package/lib/cjs/internal/app-binder/task/SendRegisterIdentityTask.js +2 -0
  75. package/lib/cjs/internal/app-binder/task/SendRegisterIdentityTask.js.map +7 -0
  76. package/lib/cjs/internal/app-binder/task/SendRegisterIdentityTask.test.js +2 -0
  77. package/lib/cjs/internal/app-binder/task/SendRegisterIdentityTask.test.js.map +7 -0
  78. package/lib/cjs/internal/app-binder/task/SendRenameContactTask.js +2 -0
  79. package/lib/cjs/internal/app-binder/task/SendRenameContactTask.js.map +7 -0
  80. package/lib/cjs/internal/app-binder/task/SendRenameContactTask.test.js +2 -0
  81. package/lib/cjs/internal/app-binder/task/SendRenameContactTask.test.js.map +7 -0
  82. package/lib/cjs/internal/di.js +1 -1
  83. package/lib/cjs/internal/di.js.map +3 -3
  84. package/lib/cjs/internal/di.test.js +1 -1
  85. package/lib/cjs/internal/di.test.js.map +3 -3
  86. package/lib/cjs/internal/use-cases/RegisterExternalAddressUseCase.js +2 -0
  87. package/lib/cjs/internal/use-cases/RegisterExternalAddressUseCase.js.map +7 -0
  88. package/lib/cjs/internal/use-cases/RegisterExternalAddressUseCase.test.js +2 -0
  89. package/lib/cjs/internal/use-cases/RegisterExternalAddressUseCase.test.js.map +7 -0
  90. package/lib/cjs/internal/use-cases/RenameContactUseCase.js +2 -0
  91. package/lib/cjs/internal/use-cases/RenameContactUseCase.js.map +7 -0
  92. package/lib/cjs/internal/use-cases/RenameContactUseCase.test.js +2 -0
  93. package/lib/cjs/internal/use-cases/RenameContactUseCase.test.js.map +7 -0
  94. package/lib/cjs/internal/use-cases/di/useCaseModule.js +2 -0
  95. package/lib/cjs/internal/use-cases/di/useCaseModule.js.map +7 -0
  96. package/lib/cjs/internal/use-cases/di/useCaseTypes.js +2 -0
  97. package/lib/cjs/internal/use-cases/di/useCaseTypes.js.map +7 -0
  98. package/lib/cjs/package.json +2 -1
  99. package/lib/esm/api/app-binder/RegisterExternalAddressDeviceActionTypes.js +1 -0
  100. package/lib/esm/api/app-binder/RegisterExternalAddressDeviceActionTypes.js.map +7 -0
  101. package/lib/esm/api/app-binder/RenameContactDeviceActionTypes.js +1 -0
  102. package/lib/esm/api/app-binder/RenameContactDeviceActionTypes.js.map +7 -0
  103. package/lib/esm/api/index.js +1 -1
  104. package/lib/esm/api/index.js.map +2 -2
  105. package/lib/esm/api/model/RegisterExternalAddress.js +1 -0
  106. package/lib/esm/api/model/RegisterExternalAddress.js.map +7 -0
  107. package/lib/esm/api/model/RenameContact.js +1 -0
  108. package/lib/esm/api/model/RenameContact.js.map +7 -0
  109. package/lib/esm/internal/DefaultContactsManager.js +1 -1
  110. package/lib/esm/internal/DefaultContactsManager.js.map +3 -3
  111. package/lib/esm/internal/DefaultContactsManager.test.js +2 -0
  112. package/lib/esm/internal/DefaultContactsManager.test.js.map +7 -0
  113. package/lib/esm/internal/app-binder/ContactsAppBinder.js +1 -1
  114. package/lib/esm/internal/app-binder/ContactsAppBinder.js.map +3 -3
  115. package/lib/esm/internal/app-binder/command/RegisterIdentityCommand.js +2 -0
  116. package/lib/esm/internal/app-binder/command/RegisterIdentityCommand.js.map +7 -0
  117. package/lib/esm/internal/app-binder/command/RegisterIdentityCommand.test.js +2 -0
  118. package/lib/esm/internal/app-binder/command/RegisterIdentityCommand.test.js.map +7 -0
  119. package/lib/esm/internal/app-binder/command/RenameContactCommand.js +2 -0
  120. package/lib/esm/internal/app-binder/command/RenameContactCommand.js.map +7 -0
  121. package/lib/esm/internal/app-binder/command/RenameContactCommand.test.js +2 -0
  122. package/lib/esm/internal/app-binder/command/RenameContactCommand.test.js.map +7 -0
  123. package/lib/esm/internal/app-binder/device-action/RegisterExternalAddress/RegisterExternalAddressDeviceAction.js +2 -0
  124. package/lib/esm/internal/app-binder/device-action/RegisterExternalAddress/RegisterExternalAddressDeviceAction.js.map +7 -0
  125. package/lib/esm/internal/app-binder/device-action/RegisterExternalAddress/RegisterExternalAddressDeviceAction.test.js +2 -0
  126. package/lib/esm/internal/app-binder/device-action/RegisterExternalAddress/RegisterExternalAddressDeviceAction.test.js.map +7 -0
  127. package/lib/esm/internal/app-binder/device-action/RegisterExternalAddress/validateRegisterExternalAddressInput.js +2 -0
  128. package/lib/esm/internal/app-binder/device-action/RegisterExternalAddress/validateRegisterExternalAddressInput.js.map +7 -0
  129. package/lib/esm/internal/app-binder/device-action/RegisterExternalAddress/validateRegisterExternalAddressInput.test.js +2 -0
  130. package/lib/esm/internal/app-binder/device-action/RegisterExternalAddress/validateRegisterExternalAddressInput.test.js.map +7 -0
  131. package/lib/esm/internal/app-binder/device-action/RenameContact/RenameContactDeviceAction.js +2 -0
  132. package/lib/esm/internal/app-binder/device-action/RenameContact/RenameContactDeviceAction.js.map +7 -0
  133. package/lib/esm/internal/app-binder/device-action/RenameContact/RenameContactDeviceAction.test.js +2 -0
  134. package/lib/esm/internal/app-binder/device-action/RenameContact/RenameContactDeviceAction.test.js.map +7 -0
  135. package/lib/esm/internal/app-binder/device-action/RenameContact/validateRenameContactInput.js +2 -0
  136. package/lib/esm/internal/app-binder/device-action/RenameContact/validateRenameContactInput.js.map +7 -0
  137. package/lib/esm/internal/app-binder/device-action/RenameContact/validateRenameContactInput.test.js +2 -0
  138. package/lib/esm/internal/app-binder/device-action/RenameContact/validateRenameContactInput.test.js.map +7 -0
  139. package/lib/esm/internal/app-binder/device-action/__test-utils__/makeInternalApi.js +2 -0
  140. package/lib/esm/internal/app-binder/device-action/__test-utils__/makeInternalApi.js.map +7 -0
  141. package/lib/esm/internal/app-binder/device-action/__test-utils__/setupGoToDashboardDAMock.js +2 -0
  142. package/lib/esm/internal/app-binder/device-action/__test-utils__/setupGoToDashboardDAMock.js.map +7 -0
  143. package/lib/esm/internal/app-binder/device-action/__test-utils__/setupOpenAppDAMock.js +2 -0
  144. package/lib/esm/internal/app-binder/device-action/__test-utils__/setupOpenAppDAMock.js.map +7 -0
  145. package/lib/esm/internal/app-binder/device-action/__test-utils__/setupWaitForAppAndVersionDAMock.js +2 -0
  146. package/lib/esm/internal/app-binder/device-action/__test-utils__/setupWaitForAppAndVersionDAMock.js.map +7 -0
  147. package/lib/esm/internal/app-binder/device-action/__test-utils__/testDeviceActionStates.js +2 -0
  148. package/lib/esm/internal/app-binder/device-action/__test-utils__/testDeviceActionStates.js.map +7 -0
  149. package/lib/esm/internal/app-binder/isContactsSupportedForSession.js +1 -1
  150. package/lib/esm/internal/app-binder/isContactsSupportedForSession.js.map +3 -3
  151. package/lib/esm/internal/app-binder/isContactsSupportedForSession.test.js +1 -1
  152. package/lib/esm/internal/app-binder/isContactsSupportedForSession.test.js.map +3 -3
  153. package/lib/esm/internal/app-binder/model/contactsConstants.js +2 -0
  154. package/lib/esm/internal/app-binder/model/contactsConstants.js.map +7 -0
  155. package/lib/esm/internal/app-binder/model/contactsErrors.js +2 -0
  156. package/lib/esm/internal/app-binder/model/contactsErrors.js.map +7 -0
  157. package/lib/esm/internal/app-binder/model/contactsValidation.js +2 -0
  158. package/lib/esm/internal/app-binder/model/contactsValidation.js.map +7 -0
  159. package/lib/esm/internal/app-binder/model/contactsValidation.test.js +2 -0
  160. package/lib/esm/internal/app-binder/model/contactsValidation.test.js.map +7 -0
  161. package/lib/esm/internal/app-binder/services/contactsTlvSerializer.js +2 -0
  162. package/lib/esm/internal/app-binder/services/contactsTlvSerializer.js.map +7 -0
  163. package/lib/esm/internal/app-binder/services/contactsTlvSerializer.test.js +2 -0
  164. package/lib/esm/internal/app-binder/services/contactsTlvSerializer.test.js.map +7 -0
  165. package/lib/esm/internal/app-binder/services/sendFramedContactsPayload.js +2 -0
  166. package/lib/esm/internal/app-binder/services/sendFramedContactsPayload.js.map +7 -0
  167. package/lib/esm/internal/app-binder/services/sendFramedContactsPayload.test.js +2 -0
  168. package/lib/esm/internal/app-binder/services/sendFramedContactsPayload.test.js.map +7 -0
  169. package/lib/esm/internal/app-binder/task/SendRegisterIdentityTask.js +2 -0
  170. package/lib/esm/internal/app-binder/task/SendRegisterIdentityTask.js.map +7 -0
  171. package/lib/esm/internal/app-binder/task/SendRegisterIdentityTask.test.js +2 -0
  172. package/lib/esm/internal/app-binder/task/SendRegisterIdentityTask.test.js.map +7 -0
  173. package/lib/esm/internal/app-binder/task/SendRenameContactTask.js +2 -0
  174. package/lib/esm/internal/app-binder/task/SendRenameContactTask.js.map +7 -0
  175. package/lib/esm/internal/app-binder/task/SendRenameContactTask.test.js +2 -0
  176. package/lib/esm/internal/app-binder/task/SendRenameContactTask.test.js.map +7 -0
  177. package/lib/esm/internal/di.js +1 -1
  178. package/lib/esm/internal/di.js.map +3 -3
  179. package/lib/esm/internal/di.test.js +1 -1
  180. package/lib/esm/internal/di.test.js.map +3 -3
  181. package/lib/esm/internal/use-cases/RegisterExternalAddressUseCase.js +2 -0
  182. package/lib/esm/internal/use-cases/RegisterExternalAddressUseCase.js.map +7 -0
  183. package/lib/esm/internal/use-cases/RegisterExternalAddressUseCase.test.js +2 -0
  184. package/lib/esm/internal/use-cases/RegisterExternalAddressUseCase.test.js.map +7 -0
  185. package/lib/esm/internal/use-cases/RenameContactUseCase.js +2 -0
  186. package/lib/esm/internal/use-cases/RenameContactUseCase.js.map +7 -0
  187. package/lib/esm/internal/use-cases/RenameContactUseCase.test.js +2 -0
  188. package/lib/esm/internal/use-cases/RenameContactUseCase.test.js.map +7 -0
  189. package/lib/esm/internal/use-cases/di/useCaseModule.js +2 -0
  190. package/lib/esm/internal/use-cases/di/useCaseModule.js.map +7 -0
  191. package/lib/esm/internal/use-cases/di/useCaseTypes.js +2 -0
  192. package/lib/esm/internal/use-cases/di/useCaseTypes.js.map +7 -0
  193. package/lib/esm/package.json +2 -1
  194. package/lib/types/api/ContactsManager.d.ts +23 -5
  195. package/lib/types/api/ContactsManager.d.ts.map +1 -1
  196. package/lib/types/api/app-binder/RegisterExternalAddressDeviceActionTypes.d.ts +30 -0
  197. package/lib/types/api/app-binder/RegisterExternalAddressDeviceActionTypes.d.ts.map +1 -0
  198. package/lib/types/api/app-binder/RenameContactDeviceActionTypes.d.ts +25 -0
  199. package/lib/types/api/app-binder/RenameContactDeviceActionTypes.d.ts.map +1 -0
  200. package/lib/types/api/index.d.ts +4 -0
  201. package/lib/types/api/index.d.ts.map +1 -1
  202. package/lib/types/api/model/RegisterExternalAddress.d.ts +50 -0
  203. package/lib/types/api/model/RegisterExternalAddress.d.ts.map +1 -0
  204. package/lib/types/api/model/RenameContact.d.ts +39 -0
  205. package/lib/types/api/model/RenameContact.d.ts.map +1 -0
  206. package/lib/types/internal/DefaultContactsManager.d.ts +8 -2
  207. package/lib/types/internal/DefaultContactsManager.d.ts.map +1 -1
  208. package/lib/types/internal/DefaultContactsManager.test.d.ts +2 -0
  209. package/lib/types/internal/DefaultContactsManager.test.d.ts.map +1 -0
  210. package/lib/types/internal/app-binder/ContactsAppBinder.d.ts +7 -3
  211. package/lib/types/internal/app-binder/ContactsAppBinder.d.ts.map +1 -1
  212. package/lib/types/internal/app-binder/command/RegisterIdentityCommand.d.ts +30 -0
  213. package/lib/types/internal/app-binder/command/RegisterIdentityCommand.d.ts.map +1 -0
  214. package/lib/types/internal/app-binder/command/RegisterIdentityCommand.test.d.ts +2 -0
  215. package/lib/types/internal/app-binder/command/RegisterIdentityCommand.test.d.ts.map +1 -0
  216. package/lib/types/internal/app-binder/command/RenameContactCommand.d.ts +25 -0
  217. package/lib/types/internal/app-binder/command/RenameContactCommand.d.ts.map +1 -0
  218. package/lib/types/internal/app-binder/command/RenameContactCommand.test.d.ts +2 -0
  219. package/lib/types/internal/app-binder/command/RenameContactCommand.test.d.ts.map +1 -0
  220. package/lib/types/internal/app-binder/device-action/RegisterExternalAddress/RegisterExternalAddressDeviceAction.d.ts +14 -0
  221. package/lib/types/internal/app-binder/device-action/RegisterExternalAddress/RegisterExternalAddressDeviceAction.d.ts.map +1 -0
  222. package/lib/types/internal/app-binder/device-action/RegisterExternalAddress/RegisterExternalAddressDeviceAction.test.d.ts +2 -0
  223. package/lib/types/internal/app-binder/device-action/RegisterExternalAddress/RegisterExternalAddressDeviceAction.test.d.ts.map +1 -0
  224. package/lib/types/internal/app-binder/device-action/RegisterExternalAddress/validateRegisterExternalAddressInput.d.ts +12 -0
  225. package/lib/types/internal/app-binder/device-action/RegisterExternalAddress/validateRegisterExternalAddressInput.d.ts.map +1 -0
  226. package/lib/types/internal/app-binder/device-action/RegisterExternalAddress/validateRegisterExternalAddressInput.test.d.ts +2 -0
  227. package/lib/types/internal/app-binder/device-action/RegisterExternalAddress/validateRegisterExternalAddressInput.test.d.ts.map +1 -0
  228. package/lib/types/internal/app-binder/device-action/RenameContact/RenameContactDeviceAction.d.ts +13 -0
  229. package/lib/types/internal/app-binder/device-action/RenameContact/RenameContactDeviceAction.d.ts.map +1 -0
  230. package/lib/types/internal/app-binder/device-action/RenameContact/RenameContactDeviceAction.test.d.ts +2 -0
  231. package/lib/types/internal/app-binder/device-action/RenameContact/RenameContactDeviceAction.test.d.ts.map +1 -0
  232. package/lib/types/internal/app-binder/device-action/RenameContact/validateRenameContactInput.d.ts +12 -0
  233. package/lib/types/internal/app-binder/device-action/RenameContact/validateRenameContactInput.d.ts.map +1 -0
  234. package/lib/types/internal/app-binder/device-action/RenameContact/validateRenameContactInput.test.d.ts +2 -0
  235. package/lib/types/internal/app-binder/device-action/RenameContact/validateRenameContactInput.test.d.ts.map +1 -0
  236. package/lib/types/internal/app-binder/device-action/__test-utils__/makeInternalApi.d.ts +4 -0
  237. package/lib/types/internal/app-binder/device-action/__test-utils__/makeInternalApi.d.ts.map +1 -0
  238. package/lib/types/internal/app-binder/device-action/__test-utils__/setupGoToDashboardDAMock.d.ts +12 -0
  239. package/lib/types/internal/app-binder/device-action/__test-utils__/setupGoToDashboardDAMock.d.ts.map +1 -0
  240. package/lib/types/internal/app-binder/device-action/__test-utils__/setupOpenAppDAMock.d.ts +2 -0
  241. package/lib/types/internal/app-binder/device-action/__test-utils__/setupOpenAppDAMock.d.ts.map +1 -0
  242. package/lib/types/internal/app-binder/device-action/__test-utils__/setupWaitForAppAndVersionDAMock.d.ts +17 -0
  243. package/lib/types/internal/app-binder/device-action/__test-utils__/setupWaitForAppAndVersionDAMock.d.ts.map +1 -0
  244. package/lib/types/internal/app-binder/device-action/__test-utils__/testDeviceActionStates.d.ts +15 -0
  245. package/lib/types/internal/app-binder/device-action/__test-utils__/testDeviceActionStates.d.ts.map +1 -0
  246. package/lib/types/internal/app-binder/isContactsSupportedForSession.d.ts +31 -8
  247. package/lib/types/internal/app-binder/isContactsSupportedForSession.d.ts.map +1 -1
  248. package/lib/types/internal/app-binder/model/contactsConstants.d.ts +39 -0
  249. package/lib/types/internal/app-binder/model/contactsConstants.d.ts.map +1 -0
  250. package/lib/types/internal/app-binder/model/contactsErrors.d.ts +30 -0
  251. package/lib/types/internal/app-binder/model/contactsErrors.d.ts.map +1 -0
  252. package/lib/types/internal/app-binder/model/contactsValidation.d.ts +53 -0
  253. package/lib/types/internal/app-binder/model/contactsValidation.d.ts.map +1 -0
  254. package/lib/types/internal/app-binder/model/contactsValidation.test.d.ts +2 -0
  255. package/lib/types/internal/app-binder/model/contactsValidation.test.d.ts.map +1 -0
  256. package/lib/types/internal/app-binder/services/contactsTlvSerializer.d.ts +33 -0
  257. package/lib/types/internal/app-binder/services/contactsTlvSerializer.d.ts.map +1 -0
  258. package/lib/types/internal/app-binder/services/contactsTlvSerializer.test.d.ts +2 -0
  259. package/lib/types/internal/app-binder/services/contactsTlvSerializer.test.d.ts.map +1 -0
  260. package/lib/types/internal/app-binder/services/sendFramedContactsPayload.d.ts +14 -0
  261. package/lib/types/internal/app-binder/services/sendFramedContactsPayload.d.ts.map +1 -0
  262. package/lib/types/internal/app-binder/services/sendFramedContactsPayload.test.d.ts +2 -0
  263. package/lib/types/internal/app-binder/services/sendFramedContactsPayload.test.d.ts.map +1 -0
  264. package/lib/types/internal/app-binder/task/SendRegisterIdentityTask.d.ts +25 -0
  265. package/lib/types/internal/app-binder/task/SendRegisterIdentityTask.d.ts.map +1 -0
  266. package/lib/types/internal/app-binder/task/SendRegisterIdentityTask.test.d.ts +2 -0
  267. package/lib/types/internal/app-binder/task/SendRegisterIdentityTask.test.d.ts.map +1 -0
  268. package/lib/types/internal/app-binder/task/SendRenameContactTask.d.ts +20 -0
  269. package/lib/types/internal/app-binder/task/SendRenameContactTask.d.ts.map +1 -0
  270. package/lib/types/internal/app-binder/task/SendRenameContactTask.test.d.ts +2 -0
  271. package/lib/types/internal/app-binder/task/SendRenameContactTask.test.d.ts.map +1 -0
  272. package/lib/types/internal/di.d.ts.map +1 -1
  273. package/lib/types/internal/use-cases/RegisterExternalAddressUseCase.d.ts +17 -0
  274. package/lib/types/internal/use-cases/RegisterExternalAddressUseCase.d.ts.map +1 -0
  275. package/lib/types/internal/use-cases/RegisterExternalAddressUseCase.test.d.ts +2 -0
  276. package/lib/types/internal/use-cases/RegisterExternalAddressUseCase.test.d.ts.map +1 -0
  277. package/lib/types/internal/use-cases/RenameContactUseCase.d.ts +19 -0
  278. package/lib/types/internal/use-cases/RenameContactUseCase.d.ts.map +1 -0
  279. package/lib/types/internal/use-cases/RenameContactUseCase.test.d.ts +2 -0
  280. package/lib/types/internal/use-cases/RenameContactUseCase.test.d.ts.map +1 -0
  281. package/lib/types/internal/use-cases/di/useCaseModule.d.ts +3 -0
  282. package/lib/types/internal/use-cases/di/useCaseModule.d.ts.map +1 -0
  283. package/lib/types/internal/use-cases/di/useCaseTypes.d.ts +5 -0
  284. package/lib/types/internal/use-cases/di/useCaseTypes.d.ts.map +1 -0
  285. package/lib/types/tsconfig.prod.tsbuildinfo +1 -1
  286. package/package.json +7 -6
@@ -0,0 +1,7 @@
1
+ {
2
+ "version": 3,
3
+ "sources": ["../../../../../../src/internal/app-binder/device-action/RegisterExternalAddress/RegisterExternalAddressDeviceAction.test.ts"],
4
+ "sourcesContent": ["import {\n CommandResultFactory,\n type DeviceActionState,\n DeviceActionStatus,\n DeviceModelId,\n DeviceSessionStateType,\n DeviceStatus,\n UnknownDAError,\n UserInteractionRequired,\n} from \"@ledgerhq/device-management-kit\";\nimport { beforeEach, describe, it, vi } from \"vitest\";\n\nimport {\n type RegisterExternalAddressDAError,\n type RegisterExternalAddressDAInput,\n type RegisterExternalAddressDAIntermediateValue,\n type RegisterExternalAddressDAOutput,\n} from \"@api/app-binder/RegisterExternalAddressDeviceActionTypes\";\nimport { makeDeviceActionInternalApiMock } from \"@internal/app-binder/device-action/__test-utils__/makeInternalApi\";\nimport { setupOpenAppDAMock } from \"@internal/app-binder/device-action/__test-utils__/setupOpenAppDAMock\";\nimport { setupWaitForAppAndVersionDAMock } from \"@internal/app-binder/device-action/__test-utils__/setupWaitForAppAndVersionDAMock\";\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 { RegisterExternalAddressDeviceAction } from \"./RegisterExternalAddressDeviceAction\";\nimport { validateRegisterExternalAddressInput } from \"./validateRegisterExternalAddressInput\";\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 OpenAppDeviceAction: vi.fn(() => ({\n makeStateMachine: vi.fn(),\n })),\n WaitForAppAndVersionDeviceAction: vi.fn(() => ({\n makeStateMachine: vi.fn(),\n })),\n };\n});\n\nconst FRESH_APP = { name: \"Ethereum\", version: \"1.15.0\" };\n\nconst OK_PROOFS = {\n groupHandle: new Uint8Array(64).fill(0xcc),\n hmacProof: new Uint8Array(32).fill(0xdd),\n hmacRest: new Uint8Array(32).fill(0xaa),\n};\n\nconst BASE_INPUT = {\n contactName: \"Alice\",\n scope: \"Eth main\",\n identifier: new Uint8Array(20).fill(0x11),\n blockchainFamily: \"ethereum\",\n chainId: 1n,\n appName: \"Ethereum\",\n};\n\ndescribe(\"RegisterExternalAddressDeviceAction\", () => {\n let apiMock: ReturnType<typeof makeDeviceActionInternalApiMock>;\n let isSupportedMock: ReturnType<typeof vi.fn>;\n let registerIdentityMock: ReturnType<typeof vi.fn>;\n\n function extractDeps() {\n return {\n isSupported: isSupportedMock,\n registerIdentity: registerIdentityMock,\n };\n }\n\n beforeEach(() => {\n apiMock = makeDeviceActionInternalApiMock();\n setupWaitForAppAndVersionDAMock(FRESH_APP);\n isSupportedMock = vi.fn().mockReturnValue(true);\n registerIdentityMock = vi\n .fn()\n .mockResolvedValue(CommandResultFactory({ data: OK_PROOFS }));\n apiMock.getDeviceSessionState.mockReturnValue({\n sessionStateType: DeviceSessionStateType.ReadyWithoutSecureChannel,\n deviceStatus: DeviceStatus.CONNECTED,\n installedApps: [],\n currentApp: { name: \"Ethereum\", version: \"1.15.0\" },\n deviceModelId: DeviceModelId.FLEX,\n isSecureConnectionAllowed: true,\n });\n });\n\n function makeAction(input: RegisterExternalAddressDAInput) {\n const action = new RegisterExternalAddressDeviceAction({ input });\n vi.spyOn(action, \"extractDependencies\").mockReturnValue(extractDeps());\n return action;\n }\n\n it(\"open-app path, new contact group: OpenApp -> VersionGuard -> RegisterIdentity -> Completed\", () =>\n new Promise<void>((resolve, reject) => {\n setupOpenAppDAMock();\n const action = makeAction({ ...BASE_INPUT, skipOpenApp: false });\n\n const expected = [\n {\n intermediateValue: {\n requiredUserInteraction: UserInteractionRequired.None,\n },\n status: DeviceActionStatus.Pending,\n },\n {\n intermediateValue: {\n requiredUserInteraction: UserInteractionRequired.ConfirmOpenApp,\n },\n status: DeviceActionStatus.Pending,\n },\n // WaitForAppAndVersion phase: entry reset, then the child's silent read\n // re-emits None through onSnapshot propagation.\n {\n intermediateValue: {\n requiredUserInteraction: UserInteractionRequired.None,\n },\n status: DeviceActionStatus.Pending,\n },\n {\n intermediateValue: {\n requiredUserInteraction: UserInteractionRequired.None,\n },\n status: DeviceActionStatus.Pending,\n },\n {\n intermediateValue: {\n requiredUserInteraction: UserInteractionRequired.RegisterWallet,\n },\n status: DeviceActionStatus.Pending,\n },\n {\n output: {\n mode: \"newContactGroup\",\n contactName: \"Alice\",\n scope: \"Eth main\",\n identifier: BASE_INPUT.identifier,\n blockchainFamily: \"ethereum\",\n chainId: 1n,\n ...OK_PROOFS,\n },\n status: DeviceActionStatus.Completed,\n },\n ] as DeviceActionState<\n RegisterExternalAddressDAOutput,\n RegisterExternalAddressDAError,\n RegisterExternalAddressDAIntermediateValue\n >[];\n\n testDeviceActionStates(action, expected, apiMock, {\n onDone: resolve,\n onError: reject,\n });\n }));\n\n it(\"skip-open-app path, existing contact group: VersionGuard -> RegisterIdentity -> Completed\", () =>\n new Promise<void>((resolve, reject) => {\n setupOpenAppDAMock();\n const existingContactGroup = {\n groupHandle: new Uint8Array(64).fill(0xcc),\n hmacProof: new Uint8Array(32).fill(0xdd),\n };\n const action = makeAction({\n ...BASE_INPUT,\n skipOpenApp: true,\n existingContactGroup,\n });\n\n const expected = [\n // WaitForAppAndVersion phase: entry reset, then the child's silent read\n // re-emits None through onSnapshot propagation.\n {\n intermediateValue: {\n requiredUserInteraction: UserInteractionRequired.None,\n },\n status: DeviceActionStatus.Pending,\n },\n {\n intermediateValue: {\n requiredUserInteraction: UserInteractionRequired.None,\n },\n status: DeviceActionStatus.Pending,\n },\n {\n intermediateValue: {\n requiredUserInteraction: UserInteractionRequired.RegisterWallet,\n },\n status: DeviceActionStatus.Pending,\n },\n {\n output: {\n mode: \"existingContactGroup\",\n contactName: \"Alice\",\n scope: \"Eth main\",\n identifier: BASE_INPUT.identifier,\n blockchainFamily: \"ethereum\",\n chainId: 1n,\n ...OK_PROOFS,\n },\n status: DeviceActionStatus.Completed,\n },\n ] as DeviceActionState<\n RegisterExternalAddressDAOutput,\n RegisterExternalAddressDAError,\n RegisterExternalAddressDAIntermediateValue\n >[];\n\n testDeviceActionStates(action, expected, apiMock, {\n onDone: resolve,\n onError: reject,\n });\n }));\n\n it(\"version guard rejects on skip-open-app path without opening the app\", () =>\n new Promise<void>((resolve, reject) => {\n setupOpenAppDAMock();\n isSupportedMock.mockReturnValue(false);\n const action = makeAction({ ...BASE_INPUT, skipOpenApp: true });\n\n const expected = [\n // WaitForAppAndVersion phase (entry reset + child read) runs before the\n // guard; both reads emit None.\n {\n intermediateValue: {\n requiredUserInteraction: UserInteractionRequired.None,\n },\n status: DeviceActionStatus.Pending,\n },\n {\n intermediateValue: {\n requiredUserInteraction: UserInteractionRequired.None,\n },\n status: DeviceActionStatus.Pending,\n },\n {\n error: new ContactsVersionRequirementError(),\n status: DeviceActionStatus.Error,\n },\n ] as DeviceActionState<\n RegisterExternalAddressDAOutput,\n RegisterExternalAddressDAError,\n RegisterExternalAddressDAIntermediateValue\n >[];\n\n testDeviceActionStates(action, expected, apiMock, {\n onDone: resolve,\n onError: reject,\n });\n expect(registerIdentityMock).not.toHaveBeenCalled();\n }));\n\n it(\"surfaces an open-app failure as the device action error\", () =>\n new Promise<void>((resolve, reject) => {\n const openAppError = new UnknownDAError(\"open app failed\");\n setupOpenAppDAMock(openAppError);\n const action = makeAction({ ...BASE_INPUT, skipOpenApp: false });\n\n const expected = [\n {\n intermediateValue: {\n requiredUserInteraction: UserInteractionRequired.None,\n },\n status: DeviceActionStatus.Pending,\n },\n {\n intermediateValue: {\n requiredUserInteraction: UserInteractionRequired.ConfirmOpenApp,\n },\n status: DeviceActionStatus.Pending,\n },\n {\n error: openAppError,\n status: DeviceActionStatus.Error,\n },\n ] as DeviceActionState<\n RegisterExternalAddressDAOutput,\n RegisterExternalAddressDAError,\n RegisterExternalAddressDAIntermediateValue\n >[];\n\n testDeviceActionStates(action, expected, apiMock, {\n onDone: resolve,\n onError: reject,\n });\n expect(isSupportedMock).not.toHaveBeenCalled();\n }));\n\n it(\"surfaces a Register Identity command error\", () =>\n new Promise<void>((resolve, reject) => {\n setupOpenAppDAMock();\n const commandError = new ContactsCommandError({\n errorCode: \"6a80\",\n message: \"device rejected\",\n });\n registerIdentityMock.mockResolvedValue(\n CommandResultFactory({ error: commandError }),\n );\n const action = makeAction({ ...BASE_INPUT, skipOpenApp: true });\n\n const expected = [\n // WaitForAppAndVersion phase: entry reset, then the child's silent read\n // re-emits None through onSnapshot propagation.\n {\n intermediateValue: {\n requiredUserInteraction: UserInteractionRequired.None,\n },\n status: DeviceActionStatus.Pending,\n },\n {\n intermediateValue: {\n requiredUserInteraction: UserInteractionRequired.None,\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 RegisterExternalAddressDAOutput,\n RegisterExternalAddressDAError,\n RegisterExternalAddressDAIntermediateValue\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 state on the skip-open-app path\", () =>\n new Promise<void>((resolve, reject) => {\n setupOpenAppDAMock();\n const invalidInput = {\n ...BASE_INPUT,\n skipOpenApp: true,\n contactName: \"\",\n };\n const validationError =\n validateRegisterExternalAddressInput(invalidInput);\n const action = makeAction(invalidInput);\n\n const expected = [\n {\n error: validationError,\n status: DeviceActionStatus.Error,\n },\n ] as DeviceActionState<\n RegisterExternalAddressDAOutput,\n RegisterExternalAddressDAError,\n RegisterExternalAddressDAIntermediateValue\n >[];\n\n testDeviceActionStates(action, expected, apiMock, {\n onDone: resolve,\n onError: reject,\n });\n // Validation fails before the version guard and before any APDU.\n expect(isSupportedMock).not.toHaveBeenCalled();\n expect(registerIdentityMock).not.toHaveBeenCalled();\n }));\n\n it(\"validates only after opening the app on the default path\", () =>\n new Promise<void>((resolve, reject) => {\n setupOpenAppDAMock();\n const invalidInput = {\n ...BASE_INPUT,\n skipOpenApp: false,\n contactName: \"\",\n };\n const validationError =\n validateRegisterExternalAddressInput(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.ConfirmOpenApp,\n },\n status: DeviceActionStatus.Pending,\n },\n {\n error: validationError,\n status: DeviceActionStatus.Error,\n },\n ] as DeviceActionState<\n RegisterExternalAddressDAOutput,\n RegisterExternalAddressDAError,\n RegisterExternalAddressDAIntermediateValue\n >[];\n\n testDeviceActionStates(action, expected, apiMock, {\n onDone: resolve,\n onError: reject,\n });\n expect(registerIdentityMock).not.toHaveBeenCalled();\n }));\n\n it(\"evaluates support from the fresh WaitForAppAndVersion result, not stale session state\", () =>\n new Promise<void>((resolve, reject) => {\n setupOpenAppDAMock();\n // Session state (from beforeEach) reports version 1.15.0; the fresh read\n // reports a different version, which is what the guard must use.\n const freshApp = { name: \"Ethereum\", version: \"9.9.9\" };\n setupWaitForAppAndVersionDAMock(freshApp);\n const action = makeAction({ ...BASE_INPUT, skipOpenApp: true });\n\n const expected = [\n // WaitForAppAndVersion phase: entry reset + child read, both None.\n {\n intermediateValue: {\n requiredUserInteraction: UserInteractionRequired.None,\n },\n status: DeviceActionStatus.Pending,\n },\n {\n intermediateValue: {\n requiredUserInteraction: UserInteractionRequired.None,\n },\n status: DeviceActionStatus.Pending,\n },\n {\n intermediateValue: {\n requiredUserInteraction: UserInteractionRequired.RegisterWallet,\n },\n status: DeviceActionStatus.Pending,\n },\n {\n output: {\n mode: \"newContactGroup\",\n contactName: \"Alice\",\n scope: \"Eth main\",\n identifier: BASE_INPUT.identifier,\n blockchainFamily: \"ethereum\",\n chainId: 1n,\n ...OK_PROOFS,\n },\n status: DeviceActionStatus.Completed,\n },\n ] as DeviceActionState<\n RegisterExternalAddressDAOutput,\n RegisterExternalAddressDAError,\n RegisterExternalAddressDAIntermediateValue\n >[];\n\n testDeviceActionStates(action, expected, apiMock, {\n onDone: () => {\n try {\n expect(isSupportedMock).toHaveBeenCalledWith(freshApp);\n resolve();\n } catch (e) {\n reject(e as Error);\n }\n },\n onError: reject,\n });\n }));\n\n it(\"surfaces a WaitForAppAndVersion failure as the device action error\", () =>\n new Promise<void>((resolve, reject) => {\n setupOpenAppDAMock();\n const waitError = new UnknownDAError(\"could not read app and version\");\n setupWaitForAppAndVersionDAMock({ error: waitError });\n const action = makeAction({ ...BASE_INPUT, skipOpenApp: true });\n\n const expected = [\n // WaitForAppAndVersion phase: entry reset + child read, both None,\n // before the child DA surfaces its failure.\n {\n intermediateValue: {\n requiredUserInteraction: UserInteractionRequired.None,\n },\n status: DeviceActionStatus.Pending,\n },\n {\n intermediateValue: {\n requiredUserInteraction: UserInteractionRequired.None,\n },\n status: DeviceActionStatus.Pending,\n },\n {\n error: waitError,\n status: DeviceActionStatus.Error,\n },\n ] as DeviceActionState<\n RegisterExternalAddressDAOutput,\n RegisterExternalAddressDAError,\n RegisterExternalAddressDAIntermediateValue\n >[];\n\n testDeviceActionStates(action, expected, apiMock, {\n onDone: resolve,\n onError: reject,\n });\n // The version guard and the APDU are never reached.\n expect(isSupportedMock).not.toHaveBeenCalled();\n expect(registerIdentityMock).not.toHaveBeenCalled();\n }));\n\n it(\"propagates the UnlockDevice interaction emitted by WaitForAppAndVersion\", () =>\n new Promise<void>((resolve, reject) => {\n setupOpenAppDAMock();\n // Locked device: the child WaitForAppAndVersion DA requests an unlock\n // before it can read the app/version. The parent must surface it so a\n // consuming client can show a \"please unlock your device\" prompt.\n setupWaitForAppAndVersionDAMock(\n FRESH_APP,\n UserInteractionRequired.UnlockDevice,\n );\n const action = makeAction({ ...BASE_INPUT, skipOpenApp: true });\n\n const expected = [\n // Entry reset before the child DA runs.\n {\n intermediateValue: {\n requiredUserInteraction: UserInteractionRequired.None,\n },\n status: DeviceActionStatus.Pending,\n },\n // Propagated from the child DA: the device needs to be unlocked.\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: {\n mode: \"newContactGroup\",\n contactName: \"Alice\",\n scope: \"Eth main\",\n identifier: BASE_INPUT.identifier,\n blockchainFamily: \"ethereum\",\n chainId: 1n,\n ...OK_PROOFS,\n },\n status: DeviceActionStatus.Completed,\n },\n ] as DeviceActionState<\n RegisterExternalAddressDAOutput,\n RegisterExternalAddressDAError,\n RegisterExternalAddressDAIntermediateValue\n >[];\n\n testDeviceActionStates(action, expected, apiMock, {\n onDone: resolve,\n onError: reject,\n });\n }));\n});\n"],
5
+ "mappings": "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",
6
+ "names": ["import_device_management_kit", "import_vitest", "import_makeInternalApi", "import_setupOpenAppDAMock", "import_setupWaitForAppAndVersionDAMock", "import_testDeviceActionStates", "import_contactsErrors", "import_RegisterExternalAddressDeviceAction", "import_validateRegisterExternalAddressInput", "importOriginal", "FRESH_APP", "OK_PROOFS", "BASE_INPUT", "apiMock", "isSupportedMock", "registerIdentityMock", "extractDeps", "makeAction", "input", "action", "resolve", "reject", "expected", "existingContactGroup", "openAppError", "commandError", "invalidInput", "validationError", "freshApp", "e", "waitError"]
7
+ }
@@ -0,0 +1,2 @@
1
+ "use strict";var o=Object.defineProperty;var c=Object.getOwnPropertyDescriptor;var f=Object.getOwnPropertyNames;var l=Object.prototype.hasOwnProperty;var s=(t,i)=>{for(var n in i)o(t,n,{get:i[n],enumerable:!0})},h=(t,i,n,a)=>{if(i&&typeof i=="object"||typeof i=="function")for(let r of f(i))!l.call(t,r)&&r!==n&&o(t,r,{get:()=>i[r],enumerable:!(a=c(i,r))||a.enumerable});return t};var m=t=>h(o({},"__esModule",{value:!0}),t);var C={};s(C,{validateRegisterExternalAddressInput:()=>E});module.exports=m(C);var d=require("../../../app-binder/model/contactsConstants"),e=require("../../../app-binder/model/contactsValidation");function E(t){try{(0,e.validatePrintableLabel)(t.contactName,{field:"contactName",bufferLength:e.CONTACT_NAME_BUFFER_LENGTH}),(0,e.validatePrintableLabel)(t.scope,{field:"scope",bufferLength:e.SCOPE_BUFFER_LENGTH});const i=t.blockchainFamily.toLowerCase();if(!(i in d.BLOCKCHAIN_FAMILY_BY_NAME))throw new e.ContactsValidationError(`Unsupported blockchain family: ${t.blockchainFamily}`);if(i==="ethereum"){if((0,e.validateByteLength)(t.identifier,{field:"identifier",expectedBytes:e.ETH_ADDRESS_BYTES}),t.chainId===void 0)throw new e.ContactsValidationError("chainId is required for the Ethereum blockchain family.")}else if(t.identifier.length===0)throw new e.ContactsValidationError("identifier must not be empty.");return t.chainId!==void 0&&(0,e.validateChainId)(t.chainId),t.existingContactGroup&&((0,e.validateByteLength)(t.existingContactGroup.groupHandle,{field:"existingContactGroup.groupHandle",expectedBytes:e.GROUP_HANDLE_SIZE}),(0,e.validateByteLength)(t.existingContactGroup.hmacProof,{field:"existingContactGroup.hmacProof",expectedBytes:e.HMAC_PROOF_LENGTH})),null}catch(i){if(i instanceof e.ContactsValidationError)return i;throw i}}0&&(module.exports={validateRegisterExternalAddressInput});
2
+ //# sourceMappingURL=validateRegisterExternalAddressInput.js.map
@@ -0,0 +1,7 @@
1
+ {
2
+ "version": 3,
3
+ "sources": ["../../../../../../src/internal/app-binder/device-action/RegisterExternalAddress/validateRegisterExternalAddressInput.ts"],
4
+ "sourcesContent": ["import { type RegisterExternalAddressInput } from \"@api/model/RegisterExternalAddress\";\nimport { BLOCKCHAIN_FAMILY_BY_NAME } from \"@internal/app-binder/model/contactsConstants\";\nimport {\n CONTACT_NAME_BUFFER_LENGTH,\n ContactsValidationError,\n ETH_ADDRESS_BYTES,\n GROUP_HANDLE_SIZE,\n HMAC_PROOF_LENGTH,\n SCOPE_BUFFER_LENGTH,\n validateByteLength,\n validateChainId,\n validatePrintableLabel,\n} from \"@internal/app-binder/model/contactsValidation\";\n\n/**\n * Validate the caller input for Register External Address. 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\n * public `ContactsManager.registerExternalAddress` free of synchronous throws.\n */\nexport function validateRegisterExternalAddressInput(\n input: RegisterExternalAddressInput,\n): ContactsValidationError | null {\n try {\n validatePrintableLabel(input.contactName, {\n field: \"contactName\",\n bufferLength: CONTACT_NAME_BUFFER_LENGTH,\n });\n validatePrintableLabel(input.scope, {\n field: \"scope\",\n bufferLength: SCOPE_BUFFER_LENGTH,\n });\n\n const family = input.blockchainFamily.toLowerCase();\n if (!(family in BLOCKCHAIN_FAMILY_BY_NAME)) {\n throw new ContactsValidationError(\n `Unsupported blockchain family: ${input.blockchainFamily}`,\n );\n }\n if (family === \"ethereum\") {\n validateByteLength(input.identifier, {\n field: \"identifier\",\n expectedBytes: ETH_ADDRESS_BYTES,\n });\n // CHAIN_ID is mandatory for the Ethereum family (multiple networks share\n // the same address format).\n if (input.chainId === undefined) {\n throw new ContactsValidationError(\n \"chainId is required for the Ethereum blockchain family.\",\n );\n }\n } else if (input.identifier.length === 0) {\n throw new ContactsValidationError(\"identifier must not be empty.\");\n }\n\n if (input.chainId !== undefined) {\n validateChainId(input.chainId);\n }\n\n if (input.existingContactGroup) {\n validateByteLength(input.existingContactGroup.groupHandle, {\n field: \"existingContactGroup.groupHandle\",\n expectedBytes: GROUP_HANDLE_SIZE,\n });\n validateByteLength(input.existingContactGroup.hmacProof, {\n field: \"existingContactGroup.hmacProof\",\n expectedBytes: HMAC_PROOF_LENGTH,\n });\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,0CAAAE,IAAA,eAAAC,EAAAH,GACA,IAAAI,EAA0C,wDAC1CC,EAUO,yDAUA,SAASH,EACdI,EACgC,CAChC,GAAI,IACF,0BAAuBA,EAAM,YAAa,CACxC,MAAO,cACP,aAAc,4BAChB,CAAC,KACD,0BAAuBA,EAAM,MAAO,CAClC,MAAO,QACP,aAAc,qBAChB,CAAC,EAED,MAAMC,EAASD,EAAM,iBAAiB,YAAY,EAClD,GAAI,EAAEC,KAAU,6BACd,MAAM,IAAI,0BACR,kCAAkCD,EAAM,gBAAgB,EAC1D,EAEF,GAAIC,IAAW,YAOb,MANA,sBAAmBD,EAAM,WAAY,CACnC,MAAO,aACP,cAAe,mBACjB,CAAC,EAGGA,EAAM,UAAY,OACpB,MAAM,IAAI,0BACR,yDACF,UAEOA,EAAM,WAAW,SAAW,EACrC,MAAM,IAAI,0BAAwB,+BAA+B,EAGnE,OAAIA,EAAM,UAAY,WACpB,mBAAgBA,EAAM,OAAO,EAG3BA,EAAM,0BACR,sBAAmBA,EAAM,qBAAqB,YAAa,CACzD,MAAO,mCACP,cAAe,mBACjB,CAAC,KACD,sBAAmBA,EAAM,qBAAqB,UAAW,CACvD,MAAO,iCACP,cAAe,mBACjB,CAAC,GAGI,IACT,OAASE,EAAO,CACd,GAAIA,aAAiB,0BACnB,OAAOA,EAET,MAAMA,CACR,CACF",
6
+ "names": ["validateRegisterExternalAddressInput_exports", "__export", "validateRegisterExternalAddressInput", "__toCommonJS", "import_contactsConstants", "import_contactsValidation", "input", "family", "error"]
7
+ }
@@ -0,0 +1,2 @@
1
+ "use strict";var n=require("../../../app-binder/model/contactsValidation"),e=require("./validateRegisterExternalAddressInput");const t={contactName:"Alice",scope:"Eth main",identifier:new Uint8Array(20).fill(17),blockchainFamily:"ethereum",chainId:1n};describe("validateRegisterExternalAddressInput",()=>{it("returns null for valid input",()=>{expect((0,e.validateRegisterExternalAddressInput)(t)).toBeNull()}),it("returns null for a valid existing-contact-group input",()=>{expect((0,e.validateRegisterExternalAddressInput)({...t,existingContactGroup:{groupHandle:new Uint8Array(64),hmacProof:new Uint8Array(32)}})).toBeNull()}),it("returns a ContactsValidationError for a non-printable contact name",()=>{expect((0,e.validateRegisterExternalAddressInput)({...t,contactName:"Am\xE9lie"})).toBeInstanceOf(n.ContactsValidationError)}),it("returns an error for an Ethereum identifier of the wrong length",()=>{expect((0,e.validateRegisterExternalAddressInput)({...t,identifier:new Uint8Array(19)})).toBeInstanceOf(n.ContactsValidationError)}),it("returns an error for an unsupported blockchain family",()=>{expect((0,e.validateRegisterExternalAddressInput)({...t,blockchainFamily:"dogecoin"})).toBeInstanceOf(n.ContactsValidationError)}),it("returns an error when chainId is missing for the Ethereum family",()=>{expect((0,e.validateRegisterExternalAddressInput)({...t,chainId:void 0})).toBeInstanceOf(n.ContactsValidationError)}),it("returns an error for a wrong-sized existing group handle",()=>{expect((0,e.validateRegisterExternalAddressInput)({...t,existingContactGroup:{groupHandle:new Uint8Array(32),hmacProof:new Uint8Array(32)}})).toBeInstanceOf(n.ContactsValidationError)})});
2
+ //# sourceMappingURL=validateRegisterExternalAddressInput.test.js.map
@@ -0,0 +1,7 @@
1
+ {
2
+ "version": 3,
3
+ "sources": ["../../../../../../src/internal/app-binder/device-action/RegisterExternalAddress/validateRegisterExternalAddressInput.test.ts"],
4
+ "sourcesContent": ["import { type RegisterExternalAddressInput } from \"@api/model/RegisterExternalAddress\";\nimport { ContactsValidationError } from \"@internal/app-binder/model/contactsValidation\";\n\nimport { validateRegisterExternalAddressInput } from \"./validateRegisterExternalAddressInput\";\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(\"validateRegisterExternalAddressInput\", () => {\n it(\"returns null for valid input\", () => {\n expect(validateRegisterExternalAddressInput(VALID_INPUT)).toBeNull();\n });\n\n it(\"returns null for a valid existing-contact-group input\", () => {\n expect(\n validateRegisterExternalAddressInput({\n ...VALID_INPUT,\n existingContactGroup: {\n groupHandle: new Uint8Array(64),\n hmacProof: new Uint8Array(32),\n },\n }),\n ).toBeNull();\n });\n\n it(\"returns a ContactsValidationError for a non-printable contact name\", () => {\n expect(\n validateRegisterExternalAddressInput({\n ...VALID_INPUT,\n contactName: \"Am\u00E9lie\",\n }),\n ).toBeInstanceOf(ContactsValidationError);\n });\n\n it(\"returns an error for an Ethereum identifier of the wrong length\", () => {\n expect(\n validateRegisterExternalAddressInput({\n ...VALID_INPUT,\n identifier: new Uint8Array(19),\n }),\n ).toBeInstanceOf(ContactsValidationError);\n });\n\n it(\"returns an error for an unsupported blockchain family\", () => {\n expect(\n validateRegisterExternalAddressInput({\n ...VALID_INPUT,\n blockchainFamily: \"dogecoin\",\n }),\n ).toBeInstanceOf(ContactsValidationError);\n });\n\n it(\"returns an error when chainId is missing for the Ethereum family\", () => {\n expect(\n validateRegisterExternalAddressInput({\n ...VALID_INPUT,\n chainId: undefined,\n }),\n ).toBeInstanceOf(ContactsValidationError);\n });\n\n it(\"returns an error for a wrong-sized existing group handle\", () => {\n expect(\n validateRegisterExternalAddressInput({\n ...VALID_INPUT,\n existingContactGroup: {\n groupHandle: new Uint8Array(32),\n hmacProof: new Uint8Array(32),\n },\n }),\n ).toBeInstanceOf(ContactsValidationError);\n });\n});\n"],
5
+ "mappings": "aACA,IAAAA,EAAwC,yDAExCC,EAAqD,kDAErD,MAAMC,EAA4C,CAChD,YAAa,QACb,MAAO,WACP,WAAY,IAAI,WAAW,EAAE,EAAE,KAAK,EAAI,EACxC,iBAAkB,WAClB,QAAS,EACX,EAEA,SAAS,uCAAwC,IAAM,CACrD,GAAG,+BAAgC,IAAM,CACvC,UAAO,wCAAqCA,CAAW,CAAC,EAAE,SAAS,CACrE,CAAC,EAED,GAAG,wDAAyD,IAAM,CAChE,UACE,wCAAqC,CACnC,GAAGA,EACH,qBAAsB,CACpB,YAAa,IAAI,WAAW,EAAE,EAC9B,UAAW,IAAI,WAAW,EAAE,CAC9B,CACF,CAAC,CACH,EAAE,SAAS,CACb,CAAC,EAED,GAAG,qEAAsE,IAAM,CAC7E,UACE,wCAAqC,CACnC,GAAGA,EACH,YAAa,WACf,CAAC,CACH,EAAE,eAAe,yBAAuB,CAC1C,CAAC,EAED,GAAG,kEAAmE,IAAM,CAC1E,UACE,wCAAqC,CACnC,GAAGA,EACH,WAAY,IAAI,WAAW,EAAE,CAC/B,CAAC,CACH,EAAE,eAAe,yBAAuB,CAC1C,CAAC,EAED,GAAG,wDAAyD,IAAM,CAChE,UACE,wCAAqC,CACnC,GAAGA,EACH,iBAAkB,UACpB,CAAC,CACH,EAAE,eAAe,yBAAuB,CAC1C,CAAC,EAED,GAAG,mEAAoE,IAAM,CAC3E,UACE,wCAAqC,CACnC,GAAGA,EACH,QAAS,MACX,CAAC,CACH,EAAE,eAAe,yBAAuB,CAC1C,CAAC,EAED,GAAG,2DAA4D,IAAM,CACnE,UACE,wCAAqC,CACnC,GAAGA,EACH,qBAAsB,CACpB,YAAa,IAAI,WAAW,EAAE,EAC9B,UAAW,IAAI,WAAW,EAAE,CAC9B,CACF,CAAC,CACH,EAAE,eAAe,yBAAuB,CAC1C,CAAC,CACH,CAAC",
6
+ "names": ["import_contactsValidation", "import_validateRegisterExternalAddressInput", "VALID_INPUT"]
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 r=Object.defineProperty;var o=Object.getOwnPropertyDescriptor;var f=Object.getOwnPropertyNames;var a=Object.prototype.hasOwnProperty;var c=(n,e)=>{for(var t in e)r(n,t,{get:e[t],enumerable:!0})},s=(n,e,t,v)=>{if(e&&typeof e=="object"||typeof e=="function")for(let i of f(e))!a.call(n,i)&&i!==t&&r(n,i,{get:()=>e[i],enumerable:!(v=o(e,i))||v.enumerable});return n};var d=n=>s(r({},"__esModule",{value:!0}),n);var p={};c(p,{makeDeviceActionInternalApiMock:()=>g});module.exports=d(p);function g(){return{sendApdu:vi.fn(),sendCommand:vi.fn().mockResolvedValue(void 0),getDeviceModel:vi.fn(),getDeviceSessionState:vi.fn(),getDeviceSessionStateObservable:vi.fn(),setDeviceSessionState:vi.fn(),getManagerApiService:vi.fn(),getSecureChannelService:vi.fn(),loggerFactory:vi.fn(n=>({debug:vi.fn(),info:vi.fn(),warn:vi.fn(),error:vi.fn(),subscribers:[]}))}}0&&(module.exports={makeDeviceActionInternalApiMock});
2
+ //# sourceMappingURL=makeInternalApi.js.map
@@ -0,0 +1,7 @@
1
+ {
2
+ "version": 3,
3
+ "sources": ["../../../../../../src/internal/app-binder/device-action/__test-utils__/makeInternalApi.ts"],
4
+ "sourcesContent": ["import { type InternalApi } from \"@ledgerhq/device-management-kit\";\nimport { type Mocked } from \"vitest\";\n\nexport function makeDeviceActionInternalApiMock(): Mocked<InternalApi> {\n return {\n sendApdu: vi.fn(),\n sendCommand: vi.fn().mockResolvedValue(undefined),\n getDeviceModel: vi.fn(),\n getDeviceSessionState: vi.fn(),\n getDeviceSessionStateObservable: vi.fn(),\n setDeviceSessionState: vi.fn(),\n getManagerApiService: vi.fn(),\n getSecureChannelService: vi.fn(),\n loggerFactory: vi.fn((_tag: string) => ({\n debug: vi.fn(),\n info: vi.fn(),\n warn: vi.fn(),\n error: vi.fn(),\n subscribers: [],\n })),\n };\n}\n"],
5
+ "mappings": "yaAAA,IAAAA,EAAA,GAAAC,EAAAD,EAAA,qCAAAE,IAAA,eAAAC,EAAAH,GAGO,SAASE,GAAuD,CACrE,MAAO,CACL,SAAU,GAAG,GAAG,EAChB,YAAa,GAAG,GAAG,EAAE,kBAAkB,MAAS,EAChD,eAAgB,GAAG,GAAG,EACtB,sBAAuB,GAAG,GAAG,EAC7B,gCAAiC,GAAG,GAAG,EACvC,sBAAuB,GAAG,GAAG,EAC7B,qBAAsB,GAAG,GAAG,EAC5B,wBAAyB,GAAG,GAAG,EAC/B,cAAe,GAAG,GAAIE,IAAkB,CACtC,MAAO,GAAG,GAAG,EACb,KAAM,GAAG,GAAG,EACZ,KAAM,GAAG,GAAG,EACZ,MAAO,GAAG,GAAG,EACb,YAAa,CAAC,CAChB,EAAE,CACJ,CACF",
6
+ "names": ["makeInternalApi_exports", "__export", "makeDeviceActionInternalApiMock", "__toCommonJS", "_tag"]
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
+ }
@@ -0,0 +1,2 @@
1
+ "use strict";var a=Object.defineProperty;var c=Object.getOwnPropertyDescriptor;var f=Object.getOwnPropertyNames;var d=Object.prototype.hasOwnProperty;var s=(e,n)=>{for(var i in n)a(e,i,{get:n[i],enumerable:!0})},u=(e,n,i,m)=>{if(n&&typeof n=="object"||typeof n=="function")for(let t of f(n))!d.call(e,t)&&t!==i&&a(e,t,{get:()=>n[t],enumerable:!(m=c(n,t))||m.enumerable});return e};var k=e=>u(a({},"__esModule",{value:!0}),e);var A={};s(A,{setupOpenAppDAMock:()=>l});module.exports=k(A);var o=require("@ledgerhq/device-management-kit"),p=require("purify-ts"),r=require("xstate");const l=e=>{o.OpenAppDeviceAction.mockImplementation(()=>({makeStateMachine:vi.fn().mockImplementation(()=>(0,r.createMachine)({initial:"pending",states:{pending:{entry:(0,r.assign)({intermediateValue:{requiredUserInteraction:o.UserInteractionRequired.ConfirmOpenApp}}),after:{0:"done"}},done:{type:"final"}},output:()=>e?(0,p.Left)(e):(0,p.Right)(void 0)}))}))};0&&(module.exports={setupOpenAppDAMock});
2
+ //# sourceMappingURL=setupOpenAppDAMock.js.map
@@ -0,0 +1,7 @@
1
+ {
2
+ "version": 3,
3
+ "sources": ["../../../../../../src/internal/app-binder/device-action/__test-utils__/setupOpenAppDAMock.ts"],
4
+ "sourcesContent": ["import {\n OpenAppDeviceAction,\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\nexport const setupOpenAppDAMock = (error?: unknown) => {\n (OpenAppDeviceAction as Mock).mockImplementation(() => ({\n makeStateMachine: vi.fn().mockImplementation(() =>\n createMachine({\n initial: \"pending\",\n states: {\n pending: {\n entry: assign({\n intermediateValue: {\n requiredUserInteraction: UserInteractionRequired.ConfirmOpenApp,\n },\n }),\n after: {\n 0: \"done\",\n },\n },\n done: {\n type: \"final\",\n },\n },\n output: () => (error ? Left(error) : Right(undefined)),\n }),\n ),\n }));\n};\n"],
5
+ "mappings": "yaAAA,IAAAA,EAAA,GAAAC,EAAAD,EAAA,wBAAAE,IAAA,eAAAC,EAAAH,GAAA,IAAAI,EAGO,2CACPC,EAA4B,qBAE5BC,EAAsC,kBAE/B,MAAMJ,EAAsBK,GAAoB,CACpD,sBAA6B,mBAAmB,KAAO,CACtD,iBAAkB,GAAG,GAAG,EAAE,mBAAmB,OAC3C,iBAAc,CACZ,QAAS,UACT,OAAQ,CACN,QAAS,CACP,SAAO,UAAO,CACZ,kBAAmB,CACjB,wBAAyB,0BAAwB,cACnD,CACF,CAAC,EACD,MAAO,CACL,EAAG,MACL,CACF,EACA,KAAM,CACJ,KAAM,OACR,CACF,EACA,OAAQ,IAAOA,KAAQ,QAAKA,CAAK,KAAI,SAAM,MAAS,CACtD,CAAC,CACH,CACF,EAAE,CACJ",
6
+ "names": ["setupOpenAppDAMock_exports", "__export", "setupOpenAppDAMock", "__toCommonJS", "import_device_management_kit", "import_purify_ts", "import_xstate", "error"]
7
+ }
@@ -0,0 +1,2 @@
1
+ "use strict";var a=Object.defineProperty;var c=Object.getOwnPropertyDescriptor;var s=Object.getOwnPropertyNames;var d=Object.prototype.hasOwnProperty;var f=(e,n)=>{for(var o in n)a(e,o,{get:n[o],enumerable:!0})},k=(e,n,o,m)=>{if(n&&typeof n=="object"||typeof n=="function")for(let t of s(n))!d.call(e,t)&&t!==o&&a(e,t,{get:()=>n[t],enumerable:!(m=c(n,t))||m.enumerable});return e};var u=e=>k(a({},"__esModule",{value:!0}),e);var g={};f(g,{setupWaitForAppAndVersionDAMock:()=>A});module.exports=u(g);var r=require("@ledgerhq/device-management-kit"),i=require("purify-ts"),p=require("xstate");const A=(e={name:"Ethereum",version:"1.15.0"},n=r.UserInteractionRequired.None)=>{r.WaitForAppAndVersionDeviceAction.mockImplementation(()=>({makeStateMachine:vi.fn().mockImplementation(()=>(0,p.createMachine)({initial:"pending",context:{intermediateValue:{requiredUserInteraction:n}},states:{pending:{after:{0:"done"}},done:{type:"final"}},output:()=>"error"in e?(0,i.Left)(e.error):(0,i.Right)(e)}))}))};0&&(module.exports={setupWaitForAppAndVersionDAMock});
2
+ //# sourceMappingURL=setupWaitForAppAndVersionDAMock.js.map
@@ -0,0 +1,7 @@
1
+ {
2
+ "version": 3,
3
+ "sources": ["../../../../../../src/internal/app-binder/device-action/__test-utils__/setupWaitForAppAndVersionDAMock.ts"],
4
+ "sourcesContent": ["import {\n UserInteractionRequired,\n WaitForAppAndVersionDeviceAction,\n} from \"@ledgerhq/device-management-kit\";\nimport { Left, Right } from \"purify-ts\";\nimport { type Mock } from \"vitest\";\nimport { createMachine } from \"xstate\";\n\n/**\n * Mock WaitForAppAndVersionDeviceAction to resolve immediately with either a\n * fresh `{ name, version }` (default) or an error.\n *\n * The mock machine carries an `intermediateValue` in its context (matching the\n * real DA) so the parent's onSnapshot propagation has a defined value to read.\n * Pass `requiredUserInteraction` to have the child emit an interaction (e.g.\n * UnlockDevice for a locked device) before completing.\n */\nexport const setupWaitForAppAndVersionDAMock = (\n result: { name: string; version: string } | { error: unknown } = {\n name: \"Ethereum\",\n version: \"1.15.0\",\n },\n requiredUserInteraction: UserInteractionRequired = UserInteractionRequired.None,\n) => {\n (WaitForAppAndVersionDeviceAction as Mock).mockImplementation(() => ({\n makeStateMachine: vi.fn().mockImplementation(() =>\n createMachine({\n initial: \"pending\",\n context: {\n intermediateValue: { requiredUserInteraction },\n },\n states: {\n pending: {\n after: {\n 0: \"done\",\n },\n },\n done: {\n type: \"final\",\n },\n },\n output: () => (\"error\" in result ? Left(result.error) : Right(result)),\n }),\n ),\n }));\n};\n"],
5
+ "mappings": "yaAAA,IAAAA,EAAA,GAAAC,EAAAD,EAAA,qCAAAE,IAAA,eAAAC,EAAAH,GAAA,IAAAI,EAGO,2CACPC,EAA4B,qBAE5BC,EAA8B,kBAWvB,MAAMJ,EAAkC,CAC7CK,EAAiE,CAC/D,KAAM,WACN,QAAS,QACX,EACAC,EAAmD,0BAAwB,OACxE,CACF,mCAA0C,mBAAmB,KAAO,CACnE,iBAAkB,GAAG,GAAG,EAAE,mBAAmB,OAC3C,iBAAc,CACZ,QAAS,UACT,QAAS,CACP,kBAAmB,CAAE,wBAAAA,CAAwB,CAC/C,EACA,OAAQ,CACN,QAAS,CACP,MAAO,CACL,EAAG,MACL,CACF,EACA,KAAM,CACJ,KAAM,OACR,CACF,EACA,OAAQ,IAAO,UAAWD,KAAS,QAAKA,EAAO,KAAK,KAAI,SAAMA,CAAM,CACtE,CAAC,CACH,CACF,EAAE,CACJ",
6
+ "names": ["setupWaitForAppAndVersionDAMock_exports", "__export", "setupWaitForAppAndVersionDAMock", "__toCommonJS", "import_device_management_kit", "import_purify_ts", "import_xstate", "result", "requiredUserInteraction"]
7
+ }
@@ -0,0 +1,2 @@
1
+ "use strict";var c=Object.defineProperty;var s=Object.getOwnPropertyDescriptor;var l=Object.getOwnPropertyNames;var v=Object.prototype.hasOwnProperty;var A=(t,e)=>{for(var o in e)c(t,o,{get:e[o],enumerable:!0})},d=(t,e,o,i)=>{if(e&&typeof e=="object"||typeof e=="function")for(let r of l(e))!v.call(t,r)&&r!==o&&c(t,r,{get:()=>e[r],enumerable:!(i=s(e,r))||i.enumerable});return t};var m=t=>d(c({},"__esModule",{value:!0}),t);var I={};A(I,{testDeviceActionStates:()=>D});module.exports=m(I);function D(t,e,o,{onDone:i,onError:r}){const a=[],{observable:u,cancel:p}=t._execute(o);return u.subscribe({next:n=>{a.push(n)},error:n=>{r(n)},complete:()=>{try{expect(a).toEqual(e),i()}catch(n){r(n)}}}),{observable:u,cancel:p}}0&&(module.exports={testDeviceActionStates});
2
+ //# sourceMappingURL=testDeviceActionStates.js.map
@@ -0,0 +1,7 @@
1
+ {
2
+ "version": 3,
3
+ "sources": ["../../../../../../src/internal/app-binder/device-action/__test-utils__/testDeviceActionStates.ts"],
4
+ "sourcesContent": ["import {\n type DeviceAction,\n type DeviceActionIntermediateValue,\n type DeviceActionState,\n type DmkError,\n type InternalApi,\n} from \"@ledgerhq/device-management-kit\";\n\n/**\n * Test that the states emitted by a device action match the expected states.\n * @param deviceAction The device action to test.\n * @param expectedStates The expected states.\n * @param callbacks { onDone, onError } The callbacks to call when the test is done or an error occurs.\n */\nexport function testDeviceActionStates<\n Output,\n Input,\n Error extends DmkError,\n IntermediateValue extends DeviceActionIntermediateValue,\n>(\n deviceAction: DeviceAction<Output, Input, Error, IntermediateValue>,\n expectedStates: Array<DeviceActionState<Output, Error, IntermediateValue>>,\n internalApi: InternalApi,\n {\n onDone,\n onError,\n }: {\n onDone: () => void;\n onError: (error: Error) => void;\n },\n) {\n const observedStates: Array<\n DeviceActionState<Output, Error, IntermediateValue>\n > = [];\n\n const { observable, cancel } = deviceAction._execute(internalApi);\n observable.subscribe({\n next: (state) => {\n observedStates.push(state);\n },\n error: (error) => {\n onError(error);\n },\n complete: () => {\n try {\n expect(observedStates).toEqual(expectedStates);\n onDone();\n } catch (e) {\n onError(e as Error);\n }\n },\n });\n return { observable, cancel };\n}\n"],
5
+ "mappings": "yaAAA,IAAAA,EAAA,GAAAC,EAAAD,EAAA,4BAAAE,IAAA,eAAAC,EAAAH,GAcO,SAASE,EAMdE,EACAC,EACAC,EACA,CACE,OAAAC,EACA,QAAAC,CACF,EAIA,CACA,MAAMC,EAEF,CAAC,EAEC,CAAE,WAAAC,EAAY,OAAAC,CAAO,EAAIP,EAAa,SAASE,CAAW,EAChE,OAAAI,EAAW,UAAU,CACnB,KAAOE,GAAU,CACfH,EAAe,KAAKG,CAAK,CAC3B,EACA,MAAQC,GAAU,CAChBL,EAAQK,CAAK,CACf,EACA,SAAU,IAAM,CACd,GAAI,CACF,OAAOJ,CAAc,EAAE,QAAQJ,CAAc,EAC7CE,EAAO,CACT,OAASO,EAAG,CACVN,EAAQM,CAAU,CACpB,CACF,CACF,CAAC,EACM,CAAE,WAAAJ,EAAY,OAAAC,CAAO,CAC9B",
6
+ "names": ["testDeviceActionStates_exports", "__export", "testDeviceActionStates", "__toCommonJS", "deviceAction", "expectedStates", "internalApi", "onDone", "onError", "observedStates", "observable", "cancel", "state", "error", "e"]
7
+ }
@@ -1,2 +1,2 @@
1
- "use strict";var s=Object.defineProperty;var u=Object.getOwnPropertyDescriptor;var m=Object.getOwnPropertyNames;var d=Object.prototype.hasOwnProperty;var l=(i,e)=>{for(var n in e)s(i,n,{get:e[n],enumerable:!0})},A=(i,e,n,t)=>{if(e&&typeof e=="object"||typeof e=="function")for(let r of m(e))!d.call(i,r)&&r!==n&&s(i,r,{get:()=>e[r],enumerable:!(t=u(e,r))||t.enumerable});return i};var V=i=>A(s({},"__esModule",{value:!0}),i);var v={};l(v,{isContactsSupportedForSession:()=>C});module.exports=V(v);var f=require("@ledgerhq/device-management-kit"),o=require("../../api/model/ContactsVersionRequirements"),c=require("./ContactsApplicationResolver");function C(i,e){const n=i.getDeviceSessionState(),t=(0,o.resolveContactsVersionRequirements)(n.deviceModelId);if(!t.supported)return!1;const r="currentApp"in n?n.currentApp?.name:void 0;if(r===void 0)return!1;const p=t.minAppVersion[r];if(p===void 0||!new f.ApplicationChecker(n,e,new c.ContactsApplicationResolver).withMinVersionInclusive(p).check())return!1;const a="firmwareVersion"in n?n.firmwareVersion?.os:void 0;return a===void 0?!1:(0,o.isVersionAtLeast)(a,t.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 type AppConfig,\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/**\n * Session-aware Contacts support check, for internal consumption by Contacts\n * `DeviceAction`s. Reads the current device session and resolves it against the\n * static requirements table:\n * - the device model must be supported;\n * - the running app must be known to Contacts and meet its minimum version \u2014\n * validated with DMK's {@link ApplicationChecker} so the version comes from\n * the authoritative `GetAppConfiguration` result;\n * - the device OS must meet its minimum version (a dimension `ApplicationChecker`\n * does not cover, so it is checked separately here).\n *\n * @param internalApi - the DeviceAction's internal API for the current session.\n * @param appConfig - the running app's configuration (must include its version).\n */\nexport function isContactsSupportedForSession(\n internalApi: InternalApi,\n appConfig: AppConfig,\n): boolean {\n const deviceState = internalApi.getDeviceSessionState();\n const requirement = resolveContactsVersionRequirements(\n deviceState.deviceModelId,\n );\n if (!requirement.supported) return false;\n\n const appName =\n \"currentApp\" in deviceState ? deviceState.currentApp?.name : undefined;\n if (appName === undefined) return false;\n\n const minAppVersion = requirement.minAppVersion[appName];\n if (minAppVersion === undefined) return false;\n\n const appCompatible = new ApplicationChecker(\n deviceState,\n appConfig,\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,EAIO,2CAEPC,EAGO,kDAEPC,EAA4C,yCAgBrC,SAASJ,EACdK,EACAC,EACS,CACT,MAAMC,EAAcF,EAAY,sBAAsB,EAChDG,KAAc,sCAClBD,EAAY,aACd,EACA,GAAI,CAACC,EAAY,UAAW,MAAO,GAEnC,MAAMC,EACJ,eAAgBF,EAAcA,EAAY,YAAY,KAAO,OAC/D,GAAIE,IAAY,OAAW,MAAO,GAElC,MAAMC,EAAgBF,EAAY,cAAcC,CAAO,EAUvD,GATIC,IAAkB,QASlB,CAPkB,IAAI,qBACxBH,EACAD,EACA,IAAI,6BACN,EACG,wBAAwBI,CAAa,EACrC,MAAM,EACW,MAAO,GAE3B,MAAMC,EACJ,oBAAqBJ,EACjBA,EAAY,iBAAiB,GAC7B,OACN,OAAII,IAAc,OAAkB,MAE7B,oBAAiBA,EAAWH,EAAY,YAAY,CAC7D",
6
- "names": ["isContactsSupportedForSession_exports", "__export", "isContactsSupportedForSession", "__toCommonJS", "import_device_management_kit", "import_ContactsVersionRequirements", "import_ContactsApplicationResolver", "internalApi", "appConfig", "deviceState", "requirement", "appName", "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 t=require("@ledgerhq/device-management-kit"),p=require("../../api/model/ContactsVersionRequirements"),n=require("./isContactsSupportedForSession");const c=(()=>{const e=(0,p.resolveContactsVersionRequirements)(t.DeviceModelId.FLEX);if(!e.supported)throw new Error("Flex must be supported");return e})(),l=c.minOsVersion,i=(()=>{const e=c.minAppVersion[p.ETHEREUM_APP_NAME];if(e===void 0)throw new Error("Ethereum min version required");return e})(),a="0.0.1";function r({appName:e=p.ETHEREUM_APP_NAME,osVersion:u=l,modelId:d=t.DeviceModelId.FLEX}={}){return{sessionStateType:t.DeviceSessionStateType.ReadyWithoutSecureChannel,deviceStatus:t.DeviceStatus.CONNECTED,installedApps:[],currentApp:{name:e,version:"0.0.0"},deviceModelId:d,firmwareVersion:{mcu:"1.0.0",bootloader:"1.0.0",os:u},isSecureConnectionAllowed:!1}}function o(e){return{getDeviceSessionState:()=>e}}function s(e){return{version:e}}describe("isContactsSupportedForSession",()=>{it("returns true when model, app version and OS version all meet the minimums",()=>{const e=o(r());expect((0,n.isContactsSupportedForSession)(e,s(i))).toBe(!0)}),it("returns false on an unsupported device model",()=>{const e=o(r({modelId:t.DeviceModelId.NANO_X}));expect((0,n.isContactsSupportedForSession)(e,s(i))).toBe(!1)}),it("returns false when the app version is below the minimum",()=>{const e=o(r());expect((0,n.isContactsSupportedForSession)(e,s(a))).toBe(!1)}),it("returns false when the running app is unknown to Contacts",()=>{const e=o(r({appName:"Bitcoin"}));expect((0,n.isContactsSupportedForSession)(e,s(i))).toBe(!1)}),it("returns false when the OS version is below the minimum",()=>{const e=o(r({osVersion:a}));expect((0,n.isContactsSupportedForSession)(e,s(i))).toBe(!1)}),it("returns false when the device session has no running app",()=>{const e=o({sessionStateType:t.DeviceSessionStateType.Connected,deviceStatus:t.DeviceStatus.CONNECTED,deviceModelId:t.DeviceModelId.FLEX});expect((0,n.isContactsSupportedForSession)(e,s(i))).toBe(!1)})});
1
+ "use strict";var t=require("@ledgerhq/device-management-kit"),o=require("../../api/model/ContactsVersionRequirements"),n=require("./isContactsSupportedForSession");const c=(()=>{const e=(0,o.resolveContactsVersionRequirements)(t.DeviceModelId.FLEX);if(!e.supported)throw new Error("Flex must be supported");return e})(),u=c.minOsVersion,d=(()=>{const e=c.minAppVersion[o.ETHEREUM_APP_NAME];if(e===void 0)throw new Error("Ethereum min version required");return e})(),a="0.0.1";function r({osVersion:e=u,modelId:p=t.DeviceModelId.FLEX}={}){return{sessionStateType:t.DeviceSessionStateType.ReadyWithoutSecureChannel,deviceStatus:t.DeviceStatus.CONNECTED,installedApps:[],currentApp:{name:o.ETHEREUM_APP_NAME,version:"0.0.0"},deviceModelId:p,firmwareVersion:{mcu:"1.0.0",bootloader:"1.0.0",os:e},isSecureConnectionAllowed:!1}}function s(e){return{getDeviceSessionState:()=>e}}function i(e=o.ETHEREUM_APP_NAME,p=d){return{name:e,version:p}}describe("isContactsSupportedForSession",()=>{it("returns true when model, app version and OS version all meet the minimums",()=>{const e=s(r());expect((0,n.isContactsSupportedForSession)(e,i())).toBe(!0)}),it("returns false on an unsupported device model",()=>{const e=s(r({modelId:t.DeviceModelId.NANO_X}));expect((0,n.isContactsSupportedForSession)(e,i())).toBe(!1)}),it("returns false when the app version is below the minimum",()=>{const e=s(r());expect((0,n.isContactsSupportedForSession)(e,i(o.ETHEREUM_APP_NAME,a))).toBe(!1)}),it("returns false when the running app is unknown to Contacts",()=>{const e=s(r());expect((0,n.isContactsSupportedForSession)(e,i("Bitcoin"))).toBe(!1)}),it("returns false when the OS version is below the minimum",()=>{const e=s(r({osVersion:a}));expect((0,n.isContactsSupportedForSession)(e,i())).toBe(!1)}),it("returns false when the device session has no running app",()=>{const e=s({sessionStateType:t.DeviceSessionStateType.Connected,deviceStatus:t.DeviceStatus.CONNECTED,deviceModelId:t.DeviceModelId.FLEX});expect((0,n.isContactsSupportedForSession)(e,i())).toBe(!1)})});
2
2
  //# sourceMappingURL=isContactsSupportedForSession.test.js.map
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "version": 3,
3
3
  "sources": ["../../../../src/internal/app-binder/isContactsSupportedForSession.test.ts"],
4
- "sourcesContent": ["import {\n type AppConfig,\n DeviceModelId,\n DeviceSessionStateType,\n DeviceStatus,\n type InternalApi,\n} from \"@ledgerhq/device-management-kit\";\n\nimport {\n ETHEREUM_APP_NAME,\n resolveContactsVersionRequirements,\n} from \"@api/model/ContactsVersionRequirements\";\n\nimport { isContactsSupportedForSession } from \"./isContactsSupportedForSession\";\n\nconst flexSupport = (() => {\n const requirement = resolveContactsVersionRequirements(DeviceModelId.FLEX);\n if (!requirement.supported) throw new Error(\"Flex must be supported\");\n return requirement;\n})();\n\nconst MIN_OS_VERSION = flexSupport.minOsVersion;\nconst MIN_APP_VERSION = (() => {\n const version = flexSupport.minAppVersion[ETHEREUM_APP_NAME];\n if (version === undefined) throw new Error(\"Ethereum min version required\");\n return version;\n})();\nconst BELOW_ANY_VERSION = \"0.0.1\";\n\ntype ReadyStateOptions = {\n appName?: string;\n osVersion?: string;\n modelId?: DeviceModelId;\n};\n\nfunction createReadyState({\n appName = ETHEREUM_APP_NAME,\n osVersion = MIN_OS_VERSION,\n modelId = DeviceModelId.FLEX,\n}: ReadyStateOptions = {}) {\n return {\n sessionStateType: DeviceSessionStateType.ReadyWithoutSecureChannel,\n deviceStatus: DeviceStatus.CONNECTED,\n installedApps: [],\n currentApp: { name: appName, version: \"0.0.0\" },\n deviceModelId: modelId,\n firmwareVersion: { mcu: \"1.0.0\", bootloader: \"1.0.0\", os: osVersion },\n isSecureConnectionAllowed: false,\n };\n}\n\nfunction createInternalApi(deviceState: object): InternalApi {\n return {\n getDeviceSessionState: () => deviceState,\n } as unknown as InternalApi;\n}\n\nfunction appConfig(version: string): AppConfig {\n return { version };\n}\n\ndescribe(\"isContactsSupportedForSession\", () => {\n it(\"returns true when model, app version and OS version all meet the minimums\", () => {\n const api = createInternalApi(createReadyState());\n expect(isContactsSupportedForSession(api, appConfig(MIN_APP_VERSION))).toBe(\n true,\n );\n });\n\n it(\"returns false on an unsupported device model\", () => {\n const api = createInternalApi(\n createReadyState({ modelId: DeviceModelId.NANO_X }),\n );\n expect(isContactsSupportedForSession(api, appConfig(MIN_APP_VERSION))).toBe(\n false,\n );\n });\n\n // App-version requirement.\n it(\"returns false when the app version is below the minimum\", () => {\n const api = createInternalApi(createReadyState());\n expect(\n isContactsSupportedForSession(api, appConfig(BELOW_ANY_VERSION)),\n ).toBe(false);\n });\n\n it(\"returns false when the running app is unknown to Contacts\", () => {\n const api = createInternalApi(createReadyState({ appName: \"Bitcoin\" }));\n expect(isContactsSupportedForSession(api, appConfig(MIN_APP_VERSION))).toBe(\n false,\n );\n });\n\n // OS-version requirement.\n it(\"returns false when the OS version is below the minimum\", () => {\n const api = createInternalApi(\n createReadyState({ osVersion: BELOW_ANY_VERSION }),\n );\n expect(isContactsSupportedForSession(api, appConfig(MIN_APP_VERSION))).toBe(\n false,\n );\n });\n\n it(\"returns false when the device session has no running app\", () => {\n const api = createInternalApi({\n sessionStateType: DeviceSessionStateType.Connected,\n deviceStatus: DeviceStatus.CONNECTED,\n deviceModelId: DeviceModelId.FLEX,\n });\n expect(isContactsSupportedForSession(api, appConfig(MIN_APP_VERSION))).toBe(\n false,\n );\n });\n});\n"],
5
- "mappings": "aAAA,IAAAA,EAMO,2CAEPC,EAGO,kDAEPC,EAA8C,2CAE9C,MAAMC,GAAe,IAAM,CACzB,MAAMC,KAAc,sCAAmC,gBAAc,IAAI,EACzE,GAAI,CAACA,EAAY,UAAW,MAAM,IAAI,MAAM,wBAAwB,EACpE,OAAOA,CACT,GAAG,EAEGC,EAAiBF,EAAY,aAC7BG,GAAmB,IAAM,CAC7B,MAAMC,EAAUJ,EAAY,cAAc,mBAAiB,EAC3D,GAAII,IAAY,OAAW,MAAM,IAAI,MAAM,+BAA+B,EAC1E,OAAOA,CACT,GAAG,EACGC,EAAoB,QAQ1B,SAASC,EAAiB,CACxB,QAAAC,EAAU,oBACV,UAAAC,EAAYN,EACZ,QAAAO,EAAU,gBAAc,IAC1B,EAAuB,CAAC,EAAG,CACzB,MAAO,CACL,iBAAkB,yBAAuB,0BACzC,aAAc,eAAa,UAC3B,cAAe,CAAC,EAChB,WAAY,CAAE,KAAMF,EAAS,QAAS,OAAQ,EAC9C,cAAeE,EACf,gBAAiB,CAAE,IAAK,QAAS,WAAY,QAAS,GAAID,CAAU,EACpE,0BAA2B,EAC7B,CACF,CAEA,SAASE,EAAkBC,EAAkC,CAC3D,MAAO,CACL,sBAAuB,IAAMA,CAC/B,CACF,CAEA,SAASC,EAAUR,EAA4B,CAC7C,MAAO,CAAE,QAAAA,CAAQ,CACnB,CAEA,SAAS,gCAAiC,IAAM,CAC9C,GAAG,4EAA6E,IAAM,CACpF,MAAMS,EAAMH,EAAkBJ,EAAiB,CAAC,EAChD,UAAO,iCAA8BO,EAAKD,EAAUT,CAAe,CAAC,CAAC,EAAE,KACrE,EACF,CACF,CAAC,EAED,GAAG,+CAAgD,IAAM,CACvD,MAAMU,EAAMH,EACVJ,EAAiB,CAAE,QAAS,gBAAc,MAAO,CAAC,CACpD,EACA,UAAO,iCAA8BO,EAAKD,EAAUT,CAAe,CAAC,CAAC,EAAE,KACrE,EACF,CACF,CAAC,EAGD,GAAG,0DAA2D,IAAM,CAClE,MAAMU,EAAMH,EAAkBJ,EAAiB,CAAC,EAChD,UACE,iCAA8BO,EAAKD,EAAUP,CAAiB,CAAC,CACjE,EAAE,KAAK,EAAK,CACd,CAAC,EAED,GAAG,4DAA6D,IAAM,CACpE,MAAMQ,EAAMH,EAAkBJ,EAAiB,CAAE,QAAS,SAAU,CAAC,CAAC,EACtE,UAAO,iCAA8BO,EAAKD,EAAUT,CAAe,CAAC,CAAC,EAAE,KACrE,EACF,CACF,CAAC,EAGD,GAAG,yDAA0D,IAAM,CACjE,MAAMU,EAAMH,EACVJ,EAAiB,CAAE,UAAWD,CAAkB,CAAC,CACnD,EACA,UAAO,iCAA8BQ,EAAKD,EAAUT,CAAe,CAAC,CAAC,EAAE,KACrE,EACF,CACF,CAAC,EAED,GAAG,2DAA4D,IAAM,CACnE,MAAMU,EAAMH,EAAkB,CAC5B,iBAAkB,yBAAuB,UACzC,aAAc,eAAa,UAC3B,cAAe,gBAAc,IAC/B,CAAC,EACD,UAAO,iCAA8BG,EAAKD,EAAUT,CAAe,CAAC,CAAC,EAAE,KACrE,EACF,CACF,CAAC,CACH,CAAC",
6
- "names": ["import_device_management_kit", "import_ContactsVersionRequirements", "import_isContactsSupportedForSession", "flexSupport", "requirement", "MIN_OS_VERSION", "MIN_APP_VERSION", "version", "BELOW_ANY_VERSION", "createReadyState", "appName", "osVersion", "modelId", "createInternalApi", "deviceState", "appConfig", "api"]
4
+ "sourcesContent": ["import {\n DeviceModelId,\n DeviceSessionStateType,\n DeviceStatus,\n type InternalApi,\n} from \"@ledgerhq/device-management-kit\";\n\nimport {\n ETHEREUM_APP_NAME,\n resolveContactsVersionRequirements,\n} from \"@api/model/ContactsVersionRequirements\";\n\nimport {\n isContactsSupportedForSession,\n type RunningApp,\n} from \"./isContactsSupportedForSession\";\n\nconst flexSupport = (() => {\n const requirement = resolveContactsVersionRequirements(DeviceModelId.FLEX);\n if (!requirement.supported) throw new Error(\"Flex must be supported\");\n return requirement;\n})();\n\nconst MIN_OS_VERSION = flexSupport.minOsVersion;\nconst MIN_APP_VERSION = (() => {\n const version = flexSupport.minAppVersion[ETHEREUM_APP_NAME];\n if (version === undefined) throw new Error(\"Ethereum min version required\");\n return version;\n})();\nconst BELOW_ANY_VERSION = \"0.0.1\";\n\ntype ReadyStateOptions = {\n osVersion?: string;\n modelId?: DeviceModelId;\n};\n\nfunction createReadyState({\n osVersion = MIN_OS_VERSION,\n modelId = DeviceModelId.FLEX,\n}: ReadyStateOptions = {}) {\n return {\n sessionStateType: DeviceSessionStateType.ReadyWithoutSecureChannel,\n deviceStatus: DeviceStatus.CONNECTED,\n installedApps: [],\n currentApp: { name: ETHEREUM_APP_NAME, version: \"0.0.0\" },\n deviceModelId: modelId,\n firmwareVersion: { mcu: \"1.0.0\", bootloader: \"1.0.0\", os: osVersion },\n isSecureConnectionAllowed: false,\n };\n}\n\nfunction createInternalApi(deviceState: object): InternalApi {\n return {\n getDeviceSessionState: () => deviceState,\n } as unknown as InternalApi;\n}\n\n// The running app identity now comes from the caller (a fresh\n// WaitForAppAndVersion result), not the device session state.\nfunction runningApp(\n name = ETHEREUM_APP_NAME,\n version = MIN_APP_VERSION,\n): RunningApp {\n return { name, version };\n}\n\ndescribe(\"isContactsSupportedForSession\", () => {\n it(\"returns true when model, app version and OS version all meet the minimums\", () => {\n const api = createInternalApi(createReadyState());\n expect(isContactsSupportedForSession(api, runningApp())).toBe(true);\n });\n\n it(\"returns false on an unsupported device model\", () => {\n const api = createInternalApi(\n createReadyState({ modelId: DeviceModelId.NANO_X }),\n );\n expect(isContactsSupportedForSession(api, runningApp())).toBe(false);\n });\n\n // App-version requirement (evaluated from the fresh app version).\n it(\"returns false when the app version is below the minimum\", () => {\n const api = createInternalApi(createReadyState());\n expect(\n isContactsSupportedForSession(\n api,\n runningApp(ETHEREUM_APP_NAME, BELOW_ANY_VERSION),\n ),\n ).toBe(false);\n });\n\n it(\"returns false when the running app is unknown to Contacts\", () => {\n const api = createInternalApi(createReadyState());\n expect(isContactsSupportedForSession(api, runningApp(\"Bitcoin\"))).toBe(\n false,\n );\n });\n\n // OS-version requirement.\n it(\"returns false when the OS version is below the minimum\", () => {\n const api = createInternalApi(\n createReadyState({ osVersion: BELOW_ANY_VERSION }),\n );\n expect(isContactsSupportedForSession(api, runningApp())).toBe(false);\n });\n\n it(\"returns false when the device session has no running app\", () => {\n const api = createInternalApi({\n sessionStateType: DeviceSessionStateType.Connected,\n deviceStatus: DeviceStatus.CONNECTED,\n deviceModelId: DeviceModelId.FLEX,\n });\n expect(isContactsSupportedForSession(api, runningApp())).toBe(false);\n });\n});\n"],
5
+ "mappings": "aAAA,IAAAA,EAKO,2CAEPC,EAGO,kDAEPC,EAGO,2CAEP,MAAMC,GAAe,IAAM,CACzB,MAAMC,KAAc,sCAAmC,gBAAc,IAAI,EACzE,GAAI,CAACA,EAAY,UAAW,MAAM,IAAI,MAAM,wBAAwB,EACpE,OAAOA,CACT,GAAG,EAEGC,EAAiBF,EAAY,aAC7BG,GAAmB,IAAM,CAC7B,MAAMC,EAAUJ,EAAY,cAAc,mBAAiB,EAC3D,GAAII,IAAY,OAAW,MAAM,IAAI,MAAM,+BAA+B,EAC1E,OAAOA,CACT,GAAG,EACGC,EAAoB,QAO1B,SAASC,EAAiB,CACxB,UAAAC,EAAYL,EACZ,QAAAM,EAAU,gBAAc,IAC1B,EAAuB,CAAC,EAAG,CACzB,MAAO,CACL,iBAAkB,yBAAuB,0BACzC,aAAc,eAAa,UAC3B,cAAe,CAAC,EAChB,WAAY,CAAE,KAAM,oBAAmB,QAAS,OAAQ,EACxD,cAAeA,EACf,gBAAiB,CAAE,IAAK,QAAS,WAAY,QAAS,GAAID,CAAU,EACpE,0BAA2B,EAC7B,CACF,CAEA,SAASE,EAAkBC,EAAkC,CAC3D,MAAO,CACL,sBAAuB,IAAMA,CAC/B,CACF,CAIA,SAASC,EACPC,EAAO,oBACPR,EAAUD,EACE,CACZ,MAAO,CAAE,KAAAS,EAAM,QAAAR,CAAQ,CACzB,CAEA,SAAS,gCAAiC,IAAM,CAC9C,GAAG,4EAA6E,IAAM,CACpF,MAAMS,EAAMJ,EAAkBH,EAAiB,CAAC,EAChD,UAAO,iCAA8BO,EAAKF,EAAW,CAAC,CAAC,EAAE,KAAK,EAAI,CACpE,CAAC,EAED,GAAG,+CAAgD,IAAM,CACvD,MAAME,EAAMJ,EACVH,EAAiB,CAAE,QAAS,gBAAc,MAAO,CAAC,CACpD,EACA,UAAO,iCAA8BO,EAAKF,EAAW,CAAC,CAAC,EAAE,KAAK,EAAK,CACrE,CAAC,EAGD,GAAG,0DAA2D,IAAM,CAClE,MAAME,EAAMJ,EAAkBH,EAAiB,CAAC,EAChD,UACE,iCACEO,EACAF,EAAW,oBAAmBN,CAAiB,CACjD,CACF,EAAE,KAAK,EAAK,CACd,CAAC,EAED,GAAG,4DAA6D,IAAM,CACpE,MAAMQ,EAAMJ,EAAkBH,EAAiB,CAAC,EAChD,UAAO,iCAA8BO,EAAKF,EAAW,SAAS,CAAC,CAAC,EAAE,KAChE,EACF,CACF,CAAC,EAGD,GAAG,yDAA0D,IAAM,CACjE,MAAME,EAAMJ,EACVH,EAAiB,CAAE,UAAWD,CAAkB,CAAC,CACnD,EACA,UAAO,iCAA8BQ,EAAKF,EAAW,CAAC,CAAC,EAAE,KAAK,EAAK,CACrE,CAAC,EAED,GAAG,2DAA4D,IAAM,CACnE,MAAME,EAAMJ,EAAkB,CAC5B,iBAAkB,yBAAuB,UACzC,aAAc,eAAa,UAC3B,cAAe,gBAAc,IAC/B,CAAC,EACD,UAAO,iCAA8BI,EAAKF,EAAW,CAAC,CAAC,EAAE,KAAK,EAAK,CACrE,CAAC,CACH,CAAC",
6
+ "names": ["import_device_management_kit", "import_ContactsVersionRequirements", "import_isContactsSupportedForSession", "flexSupport", "requirement", "MIN_OS_VERSION", "MIN_APP_VERSION", "version", "BELOW_ANY_VERSION", "createReadyState", "osVersion", "modelId", "createInternalApi", "deviceState", "runningApp", "name", "api"]
7
7
  }
@@ -0,0 +1,2 @@
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
+ //# sourceMappingURL=contactsConstants.js.map
@@ -0,0 +1,7 @@
1
+ {
2
+ "version": 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/**\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
+ }
@@ -0,0 +1,2 @@
1
+ "use strict";var s=Object.defineProperty;var m=Object.getOwnPropertyDescriptor;var i=Object.getOwnPropertyNames;var C=Object.prototype.hasOwnProperty;var p=(r,e)=>{for(var t in e)s(r,t,{get:e[t],enumerable:!0})},g=(r,e,t,a)=>{if(e&&typeof e=="object"||typeof e=="function")for(let o of i(e))!C.call(r,o)&&o!==t&&s(r,o,{get:()=>e[o],enumerable:!(a=m(e,o))||a.enumerable});return r};var E=r=>g(s({},"__esModule",{value:!0}),r);var u={};p(u,{CONTACTS_APP_ERRORS:()=>l,CONTACT_SEED_MISMATCH_ERROR_CODE:()=>d,ContactsCommandError:()=>c,ContactsVersionRequirementError:()=>h,contactsCommandErrorFactory:()=>f});module.exports=E(u);var n=require("@ledgerhq/device-management-kit");const d="6982",l={[d]:{message:"This address-book entry was registered with a different seed. Connect the Ledger device that registered it to modify this contact."},6800:{message:"Internal error (Please report)"},6983:{message:"Wrong data length"},6984:{message:"Unsupported address-book operation for this device or app configuration"},6985:{message:"Condition not satisfied"},"6a80":{message:"Invalid contact data, or operation refused on device"},"6a84":{message:"Insufficient memory: the device address book is full"},"6a88":{message:"Contact data not found"},"6af0":{message:"Invalid value for this contact entry"},"6b00":{message:"The app rejected the contact data"},"6f00":{message:"Technical problem (Internal error, please report)"}};class c extends n.DeviceExchangeError{constructor(e){super({tag:"ContactsCommandError",...e})}}const f=r=>new c(r);class h{constructor(e="The connected device or app does not meet the Contacts version requirements."){this.message=e}_tag="ContactsVersionRequirementError";originalError}0&&(module.exports={CONTACTS_APP_ERRORS,CONTACT_SEED_MISMATCH_ERROR_CODE,ContactsCommandError,ContactsVersionRequirementError,contactsCommandErrorFactory});
2
+ //# sourceMappingURL=contactsErrors.js.map
@@ -0,0 +1,7 @@
1
+ {
2
+ "version": 3,
3
+ "sources": ["../../../../../src/internal/app-binder/model/contactsErrors.ts"],
4
+ "sourcesContent": ["import {\n type CommandErrorArgs,\n type CommandErrors,\n DeviceExchangeError,\n type DmkError,\n} from \"@ledgerhq/device-management-kit\";\n\n/**\n * Status word returned by the app's Address Book *edit* operations when the\n * seed-bound HMAC / group-handle verification fails \u2014 i.e. the entry was\n * registered with a different seed than the one currently on the device.\n *\n * The device runs this check *before* showing any UI and returns 0x6982 *only*\n * for seed-binding failures (user rejection and TLV errors return 0x6a80,\n * address validation returns 0x6af0), so 0x6982 is an unambiguous \"wrong seed\"\n * signal that consumers (e.g. Ledger Wallet) can catch to guide the user.\n */\nexport const CONTACT_SEED_MISMATCH_ERROR_CODE = \"6982\" as const;\n\nexport type ContactsErrorCodes =\n | \"6982\"\n | \"6800\"\n | \"6983\"\n | \"6984\"\n | \"6985\"\n | \"6a80\"\n | \"6a84\"\n | \"6a88\"\n | \"6af0\"\n | \"6b00\"\n | \"6f00\";\n\nexport const CONTACTS_APP_ERRORS: CommandErrors<ContactsErrorCodes> = {\n [CONTACT_SEED_MISMATCH_ERROR_CODE]: {\n message:\n \"This address-book entry was registered with a different seed. Connect the Ledger device that registered it to modify this contact.\",\n },\n \"6800\": { message: \"Internal error (Please report)\" },\n \"6983\": { message: \"Wrong data length\" },\n \"6984\": {\n message:\n \"Unsupported address-book operation for this device or app configuration\",\n },\n \"6985\": { message: \"Condition not satisfied\" },\n \"6a80\": { message: \"Invalid contact data, or operation refused on device\" },\n \"6a84\": { message: \"Insufficient memory: the device address book is full\" },\n \"6a88\": { message: \"Contact data not found\" },\n \"6af0\": { message: \"Invalid value for this contact entry\" },\n \"6b00\": { message: \"The app rejected the contact data\" },\n \"6f00\": { message: \"Technical problem (Internal error, please report)\" },\n};\n\nexport class ContactsCommandError extends DeviceExchangeError<ContactsErrorCodes> {\n constructor(args: CommandErrorArgs<ContactsErrorCodes>) {\n super({ tag: \"ContactsCommandError\", ...args });\n }\n}\n\nexport const contactsCommandErrorFactory = (\n args: CommandErrorArgs<ContactsErrorCodes>,\n) => new ContactsCommandError(args);\n\n/**\n * Raised by a Contacts `DeviceAction` when the connected device model, app\n * version, or OS version does not meet the Contacts requirements \u2014 i.e. the\n * DSDK-1376 support check fails before any APDU is sent.\n */\nexport class ContactsVersionRequirementError implements DmkError {\n readonly _tag = \"ContactsVersionRequirementError\";\n readonly originalError?: unknown;\n constructor(\n readonly message = \"The connected device or app does not meet the Contacts version requirements.\",\n ) {}\n}\n"],
5
+ "mappings": "yaAAA,IAAAA,EAAA,GAAAC,EAAAD,EAAA,yBAAAE,EAAA,qCAAAC,EAAA,yBAAAC,EAAA,oCAAAC,EAAA,gCAAAC,IAAA,eAAAC,EAAAP,GAAA,IAAAQ,EAKO,2CAYA,MAAML,EAAmC,OAenCD,EAAyD,CACpE,CAACC,CAAgC,EAAG,CAClC,QACE,oIACJ,EACA,KAAQ,CAAE,QAAS,gCAAiC,EACpD,KAAQ,CAAE,QAAS,mBAAoB,EACvC,KAAQ,CACN,QACE,yEACJ,EACA,KAAQ,CAAE,QAAS,yBAA0B,EAC7C,OAAQ,CAAE,QAAS,sDAAuD,EAC1E,OAAQ,CAAE,QAAS,sDAAuD,EAC1E,OAAQ,CAAE,QAAS,wBAAyB,EAC5C,OAAQ,CAAE,QAAS,sCAAuC,EAC1D,OAAQ,CAAE,QAAS,mCAAoC,EACvD,OAAQ,CAAE,QAAS,mDAAoD,CACzE,EAEO,MAAMC,UAA6B,qBAAwC,CAChF,YAAYK,EAA4C,CACtD,MAAM,CAAE,IAAK,uBAAwB,GAAGA,CAAK,CAAC,CAChD,CACF,CAEO,MAAMH,EACXG,GACG,IAAIL,EAAqBK,CAAI,EAO3B,MAAMJ,CAAoD,CAG/D,YACWK,EAAU,+EACnB,CADS,aAAAA,CACR,CAJM,KAAO,kCACP,aAIX",
6
+ "names": ["contactsErrors_exports", "__export", "CONTACTS_APP_ERRORS", "CONTACT_SEED_MISMATCH_ERROR_CODE", "ContactsCommandError", "ContactsVersionRequirementError", "contactsCommandErrorFactory", "__toCommonJS", "import_device_management_kit", "args", "message"]
7
+ }
@@ -0,0 +1,2 @@
1
+ "use strict";var d=Object.defineProperty;var p=Object.getOwnPropertyDescriptor;var y=Object.getOwnPropertyNames;var w=Object.prototype.hasOwnProperty;var b=(t,e)=>{for(var o in e)d(t,o,{get:e[o],enumerable:!0})},x=(t,e,o,i)=>{if(e&&typeof e=="object"||typeof e=="function")for(let n of y(e))!w.call(t,n)&&n!==o&&d(t,n,{get:()=>e[n],enumerable:!(i=p(e,n))||i.enumerable});return t};var l=t=>x(d({},"__esModule",{value:!0}),t);var L={};b(L,{CONTACT_NAME_BUFFER_LENGTH:()=>$,ContactsValidationError:()=>r,ETH_ADDRESS_BYTES:()=>I,GROUP_HANDLE_SIZE:()=>N,HMAC_PROOF_LENGTH:()=>u,MAX_BIP32_DEPTH:()=>h,SCOPE_BUFFER_LENGTH:()=>E,validateByteLength:()=>T,validateChainId:()=>O,validateDerivationPath:()=>A,validatePrintableLabel:()=>P});module.exports=l(L);const $=33,E=33,N=64,u=32,h=10,I=20;class r extends Error{_tag="ContactsValidationError";originalError;constructor(e){super(e),this.name="ContactsValidationError"}}const S=32,_=126,B=new TextEncoder;function P(t,e){const{field:o,bufferLength:i}=e;if(!t)throw new r(`${o} must not be empty (firmware rejects empty strings).`);const n=B.encode(t),s=i-1;if(n.length>s)throw new r(`${o} ${JSON.stringify(t)} is too long: ${n.length} bytes encoded (max ${s}). The device buffer is ${i} bytes including the trailing NUL.`);const f=[];for(let c=0;c<n.length;c++){const a=n[c];(a<S||a>_)&&f.push(c)}if(f.length>0){const a=Array.from(new Set(f.map(g=>n[g]))).sort((g,m)=>g-m).map(g=>`0x${g.toString(16).padStart(2,"0")}`).join(", ");throw new r(`${o} ${JSON.stringify(t)} contains ${f.length} non-ASCII byte(s) at position(s) [${f.join(", ")}]: ${a}. The device buffer is byte-level isprint() \u2014 only 0x20-0x7E are accepted, no UTF-8 / accents / emoji.`)}}function T(t,e){const{field:o,expectedBytes:i}=e;if(t.length!==i)throw new r(`${o} is ${t.length} bytes, expected ${i}.`)}function A(t){if(!t)throw new r(`derivationPath must not be empty (e.g. "m/44'/60'/0'/0/0").`);const e=t.split("/"),o=e[0]==="m"||e[0]==="M"?e.slice(1):e;if(o.length===0)throw new r(`derivationPath ${JSON.stringify(t)} has no segments past 'm'.`);if(o.length>h)throw new r(`derivationPath ${JSON.stringify(t)} has ${o.length} segments (max ${h}). Firmware rejects deeper paths.`);for(const i of o){const n=i.endsWith("'")?i.slice(0,-1):i;if(!n||!/^\d+$/.test(n))throw new r(`derivationPath ${JSON.stringify(t)} segment ${JSON.stringify(i)} is not numeric. Use plain integers, optionally suffixed with ' for hardened.`);const s=Number(n);if(!Number.isSafeInteger(s)||s>=2147483648)throw new r(`derivationPath ${JSON.stringify(t)} segment ${JSON.stringify(i)} >= 2^31. Use the ' suffix for hardening rather than overflowing.`)}}function O(t){const e=typeof t=="number";if(!e&&!(typeof t=="bigint"))throw new r(`chainId must be number or bigint, got ${typeof t}.`);if(e&&!Number.isInteger(t))throw new r(`chainId must be an integer, got ${t}.`);const i=typeof t=="bigint"?t:BigInt(t);if(i<=0n)throw new r(`chainId must be positive, got ${t}.`);const n=(1n<<64n)-1n;if(i>n)throw new r(`chainId ${t} exceeds uint64 range (max ${n}).`)}0&&(module.exports={CONTACT_NAME_BUFFER_LENGTH,ContactsValidationError,ETH_ADDRESS_BYTES,GROUP_HANDLE_SIZE,HMAC_PROOF_LENGTH,MAX_BIP32_DEPTH,SCOPE_BUFFER_LENGTH,validateByteLength,validateChainId,validateDerivationPath,validatePrintableLabel});
2
+ //# sourceMappingURL=contactsValidation.js.map
@@ -0,0 +1,7 @@
1
+ {
2
+ "version": 3,
3
+ "sources": ["../../../../../src/internal/app-binder/model/contactsValidation.ts"],
4
+ "sourcesContent": ["/**\n * Pre-APDU input validators for the Contacts operations.\n *\n * Buffer-length constants mirror the Ledger secure SDK `#define` values\n * *including* the trailing NUL terminator (so a 32-printable-char name lives in\n * a 33-byte buffer). Validators subtract 1 internally so the constants remain\n * pure equality checks against the upstream `#define`s. The byte-level\n * `0x20..0x7E` printable check exactly matches firmware `is_printable_string`.\n */\nimport { type DmkError } from \"@ledgerhq/device-management-kit\";\n\n// ---- SDK-mirrored constants -------------------------------------------------\n// Source of truth: ledger-secure-sdk/app_features/address_book/include/\n\nexport const CONTACT_NAME_BUFFER_LENGTH = 33; // identity.h:49 (incl. NUL)\nexport const SCOPE_BUFFER_LENGTH = 33; // identity.h:50 (incl. NUL)\nexport const GROUP_HANDLE_SIZE = 64; // identity.h:47\nexport const HMAC_PROOF_LENGTH = 32; // CX_SHA256_SIZE\nexport const MAX_BIP32_DEPTH = 10; // bip32.h:15 (MAX_BIP32_PATH)\nexport const ETH_ADDRESS_BYTES = 20; // protocol convention, no header\n\n// ---- error type -------------------------------------------------------------\n\n/**\n * Raised when caller input fails a pre-APDU check. Implements `DmkError` (and\n * stays an `Error` subclass) so a Contacts device action can surface it as a\n * typed terminal error state on the observable rather than throwing out of the\n * public, device-action-returning API.\n */\nexport class ContactsValidationError extends Error implements DmkError {\n readonly _tag = \"ContactsValidationError\";\n readonly originalError?: unknown;\n constructor(message: string) {\n super(message);\n this.name = \"ContactsValidationError\";\n }\n}\n\n// ---- printable-string validation -------------------------------------------\n\nconst PRINTABLE_MIN = 0x20;\nconst PRINTABLE_MAX = 0x7e;\n\nconst utf8Encoder = new TextEncoder();\n\n/**\n * Mirror of firmware `is_printable_string` + length cap. `bufferLength` is the\n * firmware's fixed buffer size *including* the trailing NUL, so the maximum\n * payload byte length is `bufferLength - 1`.\n */\nexport function validatePrintableLabel(\n value: string,\n options: { field: string; bufferLength: number },\n): void {\n const { field, bufferLength } = options;\n if (!value) {\n throw new ContactsValidationError(\n `${field} must not be empty (firmware rejects empty strings).`,\n );\n }\n const encoded = utf8Encoder.encode(value);\n const maxBytes = bufferLength - 1;\n if (encoded.length > maxBytes) {\n throw new ContactsValidationError(\n `${field} ${JSON.stringify(value)} is too long: ${encoded.length} bytes ` +\n `encoded (max ${maxBytes}). The device buffer is ${bufferLength} bytes ` +\n `including the trailing NUL.`,\n );\n }\n const badPositions: number[] = [];\n for (let i = 0; i < encoded.length; i++) {\n const byte = encoded[i]!;\n if (byte < PRINTABLE_MIN || byte > PRINTABLE_MAX) {\n badPositions.push(i);\n }\n }\n if (badPositions.length > 0) {\n const offendingBytes = Array.from(\n new Set(badPositions.map((i) => encoded[i]!)),\n ).sort((a, b) => a - b);\n const offendingHex = offendingBytes\n .map((b) => `0x${b.toString(16).padStart(2, \"0\")}`)\n .join(\", \");\n throw new ContactsValidationError(\n `${field} ${JSON.stringify(value)} contains ${badPositions.length} ` +\n `non-ASCII byte(s) at position(s) [${badPositions.join(\", \")}]: ` +\n `${offendingHex}. The device buffer is byte-level isprint() \u2014 only ` +\n `0x20-0x7E are accepted, no UTF-8 / accents / emoji.`,\n );\n }\n}\n\n// ---- byte-buffer validation ------------------------------------------------\n\n/** Assert a byte buffer is exactly `expectedBytes` long and non-empty. */\nexport function validateByteLength(\n value: Uint8Array,\n options: { field: string; expectedBytes: number },\n): void {\n const { field, expectedBytes } = options;\n if (value.length !== expectedBytes) {\n throw new ContactsValidationError(\n `${field} is ${value.length} bytes, expected ${expectedBytes}.`,\n );\n }\n}\n\n// ---- BIP32 path validation -------------------------------------------------\n\n/**\n * Sanity-check a BIP32 path before serialization. Firmware enforces depth <=\n * MAX_BIP32_DEPTH and rejects malformed segments. Accepts `m/44'/60'/0'/0/0`\n * style; segments may end in `'` (hardened).\n */\nexport function validateDerivationPath(path: string): void {\n if (!path) {\n throw new ContactsValidationError(\n `derivationPath must not be empty (e.g. \"m/44'/60'/0'/0/0\").`,\n );\n }\n const parts = path.split(\"/\");\n const segments =\n parts[0] === \"m\" || parts[0] === \"M\" ? parts.slice(1) : parts;\n if (segments.length === 0) {\n throw new ContactsValidationError(\n `derivationPath ${JSON.stringify(path)} has no segments past 'm'.`,\n );\n }\n if (segments.length > MAX_BIP32_DEPTH) {\n throw new ContactsValidationError(\n `derivationPath ${JSON.stringify(path)} has ${segments.length} segments ` +\n `(max ${MAX_BIP32_DEPTH}). Firmware rejects deeper paths.`,\n );\n }\n for (const segment of segments) {\n const token = segment.endsWith(\"'\") ? segment.slice(0, -1) : segment;\n if (!token || !/^\\d+$/.test(token)) {\n throw new ContactsValidationError(\n `derivationPath ${JSON.stringify(path)} segment ${JSON.stringify(segment)} ` +\n `is not numeric. Use plain integers, optionally suffixed with ' for hardened.`,\n );\n }\n const n = Number(token);\n if (!Number.isSafeInteger(n) || n >= 0x80000000) {\n throw new ContactsValidationError(\n `derivationPath ${JSON.stringify(path)} segment ${JSON.stringify(segment)} ` +\n `>= 2^31. Use the ' suffix for hardening rather than overflowing.`,\n );\n }\n }\n}\n\n// ---- chain id validation ---------------------------------------------------\n\n/**\n * Firmware encodes chain_id as uint64. JS `number` is fine up to 2^53; accept\n * `bigint` for the high range so callers don't silently truncate.\n */\nexport function validateChainId(value: number | bigint): void {\n const isNumber = typeof value === \"number\";\n const isBigInt = typeof value === \"bigint\";\n if (!isNumber && !isBigInt) {\n throw new ContactsValidationError(\n `chainId must be number or bigint, got ${typeof value}.`,\n );\n }\n if (isNumber && !Number.isInteger(value)) {\n throw new ContactsValidationError(\n `chainId must be an integer, got ${value}.`,\n );\n }\n const v = typeof value === \"bigint\" ? value : BigInt(value);\n if (v <= 0n) {\n throw new ContactsValidationError(\n `chainId must be positive, got ${value}.`,\n );\n }\n const UINT64_MAX = (1n << 64n) - 1n;\n if (v > UINT64_MAX) {\n throw new ContactsValidationError(\n `chainId ${value} exceeds uint64 range (max ${UINT64_MAX}).`,\n );\n }\n}\n"],
5
+ "mappings": "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",
6
+ "names": ["contactsValidation_exports", "__export", "CONTACT_NAME_BUFFER_LENGTH", "ContactsValidationError", "ETH_ADDRESS_BYTES", "GROUP_HANDLE_SIZE", "HMAC_PROOF_LENGTH", "MAX_BIP32_DEPTH", "SCOPE_BUFFER_LENGTH", "validateByteLength", "validateChainId", "validateDerivationPath", "validatePrintableLabel", "__toCommonJS", "message", "PRINTABLE_MIN", "PRINTABLE_MAX", "utf8Encoder", "value", "options", "field", "bufferLength", "encoded", "maxBytes", "badPositions", "i", "byte", "offendingHex", "a", "b", "expectedBytes", "path", "parts", "segments", "segment", "token", "n", "isNumber", "v", "UINT64_MAX"]
7
+ }