@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.
- package/README.md +57 -2
- package/lib/cjs/api/ContactsManager.js +1 -1
- package/lib/cjs/api/ContactsManager.js.map +1 -1
- package/lib/cjs/api/app-binder/RegisterExternalAddressDeviceActionTypes.js +2 -0
- package/lib/cjs/api/app-binder/RegisterExternalAddressDeviceActionTypes.js.map +7 -0
- package/lib/cjs/api/app-binder/RenameContactDeviceActionTypes.js +2 -0
- package/lib/cjs/api/app-binder/RenameContactDeviceActionTypes.js.map +7 -0
- package/lib/cjs/api/index.js +1 -1
- package/lib/cjs/api/index.js.map +2 -2
- package/lib/cjs/api/model/RegisterExternalAddress.js +2 -0
- package/lib/cjs/api/model/RegisterExternalAddress.js.map +7 -0
- package/lib/cjs/api/model/RenameContact.js +2 -0
- package/lib/cjs/api/model/RenameContact.js.map +7 -0
- package/lib/cjs/internal/DefaultContactsManager.js +1 -1
- package/lib/cjs/internal/DefaultContactsManager.js.map +3 -3
- package/lib/cjs/internal/DefaultContactsManager.test.js +2 -0
- package/lib/cjs/internal/DefaultContactsManager.test.js.map +7 -0
- package/lib/cjs/internal/app-binder/ContactsAppBinder.js +1 -1
- package/lib/cjs/internal/app-binder/ContactsAppBinder.js.map +3 -3
- package/lib/cjs/internal/app-binder/command/RegisterIdentityCommand.js +2 -0
- package/lib/cjs/internal/app-binder/command/RegisterIdentityCommand.js.map +7 -0
- package/lib/cjs/internal/app-binder/command/RegisterIdentityCommand.test.js +2 -0
- package/lib/cjs/internal/app-binder/command/RegisterIdentityCommand.test.js.map +7 -0
- package/lib/cjs/internal/app-binder/command/RenameContactCommand.js +2 -0
- package/lib/cjs/internal/app-binder/command/RenameContactCommand.js.map +7 -0
- package/lib/cjs/internal/app-binder/command/RenameContactCommand.test.js +2 -0
- package/lib/cjs/internal/app-binder/command/RenameContactCommand.test.js.map +7 -0
- package/lib/cjs/internal/app-binder/device-action/RegisterExternalAddress/RegisterExternalAddressDeviceAction.js +2 -0
- package/lib/cjs/internal/app-binder/device-action/RegisterExternalAddress/RegisterExternalAddressDeviceAction.js.map +7 -0
- package/lib/cjs/internal/app-binder/device-action/RegisterExternalAddress/RegisterExternalAddressDeviceAction.test.js +2 -0
- package/lib/cjs/internal/app-binder/device-action/RegisterExternalAddress/RegisterExternalAddressDeviceAction.test.js.map +7 -0
- package/lib/cjs/internal/app-binder/device-action/RegisterExternalAddress/validateRegisterExternalAddressInput.js +2 -0
- package/lib/cjs/internal/app-binder/device-action/RegisterExternalAddress/validateRegisterExternalAddressInput.js.map +7 -0
- package/lib/cjs/internal/app-binder/device-action/RegisterExternalAddress/validateRegisterExternalAddressInput.test.js +2 -0
- package/lib/cjs/internal/app-binder/device-action/RegisterExternalAddress/validateRegisterExternalAddressInput.test.js.map +7 -0
- package/lib/cjs/internal/app-binder/device-action/RenameContact/RenameContactDeviceAction.js +2 -0
- package/lib/cjs/internal/app-binder/device-action/RenameContact/RenameContactDeviceAction.js.map +7 -0
- package/lib/cjs/internal/app-binder/device-action/RenameContact/RenameContactDeviceAction.test.js +2 -0
- package/lib/cjs/internal/app-binder/device-action/RenameContact/RenameContactDeviceAction.test.js.map +7 -0
- package/lib/cjs/internal/app-binder/device-action/RenameContact/validateRenameContactInput.js +2 -0
- package/lib/cjs/internal/app-binder/device-action/RenameContact/validateRenameContactInput.js.map +7 -0
- package/lib/cjs/internal/app-binder/device-action/RenameContact/validateRenameContactInput.test.js +2 -0
- package/lib/cjs/internal/app-binder/device-action/RenameContact/validateRenameContactInput.test.js.map +7 -0
- package/lib/cjs/internal/app-binder/device-action/__test-utils__/makeInternalApi.js +2 -0
- package/lib/cjs/internal/app-binder/device-action/__test-utils__/makeInternalApi.js.map +7 -0
- package/lib/cjs/internal/app-binder/device-action/__test-utils__/setupGoToDashboardDAMock.js +2 -0
- package/lib/cjs/internal/app-binder/device-action/__test-utils__/setupGoToDashboardDAMock.js.map +7 -0
- package/lib/cjs/internal/app-binder/device-action/__test-utils__/setupOpenAppDAMock.js +2 -0
- package/lib/cjs/internal/app-binder/device-action/__test-utils__/setupOpenAppDAMock.js.map +7 -0
- package/lib/cjs/internal/app-binder/device-action/__test-utils__/setupWaitForAppAndVersionDAMock.js +2 -0
- package/lib/cjs/internal/app-binder/device-action/__test-utils__/setupWaitForAppAndVersionDAMock.js.map +7 -0
- package/lib/cjs/internal/app-binder/device-action/__test-utils__/testDeviceActionStates.js +2 -0
- package/lib/cjs/internal/app-binder/device-action/__test-utils__/testDeviceActionStates.js.map +7 -0
- package/lib/cjs/internal/app-binder/isContactsSupportedForSession.js +1 -1
- package/lib/cjs/internal/app-binder/isContactsSupportedForSession.js.map +3 -3
- package/lib/cjs/internal/app-binder/isContactsSupportedForSession.test.js +1 -1
- package/lib/cjs/internal/app-binder/isContactsSupportedForSession.test.js.map +3 -3
- package/lib/cjs/internal/app-binder/model/contactsConstants.js +2 -0
- package/lib/cjs/internal/app-binder/model/contactsConstants.js.map +7 -0
- package/lib/cjs/internal/app-binder/model/contactsErrors.js +2 -0
- package/lib/cjs/internal/app-binder/model/contactsErrors.js.map +7 -0
- package/lib/cjs/internal/app-binder/model/contactsValidation.js +2 -0
- package/lib/cjs/internal/app-binder/model/contactsValidation.js.map +7 -0
- package/lib/cjs/internal/app-binder/model/contactsValidation.test.js +2 -0
- package/lib/cjs/internal/app-binder/model/contactsValidation.test.js.map +7 -0
- package/lib/cjs/internal/app-binder/services/contactsTlvSerializer.js +2 -0
- package/lib/cjs/internal/app-binder/services/contactsTlvSerializer.js.map +7 -0
- package/lib/cjs/internal/app-binder/services/contactsTlvSerializer.test.js +2 -0
- package/lib/cjs/internal/app-binder/services/contactsTlvSerializer.test.js.map +7 -0
- package/lib/cjs/internal/app-binder/services/sendFramedContactsPayload.js +2 -0
- package/lib/cjs/internal/app-binder/services/sendFramedContactsPayload.js.map +7 -0
- package/lib/cjs/internal/app-binder/services/sendFramedContactsPayload.test.js +2 -0
- package/lib/cjs/internal/app-binder/services/sendFramedContactsPayload.test.js.map +7 -0
- package/lib/cjs/internal/app-binder/task/SendRegisterIdentityTask.js +2 -0
- package/lib/cjs/internal/app-binder/task/SendRegisterIdentityTask.js.map +7 -0
- package/lib/cjs/internal/app-binder/task/SendRegisterIdentityTask.test.js +2 -0
- package/lib/cjs/internal/app-binder/task/SendRegisterIdentityTask.test.js.map +7 -0
- package/lib/cjs/internal/app-binder/task/SendRenameContactTask.js +2 -0
- package/lib/cjs/internal/app-binder/task/SendRenameContactTask.js.map +7 -0
- package/lib/cjs/internal/app-binder/task/SendRenameContactTask.test.js +2 -0
- package/lib/cjs/internal/app-binder/task/SendRenameContactTask.test.js.map +7 -0
- package/lib/cjs/internal/di.js +1 -1
- package/lib/cjs/internal/di.js.map +3 -3
- package/lib/cjs/internal/di.test.js +1 -1
- package/lib/cjs/internal/di.test.js.map +3 -3
- package/lib/cjs/internal/use-cases/RegisterExternalAddressUseCase.js +2 -0
- package/lib/cjs/internal/use-cases/RegisterExternalAddressUseCase.js.map +7 -0
- package/lib/cjs/internal/use-cases/RegisterExternalAddressUseCase.test.js +2 -0
- package/lib/cjs/internal/use-cases/RegisterExternalAddressUseCase.test.js.map +7 -0
- package/lib/cjs/internal/use-cases/RenameContactUseCase.js +2 -0
- package/lib/cjs/internal/use-cases/RenameContactUseCase.js.map +7 -0
- package/lib/cjs/internal/use-cases/RenameContactUseCase.test.js +2 -0
- package/lib/cjs/internal/use-cases/RenameContactUseCase.test.js.map +7 -0
- package/lib/cjs/internal/use-cases/di/useCaseModule.js +2 -0
- package/lib/cjs/internal/use-cases/di/useCaseModule.js.map +7 -0
- package/lib/cjs/internal/use-cases/di/useCaseTypes.js +2 -0
- package/lib/cjs/internal/use-cases/di/useCaseTypes.js.map +7 -0
- package/lib/cjs/package.json +2 -1
- package/lib/esm/api/app-binder/RegisterExternalAddressDeviceActionTypes.js +1 -0
- package/lib/esm/api/app-binder/RegisterExternalAddressDeviceActionTypes.js.map +7 -0
- package/lib/esm/api/app-binder/RenameContactDeviceActionTypes.js +1 -0
- package/lib/esm/api/app-binder/RenameContactDeviceActionTypes.js.map +7 -0
- package/lib/esm/api/index.js +1 -1
- package/lib/esm/api/index.js.map +2 -2
- package/lib/esm/api/model/RegisterExternalAddress.js +1 -0
- package/lib/esm/api/model/RegisterExternalAddress.js.map +7 -0
- package/lib/esm/api/model/RenameContact.js +1 -0
- package/lib/esm/api/model/RenameContact.js.map +7 -0
- package/lib/esm/internal/DefaultContactsManager.js +1 -1
- package/lib/esm/internal/DefaultContactsManager.js.map +3 -3
- package/lib/esm/internal/DefaultContactsManager.test.js +2 -0
- package/lib/esm/internal/DefaultContactsManager.test.js.map +7 -0
- package/lib/esm/internal/app-binder/ContactsAppBinder.js +1 -1
- package/lib/esm/internal/app-binder/ContactsAppBinder.js.map +3 -3
- package/lib/esm/internal/app-binder/command/RegisterIdentityCommand.js +2 -0
- package/lib/esm/internal/app-binder/command/RegisterIdentityCommand.js.map +7 -0
- package/lib/esm/internal/app-binder/command/RegisterIdentityCommand.test.js +2 -0
- package/lib/esm/internal/app-binder/command/RegisterIdentityCommand.test.js.map +7 -0
- package/lib/esm/internal/app-binder/command/RenameContactCommand.js +2 -0
- package/lib/esm/internal/app-binder/command/RenameContactCommand.js.map +7 -0
- package/lib/esm/internal/app-binder/command/RenameContactCommand.test.js +2 -0
- package/lib/esm/internal/app-binder/command/RenameContactCommand.test.js.map +7 -0
- package/lib/esm/internal/app-binder/device-action/RegisterExternalAddress/RegisterExternalAddressDeviceAction.js +2 -0
- package/lib/esm/internal/app-binder/device-action/RegisterExternalAddress/RegisterExternalAddressDeviceAction.js.map +7 -0
- package/lib/esm/internal/app-binder/device-action/RegisterExternalAddress/RegisterExternalAddressDeviceAction.test.js +2 -0
- package/lib/esm/internal/app-binder/device-action/RegisterExternalAddress/RegisterExternalAddressDeviceAction.test.js.map +7 -0
- package/lib/esm/internal/app-binder/device-action/RegisterExternalAddress/validateRegisterExternalAddressInput.js +2 -0
- package/lib/esm/internal/app-binder/device-action/RegisterExternalAddress/validateRegisterExternalAddressInput.js.map +7 -0
- package/lib/esm/internal/app-binder/device-action/RegisterExternalAddress/validateRegisterExternalAddressInput.test.js +2 -0
- package/lib/esm/internal/app-binder/device-action/RegisterExternalAddress/validateRegisterExternalAddressInput.test.js.map +7 -0
- package/lib/esm/internal/app-binder/device-action/RenameContact/RenameContactDeviceAction.js +2 -0
- package/lib/esm/internal/app-binder/device-action/RenameContact/RenameContactDeviceAction.js.map +7 -0
- package/lib/esm/internal/app-binder/device-action/RenameContact/RenameContactDeviceAction.test.js +2 -0
- package/lib/esm/internal/app-binder/device-action/RenameContact/RenameContactDeviceAction.test.js.map +7 -0
- package/lib/esm/internal/app-binder/device-action/RenameContact/validateRenameContactInput.js +2 -0
- package/lib/esm/internal/app-binder/device-action/RenameContact/validateRenameContactInput.js.map +7 -0
- package/lib/esm/internal/app-binder/device-action/RenameContact/validateRenameContactInput.test.js +2 -0
- package/lib/esm/internal/app-binder/device-action/RenameContact/validateRenameContactInput.test.js.map +7 -0
- package/lib/esm/internal/app-binder/device-action/__test-utils__/makeInternalApi.js +2 -0
- package/lib/esm/internal/app-binder/device-action/__test-utils__/makeInternalApi.js.map +7 -0
- package/lib/esm/internal/app-binder/device-action/__test-utils__/setupGoToDashboardDAMock.js +2 -0
- package/lib/esm/internal/app-binder/device-action/__test-utils__/setupGoToDashboardDAMock.js.map +7 -0
- package/lib/esm/internal/app-binder/device-action/__test-utils__/setupOpenAppDAMock.js +2 -0
- package/lib/esm/internal/app-binder/device-action/__test-utils__/setupOpenAppDAMock.js.map +7 -0
- package/lib/esm/internal/app-binder/device-action/__test-utils__/setupWaitForAppAndVersionDAMock.js +2 -0
- package/lib/esm/internal/app-binder/device-action/__test-utils__/setupWaitForAppAndVersionDAMock.js.map +7 -0
- package/lib/esm/internal/app-binder/device-action/__test-utils__/testDeviceActionStates.js +2 -0
- package/lib/esm/internal/app-binder/device-action/__test-utils__/testDeviceActionStates.js.map +7 -0
- package/lib/esm/internal/app-binder/isContactsSupportedForSession.js +1 -1
- package/lib/esm/internal/app-binder/isContactsSupportedForSession.js.map +3 -3
- package/lib/esm/internal/app-binder/isContactsSupportedForSession.test.js +1 -1
- package/lib/esm/internal/app-binder/isContactsSupportedForSession.test.js.map +3 -3
- package/lib/esm/internal/app-binder/model/contactsConstants.js +2 -0
- package/lib/esm/internal/app-binder/model/contactsConstants.js.map +7 -0
- package/lib/esm/internal/app-binder/model/contactsErrors.js +2 -0
- package/lib/esm/internal/app-binder/model/contactsErrors.js.map +7 -0
- package/lib/esm/internal/app-binder/model/contactsValidation.js +2 -0
- package/lib/esm/internal/app-binder/model/contactsValidation.js.map +7 -0
- package/lib/esm/internal/app-binder/model/contactsValidation.test.js +2 -0
- package/lib/esm/internal/app-binder/model/contactsValidation.test.js.map +7 -0
- package/lib/esm/internal/app-binder/services/contactsTlvSerializer.js +2 -0
- package/lib/esm/internal/app-binder/services/contactsTlvSerializer.js.map +7 -0
- package/lib/esm/internal/app-binder/services/contactsTlvSerializer.test.js +2 -0
- package/lib/esm/internal/app-binder/services/contactsTlvSerializer.test.js.map +7 -0
- package/lib/esm/internal/app-binder/services/sendFramedContactsPayload.js +2 -0
- package/lib/esm/internal/app-binder/services/sendFramedContactsPayload.js.map +7 -0
- package/lib/esm/internal/app-binder/services/sendFramedContactsPayload.test.js +2 -0
- package/lib/esm/internal/app-binder/services/sendFramedContactsPayload.test.js.map +7 -0
- package/lib/esm/internal/app-binder/task/SendRegisterIdentityTask.js +2 -0
- package/lib/esm/internal/app-binder/task/SendRegisterIdentityTask.js.map +7 -0
- package/lib/esm/internal/app-binder/task/SendRegisterIdentityTask.test.js +2 -0
- package/lib/esm/internal/app-binder/task/SendRegisterIdentityTask.test.js.map +7 -0
- package/lib/esm/internal/app-binder/task/SendRenameContactTask.js +2 -0
- package/lib/esm/internal/app-binder/task/SendRenameContactTask.js.map +7 -0
- package/lib/esm/internal/app-binder/task/SendRenameContactTask.test.js +2 -0
- package/lib/esm/internal/app-binder/task/SendRenameContactTask.test.js.map +7 -0
- package/lib/esm/internal/di.js +1 -1
- package/lib/esm/internal/di.js.map +3 -3
- package/lib/esm/internal/di.test.js +1 -1
- package/lib/esm/internal/di.test.js.map +3 -3
- package/lib/esm/internal/use-cases/RegisterExternalAddressUseCase.js +2 -0
- package/lib/esm/internal/use-cases/RegisterExternalAddressUseCase.js.map +7 -0
- package/lib/esm/internal/use-cases/RegisterExternalAddressUseCase.test.js +2 -0
- package/lib/esm/internal/use-cases/RegisterExternalAddressUseCase.test.js.map +7 -0
- package/lib/esm/internal/use-cases/RenameContactUseCase.js +2 -0
- package/lib/esm/internal/use-cases/RenameContactUseCase.js.map +7 -0
- package/lib/esm/internal/use-cases/RenameContactUseCase.test.js +2 -0
- package/lib/esm/internal/use-cases/RenameContactUseCase.test.js.map +7 -0
- package/lib/esm/internal/use-cases/di/useCaseModule.js +2 -0
- package/lib/esm/internal/use-cases/di/useCaseModule.js.map +7 -0
- package/lib/esm/internal/use-cases/di/useCaseTypes.js +2 -0
- package/lib/esm/internal/use-cases/di/useCaseTypes.js.map +7 -0
- package/lib/esm/package.json +2 -1
- package/lib/types/api/ContactsManager.d.ts +23 -5
- package/lib/types/api/ContactsManager.d.ts.map +1 -1
- package/lib/types/api/app-binder/RegisterExternalAddressDeviceActionTypes.d.ts +30 -0
- package/lib/types/api/app-binder/RegisterExternalAddressDeviceActionTypes.d.ts.map +1 -0
- package/lib/types/api/app-binder/RenameContactDeviceActionTypes.d.ts +25 -0
- package/lib/types/api/app-binder/RenameContactDeviceActionTypes.d.ts.map +1 -0
- package/lib/types/api/index.d.ts +4 -0
- package/lib/types/api/index.d.ts.map +1 -1
- package/lib/types/api/model/RegisterExternalAddress.d.ts +50 -0
- package/lib/types/api/model/RegisterExternalAddress.d.ts.map +1 -0
- package/lib/types/api/model/RenameContact.d.ts +39 -0
- package/lib/types/api/model/RenameContact.d.ts.map +1 -0
- package/lib/types/internal/DefaultContactsManager.d.ts +8 -2
- package/lib/types/internal/DefaultContactsManager.d.ts.map +1 -1
- package/lib/types/internal/DefaultContactsManager.test.d.ts +2 -0
- package/lib/types/internal/DefaultContactsManager.test.d.ts.map +1 -0
- package/lib/types/internal/app-binder/ContactsAppBinder.d.ts +7 -3
- package/lib/types/internal/app-binder/ContactsAppBinder.d.ts.map +1 -1
- package/lib/types/internal/app-binder/command/RegisterIdentityCommand.d.ts +30 -0
- package/lib/types/internal/app-binder/command/RegisterIdentityCommand.d.ts.map +1 -0
- package/lib/types/internal/app-binder/command/RegisterIdentityCommand.test.d.ts +2 -0
- package/lib/types/internal/app-binder/command/RegisterIdentityCommand.test.d.ts.map +1 -0
- package/lib/types/internal/app-binder/command/RenameContactCommand.d.ts +25 -0
- package/lib/types/internal/app-binder/command/RenameContactCommand.d.ts.map +1 -0
- package/lib/types/internal/app-binder/command/RenameContactCommand.test.d.ts +2 -0
- package/lib/types/internal/app-binder/command/RenameContactCommand.test.d.ts.map +1 -0
- package/lib/types/internal/app-binder/device-action/RegisterExternalAddress/RegisterExternalAddressDeviceAction.d.ts +14 -0
- package/lib/types/internal/app-binder/device-action/RegisterExternalAddress/RegisterExternalAddressDeviceAction.d.ts.map +1 -0
- package/lib/types/internal/app-binder/device-action/RegisterExternalAddress/RegisterExternalAddressDeviceAction.test.d.ts +2 -0
- package/lib/types/internal/app-binder/device-action/RegisterExternalAddress/RegisterExternalAddressDeviceAction.test.d.ts.map +1 -0
- package/lib/types/internal/app-binder/device-action/RegisterExternalAddress/validateRegisterExternalAddressInput.d.ts +12 -0
- package/lib/types/internal/app-binder/device-action/RegisterExternalAddress/validateRegisterExternalAddressInput.d.ts.map +1 -0
- package/lib/types/internal/app-binder/device-action/RegisterExternalAddress/validateRegisterExternalAddressInput.test.d.ts +2 -0
- package/lib/types/internal/app-binder/device-action/RegisterExternalAddress/validateRegisterExternalAddressInput.test.d.ts.map +1 -0
- package/lib/types/internal/app-binder/device-action/RenameContact/RenameContactDeviceAction.d.ts +13 -0
- package/lib/types/internal/app-binder/device-action/RenameContact/RenameContactDeviceAction.d.ts.map +1 -0
- package/lib/types/internal/app-binder/device-action/RenameContact/RenameContactDeviceAction.test.d.ts +2 -0
- package/lib/types/internal/app-binder/device-action/RenameContact/RenameContactDeviceAction.test.d.ts.map +1 -0
- package/lib/types/internal/app-binder/device-action/RenameContact/validateRenameContactInput.d.ts +12 -0
- package/lib/types/internal/app-binder/device-action/RenameContact/validateRenameContactInput.d.ts.map +1 -0
- package/lib/types/internal/app-binder/device-action/RenameContact/validateRenameContactInput.test.d.ts +2 -0
- package/lib/types/internal/app-binder/device-action/RenameContact/validateRenameContactInput.test.d.ts.map +1 -0
- package/lib/types/internal/app-binder/device-action/__test-utils__/makeInternalApi.d.ts +4 -0
- package/lib/types/internal/app-binder/device-action/__test-utils__/makeInternalApi.d.ts.map +1 -0
- package/lib/types/internal/app-binder/device-action/__test-utils__/setupGoToDashboardDAMock.d.ts +12 -0
- package/lib/types/internal/app-binder/device-action/__test-utils__/setupGoToDashboardDAMock.d.ts.map +1 -0
- package/lib/types/internal/app-binder/device-action/__test-utils__/setupOpenAppDAMock.d.ts +2 -0
- package/lib/types/internal/app-binder/device-action/__test-utils__/setupOpenAppDAMock.d.ts.map +1 -0
- package/lib/types/internal/app-binder/device-action/__test-utils__/setupWaitForAppAndVersionDAMock.d.ts +17 -0
- package/lib/types/internal/app-binder/device-action/__test-utils__/setupWaitForAppAndVersionDAMock.d.ts.map +1 -0
- package/lib/types/internal/app-binder/device-action/__test-utils__/testDeviceActionStates.d.ts +15 -0
- package/lib/types/internal/app-binder/device-action/__test-utils__/testDeviceActionStates.d.ts.map +1 -0
- package/lib/types/internal/app-binder/isContactsSupportedForSession.d.ts +31 -8
- package/lib/types/internal/app-binder/isContactsSupportedForSession.d.ts.map +1 -1
- package/lib/types/internal/app-binder/model/contactsConstants.d.ts +39 -0
- package/lib/types/internal/app-binder/model/contactsConstants.d.ts.map +1 -0
- package/lib/types/internal/app-binder/model/contactsErrors.d.ts +30 -0
- package/lib/types/internal/app-binder/model/contactsErrors.d.ts.map +1 -0
- package/lib/types/internal/app-binder/model/contactsValidation.d.ts +53 -0
- package/lib/types/internal/app-binder/model/contactsValidation.d.ts.map +1 -0
- package/lib/types/internal/app-binder/model/contactsValidation.test.d.ts +2 -0
- package/lib/types/internal/app-binder/model/contactsValidation.test.d.ts.map +1 -0
- package/lib/types/internal/app-binder/services/contactsTlvSerializer.d.ts +33 -0
- package/lib/types/internal/app-binder/services/contactsTlvSerializer.d.ts.map +1 -0
- package/lib/types/internal/app-binder/services/contactsTlvSerializer.test.d.ts +2 -0
- package/lib/types/internal/app-binder/services/contactsTlvSerializer.test.d.ts.map +1 -0
- package/lib/types/internal/app-binder/services/sendFramedContactsPayload.d.ts +14 -0
- package/lib/types/internal/app-binder/services/sendFramedContactsPayload.d.ts.map +1 -0
- package/lib/types/internal/app-binder/services/sendFramedContactsPayload.test.d.ts +2 -0
- package/lib/types/internal/app-binder/services/sendFramedContactsPayload.test.d.ts.map +1 -0
- package/lib/types/internal/app-binder/task/SendRegisterIdentityTask.d.ts +25 -0
- package/lib/types/internal/app-binder/task/SendRegisterIdentityTask.d.ts.map +1 -0
- package/lib/types/internal/app-binder/task/SendRegisterIdentityTask.test.d.ts +2 -0
- package/lib/types/internal/app-binder/task/SendRegisterIdentityTask.test.d.ts.map +1 -0
- package/lib/types/internal/app-binder/task/SendRenameContactTask.d.ts +20 -0
- package/lib/types/internal/app-binder/task/SendRenameContactTask.d.ts.map +1 -0
- package/lib/types/internal/app-binder/task/SendRenameContactTask.test.d.ts +2 -0
- package/lib/types/internal/app-binder/task/SendRenameContactTask.test.d.ts.map +1 -0
- package/lib/types/internal/di.d.ts.map +1 -1
- package/lib/types/internal/use-cases/RegisterExternalAddressUseCase.d.ts +17 -0
- package/lib/types/internal/use-cases/RegisterExternalAddressUseCase.d.ts.map +1 -0
- package/lib/types/internal/use-cases/RegisterExternalAddressUseCase.test.d.ts +2 -0
- package/lib/types/internal/use-cases/RegisterExternalAddressUseCase.test.d.ts.map +1 -0
- package/lib/types/internal/use-cases/RenameContactUseCase.d.ts +19 -0
- package/lib/types/internal/use-cases/RenameContactUseCase.d.ts.map +1 -0
- package/lib/types/internal/use-cases/RenameContactUseCase.test.d.ts +2 -0
- package/lib/types/internal/use-cases/RenameContactUseCase.test.d.ts.map +1 -0
- package/lib/types/internal/use-cases/di/useCaseModule.d.ts +3 -0
- package/lib/types/internal/use-cases/di/useCaseModule.d.ts.map +1 -0
- package/lib/types/internal/use-cases/di/useCaseTypes.d.ts +5 -0
- package/lib/types/internal/use-cases/di/useCaseTypes.d.ts.map +1 -0
- package/lib/types/tsconfig.prod.tsbuildinfo +1 -1
- package/package.json +7 -6
package/README.md
CHANGED
|
@@ -27,8 +27,63 @@ const contactsManager = new ContactsManagerBuilder({
|
|
|
27
27
|
}).build();
|
|
28
28
|
```
|
|
29
29
|
|
|
30
|
-
|
|
31
|
-
|
|
30
|
+
## Registering an external address
|
|
31
|
+
|
|
32
|
+
`registerExternalAddress` runs the device's REGISTER IDENTITY operation. It opens the embedded app
|
|
33
|
+
by default, checks the [Contacts version requirements](#version-requirements), then frames the
|
|
34
|
+
request to the device and returns the device-issued proof material for the host to persist.
|
|
35
|
+
|
|
36
|
+
```ts
|
|
37
|
+
const { observable } = contactsManager.registerExternalAddress({
|
|
38
|
+
contactName: "Alice",
|
|
39
|
+
scope: "Eth main",
|
|
40
|
+
identifier: addressBytes, // 20-byte Ethereum address
|
|
41
|
+
blockchainFamily: "ethereum",
|
|
42
|
+
chainId: 1n,
|
|
43
|
+
// existingContactGroup: { groupHandle, hmacProof }, // to extend an existing contact
|
|
44
|
+
// skipOpenApp: true, // skip only the open-app step; the version guard still runs
|
|
45
|
+
});
|
|
46
|
+
|
|
47
|
+
observable.subscribe((state) => {
|
|
48
|
+
// state.intermediateValue.requiredUserInteraction surfaces open-app confirmation
|
|
49
|
+
// and the on-device Register Wallet validation.
|
|
50
|
+
if (state.status === DeviceActionStatus.Completed) {
|
|
51
|
+
const { mode, groupHandle, hmacProof, hmacRest } = state.output;
|
|
52
|
+
// persist mode ("newContactGroup" | "existingContactGroup"), the echoed
|
|
53
|
+
// input, and the proof material.
|
|
54
|
+
}
|
|
55
|
+
});
|
|
56
|
+
```
|
|
57
|
+
|
|
58
|
+
## Renaming a contact
|
|
59
|
+
|
|
60
|
+
`renameContact` runs the device's EDIT CONTACT NAME operation. Unlike the register operations, this
|
|
61
|
+
is a blockchain-agnostic **dashboard** command served by the device OS: it always navigates to the
|
|
62
|
+
dashboard first (never opens an app), checks only the [minimum OS version](#version-requirements),
|
|
63
|
+
then rotates the contact group's name proof. Pass the current name, the new name, the group's
|
|
64
|
+
`groupHandle`, and the existing `hmacProof`; the op returns the replacement group-level `hmacProof`
|
|
65
|
+
for the host to persist. Per-entry `hmacRest` values are untouched — they never cover the name.
|
|
66
|
+
|
|
67
|
+
```ts
|
|
68
|
+
const { observable } = contactsManager.renameContact({
|
|
69
|
+
previousContactName: "Alice",
|
|
70
|
+
newContactName: "Bob",
|
|
71
|
+
groupHandle, // 64 bytes, from the group's Register Identity
|
|
72
|
+
hmacProof, // 32 bytes, the current name proof
|
|
73
|
+
});
|
|
74
|
+
|
|
75
|
+
observable.subscribe((state) => {
|
|
76
|
+
// state.intermediateValue.requiredUserInteraction surfaces the go-to-dashboard
|
|
77
|
+
// steps and the on-device validation.
|
|
78
|
+
if (state.status === DeviceActionStatus.Completed) {
|
|
79
|
+
const { contactName, groupHandle, hmacProof } = state.output;
|
|
80
|
+
// persist the new name and the replacement hmacProof.
|
|
81
|
+
}
|
|
82
|
+
});
|
|
83
|
+
```
|
|
84
|
+
|
|
85
|
+
Concrete Contacts operations (Edit Identifier, Edit Scope, Register Ledger Account, Edit Ledger
|
|
86
|
+
Account) are added by their dedicated implementation tickets.
|
|
32
87
|
|
|
33
88
|
## Version requirements
|
|
34
89
|
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
"use strict";var
|
|
1
|
+
"use strict";var a=Object.defineProperty;var s=Object.getOwnPropertyDescriptor;var o=Object.getOwnPropertyNames;var m=Object.prototype.hasOwnProperty;var i=(t,e,p,n)=>{if(e&&typeof e=="object"||typeof e=="function")for(let r of o(e))!m.call(t,r)&&r!==p&&a(t,r,{get:()=>e[r],enumerable:!(n=s(e,r))||n.enumerable});return t};var R=t=>i(a({},"__esModule",{value:!0}),t);var d={};module.exports=R(d);
|
|
2
2
|
//# sourceMappingURL=ContactsManager.js.map
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"version": 3,
|
|
3
3
|
"sources": ["../../../src/api/ContactsManager.ts"],
|
|
4
|
-
"sourcesContent": ["/**\n * Public, stateless Contacts (Address Book) manager.\n *\n * It only drives device interactions \u2014 taking caller input, running the device\n * operation, and returning the device output (including proof material). It\n * does not store anything, own the address book, or handle persistence; the\n * host is responsible for that.\n
|
|
4
|
+
"sourcesContent": ["import { type RegisterExternalAddressDAReturnType } from \"@api/app-binder/RegisterExternalAddressDeviceActionTypes\";\nimport { type RenameContactDAReturnType } from \"@api/app-binder/RenameContactDeviceActionTypes\";\nimport { type RegisterExternalAddressInput } from \"@api/model/RegisterExternalAddress\";\nimport { type RenameContactInput } from \"@api/model/RenameContact\";\n\n/**\n * Public, stateless Contacts (Address Book) manager.\n *\n * It only drives device interactions \u2014 taking caller input, running the device\n * operation, and returning the device output (including proof material). It\n * does not store anything, own the address book, or handle persistence; the\n * host is responsible for that.\n */\nexport interface ContactsManager {\n /**\n * Register an external address on the device \u2014 either creating a new contact\n * group or adding the address to an existing one (via\n * `input.existingContactGroup`). Opens the embedded app by default (pass\n * `skipOpenApp: true` to skip only the open-app step; the version guard still\n * runs), checks the Contacts version requirements, then runs REGISTER\n * IDENTITY. Returns the device-issued group handle and proofs to persist.\n */\n registerExternalAddress(\n input: RegisterExternalAddressInput,\n ): RegisterExternalAddressDAReturnType;\n\n /**\n * Rename an existing contact group (EDIT CONTACT NAME). This is a\n * blockchain-agnostic dashboard operation served by the device OS: it always\n * navigates to the dashboard first (never opens an app), checks the Contacts\n * minimum OS version, then rotates the group's name proof. Pass the current\n * `previousContactName`, the `newContactName`, the group's `groupHandle`, and\n * the existing `hmacProof`; returns the replacement group-level `hmacProof` to\n * persist.\n */\n renameContact(input: RenameContactInput): RenameContactDAReturnType;\n}\n"],
|
|
5
5
|
"mappings": "+WAAA,IAAAA,EAAA,kBAAAC,EAAAD",
|
|
6
6
|
"names": ["ContactsManager_exports", "__toCommonJS"]
|
|
7
7
|
}
|
|
@@ -0,0 +1,2 @@
|
|
|
1
|
+
"use strict";var s=Object.defineProperty;var a=Object.getOwnPropertyDescriptor;var d=Object.getOwnPropertyNames;var i=Object.prototype.hasOwnProperty;var p=(r,e,o,n)=>{if(e&&typeof e=="object"||typeof e=="function")for(let t of d(e))!i.call(r,t)&&t!==o&&s(r,t,{get:()=>e[t],enumerable:!(n=a(e,t))||n.enumerable});return r};var A=r=>p(s({},"__esModule",{value:!0}),r);var l={};module.exports=A(l);
|
|
2
|
+
//# sourceMappingURL=RegisterExternalAddressDeviceActionTypes.js.map
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
{
|
|
2
|
+
"version": 3,
|
|
3
|
+
"sources": ["../../../../src/api/app-binder/RegisterExternalAddressDeviceActionTypes.ts"],
|
|
4
|
+
"sourcesContent": ["import {\n type CommandErrorResult,\n type DeviceActionState,\n type ExecuteDeviceActionReturnType,\n type OpenAppDAError,\n type OpenAppDARequiredInteraction,\n type UserInteractionRequired,\n} from \"@ledgerhq/device-management-kit\";\n\nimport {\n type RegisterExternalAddressInput,\n type RegisterExternalAddressOutput,\n} from \"@api/model/RegisterExternalAddress\";\nimport {\n type ContactsErrorCodes,\n type ContactsVersionRequirementError,\n} from \"@internal/app-binder/model/contactsErrors\";\nimport { type ContactsValidationError } from \"@internal/app-binder/model/contactsValidation\";\n\n/** Machine input: the public input plus the injected embedded-app name. */\nexport type RegisterExternalAddressDAInput = RegisterExternalAddressInput & {\n readonly appName: string;\n};\n\nexport type RegisterExternalAddressDAOutput = RegisterExternalAddressOutput;\n\nexport type RegisterExternalAddressDAError =\n | OpenAppDAError\n | ContactsValidationError\n | ContactsVersionRequirementError\n | CommandErrorResult<ContactsErrorCodes>[\"error\"];\n\nexport type RegisterExternalAddressDARequiredInteraction =\n | OpenAppDARequiredInteraction\n | UserInteractionRequired.RegisterWallet;\n\nexport type RegisterExternalAddressDAIntermediateValue = {\n readonly requiredUserInteraction: RegisterExternalAddressDARequiredInteraction;\n};\n\nexport type RegisterExternalAddressDAState = DeviceActionState<\n RegisterExternalAddressDAOutput,\n RegisterExternalAddressDAError,\n RegisterExternalAddressDAIntermediateValue\n>;\n\nexport type RegisterExternalAddressDAInternalState = {\n readonly error: RegisterExternalAddressDAError | null;\n /** The running app read freshly by WaitForAppAndVersion, for the version guard. */\n readonly appAndVersion: {\n readonly name: string;\n readonly version: string;\n } | null;\n readonly proofs: {\n readonly groupHandle: Uint8Array;\n readonly hmacProof: Uint8Array;\n readonly hmacRest: Uint8Array;\n } | null;\n};\n\nexport type RegisterExternalAddressDAReturnType = ExecuteDeviceActionReturnType<\n RegisterExternalAddressDAOutput,\n RegisterExternalAddressDAError,\n RegisterExternalAddressDAIntermediateValue\n>;\n"],
|
|
5
|
+
"mappings": "+WAAA,IAAAA,EAAA,kBAAAC,EAAAD",
|
|
6
|
+
"names": ["RegisterExternalAddressDeviceActionTypes_exports", "__toCommonJS"]
|
|
7
|
+
}
|
|
@@ -0,0 +1,2 @@
|
|
|
1
|
+
"use strict";var n=Object.defineProperty;var c=Object.getOwnPropertyDescriptor;var p=Object.getOwnPropertyNames;var i=Object.prototype.hasOwnProperty;var m=(t,e,a,o)=>{if(e&&typeof e=="object"||typeof e=="function")for(let r of p(e))!i.call(t,r)&&r!==a&&n(t,r,{get:()=>e[r],enumerable:!(o=c(e,r))||o.enumerable});return t};var u=t=>m(n({},"__esModule",{value:!0}),t);var R={};module.exports=u(R);
|
|
2
|
+
//# sourceMappingURL=RenameContactDeviceActionTypes.js.map
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
{
|
|
2
|
+
"version": 3,
|
|
3
|
+
"sources": ["../../../../src/api/app-binder/RenameContactDeviceActionTypes.ts"],
|
|
4
|
+
"sourcesContent": ["import {\n type CommandErrorResult,\n type DeviceActionState,\n type ExecuteDeviceActionReturnType,\n type GoToDashboardDAError,\n type GoToDashboardDARequiredInteraction,\n type UserInteractionRequired,\n} from \"@ledgerhq/device-management-kit\";\n\nimport {\n type RenameContactInput,\n type RenameContactOutput,\n} from \"@api/model/RenameContact\";\nimport {\n type ContactsErrorCodes,\n type ContactsVersionRequirementError,\n} from \"@internal/app-binder/model/contactsErrors\";\nimport { type ContactsValidationError } from \"@internal/app-binder/model/contactsValidation\";\n\n/**\n * Rename is a dashboard operation, so the machine input is exactly the public\n * input \u2014 no embedded-app name is injected (the OS serves the command; there is\n * no app to open).\n */\nexport type RenameContactDAInput = RenameContactInput;\n\nexport type RenameContactDAOutput = RenameContactOutput;\n\nexport type RenameContactDAError =\n | GoToDashboardDAError\n | ContactsValidationError\n | ContactsVersionRequirementError\n | CommandErrorResult<ContactsErrorCodes>[\"error\"];\n\nexport type RenameContactDARequiredInteraction =\n | GoToDashboardDARequiredInteraction\n | UserInteractionRequired.RegisterWallet;\n\nexport type RenameContactDAIntermediateValue = {\n readonly requiredUserInteraction: RenameContactDARequiredInteraction;\n};\n\nexport type RenameContactDAState = DeviceActionState<\n RenameContactDAOutput,\n RenameContactDAError,\n RenameContactDAIntermediateValue\n>;\n\nexport type RenameContactDAInternalState = {\n readonly error: RenameContactDAError | null;\n readonly proof: {\n readonly hmacProof: Uint8Array;\n } | null;\n};\n\nexport type RenameContactDAReturnType = ExecuteDeviceActionReturnType<\n RenameContactDAOutput,\n RenameContactDAError,\n RenameContactDAIntermediateValue\n>;\n"],
|
|
5
|
+
"mappings": "+WAAA,IAAAA,EAAA,kBAAAC,EAAAD",
|
|
6
|
+
"names": ["RenameContactDeviceActionTypes_exports", "__toCommonJS"]
|
|
7
|
+
}
|
package/lib/cjs/api/index.js
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
"use strict";var
|
|
1
|
+
"use strict";var a=Object.defineProperty;var d=Object.getOwnPropertyDescriptor;var R=Object.getOwnPropertyNames;var y=Object.prototype.hasOwnProperty;var u=(r,t)=>{for(var p in t)a(r,p,{get:t[p],enumerable:!0})},A=(r,t,p,o)=>{if(t&&typeof t=="object"||typeof t=="function")for(let n of R(t))!y.call(r,n)&&n!==p&&a(r,n,{get:()=>t[n],enumerable:!(o=d(t,n))||o.enumerable});return r};var i=r=>A(a({},"__esModule",{value:!0}),r);var c={};u(c,{CONTACTS_VERSION_REQUIREMENTS:()=>e.CONTACTS_VERSION_REQUIREMENTS,ContactsManagerBuilder:()=>s.ContactsManagerBuilder,ETHEREUM_APP_NAME:()=>e.ETHEREUM_APP_NAME,isContactsSupported:()=>e.isContactsSupported,isVersionAtLeast:()=>e.isVersionAtLeast,resolveContactsVersionRequirements:()=>e.resolveContactsVersionRequirements});module.exports=i(c);var s=require("./ContactsManagerBuilder"),e=require("./model/ContactsVersionRequirements");0&&(module.exports={CONTACTS_VERSION_REQUIREMENTS,ContactsManagerBuilder,ETHEREUM_APP_NAME,isContactsSupported,isVersionAtLeast,resolveContactsVersionRequirements});
|
|
2
2
|
//# sourceMappingURL=index.js.map
|
package/lib/cjs/api/index.js.map
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"version": 3,
|
|
3
3
|
"sources": ["../../../src/api/index.ts"],
|
|
4
|
-
"sourcesContent": ["export { type ContactsManager } from \"@api/ContactsManager\";\nexport { ContactsManagerBuilder } from \"@api/ContactsManagerBuilder\";\nexport {\n CONTACTS_VERSION_REQUIREMENTS,\n type ContactsModelRequirement,\n type ContactsModelSupport,\n type ContactsModelUnsupported,\n type ContactsSupportQuery,\n type ContactsVersionRequirements,\n ETHEREUM_APP_NAME,\n isContactsSupported,\n isVersionAtLeast,\n resolveContactsVersionRequirements,\n} from \"@api/model/ContactsVersionRequirements\";\n"],
|
|
5
|
-
"mappings": "yaAAA,IAAAA,EAAA,GAAAC,EAAAD,EAAA,oVAAAE,EAAAF,
|
|
4
|
+
"sourcesContent": ["export {\n type RegisterExternalAddressDAError,\n type RegisterExternalAddressDAInput,\n type RegisterExternalAddressDAIntermediateValue,\n type RegisterExternalAddressDAOutput,\n type RegisterExternalAddressDARequiredInteraction,\n type RegisterExternalAddressDAReturnType,\n type RegisterExternalAddressDAState,\n} from \"@api/app-binder/RegisterExternalAddressDeviceActionTypes\";\nexport {\n type RenameContactDAError,\n type RenameContactDAInput,\n type RenameContactDAIntermediateValue,\n type RenameContactDAOutput,\n type RenameContactDARequiredInteraction,\n type RenameContactDAReturnType,\n type RenameContactDAState,\n} from \"@api/app-binder/RenameContactDeviceActionTypes\";\nexport { type ContactsManager } from \"@api/ContactsManager\";\nexport { ContactsManagerBuilder } from \"@api/ContactsManagerBuilder\";\nexport {\n CONTACTS_VERSION_REQUIREMENTS,\n type ContactsModelRequirement,\n type ContactsModelSupport,\n type ContactsModelUnsupported,\n type ContactsSupportQuery,\n type ContactsVersionRequirements,\n ETHEREUM_APP_NAME,\n isContactsSupported,\n isVersionAtLeast,\n resolveContactsVersionRequirements,\n} from \"@api/model/ContactsVersionRequirements\";\nexport {\n type ExistingContactGroup,\n type RegisterExternalAddressInput,\n type RegisterExternalAddressMode,\n type RegisterExternalAddressOutput,\n} from \"@api/model/RegisterExternalAddress\";\nexport {\n type RenameContactInput,\n type RenameContactOutput,\n} from \"@api/model/RenameContact\";\n"],
|
|
5
|
+
"mappings": "yaAAA,IAAAA,EAAA,GAAAC,EAAAD,EAAA,oVAAAE,EAAAF,GAmBA,IAAAG,EAAuC,uCACvCC,EAWO",
|
|
6
6
|
"names": ["api_exports", "__export", "__toCommonJS", "import_ContactsManagerBuilder", "import_ContactsVersionRequirements"]
|
|
7
7
|
}
|
|
@@ -0,0 +1,2 @@
|
|
|
1
|
+
"use strict";var a=Object.defineProperty;var i=Object.getOwnPropertyDescriptor;var d=Object.getOwnPropertyNames;var y=Object.prototype.hasOwnProperty;var l=(e,r,o,t)=>{if(r&&typeof r=="object"||typeof r=="function")for(let n of d(r))!y.call(e,n)&&n!==o&&a(e,n,{get:()=>r[n],enumerable:!(t=i(r,n))||t.enumerable});return e};var s=e=>l(a({},"__esModule",{value:!0}),e);var p={};module.exports=s(p);
|
|
2
|
+
//# sourceMappingURL=RegisterExternalAddress.js.map
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
{
|
|
2
|
+
"version": 3,
|
|
3
|
+
"sources": ["../../../../src/api/model/RegisterExternalAddress.ts"],
|
|
4
|
+
"sourcesContent": ["/**\n * Public input/output types for `ContactsManager.registerExternalAddress`.\n *\n * Proof material (`groupHandle`, `hmacProof`, `hmacRest`) is returned as raw\n * bytes; the host owns persistence and address-book state. `derivationPath` is\n * intentionally absent \u2014 the kit owns a single internal value for external\n * addresses and does not expose it.\n */\n\n/** The existing contact group to extend, when adding an address to it. */\nexport type ExistingContactGroup = {\n /** 64-byte group handle returned by the group's first Register Identity. */\n readonly groupHandle: Uint8Array;\n /** 32-byte name proof (device `hmac_name`) bound to that group. */\n readonly hmacProof: Uint8Array;\n};\n\nexport type RegisterExternalAddressInput = {\n readonly contactName: string;\n readonly scope: string;\n /** Chain address bytes (20 bytes for Ethereum). */\n readonly identifier: Uint8Array;\n /** Blockchain family name, e.g. \"ethereum\" (v1 supports Ethereum only). */\n readonly blockchainFamily: string;\n readonly chainId?: bigint;\n /**\n * Set to add the address to an existing contact group. Omit to create a new\n * contact group.\n */\n readonly existingContactGroup?: ExistingContactGroup;\n /**\n * When `true`, the open-app step is skipped (the caller guarantees the app is\n * already open). The app-version guard still runs.\n */\n readonly skipOpenApp?: boolean;\n};\n\nexport type RegisterExternalAddressMode =\n | \"newContactGroup\"\n | \"existingContactGroup\";\n\nexport type RegisterExternalAddressOutput = {\n /** Whether a new contact group was created or an existing one was extended. */\n readonly mode: RegisterExternalAddressMode;\n /** Echoed input, needed by the host to persist the returned proof material. */\n readonly contactName: string;\n readonly scope: string;\n readonly identifier: Uint8Array;\n readonly blockchainFamily: string;\n readonly chainId?: bigint;\n /** Device-issued proof material. */\n readonly groupHandle: Uint8Array;\n readonly hmacProof: Uint8Array;\n readonly hmacRest: Uint8Array;\n};\n"],
|
|
5
|
+
"mappings": "+WAAA,IAAAA,EAAA,kBAAAC,EAAAD",
|
|
6
|
+
"names": ["RegisterExternalAddress_exports", "__toCommonJS"]
|
|
7
|
+
}
|
|
@@ -0,0 +1,2 @@
|
|
|
1
|
+
"use strict";var e=Object.defineProperty;var y=Object.getOwnPropertyDescriptor;var d=Object.getOwnPropertyNames;var i=Object.prototype.hasOwnProperty;var l=(n,a,o,t)=>{if(a&&typeof a=="object"||typeof a=="function")for(let r of d(a))!i.call(n,r)&&r!==o&&e(n,r,{get:()=>a[r],enumerable:!(t=y(a,r))||t.enumerable});return n};var p=n=>l(e({},"__esModule",{value:!0}),n);var c={};module.exports=p(c);
|
|
2
|
+
//# sourceMappingURL=RenameContact.js.map
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
{
|
|
2
|
+
"version": 3,
|
|
3
|
+
"sources": ["../../../../src/api/model/RenameContact.ts"],
|
|
4
|
+
"sourcesContent": ["/**\n * Public input/output types for `ContactsManager.renameContact`.\n *\n * Rename (EDIT CONTACT NAME) is a blockchain-agnostic OS/dashboard operation:\n * it rotates the contact-level `hmacProof` (the device's `hmac_name`) and\n * returns the fresh proof. The per-entry `hmacRest` values are untouched \u2014 they\n * bind scope/identifier/family/chainId, never the name \u2014 so only the group's\n * name proof needs re-persisting.\n *\n * Proof material (`groupHandle`, `hmacProof`) is passed and returned as raw\n * bytes; the host owns persistence and address-book state. `derivationPath` is\n * kit-internal and not exposed: the Ethereum app requires a path on the wire\n * (a default m/44'/60'/0'/0/0 is sent), but the rename itself is name-only.\n */\n\nexport type RenameContactInput = {\n /** The contact's current name, proven to the device via `hmacProof`. */\n readonly previousContactName: string;\n /** The new name to assign to the contact group. */\n readonly newContactName: string;\n /** 64-byte group handle returned by the group's Register Identity. */\n readonly groupHandle: Uint8Array;\n /**\n * The existing 32-byte name proof (device `hmac_name`) bound to the current\n * name \u2014 passed back so the device can verify continuity before approving the\n * rename. Replaced by the returned `hmacProof` on success.\n */\n readonly hmacProof: Uint8Array;\n};\n\nexport type RenameContactOutput = {\n /** Echoed previous name, for the host to locate the entry it is replacing. */\n readonly previousContactName: string;\n /** The new name now bound to the contact group. */\n readonly contactName: string;\n /** Echoed group handle, unchanged by the rename. */\n readonly groupHandle: Uint8Array;\n /** The replacement group-level name proof (rotated `hmac_name`) to persist. */\n readonly hmacProof: Uint8Array;\n};\n"],
|
|
5
|
+
"mappings": "+WAAA,IAAAA,EAAA,kBAAAC,EAAAD",
|
|
6
|
+
"names": ["RenameContact_exports", "__toCommonJS"]
|
|
7
|
+
}
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
"use strict";var
|
|
1
|
+
"use strict";var s=Object.defineProperty;var m=Object.getOwnPropertyDescriptor;var p=Object.getOwnPropertyNames;var c=Object.prototype.hasOwnProperty;var C=(t,e)=>{for(var r in e)s(t,r,{get:e[r],enumerable:!0})},d=(t,e,r,a)=>{if(e&&typeof e=="object"||typeof e=="function")for(let n of p(e))!c.call(t,n)&&n!==r&&s(t,n,{get:()=>e[n],enumerable:!(a=m(e,n))||a.enumerable});return t};var g=t=>d(s({},"__esModule",{value:!0}),t);var R={};C(R,{DefaultContactsManager:()=>u});module.exports=g(R);var i=require("./di"),o=require("./use-cases/di/useCaseTypes");class u{_container;constructor({dmk:e,sessionId:r,appName:a}){this._container=(0,i.makeContainer)({dmk:e,sessionId:r,appName:a})}registerExternalAddress(e){return this._container.get(o.useCaseTypes.RegisterExternalAddressUseCase).execute(e)}renameContact(e){return this._container.get(o.useCaseTypes.RenameContactUseCase).execute(e)}get container(){return this._container}}0&&(module.exports={DefaultContactsManager});
|
|
2
2
|
//# sourceMappingURL=DefaultContactsManager.js.map
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"version": 3,
|
|
3
3
|
"sources": ["../../../src/internal/DefaultContactsManager.ts"],
|
|
4
|
-
"sourcesContent": ["import {\n type DeviceManagementKit,\n type DeviceSessionId,\n} from \"@ledgerhq/device-management-kit\";\nimport { type Container } from \"inversify\";\n\nimport { type ContactsManager } from \"@api/ContactsManager\";\nimport { makeContainer } from \"@internal/di\";\n\ntype DefaultContactsManagerConstructorArgs = {\n dmk: DeviceManagementKit;\n sessionId: DeviceSessionId;\n appName: string;\n};\n\nexport class DefaultContactsManager implements ContactsManager {\n private readonly _container: Container;\n\n constructor({\n dmk,\n sessionId,\n appName,\n }: DefaultContactsManagerConstructorArgs) {\n this._container = makeContainer({ dmk, sessionId, appName });\n }\n\n /**\n * Exposes the DI container so operation methods
|
|
5
|
-
"mappings": "yaAAA,IAAAA,EAAA,GAAAC,EAAAD,EAAA,4BAAAE,IAAA,eAAAC,EAAAH,
|
|
6
|
-
"names": ["DefaultContactsManager_exports", "__export", "DefaultContactsManager", "__toCommonJS", "import_di", "dmk", "sessionId", "appName"]
|
|
4
|
+
"sourcesContent": ["import {\n type DeviceManagementKit,\n type DeviceSessionId,\n} from \"@ledgerhq/device-management-kit\";\nimport { type Container } from \"inversify\";\n\nimport { type RegisterExternalAddressDAReturnType } from \"@api/app-binder/RegisterExternalAddressDeviceActionTypes\";\nimport { type RenameContactDAReturnType } from \"@api/app-binder/RenameContactDeviceActionTypes\";\nimport { type ContactsManager } from \"@api/ContactsManager\";\nimport { type RegisterExternalAddressInput } from \"@api/model/RegisterExternalAddress\";\nimport { type RenameContactInput } from \"@api/model/RenameContact\";\nimport { makeContainer } from \"@internal/di\";\nimport { useCaseTypes } from \"@internal/use-cases/di/useCaseTypes\";\nimport { type RegisterExternalAddressUseCase } from \"@internal/use-cases/RegisterExternalAddressUseCase\";\nimport { type RenameContactUseCase } from \"@internal/use-cases/RenameContactUseCase\";\n\ntype DefaultContactsManagerConstructorArgs = {\n dmk: DeviceManagementKit;\n sessionId: DeviceSessionId;\n appName: string;\n};\n\nexport class DefaultContactsManager implements ContactsManager {\n private readonly _container: Container;\n\n constructor({\n dmk,\n sessionId,\n appName,\n }: DefaultContactsManagerConstructorArgs) {\n this._container = makeContainer({ dmk, sessionId, appName });\n }\n\n registerExternalAddress(\n input: RegisterExternalAddressInput,\n ): RegisterExternalAddressDAReturnType {\n return this._container\n .get<RegisterExternalAddressUseCase>(\n useCaseTypes.RegisterExternalAddressUseCase,\n )\n .execute(input);\n }\n\n renameContact(input: RenameContactInput): RenameContactDAReturnType {\n return this._container\n .get<RenameContactUseCase>(useCaseTypes.RenameContactUseCase)\n .execute(input);\n }\n\n /**\n * Exposes the DI container so future operation methods can resolve their\n * `UseCase`. Not part of the public API.\n */\n protected get container(): Container {\n return this._container;\n }\n}\n"],
|
|
5
|
+
"mappings": "yaAAA,IAAAA,EAAA,GAAAC,EAAAD,EAAA,4BAAAE,IAAA,eAAAC,EAAAH,GAWA,IAAAI,EAA8B,wBAC9BC,EAA6B,+CAUtB,MAAMH,CAAkD,CAC5C,WAEjB,YAAY,CACV,IAAAI,EACA,UAAAC,EACA,QAAAC,CACF,EAA0C,CACxC,KAAK,cAAa,iBAAc,CAAE,IAAAF,EAAK,UAAAC,EAAW,QAAAC,CAAQ,CAAC,CAC7D,CAEA,wBACEC,EACqC,CACrC,OAAO,KAAK,WACT,IACC,eAAa,8BACf,EACC,QAAQA,CAAK,CAClB,CAEA,cAAcA,EAAsD,CAClE,OAAO,KAAK,WACT,IAA0B,eAAa,oBAAoB,EAC3D,QAAQA,CAAK,CAClB,CAMA,IAAc,WAAuB,CACnC,OAAO,KAAK,UACd,CACF",
|
|
6
|
+
"names": ["DefaultContactsManager_exports", "__export", "DefaultContactsManager", "__toCommonJS", "import_di", "import_useCaseTypes", "dmk", "sessionId", "appName", "input"]
|
|
7
7
|
}
|
|
@@ -0,0 +1,2 @@
|
|
|
1
|
+
"use strict";var s=require("./DefaultContactsManager");const o={contactName:"Alice",scope:"Eth main",identifier:new Uint8Array(20).fill(17),blockchainFamily:"ethereum",chainId:1n},c={previousContactName:"Alice",newContactName:"Bob",groupHandle:new Uint8Array(64).fill(204),hmacProof:new Uint8Array(32).fill(221)};describe("DefaultContactsManager",()=>{it("registerExternalAddress flows manager -> use-case -> binder -> dmk.executeDeviceAction",()=>{const e=vi.fn().mockReturnValue("DA_RETURN"),n={executeDeviceAction:e},i=new s.DefaultContactsManager({dmk:n,sessionId:"session-id",appName:"Ethereum"}).registerExternalAddress(o);expect(e).toHaveBeenCalledTimes(1);const t=e.mock.calls[0][0];expect(t.sessionId).toBe("session-id"),expect(t.deviceAction).toBeDefined(),expect(i).toBe("DA_RETURN")}),it("does not throw on invalid input \u2014 it dispatches the device action, which surfaces the error",()=>{const e=vi.fn().mockReturnValue("DA_RETURN"),n={executeDeviceAction:e},a=new s.DefaultContactsManager({dmk:n,sessionId:"session-id",appName:"Ethereum"});expect(()=>a.registerExternalAddress({...o,contactName:""})).not.toThrow(),expect(e).toHaveBeenCalledTimes(1)}),it("renameContact flows manager -> use-case -> binder -> dmk.executeDeviceAction",()=>{const e=vi.fn().mockReturnValue("DA_RETURN"),n={executeDeviceAction:e},i=new s.DefaultContactsManager({dmk:n,sessionId:"session-id",appName:"Ethereum"}).renameContact(c);expect(e).toHaveBeenCalledTimes(1);const t=e.mock.calls[0][0];expect(t.sessionId).toBe("session-id"),expect(t.deviceAction).toBeDefined(),expect(i).toBe("DA_RETURN")})});
|
|
2
|
+
//# sourceMappingURL=DefaultContactsManager.test.js.map
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
{
|
|
2
|
+
"version": 3,
|
|
3
|
+
"sources": ["../../../src/internal/DefaultContactsManager.test.ts"],
|
|
4
|
+
"sourcesContent": ["import { type DeviceManagementKit } from \"@ledgerhq/device-management-kit\";\n\nimport { type RegisterExternalAddressInput } from \"@api/model/RegisterExternalAddress\";\nimport { type RenameContactInput } from \"@api/model/RenameContact\";\n\nimport { DefaultContactsManager } from \"./DefaultContactsManager\";\n\nconst VALID_INPUT: RegisterExternalAddressInput = {\n contactName: \"Alice\",\n scope: \"Eth main\",\n identifier: new Uint8Array(20).fill(0x11),\n blockchainFamily: \"ethereum\",\n chainId: 1n,\n};\n\nconst VALID_RENAME_INPUT: RenameContactInput = {\n previousContactName: \"Alice\",\n newContactName: \"Bob\",\n groupHandle: new Uint8Array(64).fill(0xcc),\n hmacProof: new Uint8Array(32).fill(0xdd),\n};\n\ndescribe(\"DefaultContactsManager\", () => {\n it(\"registerExternalAddress flows manager -> use-case -> binder -> dmk.executeDeviceAction\", () => {\n const executeDeviceAction = vi.fn().mockReturnValue(\"DA_RETURN\");\n const dmk = { executeDeviceAction } as unknown as DeviceManagementKit;\n\n const manager = new DefaultContactsManager({\n dmk,\n sessionId: \"session-id\",\n appName: \"Ethereum\",\n });\n\n const result = manager.registerExternalAddress(VALID_INPUT);\n\n expect(executeDeviceAction).toHaveBeenCalledTimes(1);\n const call = executeDeviceAction.mock.calls[0]![0] as {\n sessionId: string;\n deviceAction: unknown;\n };\n expect(call.sessionId).toBe(\"session-id\");\n expect(call.deviceAction).toBeDefined();\n expect(result).toBe(\"DA_RETURN\");\n });\n\n it(\"does not throw on invalid input \u2014 it dispatches the device action, which surfaces the error\", () => {\n // The public API returns a device action; invalid caller input must reach\n // the observable as a typed error state rather than throwing synchronously.\n const executeDeviceAction = vi.fn().mockReturnValue(\"DA_RETURN\");\n const dmk = { executeDeviceAction } as unknown as DeviceManagementKit;\n\n const manager = new DefaultContactsManager({\n dmk,\n sessionId: \"session-id\",\n appName: \"Ethereum\",\n });\n\n expect(() =>\n manager.registerExternalAddress({\n ...VALID_INPUT,\n contactName: \"\",\n }),\n ).not.toThrow();\n expect(executeDeviceAction).toHaveBeenCalledTimes(1);\n });\n\n it(\"renameContact flows manager -> use-case -> binder -> dmk.executeDeviceAction\", () => {\n const executeDeviceAction = vi.fn().mockReturnValue(\"DA_RETURN\");\n const dmk = { executeDeviceAction } as unknown as DeviceManagementKit;\n\n const manager = new DefaultContactsManager({\n dmk,\n sessionId: \"session-id\",\n appName: \"Ethereum\",\n });\n\n const result = manager.renameContact(VALID_RENAME_INPUT);\n\n expect(executeDeviceAction).toHaveBeenCalledTimes(1);\n const call = executeDeviceAction.mock.calls[0]![0] as {\n sessionId: string;\n deviceAction: unknown;\n };\n expect(call.sessionId).toBe(\"session-id\");\n expect(call.deviceAction).toBeDefined();\n expect(result).toBe(\"DA_RETURN\");\n });\n});\n"],
|
|
5
|
+
"mappings": "aAKA,IAAAA,EAAuC,oCAEvC,MAAMC,EAA4C,CAChD,YAAa,QACb,MAAO,WACP,WAAY,IAAI,WAAW,EAAE,EAAE,KAAK,EAAI,EACxC,iBAAkB,WAClB,QAAS,EACX,EAEMC,EAAyC,CAC7C,oBAAqB,QACrB,eAAgB,MAChB,YAAa,IAAI,WAAW,EAAE,EAAE,KAAK,GAAI,EACzC,UAAW,IAAI,WAAW,EAAE,EAAE,KAAK,GAAI,CACzC,EAEA,SAAS,yBAA0B,IAAM,CACvC,GAAG,yFAA0F,IAAM,CACjG,MAAMC,EAAsB,GAAG,GAAG,EAAE,gBAAgB,WAAW,EACzDC,EAAM,CAAE,oBAAAD,CAAoB,EAQ5BE,EANU,IAAI,yBAAuB,CACzC,IAAAD,EACA,UAAW,aACX,QAAS,UACX,CAAC,EAEsB,wBAAwBH,CAAW,EAE1D,OAAOE,CAAmB,EAAE,sBAAsB,CAAC,EACnD,MAAMG,EAAOH,EAAoB,KAAK,MAAM,CAAC,EAAG,CAAC,EAIjD,OAAOG,EAAK,SAAS,EAAE,KAAK,YAAY,EACxC,OAAOA,EAAK,YAAY,EAAE,YAAY,EACtC,OAAOD,CAAM,EAAE,KAAK,WAAW,CACjC,CAAC,EAED,GAAG,mGAA+F,IAAM,CAGtG,MAAMF,EAAsB,GAAG,GAAG,EAAE,gBAAgB,WAAW,EACzDC,EAAM,CAAE,oBAAAD,CAAoB,EAE5BI,EAAU,IAAI,yBAAuB,CACzC,IAAAH,EACA,UAAW,aACX,QAAS,UACX,CAAC,EAED,OAAO,IACLG,EAAQ,wBAAwB,CAC9B,GAAGN,EACH,YAAa,EACf,CAAC,CACH,EAAE,IAAI,QAAQ,EACd,OAAOE,CAAmB,EAAE,sBAAsB,CAAC,CACrD,CAAC,EAED,GAAG,+EAAgF,IAAM,CACvF,MAAMA,EAAsB,GAAG,GAAG,EAAE,gBAAgB,WAAW,EACzDC,EAAM,CAAE,oBAAAD,CAAoB,EAQ5BE,EANU,IAAI,yBAAuB,CACzC,IAAAD,EACA,UAAW,aACX,QAAS,UACX,CAAC,EAEsB,cAAcF,CAAkB,EAEvD,OAAOC,CAAmB,EAAE,sBAAsB,CAAC,EACnD,MAAMG,EAAOH,EAAoB,KAAK,MAAM,CAAC,EAAG,CAAC,EAIjD,OAAOG,EAAK,SAAS,EAAE,KAAK,YAAY,EACxC,OAAOA,EAAK,YAAY,EAAE,YAAY,EACtC,OAAOD,CAAM,EAAE,KAAK,WAAW,CACjC,CAAC,CACH,CAAC",
|
|
6
|
+
"names": ["import_DefaultContactsManager", "VALID_INPUT", "VALID_RENAME_INPUT", "executeDeviceAction", "dmk", "result", "call", "manager"]
|
|
7
|
+
}
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
"use strict";var
|
|
1
|
+
"use strict";var m=Object.defineProperty;var u=Object.getOwnPropertyDescriptor;var D=Object.getOwnPropertyNames;var l=Object.prototype.hasOwnProperty;var I=(t,e)=>{for(var n in e)m(t,n,{get:e[n],enumerable:!0})},v=(t,e,n,i)=>{if(e&&typeof e=="object"||typeof e=="function")for(let r of D(e))!l.call(t,r)&&r!==n&&m(t,r,{get:()=>e[r],enumerable:!(i=u(e,r))||i.enumerable});return t};var x=t=>v(m({},"__esModule",{value:!0}),t),y=(t,e,n,i)=>{for(var r=i>1?void 0:i?u(e,n):e,c=t.length-1,d;c>=0;c--)(d=t[c])&&(r=(i?d(e,n,r):d(r))||r);return i&&r&&m(e,n,r),r},a=(t,e)=>(n,i)=>e(n,i,t);var f={};I(f,{ContactsAppBinder:()=>o});module.exports=x(f);var s=require("inversify"),A=require("../app-binder/device-action/RegisterExternalAddress/RegisterExternalAddressDeviceAction"),R=require("../app-binder/device-action/RenameContact/RenameContactDeviceAction"),p=require("../externalTypes");let o=class{constructor(e,n,i){this.dmk=e;this.sessionId=n;this.appName=i}registerExternalAddress(e){return this.dmk.executeDeviceAction({sessionId:this.sessionId,deviceAction:new A.RegisterExternalAddressDeviceAction({input:{...e,appName:this.appName}})})}renameContact(e){return this.dmk.executeDeviceAction({sessionId:this.sessionId,deviceAction:new R.RenameContactDeviceAction({input:e})})}};o=y([(0,s.injectable)(),a(0,(0,s.inject)(p.externalTypes.Dmk)),a(1,(0,s.inject)(p.externalTypes.SessionId)),a(2,(0,s.inject)(p.externalTypes.AppName))],o);0&&(module.exports={ContactsAppBinder});
|
|
2
2
|
//# sourceMappingURL=ContactsAppBinder.js.map
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"version": 3,
|
|
3
3
|
"sources": ["../../../../src/internal/app-binder/ContactsAppBinder.ts"],
|
|
4
|
-
"sourcesContent": ["import {\n type DeviceManagementKit,\n type DeviceSessionId,\n} from \"@ledgerhq/device-management-kit\";\nimport { inject, injectable } from \"inversify\";\n\nimport { externalTypes } from \"@internal/externalTypes\";\n\n/**\n * Constructs and executes Contacts `DeviceAction`s using the injected `dmk`,\n * `sessionId`, and `appName`.
|
|
5
|
-
"mappings": "okBAAA,IAAAA,EAAA,GAAAC,EAAAD,EAAA,uBAAAE,IAAA,eAAAC,EAAAH,GAIA,IAAAI,EAAmC,
|
|
6
|
-
"names": ["ContactsAppBinder_exports", "__export", "ContactsAppBinder", "__toCommonJS", "import_inversify", "import_externalTypes", "ContactsAppBinder", "dmk", "sessionId", "appName", "__decorateClass", "__decorateParam"]
|
|
4
|
+
"sourcesContent": ["import {\n type DeviceManagementKit,\n type DeviceSessionId,\n} from \"@ledgerhq/device-management-kit\";\nimport { inject, injectable } from \"inversify\";\n\nimport { type RegisterExternalAddressDAReturnType } from \"@api/app-binder/RegisterExternalAddressDeviceActionTypes\";\nimport { type RenameContactDAReturnType } from \"@api/app-binder/RenameContactDeviceActionTypes\";\nimport { type RegisterExternalAddressInput } from \"@api/model/RegisterExternalAddress\";\nimport { type RenameContactInput } from \"@api/model/RenameContact\";\nimport { RegisterExternalAddressDeviceAction } from \"@internal/app-binder/device-action/RegisterExternalAddress/RegisterExternalAddressDeviceAction\";\nimport { RenameContactDeviceAction } from \"@internal/app-binder/device-action/RenameContact/RenameContactDeviceAction\";\nimport { externalTypes } from \"@internal/externalTypes\";\n\n/**\n * Constructs and executes Contacts `DeviceAction`s using the injected `dmk`,\n * `sessionId`, and `appName`. Each Address Book operation gets one method here.\n */\n@injectable()\nexport class ContactsAppBinder {\n constructor(\n @inject(externalTypes.Dmk)\n protected readonly dmk: DeviceManagementKit,\n @inject(externalTypes.SessionId)\n protected readonly sessionId: DeviceSessionId,\n @inject(externalTypes.AppName)\n protected readonly appName: string,\n ) {}\n\n registerExternalAddress(\n input: RegisterExternalAddressInput,\n ): RegisterExternalAddressDAReturnType {\n return this.dmk.executeDeviceAction({\n sessionId: this.sessionId,\n deviceAction: new RegisterExternalAddressDeviceAction({\n input: { ...input, appName: this.appName },\n }),\n });\n }\n\n renameContact(input: RenameContactInput): RenameContactDAReturnType {\n // Rename is a dashboard operation: `appName` is intentionally not passed \u2014\n // the OS serves the command and there is no app to open.\n return this.dmk.executeDeviceAction({\n sessionId: this.sessionId,\n deviceAction: new RenameContactDeviceAction({ input }),\n });\n }\n}\n"],
|
|
5
|
+
"mappings": "okBAAA,IAAAA,EAAA,GAAAC,EAAAD,EAAA,uBAAAE,IAAA,eAAAC,EAAAH,GAIA,IAAAI,EAAmC,qBAMnCC,EAAoD,0GACpDC,EAA0C,sFAC1CC,EAA8B,mCAOvB,IAAMC,EAAN,KAAwB,CAC7B,YAEqBC,EAEAC,EAEAC,EACnB,CALmB,SAAAF,EAEA,eAAAC,EAEA,aAAAC,CAClB,CAEH,wBACEC,EACqC,CACrC,OAAO,KAAK,IAAI,oBAAoB,CAClC,UAAW,KAAK,UAChB,aAAc,IAAI,sCAAoC,CACpD,MAAO,CAAE,GAAGA,EAAO,QAAS,KAAK,OAAQ,CAC3C,CAAC,CACH,CAAC,CACH,CAEA,cAAcA,EAAsD,CAGlE,OAAO,KAAK,IAAI,oBAAoB,CAClC,UAAW,KAAK,UAChB,aAAc,IAAI,4BAA0B,CAAE,MAAAA,CAAM,CAAC,CACvD,CAAC,CACH,CACF,EA7BaJ,EAANK,EAAA,IADN,cAAW,EAGPC,EAAA,eAAO,gBAAc,GAAG,GAExBA,EAAA,eAAO,gBAAc,SAAS,GAE9BA,EAAA,eAAO,gBAAc,OAAO,IANpBN",
|
|
6
|
+
"names": ["ContactsAppBinder_exports", "__export", "ContactsAppBinder", "__toCommonJS", "import_inversify", "import_RegisterExternalAddressDeviceAction", "import_RenameContactDeviceAction", "import_externalTypes", "ContactsAppBinder", "dmk", "sessionId", "appName", "input", "__decorateClass", "__decorateParam"]
|
|
7
7
|
}
|
|
@@ -0,0 +1,2 @@
|
|
|
1
|
+
"use strict";var i=Object.defineProperty;var g=Object.getOwnPropertyDescriptor;var l=Object.getOwnPropertyNames;var R=Object.prototype.hasOwnProperty;var A=(o,r)=>{for(var t in r)i(o,t,{get:r[t],enumerable:!0})},f=(o,r,t,d)=>{if(r&&typeof r=="object"||typeof r=="function")for(let a of l(r))!R.call(o,a)&&a!==t&&i(o,a,{get:()=>r[a],enumerable:!(d=g(r,a))||d.enumerable});return o};var E=o=>f(i({},"__esModule",{value:!0}),o);var T={};A(T,{RegisterIdentityCommand:()=>_});module.exports=E(T);var e=require("@ledgerhq/device-management-kit"),c=require("@ledgerhq/signer-utils"),C=require("purify-ts"),n=require("../../app-binder/model/contactsConstants"),s=require("../../app-binder/model/contactsErrors");const y=45;function m(o,r){const t=o.extractFieldByLength(r);if(!(!t||t.length!==r))return Uint8Array.from(t)}class _{name="registerIdentity";args;errorHelper=new c.CommandErrorHelper(s.CONTACTS_APP_ERRORS,s.contactsCommandErrorFactory);constructor(r){this.args=r}getApdu(){return new e.ApduBuilder({cla:n.CONTACTS_APDU_CLA,ins:n.CONTACTS_APDU_INS,p1:n.SUB_CMD_REGISTER_IDENTITY,p2:this.args.p2}).addBufferToData(this.args.data).build()}parseResponse(r){return C.Maybe.fromNullable(this.errorHelper.getError(r)).orDefaultLazy(()=>{if(r.data.length===0)return(0,e.CommandResultFactory)({data:{}});const t=new e.ApduParser(r),d=t.extract8BitUInt();if(d!==y)return(0,e.CommandResultFactory)({error:new e.InvalidStatusWordError(`Expected struct_type 0x${y.toString(16)}, got ${d===void 0?"undefined":`0x${d.toString(16)}`}`)});const a=m(t,n.GROUP_HANDLE_BYTES);if(!a)return(0,e.CommandResultFactory)({error:new e.InvalidStatusWordError("group_handle missing or truncated")});const p=m(t,n.HMAC_PROOF_BYTES);if(!p)return(0,e.CommandResultFactory)({error:new e.InvalidStatusWordError("hmac_name missing or truncated")});const u=m(t,n.HMAC_REST_BYTES);return u?(0,e.CommandResultFactory)({data:{groupHandle:a,hmacProof:p,hmacRest:u}}):(0,e.CommandResultFactory)({error:new e.InvalidStatusWordError("hmac_rest missing or truncated")})})}}0&&(module.exports={RegisterIdentityCommand});
|
|
2
|
+
//# sourceMappingURL=RegisterIdentityCommand.js.map
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
{
|
|
2
|
+
"version": 3,
|
|
3
|
+
"sources": ["../../../../../src/internal/app-binder/command/RegisterIdentityCommand.ts"],
|
|
4
|
+
"sourcesContent": ["// Register Identity (register external address) \u2014 sub-command P1=0x01 of the\n// address-book APDU (CLA 0xB0 / INS 0x10). Caller (SendRegisterIdentityTask +\n// sendFramedContactsPayload) assembles the TLV, prepends the 2-byte BE total\n// length and slices into <=255B chunks; this command frames one chunk and, on\n// the final chunk, parses the 129-byte response: struct_type(0x2d) +\n// group_handle(64) + hmac_proof(32) + hmac_rest(32). Intermediate chunks ack\n// with SW=0x9000 and no data.\n// Protocol: Address Book Final Specifications \u2014 Register Identity.\nimport {\n type Apdu,\n ApduBuilder,\n ApduParser,\n type ApduResponse,\n type Command,\n type CommandResult,\n CommandResultFactory,\n InvalidStatusWordError,\n} from \"@ledgerhq/device-management-kit\";\nimport { CommandErrorHelper } from \"@ledgerhq/signer-utils\";\nimport { Maybe } from \"purify-ts\";\n\nimport {\n CONTACTS_APDU_CLA,\n CONTACTS_APDU_INS,\n GROUP_HANDLE_BYTES,\n HMAC_PROOF_BYTES,\n HMAC_REST_BYTES,\n SUB_CMD_REGISTER_IDENTITY,\n} from \"@internal/app-binder/model/contactsConstants\";\nimport {\n CONTACTS_APP_ERRORS,\n contactsCommandErrorFactory,\n type ContactsErrorCodes,\n} from \"@internal/app-binder/model/contactsErrors\";\n\nexport type RegisterIdentityCommandArgs = {\n /** One framed chunk built by sendFramedContactsPayload. */\n readonly data: Uint8Array;\n /** 0x00 for the first/only chunk, 0x80 for continuation chunks. */\n readonly p2: number;\n};\n\nexport type RegisterIdentityCommandResponse = {\n /**\n * Present only on the final chunk \u2014 the device returns struct_type(0x2d) +\n * group_handle(64) + hmac_proof(32) + hmac_rest(32) there. Intermediate\n * chunks return SW=0x9000 with no data.\n *\n * `hmacProof` is the device's HMAC_PROOF (binds the contact name);\n * `hmacRest` is the HMAC_REST (binds scope + identifier + family).\n */\n readonly groupHandle?: Uint8Array;\n readonly hmacProof?: Uint8Array;\n readonly hmacRest?: Uint8Array;\n};\n\nconst RESPONSE_STRUCT_TYPE = 0x2d;\n\n/**\n * Extract `length` bytes as a freshly-owned plain `Uint8Array` (the parser may\n * hand back a `Buffer` view backed by the response), or `undefined` if the\n * response is too short.\n */\nfunction extractField(\n parser: ApduParser,\n length: number,\n): Uint8Array | undefined {\n const field = parser.extractFieldByLength(length);\n if (!field || field.length !== length) return undefined;\n return Uint8Array.from(field);\n}\n\nexport class RegisterIdentityCommand\n implements\n Command<\n RegisterIdentityCommandResponse,\n RegisterIdentityCommandArgs,\n ContactsErrorCodes\n >\n{\n readonly name = \"registerIdentity\";\n readonly args: RegisterIdentityCommandArgs;\n private readonly errorHelper = new CommandErrorHelper<\n RegisterIdentityCommandResponse,\n ContactsErrorCodes\n >(CONTACTS_APP_ERRORS, contactsCommandErrorFactory);\n\n constructor(args: RegisterIdentityCommandArgs) {\n this.args = args;\n }\n\n getApdu(): Apdu {\n return new ApduBuilder({\n cla: CONTACTS_APDU_CLA,\n ins: CONTACTS_APDU_INS,\n p1: SUB_CMD_REGISTER_IDENTITY,\n p2: this.args.p2,\n })\n .addBufferToData(this.args.data)\n .build();\n }\n\n parseResponse(\n response: ApduResponse,\n ): CommandResult<RegisterIdentityCommandResponse, ContactsErrorCodes> {\n return Maybe.fromNullable(\n this.errorHelper.getError(response),\n ).orDefaultLazy(() => {\n if (response.data.length === 0) {\n // Intermediate chunk \u2014 device acks with SW=0x9000 and no payload.\n return CommandResultFactory({ data: {} });\n }\n\n const parser = new ApduParser(response);\n\n const structType = parser.extract8BitUInt();\n if (structType !== RESPONSE_STRUCT_TYPE) {\n return CommandResultFactory({\n error: new InvalidStatusWordError(\n `Expected struct_type 0x${RESPONSE_STRUCT_TYPE.toString(16)}, got ${\n structType === undefined\n ? \"undefined\"\n : `0x${structType.toString(16)}`\n }`,\n ),\n });\n }\n\n const groupHandle = extractField(parser, GROUP_HANDLE_BYTES);\n if (!groupHandle) {\n return CommandResultFactory({\n error: new InvalidStatusWordError(\n \"group_handle missing or truncated\",\n ),\n });\n }\n\n const hmacProof = extractField(parser, HMAC_PROOF_BYTES);\n if (!hmacProof) {\n return CommandResultFactory({\n error: new InvalidStatusWordError(\"hmac_name missing or truncated\"),\n });\n }\n\n const hmacRest = extractField(parser, HMAC_REST_BYTES);\n if (!hmacRest) {\n return CommandResultFactory({\n error: new InvalidStatusWordError(\"hmac_rest missing or truncated\"),\n });\n }\n\n return CommandResultFactory({\n data: { groupHandle, hmacProof, hmacRest },\n });\n });\n }\n}\n"],
|
|
5
|
+
"mappings": "yaAAA,IAAAA,EAAA,GAAAC,EAAAD,EAAA,6BAAAE,IAAA,eAAAC,EAAAH,GAQA,IAAAI,EASO,2CACPC,EAAmC,kCACnCC,EAAsB,qBAEtBC,EAOO,wDACPC,EAIO,qDAuBP,MAAMC,EAAuB,GAO7B,SAASC,EACPC,EACAC,EACwB,CACxB,MAAMC,EAAQF,EAAO,qBAAqBC,CAAM,EAChD,GAAI,GAACC,GAASA,EAAM,SAAWD,GAC/B,OAAO,WAAW,KAAKC,CAAK,CAC9B,CAEO,MAAMX,CAOb,CACW,KAAO,mBACP,KACQ,YAAc,IAAI,qBAGjC,sBAAqB,6BAA2B,EAElD,YAAYY,EAAmC,CAC7C,KAAK,KAAOA,CACd,CAEA,SAAgB,CACd,OAAO,IAAI,cAAY,CACrB,IAAK,oBACL,IAAK,oBACL,GAAI,4BACJ,GAAI,KAAK,KAAK,EAChB,CAAC,EACE,gBAAgB,KAAK,KAAK,IAAI,EAC9B,MAAM,CACX,CAEA,cACEC,EACoE,CACpE,OAAO,QAAM,aACX,KAAK,YAAY,SAASA,CAAQ,CACpC,EAAE,cAAc,IAAM,CACpB,GAAIA,EAAS,KAAK,SAAW,EAE3B,SAAO,wBAAqB,CAAE,KAAM,CAAC,CAAE,CAAC,EAG1C,MAAMJ,EAAS,IAAI,aAAWI,CAAQ,EAEhCC,EAAaL,EAAO,gBAAgB,EAC1C,GAAIK,IAAeP,EACjB,SAAO,wBAAqB,CAC1B,MAAO,IAAI,yBACT,0BAA0BA,EAAqB,SAAS,EAAE,CAAC,SACzDO,IAAe,OACX,YACA,KAAKA,EAAW,SAAS,EAAE,CAAC,EAClC,EACF,CACF,CAAC,EAGH,MAAMC,EAAcP,EAAaC,EAAQ,oBAAkB,EAC3D,GAAI,CAACM,EACH,SAAO,wBAAqB,CAC1B,MAAO,IAAI,yBACT,mCACF,CACF,CAAC,EAGH,MAAMC,EAAYR,EAAaC,EAAQ,kBAAgB,EACvD,GAAI,CAACO,EACH,SAAO,wBAAqB,CAC1B,MAAO,IAAI,yBAAuB,gCAAgC,CACpE,CAAC,EAGH,MAAMC,EAAWT,EAAaC,EAAQ,iBAAe,EACrD,OAAKQ,KAME,wBAAqB,CAC1B,KAAM,CAAE,YAAAF,EAAa,UAAAC,EAAW,SAAAC,CAAS,CAC3C,CAAC,KAPQ,wBAAqB,CAC1B,MAAO,IAAI,yBAAuB,gCAAgC,CACpE,CAAC,CAML,CAAC,CACH,CACF",
|
|
6
|
+
"names": ["RegisterIdentityCommand_exports", "__export", "RegisterIdentityCommand", "__toCommonJS", "import_device_management_kit", "import_signer_utils", "import_purify_ts", "import_contactsConstants", "import_contactsErrors", "RESPONSE_STRUCT_TYPE", "extractField", "parser", "length", "field", "args", "response", "structType", "groupHandle", "hmacProof", "hmacRest"]
|
|
7
|
+
}
|
|
@@ -0,0 +1,2 @@
|
|
|
1
|
+
"use strict";var r=require("@ledgerhq/device-management-kit"),s=require("../../app-binder/model/contactsErrors"),a=require("./RegisterIdentityCommand");function n(e){const t=new Uint8Array(e.length/2);for(let o=0;o<e.length;o+=2)t[o/2]=parseInt(e.slice(o,o+2),16);return t}const m=n("cc".repeat(64)),p=n("dd".repeat(32)),u=n("aa".repeat(32)),c="2d"+"cc".repeat(64)+"dd".repeat(32)+"aa".repeat(32);function d(e){return{data:Buffer.from(n(e)),statusCode:Buffer.from([144,0])}}describe("RegisterIdentityCommand",()=>{describe("getApdu",()=>{it("wraps the framed chunk under B0 10 01 with P2=0x00 for the first/only chunk",()=>{const e=Uint8Array.from([0,3,170,187,204]),t=new a.RegisterIdentityCommand({data:e,p2:0}).getApdu();expect(t.getRawApdu()).toStrictEqual(Uint8Array.from([176,16,1,0,5,0,3,170,187,204]))}),it("uses P2=0x80 for continuation chunks",()=>{const e=Uint8Array.from([170,187]),t=new a.RegisterIdentityCommand({data:e,p2:128}).getApdu();expect(t.getRawApdu()).toStrictEqual(Uint8Array.from([176,16,1,128,2,170,187]))})}),describe("parseResponse",()=>{it("returns an empty payload for an intermediate chunk (SW=0x9000, no data)",()=>{const e=new a.RegisterIdentityCommand({data:new Uint8Array,p2:0}).parseResponse({data:Buffer.from([]),statusCode:Buffer.from([144,0])});expect(e).toStrictEqual({status:r.CommandResultStatus.Success,data:{}})}),it("extracts group_handle / hmac_name / hmac_rest from a register response",()=>{const t=new a.RegisterIdentityCommand({data:new Uint8Array,p2:0}).parseResponse(d(c));expect(t).toStrictEqual({status:r.CommandResultStatus.Success,data:{groupHandle:m,hmacProof:p,hmacRest:u}})}),it("returns InvalidStatusWordError when struct_type is wrong",()=>{const e="ee"+c.slice(2),o=new a.RegisterIdentityCommand({data:new Uint8Array,p2:0}).parseResponse(d(e));expect(o.status).toBe(r.CommandResultStatus.Error)}),it("maps a known SW (0x6985) to a ContactsCommandError",()=>{const t=new a.RegisterIdentityCommand({data:new Uint8Array,p2:0}).parseResponse({data:Buffer.from([]),statusCode:Buffer.from([105,133])});expect(t.status).toBe(r.CommandResultStatus.Error),t.status===r.CommandResultStatus.Error&&(expect(t.error).toBeInstanceOf(s.ContactsCommandError),expect(t.error.errorCode).toBe("6985"))}),it("maps SW=0x6982 to a seed-mismatch ContactsCommandError",()=>{const t=new a.RegisterIdentityCommand({data:new Uint8Array,p2:0}).parseResponse({data:Buffer.from([]),statusCode:Buffer.from([105,130])});expect(t.status).toBe(r.CommandResultStatus.Error),t.status===r.CommandResultStatus.Error&&(expect(t.error).toBeInstanceOf(s.ContactsCommandError),expect(t.error.errorCode).toBe(s.CONTACT_SEED_MISMATCH_ERROR_CODE))})})});
|
|
2
|
+
//# sourceMappingURL=RegisterIdentityCommand.test.js.map
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
{
|
|
2
|
+
"version": 3,
|
|
3
|
+
"sources": ["../../../../../src/internal/app-binder/command/RegisterIdentityCommand.test.ts"],
|
|
4
|
+
"sourcesContent": ["// RegisterIdentityCommand is a thin chunk-framer: it wraps a pre-framed chunk\n// (2-byte BE length prefix + TLV, assembled by SendRegisterIdentityTask +\n// sendFramedContactsPayload) under B0 10 01 <P2>, and parses the 129-byte\n// register response on the final chunk. TLV byte-parity is asserted in\n// SendRegisterIdentityTask.test.ts.\nimport {\n type ApduResponse,\n CommandResultStatus,\n} from \"@ledgerhq/device-management-kit\";\n\nimport {\n CONTACT_SEED_MISMATCH_ERROR_CODE,\n ContactsCommandError,\n} from \"@internal/app-binder/model/contactsErrors\";\n\nimport { RegisterIdentityCommand } from \"./RegisterIdentityCommand\";\n\nfunction hexToBytes(hex: string): Uint8Array {\n const out = new Uint8Array(hex.length / 2);\n for (let i = 0; i < hex.length; i += 2) {\n out[i / 2] = parseInt(hex.slice(i, i + 2), 16);\n }\n return out;\n}\n\n// Device response: struct_type(0x2d) + group_handle(64) + hmac_name(32) +\n// hmac_rest(32).\nconst GROUP_HANDLE = hexToBytes(\"cc\".repeat(64));\nconst HMAC_PROOF = hexToBytes(\"dd\".repeat(32));\nconst HMAC_REST = hexToBytes(\"aa\".repeat(32));\nconst RESPONSE_HEX = \"2d\" + \"cc\".repeat(64) + \"dd\".repeat(32) + \"aa\".repeat(32);\n\nfunction makeResponse(hex: string): ApduResponse {\n return {\n data: Buffer.from(hexToBytes(hex)),\n statusCode: Buffer.from([0x90, 0x00]),\n };\n}\n\ndescribe(\"RegisterIdentityCommand\", () => {\n describe(\"getApdu\", () => {\n it(\"wraps the framed chunk under B0 10 01 with P2=0x00 for the first/only chunk\", () => {\n const data = Uint8Array.from([0x00, 0x03, 0xaa, 0xbb, 0xcc]);\n\n const apdu = new RegisterIdentityCommand({ data, p2: 0x00 }).getApdu();\n\n expect(apdu.getRawApdu()).toStrictEqual(\n Uint8Array.from([\n 0xb0, 0x10, 0x01, 0x00, 0x05, 0x00, 0x03, 0xaa, 0xbb, 0xcc,\n ]),\n );\n });\n\n it(\"uses P2=0x80 for continuation chunks\", () => {\n const data = Uint8Array.from([0xaa, 0xbb]);\n\n const apdu = new RegisterIdentityCommand({ data, p2: 0x80 }).getApdu();\n\n expect(apdu.getRawApdu()).toStrictEqual(\n Uint8Array.from([0xb0, 0x10, 0x01, 0x80, 0x02, 0xaa, 0xbb]),\n );\n });\n });\n\n describe(\"parseResponse\", () => {\n it(\"returns an empty payload for an intermediate chunk (SW=0x9000, no data)\", () => {\n const result = new RegisterIdentityCommand({\n data: new Uint8Array(),\n p2: 0x00,\n }).parseResponse({\n data: Buffer.from([]),\n statusCode: Buffer.from([0x90, 0x00]),\n });\n\n expect(result).toStrictEqual({\n status: CommandResultStatus.Success,\n data: {},\n });\n });\n\n it(\"extracts group_handle / hmac_name / hmac_rest from a register response\", () => {\n const command = new RegisterIdentityCommand({\n data: new Uint8Array(),\n p2: 0x00,\n });\n\n const result = command.parseResponse(makeResponse(RESPONSE_HEX));\n\n expect(result).toStrictEqual({\n status: CommandResultStatus.Success,\n data: {\n groupHandle: GROUP_HANDLE,\n hmacProof: HMAC_PROOF,\n hmacRest: HMAC_REST,\n },\n });\n });\n\n it(\"returns InvalidStatusWordError when struct_type is wrong\", () => {\n const wrongType = \"ee\" + RESPONSE_HEX.slice(2); // replace 0x2d with 0xee\n const command = new RegisterIdentityCommand({\n data: new Uint8Array(),\n p2: 0x00,\n });\n\n const result = command.parseResponse(makeResponse(wrongType));\n\n expect(result.status).toBe(CommandResultStatus.Error);\n });\n\n it(\"maps a known SW (0x6985) to a ContactsCommandError\", () => {\n const command = new RegisterIdentityCommand({\n data: new Uint8Array(),\n p2: 0x00,\n });\n\n const result = command.parseResponse({\n data: Buffer.from([]),\n statusCode: Buffer.from([0x69, 0x85]),\n });\n\n expect(result.status).toBe(CommandResultStatus.Error);\n if (result.status === CommandResultStatus.Error) {\n expect(result.error).toBeInstanceOf(ContactsCommandError);\n expect((result.error as ContactsCommandError).errorCode).toBe(\"6985\");\n }\n });\n\n it(\"maps SW=0x6982 to a seed-mismatch ContactsCommandError\", () => {\n // Reached when extending an existing contact whose group handle was\n // registered with another seed (once the app verifies before the UI).\n const command = new RegisterIdentityCommand({\n data: new Uint8Array(),\n p2: 0x00,\n });\n\n const result = command.parseResponse({\n data: Buffer.from([]),\n statusCode: Buffer.from([0x69, 0x82]),\n });\n\n expect(result.status).toBe(CommandResultStatus.Error);\n if (result.status === CommandResultStatus.Error) {\n expect(result.error).toBeInstanceOf(ContactsCommandError);\n expect((result.error as ContactsCommandError).errorCode).toBe(\n CONTACT_SEED_MISMATCH_ERROR_CODE,\n );\n }\n });\n });\n});\n"],
|
|
5
|
+
"mappings": "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",
|
|
6
|
+
"names": ["import_device_management_kit", "import_contactsErrors", "import_RegisterIdentityCommand", "hexToBytes", "hex", "out", "i", "GROUP_HANDLE", "HMAC_PROOF", "HMAC_REST", "RESPONSE_HEX", "makeResponse", "data", "apdu", "result", "wrongType"]
|
|
7
|
+
}
|
|
@@ -0,0 +1,2 @@
|
|
|
1
|
+
"use strict";var s=Object.defineProperty;var u=Object.getOwnPropertyDescriptor;var A=Object.getOwnPropertyNames;var R=Object.prototype.hasOwnProperty;var l=(n,r)=>{for(var t in r)s(n,t,{get:r[t],enumerable:!0})},y=(n,r,t,m)=>{if(r&&typeof r=="object"||typeof r=="function")for(let o of A(r))!R.call(n,o)&&o!==t&&s(n,o,{get:()=>r[o],enumerable:!(m=u(r,o))||m.enumerable});return n};var E=n=>y(s({},"__esModule",{value:!0}),n);var _={};l(_,{RenameContactCommand:()=>T});module.exports=E(_);var e=require("@ledgerhq/device-management-kit"),p=require("@ledgerhq/signer-utils"),c=require("purify-ts"),a=require("../../app-binder/model/contactsConstants"),d=require("../../app-binder/model/contactsErrors"),i=require("../../app-binder/services/contactsTlvSerializer");const C=i.STRUCT_TYPE_EDIT_CONTACT_NAME;function f(n,r){const t=n.extractFieldByLength(r);if(!(!t||t.length!==r))return Uint8Array.from(t)}class T{name="renameContact";args;errorHelper=new p.CommandErrorHelper(d.CONTACTS_APP_ERRORS,d.contactsCommandErrorFactory);constructor(r){this.args=r}getApdu(){return new e.ApduBuilder({cla:a.RENAME_CONTACT_APDU_CLA,ins:a.RENAME_CONTACT_APDU_INS,p1:a.RENAME_CONTACT_P1,p2:this.args.p2}).addBufferToData(this.args.data).build()}parseResponse(r){return c.Maybe.fromNullable(this.errorHelper.getError(r)).orDefaultLazy(()=>{if(r.data.length===0)return(0,e.CommandResultFactory)({data:{}});const t=new e.ApduParser(r),m=t.extract8BitUInt();if(m!==C)return(0,e.CommandResultFactory)({error:new e.InvalidStatusWordError(`Expected struct_type 0x${C.toString(16)}, got ${m===void 0?"undefined":`0x${m.toString(16)}`}`)});const o=f(t,a.HMAC_NAME_BYTES);return o?(0,e.CommandResultFactory)({data:{hmacProof:o}}):(0,e.CommandResultFactory)({error:new e.InvalidStatusWordError("hmac_name missing or truncated")})})}}0&&(module.exports={RenameContactCommand});
|
|
2
|
+
//# sourceMappingURL=RenameContactCommand.js.map
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
{
|
|
2
|
+
"version": 3,
|
|
3
|
+
"sources": ["../../../../../src/internal/app-binder/command/RenameContactCommand.ts"],
|
|
4
|
+
"sourcesContent": ["// Rename Contact (EDIT CONTACT NAME) \u2014 the blockchain-agnostic address-book\n// rename. It is dispatched as an OS/dashboard command (CLA 0xE0 / INS 0x2E /\n// P1 0x00), NOT through the embedded app: the caller navigates to the dashboard\n// first (GoToDashboardDeviceAction) so the OS handles it directly.\n// SendRenameContactTask + sendFramedContactsPayload assemble the TLV, prepend\n// the 2-byte BE total length and slice into <=255B chunks; this command frames\n// one chunk and, on the final chunk, parses the 33-byte response:\n// struct_type(0x2e) + rotated hmac_name(32). Intermediate chunks ack with\n// SW=0x9000 and no data.\n//\n// The device is stateless: it verifies the supplied group handle + old-name\n// proof against the seed-derived key (SW 0x6982 on a seed mismatch, before any\n// UI) and, on approval, returns a fresh proof for the new name.\n// Protocol: Address Book Final Specifications \u2014 Edit Contact Name.\nimport {\n type Apdu,\n ApduBuilder,\n ApduParser,\n type ApduResponse,\n type Command,\n type CommandResult,\n CommandResultFactory,\n InvalidStatusWordError,\n} from \"@ledgerhq/device-management-kit\";\nimport { CommandErrorHelper } from \"@ledgerhq/signer-utils\";\nimport { Maybe } from \"purify-ts\";\n\nimport {\n HMAC_NAME_BYTES,\n RENAME_CONTACT_APDU_CLA,\n RENAME_CONTACT_APDU_INS,\n RENAME_CONTACT_P1,\n} from \"@internal/app-binder/model/contactsConstants\";\nimport {\n CONTACTS_APP_ERRORS,\n contactsCommandErrorFactory,\n type ContactsErrorCodes,\n} from \"@internal/app-binder/model/contactsErrors\";\nimport { STRUCT_TYPE_EDIT_CONTACT_NAME } from \"@internal/app-binder/services/contactsTlvSerializer\";\n\nexport type RenameContactCommandArgs = {\n /** One framed chunk built by sendFramedContactsPayload. */\n readonly data: Uint8Array;\n /** 0x00 for the first/only chunk, 0x80 for continuation chunks. */\n readonly p2: number;\n};\n\nexport type RenameContactCommandResponse = {\n /**\n * Present only on the final chunk \u2014 the device returns struct_type(0x2e) +\n * rotated hmac_name(32) there. Intermediate chunks return SW=0x9000 with no\n * data. This is the replacement group-level name proof.\n */\n readonly hmacProof?: Uint8Array;\n};\n\nconst RESPONSE_STRUCT_TYPE = STRUCT_TYPE_EDIT_CONTACT_NAME;\n\n/**\n * Extract `length` bytes as a freshly-owned plain `Uint8Array` (the parser may\n * hand back a `Buffer` view backed by the response), or `undefined` if the\n * response is too short.\n */\nfunction extractField(\n parser: ApduParser,\n length: number,\n): Uint8Array | undefined {\n const field = parser.extractFieldByLength(length);\n if (!field || field.length !== length) return undefined;\n return Uint8Array.from(field);\n}\n\nexport class RenameContactCommand\n implements\n Command<\n RenameContactCommandResponse,\n RenameContactCommandArgs,\n ContactsErrorCodes\n >\n{\n readonly name = \"renameContact\";\n readonly args: RenameContactCommandArgs;\n private readonly errorHelper = new CommandErrorHelper<\n RenameContactCommandResponse,\n ContactsErrorCodes\n >(CONTACTS_APP_ERRORS, contactsCommandErrorFactory);\n\n constructor(args: RenameContactCommandArgs) {\n this.args = args;\n }\n\n getApdu(): Apdu {\n return new ApduBuilder({\n cla: RENAME_CONTACT_APDU_CLA,\n ins: RENAME_CONTACT_APDU_INS,\n p1: RENAME_CONTACT_P1,\n p2: this.args.p2,\n })\n .addBufferToData(this.args.data)\n .build();\n }\n\n parseResponse(\n response: ApduResponse,\n ): CommandResult<RenameContactCommandResponse, ContactsErrorCodes> {\n return Maybe.fromNullable(\n this.errorHelper.getError(response),\n ).orDefaultLazy(() => {\n if (response.data.length === 0) {\n // Intermediate chunk \u2014 device acks with SW=0x9000 and no payload.\n return CommandResultFactory({ data: {} });\n }\n\n const parser = new ApduParser(response);\n\n const structType = parser.extract8BitUInt();\n if (structType !== RESPONSE_STRUCT_TYPE) {\n return CommandResultFactory({\n error: new InvalidStatusWordError(\n `Expected struct_type 0x${RESPONSE_STRUCT_TYPE.toString(16)}, got ${\n structType === undefined\n ? \"undefined\"\n : `0x${structType.toString(16)}`\n }`,\n ),\n });\n }\n\n const hmacProof = extractField(parser, HMAC_NAME_BYTES);\n if (!hmacProof) {\n return CommandResultFactory({\n error: new InvalidStatusWordError(\"hmac_name missing or truncated\"),\n });\n }\n\n return CommandResultFactory({\n data: { hmacProof },\n });\n });\n }\n}\n"],
|
|
5
|
+
"mappings": "yaAAA,IAAAA,EAAA,GAAAC,EAAAD,EAAA,0BAAAE,IAAA,eAAAC,EAAAH,GAcA,IAAAI,EASO,2CACPC,EAAmC,kCACnCC,EAAsB,qBAEtBC,EAKO,wDACPC,EAIO,qDACPC,EAA8C,+DAkB9C,MAAMC,EAAuB,gCAO7B,SAASC,EACPC,EACAC,EACwB,CACxB,MAAMC,EAAQF,EAAO,qBAAqBC,CAAM,EAChD,GAAI,GAACC,GAASA,EAAM,SAAWD,GAC/B,OAAO,WAAW,KAAKC,CAAK,CAC9B,CAEO,MAAMZ,CAOb,CACW,KAAO,gBACP,KACQ,YAAc,IAAI,qBAGjC,sBAAqB,6BAA2B,EAElD,YAAYa,EAAgC,CAC1C,KAAK,KAAOA,CACd,CAEA,SAAgB,CACd,OAAO,IAAI,cAAY,CACrB,IAAK,0BACL,IAAK,0BACL,GAAI,oBACJ,GAAI,KAAK,KAAK,EAChB,CAAC,EACE,gBAAgB,KAAK,KAAK,IAAI,EAC9B,MAAM,CACX,CAEA,cACEC,EACiE,CACjE,OAAO,QAAM,aACX,KAAK,YAAY,SAASA,CAAQ,CACpC,EAAE,cAAc,IAAM,CACpB,GAAIA,EAAS,KAAK,SAAW,EAE3B,SAAO,wBAAqB,CAAE,KAAM,CAAC,CAAE,CAAC,EAG1C,MAAMJ,EAAS,IAAI,aAAWI,CAAQ,EAEhCC,EAAaL,EAAO,gBAAgB,EAC1C,GAAIK,IAAeP,EACjB,SAAO,wBAAqB,CAC1B,MAAO,IAAI,yBACT,0BAA0BA,EAAqB,SAAS,EAAE,CAAC,SACzDO,IAAe,OACX,YACA,KAAKA,EAAW,SAAS,EAAE,CAAC,EAClC,EACF,CACF,CAAC,EAGH,MAAMC,EAAYP,EAAaC,EAAQ,iBAAe,EACtD,OAAKM,KAME,wBAAqB,CAC1B,KAAM,CAAE,UAAAA,CAAU,CACpB,CAAC,KAPQ,wBAAqB,CAC1B,MAAO,IAAI,yBAAuB,gCAAgC,CACpE,CAAC,CAML,CAAC,CACH,CACF",
|
|
6
|
+
"names": ["RenameContactCommand_exports", "__export", "RenameContactCommand", "__toCommonJS", "import_device_management_kit", "import_signer_utils", "import_purify_ts", "import_contactsConstants", "import_contactsErrors", "import_contactsTlvSerializer", "RESPONSE_STRUCT_TYPE", "extractField", "parser", "length", "field", "args", "response", "structType", "hmacProof"]
|
|
7
|
+
}
|
|
@@ -0,0 +1,2 @@
|
|
|
1
|
+
"use strict";var a=require("@ledgerhq/device-management-kit"),n=require("../../app-binder/model/contactsErrors"),o=require("./RenameContactCommand");function m(e){const t=new Uint8Array(e.length/2);for(let r=0;r<e.length;r+=2)t[r/2]=parseInt(e.slice(r,r+2),16);return t}const d=m("dd".repeat(32)),c="2e"+"dd".repeat(32);function s(e){return{data:Buffer.from(m(e)),statusCode:Buffer.from([144,0])}}describe("RenameContactCommand",()=>{describe("getApdu",()=>{it("wraps the framed chunk under E0 2E 00 with P2=0x00 for the first/only chunk",()=>{const e=Uint8Array.from([0,3,170,187,204]),t=new o.RenameContactCommand({data:e,p2:0}).getApdu();expect(t.getRawApdu()).toStrictEqual(Uint8Array.from([224,46,0,0,5,0,3,170,187,204]))}),it("uses P2=0x80 for continuation chunks",()=>{const e=Uint8Array.from([170,187]),t=new o.RenameContactCommand({data:e,p2:128}).getApdu();expect(t.getRawApdu()).toStrictEqual(Uint8Array.from([224,46,0,128,2,170,187]))})}),describe("parseResponse",()=>{it("returns an empty payload for an intermediate chunk (SW=0x9000, no data)",()=>{const e=new o.RenameContactCommand({data:new Uint8Array,p2:0}).parseResponse({data:Buffer.from([]),statusCode:Buffer.from([144,0])});expect(e).toStrictEqual({status:a.CommandResultStatus.Success,data:{}})}),it("extracts the rotated hmac_name from an edit-contact-name response",()=>{const t=new o.RenameContactCommand({data:new Uint8Array,p2:0}).parseResponse(s(c));expect(t).toStrictEqual({status:a.CommandResultStatus.Success,data:{hmacProof:d}})}),it("returns InvalidStatusWordError when struct_type is wrong",()=>{const e="ee"+c.slice(2),r=new o.RenameContactCommand({data:new Uint8Array,p2:0}).parseResponse(s(e));expect(r.status).toBe(a.CommandResultStatus.Error)}),it("returns InvalidStatusWordError when hmac_name is truncated",()=>{const e="2e"+"dd".repeat(16),r=new o.RenameContactCommand({data:new Uint8Array,p2:0}).parseResponse(s(e));expect(r.status).toBe(a.CommandResultStatus.Error)}),it("maps a known SW (0x6985) to a ContactsCommandError",()=>{const t=new o.RenameContactCommand({data:new Uint8Array,p2:0}).parseResponse({data:Buffer.from([]),statusCode:Buffer.from([105,133])});expect(t.status).toBe(a.CommandResultStatus.Error),t.status===a.CommandResultStatus.Error&&(expect(t.error).toBeInstanceOf(n.ContactsCommandError),expect(t.error.errorCode).toBe("6985"))}),it("maps SW=0x6982 to a seed-mismatch ContactsCommandError",()=>{const t=new o.RenameContactCommand({data:new Uint8Array,p2:0}).parseResponse({data:Buffer.from([]),statusCode:Buffer.from([105,130])});expect(t.status).toBe(a.CommandResultStatus.Error),t.status===a.CommandResultStatus.Error&&(expect(t.error).toBeInstanceOf(n.ContactsCommandError),expect(t.error.errorCode).toBe(n.CONTACT_SEED_MISMATCH_ERROR_CODE))})})});
|
|
2
|
+
//# sourceMappingURL=RenameContactCommand.test.js.map
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
{
|
|
2
|
+
"version": 3,
|
|
3
|
+
"sources": ["../../../../../src/internal/app-binder/command/RenameContactCommand.test.ts"],
|
|
4
|
+
"sourcesContent": ["// RenameContactCommand is a thin chunk-framer for the OS/dashboard EDIT CONTACT\n// NAME command: it wraps a pre-framed chunk (2-byte BE length prefix + TLV,\n// assembled by SendRenameContactTask + sendFramedContactsPayload) under\n// E0 2E 00 <P2>, and parses the 33-byte response on the final chunk. TLV\n// byte-parity is asserted in SendRenameContactTask.test.ts.\nimport {\n type ApduResponse,\n CommandResultStatus,\n} from \"@ledgerhq/device-management-kit\";\n\nimport {\n CONTACT_SEED_MISMATCH_ERROR_CODE,\n ContactsCommandError,\n} from \"@internal/app-binder/model/contactsErrors\";\n\nimport { RenameContactCommand } from \"./RenameContactCommand\";\n\nfunction hexToBytes(hex: string): Uint8Array {\n const out = new Uint8Array(hex.length / 2);\n for (let i = 0; i < hex.length; i += 2) {\n out[i / 2] = parseInt(hex.slice(i, i + 2), 16);\n }\n return out;\n}\n\n// Device response: struct_type(0x2e) + rotated hmac_name(32).\nconst HMAC_PROOF = hexToBytes(\"dd\".repeat(32));\nconst RESPONSE_HEX = \"2e\" + \"dd\".repeat(32);\n\nfunction makeResponse(hex: string): ApduResponse {\n return {\n data: Buffer.from(hexToBytes(hex)),\n statusCode: Buffer.from([0x90, 0x00]),\n };\n}\n\ndescribe(\"RenameContactCommand\", () => {\n describe(\"getApdu\", () => {\n it(\"wraps the framed chunk under E0 2E 00 with P2=0x00 for the first/only chunk\", () => {\n const data = Uint8Array.from([0x00, 0x03, 0xaa, 0xbb, 0xcc]);\n\n const apdu = new RenameContactCommand({ data, p2: 0x00 }).getApdu();\n\n expect(apdu.getRawApdu()).toStrictEqual(\n Uint8Array.from([\n 0xe0, 0x2e, 0x00, 0x00, 0x05, 0x00, 0x03, 0xaa, 0xbb, 0xcc,\n ]),\n );\n });\n\n it(\"uses P2=0x80 for continuation chunks\", () => {\n const data = Uint8Array.from([0xaa, 0xbb]);\n\n const apdu = new RenameContactCommand({ data, p2: 0x80 }).getApdu();\n\n expect(apdu.getRawApdu()).toStrictEqual(\n Uint8Array.from([0xe0, 0x2e, 0x00, 0x80, 0x02, 0xaa, 0xbb]),\n );\n });\n });\n\n describe(\"parseResponse\", () => {\n it(\"returns an empty payload for an intermediate chunk (SW=0x9000, no data)\", () => {\n const result = new RenameContactCommand({\n data: new Uint8Array(),\n p2: 0x00,\n }).parseResponse({\n data: Buffer.from([]),\n statusCode: Buffer.from([0x90, 0x00]),\n });\n\n expect(result).toStrictEqual({\n status: CommandResultStatus.Success,\n data: {},\n });\n });\n\n it(\"extracts the rotated hmac_name from an edit-contact-name response\", () => {\n const command = new RenameContactCommand({\n data: new Uint8Array(),\n p2: 0x00,\n });\n\n const result = command.parseResponse(makeResponse(RESPONSE_HEX));\n\n expect(result).toStrictEqual({\n status: CommandResultStatus.Success,\n data: { hmacProof: HMAC_PROOF },\n });\n });\n\n it(\"returns InvalidStatusWordError when struct_type is wrong\", () => {\n const wrongType = \"ee\" + RESPONSE_HEX.slice(2); // replace 0x2e with 0xee\n const command = new RenameContactCommand({\n data: new Uint8Array(),\n p2: 0x00,\n });\n\n const result = command.parseResponse(makeResponse(wrongType));\n\n expect(result.status).toBe(CommandResultStatus.Error);\n });\n\n it(\"returns InvalidStatusWordError when hmac_name is truncated\", () => {\n const truncated = \"2e\" + \"dd\".repeat(16); // only 16 of 32 bytes\n const command = new RenameContactCommand({\n data: new Uint8Array(),\n p2: 0x00,\n });\n\n const result = command.parseResponse(makeResponse(truncated));\n\n expect(result.status).toBe(CommandResultStatus.Error);\n });\n\n it(\"maps a known SW (0x6985) to a ContactsCommandError\", () => {\n const command = new RenameContactCommand({\n data: new Uint8Array(),\n p2: 0x00,\n });\n\n const result = command.parseResponse({\n data: Buffer.from([]),\n statusCode: Buffer.from([0x69, 0x85]),\n });\n\n expect(result.status).toBe(CommandResultStatus.Error);\n if (result.status === CommandResultStatus.Error) {\n expect(result.error).toBeInstanceOf(ContactsCommandError);\n expect((result.error as ContactsCommandError).errorCode).toBe(\"6985\");\n }\n });\n\n it(\"maps SW=0x6982 to a seed-mismatch ContactsCommandError\", () => {\n // The device verifies the supplied group handle + old-name proof against\n // the seed-derived key before any UI, and returns 0x6982 on a mismatch.\n const command = new RenameContactCommand({\n data: new Uint8Array(),\n p2: 0x00,\n });\n\n const result = command.parseResponse({\n data: Buffer.from([]),\n statusCode: Buffer.from([0x69, 0x82]),\n });\n\n expect(result.status).toBe(CommandResultStatus.Error);\n if (result.status === CommandResultStatus.Error) {\n expect(result.error).toBeInstanceOf(ContactsCommandError);\n expect((result.error as ContactsCommandError).errorCode).toBe(\n CONTACT_SEED_MISMATCH_ERROR_CODE,\n );\n }\n });\n });\n});\n"],
|
|
5
|
+
"mappings": "aAKA,IAAAA,EAGO,2CAEPC,EAGO,qDAEPC,EAAqC,kCAErC,SAASC,EAAWC,EAAyB,CAC3C,MAAMC,EAAM,IAAI,WAAWD,EAAI,OAAS,CAAC,EACzC,QAASE,EAAI,EAAGA,EAAIF,EAAI,OAAQE,GAAK,EACnCD,EAAIC,EAAI,CAAC,EAAI,SAASF,EAAI,MAAME,EAAGA,EAAI,CAAC,EAAG,EAAE,EAE/C,OAAOD,CACT,CAGA,MAAME,EAAaJ,EAAW,KAAK,OAAO,EAAE,CAAC,EACvCK,EAAe,KAAO,KAAK,OAAO,EAAE,EAE1C,SAASC,EAAaL,EAA2B,CAC/C,MAAO,CACL,KAAM,OAAO,KAAKD,EAAWC,CAAG,CAAC,EACjC,WAAY,OAAO,KAAK,CAAC,IAAM,CAAI,CAAC,CACtC,CACF,CAEA,SAAS,uBAAwB,IAAM,CACrC,SAAS,UAAW,IAAM,CACxB,GAAG,8EAA+E,IAAM,CACtF,MAAMM,EAAO,WAAW,KAAK,CAAC,EAAM,EAAM,IAAM,IAAM,GAAI,CAAC,EAErDC,EAAO,IAAI,uBAAqB,CAAE,KAAAD,EAAM,GAAI,CAAK,CAAC,EAAE,QAAQ,EAElE,OAAOC,EAAK,WAAW,CAAC,EAAE,cACxB,WAAW,KAAK,CACd,IAAM,GAAM,EAAM,EAAM,EAAM,EAAM,EAAM,IAAM,IAAM,GACxD,CAAC,CACH,CACF,CAAC,EAED,GAAG,uCAAwC,IAAM,CAC/C,MAAMD,EAAO,WAAW,KAAK,CAAC,IAAM,GAAI,CAAC,EAEnCC,EAAO,IAAI,uBAAqB,CAAE,KAAAD,EAAM,GAAI,GAAK,CAAC,EAAE,QAAQ,EAElE,OAAOC,EAAK,WAAW,CAAC,EAAE,cACxB,WAAW,KAAK,CAAC,IAAM,GAAM,EAAM,IAAM,EAAM,IAAM,GAAI,CAAC,CAC5D,CACF,CAAC,CACH,CAAC,EAED,SAAS,gBAAiB,IAAM,CAC9B,GAAG,0EAA2E,IAAM,CAClF,MAAMC,EAAS,IAAI,uBAAqB,CACtC,KAAM,IAAI,WACV,GAAI,CACN,CAAC,EAAE,cAAc,CACf,KAAM,OAAO,KAAK,CAAC,CAAC,EACpB,WAAY,OAAO,KAAK,CAAC,IAAM,CAAI,CAAC,CACtC,CAAC,EAED,OAAOA,CAAM,EAAE,cAAc,CAC3B,OAAQ,sBAAoB,QAC5B,KAAM,CAAC,CACT,CAAC,CACH,CAAC,EAED,GAAG,oEAAqE,IAAM,CAM5E,MAAMA,EALU,IAAI,uBAAqB,CACvC,KAAM,IAAI,WACV,GAAI,CACN,CAAC,EAEsB,cAAcH,EAAaD,CAAY,CAAC,EAE/D,OAAOI,CAAM,EAAE,cAAc,CAC3B,OAAQ,sBAAoB,QAC5B,KAAM,CAAE,UAAWL,CAAW,CAChC,CAAC,CACH,CAAC,EAED,GAAG,2DAA4D,IAAM,CACnE,MAAMM,EAAY,KAAOL,EAAa,MAAM,CAAC,EAMvCI,EALU,IAAI,uBAAqB,CACvC,KAAM,IAAI,WACV,GAAI,CACN,CAAC,EAEsB,cAAcH,EAAaI,CAAS,CAAC,EAE5D,OAAOD,EAAO,MAAM,EAAE,KAAK,sBAAoB,KAAK,CACtD,CAAC,EAED,GAAG,6DAA8D,IAAM,CACrE,MAAME,EAAY,KAAO,KAAK,OAAO,EAAE,EAMjCF,EALU,IAAI,uBAAqB,CACvC,KAAM,IAAI,WACV,GAAI,CACN,CAAC,EAEsB,cAAcH,EAAaK,CAAS,CAAC,EAE5D,OAAOF,EAAO,MAAM,EAAE,KAAK,sBAAoB,KAAK,CACtD,CAAC,EAED,GAAG,qDAAsD,IAAM,CAM7D,MAAMA,EALU,IAAI,uBAAqB,CACvC,KAAM,IAAI,WACV,GAAI,CACN,CAAC,EAEsB,cAAc,CACnC,KAAM,OAAO,KAAK,CAAC,CAAC,EACpB,WAAY,OAAO,KAAK,CAAC,IAAM,GAAI,CAAC,CACtC,CAAC,EAED,OAAOA,EAAO,MAAM,EAAE,KAAK,sBAAoB,KAAK,EAChDA,EAAO,SAAW,sBAAoB,QACxC,OAAOA,EAAO,KAAK,EAAE,eAAe,sBAAoB,EACxD,OAAQA,EAAO,MAA+B,SAAS,EAAE,KAAK,MAAM,EAExE,CAAC,EAED,GAAG,yDAA0D,IAAM,CAQjE,MAAMA,EALU,IAAI,uBAAqB,CACvC,KAAM,IAAI,WACV,GAAI,CACN,CAAC,EAEsB,cAAc,CACnC,KAAM,OAAO,KAAK,CAAC,CAAC,EACpB,WAAY,OAAO,KAAK,CAAC,IAAM,GAAI,CAAC,CACtC,CAAC,EAED,OAAOA,EAAO,MAAM,EAAE,KAAK,sBAAoB,KAAK,EAChDA,EAAO,SAAW,sBAAoB,QACxC,OAAOA,EAAO,KAAK,EAAE,eAAe,sBAAoB,EACxD,OAAQA,EAAO,MAA+B,SAAS,EAAE,KACvD,kCACF,EAEJ,CAAC,CACH,CAAC,CACH,CAAC",
|
|
6
|
+
"names": ["import_device_management_kit", "import_contactsErrors", "import_RenameContactCommand", "hexToBytes", "hex", "out", "i", "HMAC_PROOF", "RESPONSE_HEX", "makeResponse", "data", "apdu", "result", "wrongType", "truncated"]
|
|
7
|
+
}
|
|
@@ -0,0 +1,2 @@
|
|
|
1
|
+
"use strict";var u=Object.defineProperty;var S=Object.getOwnPropertyDescriptor;var R=Object.getOwnPropertyNames;var I=Object.prototype.hasOwnProperty;var y=(s,n)=>{for(var p in n)u(s,p,{get:n[p],enumerable:!0})},h=(s,n,p,l)=>{if(n&&typeof n=="object"||typeof n=="function")for(let r of R(n))!I.call(s,r)&&r!==p&&u(s,r,{get:()=>n[r],enumerable:!(l=S(n,r))||l.enumerable});return s};var D=s=>h(u({},"__esModule",{value:!0}),s);var V={};y(V,{RegisterExternalAddressDeviceAction:()=>x});module.exports=D(V);var i=require("@ledgerhq/device-management-kit"),c=require("purify-ts"),a=require("xstate"),A=require("../../../app-binder/isContactsSupportedForSession"),g=require("../../../app-binder/model/contactsErrors"),m=require("../../../app-binder/task/SendRegisterIdentityTask"),E=require("./validateRegisterExternalAddressInput");class x extends i.XStateDeviceAction{makeStateMachine(n){const{isSupported:p,registerIdentity:l}=this.extractDependencies(n),r=this.input.appName;return(0,a.setup)({types:{input:{},context:{},output:{}},actors:{openAppStateMachine:new i.OpenAppDeviceAction({input:{appName:r}}).makeStateMachine(n),waitForAppAndVersionStateMachine:new i.WaitForAppAndVersionDeviceAction({input:{}}).makeStateMachine(n),registerIdentity:(0,a.fromPromise)(({input:e})=>l(e))},guards:{skipOpenApp:({context:e})=>e.input.skipOpenApp===!0,noInternalError:({context:e})=>e._internalState.error===null,contactsSupported:({context:e})=>{const{appAndVersion:t}=e._internalState;return t!==null&&p(t)}},actions:{assignValidationError:(0,a.assign)({_internalState:({context:e})=>{const t=(0,E.validateRegisterExternalAddressInput)(e.input);return t?{...e._internalState,error:t}:e._internalState}}),assignVersionError:(0,a.assign)({_internalState:({context:e})=>({...e._internalState,error:new g.ContactsVersionRequirementError})}),assignErrorFromEvent:(0,a.assign)({_internalState:({context:e,event:t})=>({...e._internalState,error:new i.UnknownDAError(t.error instanceof Error?t.error.message:String(t.error))})})}}).createMachine({id:"RegisterExternalAddressDeviceAction",initial:"InitialState",context:({input:e})=>({input:e,intermediateValue:{requiredUserInteraction:i.UserInteractionRequired.None},_internalState:{error:null,appAndVersion:null,proofs:null}}),states:{InitialState:{always:[{target:"ValidateInput",guard:"skipOpenApp"},{target:"OpenAppDeviceAction"}]},OpenAppDeviceAction:{invoke:{id:"openAppStateMachine",src:"openAppStateMachine",input:()=>({appName:r}),onSnapshot:{actions:(0,a.assign)({intermediateValue:({event:e})=>e.snapshot.context.intermediateValue})},onDone:{target:"CheckOpenAppResult",actions:(0,a.assign)({_internalState:({event:e,context:t})=>e.output.caseOf({Right:()=>t._internalState,Left:o=>({...t._internalState,error:o})})})}}},CheckOpenAppResult:{always:[{target:"ValidateInput",guard:"noInternalError"},{target:"Error"}]},ValidateInput:{entry:"assignValidationError",always:[{target:"WaitForAppAndVersion",guard:"noInternalError"},{target:"Error"}]},WaitForAppAndVersion:{entry:(0,a.assign)({intermediateValue:{requiredUserInteraction:i.UserInteractionRequired.None}}),invoke:{id:"waitForAppAndVersion",src:"waitForAppAndVersionStateMachine",input:()=>({}),onSnapshot:{actions:(0,a.assign)({intermediateValue:({event:e})=>e.snapshot.context.intermediateValue})},onDone:{target:"CheckAppAndVersion",actions:(0,a.assign)({_internalState:({event:e,context:t})=>e.output.caseOf({Right:o=>({...t._internalState,appAndVersion:{name:o.name,version:o.version}}),Left:o=>({...t._internalState,error:o})})})}}},CheckAppAndVersion:{always:[{target:"VersionGuard",guard:"noInternalError"},{target:"Error"}]},VersionGuard:{always:[{target:"RegisterIdentity",guard:"contactsSupported"},{target:"Error",actions:"assignVersionError"}]},RegisterIdentity:{entry:(0,a.assign)({intermediateValue:{requiredUserInteraction:i.UserInteractionRequired.RegisterWallet}}),exit:(0,a.assign)({intermediateValue:{requiredUserInteraction:i.UserInteractionRequired.None}}),invoke:{id:"registerIdentity",src:"registerIdentity",input:({context:e})=>e.input,onDone:{target:"RegisterIdentityResultCheck",actions:(0,a.assign)({_internalState:({event:e,context:t})=>(0,i.isSuccessCommandResult)(e.output)?{...t._internalState,proofs:e.output.data}:{...t._internalState,error:e.output.error}})},onError:{target:"Error",actions:"assignErrorFromEvent"}}},RegisterIdentityResultCheck:{always:[{target:"Success",guard:"noInternalError"},{target:"Error"}]},Success:{type:"final"},Error:{type:"final"}},output:({context:e})=>{const{proofs:t,error:o}=e._internalState;if(t){const{input:d}=e;return(0,c.Right)({mode:d.existingContactGroup?"existingContactGroup":"newContactGroup",contactName:d.contactName,scope:d.scope,identifier:d.identifier,blockchainFamily:d.blockchainFamily,chainId:d.chainId,groupHandle:t.groupHandle,hmacProof:t.hmacProof,hmacRest:t.hmacRest})}return(0,c.Left)(o??new i.UnknownDAError("No error in final state"))}})}extractDependencies(n){return{isSupported:r=>(0,A.isContactsSupportedForSession)(n,r),registerIdentity:r=>new m.SendRegisterIdentityTask(n,{contactName:r.contactName,scope:r.scope,identifier:r.identifier,blockchainFamily:r.blockchainFamily,chainId:r.chainId,existingContactGroup:r.existingContactGroup}).run()}}}0&&(module.exports={RegisterExternalAddressDeviceAction});
|
|
2
|
+
//# sourceMappingURL=RegisterExternalAddressDeviceAction.js.map
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
{
|
|
2
|
+
"version": 3,
|
|
3
|
+
"sources": ["../../../../../../src/internal/app-binder/device-action/RegisterExternalAddress/RegisterExternalAddressDeviceAction.ts"],
|
|
4
|
+
"sourcesContent": ["import {\n type DeviceActionStateMachine,\n type InternalApi,\n isSuccessCommandResult,\n OpenAppDeviceAction,\n type StateMachineTypes,\n UnknownDAError,\n UserInteractionRequired,\n WaitForAppAndVersionDeviceAction,\n XStateDeviceAction,\n} from \"@ledgerhq/device-management-kit\";\nimport { Left, Right } from \"purify-ts\";\nimport { assign, fromPromise, setup } from \"xstate\";\n\nimport {\n type RegisterExternalAddressDAError,\n type RegisterExternalAddressDAInput,\n type RegisterExternalAddressDAIntermediateValue,\n type RegisterExternalAddressDAInternalState,\n type RegisterExternalAddressDAOutput,\n} from \"@api/app-binder/RegisterExternalAddressDeviceActionTypes\";\nimport {\n isContactsSupportedForSession,\n type RunningApp,\n} from \"@internal/app-binder/isContactsSupportedForSession\";\nimport { ContactsVersionRequirementError } from \"@internal/app-binder/model/contactsErrors\";\nimport {\n type RegisterIdentityProofs,\n SendRegisterIdentityTask,\n} from \"@internal/app-binder/task/SendRegisterIdentityTask\";\n\nimport { validateRegisterExternalAddressInput } from \"./validateRegisterExternalAddressInput\";\n\nexport type RegisterExternalAddressMachineDependencies = {\n readonly isSupported: (app: RunningApp) => boolean;\n readonly registerIdentity: (\n input: RegisterExternalAddressDAInput,\n ) => Promise<Awaited<ReturnType<SendRegisterIdentityTask[\"run\"]>>>;\n};\n\nexport class RegisterExternalAddressDeviceAction extends XStateDeviceAction<\n RegisterExternalAddressDAOutput,\n RegisterExternalAddressDAInput,\n RegisterExternalAddressDAError,\n RegisterExternalAddressDAIntermediateValue,\n RegisterExternalAddressDAInternalState\n> {\n makeStateMachine(\n internalApi: InternalApi,\n ): DeviceActionStateMachine<\n RegisterExternalAddressDAOutput,\n RegisterExternalAddressDAInput,\n RegisterExternalAddressDAError,\n RegisterExternalAddressDAIntermediateValue,\n RegisterExternalAddressDAInternalState\n > {\n type types = StateMachineTypes<\n RegisterExternalAddressDAOutput,\n RegisterExternalAddressDAInput,\n RegisterExternalAddressDAError,\n RegisterExternalAddressDAIntermediateValue,\n RegisterExternalAddressDAInternalState\n >;\n\n const { isSupported, registerIdentity } =\n this.extractDependencies(internalApi);\n const appName = this.input.appName;\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 openAppStateMachine: new OpenAppDeviceAction({\n input: { appName },\n }).makeStateMachine(internalApi),\n waitForAppAndVersionStateMachine: new WaitForAppAndVersionDeviceAction({\n input: {},\n }).makeStateMachine(internalApi),\n registerIdentity: fromPromise(\n ({ input }: { input: RegisterExternalAddressDAInput }) =>\n registerIdentity(input),\n ),\n },\n guards: {\n skipOpenApp: ({ context }) => context.input.skipOpenApp === true,\n noInternalError: ({ context }) => context._internalState.error === null,\n contactsSupported: ({ context }) => {\n const { appAndVersion } = context._internalState;\n return appAndVersion !== null && isSupported(appAndVersion);\n },\n },\n actions: {\n assignValidationError: assign({\n _internalState: ({ context }) => {\n const error = validateRegisterExternalAddressInput(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: \"RegisterExternalAddressDeviceAction\",\n initial: \"InitialState\",\n context: ({ input }) => ({\n input,\n intermediateValue: {\n requiredUserInteraction: UserInteractionRequired.None,\n },\n _internalState: {\n error: null,\n appAndVersion: null,\n proofs: null,\n },\n }),\n states: {\n InitialState: {\n always: [\n { target: \"ValidateInput\", guard: \"skipOpenApp\" },\n { target: \"OpenAppDeviceAction\" },\n ],\n },\n OpenAppDeviceAction: {\n invoke: {\n id: \"openAppStateMachine\",\n src: \"openAppStateMachine\",\n input: () => ({ appName }),\n onSnapshot: {\n actions: assign({\n intermediateValue: ({ event }) =>\n event.snapshot.context.intermediateValue,\n }),\n },\n onDone: {\n target: \"CheckOpenAppResult\",\n actions: assign({\n _internalState: ({ event, context }) =>\n event.output.caseOf<RegisterExternalAddressDAInternalState>({\n Right: () => context._internalState,\n Left: (error) => ({ ...context._internalState, error }),\n }),\n }),\n },\n },\n },\n CheckOpenAppResult: {\n always: [\n { target: \"ValidateInput\", guard: \"noInternalError\" },\n { target: \"Error\" },\n ],\n },\n // Input validation runs inside the device action (after the app is\n // opened) so invalid caller input surfaces as a typed terminal error\n // state on the observable instead of a synchronous throw. Runs on both\n // the open-app and skip-open-app paths.\n ValidateInput: {\n entry: \"assignValidationError\",\n always: [\n { target: \"WaitForAppAndVersion\", guard: \"noInternalError\" },\n { target: \"Error\" },\n ],\n },\n // Read the running app + version freshly from the device (rather than\n // the possibly-stale session state) so the version guard evaluates the\n // app that is actually running \u2014 e.g. when open-app is skipped and the\n // app was changed outside DMK. Runs on both paths.\n WaitForAppAndVersion: {\n // Start the phase from a clean value, clearing any interaction left\n // over from the OpenApp phase (e.g. ConfirmOpenApp).\n entry: assign({\n intermediateValue: {\n requiredUserInteraction: UserInteractionRequired.None,\n },\n }),\n invoke: {\n id: \"waitForAppAndVersion\",\n src: \"waitForAppAndVersionStateMachine\",\n input: () => ({}),\n // Propagate the child DA's intermediate value so a consuming client\n // can render, e.g., a \"please unlock your device\" prompt when the\n // device is locked. Mirrors the OpenAppDeviceAction invoke above.\n onSnapshot: {\n actions: assign({\n intermediateValue: ({ event }) =>\n event.snapshot.context.intermediateValue,\n }),\n },\n onDone: {\n target: \"CheckAppAndVersion\",\n actions: assign({\n _internalState: ({ event, context }) =>\n event.output.caseOf<RegisterExternalAddressDAInternalState>({\n Right: (appAndVersion) => ({\n ...context._internalState,\n appAndVersion: {\n name: appAndVersion.name,\n version: appAndVersion.version,\n },\n }),\n Left: (error) => ({ ...context._internalState, error }),\n }),\n }),\n },\n },\n },\n CheckAppAndVersion: {\n always: [\n { target: \"VersionGuard\", guard: \"noInternalError\" },\n { target: \"Error\" },\n ],\n },\n // Version guard evaluates support from the fresh WaitForAppAndVersion\n // result. Runs on both the open-app and skip-open-app paths.\n VersionGuard: {\n always: [\n { target: \"RegisterIdentity\", guard: \"contactsSupported\" },\n { target: \"Error\", actions: \"assignVersionError\" },\n ],\n },\n RegisterIdentity: {\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: \"registerIdentity\",\n src: \"registerIdentity\",\n input: ({ context }) => context.input,\n onDone: {\n target: \"RegisterIdentityResultCheck\",\n actions: assign({\n _internalState: ({ event, context }) =>\n isSuccessCommandResult(event.output)\n ? { ...context._internalState, proofs: 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 RegisterIdentityResultCheck: {\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 { proofs, error } = context._internalState;\n if (proofs) {\n const { input } = context;\n return Right({\n mode: input.existingContactGroup\n ? (\"existingContactGroup\" as const)\n : (\"newContactGroup\" as const),\n contactName: input.contactName,\n scope: input.scope,\n identifier: input.identifier,\n blockchainFamily: input.blockchainFamily,\n chainId: input.chainId,\n groupHandle: proofs.groupHandle,\n hmacProof: proofs.hmacProof,\n hmacRest: proofs.hmacRest,\n });\n }\n return Left(error ?? new UnknownDAError(\"No error in final state\"));\n },\n });\n }\n\n extractDependencies(\n internalApi: InternalApi,\n ): RegisterExternalAddressMachineDependencies {\n const isSupported = (app: RunningApp) =>\n isContactsSupportedForSession(internalApi, app);\n\n const registerIdentity = (\n input: RegisterExternalAddressDAInput,\n ): Promise<Awaited<ReturnType<SendRegisterIdentityTask[\"run\"]>>> =>\n new SendRegisterIdentityTask(internalApi, {\n contactName: input.contactName,\n scope: input.scope,\n identifier: input.identifier,\n blockchainFamily: input.blockchainFamily,\n chainId: input.chainId,\n existingContactGroup: input.existingContactGroup,\n }).run();\n\n return { isSupported, registerIdentity };\n }\n}\n\nexport type { RegisterIdentityProofs };\n"],
|
|
5
|
+
"mappings": "yaAAA,IAAAA,EAAA,GAAAC,EAAAD,EAAA,yCAAAE,IAAA,eAAAC,EAAAH,GAAA,IAAAI,EAUO,2CACPC,EAA4B,qBAC5BC,EAA2C,kBAS3CC,EAGO,8DACPC,EAAgD,qDAChDC,EAGO,8DAEPC,EAAqD,kDAS9C,MAAMR,UAA4C,oBAMvD,CACA,iBACES,EAOA,CASA,KAAM,CAAE,YAAAC,EAAa,iBAAAC,CAAiB,EACpC,KAAK,oBAAoBF,CAAW,EAChCG,EAAU,KAAK,MAAM,QAE3B,SAAO,SAAM,CACX,MAAO,CACL,MAAO,CAAC,EACR,QAAS,CAAC,EACV,OAAQ,CAAC,CACX,EACA,OAAQ,CACN,oBAAqB,IAAI,sBAAoB,CAC3C,MAAO,CAAE,QAAAA,CAAQ,CACnB,CAAC,EAAE,iBAAiBH,CAAW,EAC/B,iCAAkC,IAAI,mCAAiC,CACrE,MAAO,CAAC,CACV,CAAC,EAAE,iBAAiBA,CAAW,EAC/B,oBAAkB,eAChB,CAAC,CAAE,MAAAI,CAAM,IACPF,EAAiBE,CAAK,CAC1B,CACF,EACA,OAAQ,CACN,YAAa,CAAC,CAAE,QAAAC,CAAQ,IAAMA,EAAQ,MAAM,cAAgB,GAC5D,gBAAiB,CAAC,CAAE,QAAAA,CAAQ,IAAMA,EAAQ,eAAe,QAAU,KACnE,kBAAmB,CAAC,CAAE,QAAAA,CAAQ,IAAM,CAClC,KAAM,CAAE,cAAAC,CAAc,EAAID,EAAQ,eAClC,OAAOC,IAAkB,MAAQL,EAAYK,CAAa,CAC5D,CACF,EACA,QAAS,CACP,yBAAuB,UAAO,CAC5B,eAAgB,CAAC,CAAE,QAAAD,CAAQ,IAAM,CAC/B,MAAME,KAAQ,wCAAqCF,EAAQ,KAAK,EAChE,OAAOE,EACH,CAAE,GAAGF,EAAQ,eAAgB,MAAAE,CAAM,EACnCF,EAAQ,cACd,CACF,CAAC,EACD,sBAAoB,UAAO,CACzB,eAAgB,CAAC,CAAE,QAAAA,CAAQ,KAAO,CAChC,GAAGA,EAAQ,eACX,MAAO,IAAI,iCACb,EACF,CAAC,EACD,wBAAsB,UAAO,CAC3B,eAAgB,CAAC,CAAE,QAAAA,EAAS,MAAAG,CAAM,KAAO,CACvC,GAAGH,EAAQ,eACX,MAAO,IAAI,iBACTG,EAAM,iBAAoB,MACtBA,EAAM,MAAS,QACf,OAAOA,EAAM,KAAQ,CAC3B,CACF,EACF,CAAC,CACH,CACF,CAAC,EAAE,cAAc,CACf,GAAI,sCACJ,QAAS,eACT,QAAS,CAAC,CAAE,MAAAJ,CAAM,KAAO,CACvB,MAAAA,EACA,kBAAmB,CACjB,wBAAyB,0BAAwB,IACnD,EACA,eAAgB,CACd,MAAO,KACP,cAAe,KACf,OAAQ,IACV,CACF,GACA,OAAQ,CACN,aAAc,CACZ,OAAQ,CACN,CAAE,OAAQ,gBAAiB,MAAO,aAAc,EAChD,CAAE,OAAQ,qBAAsB,CAClC,CACF,EACA,oBAAqB,CACnB,OAAQ,CACN,GAAI,sBACJ,IAAK,sBACL,MAAO,KAAO,CAAE,QAAAD,CAAQ,GACxB,WAAY,CACV,WAAS,UAAO,CACd,kBAAmB,CAAC,CAAE,MAAAK,CAAM,IAC1BA,EAAM,SAAS,QAAQ,iBAC3B,CAAC,CACH,EACA,OAAQ,CACN,OAAQ,qBACR,WAAS,UAAO,CACd,eAAgB,CAAC,CAAE,MAAAA,EAAO,QAAAH,CAAQ,IAChCG,EAAM,OAAO,OAA+C,CAC1D,MAAO,IAAMH,EAAQ,eACrB,KAAOE,IAAW,CAAE,GAAGF,EAAQ,eAAgB,MAAAE,CAAM,EACvD,CAAC,CACL,CAAC,CACH,CACF,CACF,EACA,mBAAoB,CAClB,OAAQ,CACN,CAAE,OAAQ,gBAAiB,MAAO,iBAAkB,EACpD,CAAE,OAAQ,OAAQ,CACpB,CACF,EAKA,cAAe,CACb,MAAO,wBACP,OAAQ,CACN,CAAE,OAAQ,uBAAwB,MAAO,iBAAkB,EAC3D,CAAE,OAAQ,OAAQ,CACpB,CACF,EAKA,qBAAsB,CAGpB,SAAO,UAAO,CACZ,kBAAmB,CACjB,wBAAyB,0BAAwB,IACnD,CACF,CAAC,EACD,OAAQ,CACN,GAAI,uBACJ,IAAK,mCACL,MAAO,KAAO,CAAC,GAIf,WAAY,CACV,WAAS,UAAO,CACd,kBAAmB,CAAC,CAAE,MAAAC,CAAM,IAC1BA,EAAM,SAAS,QAAQ,iBAC3B,CAAC,CACH,EACA,OAAQ,CACN,OAAQ,qBACR,WAAS,UAAO,CACd,eAAgB,CAAC,CAAE,MAAAA,EAAO,QAAAH,CAAQ,IAChCG,EAAM,OAAO,OAA+C,CAC1D,MAAQF,IAAmB,CACzB,GAAGD,EAAQ,eACX,cAAe,CACb,KAAMC,EAAc,KACpB,QAASA,EAAc,OACzB,CACF,GACA,KAAOC,IAAW,CAAE,GAAGF,EAAQ,eAAgB,MAAAE,CAAM,EACvD,CAAC,CACL,CAAC,CACH,CACF,CACF,EACA,mBAAoB,CAClB,OAAQ,CACN,CAAE,OAAQ,eAAgB,MAAO,iBAAkB,EACnD,CAAE,OAAQ,OAAQ,CACpB,CACF,EAGA,aAAc,CACZ,OAAQ,CACN,CAAE,OAAQ,mBAAoB,MAAO,mBAAoB,EACzD,CAAE,OAAQ,QAAS,QAAS,oBAAqB,CACnD,CACF,EACA,iBAAkB,CAChB,SAAO,UAAO,CACZ,kBAAmB,CACjB,wBAAyB,0BAAwB,cACnD,CACF,CAAC,EACD,QAAM,UAAO,CACX,kBAAmB,CACjB,wBAAyB,0BAAwB,IACnD,CACF,CAAC,EACD,OAAQ,CACN,GAAI,mBACJ,IAAK,mBACL,MAAO,CAAC,CAAE,QAAAF,CAAQ,IAAMA,EAAQ,MAChC,OAAQ,CACN,OAAQ,8BACR,WAAS,UAAO,CACd,eAAgB,CAAC,CAAE,MAAAG,EAAO,QAAAH,CAAQ,OAChC,0BAAuBG,EAAM,MAAM,EAC/B,CAAE,GAAGH,EAAQ,eAAgB,OAAQG,EAAM,OAAO,IAAK,EACvD,CACE,GAAGH,EAAQ,eACX,MAAOG,EAAM,OAAO,KACtB,CACR,CAAC,CACH,EACA,QAAS,CACP,OAAQ,QACR,QAAS,sBACX,CACF,CACF,EACA,4BAA6B,CAC3B,OAAQ,CACN,CAAE,OAAQ,UAAW,MAAO,iBAAkB,EAC9C,CAAE,OAAQ,OAAQ,CACpB,CACF,EACA,QAAS,CAAE,KAAM,OAAQ,EACzB,MAAO,CAAE,KAAM,OAAQ,CACzB,EACA,OAAQ,CAAC,CAAE,QAAAH,CAAQ,IAAM,CACvB,KAAM,CAAE,OAAAI,EAAQ,MAAAF,CAAM,EAAIF,EAAQ,eAClC,GAAII,EAAQ,CACV,KAAM,CAAE,MAAAL,CAAM,EAAIC,EAClB,SAAO,SAAM,CACX,KAAMD,EAAM,qBACP,uBACA,kBACL,YAAaA,EAAM,YACnB,MAAOA,EAAM,MACb,WAAYA,EAAM,WAClB,iBAAkBA,EAAM,iBACxB,QAASA,EAAM,QACf,YAAaK,EAAO,YACpB,UAAWA,EAAO,UAClB,SAAUA,EAAO,QACnB,CAAC,CACH,CACA,SAAO,QAAKF,GAAS,IAAI,iBAAe,yBAAyB,CAAC,CACpE,CACF,CAAC,CACH,CAEA,oBACEP,EAC4C,CAgB5C,MAAO,CAAE,YAfYU,MACnB,iCAA8BV,EAAaU,CAAG,EAc1B,iBAXpBN,GAEA,IAAI,2BAAyBJ,EAAa,CACxC,YAAaI,EAAM,YACnB,MAAOA,EAAM,MACb,WAAYA,EAAM,WAClB,iBAAkBA,EAAM,iBACxB,QAASA,EAAM,QACf,qBAAsBA,EAAM,oBAC9B,CAAC,EAAE,IAAI,CAE8B,CACzC,CACF",
|
|
6
|
+
"names": ["RegisterExternalAddressDeviceAction_exports", "__export", "RegisterExternalAddressDeviceAction", "__toCommonJS", "import_device_management_kit", "import_purify_ts", "import_xstate", "import_isContactsSupportedForSession", "import_contactsErrors", "import_SendRegisterIdentityTask", "import_validateRegisterExternalAddressInput", "internalApi", "isSupported", "registerIdentity", "appName", "input", "context", "appAndVersion", "error", "event", "proofs", "app"]
|
|
7
|
+
}
|
|
@@ -0,0 +1,2 @@
|
|
|
1
|
+
"use strict";var e=require("@ledgerhq/device-management-kit"),r=require("vitest"),R=require("../../../app-binder/device-action/__test-utils__/makeInternalApi"),c=require("../../../app-binder/device-action/__test-utils__/setupOpenAppDAMock"),E=require("../../../app-binder/device-action/__test-utils__/setupWaitForAppAndVersionDAMock"),p=require("../../../app-binder/device-action/__test-utils__/testDeviceActionStates"),D=require("../../../app-binder/model/contactsErrors"),f=require("./RegisterExternalAddressDeviceAction"),v=require("./validateRegisterExternalAddressInput");r.vi.mock("@ledgerhq/device-management-kit",async o=>({...await o(),OpenAppDeviceAction:r.vi.fn(()=>({makeStateMachine:r.vi.fn()})),WaitForAppAndVersionDeviceAction:r.vi.fn(()=>({makeStateMachine:r.vi.fn()}))}));const x={name:"Ethereum",version:"1.15.0"},g={groupHandle:new Uint8Array(64).fill(204),hmacProof:new Uint8Array(32).fill(221),hmacRest:new Uint8Array(32).fill(170)},s={contactName:"Alice",scope:"Eth main",identifier:new Uint8Array(20).fill(17),blockchainFamily:"ethereum",chainId:1n,appName:"Ethereum"};(0,r.describe)("RegisterExternalAddressDeviceAction",()=>{let o,l,A;function I(){return{isSupported:l,registerIdentity:A}}(0,r.beforeEach)(()=>{o=(0,R.makeDeviceActionInternalApiMock)(),(0,E.setupWaitForAppAndVersionDAMock)(x),l=r.vi.fn().mockReturnValue(!0),A=r.vi.fn().mockResolvedValue((0,e.CommandResultFactory)({data:g})),o.getDeviceSessionState.mockReturnValue({sessionStateType:e.DeviceSessionStateType.ReadyWithoutSecureChannel,deviceStatus:e.DeviceStatus.CONNECTED,installedApps:[],currentApp:{name:"Ethereum",version:"1.15.0"},deviceModelId:e.DeviceModelId.FLEX,isSecureConnectionAllowed:!0})});function u(i){const n=new f.RegisterExternalAddressDeviceAction({input:i});return r.vi.spyOn(n,"extractDependencies").mockReturnValue(I()),n}(0,r.it)("open-app path, new contact group: OpenApp -> VersionGuard -> RegisterIdentity -> Completed",()=>new Promise((i,n)=>{(0,c.setupOpenAppDAMock)();const t=u({...s,skipOpenApp:!1}),a=[{intermediateValue:{requiredUserInteraction:e.UserInteractionRequired.None},status:e.DeviceActionStatus.Pending},{intermediateValue:{requiredUserInteraction:e.UserInteractionRequired.ConfirmOpenApp},status:e.DeviceActionStatus.Pending},{intermediateValue:{requiredUserInteraction:e.UserInteractionRequired.None},status:e.DeviceActionStatus.Pending},{intermediateValue:{requiredUserInteraction:e.UserInteractionRequired.None},status:e.DeviceActionStatus.Pending},{intermediateValue:{requiredUserInteraction:e.UserInteractionRequired.RegisterWallet},status:e.DeviceActionStatus.Pending},{output:{mode:"newContactGroup",contactName:"Alice",scope:"Eth main",identifier:s.identifier,blockchainFamily:"ethereum",chainId:1n,...g},status:e.DeviceActionStatus.Completed}];(0,p.testDeviceActionStates)(t,a,o,{onDone:i,onError:n})})),(0,r.it)("skip-open-app path, existing contact group: VersionGuard -> RegisterIdentity -> Completed",()=>new Promise((i,n)=>{(0,c.setupOpenAppDAMock)();const t={groupHandle:new Uint8Array(64).fill(204),hmacProof:new Uint8Array(32).fill(221)},a=u({...s,skipOpenApp:!0,existingContactGroup:t}),d=[{intermediateValue:{requiredUserInteraction:e.UserInteractionRequired.None},status:e.DeviceActionStatus.Pending},{intermediateValue:{requiredUserInteraction:e.UserInteractionRequired.None},status:e.DeviceActionStatus.Pending},{intermediateValue:{requiredUserInteraction:e.UserInteractionRequired.RegisterWallet},status:e.DeviceActionStatus.Pending},{output:{mode:"existingContactGroup",contactName:"Alice",scope:"Eth main",identifier:s.identifier,blockchainFamily:"ethereum",chainId:1n,...g},status:e.DeviceActionStatus.Completed}];(0,p.testDeviceActionStates)(a,d,o,{onDone:i,onError:n})})),(0,r.it)("version guard rejects on skip-open-app path without opening the app",()=>new Promise((i,n)=>{(0,c.setupOpenAppDAMock)(),l.mockReturnValue(!1);const t=u({...s,skipOpenApp:!0}),a=[{intermediateValue:{requiredUserInteraction:e.UserInteractionRequired.None},status:e.DeviceActionStatus.Pending},{intermediateValue:{requiredUserInteraction:e.UserInteractionRequired.None},status:e.DeviceActionStatus.Pending},{error:new D.ContactsVersionRequirementError,status:e.DeviceActionStatus.Error}];(0,p.testDeviceActionStates)(t,a,o,{onDone:i,onError:n}),expect(A).not.toHaveBeenCalled()})),(0,r.it)("surfaces an open-app failure as the device action error",()=>new Promise((i,n)=>{const t=new e.UnknownDAError("open app failed");(0,c.setupOpenAppDAMock)(t);const a=u({...s,skipOpenApp:!1}),d=[{intermediateValue:{requiredUserInteraction:e.UserInteractionRequired.None},status:e.DeviceActionStatus.Pending},{intermediateValue:{requiredUserInteraction:e.UserInteractionRequired.ConfirmOpenApp},status:e.DeviceActionStatus.Pending},{error:t,status:e.DeviceActionStatus.Error}];(0,p.testDeviceActionStates)(a,d,o,{onDone:i,onError:n}),expect(l).not.toHaveBeenCalled()})),(0,r.it)("surfaces a Register Identity command error",()=>new Promise((i,n)=>{(0,c.setupOpenAppDAMock)();const t=new D.ContactsCommandError({errorCode:"6a80",message:"device rejected"});A.mockResolvedValue((0,e.CommandResultFactory)({error:t}));const a=u({...s,skipOpenApp:!0}),d=[{intermediateValue:{requiredUserInteraction:e.UserInteractionRequired.None},status:e.DeviceActionStatus.Pending},{intermediateValue:{requiredUserInteraction:e.UserInteractionRequired.None},status:e.DeviceActionStatus.Pending},{intermediateValue:{requiredUserInteraction:e.UserInteractionRequired.RegisterWallet},status:e.DeviceActionStatus.Pending},{error:t,status:e.DeviceActionStatus.Error}];(0,p.testDeviceActionStates)(a,d,o,{onDone:i,onError:n})})),(0,r.it)("surfaces invalid input as a typed error state on the skip-open-app path",()=>new Promise((i,n)=>{(0,c.setupOpenAppDAMock)();const t={...s,skipOpenApp:!0,contactName:""},a=(0,v.validateRegisterExternalAddressInput)(t),d=u(t),m=[{error:a,status:e.DeviceActionStatus.Error}];(0,p.testDeviceActionStates)(d,m,o,{onDone:i,onError:n}),expect(l).not.toHaveBeenCalled(),expect(A).not.toHaveBeenCalled()})),(0,r.it)("validates only after opening the app on the default path",()=>new Promise((i,n)=>{(0,c.setupOpenAppDAMock)();const t={...s,skipOpenApp:!1,contactName:""},a=(0,v.validateRegisterExternalAddressInput)(t),d=u(t),m=[{intermediateValue:{requiredUserInteraction:e.UserInteractionRequired.None},status:e.DeviceActionStatus.Pending},{intermediateValue:{requiredUserInteraction:e.UserInteractionRequired.ConfirmOpenApp},status:e.DeviceActionStatus.Pending},{error:a,status:e.DeviceActionStatus.Error}];(0,p.testDeviceActionStates)(d,m,o,{onDone:i,onError:n}),expect(A).not.toHaveBeenCalled()})),(0,r.it)("evaluates support from the fresh WaitForAppAndVersion result, not stale session state",()=>new Promise((i,n)=>{(0,c.setupOpenAppDAMock)();const t={name:"Ethereum",version:"9.9.9"};(0,E.setupWaitForAppAndVersionDAMock)(t);const a=u({...s,skipOpenApp:!0}),d=[{intermediateValue:{requiredUserInteraction:e.UserInteractionRequired.None},status:e.DeviceActionStatus.Pending},{intermediateValue:{requiredUserInteraction:e.UserInteractionRequired.None},status:e.DeviceActionStatus.Pending},{intermediateValue:{requiredUserInteraction:e.UserInteractionRequired.RegisterWallet},status:e.DeviceActionStatus.Pending},{output:{mode:"newContactGroup",contactName:"Alice",scope:"Eth main",identifier:s.identifier,blockchainFamily:"ethereum",chainId:1n,...g},status:e.DeviceActionStatus.Completed}];(0,p.testDeviceActionStates)(a,d,o,{onDone:()=>{try{expect(l).toHaveBeenCalledWith(t),i()}catch(m){n(m)}},onError:n})})),(0,r.it)("surfaces a WaitForAppAndVersion failure as the device action error",()=>new Promise((i,n)=>{(0,c.setupOpenAppDAMock)();const t=new e.UnknownDAError("could not read app and version");(0,E.setupWaitForAppAndVersionDAMock)({error:t});const a=u({...s,skipOpenApp:!0}),d=[{intermediateValue:{requiredUserInteraction:e.UserInteractionRequired.None},status:e.DeviceActionStatus.Pending},{intermediateValue:{requiredUserInteraction:e.UserInteractionRequired.None},status:e.DeviceActionStatus.Pending},{error:t,status:e.DeviceActionStatus.Error}];(0,p.testDeviceActionStates)(a,d,o,{onDone:i,onError:n}),expect(l).not.toHaveBeenCalled(),expect(A).not.toHaveBeenCalled()})),(0,r.it)("propagates the UnlockDevice interaction emitted by WaitForAppAndVersion",()=>new Promise((i,n)=>{(0,c.setupOpenAppDAMock)(),(0,E.setupWaitForAppAndVersionDAMock)(x,e.UserInteractionRequired.UnlockDevice);const t=u({...s,skipOpenApp:!0}),a=[{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:{mode:"newContactGroup",contactName:"Alice",scope:"Eth main",identifier:s.identifier,blockchainFamily:"ethereum",chainId:1n,...g},status:e.DeviceActionStatus.Completed}];(0,p.testDeviceActionStates)(t,a,o,{onDone:i,onError:n})}))});
|
|
2
|
+
//# sourceMappingURL=RegisterExternalAddressDeviceAction.test.js.map
|