@ledgerhq/device-contacts-kit 0.2.0 → 0.3.1
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 +29 -2
- package/lib/cjs/api/ContactsManager.js +1 -1
- package/lib/cjs/api/ContactsManager.js.map +1 -1
- package/lib/cjs/api/app-binder/EditExternalAddressIdentifierDeviceActionTypes.js +2 -0
- package/lib/cjs/api/app-binder/EditExternalAddressIdentifierDeviceActionTypes.js.map +7 -0
- package/lib/cjs/api/app-binder/EditExternalAddressScopeDeviceActionTypes.js +2 -0
- package/lib/cjs/api/app-binder/EditExternalAddressScopeDeviceActionTypes.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/EditExternalAddressIdentifier.js +2 -0
- package/lib/cjs/api/model/EditExternalAddressIdentifier.js.map +7 -0
- package/lib/cjs/api/model/EditExternalAddressScope.js +2 -0
- package/lib/cjs/api/model/EditExternalAddressScope.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 +2 -2
- package/lib/cjs/internal/DefaultContactsManager.test.js +1 -1
- package/lib/cjs/internal/DefaultContactsManager.test.js.map +3 -3
- 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/EditExternalAddressIdentifierCommand.js +2 -0
- package/lib/cjs/internal/app-binder/command/EditExternalAddressIdentifierCommand.js.map +7 -0
- package/lib/cjs/internal/app-binder/command/EditExternalAddressIdentifierCommand.test.js +2 -0
- package/lib/cjs/internal/app-binder/command/EditExternalAddressIdentifierCommand.test.js.map +7 -0
- package/lib/cjs/internal/app-binder/command/EditExternalAddressScopeCommand.js +2 -0
- package/lib/cjs/internal/app-binder/command/EditExternalAddressScopeCommand.js.map +7 -0
- package/lib/cjs/internal/app-binder/command/EditExternalAddressScopeCommand.test.js +2 -0
- package/lib/cjs/internal/app-binder/command/EditExternalAddressScopeCommand.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/contactsVersionGuards.js +2 -0
- package/lib/cjs/internal/app-binder/contactsVersionGuards.js.map +7 -0
- package/lib/cjs/internal/app-binder/contactsVersionGuards.test.js +2 -0
- package/lib/cjs/internal/app-binder/contactsVersionGuards.test.js.map +7 -0
- package/lib/cjs/internal/app-binder/device-action/EditExternalAddressIdentifier/EditExternalAddressIdentifierDeviceAction.js +2 -0
- package/lib/cjs/internal/app-binder/device-action/EditExternalAddressIdentifier/EditExternalAddressIdentifierDeviceAction.js.map +7 -0
- package/lib/cjs/internal/app-binder/device-action/EditExternalAddressIdentifier/EditExternalAddressIdentifierDeviceAction.test.js +2 -0
- package/lib/cjs/internal/app-binder/device-action/EditExternalAddressIdentifier/EditExternalAddressIdentifierDeviceAction.test.js.map +7 -0
- package/lib/cjs/internal/app-binder/device-action/EditExternalAddressIdentifier/validateEditExternalAddressIdentifierInput.js +2 -0
- package/lib/cjs/internal/app-binder/device-action/EditExternalAddressIdentifier/validateEditExternalAddressIdentifierInput.js.map +7 -0
- package/lib/cjs/internal/app-binder/device-action/EditExternalAddressIdentifier/validateEditExternalAddressIdentifierInput.test.js +2 -0
- package/lib/cjs/internal/app-binder/device-action/EditExternalAddressIdentifier/validateEditExternalAddressIdentifierInput.test.js.map +7 -0
- package/lib/cjs/internal/app-binder/device-action/EditExternalAddressScope/EditExternalAddressScopeDeviceAction.js +2 -0
- package/lib/cjs/internal/app-binder/device-action/EditExternalAddressScope/EditExternalAddressScopeDeviceAction.js.map +7 -0
- package/lib/cjs/internal/app-binder/device-action/EditExternalAddressScope/EditExternalAddressScopeDeviceAction.test.js +2 -0
- package/lib/cjs/internal/app-binder/device-action/EditExternalAddressScope/EditExternalAddressScopeDeviceAction.test.js.map +7 -0
- package/lib/cjs/internal/app-binder/device-action/EditExternalAddressScope/validateEditExternalAddressScopeInput.js +2 -0
- package/lib/cjs/internal/app-binder/device-action/EditExternalAddressScope/validateEditExternalAddressScopeInput.js.map +7 -0
- package/lib/cjs/internal/app-binder/device-action/EditExternalAddressScope/validateEditExternalAddressScopeInput.test.js +2 -0
- package/lib/cjs/internal/app-binder/device-action/EditExternalAddressScope/validateEditExternalAddressScopeInput.test.js.map +7 -0
- package/lib/cjs/internal/app-binder/device-action/RegisterExternalAddress/RegisterExternalAddressDeviceAction.js +1 -1
- package/lib/cjs/internal/app-binder/device-action/RegisterExternalAddress/RegisterExternalAddressDeviceAction.js.map +3 -3
- 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__/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/model/contactsConstants.js +1 -1
- package/lib/cjs/internal/app-binder/model/contactsConstants.js.map +3 -3
- package/lib/cjs/internal/app-binder/task/SendEditExternalAddressIdentifierTask.js +2 -0
- package/lib/cjs/internal/app-binder/task/SendEditExternalAddressIdentifierTask.js.map +7 -0
- package/lib/cjs/internal/app-binder/task/SendEditExternalAddressIdentifierTask.test.js +2 -0
- package/lib/cjs/internal/app-binder/task/SendEditExternalAddressIdentifierTask.test.js.map +7 -0
- package/lib/cjs/internal/app-binder/task/SendEditExternalAddressScopeTask.js +2 -0
- package/lib/cjs/internal/app-binder/task/SendEditExternalAddressScopeTask.js.map +7 -0
- package/lib/cjs/internal/app-binder/task/SendEditExternalAddressScopeTask.test.js +2 -0
- package/lib/cjs/internal/app-binder/task/SendEditExternalAddressScopeTask.test.js.map +7 -0
- package/lib/cjs/internal/app-binder/task/SendRegisterIdentityTask.js +1 -1
- package/lib/cjs/internal/app-binder/task/SendRegisterIdentityTask.js.map +2 -2
- package/lib/cjs/internal/app-binder/task/SendRegisterIdentityTask.test.js +1 -1
- package/lib/cjs/internal/app-binder/task/SendRegisterIdentityTask.test.js.map +2 -2
- 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.test.js +1 -1
- package/lib/cjs/internal/di.test.js.map +3 -3
- package/lib/cjs/internal/use-cases/EditExternalAddressIdentifierUseCase.js +2 -0
- package/lib/cjs/internal/use-cases/EditExternalAddressIdentifierUseCase.js.map +7 -0
- package/lib/cjs/internal/use-cases/EditExternalAddressIdentifierUseCase.test.js +2 -0
- package/lib/cjs/internal/use-cases/EditExternalAddressIdentifierUseCase.test.js.map +7 -0
- package/lib/cjs/internal/use-cases/EditExternalAddressScopeUseCase.js +2 -0
- package/lib/cjs/internal/use-cases/EditExternalAddressScopeUseCase.js.map +7 -0
- package/lib/cjs/internal/use-cases/EditExternalAddressScopeUseCase.test.js +2 -0
- package/lib/cjs/internal/use-cases/EditExternalAddressScopeUseCase.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 +1 -1
- package/lib/cjs/internal/use-cases/di/useCaseModule.js.map +3 -3
- package/lib/cjs/internal/use-cases/di/useCaseTypes.js +1 -1
- package/lib/cjs/internal/use-cases/di/useCaseTypes.js.map +2 -2
- package/lib/cjs/package.json +1 -1
- package/lib/esm/api/app-binder/EditExternalAddressIdentifierDeviceActionTypes.js +1 -0
- package/lib/esm/api/app-binder/EditExternalAddressIdentifierDeviceActionTypes.js.map +7 -0
- package/lib/esm/api/app-binder/EditExternalAddressScopeDeviceActionTypes.js +1 -0
- package/lib/esm/api/app-binder/EditExternalAddressScopeDeviceActionTypes.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/EditExternalAddressIdentifier.js +1 -0
- package/lib/esm/api/model/EditExternalAddressIdentifier.js.map +7 -0
- package/lib/esm/api/model/EditExternalAddressScope.js +1 -0
- package/lib/esm/api/model/EditExternalAddressScope.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 +2 -2
- package/lib/esm/internal/DefaultContactsManager.test.js +1 -1
- package/lib/esm/internal/DefaultContactsManager.test.js.map +3 -3
- 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/EditExternalAddressIdentifierCommand.js +2 -0
- package/lib/esm/internal/app-binder/command/EditExternalAddressIdentifierCommand.js.map +7 -0
- package/lib/esm/internal/app-binder/command/EditExternalAddressIdentifierCommand.test.js +2 -0
- package/lib/esm/internal/app-binder/command/EditExternalAddressIdentifierCommand.test.js.map +7 -0
- package/lib/esm/internal/app-binder/command/EditExternalAddressScopeCommand.js +2 -0
- package/lib/esm/internal/app-binder/command/EditExternalAddressScopeCommand.js.map +7 -0
- package/lib/esm/internal/app-binder/command/EditExternalAddressScopeCommand.test.js +2 -0
- package/lib/esm/internal/app-binder/command/EditExternalAddressScopeCommand.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/contactsVersionGuards.js +2 -0
- package/lib/esm/internal/app-binder/contactsVersionGuards.js.map +7 -0
- package/lib/esm/internal/app-binder/contactsVersionGuards.test.js +2 -0
- package/lib/esm/internal/app-binder/contactsVersionGuards.test.js.map +7 -0
- package/lib/esm/internal/app-binder/device-action/EditExternalAddressIdentifier/EditExternalAddressIdentifierDeviceAction.js +2 -0
- package/lib/esm/internal/app-binder/device-action/EditExternalAddressIdentifier/EditExternalAddressIdentifierDeviceAction.js.map +7 -0
- package/lib/esm/internal/app-binder/device-action/EditExternalAddressIdentifier/EditExternalAddressIdentifierDeviceAction.test.js +2 -0
- package/lib/esm/internal/app-binder/device-action/EditExternalAddressIdentifier/EditExternalAddressIdentifierDeviceAction.test.js.map +7 -0
- package/lib/esm/internal/app-binder/device-action/EditExternalAddressIdentifier/validateEditExternalAddressIdentifierInput.js +2 -0
- package/lib/esm/internal/app-binder/device-action/EditExternalAddressIdentifier/validateEditExternalAddressIdentifierInput.js.map +7 -0
- package/lib/esm/internal/app-binder/device-action/EditExternalAddressIdentifier/validateEditExternalAddressIdentifierInput.test.js +2 -0
- package/lib/esm/internal/app-binder/device-action/EditExternalAddressIdentifier/validateEditExternalAddressIdentifierInput.test.js.map +7 -0
- package/lib/esm/internal/app-binder/device-action/EditExternalAddressScope/EditExternalAddressScopeDeviceAction.js +2 -0
- package/lib/esm/internal/app-binder/device-action/EditExternalAddressScope/EditExternalAddressScopeDeviceAction.js.map +7 -0
- package/lib/esm/internal/app-binder/device-action/EditExternalAddressScope/EditExternalAddressScopeDeviceAction.test.js +2 -0
- package/lib/esm/internal/app-binder/device-action/EditExternalAddressScope/EditExternalAddressScopeDeviceAction.test.js.map +7 -0
- package/lib/esm/internal/app-binder/device-action/EditExternalAddressScope/validateEditExternalAddressScopeInput.js +2 -0
- package/lib/esm/internal/app-binder/device-action/EditExternalAddressScope/validateEditExternalAddressScopeInput.js.map +7 -0
- package/lib/esm/internal/app-binder/device-action/EditExternalAddressScope/validateEditExternalAddressScopeInput.test.js +2 -0
- package/lib/esm/internal/app-binder/device-action/EditExternalAddressScope/validateEditExternalAddressScopeInput.test.js.map +7 -0
- package/lib/esm/internal/app-binder/device-action/RegisterExternalAddress/RegisterExternalAddressDeviceAction.js +1 -1
- package/lib/esm/internal/app-binder/device-action/RegisterExternalAddress/RegisterExternalAddressDeviceAction.js.map +3 -3
- 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__/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/model/contactsConstants.js +1 -1
- package/lib/esm/internal/app-binder/model/contactsConstants.js.map +3 -3
- package/lib/esm/internal/app-binder/task/SendEditExternalAddressIdentifierTask.js +2 -0
- package/lib/esm/internal/app-binder/task/SendEditExternalAddressIdentifierTask.js.map +7 -0
- package/lib/esm/internal/app-binder/task/SendEditExternalAddressIdentifierTask.test.js +2 -0
- package/lib/esm/internal/app-binder/task/SendEditExternalAddressIdentifierTask.test.js.map +7 -0
- package/lib/esm/internal/app-binder/task/SendEditExternalAddressScopeTask.js +2 -0
- package/lib/esm/internal/app-binder/task/SendEditExternalAddressScopeTask.js.map +7 -0
- package/lib/esm/internal/app-binder/task/SendEditExternalAddressScopeTask.test.js +2 -0
- package/lib/esm/internal/app-binder/task/SendEditExternalAddressScopeTask.test.js.map +7 -0
- package/lib/esm/internal/app-binder/task/SendRegisterIdentityTask.js +1 -1
- package/lib/esm/internal/app-binder/task/SendRegisterIdentityTask.js.map +3 -3
- package/lib/esm/internal/app-binder/task/SendRegisterIdentityTask.test.js +1 -1
- package/lib/esm/internal/app-binder/task/SendRegisterIdentityTask.test.js.map +2 -2
- 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.test.js +1 -1
- package/lib/esm/internal/di.test.js.map +3 -3
- package/lib/esm/internal/use-cases/EditExternalAddressIdentifierUseCase.js +2 -0
- package/lib/esm/internal/use-cases/EditExternalAddressIdentifierUseCase.js.map +7 -0
- package/lib/esm/internal/use-cases/EditExternalAddressIdentifierUseCase.test.js +2 -0
- package/lib/esm/internal/use-cases/EditExternalAddressIdentifierUseCase.test.js.map +7 -0
- package/lib/esm/internal/use-cases/EditExternalAddressScopeUseCase.js +2 -0
- package/lib/esm/internal/use-cases/EditExternalAddressScopeUseCase.js.map +7 -0
- package/lib/esm/internal/use-cases/EditExternalAddressScopeUseCase.test.js +2 -0
- package/lib/esm/internal/use-cases/EditExternalAddressScopeUseCase.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 +1 -1
- package/lib/esm/internal/use-cases/di/useCaseModule.js.map +3 -3
- package/lib/esm/internal/use-cases/di/useCaseTypes.js +1 -1
- package/lib/esm/internal/use-cases/di/useCaseTypes.js.map +2 -2
- package/lib/esm/package.json +1 -1
- package/lib/types/api/ContactsManager.d.ts +35 -0
- package/lib/types/api/ContactsManager.d.ts.map +1 -1
- package/lib/types/api/app-binder/EditExternalAddressIdentifierDeviceActionTypes.d.ts +27 -0
- package/lib/types/api/app-binder/EditExternalAddressIdentifierDeviceActionTypes.d.ts.map +1 -0
- package/lib/types/api/app-binder/EditExternalAddressScopeDeviceActionTypes.d.ts +27 -0
- package/lib/types/api/app-binder/EditExternalAddressScopeDeviceActionTypes.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 +6 -0
- package/lib/types/api/index.d.ts.map +1 -1
- package/lib/types/api/model/EditExternalAddressIdentifier.d.ts +57 -0
- package/lib/types/api/model/EditExternalAddressIdentifier.d.ts.map +1 -0
- package/lib/types/api/model/EditExternalAddressScope.d.ts +59 -0
- package/lib/types/api/model/EditExternalAddressScope.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 +9 -0
- package/lib/types/internal/DefaultContactsManager.d.ts.map +1 -1
- package/lib/types/internal/app-binder/ContactsAppBinder.d.ts +9 -0
- package/lib/types/internal/app-binder/ContactsAppBinder.d.ts.map +1 -1
- package/lib/types/internal/app-binder/command/EditExternalAddressIdentifierCommand.d.ts +25 -0
- package/lib/types/internal/app-binder/command/EditExternalAddressIdentifierCommand.d.ts.map +1 -0
- package/lib/types/internal/app-binder/command/EditExternalAddressIdentifierCommand.test.d.ts +2 -0
- package/lib/types/internal/app-binder/command/EditExternalAddressIdentifierCommand.test.d.ts.map +1 -0
- package/lib/types/internal/app-binder/command/EditExternalAddressScopeCommand.d.ts +25 -0
- package/lib/types/internal/app-binder/command/EditExternalAddressScopeCommand.d.ts.map +1 -0
- package/lib/types/internal/app-binder/command/EditExternalAddressScopeCommand.test.d.ts +2 -0
- package/lib/types/internal/app-binder/command/EditExternalAddressScopeCommand.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/contactsVersionGuards.d.ts +38 -0
- package/lib/types/internal/app-binder/contactsVersionGuards.d.ts.map +1 -0
- package/lib/types/internal/app-binder/contactsVersionGuards.test.d.ts +2 -0
- package/lib/types/internal/app-binder/contactsVersionGuards.test.d.ts.map +1 -0
- package/lib/types/internal/app-binder/device-action/EditExternalAddressIdentifier/EditExternalAddressIdentifierDeviceAction.d.ts +14 -0
- package/lib/types/internal/app-binder/device-action/EditExternalAddressIdentifier/EditExternalAddressIdentifierDeviceAction.d.ts.map +1 -0
- package/lib/types/internal/app-binder/device-action/EditExternalAddressIdentifier/EditExternalAddressIdentifierDeviceAction.test.d.ts +2 -0
- package/lib/types/internal/app-binder/device-action/EditExternalAddressIdentifier/EditExternalAddressIdentifierDeviceAction.test.d.ts.map +1 -0
- package/lib/types/internal/app-binder/device-action/EditExternalAddressIdentifier/validateEditExternalAddressIdentifierInput.d.ts +9 -0
- package/lib/types/internal/app-binder/device-action/EditExternalAddressIdentifier/validateEditExternalAddressIdentifierInput.d.ts.map +1 -0
- package/lib/types/internal/app-binder/device-action/EditExternalAddressIdentifier/validateEditExternalAddressIdentifierInput.test.d.ts +2 -0
- package/lib/types/internal/app-binder/device-action/EditExternalAddressIdentifier/validateEditExternalAddressIdentifierInput.test.d.ts.map +1 -0
- package/lib/types/internal/app-binder/device-action/EditExternalAddressScope/EditExternalAddressScopeDeviceAction.d.ts +14 -0
- package/lib/types/internal/app-binder/device-action/EditExternalAddressScope/EditExternalAddressScopeDeviceAction.d.ts.map +1 -0
- package/lib/types/internal/app-binder/device-action/EditExternalAddressScope/EditExternalAddressScopeDeviceAction.test.d.ts +2 -0
- package/lib/types/internal/app-binder/device-action/EditExternalAddressScope/EditExternalAddressScopeDeviceAction.test.d.ts.map +1 -0
- package/lib/types/internal/app-binder/device-action/EditExternalAddressScope/validateEditExternalAddressScopeInput.d.ts +9 -0
- package/lib/types/internal/app-binder/device-action/EditExternalAddressScope/validateEditExternalAddressScopeInput.d.ts.map +1 -0
- package/lib/types/internal/app-binder/device-action/EditExternalAddressScope/validateEditExternalAddressScopeInput.test.d.ts +2 -0
- package/lib/types/internal/app-binder/device-action/EditExternalAddressScope/validateEditExternalAddressScopeInput.test.d.ts.map +1 -0
- package/lib/types/internal/app-binder/device-action/RegisterExternalAddress/RegisterExternalAddressDeviceAction.d.ts +1 -1
- package/lib/types/internal/app-binder/device-action/RegisterExternalAddress/RegisterExternalAddressDeviceAction.d.ts.map +1 -1
- 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__/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/model/contactsConstants.d.ts +26 -0
- package/lib/types/internal/app-binder/model/contactsConstants.d.ts.map +1 -1
- package/lib/types/internal/app-binder/task/SendEditExternalAddressIdentifierTask.d.ts +25 -0
- package/lib/types/internal/app-binder/task/SendEditExternalAddressIdentifierTask.d.ts.map +1 -0
- package/lib/types/internal/app-binder/task/SendEditExternalAddressIdentifierTask.test.d.ts +2 -0
- package/lib/types/internal/app-binder/task/SendEditExternalAddressIdentifierTask.test.d.ts.map +1 -0
- package/lib/types/internal/app-binder/task/SendEditExternalAddressScopeTask.d.ts +25 -0
- package/lib/types/internal/app-binder/task/SendEditExternalAddressScopeTask.d.ts.map +1 -0
- package/lib/types/internal/app-binder/task/SendEditExternalAddressScopeTask.test.d.ts +2 -0
- package/lib/types/internal/app-binder/task/SendEditExternalAddressScopeTask.test.d.ts.map +1 -0
- package/lib/types/internal/app-binder/task/SendRegisterIdentityTask.d.ts.map +1 -1
- 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/use-cases/EditExternalAddressIdentifierUseCase.d.ts +14 -0
- package/lib/types/internal/use-cases/EditExternalAddressIdentifierUseCase.d.ts.map +1 -0
- package/lib/types/internal/use-cases/EditExternalAddressIdentifierUseCase.test.d.ts +2 -0
- package/lib/types/internal/use-cases/EditExternalAddressIdentifierUseCase.test.d.ts.map +1 -0
- package/lib/types/internal/use-cases/EditExternalAddressScopeUseCase.d.ts +14 -0
- package/lib/types/internal/use-cases/EditExternalAddressScopeUseCase.d.ts.map +1 -0
- package/lib/types/internal/use-cases/EditExternalAddressScopeUseCase.test.d.ts +2 -0
- package/lib/types/internal/use-cases/EditExternalAddressScopeUseCase.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.map +1 -1
- package/lib/types/internal/use-cases/di/useCaseTypes.d.ts +3 -0
- package/lib/types/internal/use-cases/di/useCaseTypes.d.ts.map +1 -1
- package/lib/types/tsconfig.prod.tsbuildinfo +1 -1
- package/package.json +4 -4
- package/lib/cjs/internal/app-binder/isContactsSupportedForSession.js +0 -2
- package/lib/cjs/internal/app-binder/isContactsSupportedForSession.js.map +0 -7
- package/lib/cjs/internal/app-binder/isContactsSupportedForSession.test.js +0 -2
- package/lib/cjs/internal/app-binder/isContactsSupportedForSession.test.js.map +0 -7
- package/lib/esm/internal/app-binder/isContactsSupportedForSession.js +0 -2
- package/lib/esm/internal/app-binder/isContactsSupportedForSession.js.map +0 -7
- package/lib/esm/internal/app-binder/isContactsSupportedForSession.test.js +0 -2
- package/lib/esm/internal/app-binder/isContactsSupportedForSession.test.js.map +0 -7
- package/lib/types/internal/app-binder/isContactsSupportedForSession.d.ts +0 -25
- package/lib/types/internal/app-binder/isContactsSupportedForSession.d.ts.map +0 -1
- package/lib/types/internal/app-binder/isContactsSupportedForSession.test.d.ts +0 -2
- package/lib/types/internal/app-binder/isContactsSupportedForSession.test.d.ts.map +0 -1
package/README.md
CHANGED
|
@@ -55,8 +55,35 @@ observable.subscribe((state) => {
|
|
|
55
55
|
});
|
|
56
56
|
```
|
|
57
57
|
|
|
58
|
-
|
|
59
|
-
|
|
58
|
+
## Renaming a contact
|
|
59
|
+
|
|
60
|
+
`renameContact` runs the device's EDIT CONTACT NAME operation. Unlike the register operations, this
|
|
61
|
+
is a blockchain-agnostic **dashboard** command served by the device OS: it always navigates to the
|
|
62
|
+
dashboard first (never opens an app), checks only the [minimum OS version](#version-requirements),
|
|
63
|
+
then rotates the contact group's name proof. Pass the current name, the new name, the group's
|
|
64
|
+
`groupHandle`, and the existing `hmacProof`; the op returns the replacement group-level `hmacProof`
|
|
65
|
+
for the host to persist. Per-entry `hmacRest` values are untouched — they never cover the name.
|
|
66
|
+
|
|
67
|
+
```ts
|
|
68
|
+
const { observable } = contactsManager.renameContact({
|
|
69
|
+
previousContactName: "Alice",
|
|
70
|
+
newContactName: "Bob",
|
|
71
|
+
groupHandle, // 64 bytes, from the group's Register Identity
|
|
72
|
+
hmacProof, // 32 bytes, the current name proof
|
|
73
|
+
});
|
|
74
|
+
|
|
75
|
+
observable.subscribe((state) => {
|
|
76
|
+
// state.intermediateValue.requiredUserInteraction surfaces the go-to-dashboard
|
|
77
|
+
// steps and the on-device validation.
|
|
78
|
+
if (state.status === DeviceActionStatus.Completed) {
|
|
79
|
+
const { contactName, groupHandle, hmacProof } = state.output;
|
|
80
|
+
// persist the new name and the replacement hmacProof.
|
|
81
|
+
}
|
|
82
|
+
});
|
|
83
|
+
```
|
|
84
|
+
|
|
85
|
+
Concrete Contacts operations (Edit Identifier, Edit Scope, Register Ledger Account, Edit Ledger
|
|
86
|
+
Account) are added by their dedicated implementation tickets.
|
|
60
87
|
|
|
61
88
|
## Version requirements
|
|
62
89
|
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
"use strict";var
|
|
1
|
+
"use strict";var d=Object.defineProperty;var i=Object.getOwnPropertyDescriptor;var s=Object.getOwnPropertyNames;var a=Object.prototype.hasOwnProperty;var o=(t,e,p,n)=>{if(e&&typeof e=="object"||typeof e=="function")for(let r of s(e))!a.call(t,r)&&r!==p&&d(t,r,{get:()=>e[r],enumerable:!(n=i(e,r))||n.enumerable});return t};var A=t=>o(d({},"__esModule",{value:!0}),t);var E={};module.exports=A(E);
|
|
2
2
|
//# sourceMappingURL=ContactsManager.js.map
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"version": 3,
|
|
3
3
|
"sources": ["../../../src/api/ContactsManager.ts"],
|
|
4
|
-
"sourcesContent": ["import { type RegisterExternalAddressDAReturnType } from \"@api/app-binder/RegisterExternalAddressDeviceActionTypes\";\nimport { type RegisterExternalAddressInput } from \"@api/model/RegisterExternalAddress\";\n\n/**\n * Public, stateless Contacts (Address Book) manager.\n *\n * It only drives device interactions \u2014 taking caller input, running the device\n * operation, and returning the device output (including proof material). It\n * does not store anything, own the address book, or handle persistence; the\n * host is responsible for that.\n */\nexport interface ContactsManager {\n /**\n * Register an external address on the device \u2014 either creating a new contact\n * group or adding the address to an existing one (via\n * `input.existingContactGroup`). Opens the embedded app by default (pass\n * `skipOpenApp: true` to skip only the open-app step; the version guard still\n * runs), checks the Contacts version requirements, then runs REGISTER\n * IDENTITY. Returns the device-issued group handle and proofs to persist.\n */\n registerExternalAddress(\n input: RegisterExternalAddressInput,\n ): RegisterExternalAddressDAReturnType;\n}\n"],
|
|
4
|
+
"sourcesContent": ["import { type EditExternalAddressIdentifierDAReturnType } from \"@api/app-binder/EditExternalAddressIdentifierDeviceActionTypes\";\nimport { type EditExternalAddressScopeDAReturnType } from \"@api/app-binder/EditExternalAddressScopeDeviceActionTypes\";\nimport { type RegisterExternalAddressDAReturnType } from \"@api/app-binder/RegisterExternalAddressDeviceActionTypes\";\nimport { type RenameContactDAReturnType } from \"@api/app-binder/RenameContactDeviceActionTypes\";\nimport { type EditExternalAddressIdentifierInput } from \"@api/model/EditExternalAddressIdentifier\";\nimport { type EditExternalAddressScopeInput } from \"@api/model/EditExternalAddressScope\";\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 /**\n * Edit an external address's identifier (EDIT IDENTIFIER) \u2014 replace an entry's\n * address bytes within a contact group. Opens the app by default (`skipOpenApp:\n * true` skips it; the version guard still runs) and checks the Contacts version\n * requirements. Pass the previous/new identifiers, `groupHandle`, `hmacProof`,\n * and current `hmacRest`; returns the replacement `hmacRest` (the `hmacProof`\n * is unchanged).\n */\n editExternalAddressIdentifier(\n input: EditExternalAddressIdentifierInput,\n ): EditExternalAddressIdentifierDAReturnType;\n\n /**\n * Edit an external address's scope (EDIT SCOPE) \u2014 replace an entry's scope\n * (its context label) within a contact group while keeping the same contact\n * name and identifier. Opens the app by default (`skipOpenApp: true` skips it;\n * the version guard still runs) and checks the Contacts version requirements.\n * Pass the previous/new scopes, `identifier`, `groupHandle`, `hmacProof`, and\n * current `hmacRest`; returns the replacement `hmacRest` (the `hmacProof` is\n * unchanged).\n */\n editExternalAddressScope(\n input: EditExternalAddressScopeInput,\n ): EditExternalAddressScopeDAReturnType;\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 d=Object.defineProperty;var o=Object.getOwnPropertyDescriptor;var a=Object.getOwnPropertyNames;var s=Object.prototype.hasOwnProperty;var p=(r,e,i,n)=>{if(e&&typeof e=="object"||typeof e=="function")for(let t of a(e))!s.call(r,t)&&t!==i&&d(r,t,{get:()=>e[t],enumerable:!(n=o(e,t))||n.enumerable});return r};var E=r=>p(d({},"__esModule",{value:!0}),r);var A={};module.exports=E(A);
|
|
2
|
+
//# sourceMappingURL=EditExternalAddressIdentifierDeviceActionTypes.js.map
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
{
|
|
2
|
+
"version": 3,
|
|
3
|
+
"sources": ["../../../../src/api/app-binder/EditExternalAddressIdentifierDeviceActionTypes.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 EditExternalAddressIdentifierInput,\n type EditExternalAddressIdentifierOutput,\n} from \"@api/model/EditExternalAddressIdentifier\";\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 EditExternalAddressIdentifierDAInput =\n EditExternalAddressIdentifierInput & {\n readonly appName: string;\n };\n\nexport type EditExternalAddressIdentifierDAOutput =\n EditExternalAddressIdentifierOutput;\n\nexport type EditExternalAddressIdentifierDAError =\n | OpenAppDAError\n | ContactsValidationError\n | ContactsVersionRequirementError\n | CommandErrorResult<ContactsErrorCodes>[\"error\"];\n\nexport type EditExternalAddressIdentifierDARequiredInteraction =\n | OpenAppDARequiredInteraction\n | UserInteractionRequired.RegisterWallet;\n\nexport type EditExternalAddressIdentifierDAIntermediateValue = {\n readonly requiredUserInteraction: EditExternalAddressIdentifierDARequiredInteraction;\n};\n\nexport type EditExternalAddressIdentifierDAState = DeviceActionState<\n EditExternalAddressIdentifierDAOutput,\n EditExternalAddressIdentifierDAError,\n EditExternalAddressIdentifierDAIntermediateValue\n>;\n\nexport type EditExternalAddressIdentifierDAInternalState = {\n readonly error: EditExternalAddressIdentifierDAError | 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 /** The rotated address-level proof returned by the device on success. */\n readonly hmacRest: Uint8Array | null;\n};\n\nexport type EditExternalAddressIdentifierDAReturnType =\n ExecuteDeviceActionReturnType<\n EditExternalAddressIdentifierDAOutput,\n EditExternalAddressIdentifierDAError,\n EditExternalAddressIdentifierDAIntermediateValue\n >;\n"],
|
|
5
|
+
"mappings": "+WAAA,IAAAA,EAAA,kBAAAC,EAAAD",
|
|
6
|
+
"names": ["EditExternalAddressIdentifierDeviceActionTypes_exports", "__toCommonJS"]
|
|
7
|
+
}
|
|
@@ -0,0 +1,2 @@
|
|
|
1
|
+
"use strict";var n=Object.defineProperty;var p=Object.getOwnPropertyDescriptor;var a=Object.getOwnPropertyNames;var i=Object.prototype.hasOwnProperty;var s=(r,e,d,o)=>{if(e&&typeof e=="object"||typeof e=="function")for(let t of a(e))!i.call(r,t)&&t!==d&&n(r,t,{get:()=>e[t],enumerable:!(o=p(e,t))||o.enumerable});return r};var E=r=>s(n({},"__esModule",{value:!0}),r);var A={};module.exports=E(A);
|
|
2
|
+
//# sourceMappingURL=EditExternalAddressScopeDeviceActionTypes.js.map
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
{
|
|
2
|
+
"version": 3,
|
|
3
|
+
"sources": ["../../../../src/api/app-binder/EditExternalAddressScopeDeviceActionTypes.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 EditExternalAddressScopeInput,\n type EditExternalAddressScopeOutput,\n} from \"@api/model/EditExternalAddressScope\";\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 EditExternalAddressScopeDAInput = EditExternalAddressScopeInput & {\n readonly appName: string;\n};\n\nexport type EditExternalAddressScopeDAOutput = EditExternalAddressScopeOutput;\n\nexport type EditExternalAddressScopeDAError =\n | OpenAppDAError\n | ContactsValidationError\n | ContactsVersionRequirementError\n | CommandErrorResult<ContactsErrorCodes>[\"error\"];\n\nexport type EditExternalAddressScopeDARequiredInteraction =\n | OpenAppDARequiredInteraction\n | UserInteractionRequired.RegisterWallet;\n\nexport type EditExternalAddressScopeDAIntermediateValue = {\n readonly requiredUserInteraction: EditExternalAddressScopeDARequiredInteraction;\n};\n\nexport type EditExternalAddressScopeDAState = DeviceActionState<\n EditExternalAddressScopeDAOutput,\n EditExternalAddressScopeDAError,\n EditExternalAddressScopeDAIntermediateValue\n>;\n\nexport type EditExternalAddressScopeDAInternalState = {\n readonly error: EditExternalAddressScopeDAError | 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 /** The rotated address-level proof returned by the device on success. */\n readonly hmacRest: Uint8Array | null;\n};\n\nexport type EditExternalAddressScopeDAReturnType =\n ExecuteDeviceActionReturnType<\n EditExternalAddressScopeDAOutput,\n EditExternalAddressScopeDAError,\n EditExternalAddressScopeDAIntermediateValue\n >;\n"],
|
|
5
|
+
"mappings": "+WAAA,IAAAA,EAAA,kBAAAC,EAAAD",
|
|
6
|
+
"names": ["EditExternalAddressScopeDeviceActionTypes_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 p=Object.defineProperty;var
|
|
1
|
+
"use strict";var p=Object.defineProperty;var o=Object.getOwnPropertyDescriptor;var i=Object.getOwnPropertyNames;var A=Object.prototype.hasOwnProperty;var E=(r,t)=>{for(var d in t)p(r,d,{get:t[d],enumerable:!0})},y=(r,t,d,s)=>{if(t&&typeof t=="object"||typeof t=="function")for(let n of i(t))!A.call(r,n)&&n!==d&&p(r,n,{get:()=>t[n],enumerable:!(s=o(t,n))||s.enumerable});return r};var u=r=>y(p({},"__esModule",{value:!0}),r);var x={};E(x,{CONTACTS_VERSION_REQUIREMENTS:()=>e.CONTACTS_VERSION_REQUIREMENTS,ContactsManagerBuilder:()=>a.ContactsManagerBuilder,ETHEREUM_APP_NAME:()=>e.ETHEREUM_APP_NAME,isContactsSupported:()=>e.isContactsSupported,isVersionAtLeast:()=>e.isVersionAtLeast,resolveContactsVersionRequirements:()=>e.resolveContactsVersionRequirements});module.exports=u(x);var a=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 {\n type RegisterExternalAddressDAError,\n type RegisterExternalAddressDAInput,\n type RegisterExternalAddressDAIntermediateValue,\n type RegisterExternalAddressDAOutput,\n type RegisterExternalAddressDARequiredInteraction,\n type RegisterExternalAddressDAReturnType,\n type RegisterExternalAddressDAState,\n} from \"@api/app-binder/RegisterExternalAddressDeviceActionTypes\";\nexport { type ContactsManager } from \"@api/ContactsManager\";\nexport { ContactsManagerBuilder } from \"@api/ContactsManagerBuilder\";\nexport {\n CONTACTS_VERSION_REQUIREMENTS,\n type ContactsModelRequirement,\n type ContactsModelSupport,\n type ContactsModelUnsupported,\n type ContactsSupportQuery,\n type ContactsVersionRequirements,\n ETHEREUM_APP_NAME,\n isContactsSupported,\n isVersionAtLeast,\n resolveContactsVersionRequirements,\n} from \"@api/model/ContactsVersionRequirements\";\nexport {\n type ExistingContactGroup,\n type RegisterExternalAddressInput,\n type RegisterExternalAddressMode,\n type RegisterExternalAddressOutput,\n} from \"@api/model/RegisterExternalAddress\";\n"],
|
|
5
|
-
"mappings": "yaAAA,IAAAA,EAAA,GAAAC,EAAAD,EAAA,oVAAAE,EAAAF,
|
|
4
|
+
"sourcesContent": ["export {\n type EditExternalAddressIdentifierDAError,\n type EditExternalAddressIdentifierDAInput,\n type EditExternalAddressIdentifierDAIntermediateValue,\n type EditExternalAddressIdentifierDAOutput,\n type EditExternalAddressIdentifierDARequiredInteraction,\n type EditExternalAddressIdentifierDAReturnType,\n type EditExternalAddressIdentifierDAState,\n} from \"@api/app-binder/EditExternalAddressIdentifierDeviceActionTypes\";\nexport {\n type EditExternalAddressScopeDAError,\n type EditExternalAddressScopeDAInput,\n type EditExternalAddressScopeDAIntermediateValue,\n type EditExternalAddressScopeDAOutput,\n type EditExternalAddressScopeDARequiredInteraction,\n type EditExternalAddressScopeDAReturnType,\n type EditExternalAddressScopeDAState,\n} from \"@api/app-binder/EditExternalAddressScopeDeviceActionTypes\";\nexport {\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 EditExternalAddressIdentifierInput,\n type EditExternalAddressIdentifierOutput,\n} from \"@api/model/EditExternalAddressIdentifier\";\nexport {\n type EditExternalAddressScopeInput,\n type EditExternalAddressScopeOutput,\n} from \"@api/model/EditExternalAddressScope\";\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,GAqCA,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 i=Object.defineProperty;var o=Object.getOwnPropertyDescriptor;var d=Object.getOwnPropertyNames;var y=Object.prototype.hasOwnProperty;var l=(n,r,t,a)=>{if(r&&typeof r=="object"||typeof r=="function")for(let e of d(r))!y.call(n,e)&&e!==t&&i(n,e,{get:()=>r[e],enumerable:!(a=o(r,e))||a.enumerable});return n};var s=n=>l(i({},"__esModule",{value:!0}),n);var c={};module.exports=s(c);
|
|
2
|
+
//# sourceMappingURL=EditExternalAddressIdentifier.js.map
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
{
|
|
2
|
+
"version": 3,
|
|
3
|
+
"sources": ["../../../../src/api/model/EditExternalAddressIdentifier.ts"],
|
|
4
|
+
"sourcesContent": ["/**\n * Public input/output types for `ContactsManager.editExternalAddressIdentifier`.\n *\n * EDIT IDENTIFIER replaces an entry's identifier bytes within an existing\n * contact group. Only the address-level `hmacRest` rotates; the group-level\n * `hmacProof` passes through unchanged. Proof material is raw bytes (the host\n * owns persistence); `derivationPath` is kit-internal and not exposed.\n */\n\nexport type EditExternalAddressIdentifierInput = {\n /** The contact's name, proven to the device via `hmacProof`. */\n readonly contactName: string;\n /** The entry's current label/scope; shown on the approval screen. */\n readonly scope: string;\n /** The current (pre-edit) address bytes, proven via `hmacRest`. */\n readonly previousIdentifier: Uint8Array;\n /** The replacement address bytes (20 bytes for Ethereum). */\n readonly newIdentifier: Uint8Array;\n /** Blockchain family name, e.g. \"ethereum\" (v1 supports Ethereum only). */\n readonly blockchainFamily: string;\n readonly chainId?: bigint;\n /** 64-byte group handle returned by the group's Register Identity. */\n readonly groupHandle: Uint8Array;\n /**\n * The contact-group name proof (device `hmac_name`) \u2014 passed back so the\n * device can verify the entry belongs to the group. Unchanged by the edit.\n */\n readonly hmacProof: Uint8Array;\n /**\n * The entry's current 32-byte address proof (`hmac_rest`) \u2014 passed back so the\n * device can verify continuity before approving. Replaced by the returned\n * `hmacRest` on success.\n */\n readonly hmacRest: Uint8Array;\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 EditExternalAddressIdentifierOutput = {\n /** Echoed input, needed by the host to locate the entry it is replacing. */\n readonly contactName: string;\n readonly scope: string;\n /** Echoed previous address bytes, to match the entry being replaced. */\n readonly previousIdentifier: Uint8Array;\n /** The new address bytes now bound to the entry. */\n readonly identifier: Uint8Array;\n readonly blockchainFamily: string;\n readonly chainId?: bigint;\n /** Echoed group handle, unchanged by the edit. */\n readonly groupHandle: Uint8Array;\n /** Echoed group-level name proof, unchanged by the edit. */\n readonly hmacProof: Uint8Array;\n /** The replacement address-level proof (rotated `hmac_rest`) to persist. */\n readonly hmacRest: Uint8Array;\n};\n"],
|
|
5
|
+
"mappings": "+WAAA,IAAAA,EAAA,kBAAAC,EAAAD",
|
|
6
|
+
"names": ["EditExternalAddressIdentifier_exports", "__toCommonJS"]
|
|
7
|
+
}
|
|
@@ -0,0 +1,2 @@
|
|
|
1
|
+
"use strict";var o=Object.defineProperty;var t=Object.getOwnPropertyDescriptor;var d=Object.getOwnPropertyNames;var y=Object.prototype.hasOwnProperty;var l=(n,r,i,a)=>{if(r&&typeof r=="object"||typeof r=="function")for(let e of d(r))!y.call(n,e)&&e!==i&&o(n,e,{get:()=>r[e],enumerable:!(a=t(r,e))||a.enumerable});return n};var c=n=>l(o({},"__esModule",{value:!0}),n);var p={};module.exports=c(p);
|
|
2
|
+
//# sourceMappingURL=EditExternalAddressScope.js.map
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
{
|
|
2
|
+
"version": 3,
|
|
3
|
+
"sources": ["../../../../src/api/model/EditExternalAddressScope.ts"],
|
|
4
|
+
"sourcesContent": ["/**\n * Public input/output types for `ContactsManager.editExternalAddressScope`.\n *\n * EDIT SCOPE replaces an entry's scope (its context label) within an existing\n * contact group while keeping the same contact name and identifier. Only the\n * address-level `hmacRest` rotates; the group-level `hmacProof` passes through\n * unchanged. Proof material is raw bytes (the host owns persistence);\n * `derivationPath` is kit-internal and not exposed.\n */\n\nexport type EditExternalAddressScopeInput = {\n /** The contact's name, proven to the device via `hmacProof`. Unchanged. */\n readonly contactName: string;\n /** The entry's current scope; shown on the approval screen and proven via `hmacRest`. */\n readonly previousScope: string;\n /** The replacement scope (max 32 printable ASCII chars). */\n readonly newScope: string;\n /** The entry's identifier bytes (20 bytes for Ethereum). Unchanged by the edit. */\n readonly identifier: Uint8Array;\n /** Blockchain family name, e.g. \"ethereum\" (v1 supports Ethereum only). */\n readonly blockchainFamily: string;\n readonly chainId?: bigint;\n /** 64-byte group handle returned by the group's Register Identity. */\n readonly groupHandle: Uint8Array;\n /**\n * The contact-group name proof (device `hmac_name`) \u2014 passed back so the\n * device can verify the entry belongs to the group. Unchanged by the edit.\n */\n readonly hmacProof: Uint8Array;\n /**\n * The entry's current 32-byte address proof (`hmac_rest`) \u2014 passed back so the\n * device can verify the previous scope/identifier before approving. Replaced\n * by the returned `hmacRest` on success.\n */\n readonly hmacRest: Uint8Array;\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 EditExternalAddressScopeOutput = {\n /** Echoed input, needed by the host to locate the entry it is replacing. */\n readonly contactName: string;\n /** Echoed previous scope, to match the entry being replaced. */\n readonly previousScope: string;\n /** The new scope now bound to the entry. */\n readonly scope: string;\n /** Echoed identifier bytes, unchanged by the edit. */\n readonly identifier: Uint8Array;\n readonly blockchainFamily: string;\n readonly chainId?: bigint;\n /** Echoed group handle, unchanged by the edit. */\n readonly groupHandle: Uint8Array;\n /** Echoed group-level name proof, unchanged by the edit. */\n readonly hmacProof: Uint8Array;\n /** The replacement address-level proof (rotated `hmac_rest`) to persist. */\n readonly hmacRest: Uint8Array;\n};\n"],
|
|
5
|
+
"mappings": "+WAAA,IAAAA,EAAA,kBAAAC,EAAAD",
|
|
6
|
+
"names": ["EditExternalAddressScope_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 i=Object.defineProperty;var d=Object.getOwnPropertyDescriptor;var p=Object.getOwnPropertyNames;var m=Object.prototype.hasOwnProperty;var c=(t,e)=>{for(var r in e)i(t,r,{get:e[r],enumerable:!0})},E=(t,e,r,a)=>{if(e&&typeof e=="object"||typeof e=="function")for(let n of p(e))!m.call(t,n)&&n!==r&&i(t,n,{get:()=>e[n],enumerable:!(a=d(e,n))||a.enumerable});return t};var A=t=>E(i({},"__esModule",{value:!0}),t);var C={};c(C,{DefaultContactsManager:()=>u});module.exports=A(C);var o=require("./di"),s=require("./use-cases/di/useCaseTypes");class u{_container;constructor({dmk:e,sessionId:r,appName:a}){this._container=(0,o.makeContainer)({dmk:e,sessionId:r,appName:a})}registerExternalAddress(e){return this._container.get(s.useCaseTypes.RegisterExternalAddressUseCase).execute(e)}renameContact(e){return this._container.get(s.useCaseTypes.RenameContactUseCase).execute(e)}editExternalAddressIdentifier(e){return this._container.get(s.useCaseTypes.EditExternalAddressIdentifierUseCase).execute(e)}editExternalAddressScope(e){return this._container.get(s.useCaseTypes.EditExternalAddressScopeUseCase).execute(e)}get container(){return this._container}}0&&(module.exports={DefaultContactsManager});
|
|
2
2
|
//# sourceMappingURL=DefaultContactsManager.js.map
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"version": 3,
|
|
3
3
|
"sources": ["../../../src/internal/DefaultContactsManager.ts"],
|
|
4
|
-
"sourcesContent": ["import {\n type DeviceManagementKit,\n type DeviceSessionId,\n} from \"@ledgerhq/device-management-kit\";\nimport { type Container } from \"inversify\";\n\nimport { type RegisterExternalAddressDAReturnType } from \"@api/app-binder/RegisterExternalAddressDeviceActionTypes\";\nimport { type ContactsManager } from \"@api/ContactsManager\";\nimport { type RegisterExternalAddressInput } from \"@api/model/RegisterExternalAddress\";\nimport { makeContainer } from \"@internal/di\";\nimport { useCaseTypes } from \"@internal/use-cases/di/useCaseTypes\";\nimport { type RegisterExternalAddressUseCase } from \"@internal/use-cases/RegisterExternalAddressUseCase\";\n\ntype DefaultContactsManagerConstructorArgs = {\n dmk: DeviceManagementKit;\n sessionId: DeviceSessionId;\n appName: string;\n};\n\nexport class DefaultContactsManager implements ContactsManager {\n private readonly _container: Container;\n\n constructor({\n dmk,\n sessionId,\n appName,\n }: DefaultContactsManagerConstructorArgs) {\n this._container = makeContainer({ dmk, sessionId, appName });\n }\n\n registerExternalAddress(\n input: RegisterExternalAddressInput,\n ): RegisterExternalAddressDAReturnType {\n return this._container\n .get<RegisterExternalAddressUseCase>(\n useCaseTypes.RegisterExternalAddressUseCase,\n )\n .execute(input);\n }\n\n /**\n * Exposes the DI container so future operation methods can resolve their\n * `UseCase`. Not part of the public API.\n */\n protected get container(): Container {\n return this._container;\n }\n}\n"],
|
|
5
|
-
"mappings": "yaAAA,IAAAA,EAAA,GAAAC,EAAAD,EAAA,4BAAAE,IAAA,eAAAC,EAAAH,
|
|
4
|
+
"sourcesContent": ["import {\n type DeviceManagementKit,\n type DeviceSessionId,\n} from \"@ledgerhq/device-management-kit\";\nimport { type Container } from \"inversify\";\n\nimport { type EditExternalAddressIdentifierDAReturnType } from \"@api/app-binder/EditExternalAddressIdentifierDeviceActionTypes\";\nimport { type EditExternalAddressScopeDAReturnType } from \"@api/app-binder/EditExternalAddressScopeDeviceActionTypes\";\nimport { type RegisterExternalAddressDAReturnType } from \"@api/app-binder/RegisterExternalAddressDeviceActionTypes\";\nimport { type RenameContactDAReturnType } from \"@api/app-binder/RenameContactDeviceActionTypes\";\nimport { type ContactsManager } from \"@api/ContactsManager\";\nimport { type EditExternalAddressIdentifierInput } from \"@api/model/EditExternalAddressIdentifier\";\nimport { type EditExternalAddressScopeInput } from \"@api/model/EditExternalAddressScope\";\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 EditExternalAddressIdentifierUseCase } from \"@internal/use-cases/EditExternalAddressIdentifierUseCase\";\nimport { type EditExternalAddressScopeUseCase } from \"@internal/use-cases/EditExternalAddressScopeUseCase\";\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 editExternalAddressIdentifier(\n input: EditExternalAddressIdentifierInput,\n ): EditExternalAddressIdentifierDAReturnType {\n return this._container\n .get<EditExternalAddressIdentifierUseCase>(\n useCaseTypes.EditExternalAddressIdentifierUseCase,\n )\n .execute(input);\n }\n\n editExternalAddressScope(\n input: EditExternalAddressScopeInput,\n ): EditExternalAddressScopeDAReturnType {\n return this._container\n .get<EditExternalAddressScopeUseCase>(\n useCaseTypes.EditExternalAddressScopeUseCase,\n )\n .execute(input);\n }\n\n /**\n * Exposes the DI container so future operation methods can resolve their\n * `UseCase`. Not part of the public API.\n */\n protected get container(): Container {\n return this._container;\n }\n}\n"],
|
|
5
|
+
"mappings": "yaAAA,IAAAA,EAAA,GAAAC,EAAAD,EAAA,4BAAAE,IAAA,eAAAC,EAAAH,GAeA,IAAAI,EAA8B,wBAC9BC,EAA6B,+CAYtB,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,CAEA,8BACEA,EAC2C,CAC3C,OAAO,KAAK,WACT,IACC,eAAa,oCACf,EACC,QAAQA,CAAK,CAClB,CAEA,yBACEA,EACsC,CACtC,OAAO,KAAK,WACT,IACC,eAAa,+BACf,EACC,QAAQA,CAAK,CAClB,CAMA,IAAc,WAAuB,CACnC,OAAO,KAAK,UACd,CACF",
|
|
6
6
|
"names": ["DefaultContactsManager_exports", "__export", "DefaultContactsManager", "__toCommonJS", "import_di", "import_useCaseTypes", "dmk", "sessionId", "appName", "input"]
|
|
7
7
|
}
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
"use strict";var
|
|
1
|
+
"use strict";var s=require("./DefaultContactsManager");const c={contactName:"Alice",scope:"Eth main",identifier:new Uint8Array(20).fill(17),blockchainFamily:"ethereum",chainId:1n},o={previousContactName:"Alice",newContactName:"Bob",groupHandle:new Uint8Array(64).fill(204),hmacProof:new Uint8Array(32).fill(221)},r={contactName:"Alice",scope:"Eth main",previousIdentifier:new Uint8Array(20).fill(17),newIdentifier:new Uint8Array(20).fill(34),blockchainFamily:"ethereum",chainId:1n,groupHandle:new Uint8Array(64).fill(204),hmacProof:new Uint8Array(32).fill(221),hmacRest:new Uint8Array(32).fill(170)},d={contactName:"Alice",previousScope:"Eth main",newScope:"Eth cold",identifier:new Uint8Array(20).fill(17),blockchainFamily:"ethereum",chainId:1n,groupHandle:new Uint8Array(64).fill(204),hmacProof:new Uint8Array(32).fill(221),hmacRest:new Uint8Array(32).fill(170)};describe("DefaultContactsManager",()=>{it("registerExternalAddress flows manager -> use-case -> binder -> dmk.executeDeviceAction",()=>{const e=vi.fn().mockReturnValue("DA_RETURN"),t={executeDeviceAction:e},i=new s.DefaultContactsManager({dmk:t,sessionId:"session-id",appName:"Ethereum"}).registerExternalAddress(c);expect(e).toHaveBeenCalledTimes(1);const n=e.mock.calls[0][0];expect(n.sessionId).toBe("session-id"),expect(n.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"),t={executeDeviceAction:e},a=new s.DefaultContactsManager({dmk:t,sessionId:"session-id",appName:"Ethereum"});expect(()=>a.registerExternalAddress({...c,contactName:""})).not.toThrow(),expect(e).toHaveBeenCalledTimes(1)}),it("renameContact flows manager -> use-case -> binder -> dmk.executeDeviceAction",()=>{const e=vi.fn().mockReturnValue("DA_RETURN"),t={executeDeviceAction:e},i=new s.DefaultContactsManager({dmk:t,sessionId:"session-id",appName:"Ethereum"}).renameContact(o);expect(e).toHaveBeenCalledTimes(1);const n=e.mock.calls[0][0];expect(n.sessionId).toBe("session-id"),expect(n.deviceAction).toBeDefined(),expect(i).toBe("DA_RETURN")}),it("editExternalAddressIdentifier flows manager -> use-case -> binder -> dmk.executeDeviceAction",()=>{const e=vi.fn().mockReturnValue("DA_RETURN"),t={executeDeviceAction:e},i=new s.DefaultContactsManager({dmk:t,sessionId:"session-id",appName:"Ethereum"}).editExternalAddressIdentifier(r);expect(e).toHaveBeenCalledTimes(1);const n=e.mock.calls[0][0];expect(n.sessionId).toBe("session-id"),expect(n.deviceAction).toBeDefined(),expect(i).toBe("DA_RETURN")}),it("editExternalAddressScope flows manager -> use-case -> binder -> dmk.executeDeviceAction",()=>{const e=vi.fn().mockReturnValue("DA_RETURN"),t={executeDeviceAction:e},i=new s.DefaultContactsManager({dmk:t,sessionId:"session-id",appName:"Ethereum"}).editExternalAddressScope(d);expect(e).toHaveBeenCalledTimes(1);const n=e.mock.calls[0][0];expect(n.sessionId).toBe("session-id"),expect(n.deviceAction).toBeDefined(),expect(i).toBe("DA_RETURN")})});
|
|
2
2
|
//# sourceMappingURL=DefaultContactsManager.test.js.map
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"version": 3,
|
|
3
3
|
"sources": ["../../../src/internal/DefaultContactsManager.test.ts"],
|
|
4
|
-
"sourcesContent": ["import { type DeviceManagementKit } from \"@ledgerhq/device-management-kit\";\n\nimport { type RegisterExternalAddressInput } from \"@api/model/RegisterExternalAddress\";\n\nimport { DefaultContactsManager } from \"./DefaultContactsManager\";\n\nconst VALID_INPUT: RegisterExternalAddressInput = {\n contactName: \"Alice\",\n scope: \"Eth main\",\n identifier: new Uint8Array(20).fill(0x11),\n blockchainFamily: \"ethereum\",\n chainId: 1n,\n};\n\ndescribe(\"DefaultContactsManager\", () => {\n it(\"registerExternalAddress flows manager -> use-case -> binder -> dmk.executeDeviceAction\", () => {\n const executeDeviceAction = vi.fn().mockReturnValue(\"DA_RETURN\");\n const dmk = { executeDeviceAction } as unknown as DeviceManagementKit;\n\n const manager = new DefaultContactsManager({\n dmk,\n sessionId: \"session-id\",\n appName: \"Ethereum\",\n });\n\n const result = manager.registerExternalAddress(VALID_INPUT);\n\n expect(executeDeviceAction).toHaveBeenCalledTimes(1);\n const call = executeDeviceAction.mock.calls[0]![0] as {\n sessionId: string;\n deviceAction: unknown;\n };\n expect(call.sessionId).toBe(\"session-id\");\n expect(call.deviceAction).toBeDefined();\n expect(result).toBe(\"DA_RETURN\");\n });\n\n it(\"does not throw on invalid input \u2014 it dispatches the device action, which surfaces the error\", () => {\n // The public API returns a device action; invalid caller input must reach\n // the observable as a typed error state rather than throwing synchronously.\n const executeDeviceAction = vi.fn().mockReturnValue(\"DA_RETURN\");\n const dmk = { executeDeviceAction } as unknown as DeviceManagementKit;\n\n const manager = new DefaultContactsManager({\n dmk,\n sessionId: \"session-id\",\n appName: \"Ethereum\",\n });\n\n expect(() =>\n manager.registerExternalAddress({\n ...VALID_INPUT,\n contactName: \"\",\n }),\n ).not.toThrow();\n expect(executeDeviceAction).toHaveBeenCalledTimes(1);\n });\n});\n"],
|
|
5
|
-
"mappings": "
|
|
6
|
-
"names": ["import_DefaultContactsManager", "VALID_INPUT", "executeDeviceAction", "dmk", "result", "call", "manager"]
|
|
4
|
+
"sourcesContent": ["import { type DeviceManagementKit } from \"@ledgerhq/device-management-kit\";\n\nimport { type EditExternalAddressIdentifierInput } from \"@api/model/EditExternalAddressIdentifier\";\nimport { type EditExternalAddressScopeInput } from \"@api/model/EditExternalAddressScope\";\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\nconst VALID_EDIT_INPUT: EditExternalAddressIdentifierInput = {\n contactName: \"Alice\",\n scope: \"Eth main\",\n previousIdentifier: new Uint8Array(20).fill(0x11),\n newIdentifier: new Uint8Array(20).fill(0x22),\n blockchainFamily: \"ethereum\",\n chainId: 1n,\n groupHandle: new Uint8Array(64).fill(0xcc),\n hmacProof: new Uint8Array(32).fill(0xdd),\n hmacRest: new Uint8Array(32).fill(0xaa),\n};\n\nconst VALID_EDIT_SCOPE_INPUT: EditExternalAddressScopeInput = {\n contactName: \"Alice\",\n previousScope: \"Eth main\",\n newScope: \"Eth cold\",\n identifier: new Uint8Array(20).fill(0x11),\n blockchainFamily: \"ethereum\",\n chainId: 1n,\n groupHandle: new Uint8Array(64).fill(0xcc),\n hmacProof: new Uint8Array(32).fill(0xdd),\n hmacRest: new Uint8Array(32).fill(0xaa),\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 it(\"editExternalAddressIdentifier 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.editExternalAddressIdentifier(VALID_EDIT_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(\"editExternalAddressScope 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.editExternalAddressScope(VALID_EDIT_SCOPE_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": "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",
|
|
6
|
+
"names": ["import_DefaultContactsManager", "VALID_INPUT", "VALID_RENAME_INPUT", "VALID_EDIT_INPUT", "VALID_EDIT_SCOPE_INPUT", "executeDeviceAction", "dmk", "result", "call", "manager"]
|
|
7
7
|
}
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
"use strict";var
|
|
1
|
+
"use strict";var o=Object.defineProperty;var A=Object.getOwnPropertyDescriptor;var y=Object.getOwnPropertyNames;var f=Object.prototype.hasOwnProperty;var D=(t,e)=>{for(var i in e)o(t,i,{get:e[i],enumerable:!0})},R=(t,e,i,n)=>{if(e&&typeof e=="object"||typeof e=="function")for(let r of y(e))!f.call(t,r)&&r!==i&&o(t,r,{get:()=>e[r],enumerable:!(n=A(e,r))||n.enumerable});return t};var v=t=>R(o({},"__esModule",{value:!0}),t),u=(t,e,i,n)=>{for(var r=n>1?void 0:n?A(e,i):e,m=t.length-1,c;m>=0;m--)(c=t[m])&&(r=(n?c(e,i,r):c(r))||r);return n&&r&&o(e,i,r),r},p=(t,e)=>(i,n)=>e(i,n,t);var h={};D(h,{ContactsAppBinder:()=>d});module.exports=v(h);var s=require("inversify"),E=require("../app-binder/device-action/EditExternalAddressIdentifier/EditExternalAddressIdentifierDeviceAction"),I=require("../app-binder/device-action/EditExternalAddressScope/EditExternalAddressScopeDeviceAction"),l=require("../app-binder/device-action/RegisterExternalAddress/RegisterExternalAddressDeviceAction"),x=require("../app-binder/device-action/RenameContact/RenameContactDeviceAction"),a=require("../externalTypes");let d=class{constructor(e,i,n){this.dmk=e;this.sessionId=i;this.appName=n}registerExternalAddress(e){return this.dmk.executeDeviceAction({sessionId:this.sessionId,deviceAction:new l.RegisterExternalAddressDeviceAction({input:{...e,appName:this.appName}})})}renameContact(e){return this.dmk.executeDeviceAction({sessionId:this.sessionId,deviceAction:new x.RenameContactDeviceAction({input:e})})}editExternalAddressIdentifier(e){return this.dmk.executeDeviceAction({sessionId:this.sessionId,deviceAction:new E.EditExternalAddressIdentifierDeviceAction({input:{...e,appName:this.appName}})})}editExternalAddressScope(e){return this.dmk.executeDeviceAction({sessionId:this.sessionId,deviceAction:new I.EditExternalAddressScopeDeviceAction({input:{...e,appName:this.appName}})})}};d=u([(0,s.injectable)(),p(0,(0,s.inject)(a.externalTypes.Dmk)),p(1,(0,s.inject)(a.externalTypes.SessionId)),p(2,(0,s.inject)(a.externalTypes.AppName))],d);0&&(module.exports={ContactsAppBinder});
|
|
2
2
|
//# sourceMappingURL=ContactsAppBinder.js.map
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"version": 3,
|
|
3
3
|
"sources": ["../../../../src/internal/app-binder/ContactsAppBinder.ts"],
|
|
4
|
-
"sourcesContent": ["import {\n type DeviceManagementKit,\n type DeviceSessionId,\n} from \"@ledgerhq/device-management-kit\";\nimport { inject, injectable } from \"inversify\";\n\nimport { type RegisterExternalAddressDAReturnType } from \"@api/app-binder/RegisterExternalAddressDeviceActionTypes\";\nimport { type RegisterExternalAddressInput } from \"@api/model/RegisterExternalAddress\";\nimport { RegisterExternalAddressDeviceAction } from \"@internal/app-binder/device-action/RegisterExternalAddress/RegisterExternalAddressDeviceAction\";\nimport { externalTypes } from \"@internal/externalTypes\";\n\n/**\n * Constructs and executes Contacts `DeviceAction`s using the injected `dmk`,\n * `sessionId`, and `appName`. Each Address Book operation gets one method here.\n */\n@injectable()\nexport class ContactsAppBinder {\n constructor(\n @inject(externalTypes.Dmk)\n protected readonly dmk: DeviceManagementKit,\n @inject(externalTypes.SessionId)\n protected readonly sessionId: DeviceSessionId,\n @inject(externalTypes.AppName)\n protected readonly appName: string,\n ) {}\n\n registerExternalAddress(\n input: RegisterExternalAddressInput,\n ): RegisterExternalAddressDAReturnType {\n return this.dmk.executeDeviceAction({\n sessionId: this.sessionId,\n deviceAction: new RegisterExternalAddressDeviceAction({\n input: { ...input, appName: this.appName },\n }),\n });\n }\n}\n"],
|
|
5
|
-
"mappings": "okBAAA,IAAAA,EAAA,GAAAC,EAAAD,EAAA,uBAAAE,IAAA,eAAAC,EAAAH,GAIA,IAAAI,EAAmC,
|
|
6
|
-
"names": ["ContactsAppBinder_exports", "__export", "ContactsAppBinder", "__toCommonJS", "import_inversify", "import_RegisterExternalAddressDeviceAction", "import_externalTypes", "ContactsAppBinder", "dmk", "sessionId", "appName", "input", "__decorateClass", "__decorateParam"]
|
|
4
|
+
"sourcesContent": ["import {\n type DeviceManagementKit,\n type DeviceSessionId,\n} from \"@ledgerhq/device-management-kit\";\nimport { inject, injectable } from \"inversify\";\n\nimport { type EditExternalAddressIdentifierDAReturnType } from \"@api/app-binder/EditExternalAddressIdentifierDeviceActionTypes\";\nimport { type EditExternalAddressScopeDAReturnType } from \"@api/app-binder/EditExternalAddressScopeDeviceActionTypes\";\nimport { type RegisterExternalAddressDAReturnType } from \"@api/app-binder/RegisterExternalAddressDeviceActionTypes\";\nimport { type RenameContactDAReturnType } from \"@api/app-binder/RenameContactDeviceActionTypes\";\nimport { type EditExternalAddressIdentifierInput } from \"@api/model/EditExternalAddressIdentifier\";\nimport { type EditExternalAddressScopeInput } from \"@api/model/EditExternalAddressScope\";\nimport { type RegisterExternalAddressInput } from \"@api/model/RegisterExternalAddress\";\nimport { type RenameContactInput } from \"@api/model/RenameContact\";\nimport { EditExternalAddressIdentifierDeviceAction } from \"@internal/app-binder/device-action/EditExternalAddressIdentifier/EditExternalAddressIdentifierDeviceAction\";\nimport { EditExternalAddressScopeDeviceAction } from \"@internal/app-binder/device-action/EditExternalAddressScope/EditExternalAddressScopeDeviceAction\";\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 editExternalAddressIdentifier(\n input: EditExternalAddressIdentifierInput,\n ): EditExternalAddressIdentifierDAReturnType {\n return this.dmk.executeDeviceAction({\n sessionId: this.sessionId,\n deviceAction: new EditExternalAddressIdentifierDeviceAction({\n input: { ...input, appName: this.appName },\n }),\n });\n }\n\n editExternalAddressScope(\n input: EditExternalAddressScopeInput,\n ): EditExternalAddressScopeDAReturnType {\n return this.dmk.executeDeviceAction({\n sessionId: this.sessionId,\n deviceAction: new EditExternalAddressScopeDeviceAction({\n input: { ...input, appName: this.appName },\n }),\n });\n }\n}\n"],
|
|
5
|
+
"mappings": "okBAAA,IAAAA,EAAA,GAAAC,EAAAD,EAAA,uBAAAE,IAAA,eAAAC,EAAAH,GAIA,IAAAI,EAAmC,qBAUnCC,EAA0D,sHAC1DC,EAAqD,4GACrDC,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,CAEA,8BACEA,EAC2C,CAC3C,OAAO,KAAK,IAAI,oBAAoB,CAClC,UAAW,KAAK,UAChB,aAAc,IAAI,4CAA0C,CAC1D,MAAO,CAAE,GAAGA,EAAO,QAAS,KAAK,OAAQ,CAC3C,CAAC,CACH,CAAC,CACH,CAEA,yBACEA,EACsC,CACtC,OAAO,KAAK,IAAI,oBAAoB,CAClC,UAAW,KAAK,UAChB,aAAc,IAAI,uCAAqC,CACrD,MAAO,CAAE,GAAGA,EAAO,QAAS,KAAK,OAAQ,CAC3C,CAAC,CACH,CAAC,CACH,CACF,EAnDaJ,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_EditExternalAddressIdentifierDeviceAction", "import_EditExternalAddressScopeDeviceAction", "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 u=Object.getOwnPropertyDescriptor;var C=Object.getOwnPropertyNames;var A=Object.prototype.hasOwnProperty;var f=(d,r)=>{for(var t in r)i(d,t,{get:r[t],enumerable:!0})},c=(d,r,t,a)=>{if(r&&typeof r=="object"||typeof r=="function")for(let n of C(r))!A.call(d,n)&&n!==t&&i(d,n,{get:()=>r[n],enumerable:!(a=u(r,n))||a.enumerable});return d};var y=d=>c(i({},"__esModule",{value:!0}),d);var T={};f(T,{EditExternalAddressIdentifierCommand:()=>R});module.exports=y(T);var e=require("@ledgerhq/device-management-kit"),p=require("@ledgerhq/signer-utils"),E=require("purify-ts"),o=require("../../app-binder/model/contactsConstants"),s=require("../../app-binder/model/contactsErrors"),l=require("../../app-binder/services/contactsTlvSerializer");const m=l.STRUCT_TYPE_EDIT_IDENTIFIER;function I(d,r){const t=d.extractFieldByLength(r);if(!(!t||t.length!==r))return Uint8Array.from(t)}class R{name="editExternalAddressIdentifier";args;errorHelper=new p.CommandErrorHelper(s.CONTACTS_APP_ERRORS,s.contactsCommandErrorFactory);constructor(r){this.args=r}getApdu(){return new e.ApduBuilder({cla:o.CONTACTS_APDU_CLA,ins:o.CONTACTS_APDU_INS,p1:o.SUB_CMD_EDIT_IDENTIFIER,p2:this.args.p2}).addBufferToData(this.args.data).build()}parseResponse(r){return E.Maybe.fromNullable(this.errorHelper.getError(r)).orDefaultLazy(()=>{if(r.data.length===0)return(0,e.CommandResultFactory)({data:{}});const t=new e.ApduParser(r),a=t.extract8BitUInt();if(a!==m)return(0,e.CommandResultFactory)({error:new e.InvalidStatusWordError(`Expected struct_type 0x${m.toString(16)}, got ${a===void 0?"undefined":`0x${a.toString(16)}`}`)});const n=I(t,o.HMAC_REST_BYTES);return n?(0,e.CommandResultFactory)({data:{hmacRest:n}}):(0,e.CommandResultFactory)({error:new e.InvalidStatusWordError("hmac_rest missing or truncated")})})}}0&&(module.exports={EditExternalAddressIdentifierCommand});
|
|
2
|
+
//# sourceMappingURL=EditExternalAddressIdentifierCommand.js.map
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
{
|
|
2
|
+
"version": 3,
|
|
3
|
+
"sources": ["../../../../../src/internal/app-binder/command/EditExternalAddressIdentifierCommand.ts"],
|
|
4
|
+
"sourcesContent": ["// Edit Identifier \u2014 sub-command P1=0x03 of the address-book APDU (CLA 0xB0 /\n// INS 0x10). Frames one chunk; on the final chunk parses the 33-byte response\n// struct_type(0x31) + hmac_rest(32) (the rotated address-level proof).\n// Intermediate chunks ack SW=0x9000 with no data. SW 0x6982 = seed/handle\n// mismatch, surfaced via the shared error helper before any device UI.\n// Protocol: Address Book Final Specifications \u2014 Edit Identifier.\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 HMAC_REST_BYTES,\n SUB_CMD_EDIT_IDENTIFIER,\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_IDENTIFIER } from \"@internal/app-binder/services/contactsTlvSerializer\";\n\nexport type EditExternalAddressIdentifierCommandArgs = {\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 EditExternalAddressIdentifierCommandResponse = {\n /**\n * Present only on the final chunk \u2014 the device returns struct_type(0x31) +\n * hmac_rest(32) there. Intermediate chunks return SW=0x9000 with no data.\n * This is the replacement address-level proof (rotated `hmac_rest`).\n */\n readonly hmacRest?: Uint8Array;\n};\n\nconst RESPONSE_STRUCT_TYPE = STRUCT_TYPE_EDIT_IDENTIFIER;\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 EditExternalAddressIdentifierCommand\n implements\n Command<\n EditExternalAddressIdentifierCommandResponse,\n EditExternalAddressIdentifierCommandArgs,\n ContactsErrorCodes\n >\n{\n readonly name = \"editExternalAddressIdentifier\";\n readonly args: EditExternalAddressIdentifierCommandArgs;\n private readonly errorHelper = new CommandErrorHelper<\n EditExternalAddressIdentifierCommandResponse,\n ContactsErrorCodes\n >(CONTACTS_APP_ERRORS, contactsCommandErrorFactory);\n\n constructor(args: EditExternalAddressIdentifierCommandArgs) {\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_EDIT_IDENTIFIER,\n p2: this.args.p2,\n })\n .addBufferToData(this.args.data)\n .build();\n }\n\n parseResponse(\n response: ApduResponse,\n ): CommandResult<\n EditExternalAddressIdentifierCommandResponse,\n ContactsErrorCodes\n > {\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 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: { hmacRest },\n });\n });\n }\n}\n"],
|
|
5
|
+
"mappings": "yaAAA,IAAAA,EAAA,GAAAC,EAAAD,EAAA,0CAAAE,IAAA,eAAAC,EAAAH,GAMA,IAAAI,EASO,2CACPC,EAAmC,kCACnCC,EAAsB,qBAEtBC,EAKO,wDACPC,EAIO,qDACPC,EAA4C,+DAkB5C,MAAMC,EAAuB,8BAO7B,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,gCACP,KACQ,YAAc,IAAI,qBAGjC,sBAAqB,6BAA2B,EAElD,YAAYa,EAAgD,CAC1D,KAAK,KAAOA,CACd,CAEA,SAAgB,CACd,OAAO,IAAI,cAAY,CACrB,IAAK,oBACL,IAAK,oBACL,GAAI,0BACJ,GAAI,KAAK,KAAK,EAChB,CAAC,EACE,gBAAgB,KAAK,KAAK,IAAI,EAC9B,MAAM,CACX,CAEA,cACEC,EAIA,CACA,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,EAAWP,EAAaC,EAAQ,iBAAe,EACrD,OAAKM,KAME,wBAAqB,CAC1B,KAAM,CAAE,SAAAA,CAAS,CACnB,CAAC,KAPQ,wBAAqB,CAC1B,MAAO,IAAI,yBAAuB,gCAAgC,CACpE,CAAC,CAML,CAAC,CACH,CACF",
|
|
6
|
+
"names": ["EditExternalAddressIdentifierCommand_exports", "__export", "EditExternalAddressIdentifierCommand", "__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", "hmacRest"]
|
|
7
|
+
}
|
|
@@ -0,0 +1,2 @@
|
|
|
1
|
+
"use strict";var a=require("@ledgerhq/device-management-kit"),n=require("../../app-binder/model/contactsErrors"),o=require("./EditExternalAddressIdentifierCommand");function d(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 m=d("88".repeat(32)),c="31"+"88".repeat(32);function s(e){return{data:Buffer.from(d(e)),statusCode:Buffer.from([144,0])}}describe("EditExternalAddressIdentifierCommand",()=>{describe("getApdu",()=>{it("wraps the framed chunk under B0 10 03 with P2=0x00 for the first/only chunk",()=>{const e=Uint8Array.from([0,3,170,187,204]),t=new o.EditExternalAddressIdentifierCommand({data:e,p2:0}).getApdu();expect(t.getRawApdu()).toStrictEqual(Uint8Array.from([176,16,3,0,5,0,3,170,187,204]))}),it("uses P2=0x80 for continuation chunks",()=>{const e=Uint8Array.from([170,187]),t=new o.EditExternalAddressIdentifierCommand({data:e,p2:128}).getApdu();expect(t.getRawApdu()).toStrictEqual(Uint8Array.from([176,16,3,128,2,170,187]))})}),describe("parseResponse",()=>{it("returns an empty payload for an intermediate chunk (SW=0x9000, no data)",()=>{const e=new o.EditExternalAddressIdentifierCommand({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_rest from the final-chunk response",()=>{const t=new o.EditExternalAddressIdentifierCommand({data:new Uint8Array,p2:0}).parseResponse(s(c));expect(t).toStrictEqual({status:a.CommandResultStatus.Success,data:{hmacRest:m}})}),it("returns InvalidStatusWordError when struct_type is wrong",()=>{const e="ee"+c.slice(2),r=new o.EditExternalAddressIdentifierCommand({data:new Uint8Array,p2:0}).parseResponse(s(e));expect(r.status).toBe(a.CommandResultStatus.Error)}),it("returns InvalidStatusWordError when hmac_rest is truncated",()=>{const e="31"+"88".repeat(16),r=new o.EditExternalAddressIdentifierCommand({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.EditExternalAddressIdentifierCommand({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.EditExternalAddressIdentifierCommand({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=EditExternalAddressIdentifierCommand.test.js.map
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
{
|
|
2
|
+
"version": 3,
|
|
3
|
+
"sources": ["../../../../../src/internal/app-binder/command/EditExternalAddressIdentifierCommand.test.ts"],
|
|
4
|
+
"sourcesContent": ["// Thin chunk-framer: wraps a pre-framed chunk under B0 10 03 <P2> and parses\n// the 33-byte edit response (struct_type 0x31 + hmac_rest) on the final chunk.\n// TLV byte-parity is asserted in SendEditExternalAddressIdentifierTask.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 { EditExternalAddressIdentifierCommand } from \"./EditExternalAddressIdentifierCommand\";\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(0x31) + rotated hmac_rest(32).\nconst HMAC_REST = hexToBytes(\"88\".repeat(32));\nconst RESPONSE_HEX = \"31\" + \"88\".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(\"EditExternalAddressIdentifierCommand\", () => {\n describe(\"getApdu\", () => {\n it(\"wraps the framed chunk under B0 10 03 with P2=0x00 for the first/only chunk\", () => {\n const data = Uint8Array.from([0x00, 0x03, 0xaa, 0xbb, 0xcc]);\n\n const apdu = new EditExternalAddressIdentifierCommand({\n data,\n p2: 0x00,\n }).getApdu();\n\n expect(apdu.getRawApdu()).toStrictEqual(\n Uint8Array.from([\n 0xb0, 0x10, 0x03, 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 EditExternalAddressIdentifierCommand({\n data,\n p2: 0x80,\n }).getApdu();\n\n expect(apdu.getRawApdu()).toStrictEqual(\n Uint8Array.from([0xb0, 0x10, 0x03, 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 EditExternalAddressIdentifierCommand({\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_rest from the final-chunk response\", () => {\n const command = new EditExternalAddressIdentifierCommand({\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: { hmacRest: HMAC_REST },\n });\n });\n\n it(\"returns InvalidStatusWordError when struct_type is wrong\", () => {\n const wrongType = \"ee\" + RESPONSE_HEX.slice(2); // replace 0x31 with 0xee\n const command = new EditExternalAddressIdentifierCommand({\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_rest is truncated\", () => {\n const truncated = \"31\" + \"88\".repeat(16); // only 16 of 32 bytes\n const command = new EditExternalAddressIdentifierCommand({\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 EditExternalAddressIdentifierCommand({\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 returns 0x6982 when the seed-bound HMAC / group-handle\n // verification fails \u2014 i.e. the entry was registered with another seed.\n const command = new EditExternalAddressIdentifierCommand({\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_EditExternalAddressIdentifierCommand", "hexToBytes", "hex", "out", "i", "HMAC_REST", "RESPONSE_HEX", "makeResponse", "data", "apdu", "result", "wrongType", "truncated"]
|
|
7
|
+
}
|
|
@@ -0,0 +1,2 @@
|
|
|
1
|
+
"use strict";var m=Object.defineProperty;var C=Object.getOwnPropertyDescriptor;var l=Object.getOwnPropertyNames;var u=Object.prototype.hasOwnProperty;var A=(o,r)=>{for(var t in r)m(o,t,{get:r[t],enumerable:!0})},S=(o,r,t,a)=>{if(r&&typeof r=="object"||typeof r=="function")for(let d of l(r))!u.call(o,d)&&d!==t&&m(o,d,{get:()=>r[d],enumerable:!(a=C(r,d))||a.enumerable});return o};var y=o=>S(m({},"__esModule",{value:!0}),o);var R={};A(R,{EditExternalAddressScopeCommand:()=>x});module.exports=y(R);var e=require("@ledgerhq/device-management-kit"),i=require("@ledgerhq/signer-utils"),E=require("purify-ts"),n=require("../../app-binder/model/contactsConstants"),s=require("../../app-binder/model/contactsErrors"),c=require("../../app-binder/services/contactsTlvSerializer");const p=c.STRUCT_TYPE_EDIT_SCOPE;function f(o,r){const t=o.extractFieldByLength(r);if(!(!t||t.length!==r))return Uint8Array.from(t)}class x{name="editExternalAddressScope";args;errorHelper=new i.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_EDIT_SCOPE,p2:this.args.p2}).addBufferToData(this.args.data).build()}parseResponse(r){return E.Maybe.fromNullable(this.errorHelper.getError(r)).orDefaultLazy(()=>{if(r.data.length===0)return(0,e.CommandResultFactory)({data:{}});const t=new e.ApduParser(r),a=t.extract8BitUInt();if(a!==p)return(0,e.CommandResultFactory)({error:new e.InvalidStatusWordError(`Expected struct_type 0x${p.toString(16)}, got ${a===void 0?"undefined":`0x${a.toString(16)}`}`)});const d=f(t,n.HMAC_REST_BYTES);return d?(0,e.CommandResultFactory)({data:{hmacRest:d}}):(0,e.CommandResultFactory)({error:new e.InvalidStatusWordError("hmac_rest missing or truncated")})})}}0&&(module.exports={EditExternalAddressScopeCommand});
|
|
2
|
+
//# sourceMappingURL=EditExternalAddressScopeCommand.js.map
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
{
|
|
2
|
+
"version": 3,
|
|
3
|
+
"sources": ["../../../../../src/internal/app-binder/command/EditExternalAddressScopeCommand.ts"],
|
|
4
|
+
"sourcesContent": ["// Edit Scope \u2014 sub-command P1=0x04 of the address-book APDU (CLA 0xB0 /\n// INS 0x10). Frames one chunk; on the final chunk parses the 33-byte response\n// struct_type(0x32) + hmac_rest(32) (the rotated address-level proof).\n// Intermediate chunks ack SW=0x9000 with no data. SW 0x6982 = seed/handle\n// mismatch, surfaced via the shared error helper before any device UI.\n// Protocol: Address Book Final Specifications \u2014 Edit Scope.\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 HMAC_REST_BYTES,\n SUB_CMD_EDIT_SCOPE,\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_SCOPE } from \"@internal/app-binder/services/contactsTlvSerializer\";\n\nexport type EditExternalAddressScopeCommandArgs = {\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 EditExternalAddressScopeCommandResponse = {\n /**\n * Present only on the final chunk \u2014 the device returns struct_type(0x32) +\n * hmac_rest(32) there. Intermediate chunks return SW=0x9000 with no data.\n * This is the replacement address-level proof (rotated `hmac_rest`).\n */\n readonly hmacRest?: Uint8Array;\n};\n\nconst RESPONSE_STRUCT_TYPE = STRUCT_TYPE_EDIT_SCOPE;\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 EditExternalAddressScopeCommand\n implements\n Command<\n EditExternalAddressScopeCommandResponse,\n EditExternalAddressScopeCommandArgs,\n ContactsErrorCodes\n >\n{\n readonly name = \"editExternalAddressScope\";\n readonly args: EditExternalAddressScopeCommandArgs;\n private readonly errorHelper = new CommandErrorHelper<\n EditExternalAddressScopeCommandResponse,\n ContactsErrorCodes\n >(CONTACTS_APP_ERRORS, contactsCommandErrorFactory);\n\n constructor(args: EditExternalAddressScopeCommandArgs) {\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_EDIT_SCOPE,\n p2: this.args.p2,\n })\n .addBufferToData(this.args.data)\n .build();\n }\n\n parseResponse(\n response: ApduResponse,\n ): CommandResult<\n EditExternalAddressScopeCommandResponse,\n ContactsErrorCodes\n > {\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 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: { hmacRest },\n });\n });\n }\n}\n"],
|
|
5
|
+
"mappings": "yaAAA,IAAAA,EAAA,GAAAC,EAAAD,EAAA,qCAAAE,IAAA,eAAAC,EAAAH,GAMA,IAAAI,EASO,2CACPC,EAAmC,kCACnCC,EAAsB,qBAEtBC,EAKO,wDACPC,EAIO,qDACPC,EAAuC,+DAkBvC,MAAMC,EAAuB,yBAO7B,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,2BACP,KACQ,YAAc,IAAI,qBAGjC,sBAAqB,6BAA2B,EAElD,YAAYa,EAA2C,CACrD,KAAK,KAAOA,CACd,CAEA,SAAgB,CACd,OAAO,IAAI,cAAY,CACrB,IAAK,oBACL,IAAK,oBACL,GAAI,qBACJ,GAAI,KAAK,KAAK,EAChB,CAAC,EACE,gBAAgB,KAAK,KAAK,IAAI,EAC9B,MAAM,CACX,CAEA,cACEC,EAIA,CACA,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,EAAWP,EAAaC,EAAQ,iBAAe,EACrD,OAAKM,KAME,wBAAqB,CAC1B,KAAM,CAAE,SAAAA,CAAS,CACnB,CAAC,KAPQ,wBAAqB,CAC1B,MAAO,IAAI,yBAAuB,gCAAgC,CACpE,CAAC,CAML,CAAC,CACH,CACF",
|
|
6
|
+
"names": ["EditExternalAddressScopeCommand_exports", "__export", "EditExternalAddressScopeCommand", "__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", "hmacRest"]
|
|
7
|
+
}
|
|
@@ -0,0 +1,2 @@
|
|
|
1
|
+
"use strict";var a=require("@ledgerhq/device-management-kit"),s=require("../../app-binder/model/contactsErrors"),o=require("./EditExternalAddressScopeCommand");function d(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 m=d("88".repeat(32)),c="32"+"88".repeat(32);function n(e){return{data:Buffer.from(d(e)),statusCode:Buffer.from([144,0])}}describe("EditExternalAddressScopeCommand",()=>{describe("getApdu",()=>{it("wraps the framed chunk under B0 10 04 with P2=0x00 for the first/only chunk",()=>{const e=Uint8Array.from([0,3,170,187,204]),t=new o.EditExternalAddressScopeCommand({data:e,p2:0}).getApdu();expect(t.getRawApdu()).toStrictEqual(Uint8Array.from([176,16,4,0,5,0,3,170,187,204]))}),it("uses P2=0x80 for continuation chunks",()=>{const e=Uint8Array.from([170,187]),t=new o.EditExternalAddressScopeCommand({data:e,p2:128}).getApdu();expect(t.getRawApdu()).toStrictEqual(Uint8Array.from([176,16,4,128,2,170,187]))})}),describe("parseResponse",()=>{it("returns an empty payload for an intermediate chunk (SW=0x9000, no data)",()=>{const e=new o.EditExternalAddressScopeCommand({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_rest from the final-chunk response",()=>{const t=new o.EditExternalAddressScopeCommand({data:new Uint8Array,p2:0}).parseResponse(n(c));expect(t).toStrictEqual({status:a.CommandResultStatus.Success,data:{hmacRest:m}})}),it("returns InvalidStatusWordError when struct_type is wrong",()=>{const e="ee"+c.slice(2),r=new o.EditExternalAddressScopeCommand({data:new Uint8Array,p2:0}).parseResponse(n(e));expect(r.status).toBe(a.CommandResultStatus.Error)}),it("returns InvalidStatusWordError when hmac_rest is truncated",()=>{const e="32"+"88".repeat(16),r=new o.EditExternalAddressScopeCommand({data:new Uint8Array,p2:0}).parseResponse(n(e));expect(r.status).toBe(a.CommandResultStatus.Error)}),it("maps a known SW (0x6985) to a ContactsCommandError",()=>{const t=new o.EditExternalAddressScopeCommand({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(s.ContactsCommandError),expect(t.error.errorCode).toBe("6985"))}),it("maps SW=0x6982 to a seed-mismatch ContactsCommandError",()=>{const t=new o.EditExternalAddressScopeCommand({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(s.ContactsCommandError),expect(t.error.errorCode).toBe(s.CONTACT_SEED_MISMATCH_ERROR_CODE))})})});
|
|
2
|
+
//# sourceMappingURL=EditExternalAddressScopeCommand.test.js.map
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
{
|
|
2
|
+
"version": 3,
|
|
3
|
+
"sources": ["../../../../../src/internal/app-binder/command/EditExternalAddressScopeCommand.test.ts"],
|
|
4
|
+
"sourcesContent": ["// Thin chunk-framer: wraps a pre-framed chunk under B0 10 04 <P2> and parses\n// the 33-byte edit response (struct_type 0x32 + hmac_rest) on the final chunk.\n// TLV byte-parity is asserted in SendEditExternalAddressScopeTask.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 { EditExternalAddressScopeCommand } from \"./EditExternalAddressScopeCommand\";\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(0x32) + rotated hmac_rest(32).\nconst HMAC_REST = hexToBytes(\"88\".repeat(32));\nconst RESPONSE_HEX = \"32\" + \"88\".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(\"EditExternalAddressScopeCommand\", () => {\n describe(\"getApdu\", () => {\n it(\"wraps the framed chunk under B0 10 04 with P2=0x00 for the first/only chunk\", () => {\n const data = Uint8Array.from([0x00, 0x03, 0xaa, 0xbb, 0xcc]);\n\n const apdu = new EditExternalAddressScopeCommand({\n data,\n p2: 0x00,\n }).getApdu();\n\n expect(apdu.getRawApdu()).toStrictEqual(\n Uint8Array.from([\n 0xb0, 0x10, 0x04, 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 EditExternalAddressScopeCommand({\n data,\n p2: 0x80,\n }).getApdu();\n\n expect(apdu.getRawApdu()).toStrictEqual(\n Uint8Array.from([0xb0, 0x10, 0x04, 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 EditExternalAddressScopeCommand({\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_rest from the final-chunk response\", () => {\n const command = new EditExternalAddressScopeCommand({\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: { hmacRest: HMAC_REST },\n });\n });\n\n it(\"returns InvalidStatusWordError when struct_type is wrong\", () => {\n const wrongType = \"ee\" + RESPONSE_HEX.slice(2); // replace 0x32 with 0xee\n const command = new EditExternalAddressScopeCommand({\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_rest is truncated\", () => {\n const truncated = \"32\" + \"88\".repeat(16); // only 16 of 32 bytes\n const command = new EditExternalAddressScopeCommand({\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 EditExternalAddressScopeCommand({\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 returns 0x6982 when the seed-bound HMAC / group-handle\n // verification fails \u2014 i.e. the entry was registered with another seed.\n const command = new EditExternalAddressScopeCommand({\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_EditExternalAddressScopeCommand", "hexToBytes", "hex", "out", "i", "HMAC_REST", "RESPONSE_HEX", "makeResponse", "data", "apdu", "result", "wrongType", "truncated"]
|
|
7
|
+
}
|
|
@@ -0,0 +1,2 @@
|
|
|
1
|
+
"use strict";var s=Object.defineProperty;var u=Object.getOwnPropertyDescriptor;var A=Object.getOwnPropertyNames;var R=Object.prototype.hasOwnProperty;var l=(n,r)=>{for(var t in r)s(n,t,{get:r[t],enumerable:!0})},y=(n,r,t,m)=>{if(r&&typeof r=="object"||typeof r=="function")for(let o of A(r))!R.call(n,o)&&o!==t&&s(n,o,{get:()=>r[o],enumerable:!(m=u(r,o))||m.enumerable});return n};var E=n=>y(s({},"__esModule",{value:!0}),n);var _={};l(_,{RenameContactCommand:()=>T});module.exports=E(_);var e=require("@ledgerhq/device-management-kit"),p=require("@ledgerhq/signer-utils"),c=require("purify-ts"),a=require("../../app-binder/model/contactsConstants"),d=require("../../app-binder/model/contactsErrors"),i=require("../../app-binder/services/contactsTlvSerializer");const C=i.STRUCT_TYPE_EDIT_CONTACT_NAME;function f(n,r){const t=n.extractFieldByLength(r);if(!(!t||t.length!==r))return Uint8Array.from(t)}class T{name="renameContact";args;errorHelper=new p.CommandErrorHelper(d.CONTACTS_APP_ERRORS,d.contactsCommandErrorFactory);constructor(r){this.args=r}getApdu(){return new e.ApduBuilder({cla:a.RENAME_CONTACT_APDU_CLA,ins:a.RENAME_CONTACT_APDU_INS,p1:a.RENAME_CONTACT_P1,p2:this.args.p2}).addBufferToData(this.args.data).build()}parseResponse(r){return c.Maybe.fromNullable(this.errorHelper.getError(r)).orDefaultLazy(()=>{if(r.data.length===0)return(0,e.CommandResultFactory)({data:{}});const t=new e.ApduParser(r),m=t.extract8BitUInt();if(m!==C)return(0,e.CommandResultFactory)({error:new e.InvalidStatusWordError(`Expected struct_type 0x${C.toString(16)}, got ${m===void 0?"undefined":`0x${m.toString(16)}`}`)});const o=f(t,a.HMAC_NAME_BYTES);return o?(0,e.CommandResultFactory)({data:{hmacProof:o}}):(0,e.CommandResultFactory)({error:new e.InvalidStatusWordError("hmac_name missing or truncated")})})}}0&&(module.exports={RenameContactCommand});
|
|
2
|
+
//# sourceMappingURL=RenameContactCommand.js.map
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
{
|
|
2
|
+
"version": 3,
|
|
3
|
+
"sources": ["../../../../../src/internal/app-binder/command/RenameContactCommand.ts"],
|
|
4
|
+
"sourcesContent": ["// Rename Contact (EDIT CONTACT NAME) \u2014 the blockchain-agnostic address-book\n// rename. It is dispatched as an OS/dashboard command (CLA 0xE0 / INS 0x2E /\n// P1 0x00), NOT through the embedded app: the caller navigates to the dashboard\n// first (GoToDashboardDeviceAction) so the OS handles it directly.\n// SendRenameContactTask + sendFramedContactsPayload assemble the TLV, prepend\n// the 2-byte BE total length and slice into <=255B chunks; this command frames\n// one chunk and, on the final chunk, parses the 33-byte response:\n// struct_type(0x2e) + rotated hmac_name(32). Intermediate chunks ack with\n// SW=0x9000 and no data.\n//\n// The device is stateless: it verifies the supplied group handle + old-name\n// proof against the seed-derived key (SW 0x6982 on a seed mismatch, before any\n// UI) and, on approval, returns a fresh proof for the new name.\n// Protocol: Address Book Final Specifications \u2014 Edit Contact Name.\nimport {\n type Apdu,\n ApduBuilder,\n ApduParser,\n type ApduResponse,\n type Command,\n type CommandResult,\n CommandResultFactory,\n InvalidStatusWordError,\n} from \"@ledgerhq/device-management-kit\";\nimport { CommandErrorHelper } from \"@ledgerhq/signer-utils\";\nimport { Maybe } from \"purify-ts\";\n\nimport {\n HMAC_NAME_BYTES,\n RENAME_CONTACT_APDU_CLA,\n RENAME_CONTACT_APDU_INS,\n RENAME_CONTACT_P1,\n} from \"@internal/app-binder/model/contactsConstants\";\nimport {\n CONTACTS_APP_ERRORS,\n contactsCommandErrorFactory,\n type ContactsErrorCodes,\n} from \"@internal/app-binder/model/contactsErrors\";\nimport { STRUCT_TYPE_EDIT_CONTACT_NAME } from \"@internal/app-binder/services/contactsTlvSerializer\";\n\nexport type RenameContactCommandArgs = {\n /** One framed chunk built by sendFramedContactsPayload. */\n readonly data: Uint8Array;\n /** 0x00 for the first/only chunk, 0x80 for continuation chunks. */\n readonly p2: number;\n};\n\nexport type RenameContactCommandResponse = {\n /**\n * Present only on the final chunk \u2014 the device returns struct_type(0x2e) +\n * rotated hmac_name(32) there. Intermediate chunks return SW=0x9000 with no\n * data. This is the replacement group-level name proof.\n */\n readonly hmacProof?: Uint8Array;\n};\n\nconst RESPONSE_STRUCT_TYPE = STRUCT_TYPE_EDIT_CONTACT_NAME;\n\n/**\n * Extract `length` bytes as a freshly-owned plain `Uint8Array` (the parser may\n * hand back a `Buffer` view backed by the response), or `undefined` if the\n * response is too short.\n */\nfunction extractField(\n parser: ApduParser,\n length: number,\n): Uint8Array | undefined {\n const field = parser.extractFieldByLength(length);\n if (!field || field.length !== length) return undefined;\n return Uint8Array.from(field);\n}\n\nexport class RenameContactCommand\n implements\n Command<\n RenameContactCommandResponse,\n RenameContactCommandArgs,\n ContactsErrorCodes\n >\n{\n readonly name = \"renameContact\";\n readonly args: RenameContactCommandArgs;\n private readonly errorHelper = new CommandErrorHelper<\n RenameContactCommandResponse,\n ContactsErrorCodes\n >(CONTACTS_APP_ERRORS, contactsCommandErrorFactory);\n\n constructor(args: RenameContactCommandArgs) {\n this.args = args;\n }\n\n getApdu(): Apdu {\n return new ApduBuilder({\n cla: RENAME_CONTACT_APDU_CLA,\n ins: RENAME_CONTACT_APDU_INS,\n p1: RENAME_CONTACT_P1,\n p2: this.args.p2,\n })\n .addBufferToData(this.args.data)\n .build();\n }\n\n parseResponse(\n response: ApduResponse,\n ): CommandResult<RenameContactCommandResponse, ContactsErrorCodes> {\n return Maybe.fromNullable(\n this.errorHelper.getError(response),\n ).orDefaultLazy(() => {\n if (response.data.length === 0) {\n // Intermediate chunk \u2014 device acks with SW=0x9000 and no payload.\n return CommandResultFactory({ data: {} });\n }\n\n const parser = new ApduParser(response);\n\n const structType = parser.extract8BitUInt();\n if (structType !== RESPONSE_STRUCT_TYPE) {\n return CommandResultFactory({\n error: new InvalidStatusWordError(\n `Expected struct_type 0x${RESPONSE_STRUCT_TYPE.toString(16)}, got ${\n structType === undefined\n ? \"undefined\"\n : `0x${structType.toString(16)}`\n }`,\n ),\n });\n }\n\n const hmacProof = extractField(parser, HMAC_NAME_BYTES);\n if (!hmacProof) {\n return CommandResultFactory({\n error: new InvalidStatusWordError(\"hmac_name missing or truncated\"),\n });\n }\n\n return CommandResultFactory({\n data: { hmacProof },\n });\n });\n }\n}\n"],
|
|
5
|
+
"mappings": "yaAAA,IAAAA,EAAA,GAAAC,EAAAD,EAAA,0BAAAE,IAAA,eAAAC,EAAAH,GAcA,IAAAI,EASO,2CACPC,EAAmC,kCACnCC,EAAsB,qBAEtBC,EAKO,wDACPC,EAIO,qDACPC,EAA8C,+DAkB9C,MAAMC,EAAuB,gCAO7B,SAASC,EACPC,EACAC,EACwB,CACxB,MAAMC,EAAQF,EAAO,qBAAqBC,CAAM,EAChD,GAAI,GAACC,GAASA,EAAM,SAAWD,GAC/B,OAAO,WAAW,KAAKC,CAAK,CAC9B,CAEO,MAAMZ,CAOb,CACW,KAAO,gBACP,KACQ,YAAc,IAAI,qBAGjC,sBAAqB,6BAA2B,EAElD,YAAYa,EAAgC,CAC1C,KAAK,KAAOA,CACd,CAEA,SAAgB,CACd,OAAO,IAAI,cAAY,CACrB,IAAK,0BACL,IAAK,0BACL,GAAI,oBACJ,GAAI,KAAK,KAAK,EAChB,CAAC,EACE,gBAAgB,KAAK,KAAK,IAAI,EAC9B,MAAM,CACX,CAEA,cACEC,EACiE,CACjE,OAAO,QAAM,aACX,KAAK,YAAY,SAASA,CAAQ,CACpC,EAAE,cAAc,IAAM,CACpB,GAAIA,EAAS,KAAK,SAAW,EAE3B,SAAO,wBAAqB,CAAE,KAAM,CAAC,CAAE,CAAC,EAG1C,MAAMJ,EAAS,IAAI,aAAWI,CAAQ,EAEhCC,EAAaL,EAAO,gBAAgB,EAC1C,GAAIK,IAAeP,EACjB,SAAO,wBAAqB,CAC1B,MAAO,IAAI,yBACT,0BAA0BA,EAAqB,SAAS,EAAE,CAAC,SACzDO,IAAe,OACX,YACA,KAAKA,EAAW,SAAS,EAAE,CAAC,EAClC,EACF,CACF,CAAC,EAGH,MAAMC,EAAYP,EAAaC,EAAQ,iBAAe,EACtD,OAAKM,KAME,wBAAqB,CAC1B,KAAM,CAAE,UAAAA,CAAU,CACpB,CAAC,KAPQ,wBAAqB,CAC1B,MAAO,IAAI,yBAAuB,gCAAgC,CACpE,CAAC,CAML,CAAC,CACH,CACF",
|
|
6
|
+
"names": ["RenameContactCommand_exports", "__export", "RenameContactCommand", "__toCommonJS", "import_device_management_kit", "import_signer_utils", "import_purify_ts", "import_contactsConstants", "import_contactsErrors", "import_contactsTlvSerializer", "RESPONSE_STRUCT_TYPE", "extractField", "parser", "length", "field", "args", "response", "structType", "hmacProof"]
|
|
7
|
+
}
|
|
@@ -0,0 +1,2 @@
|
|
|
1
|
+
"use strict";var a=require("@ledgerhq/device-management-kit"),n=require("../../app-binder/model/contactsErrors"),o=require("./RenameContactCommand");function m(e){const t=new Uint8Array(e.length/2);for(let r=0;r<e.length;r+=2)t[r/2]=parseInt(e.slice(r,r+2),16);return t}const d=m("dd".repeat(32)),c="2e"+"dd".repeat(32);function s(e){return{data:Buffer.from(m(e)),statusCode:Buffer.from([144,0])}}describe("RenameContactCommand",()=>{describe("getApdu",()=>{it("wraps the framed chunk under E0 2E 00 with P2=0x00 for the first/only chunk",()=>{const e=Uint8Array.from([0,3,170,187,204]),t=new o.RenameContactCommand({data:e,p2:0}).getApdu();expect(t.getRawApdu()).toStrictEqual(Uint8Array.from([224,46,0,0,5,0,3,170,187,204]))}),it("uses P2=0x80 for continuation chunks",()=>{const e=Uint8Array.from([170,187]),t=new o.RenameContactCommand({data:e,p2:128}).getApdu();expect(t.getRawApdu()).toStrictEqual(Uint8Array.from([224,46,0,128,2,170,187]))})}),describe("parseResponse",()=>{it("returns an empty payload for an intermediate chunk (SW=0x9000, no data)",()=>{const e=new o.RenameContactCommand({data:new Uint8Array,p2:0}).parseResponse({data:Buffer.from([]),statusCode:Buffer.from([144,0])});expect(e).toStrictEqual({status:a.CommandResultStatus.Success,data:{}})}),it("extracts the rotated hmac_name from an edit-contact-name response",()=>{const t=new o.RenameContactCommand({data:new Uint8Array,p2:0}).parseResponse(s(c));expect(t).toStrictEqual({status:a.CommandResultStatus.Success,data:{hmacProof:d}})}),it("returns InvalidStatusWordError when struct_type is wrong",()=>{const e="ee"+c.slice(2),r=new o.RenameContactCommand({data:new Uint8Array,p2:0}).parseResponse(s(e));expect(r.status).toBe(a.CommandResultStatus.Error)}),it("returns InvalidStatusWordError when hmac_name is truncated",()=>{const e="2e"+"dd".repeat(16),r=new o.RenameContactCommand({data:new Uint8Array,p2:0}).parseResponse(s(e));expect(r.status).toBe(a.CommandResultStatus.Error)}),it("maps a known SW (0x6985) to a ContactsCommandError",()=>{const t=new o.RenameContactCommand({data:new Uint8Array,p2:0}).parseResponse({data:Buffer.from([]),statusCode:Buffer.from([105,133])});expect(t.status).toBe(a.CommandResultStatus.Error),t.status===a.CommandResultStatus.Error&&(expect(t.error).toBeInstanceOf(n.ContactsCommandError),expect(t.error.errorCode).toBe("6985"))}),it("maps SW=0x6982 to a seed-mismatch ContactsCommandError",()=>{const t=new o.RenameContactCommand({data:new Uint8Array,p2:0}).parseResponse({data:Buffer.from([]),statusCode:Buffer.from([105,130])});expect(t.status).toBe(a.CommandResultStatus.Error),t.status===a.CommandResultStatus.Error&&(expect(t.error).toBeInstanceOf(n.ContactsCommandError),expect(t.error.errorCode).toBe(n.CONTACT_SEED_MISMATCH_ERROR_CODE))})})});
|
|
2
|
+
//# sourceMappingURL=RenameContactCommand.test.js.map
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
{
|
|
2
|
+
"version": 3,
|
|
3
|
+
"sources": ["../../../../../src/internal/app-binder/command/RenameContactCommand.test.ts"],
|
|
4
|
+
"sourcesContent": ["// RenameContactCommand is a thin chunk-framer for the OS/dashboard EDIT CONTACT\n// NAME command: it wraps a pre-framed chunk (2-byte BE length prefix + TLV,\n// assembled by SendRenameContactTask + sendFramedContactsPayload) under\n// E0 2E 00 <P2>, and parses the 33-byte response on the final chunk. TLV\n// byte-parity is asserted in SendRenameContactTask.test.ts.\nimport {\n type ApduResponse,\n CommandResultStatus,\n} from \"@ledgerhq/device-management-kit\";\n\nimport {\n CONTACT_SEED_MISMATCH_ERROR_CODE,\n ContactsCommandError,\n} from \"@internal/app-binder/model/contactsErrors\";\n\nimport { RenameContactCommand } from \"./RenameContactCommand\";\n\nfunction hexToBytes(hex: string): Uint8Array {\n const out = new Uint8Array(hex.length / 2);\n for (let i = 0; i < hex.length; i += 2) {\n out[i / 2] = parseInt(hex.slice(i, i + 2), 16);\n }\n return out;\n}\n\n// Device response: struct_type(0x2e) + rotated hmac_name(32).\nconst HMAC_PROOF = hexToBytes(\"dd\".repeat(32));\nconst RESPONSE_HEX = \"2e\" + \"dd\".repeat(32);\n\nfunction makeResponse(hex: string): ApduResponse {\n return {\n data: Buffer.from(hexToBytes(hex)),\n statusCode: Buffer.from([0x90, 0x00]),\n };\n}\n\ndescribe(\"RenameContactCommand\", () => {\n describe(\"getApdu\", () => {\n it(\"wraps the framed chunk under E0 2E 00 with P2=0x00 for the first/only chunk\", () => {\n const data = Uint8Array.from([0x00, 0x03, 0xaa, 0xbb, 0xcc]);\n\n const apdu = new RenameContactCommand({ data, p2: 0x00 }).getApdu();\n\n expect(apdu.getRawApdu()).toStrictEqual(\n Uint8Array.from([\n 0xe0, 0x2e, 0x00, 0x00, 0x05, 0x00, 0x03, 0xaa, 0xbb, 0xcc,\n ]),\n );\n });\n\n it(\"uses P2=0x80 for continuation chunks\", () => {\n const data = Uint8Array.from([0xaa, 0xbb]);\n\n const apdu = new RenameContactCommand({ data, p2: 0x80 }).getApdu();\n\n expect(apdu.getRawApdu()).toStrictEqual(\n Uint8Array.from([0xe0, 0x2e, 0x00, 0x80, 0x02, 0xaa, 0xbb]),\n );\n });\n });\n\n describe(\"parseResponse\", () => {\n it(\"returns an empty payload for an intermediate chunk (SW=0x9000, no data)\", () => {\n const result = new RenameContactCommand({\n data: new Uint8Array(),\n p2: 0x00,\n }).parseResponse({\n data: Buffer.from([]),\n statusCode: Buffer.from([0x90, 0x00]),\n });\n\n expect(result).toStrictEqual({\n status: CommandResultStatus.Success,\n data: {},\n });\n });\n\n it(\"extracts the rotated hmac_name from an edit-contact-name response\", () => {\n const command = new RenameContactCommand({\n data: new Uint8Array(),\n p2: 0x00,\n });\n\n const result = command.parseResponse(makeResponse(RESPONSE_HEX));\n\n expect(result).toStrictEqual({\n status: CommandResultStatus.Success,\n data: { hmacProof: HMAC_PROOF },\n });\n });\n\n it(\"returns InvalidStatusWordError when struct_type is wrong\", () => {\n const wrongType = \"ee\" + RESPONSE_HEX.slice(2); // replace 0x2e with 0xee\n const command = new RenameContactCommand({\n data: new Uint8Array(),\n p2: 0x00,\n });\n\n const result = command.parseResponse(makeResponse(wrongType));\n\n expect(result.status).toBe(CommandResultStatus.Error);\n });\n\n it(\"returns InvalidStatusWordError when hmac_name is truncated\", () => {\n const truncated = \"2e\" + \"dd\".repeat(16); // only 16 of 32 bytes\n const command = new RenameContactCommand({\n data: new Uint8Array(),\n p2: 0x00,\n });\n\n const result = command.parseResponse(makeResponse(truncated));\n\n expect(result.status).toBe(CommandResultStatus.Error);\n });\n\n it(\"maps a known SW (0x6985) to a ContactsCommandError\", () => {\n const command = new RenameContactCommand({\n data: new Uint8Array(),\n p2: 0x00,\n });\n\n const result = command.parseResponse({\n data: Buffer.from([]),\n statusCode: Buffer.from([0x69, 0x85]),\n });\n\n expect(result.status).toBe(CommandResultStatus.Error);\n if (result.status === CommandResultStatus.Error) {\n expect(result.error).toBeInstanceOf(ContactsCommandError);\n expect((result.error as ContactsCommandError).errorCode).toBe(\"6985\");\n }\n });\n\n it(\"maps SW=0x6982 to a seed-mismatch ContactsCommandError\", () => {\n // The device verifies the supplied group handle + old-name proof against\n // the seed-derived key before any UI, and returns 0x6982 on a mismatch.\n const command = new RenameContactCommand({\n data: new Uint8Array(),\n p2: 0x00,\n });\n\n const result = command.parseResponse({\n data: Buffer.from([]),\n statusCode: Buffer.from([0x69, 0x82]),\n });\n\n expect(result.status).toBe(CommandResultStatus.Error);\n if (result.status === CommandResultStatus.Error) {\n expect(result.error).toBeInstanceOf(ContactsCommandError);\n expect((result.error as ContactsCommandError).errorCode).toBe(\n CONTACT_SEED_MISMATCH_ERROR_CODE,\n );\n }\n });\n });\n});\n"],
|
|
5
|
+
"mappings": "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",
|
|
6
|
+
"names": ["import_device_management_kit", "import_contactsErrors", "import_RenameContactCommand", "hexToBytes", "hex", "out", "i", "HMAC_PROOF", "RESPONSE_HEX", "makeResponse", "data", "apdu", "result", "wrongType", "truncated"]
|
|
7
|
+
}
|
|
@@ -0,0 +1,2 @@
|
|
|
1
|
+
"use strict";var s=Object.defineProperty;var u=Object.getOwnPropertyDescriptor;var d=Object.getOwnPropertyNames;var l=Object.prototype.hasOwnProperty;var f=(n,e)=>{for(var t in e)s(n,t,{get:e[t],enumerable:!0})},m=(n,e,t,o)=>{if(e&&typeof e=="object"||typeof e=="function")for(let i of d(e))!l.call(n,i)&&i!==t&&s(n,i,{get:()=>e[i],enumerable:!(o=u(e,i))||o.enumerable});return n};var S=n=>m(s({},"__esModule",{value:!0}),n);var C={};f(C,{isContactsAppVersionSupportedForSession:()=>A,isContactsOsSupportedForSession:()=>v});module.exports=S(C);var p=require("@ledgerhq/device-management-kit"),r=require("../../api/model/ContactsVersionRequirements"),a=require("./ContactsApplicationResolver");function c(n){return n.supported}function v(n){const e=n.getDeviceSessionState(),t=(0,r.resolveContactsVersionRequirements)(e.deviceModelId);if(!c(t))return!1;const o="firmwareVersion"in e?e.firmwareVersion?.os:void 0;return o===void 0?!1:(0,r.isVersionAtLeast)(o,t.minOsVersion)}function A(n,e){const t=n.getDeviceSessionState(),o=(0,r.resolveContactsVersionRequirements)(t.deviceModelId);if(!c(o))return!1;const i=o.minAppVersion[e.name];return i===void 0?!1:new p.ApplicationChecker(t,{version:e.version},new a.ContactsApplicationResolver).withMinVersionInclusive(i).check()}0&&(module.exports={isContactsAppVersionSupportedForSession,isContactsOsSupportedForSession});
|
|
2
|
+
//# sourceMappingURL=contactsVersionGuards.js.map
|