@ledgerhq/device-contacts-kit 0.0.0-develop-20260827155839 → 0.0.0-develop-20260828024102
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 +30 -2
- package/lib/cjs/api/ContactsManager.js +1 -1
- package/lib/cjs/api/ContactsManager.js.map +1 -1
- package/lib/cjs/api/app-binder/RegisterExternalAddressDeviceActionTypes.js +2 -0
- package/lib/cjs/api/app-binder/RegisterExternalAddressDeviceActionTypes.js.map +7 -0
- package/lib/cjs/api/index.js +1 -1
- package/lib/cjs/api/index.js.map +2 -2
- package/lib/cjs/api/model/RegisterExternalAddress.js +2 -0
- package/lib/cjs/api/model/RegisterExternalAddress.js.map +7 -0
- package/lib/cjs/internal/DefaultContactsManager.js +1 -1
- package/lib/cjs/internal/DefaultContactsManager.js.map +3 -3
- package/lib/cjs/internal/DefaultContactsManager.test.js +2 -0
- package/lib/cjs/internal/DefaultContactsManager.test.js.map +7 -0
- package/lib/cjs/internal/app-binder/ContactsAppBinder.js +1 -1
- package/lib/cjs/internal/app-binder/ContactsAppBinder.js.map +3 -3
- package/lib/cjs/internal/app-binder/command/RegisterIdentityCommand.js +2 -0
- package/lib/cjs/internal/app-binder/command/RegisterIdentityCommand.js.map +7 -0
- package/lib/cjs/internal/app-binder/command/RegisterIdentityCommand.test.js +2 -0
- package/lib/cjs/internal/app-binder/command/RegisterIdentityCommand.test.js.map +7 -0
- package/lib/cjs/internal/app-binder/device-action/RegisterExternalAddress/RegisterExternalAddressDeviceAction.js +2 -0
- package/lib/cjs/internal/app-binder/device-action/RegisterExternalAddress/RegisterExternalAddressDeviceAction.js.map +7 -0
- package/lib/cjs/internal/app-binder/device-action/RegisterExternalAddress/RegisterExternalAddressDeviceAction.test.js +2 -0
- package/lib/cjs/internal/app-binder/device-action/RegisterExternalAddress/RegisterExternalAddressDeviceAction.test.js.map +7 -0
- package/lib/cjs/internal/app-binder/device-action/RegisterExternalAddress/validateRegisterExternalAddressInput.js +2 -0
- package/lib/cjs/internal/app-binder/device-action/RegisterExternalAddress/validateRegisterExternalAddressInput.js.map +7 -0
- package/lib/cjs/internal/app-binder/device-action/RegisterExternalAddress/validateRegisterExternalAddressInput.test.js +2 -0
- package/lib/cjs/internal/app-binder/device-action/RegisterExternalAddress/validateRegisterExternalAddressInput.test.js.map +7 -0
- package/lib/cjs/internal/app-binder/device-action/__test-utils__/makeInternalApi.js +2 -0
- package/lib/cjs/internal/app-binder/device-action/__test-utils__/makeInternalApi.js.map +7 -0
- package/lib/cjs/internal/app-binder/device-action/__test-utils__/setupOpenAppDAMock.js +2 -0
- package/lib/cjs/internal/app-binder/device-action/__test-utils__/setupOpenAppDAMock.js.map +7 -0
- package/lib/cjs/internal/app-binder/device-action/__test-utils__/setupWaitForAppAndVersionDAMock.js +2 -0
- package/lib/cjs/internal/app-binder/device-action/__test-utils__/setupWaitForAppAndVersionDAMock.js.map +7 -0
- package/lib/cjs/internal/app-binder/device-action/__test-utils__/testDeviceActionStates.js +2 -0
- package/lib/cjs/internal/app-binder/device-action/__test-utils__/testDeviceActionStates.js.map +7 -0
- package/lib/cjs/internal/app-binder/isContactsSupportedForSession.js +1 -1
- package/lib/cjs/internal/app-binder/isContactsSupportedForSession.js.map +3 -3
- package/lib/cjs/internal/app-binder/isContactsSupportedForSession.test.js +1 -1
- package/lib/cjs/internal/app-binder/isContactsSupportedForSession.test.js.map +3 -3
- package/lib/cjs/internal/app-binder/model/contactsConstants.js +2 -0
- package/lib/cjs/internal/app-binder/model/contactsConstants.js.map +7 -0
- package/lib/cjs/internal/app-binder/model/contactsErrors.js +2 -0
- package/lib/cjs/internal/app-binder/model/contactsErrors.js.map +7 -0
- package/lib/cjs/internal/app-binder/model/contactsValidation.js +2 -0
- package/lib/cjs/internal/app-binder/model/contactsValidation.js.map +7 -0
- package/lib/cjs/internal/app-binder/model/contactsValidation.test.js +2 -0
- package/lib/cjs/internal/app-binder/model/contactsValidation.test.js.map +7 -0
- package/lib/cjs/internal/app-binder/services/contactsTlvSerializer.js +2 -0
- package/lib/cjs/internal/app-binder/services/contactsTlvSerializer.js.map +7 -0
- package/lib/cjs/internal/app-binder/services/contactsTlvSerializer.test.js +2 -0
- package/lib/cjs/internal/app-binder/services/contactsTlvSerializer.test.js.map +7 -0
- package/lib/cjs/internal/app-binder/services/sendFramedContactsPayload.js +2 -0
- package/lib/cjs/internal/app-binder/services/sendFramedContactsPayload.js.map +7 -0
- package/lib/cjs/internal/app-binder/services/sendFramedContactsPayload.test.js +2 -0
- package/lib/cjs/internal/app-binder/services/sendFramedContactsPayload.test.js.map +7 -0
- package/lib/cjs/internal/app-binder/task/SendRegisterIdentityTask.js +2 -0
- package/lib/cjs/internal/app-binder/task/SendRegisterIdentityTask.js.map +7 -0
- package/lib/cjs/internal/app-binder/task/SendRegisterIdentityTask.test.js +2 -0
- package/lib/cjs/internal/app-binder/task/SendRegisterIdentityTask.test.js.map +7 -0
- package/lib/cjs/internal/di.js +1 -1
- package/lib/cjs/internal/di.js.map +3 -3
- package/lib/cjs/internal/di.test.js +1 -1
- package/lib/cjs/internal/di.test.js.map +3 -3
- package/lib/cjs/internal/use-cases/RegisterExternalAddressUseCase.js +2 -0
- package/lib/cjs/internal/use-cases/RegisterExternalAddressUseCase.js.map +7 -0
- package/lib/cjs/internal/use-cases/RegisterExternalAddressUseCase.test.js +2 -0
- package/lib/cjs/internal/use-cases/RegisterExternalAddressUseCase.test.js.map +7 -0
- package/lib/cjs/internal/use-cases/di/useCaseModule.js +2 -0
- package/lib/cjs/internal/use-cases/di/useCaseModule.js.map +7 -0
- package/lib/cjs/internal/use-cases/di/useCaseTypes.js +2 -0
- package/lib/cjs/internal/use-cases/di/useCaseTypes.js.map +7 -0
- package/lib/cjs/package.json +2 -1
- package/lib/esm/api/app-binder/RegisterExternalAddressDeviceActionTypes.js +1 -0
- package/lib/esm/api/app-binder/RegisterExternalAddressDeviceActionTypes.js.map +7 -0
- package/lib/esm/api/index.js +1 -1
- package/lib/esm/api/index.js.map +2 -2
- package/lib/esm/api/model/RegisterExternalAddress.js +1 -0
- package/lib/esm/api/model/RegisterExternalAddress.js.map +7 -0
- package/lib/esm/internal/DefaultContactsManager.js +1 -1
- package/lib/esm/internal/DefaultContactsManager.js.map +3 -3
- package/lib/esm/internal/DefaultContactsManager.test.js +2 -0
- package/lib/esm/internal/DefaultContactsManager.test.js.map +7 -0
- package/lib/esm/internal/app-binder/ContactsAppBinder.js +1 -1
- package/lib/esm/internal/app-binder/ContactsAppBinder.js.map +3 -3
- package/lib/esm/internal/app-binder/command/RegisterIdentityCommand.js +2 -0
- package/lib/esm/internal/app-binder/command/RegisterIdentityCommand.js.map +7 -0
- package/lib/esm/internal/app-binder/command/RegisterIdentityCommand.test.js +2 -0
- package/lib/esm/internal/app-binder/command/RegisterIdentityCommand.test.js.map +7 -0
- package/lib/esm/internal/app-binder/device-action/RegisterExternalAddress/RegisterExternalAddressDeviceAction.js +2 -0
- package/lib/esm/internal/app-binder/device-action/RegisterExternalAddress/RegisterExternalAddressDeviceAction.js.map +7 -0
- package/lib/esm/internal/app-binder/device-action/RegisterExternalAddress/RegisterExternalAddressDeviceAction.test.js +2 -0
- package/lib/esm/internal/app-binder/device-action/RegisterExternalAddress/RegisterExternalAddressDeviceAction.test.js.map +7 -0
- package/lib/esm/internal/app-binder/device-action/RegisterExternalAddress/validateRegisterExternalAddressInput.js +2 -0
- package/lib/esm/internal/app-binder/device-action/RegisterExternalAddress/validateRegisterExternalAddressInput.js.map +7 -0
- package/lib/esm/internal/app-binder/device-action/RegisterExternalAddress/validateRegisterExternalAddressInput.test.js +2 -0
- package/lib/esm/internal/app-binder/device-action/RegisterExternalAddress/validateRegisterExternalAddressInput.test.js.map +7 -0
- package/lib/esm/internal/app-binder/device-action/__test-utils__/makeInternalApi.js +2 -0
- package/lib/esm/internal/app-binder/device-action/__test-utils__/makeInternalApi.js.map +7 -0
- package/lib/esm/internal/app-binder/device-action/__test-utils__/setupOpenAppDAMock.js +2 -0
- package/lib/esm/internal/app-binder/device-action/__test-utils__/setupOpenAppDAMock.js.map +7 -0
- package/lib/esm/internal/app-binder/device-action/__test-utils__/setupWaitForAppAndVersionDAMock.js +2 -0
- package/lib/esm/internal/app-binder/device-action/__test-utils__/setupWaitForAppAndVersionDAMock.js.map +7 -0
- package/lib/esm/internal/app-binder/device-action/__test-utils__/testDeviceActionStates.js +2 -0
- package/lib/esm/internal/app-binder/device-action/__test-utils__/testDeviceActionStates.js.map +7 -0
- package/lib/esm/internal/app-binder/isContactsSupportedForSession.js +1 -1
- package/lib/esm/internal/app-binder/isContactsSupportedForSession.js.map +3 -3
- package/lib/esm/internal/app-binder/isContactsSupportedForSession.test.js +1 -1
- package/lib/esm/internal/app-binder/isContactsSupportedForSession.test.js.map +3 -3
- package/lib/esm/internal/app-binder/model/contactsConstants.js +2 -0
- package/lib/esm/internal/app-binder/model/contactsConstants.js.map +7 -0
- package/lib/esm/internal/app-binder/model/contactsErrors.js +2 -0
- package/lib/esm/internal/app-binder/model/contactsErrors.js.map +7 -0
- package/lib/esm/internal/app-binder/model/contactsValidation.js +2 -0
- package/lib/esm/internal/app-binder/model/contactsValidation.js.map +7 -0
- package/lib/esm/internal/app-binder/model/contactsValidation.test.js +2 -0
- package/lib/esm/internal/app-binder/model/contactsValidation.test.js.map +7 -0
- package/lib/esm/internal/app-binder/services/contactsTlvSerializer.js +2 -0
- package/lib/esm/internal/app-binder/services/contactsTlvSerializer.js.map +7 -0
- package/lib/esm/internal/app-binder/services/contactsTlvSerializer.test.js +2 -0
- package/lib/esm/internal/app-binder/services/contactsTlvSerializer.test.js.map +7 -0
- package/lib/esm/internal/app-binder/services/sendFramedContactsPayload.js +2 -0
- package/lib/esm/internal/app-binder/services/sendFramedContactsPayload.js.map +7 -0
- package/lib/esm/internal/app-binder/services/sendFramedContactsPayload.test.js +2 -0
- package/lib/esm/internal/app-binder/services/sendFramedContactsPayload.test.js.map +7 -0
- package/lib/esm/internal/app-binder/task/SendRegisterIdentityTask.js +2 -0
- package/lib/esm/internal/app-binder/task/SendRegisterIdentityTask.js.map +7 -0
- package/lib/esm/internal/app-binder/task/SendRegisterIdentityTask.test.js +2 -0
- package/lib/esm/internal/app-binder/task/SendRegisterIdentityTask.test.js.map +7 -0
- package/lib/esm/internal/di.js +1 -1
- package/lib/esm/internal/di.js.map +3 -3
- package/lib/esm/internal/di.test.js +1 -1
- package/lib/esm/internal/di.test.js.map +3 -3
- package/lib/esm/internal/use-cases/RegisterExternalAddressUseCase.js +2 -0
- package/lib/esm/internal/use-cases/RegisterExternalAddressUseCase.js.map +7 -0
- package/lib/esm/internal/use-cases/RegisterExternalAddressUseCase.test.js +2 -0
- package/lib/esm/internal/use-cases/RegisterExternalAddressUseCase.test.js.map +7 -0
- package/lib/esm/internal/use-cases/di/useCaseModule.js +2 -0
- package/lib/esm/internal/use-cases/di/useCaseModule.js.map +7 -0
- package/lib/esm/internal/use-cases/di/useCaseTypes.js +2 -0
- package/lib/esm/internal/use-cases/di/useCaseTypes.js.map +7 -0
- package/lib/esm/package.json +2 -1
- package/lib/types/api/ContactsManager.d.ts +11 -5
- package/lib/types/api/ContactsManager.d.ts.map +1 -1
- package/lib/types/api/app-binder/RegisterExternalAddressDeviceActionTypes.d.ts +30 -0
- package/lib/types/api/app-binder/RegisterExternalAddressDeviceActionTypes.d.ts.map +1 -0
- package/lib/types/api/index.d.ts +2 -0
- package/lib/types/api/index.d.ts.map +1 -1
- package/lib/types/api/model/RegisterExternalAddress.d.ts +50 -0
- package/lib/types/api/model/RegisterExternalAddress.d.ts.map +1 -0
- package/lib/types/internal/DefaultContactsManager.d.ts +5 -2
- package/lib/types/internal/DefaultContactsManager.d.ts.map +1 -1
- package/lib/types/internal/DefaultContactsManager.test.d.ts +2 -0
- package/lib/types/internal/DefaultContactsManager.test.d.ts.map +1 -0
- package/lib/types/internal/app-binder/ContactsAppBinder.d.ts +4 -3
- package/lib/types/internal/app-binder/ContactsAppBinder.d.ts.map +1 -1
- package/lib/types/internal/app-binder/command/RegisterIdentityCommand.d.ts +30 -0
- package/lib/types/internal/app-binder/command/RegisterIdentityCommand.d.ts.map +1 -0
- package/lib/types/internal/app-binder/command/RegisterIdentityCommand.test.d.ts +2 -0
- package/lib/types/internal/app-binder/command/RegisterIdentityCommand.test.d.ts.map +1 -0
- package/lib/types/internal/app-binder/device-action/RegisterExternalAddress/RegisterExternalAddressDeviceAction.d.ts +14 -0
- package/lib/types/internal/app-binder/device-action/RegisterExternalAddress/RegisterExternalAddressDeviceAction.d.ts.map +1 -0
- package/lib/types/internal/app-binder/device-action/RegisterExternalAddress/RegisterExternalAddressDeviceAction.test.d.ts +2 -0
- package/lib/types/internal/app-binder/device-action/RegisterExternalAddress/RegisterExternalAddressDeviceAction.test.d.ts.map +1 -0
- package/lib/types/internal/app-binder/device-action/RegisterExternalAddress/validateRegisterExternalAddressInput.d.ts +12 -0
- package/lib/types/internal/app-binder/device-action/RegisterExternalAddress/validateRegisterExternalAddressInput.d.ts.map +1 -0
- package/lib/types/internal/app-binder/device-action/RegisterExternalAddress/validateRegisterExternalAddressInput.test.d.ts +2 -0
- package/lib/types/internal/app-binder/device-action/RegisterExternalAddress/validateRegisterExternalAddressInput.test.d.ts.map +1 -0
- package/lib/types/internal/app-binder/device-action/__test-utils__/makeInternalApi.d.ts +4 -0
- package/lib/types/internal/app-binder/device-action/__test-utils__/makeInternalApi.d.ts.map +1 -0
- package/lib/types/internal/app-binder/device-action/__test-utils__/setupOpenAppDAMock.d.ts +2 -0
- package/lib/types/internal/app-binder/device-action/__test-utils__/setupOpenAppDAMock.d.ts.map +1 -0
- package/lib/types/internal/app-binder/device-action/__test-utils__/setupWaitForAppAndVersionDAMock.d.ts +17 -0
- package/lib/types/internal/app-binder/device-action/__test-utils__/setupWaitForAppAndVersionDAMock.d.ts.map +1 -0
- package/lib/types/internal/app-binder/device-action/__test-utils__/testDeviceActionStates.d.ts +15 -0
- package/lib/types/internal/app-binder/device-action/__test-utils__/testDeviceActionStates.d.ts.map +1 -0
- package/lib/types/internal/app-binder/isContactsSupportedForSession.d.ts +16 -8
- package/lib/types/internal/app-binder/isContactsSupportedForSession.d.ts.map +1 -1
- package/lib/types/internal/app-binder/model/contactsConstants.d.ts +24 -0
- package/lib/types/internal/app-binder/model/contactsConstants.d.ts.map +1 -0
- package/lib/types/internal/app-binder/model/contactsErrors.d.ts +30 -0
- package/lib/types/internal/app-binder/model/contactsErrors.d.ts.map +1 -0
- package/lib/types/internal/app-binder/model/contactsValidation.d.ts +53 -0
- package/lib/types/internal/app-binder/model/contactsValidation.d.ts.map +1 -0
- package/lib/types/internal/app-binder/model/contactsValidation.test.d.ts +2 -0
- package/lib/types/internal/app-binder/model/contactsValidation.test.d.ts.map +1 -0
- package/lib/types/internal/app-binder/services/contactsTlvSerializer.d.ts +33 -0
- package/lib/types/internal/app-binder/services/contactsTlvSerializer.d.ts.map +1 -0
- package/lib/types/internal/app-binder/services/contactsTlvSerializer.test.d.ts +2 -0
- package/lib/types/internal/app-binder/services/contactsTlvSerializer.test.d.ts.map +1 -0
- package/lib/types/internal/app-binder/services/sendFramedContactsPayload.d.ts +14 -0
- package/lib/types/internal/app-binder/services/sendFramedContactsPayload.d.ts.map +1 -0
- package/lib/types/internal/app-binder/services/sendFramedContactsPayload.test.d.ts +2 -0
- package/lib/types/internal/app-binder/services/sendFramedContactsPayload.test.d.ts.map +1 -0
- package/lib/types/internal/app-binder/task/SendRegisterIdentityTask.d.ts +25 -0
- package/lib/types/internal/app-binder/task/SendRegisterIdentityTask.d.ts.map +1 -0
- package/lib/types/internal/app-binder/task/SendRegisterIdentityTask.test.d.ts +2 -0
- package/lib/types/internal/app-binder/task/SendRegisterIdentityTask.test.d.ts.map +1 -0
- package/lib/types/internal/di.d.ts.map +1 -1
- package/lib/types/internal/use-cases/RegisterExternalAddressUseCase.d.ts +17 -0
- package/lib/types/internal/use-cases/RegisterExternalAddressUseCase.d.ts.map +1 -0
- package/lib/types/internal/use-cases/RegisterExternalAddressUseCase.test.d.ts +2 -0
- package/lib/types/internal/use-cases/RegisterExternalAddressUseCase.test.d.ts.map +1 -0
- package/lib/types/internal/use-cases/di/useCaseModule.d.ts +3 -0
- package/lib/types/internal/use-cases/di/useCaseModule.d.ts.map +1 -0
- package/lib/types/internal/use-cases/di/useCaseTypes.d.ts +4 -0
- package/lib/types/internal/use-cases/di/useCaseTypes.d.ts.map +1 -0
- package/lib/types/tsconfig.prod.tsbuildinfo +1 -1
- package/package.json +8 -7
package/README.md
CHANGED
|
@@ -27,8 +27,36 @@ const contactsManager = new ContactsManagerBuilder({
|
|
|
27
27
|
}).build();
|
|
28
28
|
```
|
|
29
29
|
|
|
30
|
-
|
|
31
|
-
|
|
30
|
+
## Registering an external address
|
|
31
|
+
|
|
32
|
+
`registerExternalAddress` runs the device's REGISTER IDENTITY operation. It opens the embedded app
|
|
33
|
+
by default, checks the [Contacts version requirements](#version-requirements), then frames the
|
|
34
|
+
request to the device and returns the device-issued proof material for the host to persist.
|
|
35
|
+
|
|
36
|
+
```ts
|
|
37
|
+
const { observable } = contactsManager.registerExternalAddress({
|
|
38
|
+
contactName: "Alice",
|
|
39
|
+
scope: "Eth main",
|
|
40
|
+
identifier: addressBytes, // 20-byte Ethereum address
|
|
41
|
+
blockchainFamily: "ethereum",
|
|
42
|
+
chainId: 1n,
|
|
43
|
+
// existingContactGroup: { groupHandle, hmacProof }, // to extend an existing contact
|
|
44
|
+
// skipOpenApp: true, // skip only the open-app step; the version guard still runs
|
|
45
|
+
});
|
|
46
|
+
|
|
47
|
+
observable.subscribe((state) => {
|
|
48
|
+
// state.intermediateValue.requiredUserInteraction surfaces open-app confirmation
|
|
49
|
+
// and the on-device Register Wallet validation.
|
|
50
|
+
if (state.status === DeviceActionStatus.Completed) {
|
|
51
|
+
const { mode, groupHandle, hmacProof, hmacRest } = state.output;
|
|
52
|
+
// persist mode ("newContactGroup" | "existingContactGroup"), the echoed
|
|
53
|
+
// input, and the proof material.
|
|
54
|
+
}
|
|
55
|
+
});
|
|
56
|
+
```
|
|
57
|
+
|
|
58
|
+
Concrete Contacts operations (Edit Contact Name, Edit Identifier, Edit Scope, Register Ledger
|
|
59
|
+
Account, Edit Ledger Account) are added by their dedicated implementation tickets.
|
|
32
60
|
|
|
33
61
|
## Version requirements
|
|
34
62
|
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
"use strict";var
|
|
1
|
+
"use strict";var n=Object.defineProperty;var p=Object.getOwnPropertyDescriptor;var a=Object.getOwnPropertyNames;var i=Object.prototype.hasOwnProperty;var A=(r,e,d,s)=>{if(e&&typeof e=="object"||typeof e=="function")for(let t of a(e))!i.call(r,t)&&t!==d&&n(r,t,{get:()=>e[t],enumerable:!(s=p(e,t))||s.enumerable});return r};var g=r=>A(n({},"__esModule",{value:!0}),r);var o={};module.exports=g(o);
|
|
2
2
|
//# sourceMappingURL=ContactsManager.js.map
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"version": 3,
|
|
3
3
|
"sources": ["../../../src/api/ContactsManager.ts"],
|
|
4
|
-
"sourcesContent": ["/**\n * Public, stateless Contacts (Address Book) manager.\n *\n * It only drives device interactions \u2014 taking caller input, running the device\n * operation, and returning the device output (including proof material). It\n * does not store anything, own the address book, or handle persistence; the\n * host is responsible for that.\n
|
|
4
|
+
"sourcesContent": ["import { type RegisterExternalAddressDAReturnType } from \"@api/app-binder/RegisterExternalAddressDeviceActionTypes\";\nimport { type 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"],
|
|
5
5
|
"mappings": "+WAAA,IAAAA,EAAA,kBAAAC,EAAAD",
|
|
6
6
|
"names": ["ContactsManager_exports", "__toCommonJS"]
|
|
7
7
|
}
|
|
@@ -0,0 +1,2 @@
|
|
|
1
|
+
"use strict";var s=Object.defineProperty;var a=Object.getOwnPropertyDescriptor;var d=Object.getOwnPropertyNames;var i=Object.prototype.hasOwnProperty;var p=(r,e,o,n)=>{if(e&&typeof e=="object"||typeof e=="function")for(let t of d(e))!i.call(r,t)&&t!==o&&s(r,t,{get:()=>e[t],enumerable:!(n=a(e,t))||n.enumerable});return r};var A=r=>p(s({},"__esModule",{value:!0}),r);var l={};module.exports=A(l);
|
|
2
|
+
//# sourceMappingURL=RegisterExternalAddressDeviceActionTypes.js.map
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
{
|
|
2
|
+
"version": 3,
|
|
3
|
+
"sources": ["../../../../src/api/app-binder/RegisterExternalAddressDeviceActionTypes.ts"],
|
|
4
|
+
"sourcesContent": ["import {\n type CommandErrorResult,\n type DeviceActionState,\n type ExecuteDeviceActionReturnType,\n type OpenAppDAError,\n type OpenAppDARequiredInteraction,\n type UserInteractionRequired,\n} from \"@ledgerhq/device-management-kit\";\n\nimport {\n type RegisterExternalAddressInput,\n type RegisterExternalAddressOutput,\n} from \"@api/model/RegisterExternalAddress\";\nimport {\n type ContactsErrorCodes,\n type ContactsVersionRequirementError,\n} from \"@internal/app-binder/model/contactsErrors\";\nimport { type ContactsValidationError } from \"@internal/app-binder/model/contactsValidation\";\n\n/** Machine input: the public input plus the injected embedded-app name. */\nexport type RegisterExternalAddressDAInput = RegisterExternalAddressInput & {\n readonly appName: string;\n};\n\nexport type RegisterExternalAddressDAOutput = RegisterExternalAddressOutput;\n\nexport type RegisterExternalAddressDAError =\n | OpenAppDAError\n | ContactsValidationError\n | ContactsVersionRequirementError\n | CommandErrorResult<ContactsErrorCodes>[\"error\"];\n\nexport type RegisterExternalAddressDARequiredInteraction =\n | OpenAppDARequiredInteraction\n | UserInteractionRequired.RegisterWallet;\n\nexport type RegisterExternalAddressDAIntermediateValue = {\n readonly requiredUserInteraction: RegisterExternalAddressDARequiredInteraction;\n};\n\nexport type RegisterExternalAddressDAState = DeviceActionState<\n RegisterExternalAddressDAOutput,\n RegisterExternalAddressDAError,\n RegisterExternalAddressDAIntermediateValue\n>;\n\nexport type RegisterExternalAddressDAInternalState = {\n readonly error: RegisterExternalAddressDAError | null;\n /** The running app read freshly by WaitForAppAndVersion, for the version guard. */\n readonly appAndVersion: {\n readonly name: string;\n readonly version: string;\n } | null;\n readonly proofs: {\n readonly groupHandle: Uint8Array;\n readonly hmacProof: Uint8Array;\n readonly hmacRest: Uint8Array;\n } | null;\n};\n\nexport type RegisterExternalAddressDAReturnType = ExecuteDeviceActionReturnType<\n RegisterExternalAddressDAOutput,\n RegisterExternalAddressDAError,\n RegisterExternalAddressDAIntermediateValue\n>;\n"],
|
|
5
|
+
"mappings": "+WAAA,IAAAA,EAAA,kBAAAC,EAAAD",
|
|
6
|
+
"names": ["RegisterExternalAddressDeviceActionTypes_exports", "__toCommonJS"]
|
|
7
|
+
}
|
package/lib/cjs/api/index.js
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
"use strict";var
|
|
1
|
+
"use strict";var p=Object.defineProperty;var d=Object.getOwnPropertyDescriptor;var i=Object.getOwnPropertyNames;var A=Object.prototype.hasOwnProperty;var E=(r,t)=>{for(var n in t)p(r,n,{get:t[n],enumerable:!0})},u=(r,t,n,o)=>{if(t&&typeof t=="object"||typeof t=="function")for(let s of i(t))!A.call(r,s)&&s!==n&&p(r,s,{get:()=>t[s],enumerable:!(o=d(t,s))||o.enumerable});return r};var y=r=>u(p({},"__esModule",{value:!0}),r);var R={};E(R,{CONTACTS_VERSION_REQUIREMENTS:()=>e.CONTACTS_VERSION_REQUIREMENTS,ContactsManagerBuilder:()=>a.ContactsManagerBuilder,ETHEREUM_APP_NAME:()=>e.ETHEREUM_APP_NAME,isContactsSupported:()=>e.isContactsSupported,isVersionAtLeast:()=>e.isVersionAtLeast,resolveContactsVersionRequirements:()=>e.resolveContactsVersionRequirements});module.exports=y(R);var a=require("./ContactsManagerBuilder"),e=require("./model/ContactsVersionRequirements");0&&(module.exports={CONTACTS_VERSION_REQUIREMENTS,ContactsManagerBuilder,ETHEREUM_APP_NAME,isContactsSupported,isVersionAtLeast,resolveContactsVersionRequirements});
|
|
2
2
|
//# sourceMappingURL=index.js.map
|
package/lib/cjs/api/index.js.map
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"version": 3,
|
|
3
3
|
"sources": ["../../../src/api/index.ts"],
|
|
4
|
-
"sourcesContent": ["export { type ContactsManager } from \"@api/ContactsManager\";\nexport { ContactsManagerBuilder } from \"@api/ContactsManagerBuilder\";\nexport {\n CONTACTS_VERSION_REQUIREMENTS,\n type ContactsModelRequirement,\n type ContactsModelSupport,\n type ContactsModelUnsupported,\n type ContactsSupportQuery,\n type ContactsVersionRequirements,\n ETHEREUM_APP_NAME,\n isContactsSupported,\n isVersionAtLeast,\n resolveContactsVersionRequirements,\n} from \"@api/model/ContactsVersionRequirements\";\n"],
|
|
5
|
-
"mappings": "yaAAA,IAAAA,EAAA,GAAAC,EAAAD,EAAA,oVAAAE,EAAAF,
|
|
4
|
+
"sourcesContent": ["export {\n type RegisterExternalAddressDAError,\n type RegisterExternalAddressDAInput,\n type RegisterExternalAddressDAIntermediateValue,\n type RegisterExternalAddressDAOutput,\n type RegisterExternalAddressDARequiredInteraction,\n type RegisterExternalAddressDAReturnType,\n type RegisterExternalAddressDAState,\n} from \"@api/app-binder/RegisterExternalAddressDeviceActionTypes\";\nexport { type ContactsManager } from \"@api/ContactsManager\";\nexport { ContactsManagerBuilder } from \"@api/ContactsManagerBuilder\";\nexport {\n CONTACTS_VERSION_REQUIREMENTS,\n type ContactsModelRequirement,\n type ContactsModelSupport,\n type ContactsModelUnsupported,\n type ContactsSupportQuery,\n type ContactsVersionRequirements,\n ETHEREUM_APP_NAME,\n isContactsSupported,\n isVersionAtLeast,\n resolveContactsVersionRequirements,\n} from \"@api/model/ContactsVersionRequirements\";\nexport {\n type ExistingContactGroup,\n type RegisterExternalAddressInput,\n type RegisterExternalAddressMode,\n type RegisterExternalAddressOutput,\n} from \"@api/model/RegisterExternalAddress\";\n"],
|
|
5
|
+
"mappings": "yaAAA,IAAAA,EAAA,GAAAC,EAAAD,EAAA,oVAAAE,EAAAF,GAUA,IAAAG,EAAuC,uCACvCC,EAWO",
|
|
6
6
|
"names": ["api_exports", "__export", "__toCommonJS", "import_ContactsManagerBuilder", "import_ContactsVersionRequirements"]
|
|
7
7
|
}
|
|
@@ -0,0 +1,2 @@
|
|
|
1
|
+
"use strict";var a=Object.defineProperty;var i=Object.getOwnPropertyDescriptor;var d=Object.getOwnPropertyNames;var y=Object.prototype.hasOwnProperty;var l=(e,r,o,t)=>{if(r&&typeof r=="object"||typeof r=="function")for(let n of d(r))!y.call(e,n)&&n!==o&&a(e,n,{get:()=>r[n],enumerable:!(t=i(r,n))||t.enumerable});return e};var s=e=>l(a({},"__esModule",{value:!0}),e);var p={};module.exports=s(p);
|
|
2
|
+
//# sourceMappingURL=RegisterExternalAddress.js.map
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
{
|
|
2
|
+
"version": 3,
|
|
3
|
+
"sources": ["../../../../src/api/model/RegisterExternalAddress.ts"],
|
|
4
|
+
"sourcesContent": ["/**\n * Public input/output types for `ContactsManager.registerExternalAddress`.\n *\n * Proof material (`groupHandle`, `hmacProof`, `hmacRest`) is returned as raw\n * bytes; the host owns persistence and address-book state. `derivationPath` is\n * intentionally absent \u2014 the kit owns a single internal value for external\n * addresses and does not expose it.\n */\n\n/** The existing contact group to extend, when adding an address to it. */\nexport type ExistingContactGroup = {\n /** 64-byte group handle returned by the group's first Register Identity. */\n readonly groupHandle: Uint8Array;\n /** 32-byte name proof (device `hmac_name`) bound to that group. */\n readonly hmacProof: Uint8Array;\n};\n\nexport type RegisterExternalAddressInput = {\n readonly contactName: string;\n readonly scope: string;\n /** Chain address bytes (20 bytes for Ethereum). */\n readonly identifier: Uint8Array;\n /** Blockchain family name, e.g. \"ethereum\" (v1 supports Ethereum only). */\n readonly blockchainFamily: string;\n readonly chainId?: bigint;\n /**\n * Set to add the address to an existing contact group. Omit to create a new\n * contact group.\n */\n readonly existingContactGroup?: ExistingContactGroup;\n /**\n * When `true`, the open-app step is skipped (the caller guarantees the app is\n * already open). The app-version guard still runs.\n */\n readonly skipOpenApp?: boolean;\n};\n\nexport type RegisterExternalAddressMode =\n | \"newContactGroup\"\n | \"existingContactGroup\";\n\nexport type RegisterExternalAddressOutput = {\n /** Whether a new contact group was created or an existing one was extended. */\n readonly mode: RegisterExternalAddressMode;\n /** Echoed input, needed by the host to persist the returned proof material. */\n readonly contactName: string;\n readonly scope: string;\n readonly identifier: Uint8Array;\n readonly blockchainFamily: string;\n readonly chainId?: bigint;\n /** Device-issued proof material. */\n readonly groupHandle: Uint8Array;\n readonly hmacProof: Uint8Array;\n readonly hmacRest: Uint8Array;\n};\n"],
|
|
5
|
+
"mappings": "+WAAA,IAAAA,EAAA,kBAAAC,EAAAD",
|
|
6
|
+
"names": ["RegisterExternalAddress_exports", "__toCommonJS"]
|
|
7
|
+
}
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
"use strict";var
|
|
1
|
+
"use strict";var a=Object.defineProperty;var p=Object.getOwnPropertyDescriptor;var m=Object.getOwnPropertyNames;var d=Object.prototype.hasOwnProperty;var c=(t,e)=>{for(var r in e)a(t,r,{get:e[r],enumerable:!0})},g=(t,e,r,n)=>{if(e&&typeof e=="object"||typeof e=="function")for(let s of m(e))!d.call(t,s)&&s!==r&&a(t,s,{get:()=>e[s],enumerable:!(n=p(e,s))||n.enumerable});return t};var C=t=>g(a({},"__esModule",{value:!0}),t);var u={};c(u,{DefaultContactsManager:()=>l});module.exports=C(u);var o=require("./di"),i=require("./use-cases/di/useCaseTypes");class l{_container;constructor({dmk:e,sessionId:r,appName:n}){this._container=(0,o.makeContainer)({dmk:e,sessionId:r,appName:n})}registerExternalAddress(e){return this._container.get(i.useCaseTypes.RegisterExternalAddressUseCase).execute(e)}get container(){return this._container}}0&&(module.exports={DefaultContactsManager});
|
|
2
2
|
//# sourceMappingURL=DefaultContactsManager.js.map
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"version": 3,
|
|
3
3
|
"sources": ["../../../src/internal/DefaultContactsManager.ts"],
|
|
4
|
-
"sourcesContent": ["import {\n type DeviceManagementKit,\n type DeviceSessionId,\n} from \"@ledgerhq/device-management-kit\";\nimport { type Container } from \"inversify\";\n\nimport { type ContactsManager } from \"@api/ContactsManager\";\nimport { makeContainer } from \"@internal/di\";\n\ntype DefaultContactsManagerConstructorArgs = {\n dmk: DeviceManagementKit;\n sessionId: DeviceSessionId;\n appName: string;\n};\n\nexport class DefaultContactsManager implements ContactsManager {\n private readonly _container: Container;\n\n constructor({\n dmk,\n sessionId,\n appName,\n }: DefaultContactsManagerConstructorArgs) {\n this._container = makeContainer({ dmk, sessionId, appName });\n }\n\n /**\n * Exposes the DI container so operation methods
|
|
5
|
-
"mappings": "yaAAA,IAAAA,EAAA,GAAAC,EAAAD,EAAA,4BAAAE,IAAA,eAAAC,EAAAH,
|
|
6
|
-
"names": ["DefaultContactsManager_exports", "__export", "DefaultContactsManager", "__toCommonJS", "import_di", "dmk", "sessionId", "appName"]
|
|
4
|
+
"sourcesContent": ["import {\n type DeviceManagementKit,\n type DeviceSessionId,\n} from \"@ledgerhq/device-management-kit\";\nimport { type Container } from \"inversify\";\n\nimport { type RegisterExternalAddressDAReturnType } from \"@api/app-binder/RegisterExternalAddressDeviceActionTypes\";\nimport { type ContactsManager } from \"@api/ContactsManager\";\nimport { type RegisterExternalAddressInput } from \"@api/model/RegisterExternalAddress\";\nimport { makeContainer } from \"@internal/di\";\nimport { useCaseTypes } from \"@internal/use-cases/di/useCaseTypes\";\nimport { type RegisterExternalAddressUseCase } from \"@internal/use-cases/RegisterExternalAddressUseCase\";\n\ntype DefaultContactsManagerConstructorArgs = {\n dmk: DeviceManagementKit;\n sessionId: DeviceSessionId;\n appName: string;\n};\n\nexport class DefaultContactsManager implements ContactsManager {\n private readonly _container: Container;\n\n constructor({\n dmk,\n sessionId,\n appName,\n }: DefaultContactsManagerConstructorArgs) {\n this._container = makeContainer({ dmk, sessionId, appName });\n }\n\n registerExternalAddress(\n input: RegisterExternalAddressInput,\n ): RegisterExternalAddressDAReturnType {\n return this._container\n .get<RegisterExternalAddressUseCase>(\n useCaseTypes.RegisterExternalAddressUseCase,\n )\n .execute(input);\n }\n\n /**\n * Exposes the DI container so future operation methods can resolve their\n * `UseCase`. Not part of the public API.\n */\n protected get container(): Container {\n return this._container;\n }\n}\n"],
|
|
5
|
+
"mappings": "yaAAA,IAAAA,EAAA,GAAAC,EAAAD,EAAA,4BAAAE,IAAA,eAAAC,EAAAH,GASA,IAAAI,EAA8B,wBAC9BC,EAA6B,+CAStB,MAAMH,CAAkD,CAC5C,WAEjB,YAAY,CACV,IAAAI,EACA,UAAAC,EACA,QAAAC,CACF,EAA0C,CACxC,KAAK,cAAa,iBAAc,CAAE,IAAAF,EAAK,UAAAC,EAAW,QAAAC,CAAQ,CAAC,CAC7D,CAEA,wBACEC,EACqC,CACrC,OAAO,KAAK,WACT,IACC,eAAa,8BACf,EACC,QAAQA,CAAK,CAClB,CAMA,IAAc,WAAuB,CACnC,OAAO,KAAK,UACd,CACF",
|
|
6
|
+
"names": ["DefaultContactsManager_exports", "__export", "DefaultContactsManager", "__toCommonJS", "import_di", "import_useCaseTypes", "dmk", "sessionId", "appName", "input"]
|
|
7
7
|
}
|
|
@@ -0,0 +1,2 @@
|
|
|
1
|
+
"use strict";var n=require("./DefaultContactsManager");const a={contactName:"Alice",scope:"Eth main",identifier:new Uint8Array(20).fill(17),blockchainFamily:"ethereum",chainId:1n};describe("DefaultContactsManager",()=>{it("registerExternalAddress flows manager -> use-case -> binder -> dmk.executeDeviceAction",()=>{const e=vi.fn().mockReturnValue("DA_RETURN"),t={executeDeviceAction:e},c=new n.DefaultContactsManager({dmk:t,sessionId:"session-id",appName:"Ethereum"}).registerExternalAddress(a);expect(e).toHaveBeenCalledTimes(1);const i=e.mock.calls[0][0];expect(i.sessionId).toBe("session-id"),expect(i.deviceAction).toBeDefined(),expect(c).toBe("DA_RETURN")}),it("does not throw on invalid input \u2014 it dispatches the device action, which surfaces the error",()=>{const e=vi.fn().mockReturnValue("DA_RETURN"),t={executeDeviceAction:e},s=new n.DefaultContactsManager({dmk:t,sessionId:"session-id",appName:"Ethereum"});expect(()=>s.registerExternalAddress({...a,contactName:""})).not.toThrow(),expect(e).toHaveBeenCalledTimes(1)})});
|
|
2
|
+
//# sourceMappingURL=DefaultContactsManager.test.js.map
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
{
|
|
2
|
+
"version": 3,
|
|
3
|
+
"sources": ["../../../src/internal/DefaultContactsManager.test.ts"],
|
|
4
|
+
"sourcesContent": ["import { type DeviceManagementKit } from \"@ledgerhq/device-management-kit\";\n\nimport { type RegisterExternalAddressInput } from \"@api/model/RegisterExternalAddress\";\n\nimport { DefaultContactsManager } from \"./DefaultContactsManager\";\n\nconst VALID_INPUT: RegisterExternalAddressInput = {\n contactName: \"Alice\",\n scope: \"Eth main\",\n identifier: new Uint8Array(20).fill(0x11),\n blockchainFamily: \"ethereum\",\n chainId: 1n,\n};\n\ndescribe(\"DefaultContactsManager\", () => {\n it(\"registerExternalAddress flows manager -> use-case -> binder -> dmk.executeDeviceAction\", () => {\n const executeDeviceAction = vi.fn().mockReturnValue(\"DA_RETURN\");\n const dmk = { executeDeviceAction } as unknown as DeviceManagementKit;\n\n const manager = new DefaultContactsManager({\n dmk,\n sessionId: \"session-id\",\n appName: \"Ethereum\",\n });\n\n const result = manager.registerExternalAddress(VALID_INPUT);\n\n expect(executeDeviceAction).toHaveBeenCalledTimes(1);\n const call = executeDeviceAction.mock.calls[0]![0] as {\n sessionId: string;\n deviceAction: unknown;\n };\n expect(call.sessionId).toBe(\"session-id\");\n expect(call.deviceAction).toBeDefined();\n expect(result).toBe(\"DA_RETURN\");\n });\n\n it(\"does not throw on invalid input \u2014 it dispatches the device action, which surfaces the error\", () => {\n // The public API returns a device action; invalid caller input must reach\n // the observable as a typed error state rather than throwing synchronously.\n const executeDeviceAction = vi.fn().mockReturnValue(\"DA_RETURN\");\n const dmk = { executeDeviceAction } as unknown as DeviceManagementKit;\n\n const manager = new DefaultContactsManager({\n dmk,\n sessionId: \"session-id\",\n appName: \"Ethereum\",\n });\n\n expect(() =>\n manager.registerExternalAddress({\n ...VALID_INPUT,\n contactName: \"\",\n }),\n ).not.toThrow();\n expect(executeDeviceAction).toHaveBeenCalledTimes(1);\n });\n});\n"],
|
|
5
|
+
"mappings": "aAIA,IAAAA,EAAuC,oCAEvC,MAAMC,EAA4C,CAChD,YAAa,QACb,MAAO,WACP,WAAY,IAAI,WAAW,EAAE,EAAE,KAAK,EAAI,EACxC,iBAAkB,WAClB,QAAS,EACX,EAEA,SAAS,yBAA0B,IAAM,CACvC,GAAG,yFAA0F,IAAM,CACjG,MAAMC,EAAsB,GAAG,GAAG,EAAE,gBAAgB,WAAW,EACzDC,EAAM,CAAE,oBAAAD,CAAoB,EAQ5BE,EANU,IAAI,yBAAuB,CACzC,IAAAD,EACA,UAAW,aACX,QAAS,UACX,CAAC,EAEsB,wBAAwBF,CAAW,EAE1D,OAAOC,CAAmB,EAAE,sBAAsB,CAAC,EACnD,MAAMG,EAAOH,EAAoB,KAAK,MAAM,CAAC,EAAG,CAAC,EAIjD,OAAOG,EAAK,SAAS,EAAE,KAAK,YAAY,EACxC,OAAOA,EAAK,YAAY,EAAE,YAAY,EACtC,OAAOD,CAAM,EAAE,KAAK,WAAW,CACjC,CAAC,EAED,GAAG,mGAA+F,IAAM,CAGtG,MAAMF,EAAsB,GAAG,GAAG,EAAE,gBAAgB,WAAW,EACzDC,EAAM,CAAE,oBAAAD,CAAoB,EAE5BI,EAAU,IAAI,yBAAuB,CACzC,IAAAH,EACA,UAAW,aACX,QAAS,UACX,CAAC,EAED,OAAO,IACLG,EAAQ,wBAAwB,CAC9B,GAAGL,EACH,YAAa,EACf,CAAC,CACH,EAAE,IAAI,QAAQ,EACd,OAAOC,CAAmB,EAAE,sBAAsB,CAAC,CACrD,CAAC,CACH,CAAC",
|
|
6
|
+
"names": ["import_DefaultContactsManager", "VALID_INPUT", "executeDeviceAction", "dmk", "result", "call", "manager"]
|
|
7
|
+
}
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
"use strict";var
|
|
1
|
+
"use strict";var d=Object.defineProperty;var l=Object.getOwnPropertyDescriptor;var x=Object.getOwnPropertyNames;var A=Object.prototype.hasOwnProperty;var D=(t,e)=>{for(var s in e)d(t,s,{get:e[s],enumerable:!0})},u=(t,e,s,i)=>{if(e&&typeof e=="object"||typeof e=="function")for(let r of x(e))!A.call(t,r)&&r!==s&&d(t,r,{get:()=>e[r],enumerable:!(i=l(e,r))||i.enumerable});return t};var I=t=>u(d({},"__esModule",{value:!0}),t),y=(t,e,s,i)=>{for(var r=i>1?void 0:i?l(e,s):e,a=t.length-1,c;a>=0;a--)(c=t[a])&&(r=(i?c(e,s,r):c(r))||r);return i&&r&&d(e,s,r),r},p=(t,e)=>(s,i)=>e(s,i,t);var v={};D(v,{ContactsAppBinder:()=>o});module.exports=I(v);var n=require("inversify"),g=require("../app-binder/device-action/RegisterExternalAddress/RegisterExternalAddressDeviceAction"),m=require("../externalTypes");let o=class{constructor(e,s,i){this.dmk=e;this.sessionId=s;this.appName=i}registerExternalAddress(e){return this.dmk.executeDeviceAction({sessionId:this.sessionId,deviceAction:new g.RegisterExternalAddressDeviceAction({input:{...e,appName:this.appName}})})}};o=y([(0,n.injectable)(),p(0,(0,n.inject)(m.externalTypes.Dmk)),p(1,(0,n.inject)(m.externalTypes.SessionId)),p(2,(0,n.inject)(m.externalTypes.AppName))],o);0&&(module.exports={ContactsAppBinder});
|
|
2
2
|
//# sourceMappingURL=ContactsAppBinder.js.map
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"version": 3,
|
|
3
3
|
"sources": ["../../../../src/internal/app-binder/ContactsAppBinder.ts"],
|
|
4
|
-
"sourcesContent": ["import {\n type DeviceManagementKit,\n type DeviceSessionId,\n} from \"@ledgerhq/device-management-kit\";\nimport { inject, injectable } from \"inversify\";\n\nimport { externalTypes } from \"@internal/externalTypes\";\n\n/**\n * Constructs and executes Contacts `DeviceAction`s using the injected `dmk`,\n * `sessionId`, and `appName`.
|
|
5
|
-
"mappings": "okBAAA,IAAAA,EAAA,GAAAC,EAAAD,EAAA,uBAAAE,IAAA,eAAAC,EAAAH,GAIA,IAAAI,EAAmC,
|
|
6
|
-
"names": ["ContactsAppBinder_exports", "__export", "ContactsAppBinder", "__toCommonJS", "import_inversify", "import_externalTypes", "ContactsAppBinder", "dmk", "sessionId", "appName", "__decorateClass", "__decorateParam"]
|
|
4
|
+
"sourcesContent": ["import {\n type DeviceManagementKit,\n type DeviceSessionId,\n} from \"@ledgerhq/device-management-kit\";\nimport { inject, injectable } from \"inversify\";\n\nimport { type RegisterExternalAddressDAReturnType } from \"@api/app-binder/RegisterExternalAddressDeviceActionTypes\";\nimport { type RegisterExternalAddressInput } from \"@api/model/RegisterExternalAddress\";\nimport { RegisterExternalAddressDeviceAction } from \"@internal/app-binder/device-action/RegisterExternalAddress/RegisterExternalAddressDeviceAction\";\nimport { externalTypes } from \"@internal/externalTypes\";\n\n/**\n * Constructs and executes Contacts `DeviceAction`s using the injected `dmk`,\n * `sessionId`, and `appName`. Each Address Book operation gets one method here.\n */\n@injectable()\nexport class ContactsAppBinder {\n constructor(\n @inject(externalTypes.Dmk)\n protected readonly dmk: DeviceManagementKit,\n @inject(externalTypes.SessionId)\n protected readonly sessionId: DeviceSessionId,\n @inject(externalTypes.AppName)\n protected readonly appName: string,\n ) {}\n\n registerExternalAddress(\n input: RegisterExternalAddressInput,\n ): RegisterExternalAddressDAReturnType {\n return this.dmk.executeDeviceAction({\n sessionId: this.sessionId,\n deviceAction: new RegisterExternalAddressDeviceAction({\n input: { ...input, appName: this.appName },\n }),\n });\n }\n}\n"],
|
|
5
|
+
"mappings": "okBAAA,IAAAA,EAAA,GAAAC,EAAAD,EAAA,uBAAAE,IAAA,eAAAC,EAAAH,GAIA,IAAAI,EAAmC,qBAInCC,EAAoD,0GACpDC,EAA8B,mCAOvB,IAAMC,EAAN,KAAwB,CAC7B,YAEqBC,EAEAC,EAEAC,EACnB,CALmB,SAAAF,EAEA,eAAAC,EAEA,aAAAC,CAClB,CAEH,wBACEC,EACqC,CACrC,OAAO,KAAK,IAAI,oBAAoB,CAClC,UAAW,KAAK,UAChB,aAAc,IAAI,sCAAoC,CACpD,MAAO,CAAE,GAAGA,EAAO,QAAS,KAAK,OAAQ,CAC3C,CAAC,CACH,CAAC,CACH,CACF,EApBaJ,EAANK,EAAA,IADN,cAAW,EAGPC,EAAA,eAAO,gBAAc,GAAG,GAExBA,EAAA,eAAO,gBAAc,SAAS,GAE9BA,EAAA,eAAO,gBAAc,OAAO,IANpBN",
|
|
6
|
+
"names": ["ContactsAppBinder_exports", "__export", "ContactsAppBinder", "__toCommonJS", "import_inversify", "import_RegisterExternalAddressDeviceAction", "import_externalTypes", "ContactsAppBinder", "dmk", "sessionId", "appName", "input", "__decorateClass", "__decorateParam"]
|
|
7
7
|
}
|
|
@@ -0,0 +1,2 @@
|
|
|
1
|
+
"use strict";var i=Object.defineProperty;var g=Object.getOwnPropertyDescriptor;var l=Object.getOwnPropertyNames;var R=Object.prototype.hasOwnProperty;var A=(o,r)=>{for(var t in r)i(o,t,{get:r[t],enumerable:!0})},f=(o,r,t,d)=>{if(r&&typeof r=="object"||typeof r=="function")for(let a of l(r))!R.call(o,a)&&a!==t&&i(o,a,{get:()=>r[a],enumerable:!(d=g(r,a))||d.enumerable});return o};var E=o=>f(i({},"__esModule",{value:!0}),o);var T={};A(T,{RegisterIdentityCommand:()=>_});module.exports=E(T);var e=require("@ledgerhq/device-management-kit"),c=require("@ledgerhq/signer-utils"),C=require("purify-ts"),n=require("../../app-binder/model/contactsConstants"),s=require("../../app-binder/model/contactsErrors");const y=45;function m(o,r){const t=o.extractFieldByLength(r);if(!(!t||t.length!==r))return Uint8Array.from(t)}class _{name="registerIdentity";args;errorHelper=new c.CommandErrorHelper(s.CONTACTS_APP_ERRORS,s.contactsCommandErrorFactory);constructor(r){this.args=r}getApdu(){return new e.ApduBuilder({cla:n.CONTACTS_APDU_CLA,ins:n.CONTACTS_APDU_INS,p1:n.SUB_CMD_REGISTER_IDENTITY,p2:this.args.p2}).addBufferToData(this.args.data).build()}parseResponse(r){return C.Maybe.fromNullable(this.errorHelper.getError(r)).orDefaultLazy(()=>{if(r.data.length===0)return(0,e.CommandResultFactory)({data:{}});const t=new e.ApduParser(r),d=t.extract8BitUInt();if(d!==y)return(0,e.CommandResultFactory)({error:new e.InvalidStatusWordError(`Expected struct_type 0x${y.toString(16)}, got ${d===void 0?"undefined":`0x${d.toString(16)}`}`)});const a=m(t,n.GROUP_HANDLE_BYTES);if(!a)return(0,e.CommandResultFactory)({error:new e.InvalidStatusWordError("group_handle missing or truncated")});const p=m(t,n.HMAC_PROOF_BYTES);if(!p)return(0,e.CommandResultFactory)({error:new e.InvalidStatusWordError("hmac_name missing or truncated")});const u=m(t,n.HMAC_REST_BYTES);return u?(0,e.CommandResultFactory)({data:{groupHandle:a,hmacProof:p,hmacRest:u}}):(0,e.CommandResultFactory)({error:new e.InvalidStatusWordError("hmac_rest missing or truncated")})})}}0&&(module.exports={RegisterIdentityCommand});
|
|
2
|
+
//# sourceMappingURL=RegisterIdentityCommand.js.map
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
{
|
|
2
|
+
"version": 3,
|
|
3
|
+
"sources": ["../../../../../src/internal/app-binder/command/RegisterIdentityCommand.ts"],
|
|
4
|
+
"sourcesContent": ["// Register Identity (register external address) \u2014 sub-command P1=0x01 of the\n// address-book APDU (CLA 0xB0 / INS 0x10). Caller (SendRegisterIdentityTask +\n// sendFramedContactsPayload) assembles the TLV, prepends the 2-byte BE total\n// length and slices into <=255B chunks; this command frames one chunk and, on\n// the final chunk, parses the 129-byte response: struct_type(0x2d) +\n// group_handle(64) + hmac_proof(32) + hmac_rest(32). Intermediate chunks ack\n// with SW=0x9000 and no data.\n// Protocol: Address Book Final Specifications \u2014 Register Identity.\nimport {\n type Apdu,\n ApduBuilder,\n ApduParser,\n type ApduResponse,\n type Command,\n type CommandResult,\n CommandResultFactory,\n InvalidStatusWordError,\n} from \"@ledgerhq/device-management-kit\";\nimport { CommandErrorHelper } from \"@ledgerhq/signer-utils\";\nimport { Maybe } from \"purify-ts\";\n\nimport {\n CONTACTS_APDU_CLA,\n CONTACTS_APDU_INS,\n GROUP_HANDLE_BYTES,\n HMAC_PROOF_BYTES,\n HMAC_REST_BYTES,\n SUB_CMD_REGISTER_IDENTITY,\n} from \"@internal/app-binder/model/contactsConstants\";\nimport {\n CONTACTS_APP_ERRORS,\n contactsCommandErrorFactory,\n type ContactsErrorCodes,\n} from \"@internal/app-binder/model/contactsErrors\";\n\nexport type RegisterIdentityCommandArgs = {\n /** One framed chunk built by sendFramedContactsPayload. */\n readonly data: Uint8Array;\n /** 0x00 for the first/only chunk, 0x80 for continuation chunks. */\n readonly p2: number;\n};\n\nexport type RegisterIdentityCommandResponse = {\n /**\n * Present only on the final chunk \u2014 the device returns struct_type(0x2d) +\n * group_handle(64) + hmac_proof(32) + hmac_rest(32) there. Intermediate\n * chunks return SW=0x9000 with no data.\n *\n * `hmacProof` is the device's HMAC_PROOF (binds the contact name);\n * `hmacRest` is the HMAC_REST (binds scope + identifier + family).\n */\n readonly groupHandle?: Uint8Array;\n readonly hmacProof?: Uint8Array;\n readonly hmacRest?: Uint8Array;\n};\n\nconst RESPONSE_STRUCT_TYPE = 0x2d;\n\n/**\n * Extract `length` bytes as a freshly-owned plain `Uint8Array` (the parser may\n * hand back a `Buffer` view backed by the response), or `undefined` if the\n * response is too short.\n */\nfunction extractField(\n parser: ApduParser,\n length: number,\n): Uint8Array | undefined {\n const field = parser.extractFieldByLength(length);\n if (!field || field.length !== length) return undefined;\n return Uint8Array.from(field);\n}\n\nexport class RegisterIdentityCommand\n implements\n Command<\n RegisterIdentityCommandResponse,\n RegisterIdentityCommandArgs,\n ContactsErrorCodes\n >\n{\n readonly name = \"registerIdentity\";\n readonly args: RegisterIdentityCommandArgs;\n private readonly errorHelper = new CommandErrorHelper<\n RegisterIdentityCommandResponse,\n ContactsErrorCodes\n >(CONTACTS_APP_ERRORS, contactsCommandErrorFactory);\n\n constructor(args: RegisterIdentityCommandArgs) {\n this.args = args;\n }\n\n getApdu(): Apdu {\n return new ApduBuilder({\n cla: CONTACTS_APDU_CLA,\n ins: CONTACTS_APDU_INS,\n p1: SUB_CMD_REGISTER_IDENTITY,\n p2: this.args.p2,\n })\n .addBufferToData(this.args.data)\n .build();\n }\n\n parseResponse(\n response: ApduResponse,\n ): CommandResult<RegisterIdentityCommandResponse, ContactsErrorCodes> {\n return Maybe.fromNullable(\n this.errorHelper.getError(response),\n ).orDefaultLazy(() => {\n if (response.data.length === 0) {\n // Intermediate chunk \u2014 device acks with SW=0x9000 and no payload.\n return CommandResultFactory({ data: {} });\n }\n\n const parser = new ApduParser(response);\n\n const structType = parser.extract8BitUInt();\n if (structType !== RESPONSE_STRUCT_TYPE) {\n return CommandResultFactory({\n error: new InvalidStatusWordError(\n `Expected struct_type 0x${RESPONSE_STRUCT_TYPE.toString(16)}, got ${\n structType === undefined\n ? \"undefined\"\n : `0x${structType.toString(16)}`\n }`,\n ),\n });\n }\n\n const groupHandle = extractField(parser, GROUP_HANDLE_BYTES);\n if (!groupHandle) {\n return CommandResultFactory({\n error: new InvalidStatusWordError(\n \"group_handle missing or truncated\",\n ),\n });\n }\n\n const hmacProof = extractField(parser, HMAC_PROOF_BYTES);\n if (!hmacProof) {\n return CommandResultFactory({\n error: new InvalidStatusWordError(\"hmac_name missing or truncated\"),\n });\n }\n\n const hmacRest = extractField(parser, HMAC_REST_BYTES);\n if (!hmacRest) {\n return CommandResultFactory({\n error: new InvalidStatusWordError(\"hmac_rest missing or truncated\"),\n });\n }\n\n return CommandResultFactory({\n data: { groupHandle, hmacProof, hmacRest },\n });\n });\n }\n}\n"],
|
|
5
|
+
"mappings": "yaAAA,IAAAA,EAAA,GAAAC,EAAAD,EAAA,6BAAAE,IAAA,eAAAC,EAAAH,GAQA,IAAAI,EASO,2CACPC,EAAmC,kCACnCC,EAAsB,qBAEtBC,EAOO,wDACPC,EAIO,qDAuBP,MAAMC,EAAuB,GAO7B,SAASC,EACPC,EACAC,EACwB,CACxB,MAAMC,EAAQF,EAAO,qBAAqBC,CAAM,EAChD,GAAI,GAACC,GAASA,EAAM,SAAWD,GAC/B,OAAO,WAAW,KAAKC,CAAK,CAC9B,CAEO,MAAMX,CAOb,CACW,KAAO,mBACP,KACQ,YAAc,IAAI,qBAGjC,sBAAqB,6BAA2B,EAElD,YAAYY,EAAmC,CAC7C,KAAK,KAAOA,CACd,CAEA,SAAgB,CACd,OAAO,IAAI,cAAY,CACrB,IAAK,oBACL,IAAK,oBACL,GAAI,4BACJ,GAAI,KAAK,KAAK,EAChB,CAAC,EACE,gBAAgB,KAAK,KAAK,IAAI,EAC9B,MAAM,CACX,CAEA,cACEC,EACoE,CACpE,OAAO,QAAM,aACX,KAAK,YAAY,SAASA,CAAQ,CACpC,EAAE,cAAc,IAAM,CACpB,GAAIA,EAAS,KAAK,SAAW,EAE3B,SAAO,wBAAqB,CAAE,KAAM,CAAC,CAAE,CAAC,EAG1C,MAAMJ,EAAS,IAAI,aAAWI,CAAQ,EAEhCC,EAAaL,EAAO,gBAAgB,EAC1C,GAAIK,IAAeP,EACjB,SAAO,wBAAqB,CAC1B,MAAO,IAAI,yBACT,0BAA0BA,EAAqB,SAAS,EAAE,CAAC,SACzDO,IAAe,OACX,YACA,KAAKA,EAAW,SAAS,EAAE,CAAC,EAClC,EACF,CACF,CAAC,EAGH,MAAMC,EAAcP,EAAaC,EAAQ,oBAAkB,EAC3D,GAAI,CAACM,EACH,SAAO,wBAAqB,CAC1B,MAAO,IAAI,yBACT,mCACF,CACF,CAAC,EAGH,MAAMC,EAAYR,EAAaC,EAAQ,kBAAgB,EACvD,GAAI,CAACO,EACH,SAAO,wBAAqB,CAC1B,MAAO,IAAI,yBAAuB,gCAAgC,CACpE,CAAC,EAGH,MAAMC,EAAWT,EAAaC,EAAQ,iBAAe,EACrD,OAAKQ,KAME,wBAAqB,CAC1B,KAAM,CAAE,YAAAF,EAAa,UAAAC,EAAW,SAAAC,CAAS,CAC3C,CAAC,KAPQ,wBAAqB,CAC1B,MAAO,IAAI,yBAAuB,gCAAgC,CACpE,CAAC,CAML,CAAC,CACH,CACF",
|
|
6
|
+
"names": ["RegisterIdentityCommand_exports", "__export", "RegisterIdentityCommand", "__toCommonJS", "import_device_management_kit", "import_signer_utils", "import_purify_ts", "import_contactsConstants", "import_contactsErrors", "RESPONSE_STRUCT_TYPE", "extractField", "parser", "length", "field", "args", "response", "structType", "groupHandle", "hmacProof", "hmacRest"]
|
|
7
|
+
}
|
|
@@ -0,0 +1,2 @@
|
|
|
1
|
+
"use strict";var r=require("@ledgerhq/device-management-kit"),s=require("../../app-binder/model/contactsErrors"),a=require("./RegisterIdentityCommand");function n(e){const t=new Uint8Array(e.length/2);for(let o=0;o<e.length;o+=2)t[o/2]=parseInt(e.slice(o,o+2),16);return t}const m=n("cc".repeat(64)),p=n("dd".repeat(32)),u=n("aa".repeat(32)),c="2d"+"cc".repeat(64)+"dd".repeat(32)+"aa".repeat(32);function d(e){return{data:Buffer.from(n(e)),statusCode:Buffer.from([144,0])}}describe("RegisterIdentityCommand",()=>{describe("getApdu",()=>{it("wraps the framed chunk under B0 10 01 with P2=0x00 for the first/only chunk",()=>{const e=Uint8Array.from([0,3,170,187,204]),t=new a.RegisterIdentityCommand({data:e,p2:0}).getApdu();expect(t.getRawApdu()).toStrictEqual(Uint8Array.from([176,16,1,0,5,0,3,170,187,204]))}),it("uses P2=0x80 for continuation chunks",()=>{const e=Uint8Array.from([170,187]),t=new a.RegisterIdentityCommand({data:e,p2:128}).getApdu();expect(t.getRawApdu()).toStrictEqual(Uint8Array.from([176,16,1,128,2,170,187]))})}),describe("parseResponse",()=>{it("returns an empty payload for an intermediate chunk (SW=0x9000, no data)",()=>{const e=new a.RegisterIdentityCommand({data:new Uint8Array,p2:0}).parseResponse({data:Buffer.from([]),statusCode:Buffer.from([144,0])});expect(e).toStrictEqual({status:r.CommandResultStatus.Success,data:{}})}),it("extracts group_handle / hmac_name / hmac_rest from a register response",()=>{const t=new a.RegisterIdentityCommand({data:new Uint8Array,p2:0}).parseResponse(d(c));expect(t).toStrictEqual({status:r.CommandResultStatus.Success,data:{groupHandle:m,hmacProof:p,hmacRest:u}})}),it("returns InvalidStatusWordError when struct_type is wrong",()=>{const e="ee"+c.slice(2),o=new a.RegisterIdentityCommand({data:new Uint8Array,p2:0}).parseResponse(d(e));expect(o.status).toBe(r.CommandResultStatus.Error)}),it("maps a known SW (0x6985) to a ContactsCommandError",()=>{const t=new a.RegisterIdentityCommand({data:new Uint8Array,p2:0}).parseResponse({data:Buffer.from([]),statusCode:Buffer.from([105,133])});expect(t.status).toBe(r.CommandResultStatus.Error),t.status===r.CommandResultStatus.Error&&(expect(t.error).toBeInstanceOf(s.ContactsCommandError),expect(t.error.errorCode).toBe("6985"))}),it("maps SW=0x6982 to a seed-mismatch ContactsCommandError",()=>{const t=new a.RegisterIdentityCommand({data:new Uint8Array,p2:0}).parseResponse({data:Buffer.from([]),statusCode:Buffer.from([105,130])});expect(t.status).toBe(r.CommandResultStatus.Error),t.status===r.CommandResultStatus.Error&&(expect(t.error).toBeInstanceOf(s.ContactsCommandError),expect(t.error.errorCode).toBe(s.CONTACT_SEED_MISMATCH_ERROR_CODE))})})});
|
|
2
|
+
//# sourceMappingURL=RegisterIdentityCommand.test.js.map
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
{
|
|
2
|
+
"version": 3,
|
|
3
|
+
"sources": ["../../../../../src/internal/app-binder/command/RegisterIdentityCommand.test.ts"],
|
|
4
|
+
"sourcesContent": ["// RegisterIdentityCommand is a thin chunk-framer: it wraps a pre-framed chunk\n// (2-byte BE length prefix + TLV, assembled by SendRegisterIdentityTask +\n// sendFramedContactsPayload) under B0 10 01 <P2>, and parses the 129-byte\n// register response on the final chunk. TLV byte-parity is asserted in\n// SendRegisterIdentityTask.test.ts.\nimport {\n type ApduResponse,\n CommandResultStatus,\n} from \"@ledgerhq/device-management-kit\";\n\nimport {\n CONTACT_SEED_MISMATCH_ERROR_CODE,\n ContactsCommandError,\n} from \"@internal/app-binder/model/contactsErrors\";\n\nimport { RegisterIdentityCommand } from \"./RegisterIdentityCommand\";\n\nfunction hexToBytes(hex: string): Uint8Array {\n const out = new Uint8Array(hex.length / 2);\n for (let i = 0; i < hex.length; i += 2) {\n out[i / 2] = parseInt(hex.slice(i, i + 2), 16);\n }\n return out;\n}\n\n// Device response: struct_type(0x2d) + group_handle(64) + hmac_name(32) +\n// hmac_rest(32).\nconst GROUP_HANDLE = hexToBytes(\"cc\".repeat(64));\nconst HMAC_PROOF = hexToBytes(\"dd\".repeat(32));\nconst HMAC_REST = hexToBytes(\"aa\".repeat(32));\nconst RESPONSE_HEX = \"2d\" + \"cc\".repeat(64) + \"dd\".repeat(32) + \"aa\".repeat(32);\n\nfunction makeResponse(hex: string): ApduResponse {\n return {\n data: Buffer.from(hexToBytes(hex)),\n statusCode: Buffer.from([0x90, 0x00]),\n };\n}\n\ndescribe(\"RegisterIdentityCommand\", () => {\n describe(\"getApdu\", () => {\n it(\"wraps the framed chunk under B0 10 01 with P2=0x00 for the first/only chunk\", () => {\n const data = Uint8Array.from([0x00, 0x03, 0xaa, 0xbb, 0xcc]);\n\n const apdu = new RegisterIdentityCommand({ data, p2: 0x00 }).getApdu();\n\n expect(apdu.getRawApdu()).toStrictEqual(\n Uint8Array.from([\n 0xb0, 0x10, 0x01, 0x00, 0x05, 0x00, 0x03, 0xaa, 0xbb, 0xcc,\n ]),\n );\n });\n\n it(\"uses P2=0x80 for continuation chunks\", () => {\n const data = Uint8Array.from([0xaa, 0xbb]);\n\n const apdu = new RegisterIdentityCommand({ data, p2: 0x80 }).getApdu();\n\n expect(apdu.getRawApdu()).toStrictEqual(\n Uint8Array.from([0xb0, 0x10, 0x01, 0x80, 0x02, 0xaa, 0xbb]),\n );\n });\n });\n\n describe(\"parseResponse\", () => {\n it(\"returns an empty payload for an intermediate chunk (SW=0x9000, no data)\", () => {\n const result = new RegisterIdentityCommand({\n data: new Uint8Array(),\n p2: 0x00,\n }).parseResponse({\n data: Buffer.from([]),\n statusCode: Buffer.from([0x90, 0x00]),\n });\n\n expect(result).toStrictEqual({\n status: CommandResultStatus.Success,\n data: {},\n });\n });\n\n it(\"extracts group_handle / hmac_name / hmac_rest from a register response\", () => {\n const command = new RegisterIdentityCommand({\n data: new Uint8Array(),\n p2: 0x00,\n });\n\n const result = command.parseResponse(makeResponse(RESPONSE_HEX));\n\n expect(result).toStrictEqual({\n status: CommandResultStatus.Success,\n data: {\n groupHandle: GROUP_HANDLE,\n hmacProof: HMAC_PROOF,\n hmacRest: HMAC_REST,\n },\n });\n });\n\n it(\"returns InvalidStatusWordError when struct_type is wrong\", () => {\n const wrongType = \"ee\" + RESPONSE_HEX.slice(2); // replace 0x2d with 0xee\n const command = new RegisterIdentityCommand({\n data: new Uint8Array(),\n p2: 0x00,\n });\n\n const result = command.parseResponse(makeResponse(wrongType));\n\n expect(result.status).toBe(CommandResultStatus.Error);\n });\n\n it(\"maps a known SW (0x6985) to a ContactsCommandError\", () => {\n const command = new RegisterIdentityCommand({\n data: new Uint8Array(),\n p2: 0x00,\n });\n\n const result = command.parseResponse({\n data: Buffer.from([]),\n statusCode: Buffer.from([0x69, 0x85]),\n });\n\n expect(result.status).toBe(CommandResultStatus.Error);\n if (result.status === CommandResultStatus.Error) {\n expect(result.error).toBeInstanceOf(ContactsCommandError);\n expect((result.error as ContactsCommandError).errorCode).toBe(\"6985\");\n }\n });\n\n it(\"maps SW=0x6982 to a seed-mismatch ContactsCommandError\", () => {\n // Reached when extending an existing contact whose group handle was\n // registered with another seed (once the app verifies before the UI).\n const command = new RegisterIdentityCommand({\n data: new Uint8Array(),\n p2: 0x00,\n });\n\n const result = command.parseResponse({\n data: Buffer.from([]),\n statusCode: Buffer.from([0x69, 0x82]),\n });\n\n expect(result.status).toBe(CommandResultStatus.Error);\n if (result.status === CommandResultStatus.Error) {\n expect(result.error).toBeInstanceOf(ContactsCommandError);\n expect((result.error as ContactsCommandError).errorCode).toBe(\n CONTACT_SEED_MISMATCH_ERROR_CODE,\n );\n }\n });\n });\n});\n"],
|
|
5
|
+
"mappings": "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",
|
|
6
|
+
"names": ["import_device_management_kit", "import_contactsErrors", "import_RegisterIdentityCommand", "hexToBytes", "hex", "out", "i", "GROUP_HANDLE", "HMAC_PROOF", "HMAC_REST", "RESPONSE_HEX", "makeResponse", "data", "apdu", "result", "wrongType"]
|
|
7
|
+
}
|
|
@@ -0,0 +1,2 @@
|
|
|
1
|
+
"use strict";var u=Object.defineProperty;var S=Object.getOwnPropertyDescriptor;var R=Object.getOwnPropertyNames;var I=Object.prototype.hasOwnProperty;var y=(s,n)=>{for(var p in n)u(s,p,{get:n[p],enumerable:!0})},h=(s,n,p,l)=>{if(n&&typeof n=="object"||typeof n=="function")for(let r of R(n))!I.call(s,r)&&r!==p&&u(s,r,{get:()=>n[r],enumerable:!(l=S(n,r))||l.enumerable});return s};var D=s=>h(u({},"__esModule",{value:!0}),s);var V={};y(V,{RegisterExternalAddressDeviceAction:()=>x});module.exports=D(V);var i=require("@ledgerhq/device-management-kit"),c=require("purify-ts"),a=require("xstate"),A=require("../../../app-binder/isContactsSupportedForSession"),g=require("../../../app-binder/model/contactsErrors"),m=require("../../../app-binder/task/SendRegisterIdentityTask"),E=require("./validateRegisterExternalAddressInput");class x extends i.XStateDeviceAction{makeStateMachine(n){const{isSupported:p,registerIdentity:l}=this.extractDependencies(n),r=this.input.appName;return(0,a.setup)({types:{input:{},context:{},output:{}},actors:{openAppStateMachine:new i.OpenAppDeviceAction({input:{appName:r}}).makeStateMachine(n),waitForAppAndVersionStateMachine:new i.WaitForAppAndVersionDeviceAction({input:{}}).makeStateMachine(n),registerIdentity:(0,a.fromPromise)(({input:e})=>l(e))},guards:{skipOpenApp:({context:e})=>e.input.skipOpenApp===!0,noInternalError:({context:e})=>e._internalState.error===null,contactsSupported:({context:e})=>{const{appAndVersion:t}=e._internalState;return t!==null&&p(t)}},actions:{assignValidationError:(0,a.assign)({_internalState:({context:e})=>{const t=(0,E.validateRegisterExternalAddressInput)(e.input);return t?{...e._internalState,error:t}:e._internalState}}),assignVersionError:(0,a.assign)({_internalState:({context:e})=>({...e._internalState,error:new g.ContactsVersionRequirementError})}),assignErrorFromEvent:(0,a.assign)({_internalState:({context:e,event:t})=>({...e._internalState,error:new i.UnknownDAError(t.error instanceof Error?t.error.message:String(t.error))})})}}).createMachine({id:"RegisterExternalAddressDeviceAction",initial:"InitialState",context:({input:e})=>({input:e,intermediateValue:{requiredUserInteraction:i.UserInteractionRequired.None},_internalState:{error:null,appAndVersion:null,proofs:null}}),states:{InitialState:{always:[{target:"ValidateInput",guard:"skipOpenApp"},{target:"OpenAppDeviceAction"}]},OpenAppDeviceAction:{invoke:{id:"openAppStateMachine",src:"openAppStateMachine",input:()=>({appName:r}),onSnapshot:{actions:(0,a.assign)({intermediateValue:({event:e})=>e.snapshot.context.intermediateValue})},onDone:{target:"CheckOpenAppResult",actions:(0,a.assign)({_internalState:({event:e,context:t})=>e.output.caseOf({Right:()=>t._internalState,Left:o=>({...t._internalState,error:o})})})}}},CheckOpenAppResult:{always:[{target:"ValidateInput",guard:"noInternalError"},{target:"Error"}]},ValidateInput:{entry:"assignValidationError",always:[{target:"WaitForAppAndVersion",guard:"noInternalError"},{target:"Error"}]},WaitForAppAndVersion:{entry:(0,a.assign)({intermediateValue:{requiredUserInteraction:i.UserInteractionRequired.None}}),invoke:{id:"waitForAppAndVersion",src:"waitForAppAndVersionStateMachine",input:()=>({}),onSnapshot:{actions:(0,a.assign)({intermediateValue:({event:e})=>e.snapshot.context.intermediateValue})},onDone:{target:"CheckAppAndVersion",actions:(0,a.assign)({_internalState:({event:e,context:t})=>e.output.caseOf({Right:o=>({...t._internalState,appAndVersion:{name:o.name,version:o.version}}),Left:o=>({...t._internalState,error:o})})})}}},CheckAppAndVersion:{always:[{target:"VersionGuard",guard:"noInternalError"},{target:"Error"}]},VersionGuard:{always:[{target:"RegisterIdentity",guard:"contactsSupported"},{target:"Error",actions:"assignVersionError"}]},RegisterIdentity:{entry:(0,a.assign)({intermediateValue:{requiredUserInteraction:i.UserInteractionRequired.RegisterWallet}}),exit:(0,a.assign)({intermediateValue:{requiredUserInteraction:i.UserInteractionRequired.None}}),invoke:{id:"registerIdentity",src:"registerIdentity",input:({context:e})=>e.input,onDone:{target:"RegisterIdentityResultCheck",actions:(0,a.assign)({_internalState:({event:e,context:t})=>(0,i.isSuccessCommandResult)(e.output)?{...t._internalState,proofs:e.output.data}:{...t._internalState,error:e.output.error}})},onError:{target:"Error",actions:"assignErrorFromEvent"}}},RegisterIdentityResultCheck:{always:[{target:"Success",guard:"noInternalError"},{target:"Error"}]},Success:{type:"final"},Error:{type:"final"}},output:({context:e})=>{const{proofs:t,error:o}=e._internalState;if(t){const{input:d}=e;return(0,c.Right)({mode:d.existingContactGroup?"existingContactGroup":"newContactGroup",contactName:d.contactName,scope:d.scope,identifier:d.identifier,blockchainFamily:d.blockchainFamily,chainId:d.chainId,groupHandle:t.groupHandle,hmacProof:t.hmacProof,hmacRest:t.hmacRest})}return(0,c.Left)(o??new i.UnknownDAError("No error in final state"))}})}extractDependencies(n){return{isSupported:r=>(0,A.isContactsSupportedForSession)(n,r),registerIdentity:r=>new m.SendRegisterIdentityTask(n,{contactName:r.contactName,scope:r.scope,identifier:r.identifier,blockchainFamily:r.blockchainFamily,chainId:r.chainId,existingContactGroup:r.existingContactGroup}).run()}}}0&&(module.exports={RegisterExternalAddressDeviceAction});
|
|
2
|
+
//# sourceMappingURL=RegisterExternalAddressDeviceAction.js.map
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
{
|
|
2
|
+
"version": 3,
|
|
3
|
+
"sources": ["../../../../../../src/internal/app-binder/device-action/RegisterExternalAddress/RegisterExternalAddressDeviceAction.ts"],
|
|
4
|
+
"sourcesContent": ["import {\n type DeviceActionStateMachine,\n type InternalApi,\n isSuccessCommandResult,\n OpenAppDeviceAction,\n type StateMachineTypes,\n UnknownDAError,\n UserInteractionRequired,\n WaitForAppAndVersionDeviceAction,\n XStateDeviceAction,\n} from \"@ledgerhq/device-management-kit\";\nimport { Left, Right } from \"purify-ts\";\nimport { assign, fromPromise, setup } from \"xstate\";\n\nimport {\n type RegisterExternalAddressDAError,\n type RegisterExternalAddressDAInput,\n type RegisterExternalAddressDAIntermediateValue,\n type RegisterExternalAddressDAInternalState,\n type RegisterExternalAddressDAOutput,\n} from \"@api/app-binder/RegisterExternalAddressDeviceActionTypes\";\nimport {\n isContactsSupportedForSession,\n type RunningApp,\n} from \"@internal/app-binder/isContactsSupportedForSession\";\nimport { ContactsVersionRequirementError } from \"@internal/app-binder/model/contactsErrors\";\nimport {\n type RegisterIdentityProofs,\n SendRegisterIdentityTask,\n} from \"@internal/app-binder/task/SendRegisterIdentityTask\";\n\nimport { validateRegisterExternalAddressInput } from \"./validateRegisterExternalAddressInput\";\n\nexport type RegisterExternalAddressMachineDependencies = {\n readonly isSupported: (app: RunningApp) => boolean;\n readonly registerIdentity: (\n input: RegisterExternalAddressDAInput,\n ) => Promise<Awaited<ReturnType<SendRegisterIdentityTask[\"run\"]>>>;\n};\n\nexport class RegisterExternalAddressDeviceAction extends XStateDeviceAction<\n RegisterExternalAddressDAOutput,\n RegisterExternalAddressDAInput,\n RegisterExternalAddressDAError,\n RegisterExternalAddressDAIntermediateValue,\n RegisterExternalAddressDAInternalState\n> {\n makeStateMachine(\n internalApi: InternalApi,\n ): DeviceActionStateMachine<\n RegisterExternalAddressDAOutput,\n RegisterExternalAddressDAInput,\n RegisterExternalAddressDAError,\n RegisterExternalAddressDAIntermediateValue,\n RegisterExternalAddressDAInternalState\n > {\n type types = StateMachineTypes<\n RegisterExternalAddressDAOutput,\n RegisterExternalAddressDAInput,\n RegisterExternalAddressDAError,\n RegisterExternalAddressDAIntermediateValue,\n RegisterExternalAddressDAInternalState\n >;\n\n const { isSupported, registerIdentity } =\n this.extractDependencies(internalApi);\n const appName = this.input.appName;\n\n return setup({\n types: {\n input: {} as types[\"input\"],\n context: {} as types[\"context\"],\n output: {} as types[\"output\"],\n },\n actors: {\n openAppStateMachine: new OpenAppDeviceAction({\n input: { appName },\n }).makeStateMachine(internalApi),\n waitForAppAndVersionStateMachine: new WaitForAppAndVersionDeviceAction({\n input: {},\n }).makeStateMachine(internalApi),\n registerIdentity: fromPromise(\n ({ input }: { input: RegisterExternalAddressDAInput }) =>\n registerIdentity(input),\n ),\n },\n guards: {\n skipOpenApp: ({ context }) => context.input.skipOpenApp === true,\n noInternalError: ({ context }) => context._internalState.error === null,\n contactsSupported: ({ context }) => {\n const { appAndVersion } = context._internalState;\n return appAndVersion !== null && isSupported(appAndVersion);\n },\n },\n actions: {\n assignValidationError: assign({\n _internalState: ({ context }) => {\n const error = validateRegisterExternalAddressInput(context.input);\n return error\n ? { ...context._internalState, error }\n : context._internalState;\n },\n }),\n assignVersionError: assign({\n _internalState: ({ context }) => ({\n ...context._internalState,\n error: new ContactsVersionRequirementError(),\n }),\n }),\n assignErrorFromEvent: assign({\n _internalState: ({ context, event }) => ({\n ...context._internalState,\n error: new UnknownDAError(\n event[\"error\"] instanceof Error\n ? event[\"error\"].message\n : String(event[\"error\"]),\n ),\n }),\n }),\n },\n }).createMachine({\n id: \"RegisterExternalAddressDeviceAction\",\n initial: \"InitialState\",\n context: ({ input }) => ({\n input,\n intermediateValue: {\n requiredUserInteraction: UserInteractionRequired.None,\n },\n _internalState: {\n error: null,\n appAndVersion: null,\n proofs: null,\n },\n }),\n states: {\n InitialState: {\n always: [\n { target: \"ValidateInput\", guard: \"skipOpenApp\" },\n { target: \"OpenAppDeviceAction\" },\n ],\n },\n OpenAppDeviceAction: {\n invoke: {\n id: \"openAppStateMachine\",\n src: \"openAppStateMachine\",\n input: () => ({ appName }),\n onSnapshot: {\n actions: assign({\n intermediateValue: ({ event }) =>\n event.snapshot.context.intermediateValue,\n }),\n },\n onDone: {\n target: \"CheckOpenAppResult\",\n actions: assign({\n _internalState: ({ event, context }) =>\n event.output.caseOf<RegisterExternalAddressDAInternalState>({\n Right: () => context._internalState,\n Left: (error) => ({ ...context._internalState, error }),\n }),\n }),\n },\n },\n },\n CheckOpenAppResult: {\n always: [\n { target: \"ValidateInput\", guard: \"noInternalError\" },\n { target: \"Error\" },\n ],\n },\n // Input validation runs inside the device action (after the app is\n // opened) so invalid caller input surfaces as a typed terminal error\n // state on the observable instead of a synchronous throw. Runs on both\n // the open-app and skip-open-app paths.\n ValidateInput: {\n entry: \"assignValidationError\",\n always: [\n { target: \"WaitForAppAndVersion\", guard: \"noInternalError\" },\n { target: \"Error\" },\n ],\n },\n // Read the running app + version freshly from the device (rather than\n // the possibly-stale session state) so the version guard evaluates the\n // app that is actually running \u2014 e.g. when open-app is skipped and the\n // app was changed outside DMK. Runs on both paths.\n WaitForAppAndVersion: {\n // Start the phase from a clean value, clearing any interaction left\n // over from the OpenApp phase (e.g. ConfirmOpenApp).\n entry: assign({\n intermediateValue: {\n requiredUserInteraction: UserInteractionRequired.None,\n },\n }),\n invoke: {\n id: \"waitForAppAndVersion\",\n src: \"waitForAppAndVersionStateMachine\",\n input: () => ({}),\n // Propagate the child DA's intermediate value so a consuming client\n // can render, e.g., a \"please unlock your device\" prompt when the\n // device is locked. Mirrors the OpenAppDeviceAction invoke above.\n onSnapshot: {\n actions: assign({\n intermediateValue: ({ event }) =>\n event.snapshot.context.intermediateValue,\n }),\n },\n onDone: {\n target: \"CheckAppAndVersion\",\n actions: assign({\n _internalState: ({ event, context }) =>\n event.output.caseOf<RegisterExternalAddressDAInternalState>({\n Right: (appAndVersion) => ({\n ...context._internalState,\n appAndVersion: {\n name: appAndVersion.name,\n version: appAndVersion.version,\n },\n }),\n Left: (error) => ({ ...context._internalState, error }),\n }),\n }),\n },\n },\n },\n CheckAppAndVersion: {\n always: [\n { target: \"VersionGuard\", guard: \"noInternalError\" },\n { target: \"Error\" },\n ],\n },\n // Version guard evaluates support from the fresh WaitForAppAndVersion\n // result. Runs on both the open-app and skip-open-app paths.\n VersionGuard: {\n always: [\n { target: \"RegisterIdentity\", guard: \"contactsSupported\" },\n { target: \"Error\", actions: \"assignVersionError\" },\n ],\n },\n RegisterIdentity: {\n entry: assign({\n intermediateValue: {\n requiredUserInteraction: UserInteractionRequired.RegisterWallet,\n },\n }),\n exit: assign({\n intermediateValue: {\n requiredUserInteraction: UserInteractionRequired.None,\n },\n }),\n invoke: {\n id: \"registerIdentity\",\n src: \"registerIdentity\",\n input: ({ context }) => context.input,\n onDone: {\n target: \"RegisterIdentityResultCheck\",\n actions: assign({\n _internalState: ({ event, context }) =>\n isSuccessCommandResult(event.output)\n ? { ...context._internalState, proofs: event.output.data }\n : {\n ...context._internalState,\n error: event.output.error,\n },\n }),\n },\n onError: {\n target: \"Error\",\n actions: \"assignErrorFromEvent\",\n },\n },\n },\n RegisterIdentityResultCheck: {\n always: [\n { target: \"Success\", guard: \"noInternalError\" },\n { target: \"Error\" },\n ],\n },\n Success: { type: \"final\" },\n Error: { type: \"final\" },\n },\n output: ({ context }) => {\n const { proofs, error } = context._internalState;\n if (proofs) {\n const { input } = context;\n return Right({\n mode: input.existingContactGroup\n ? (\"existingContactGroup\" as const)\n : (\"newContactGroup\" as const),\n contactName: input.contactName,\n scope: input.scope,\n identifier: input.identifier,\n blockchainFamily: input.blockchainFamily,\n chainId: input.chainId,\n groupHandle: proofs.groupHandle,\n hmacProof: proofs.hmacProof,\n hmacRest: proofs.hmacRest,\n });\n }\n return Left(error ?? new UnknownDAError(\"No error in final state\"));\n },\n });\n }\n\n extractDependencies(\n internalApi: InternalApi,\n ): RegisterExternalAddressMachineDependencies {\n const isSupported = (app: RunningApp) =>\n isContactsSupportedForSession(internalApi, app);\n\n const registerIdentity = (\n input: RegisterExternalAddressDAInput,\n ): Promise<Awaited<ReturnType<SendRegisterIdentityTask[\"run\"]>>> =>\n new SendRegisterIdentityTask(internalApi, {\n contactName: input.contactName,\n scope: input.scope,\n identifier: input.identifier,\n blockchainFamily: input.blockchainFamily,\n chainId: input.chainId,\n existingContactGroup: input.existingContactGroup,\n }).run();\n\n return { isSupported, registerIdentity };\n }\n}\n\nexport type { RegisterIdentityProofs };\n"],
|
|
5
|
+
"mappings": "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",
|
|
6
|
+
"names": ["RegisterExternalAddressDeviceAction_exports", "__export", "RegisterExternalAddressDeviceAction", "__toCommonJS", "import_device_management_kit", "import_purify_ts", "import_xstate", "import_isContactsSupportedForSession", "import_contactsErrors", "import_SendRegisterIdentityTask", "import_validateRegisterExternalAddressInput", "internalApi", "isSupported", "registerIdentity", "appName", "input", "context", "appAndVersion", "error", "event", "proofs", "app"]
|
|
7
|
+
}
|
|
@@ -0,0 +1,2 @@
|
|
|
1
|
+
"use strict";var e=require("@ledgerhq/device-management-kit"),r=require("vitest"),R=require("../../../app-binder/device-action/__test-utils__/makeInternalApi"),c=require("../../../app-binder/device-action/__test-utils__/setupOpenAppDAMock"),E=require("../../../app-binder/device-action/__test-utils__/setupWaitForAppAndVersionDAMock"),p=require("../../../app-binder/device-action/__test-utils__/testDeviceActionStates"),D=require("../../../app-binder/model/contactsErrors"),f=require("./RegisterExternalAddressDeviceAction"),v=require("./validateRegisterExternalAddressInput");r.vi.mock("@ledgerhq/device-management-kit",async o=>({...await o(),OpenAppDeviceAction:r.vi.fn(()=>({makeStateMachine:r.vi.fn()})),WaitForAppAndVersionDeviceAction:r.vi.fn(()=>({makeStateMachine:r.vi.fn()}))}));const x={name:"Ethereum",version:"1.15.0"},g={groupHandle:new Uint8Array(64).fill(204),hmacProof:new Uint8Array(32).fill(221),hmacRest:new Uint8Array(32).fill(170)},s={contactName:"Alice",scope:"Eth main",identifier:new Uint8Array(20).fill(17),blockchainFamily:"ethereum",chainId:1n,appName:"Ethereum"};(0,r.describe)("RegisterExternalAddressDeviceAction",()=>{let o,l,A;function I(){return{isSupported:l,registerIdentity:A}}(0,r.beforeEach)(()=>{o=(0,R.makeDeviceActionInternalApiMock)(),(0,E.setupWaitForAppAndVersionDAMock)(x),l=r.vi.fn().mockReturnValue(!0),A=r.vi.fn().mockResolvedValue((0,e.CommandResultFactory)({data:g})),o.getDeviceSessionState.mockReturnValue({sessionStateType:e.DeviceSessionStateType.ReadyWithoutSecureChannel,deviceStatus:e.DeviceStatus.CONNECTED,installedApps:[],currentApp:{name:"Ethereum",version:"1.15.0"},deviceModelId:e.DeviceModelId.FLEX,isSecureConnectionAllowed:!0})});function u(i){const n=new f.RegisterExternalAddressDeviceAction({input:i});return r.vi.spyOn(n,"extractDependencies").mockReturnValue(I()),n}(0,r.it)("open-app path, new contact group: OpenApp -> VersionGuard -> RegisterIdentity -> Completed",()=>new Promise((i,n)=>{(0,c.setupOpenAppDAMock)();const t=u({...s,skipOpenApp:!1}),a=[{intermediateValue:{requiredUserInteraction:e.UserInteractionRequired.None},status:e.DeviceActionStatus.Pending},{intermediateValue:{requiredUserInteraction:e.UserInteractionRequired.ConfirmOpenApp},status:e.DeviceActionStatus.Pending},{intermediateValue:{requiredUserInteraction:e.UserInteractionRequired.None},status:e.DeviceActionStatus.Pending},{intermediateValue:{requiredUserInteraction:e.UserInteractionRequired.None},status:e.DeviceActionStatus.Pending},{intermediateValue:{requiredUserInteraction:e.UserInteractionRequired.RegisterWallet},status:e.DeviceActionStatus.Pending},{output:{mode:"newContactGroup",contactName:"Alice",scope:"Eth main",identifier:s.identifier,blockchainFamily:"ethereum",chainId:1n,...g},status:e.DeviceActionStatus.Completed}];(0,p.testDeviceActionStates)(t,a,o,{onDone:i,onError:n})})),(0,r.it)("skip-open-app path, existing contact group: VersionGuard -> RegisterIdentity -> Completed",()=>new Promise((i,n)=>{(0,c.setupOpenAppDAMock)();const t={groupHandle:new Uint8Array(64).fill(204),hmacProof:new Uint8Array(32).fill(221)},a=u({...s,skipOpenApp:!0,existingContactGroup:t}),d=[{intermediateValue:{requiredUserInteraction:e.UserInteractionRequired.None},status:e.DeviceActionStatus.Pending},{intermediateValue:{requiredUserInteraction:e.UserInteractionRequired.None},status:e.DeviceActionStatus.Pending},{intermediateValue:{requiredUserInteraction:e.UserInteractionRequired.RegisterWallet},status:e.DeviceActionStatus.Pending},{output:{mode:"existingContactGroup",contactName:"Alice",scope:"Eth main",identifier:s.identifier,blockchainFamily:"ethereum",chainId:1n,...g},status:e.DeviceActionStatus.Completed}];(0,p.testDeviceActionStates)(a,d,o,{onDone:i,onError:n})})),(0,r.it)("version guard rejects on skip-open-app path without opening the app",()=>new Promise((i,n)=>{(0,c.setupOpenAppDAMock)(),l.mockReturnValue(!1);const t=u({...s,skipOpenApp:!0}),a=[{intermediateValue:{requiredUserInteraction:e.UserInteractionRequired.None},status:e.DeviceActionStatus.Pending},{intermediateValue:{requiredUserInteraction:e.UserInteractionRequired.None},status:e.DeviceActionStatus.Pending},{error:new D.ContactsVersionRequirementError,status:e.DeviceActionStatus.Error}];(0,p.testDeviceActionStates)(t,a,o,{onDone:i,onError:n}),expect(A).not.toHaveBeenCalled()})),(0,r.it)("surfaces an open-app failure as the device action error",()=>new Promise((i,n)=>{const t=new e.UnknownDAError("open app failed");(0,c.setupOpenAppDAMock)(t);const a=u({...s,skipOpenApp:!1}),d=[{intermediateValue:{requiredUserInteraction:e.UserInteractionRequired.None},status:e.DeviceActionStatus.Pending},{intermediateValue:{requiredUserInteraction:e.UserInteractionRequired.ConfirmOpenApp},status:e.DeviceActionStatus.Pending},{error:t,status:e.DeviceActionStatus.Error}];(0,p.testDeviceActionStates)(a,d,o,{onDone:i,onError:n}),expect(l).not.toHaveBeenCalled()})),(0,r.it)("surfaces a Register Identity command error",()=>new Promise((i,n)=>{(0,c.setupOpenAppDAMock)();const t=new D.ContactsCommandError({errorCode:"6a80",message:"device rejected"});A.mockResolvedValue((0,e.CommandResultFactory)({error:t}));const a=u({...s,skipOpenApp:!0}),d=[{intermediateValue:{requiredUserInteraction:e.UserInteractionRequired.None},status:e.DeviceActionStatus.Pending},{intermediateValue:{requiredUserInteraction:e.UserInteractionRequired.None},status:e.DeviceActionStatus.Pending},{intermediateValue:{requiredUserInteraction:e.UserInteractionRequired.RegisterWallet},status:e.DeviceActionStatus.Pending},{error:t,status:e.DeviceActionStatus.Error}];(0,p.testDeviceActionStates)(a,d,o,{onDone:i,onError:n})})),(0,r.it)("surfaces invalid input as a typed error state on the skip-open-app path",()=>new Promise((i,n)=>{(0,c.setupOpenAppDAMock)();const t={...s,skipOpenApp:!0,contactName:""},a=(0,v.validateRegisterExternalAddressInput)(t),d=u(t),m=[{error:a,status:e.DeviceActionStatus.Error}];(0,p.testDeviceActionStates)(d,m,o,{onDone:i,onError:n}),expect(l).not.toHaveBeenCalled(),expect(A).not.toHaveBeenCalled()})),(0,r.it)("validates only after opening the app on the default path",()=>new Promise((i,n)=>{(0,c.setupOpenAppDAMock)();const t={...s,skipOpenApp:!1,contactName:""},a=(0,v.validateRegisterExternalAddressInput)(t),d=u(t),m=[{intermediateValue:{requiredUserInteraction:e.UserInteractionRequired.None},status:e.DeviceActionStatus.Pending},{intermediateValue:{requiredUserInteraction:e.UserInteractionRequired.ConfirmOpenApp},status:e.DeviceActionStatus.Pending},{error:a,status:e.DeviceActionStatus.Error}];(0,p.testDeviceActionStates)(d,m,o,{onDone:i,onError:n}),expect(A).not.toHaveBeenCalled()})),(0,r.it)("evaluates support from the fresh WaitForAppAndVersion result, not stale session state",()=>new Promise((i,n)=>{(0,c.setupOpenAppDAMock)();const t={name:"Ethereum",version:"9.9.9"};(0,E.setupWaitForAppAndVersionDAMock)(t);const a=u({...s,skipOpenApp:!0}),d=[{intermediateValue:{requiredUserInteraction:e.UserInteractionRequired.None},status:e.DeviceActionStatus.Pending},{intermediateValue:{requiredUserInteraction:e.UserInteractionRequired.None},status:e.DeviceActionStatus.Pending},{intermediateValue:{requiredUserInteraction:e.UserInteractionRequired.RegisterWallet},status:e.DeviceActionStatus.Pending},{output:{mode:"newContactGroup",contactName:"Alice",scope:"Eth main",identifier:s.identifier,blockchainFamily:"ethereum",chainId:1n,...g},status:e.DeviceActionStatus.Completed}];(0,p.testDeviceActionStates)(a,d,o,{onDone:()=>{try{expect(l).toHaveBeenCalledWith(t),i()}catch(m){n(m)}},onError:n})})),(0,r.it)("surfaces a WaitForAppAndVersion failure as the device action error",()=>new Promise((i,n)=>{(0,c.setupOpenAppDAMock)();const t=new e.UnknownDAError("could not read app and version");(0,E.setupWaitForAppAndVersionDAMock)({error:t});const a=u({...s,skipOpenApp:!0}),d=[{intermediateValue:{requiredUserInteraction:e.UserInteractionRequired.None},status:e.DeviceActionStatus.Pending},{intermediateValue:{requiredUserInteraction:e.UserInteractionRequired.None},status:e.DeviceActionStatus.Pending},{error:t,status:e.DeviceActionStatus.Error}];(0,p.testDeviceActionStates)(a,d,o,{onDone:i,onError:n}),expect(l).not.toHaveBeenCalled(),expect(A).not.toHaveBeenCalled()})),(0,r.it)("propagates the UnlockDevice interaction emitted by WaitForAppAndVersion",()=>new Promise((i,n)=>{(0,c.setupOpenAppDAMock)(),(0,E.setupWaitForAppAndVersionDAMock)(x,e.UserInteractionRequired.UnlockDevice);const t=u({...s,skipOpenApp:!0}),a=[{intermediateValue:{requiredUserInteraction:e.UserInteractionRequired.None},status:e.DeviceActionStatus.Pending},{intermediateValue:{requiredUserInteraction:e.UserInteractionRequired.UnlockDevice},status:e.DeviceActionStatus.Pending},{intermediateValue:{requiredUserInteraction:e.UserInteractionRequired.RegisterWallet},status:e.DeviceActionStatus.Pending},{output:{mode:"newContactGroup",contactName:"Alice",scope:"Eth main",identifier:s.identifier,blockchainFamily:"ethereum",chainId:1n,...g},status:e.DeviceActionStatus.Completed}];(0,p.testDeviceActionStates)(t,a,o,{onDone:i,onError:n})}))});
|
|
2
|
+
//# sourceMappingURL=RegisterExternalAddressDeviceAction.test.js.map
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
{
|
|
2
|
+
"version": 3,
|
|
3
|
+
"sources": ["../../../../../../src/internal/app-binder/device-action/RegisterExternalAddress/RegisterExternalAddressDeviceAction.test.ts"],
|
|
4
|
+
"sourcesContent": ["import {\n CommandResultFactory,\n type DeviceActionState,\n DeviceActionStatus,\n DeviceModelId,\n DeviceSessionStateType,\n DeviceStatus,\n UnknownDAError,\n UserInteractionRequired,\n} from \"@ledgerhq/device-management-kit\";\nimport { beforeEach, describe, it, vi } from \"vitest\";\n\nimport {\n type RegisterExternalAddressDAError,\n type RegisterExternalAddressDAInput,\n type RegisterExternalAddressDAIntermediateValue,\n type RegisterExternalAddressDAOutput,\n} from \"@api/app-binder/RegisterExternalAddressDeviceActionTypes\";\nimport { makeDeviceActionInternalApiMock } from \"@internal/app-binder/device-action/__test-utils__/makeInternalApi\";\nimport { setupOpenAppDAMock } from \"@internal/app-binder/device-action/__test-utils__/setupOpenAppDAMock\";\nimport { setupWaitForAppAndVersionDAMock } from \"@internal/app-binder/device-action/__test-utils__/setupWaitForAppAndVersionDAMock\";\nimport { testDeviceActionStates } from \"@internal/app-binder/device-action/__test-utils__/testDeviceActionStates\";\nimport {\n ContactsCommandError,\n ContactsVersionRequirementError,\n} from \"@internal/app-binder/model/contactsErrors\";\n\nimport { RegisterExternalAddressDeviceAction } from \"./RegisterExternalAddressDeviceAction\";\nimport { validateRegisterExternalAddressInput } from \"./validateRegisterExternalAddressInput\";\n\nvi.mock(\"@ledgerhq/device-management-kit\", async (importOriginal) => {\n const original =\n // eslint-disable-next-line @typescript-eslint/consistent-type-imports\n await importOriginal<typeof import(\"@ledgerhq/device-management-kit\")>();\n return {\n ...original,\n OpenAppDeviceAction: vi.fn(() => ({\n makeStateMachine: vi.fn(),\n })),\n WaitForAppAndVersionDeviceAction: vi.fn(() => ({\n makeStateMachine: vi.fn(),\n })),\n };\n});\n\nconst FRESH_APP = { name: \"Ethereum\", version: \"1.15.0\" };\n\nconst OK_PROOFS = {\n groupHandle: new Uint8Array(64).fill(0xcc),\n hmacProof: new Uint8Array(32).fill(0xdd),\n hmacRest: new Uint8Array(32).fill(0xaa),\n};\n\nconst BASE_INPUT = {\n contactName: \"Alice\",\n scope: \"Eth main\",\n identifier: new Uint8Array(20).fill(0x11),\n blockchainFamily: \"ethereum\",\n chainId: 1n,\n appName: \"Ethereum\",\n};\n\ndescribe(\"RegisterExternalAddressDeviceAction\", () => {\n let apiMock: ReturnType<typeof makeDeviceActionInternalApiMock>;\n let isSupportedMock: ReturnType<typeof vi.fn>;\n let registerIdentityMock: ReturnType<typeof vi.fn>;\n\n function extractDeps() {\n return {\n isSupported: isSupportedMock,\n registerIdentity: registerIdentityMock,\n };\n }\n\n beforeEach(() => {\n apiMock = makeDeviceActionInternalApiMock();\n setupWaitForAppAndVersionDAMock(FRESH_APP);\n isSupportedMock = vi.fn().mockReturnValue(true);\n registerIdentityMock = vi\n .fn()\n .mockResolvedValue(CommandResultFactory({ data: OK_PROOFS }));\n apiMock.getDeviceSessionState.mockReturnValue({\n sessionStateType: DeviceSessionStateType.ReadyWithoutSecureChannel,\n deviceStatus: DeviceStatus.CONNECTED,\n installedApps: [],\n currentApp: { name: \"Ethereum\", version: \"1.15.0\" },\n deviceModelId: DeviceModelId.FLEX,\n isSecureConnectionAllowed: true,\n });\n });\n\n function makeAction(input: RegisterExternalAddressDAInput) {\n const action = new RegisterExternalAddressDeviceAction({ input });\n vi.spyOn(action, \"extractDependencies\").mockReturnValue(extractDeps());\n return action;\n }\n\n it(\"open-app path, new contact group: OpenApp -> VersionGuard -> RegisterIdentity -> Completed\", () =>\n new Promise<void>((resolve, reject) => {\n setupOpenAppDAMock();\n const action = makeAction({ ...BASE_INPUT, skipOpenApp: false });\n\n const expected = [\n {\n intermediateValue: {\n requiredUserInteraction: UserInteractionRequired.None,\n },\n status: DeviceActionStatus.Pending,\n },\n {\n intermediateValue: {\n requiredUserInteraction: UserInteractionRequired.ConfirmOpenApp,\n },\n status: DeviceActionStatus.Pending,\n },\n // WaitForAppAndVersion phase: entry reset, then the child's silent read\n // re-emits None through onSnapshot propagation.\n {\n intermediateValue: {\n requiredUserInteraction: UserInteractionRequired.None,\n },\n status: DeviceActionStatus.Pending,\n },\n {\n intermediateValue: {\n requiredUserInteraction: UserInteractionRequired.None,\n },\n status: DeviceActionStatus.Pending,\n },\n {\n intermediateValue: {\n requiredUserInteraction: UserInteractionRequired.RegisterWallet,\n },\n status: DeviceActionStatus.Pending,\n },\n {\n output: {\n mode: \"newContactGroup\",\n contactName: \"Alice\",\n scope: \"Eth main\",\n identifier: BASE_INPUT.identifier,\n blockchainFamily: \"ethereum\",\n chainId: 1n,\n ...OK_PROOFS,\n },\n status: DeviceActionStatus.Completed,\n },\n ] as DeviceActionState<\n RegisterExternalAddressDAOutput,\n RegisterExternalAddressDAError,\n RegisterExternalAddressDAIntermediateValue\n >[];\n\n testDeviceActionStates(action, expected, apiMock, {\n onDone: resolve,\n onError: reject,\n });\n }));\n\n it(\"skip-open-app path, existing contact group: VersionGuard -> RegisterIdentity -> Completed\", () =>\n new Promise<void>((resolve, reject) => {\n setupOpenAppDAMock();\n const existingContactGroup = {\n groupHandle: new Uint8Array(64).fill(0xcc),\n hmacProof: new Uint8Array(32).fill(0xdd),\n };\n const action = makeAction({\n ...BASE_INPUT,\n skipOpenApp: true,\n existingContactGroup,\n });\n\n const expected = [\n // WaitForAppAndVersion phase: entry reset, then the child's silent read\n // re-emits None through onSnapshot propagation.\n {\n intermediateValue: {\n requiredUserInteraction: UserInteractionRequired.None,\n },\n status: DeviceActionStatus.Pending,\n },\n {\n intermediateValue: {\n requiredUserInteraction: UserInteractionRequired.None,\n },\n status: DeviceActionStatus.Pending,\n },\n {\n intermediateValue: {\n requiredUserInteraction: UserInteractionRequired.RegisterWallet,\n },\n status: DeviceActionStatus.Pending,\n },\n {\n output: {\n mode: \"existingContactGroup\",\n contactName: \"Alice\",\n scope: \"Eth main\",\n identifier: BASE_INPUT.identifier,\n blockchainFamily: \"ethereum\",\n chainId: 1n,\n ...OK_PROOFS,\n },\n status: DeviceActionStatus.Completed,\n },\n ] as DeviceActionState<\n RegisterExternalAddressDAOutput,\n RegisterExternalAddressDAError,\n RegisterExternalAddressDAIntermediateValue\n >[];\n\n testDeviceActionStates(action, expected, apiMock, {\n onDone: resolve,\n onError: reject,\n });\n }));\n\n it(\"version guard rejects on skip-open-app path without opening the app\", () =>\n new Promise<void>((resolve, reject) => {\n setupOpenAppDAMock();\n isSupportedMock.mockReturnValue(false);\n const action = makeAction({ ...BASE_INPUT, skipOpenApp: true });\n\n const expected = [\n // WaitForAppAndVersion phase (entry reset + child read) runs before the\n // guard; both reads emit None.\n {\n intermediateValue: {\n requiredUserInteraction: UserInteractionRequired.None,\n },\n status: DeviceActionStatus.Pending,\n },\n {\n intermediateValue: {\n requiredUserInteraction: UserInteractionRequired.None,\n },\n status: DeviceActionStatus.Pending,\n },\n {\n error: new ContactsVersionRequirementError(),\n status: DeviceActionStatus.Error,\n },\n ] as DeviceActionState<\n RegisterExternalAddressDAOutput,\n RegisterExternalAddressDAError,\n RegisterExternalAddressDAIntermediateValue\n >[];\n\n testDeviceActionStates(action, expected, apiMock, {\n onDone: resolve,\n onError: reject,\n });\n expect(registerIdentityMock).not.toHaveBeenCalled();\n }));\n\n it(\"surfaces an open-app failure as the device action error\", () =>\n new Promise<void>((resolve, reject) => {\n const openAppError = new UnknownDAError(\"open app failed\");\n setupOpenAppDAMock(openAppError);\n const action = makeAction({ ...BASE_INPUT, skipOpenApp: false });\n\n const expected = [\n {\n intermediateValue: {\n requiredUserInteraction: UserInteractionRequired.None,\n },\n status: DeviceActionStatus.Pending,\n },\n {\n intermediateValue: {\n requiredUserInteraction: UserInteractionRequired.ConfirmOpenApp,\n },\n status: DeviceActionStatus.Pending,\n },\n {\n error: openAppError,\n status: DeviceActionStatus.Error,\n },\n ] as DeviceActionState<\n RegisterExternalAddressDAOutput,\n RegisterExternalAddressDAError,\n RegisterExternalAddressDAIntermediateValue\n >[];\n\n testDeviceActionStates(action, expected, apiMock, {\n onDone: resolve,\n onError: reject,\n });\n expect(isSupportedMock).not.toHaveBeenCalled();\n }));\n\n it(\"surfaces a Register Identity command error\", () =>\n new Promise<void>((resolve, reject) => {\n setupOpenAppDAMock();\n const commandError = new ContactsCommandError({\n errorCode: \"6a80\",\n message: \"device rejected\",\n });\n registerIdentityMock.mockResolvedValue(\n CommandResultFactory({ error: commandError }),\n );\n const action = makeAction({ ...BASE_INPUT, skipOpenApp: true });\n\n const expected = [\n // WaitForAppAndVersion phase: entry reset, then the child's silent read\n // re-emits None through onSnapshot propagation.\n {\n intermediateValue: {\n requiredUserInteraction: UserInteractionRequired.None,\n },\n status: DeviceActionStatus.Pending,\n },\n {\n intermediateValue: {\n requiredUserInteraction: UserInteractionRequired.None,\n },\n status: DeviceActionStatus.Pending,\n },\n {\n intermediateValue: {\n requiredUserInteraction: UserInteractionRequired.RegisterWallet,\n },\n status: DeviceActionStatus.Pending,\n },\n {\n error: commandError,\n status: DeviceActionStatus.Error,\n },\n ] as DeviceActionState<\n RegisterExternalAddressDAOutput,\n RegisterExternalAddressDAError,\n RegisterExternalAddressDAIntermediateValue\n >[];\n\n testDeviceActionStates(action, expected, apiMock, {\n onDone: resolve,\n onError: reject,\n });\n }));\n\n it(\"surfaces invalid input as a typed error state on the skip-open-app path\", () =>\n new Promise<void>((resolve, reject) => {\n setupOpenAppDAMock();\n const invalidInput = {\n ...BASE_INPUT,\n skipOpenApp: true,\n contactName: \"\",\n };\n const validationError =\n validateRegisterExternalAddressInput(invalidInput);\n const action = makeAction(invalidInput);\n\n const expected = [\n {\n error: validationError,\n status: DeviceActionStatus.Error,\n },\n ] as DeviceActionState<\n RegisterExternalAddressDAOutput,\n RegisterExternalAddressDAError,\n RegisterExternalAddressDAIntermediateValue\n >[];\n\n testDeviceActionStates(action, expected, apiMock, {\n onDone: resolve,\n onError: reject,\n });\n // Validation fails before the version guard and before any APDU.\n expect(isSupportedMock).not.toHaveBeenCalled();\n expect(registerIdentityMock).not.toHaveBeenCalled();\n }));\n\n it(\"validates only after opening the app on the default path\", () =>\n new Promise<void>((resolve, reject) => {\n setupOpenAppDAMock();\n const invalidInput = {\n ...BASE_INPUT,\n skipOpenApp: false,\n contactName: \"\",\n };\n const validationError =\n validateRegisterExternalAddressInput(invalidInput);\n const action = makeAction(invalidInput);\n\n const expected = [\n {\n intermediateValue: {\n requiredUserInteraction: UserInteractionRequired.None,\n },\n status: DeviceActionStatus.Pending,\n },\n {\n intermediateValue: {\n requiredUserInteraction: UserInteractionRequired.ConfirmOpenApp,\n },\n status: DeviceActionStatus.Pending,\n },\n {\n error: validationError,\n status: DeviceActionStatus.Error,\n },\n ] as DeviceActionState<\n RegisterExternalAddressDAOutput,\n RegisterExternalAddressDAError,\n RegisterExternalAddressDAIntermediateValue\n >[];\n\n testDeviceActionStates(action, expected, apiMock, {\n onDone: resolve,\n onError: reject,\n });\n expect(registerIdentityMock).not.toHaveBeenCalled();\n }));\n\n it(\"evaluates support from the fresh WaitForAppAndVersion result, not stale session state\", () =>\n new Promise<void>((resolve, reject) => {\n setupOpenAppDAMock();\n // Session state (from beforeEach) reports version 1.15.0; the fresh read\n // reports a different version, which is what the guard must use.\n const freshApp = { name: \"Ethereum\", version: \"9.9.9\" };\n setupWaitForAppAndVersionDAMock(freshApp);\n const action = makeAction({ ...BASE_INPUT, skipOpenApp: true });\n\n const expected = [\n // WaitForAppAndVersion phase: entry reset + child read, both None.\n {\n intermediateValue: {\n requiredUserInteraction: UserInteractionRequired.None,\n },\n status: DeviceActionStatus.Pending,\n },\n {\n intermediateValue: {\n requiredUserInteraction: UserInteractionRequired.None,\n },\n status: DeviceActionStatus.Pending,\n },\n {\n intermediateValue: {\n requiredUserInteraction: UserInteractionRequired.RegisterWallet,\n },\n status: DeviceActionStatus.Pending,\n },\n {\n output: {\n mode: \"newContactGroup\",\n contactName: \"Alice\",\n scope: \"Eth main\",\n identifier: BASE_INPUT.identifier,\n blockchainFamily: \"ethereum\",\n chainId: 1n,\n ...OK_PROOFS,\n },\n status: DeviceActionStatus.Completed,\n },\n ] as DeviceActionState<\n RegisterExternalAddressDAOutput,\n RegisterExternalAddressDAError,\n RegisterExternalAddressDAIntermediateValue\n >[];\n\n testDeviceActionStates(action, expected, apiMock, {\n onDone: () => {\n try {\n expect(isSupportedMock).toHaveBeenCalledWith(freshApp);\n resolve();\n } catch (e) {\n reject(e as Error);\n }\n },\n onError: reject,\n });\n }));\n\n it(\"surfaces a WaitForAppAndVersion failure as the device action error\", () =>\n new Promise<void>((resolve, reject) => {\n setupOpenAppDAMock();\n const waitError = new UnknownDAError(\"could not read app and version\");\n setupWaitForAppAndVersionDAMock({ error: waitError });\n const action = makeAction({ ...BASE_INPUT, skipOpenApp: true });\n\n const expected = [\n // WaitForAppAndVersion phase: entry reset + child read, both None,\n // before the child DA surfaces its failure.\n {\n intermediateValue: {\n requiredUserInteraction: UserInteractionRequired.None,\n },\n status: DeviceActionStatus.Pending,\n },\n {\n intermediateValue: {\n requiredUserInteraction: UserInteractionRequired.None,\n },\n status: DeviceActionStatus.Pending,\n },\n {\n error: waitError,\n status: DeviceActionStatus.Error,\n },\n ] as DeviceActionState<\n RegisterExternalAddressDAOutput,\n RegisterExternalAddressDAError,\n RegisterExternalAddressDAIntermediateValue\n >[];\n\n testDeviceActionStates(action, expected, apiMock, {\n onDone: resolve,\n onError: reject,\n });\n // The version guard and the APDU are never reached.\n expect(isSupportedMock).not.toHaveBeenCalled();\n expect(registerIdentityMock).not.toHaveBeenCalled();\n }));\n\n it(\"propagates the UnlockDevice interaction emitted by WaitForAppAndVersion\", () =>\n new Promise<void>((resolve, reject) => {\n setupOpenAppDAMock();\n // Locked device: the child WaitForAppAndVersion DA requests an unlock\n // before it can read the app/version. The parent must surface it so a\n // consuming client can show a \"please unlock your device\" prompt.\n setupWaitForAppAndVersionDAMock(\n FRESH_APP,\n UserInteractionRequired.UnlockDevice,\n );\n const action = makeAction({ ...BASE_INPUT, skipOpenApp: true });\n\n const expected = [\n // Entry reset before the child DA runs.\n {\n intermediateValue: {\n requiredUserInteraction: UserInteractionRequired.None,\n },\n status: DeviceActionStatus.Pending,\n },\n // Propagated from the child DA: the device needs to be unlocked.\n {\n intermediateValue: {\n requiredUserInteraction: UserInteractionRequired.UnlockDevice,\n },\n status: DeviceActionStatus.Pending,\n },\n {\n intermediateValue: {\n requiredUserInteraction: UserInteractionRequired.RegisterWallet,\n },\n status: DeviceActionStatus.Pending,\n },\n {\n output: {\n mode: \"newContactGroup\",\n contactName: \"Alice\",\n scope: \"Eth main\",\n identifier: BASE_INPUT.identifier,\n blockchainFamily: \"ethereum\",\n chainId: 1n,\n ...OK_PROOFS,\n },\n status: DeviceActionStatus.Completed,\n },\n ] as DeviceActionState<\n RegisterExternalAddressDAOutput,\n RegisterExternalAddressDAError,\n RegisterExternalAddressDAIntermediateValue\n >[];\n\n testDeviceActionStates(action, expected, apiMock, {\n onDone: resolve,\n onError: reject,\n });\n }));\n});\n"],
|
|
5
|
+
"mappings": "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",
|
|
6
|
+
"names": ["import_device_management_kit", "import_vitest", "import_makeInternalApi", "import_setupOpenAppDAMock", "import_setupWaitForAppAndVersionDAMock", "import_testDeviceActionStates", "import_contactsErrors", "import_RegisterExternalAddressDeviceAction", "import_validateRegisterExternalAddressInput", "importOriginal", "FRESH_APP", "OK_PROOFS", "BASE_INPUT", "apiMock", "isSupportedMock", "registerIdentityMock", "extractDeps", "makeAction", "input", "action", "resolve", "reject", "expected", "existingContactGroup", "openAppError", "commandError", "invalidInput", "validationError", "freshApp", "e", "waitError"]
|
|
7
|
+
}
|
|
@@ -0,0 +1,2 @@
|
|
|
1
|
+
"use strict";var o=Object.defineProperty;var c=Object.getOwnPropertyDescriptor;var f=Object.getOwnPropertyNames;var l=Object.prototype.hasOwnProperty;var s=(t,i)=>{for(var n in i)o(t,n,{get:i[n],enumerable:!0})},h=(t,i,n,a)=>{if(i&&typeof i=="object"||typeof i=="function")for(let r of f(i))!l.call(t,r)&&r!==n&&o(t,r,{get:()=>i[r],enumerable:!(a=c(i,r))||a.enumerable});return t};var m=t=>h(o({},"__esModule",{value:!0}),t);var C={};s(C,{validateRegisterExternalAddressInput:()=>E});module.exports=m(C);var d=require("../../../app-binder/model/contactsConstants"),e=require("../../../app-binder/model/contactsValidation");function E(t){try{(0,e.validatePrintableLabel)(t.contactName,{field:"contactName",bufferLength:e.CONTACT_NAME_BUFFER_LENGTH}),(0,e.validatePrintableLabel)(t.scope,{field:"scope",bufferLength:e.SCOPE_BUFFER_LENGTH});const i=t.blockchainFamily.toLowerCase();if(!(i in d.BLOCKCHAIN_FAMILY_BY_NAME))throw new e.ContactsValidationError(`Unsupported blockchain family: ${t.blockchainFamily}`);if(i==="ethereum"){if((0,e.validateByteLength)(t.identifier,{field:"identifier",expectedBytes:e.ETH_ADDRESS_BYTES}),t.chainId===void 0)throw new e.ContactsValidationError("chainId is required for the Ethereum blockchain family.")}else if(t.identifier.length===0)throw new e.ContactsValidationError("identifier must not be empty.");return t.chainId!==void 0&&(0,e.validateChainId)(t.chainId),t.existingContactGroup&&((0,e.validateByteLength)(t.existingContactGroup.groupHandle,{field:"existingContactGroup.groupHandle",expectedBytes:e.GROUP_HANDLE_SIZE}),(0,e.validateByteLength)(t.existingContactGroup.hmacProof,{field:"existingContactGroup.hmacProof",expectedBytes:e.HMAC_PROOF_LENGTH})),null}catch(i){if(i instanceof e.ContactsValidationError)return i;throw i}}0&&(module.exports={validateRegisterExternalAddressInput});
|
|
2
|
+
//# sourceMappingURL=validateRegisterExternalAddressInput.js.map
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
{
|
|
2
|
+
"version": 3,
|
|
3
|
+
"sources": ["../../../../../../src/internal/app-binder/device-action/RegisterExternalAddress/validateRegisterExternalAddressInput.ts"],
|
|
4
|
+
"sourcesContent": ["import { type RegisterExternalAddressInput } from \"@api/model/RegisterExternalAddress\";\nimport { BLOCKCHAIN_FAMILY_BY_NAME } from \"@internal/app-binder/model/contactsConstants\";\nimport {\n CONTACT_NAME_BUFFER_LENGTH,\n ContactsValidationError,\n ETH_ADDRESS_BYTES,\n GROUP_HANDLE_SIZE,\n HMAC_PROOF_LENGTH,\n SCOPE_BUFFER_LENGTH,\n validateByteLength,\n validateChainId,\n validatePrintableLabel,\n} from \"@internal/app-binder/model/contactsValidation\";\n\n/**\n * Validate the caller input for Register External Address. Returns the first\n * `ContactsValidationError` found, or `null` when the input is valid.\n *\n * Non-throwing by design: the device action calls this so an invalid input is\n * surfaced as a typed terminal error state on the observable, keeping the\n * public `ContactsManager.registerExternalAddress` free of synchronous throws.\n */\nexport function validateRegisterExternalAddressInput(\n input: RegisterExternalAddressInput,\n): ContactsValidationError | null {\n try {\n validatePrintableLabel(input.contactName, {\n field: \"contactName\",\n bufferLength: CONTACT_NAME_BUFFER_LENGTH,\n });\n validatePrintableLabel(input.scope, {\n field: \"scope\",\n bufferLength: SCOPE_BUFFER_LENGTH,\n });\n\n const family = input.blockchainFamily.toLowerCase();\n if (!(family in BLOCKCHAIN_FAMILY_BY_NAME)) {\n throw new ContactsValidationError(\n `Unsupported blockchain family: ${input.blockchainFamily}`,\n );\n }\n if (family === \"ethereum\") {\n validateByteLength(input.identifier, {\n field: \"identifier\",\n expectedBytes: ETH_ADDRESS_BYTES,\n });\n // CHAIN_ID is mandatory for the Ethereum family (multiple networks share\n // the same address format).\n if (input.chainId === undefined) {\n throw new ContactsValidationError(\n \"chainId is required for the Ethereum blockchain family.\",\n );\n }\n } else if (input.identifier.length === 0) {\n throw new ContactsValidationError(\"identifier must not be empty.\");\n }\n\n if (input.chainId !== undefined) {\n validateChainId(input.chainId);\n }\n\n if (input.existingContactGroup) {\n validateByteLength(input.existingContactGroup.groupHandle, {\n field: \"existingContactGroup.groupHandle\",\n expectedBytes: GROUP_HANDLE_SIZE,\n });\n validateByteLength(input.existingContactGroup.hmacProof, {\n field: \"existingContactGroup.hmacProof\",\n expectedBytes: HMAC_PROOF_LENGTH,\n });\n }\n\n return null;\n } catch (error) {\n if (error instanceof ContactsValidationError) {\n return error;\n }\n throw error;\n }\n}\n"],
|
|
5
|
+
"mappings": "yaAAA,IAAAA,EAAA,GAAAC,EAAAD,EAAA,0CAAAE,IAAA,eAAAC,EAAAH,GACA,IAAAI,EAA0C,wDAC1CC,EAUO,yDAUA,SAASH,EACdI,EACgC,CAChC,GAAI,IACF,0BAAuBA,EAAM,YAAa,CACxC,MAAO,cACP,aAAc,4BAChB,CAAC,KACD,0BAAuBA,EAAM,MAAO,CAClC,MAAO,QACP,aAAc,qBAChB,CAAC,EAED,MAAMC,EAASD,EAAM,iBAAiB,YAAY,EAClD,GAAI,EAAEC,KAAU,6BACd,MAAM,IAAI,0BACR,kCAAkCD,EAAM,gBAAgB,EAC1D,EAEF,GAAIC,IAAW,YAOb,MANA,sBAAmBD,EAAM,WAAY,CACnC,MAAO,aACP,cAAe,mBACjB,CAAC,EAGGA,EAAM,UAAY,OACpB,MAAM,IAAI,0BACR,yDACF,UAEOA,EAAM,WAAW,SAAW,EACrC,MAAM,IAAI,0BAAwB,+BAA+B,EAGnE,OAAIA,EAAM,UAAY,WACpB,mBAAgBA,EAAM,OAAO,EAG3BA,EAAM,0BACR,sBAAmBA,EAAM,qBAAqB,YAAa,CACzD,MAAO,mCACP,cAAe,mBACjB,CAAC,KACD,sBAAmBA,EAAM,qBAAqB,UAAW,CACvD,MAAO,iCACP,cAAe,mBACjB,CAAC,GAGI,IACT,OAASE,EAAO,CACd,GAAIA,aAAiB,0BACnB,OAAOA,EAET,MAAMA,CACR,CACF",
|
|
6
|
+
"names": ["validateRegisterExternalAddressInput_exports", "__export", "validateRegisterExternalAddressInput", "__toCommonJS", "import_contactsConstants", "import_contactsValidation", "input", "family", "error"]
|
|
7
|
+
}
|
|
@@ -0,0 +1,2 @@
|
|
|
1
|
+
"use strict";var n=require("../../../app-binder/model/contactsValidation"),e=require("./validateRegisterExternalAddressInput");const t={contactName:"Alice",scope:"Eth main",identifier:new Uint8Array(20).fill(17),blockchainFamily:"ethereum",chainId:1n};describe("validateRegisterExternalAddressInput",()=>{it("returns null for valid input",()=>{expect((0,e.validateRegisterExternalAddressInput)(t)).toBeNull()}),it("returns null for a valid existing-contact-group input",()=>{expect((0,e.validateRegisterExternalAddressInput)({...t,existingContactGroup:{groupHandle:new Uint8Array(64),hmacProof:new Uint8Array(32)}})).toBeNull()}),it("returns a ContactsValidationError for a non-printable contact name",()=>{expect((0,e.validateRegisterExternalAddressInput)({...t,contactName:"Am\xE9lie"})).toBeInstanceOf(n.ContactsValidationError)}),it("returns an error for an Ethereum identifier of the wrong length",()=>{expect((0,e.validateRegisterExternalAddressInput)({...t,identifier:new Uint8Array(19)})).toBeInstanceOf(n.ContactsValidationError)}),it("returns an error for an unsupported blockchain family",()=>{expect((0,e.validateRegisterExternalAddressInput)({...t,blockchainFamily:"dogecoin"})).toBeInstanceOf(n.ContactsValidationError)}),it("returns an error when chainId is missing for the Ethereum family",()=>{expect((0,e.validateRegisterExternalAddressInput)({...t,chainId:void 0})).toBeInstanceOf(n.ContactsValidationError)}),it("returns an error for a wrong-sized existing group handle",()=>{expect((0,e.validateRegisterExternalAddressInput)({...t,existingContactGroup:{groupHandle:new Uint8Array(32),hmacProof:new Uint8Array(32)}})).toBeInstanceOf(n.ContactsValidationError)})});
|
|
2
|
+
//# sourceMappingURL=validateRegisterExternalAddressInput.test.js.map
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
{
|
|
2
|
+
"version": 3,
|
|
3
|
+
"sources": ["../../../../../../src/internal/app-binder/device-action/RegisterExternalAddress/validateRegisterExternalAddressInput.test.ts"],
|
|
4
|
+
"sourcesContent": ["import { type RegisterExternalAddressInput } from \"@api/model/RegisterExternalAddress\";\nimport { ContactsValidationError } from \"@internal/app-binder/model/contactsValidation\";\n\nimport { validateRegisterExternalAddressInput } from \"./validateRegisterExternalAddressInput\";\n\nconst VALID_INPUT: RegisterExternalAddressInput = {\n contactName: \"Alice\",\n scope: \"Eth main\",\n identifier: new Uint8Array(20).fill(0x11),\n blockchainFamily: \"ethereum\",\n chainId: 1n,\n};\n\ndescribe(\"validateRegisterExternalAddressInput\", () => {\n it(\"returns null for valid input\", () => {\n expect(validateRegisterExternalAddressInput(VALID_INPUT)).toBeNull();\n });\n\n it(\"returns null for a valid existing-contact-group input\", () => {\n expect(\n validateRegisterExternalAddressInput({\n ...VALID_INPUT,\n existingContactGroup: {\n groupHandle: new Uint8Array(64),\n hmacProof: new Uint8Array(32),\n },\n }),\n ).toBeNull();\n });\n\n it(\"returns a ContactsValidationError for a non-printable contact name\", () => {\n expect(\n validateRegisterExternalAddressInput({\n ...VALID_INPUT,\n contactName: \"Am\u00E9lie\",\n }),\n ).toBeInstanceOf(ContactsValidationError);\n });\n\n it(\"returns an error for an Ethereum identifier of the wrong length\", () => {\n expect(\n validateRegisterExternalAddressInput({\n ...VALID_INPUT,\n identifier: new Uint8Array(19),\n }),\n ).toBeInstanceOf(ContactsValidationError);\n });\n\n it(\"returns an error for an unsupported blockchain family\", () => {\n expect(\n validateRegisterExternalAddressInput({\n ...VALID_INPUT,\n blockchainFamily: \"dogecoin\",\n }),\n ).toBeInstanceOf(ContactsValidationError);\n });\n\n it(\"returns an error when chainId is missing for the Ethereum family\", () => {\n expect(\n validateRegisterExternalAddressInput({\n ...VALID_INPUT,\n chainId: undefined,\n }),\n ).toBeInstanceOf(ContactsValidationError);\n });\n\n it(\"returns an error for a wrong-sized existing group handle\", () => {\n expect(\n validateRegisterExternalAddressInput({\n ...VALID_INPUT,\n existingContactGroup: {\n groupHandle: new Uint8Array(32),\n hmacProof: new Uint8Array(32),\n },\n }),\n ).toBeInstanceOf(ContactsValidationError);\n });\n});\n"],
|
|
5
|
+
"mappings": "aACA,IAAAA,EAAwC,yDAExCC,EAAqD,kDAErD,MAAMC,EAA4C,CAChD,YAAa,QACb,MAAO,WACP,WAAY,IAAI,WAAW,EAAE,EAAE,KAAK,EAAI,EACxC,iBAAkB,WAClB,QAAS,EACX,EAEA,SAAS,uCAAwC,IAAM,CACrD,GAAG,+BAAgC,IAAM,CACvC,UAAO,wCAAqCA,CAAW,CAAC,EAAE,SAAS,CACrE,CAAC,EAED,GAAG,wDAAyD,IAAM,CAChE,UACE,wCAAqC,CACnC,GAAGA,EACH,qBAAsB,CACpB,YAAa,IAAI,WAAW,EAAE,EAC9B,UAAW,IAAI,WAAW,EAAE,CAC9B,CACF,CAAC,CACH,EAAE,SAAS,CACb,CAAC,EAED,GAAG,qEAAsE,IAAM,CAC7E,UACE,wCAAqC,CACnC,GAAGA,EACH,YAAa,WACf,CAAC,CACH,EAAE,eAAe,yBAAuB,CAC1C,CAAC,EAED,GAAG,kEAAmE,IAAM,CAC1E,UACE,wCAAqC,CACnC,GAAGA,EACH,WAAY,IAAI,WAAW,EAAE,CAC/B,CAAC,CACH,EAAE,eAAe,yBAAuB,CAC1C,CAAC,EAED,GAAG,wDAAyD,IAAM,CAChE,UACE,wCAAqC,CACnC,GAAGA,EACH,iBAAkB,UACpB,CAAC,CACH,EAAE,eAAe,yBAAuB,CAC1C,CAAC,EAED,GAAG,mEAAoE,IAAM,CAC3E,UACE,wCAAqC,CACnC,GAAGA,EACH,QAAS,MACX,CAAC,CACH,EAAE,eAAe,yBAAuB,CAC1C,CAAC,EAED,GAAG,2DAA4D,IAAM,CACnE,UACE,wCAAqC,CACnC,GAAGA,EACH,qBAAsB,CACpB,YAAa,IAAI,WAAW,EAAE,EAC9B,UAAW,IAAI,WAAW,EAAE,CAC9B,CACF,CAAC,CACH,EAAE,eAAe,yBAAuB,CAC1C,CAAC,CACH,CAAC",
|
|
6
|
+
"names": ["import_contactsValidation", "import_validateRegisterExternalAddressInput", "VALID_INPUT"]
|
|
7
|
+
}
|
|
@@ -0,0 +1,2 @@
|
|
|
1
|
+
"use strict";var r=Object.defineProperty;var o=Object.getOwnPropertyDescriptor;var f=Object.getOwnPropertyNames;var a=Object.prototype.hasOwnProperty;var c=(n,e)=>{for(var t in e)r(n,t,{get:e[t],enumerable:!0})},s=(n,e,t,v)=>{if(e&&typeof e=="object"||typeof e=="function")for(let i of f(e))!a.call(n,i)&&i!==t&&r(n,i,{get:()=>e[i],enumerable:!(v=o(e,i))||v.enumerable});return n};var d=n=>s(r({},"__esModule",{value:!0}),n);var p={};c(p,{makeDeviceActionInternalApiMock:()=>g});module.exports=d(p);function g(){return{sendApdu:vi.fn(),sendCommand:vi.fn().mockResolvedValue(void 0),getDeviceModel:vi.fn(),getDeviceSessionState:vi.fn(),getDeviceSessionStateObservable:vi.fn(),setDeviceSessionState:vi.fn(),getManagerApiService:vi.fn(),getSecureChannelService:vi.fn(),loggerFactory:vi.fn(n=>({debug:vi.fn(),info:vi.fn(),warn:vi.fn(),error:vi.fn(),subscribers:[]}))}}0&&(module.exports={makeDeviceActionInternalApiMock});
|
|
2
|
+
//# sourceMappingURL=makeInternalApi.js.map
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
{
|
|
2
|
+
"version": 3,
|
|
3
|
+
"sources": ["../../../../../../src/internal/app-binder/device-action/__test-utils__/makeInternalApi.ts"],
|
|
4
|
+
"sourcesContent": ["import { type InternalApi } from \"@ledgerhq/device-management-kit\";\nimport { type Mocked } from \"vitest\";\n\nexport function makeDeviceActionInternalApiMock(): Mocked<InternalApi> {\n return {\n sendApdu: vi.fn(),\n sendCommand: vi.fn().mockResolvedValue(undefined),\n getDeviceModel: vi.fn(),\n getDeviceSessionState: vi.fn(),\n getDeviceSessionStateObservable: vi.fn(),\n setDeviceSessionState: vi.fn(),\n getManagerApiService: vi.fn(),\n getSecureChannelService: vi.fn(),\n loggerFactory: vi.fn((_tag: string) => ({\n debug: vi.fn(),\n info: vi.fn(),\n warn: vi.fn(),\n error: vi.fn(),\n subscribers: [],\n })),\n };\n}\n"],
|
|
5
|
+
"mappings": "yaAAA,IAAAA,EAAA,GAAAC,EAAAD,EAAA,qCAAAE,IAAA,eAAAC,EAAAH,GAGO,SAASE,GAAuD,CACrE,MAAO,CACL,SAAU,GAAG,GAAG,EAChB,YAAa,GAAG,GAAG,EAAE,kBAAkB,MAAS,EAChD,eAAgB,GAAG,GAAG,EACtB,sBAAuB,GAAG,GAAG,EAC7B,gCAAiC,GAAG,GAAG,EACvC,sBAAuB,GAAG,GAAG,EAC7B,qBAAsB,GAAG,GAAG,EAC5B,wBAAyB,GAAG,GAAG,EAC/B,cAAe,GAAG,GAAIE,IAAkB,CACtC,MAAO,GAAG,GAAG,EACb,KAAM,GAAG,GAAG,EACZ,KAAM,GAAG,GAAG,EACZ,MAAO,GAAG,GAAG,EACb,YAAa,CAAC,CAChB,EAAE,CACJ,CACF",
|
|
6
|
+
"names": ["makeInternalApi_exports", "__export", "makeDeviceActionInternalApiMock", "__toCommonJS", "_tag"]
|
|
7
|
+
}
|
|
@@ -0,0 +1,2 @@
|
|
|
1
|
+
"use strict";var a=Object.defineProperty;var c=Object.getOwnPropertyDescriptor;var f=Object.getOwnPropertyNames;var d=Object.prototype.hasOwnProperty;var s=(e,n)=>{for(var i in n)a(e,i,{get:n[i],enumerable:!0})},u=(e,n,i,m)=>{if(n&&typeof n=="object"||typeof n=="function")for(let t of f(n))!d.call(e,t)&&t!==i&&a(e,t,{get:()=>n[t],enumerable:!(m=c(n,t))||m.enumerable});return e};var k=e=>u(a({},"__esModule",{value:!0}),e);var A={};s(A,{setupOpenAppDAMock:()=>l});module.exports=k(A);var o=require("@ledgerhq/device-management-kit"),p=require("purify-ts"),r=require("xstate");const l=e=>{o.OpenAppDeviceAction.mockImplementation(()=>({makeStateMachine:vi.fn().mockImplementation(()=>(0,r.createMachine)({initial:"pending",states:{pending:{entry:(0,r.assign)({intermediateValue:{requiredUserInteraction:o.UserInteractionRequired.ConfirmOpenApp}}),after:{0:"done"}},done:{type:"final"}},output:()=>e?(0,p.Left)(e):(0,p.Right)(void 0)}))}))};0&&(module.exports={setupOpenAppDAMock});
|
|
2
|
+
//# sourceMappingURL=setupOpenAppDAMock.js.map
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
{
|
|
2
|
+
"version": 3,
|
|
3
|
+
"sources": ["../../../../../../src/internal/app-binder/device-action/__test-utils__/setupOpenAppDAMock.ts"],
|
|
4
|
+
"sourcesContent": ["import {\n OpenAppDeviceAction,\n UserInteractionRequired,\n} from \"@ledgerhq/device-management-kit\";\nimport { Left, Right } from \"purify-ts\";\nimport { type Mock } from \"vitest\";\nimport { assign, createMachine } from \"xstate\";\n\nexport const setupOpenAppDAMock = (error?: unknown) => {\n (OpenAppDeviceAction as Mock).mockImplementation(() => ({\n makeStateMachine: vi.fn().mockImplementation(() =>\n createMachine({\n initial: \"pending\",\n states: {\n pending: {\n entry: assign({\n intermediateValue: {\n requiredUserInteraction: UserInteractionRequired.ConfirmOpenApp,\n },\n }),\n after: {\n 0: \"done\",\n },\n },\n done: {\n type: \"final\",\n },\n },\n output: () => (error ? Left(error) : Right(undefined)),\n }),\n ),\n }));\n};\n"],
|
|
5
|
+
"mappings": "yaAAA,IAAAA,EAAA,GAAAC,EAAAD,EAAA,wBAAAE,IAAA,eAAAC,EAAAH,GAAA,IAAAI,EAGO,2CACPC,EAA4B,qBAE5BC,EAAsC,kBAE/B,MAAMJ,EAAsBK,GAAoB,CACpD,sBAA6B,mBAAmB,KAAO,CACtD,iBAAkB,GAAG,GAAG,EAAE,mBAAmB,OAC3C,iBAAc,CACZ,QAAS,UACT,OAAQ,CACN,QAAS,CACP,SAAO,UAAO,CACZ,kBAAmB,CACjB,wBAAyB,0BAAwB,cACnD,CACF,CAAC,EACD,MAAO,CACL,EAAG,MACL,CACF,EACA,KAAM,CACJ,KAAM,OACR,CACF,EACA,OAAQ,IAAOA,KAAQ,QAAKA,CAAK,KAAI,SAAM,MAAS,CACtD,CAAC,CACH,CACF,EAAE,CACJ",
|
|
6
|
+
"names": ["setupOpenAppDAMock_exports", "__export", "setupOpenAppDAMock", "__toCommonJS", "import_device_management_kit", "import_purify_ts", "import_xstate", "error"]
|
|
7
|
+
}
|
package/lib/cjs/internal/app-binder/device-action/__test-utils__/setupWaitForAppAndVersionDAMock.js
ADDED
|
@@ -0,0 +1,2 @@
|
|
|
1
|
+
"use strict";var a=Object.defineProperty;var c=Object.getOwnPropertyDescriptor;var s=Object.getOwnPropertyNames;var d=Object.prototype.hasOwnProperty;var f=(e,n)=>{for(var o in n)a(e,o,{get:n[o],enumerable:!0})},k=(e,n,o,m)=>{if(n&&typeof n=="object"||typeof n=="function")for(let t of s(n))!d.call(e,t)&&t!==o&&a(e,t,{get:()=>n[t],enumerable:!(m=c(n,t))||m.enumerable});return e};var u=e=>k(a({},"__esModule",{value:!0}),e);var g={};f(g,{setupWaitForAppAndVersionDAMock:()=>A});module.exports=u(g);var r=require("@ledgerhq/device-management-kit"),i=require("purify-ts"),p=require("xstate");const A=(e={name:"Ethereum",version:"1.15.0"},n=r.UserInteractionRequired.None)=>{r.WaitForAppAndVersionDeviceAction.mockImplementation(()=>({makeStateMachine:vi.fn().mockImplementation(()=>(0,p.createMachine)({initial:"pending",context:{intermediateValue:{requiredUserInteraction:n}},states:{pending:{after:{0:"done"}},done:{type:"final"}},output:()=>"error"in e?(0,i.Left)(e.error):(0,i.Right)(e)}))}))};0&&(module.exports={setupWaitForAppAndVersionDAMock});
|
|
2
|
+
//# sourceMappingURL=setupWaitForAppAndVersionDAMock.js.map
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
{
|
|
2
|
+
"version": 3,
|
|
3
|
+
"sources": ["../../../../../../src/internal/app-binder/device-action/__test-utils__/setupWaitForAppAndVersionDAMock.ts"],
|
|
4
|
+
"sourcesContent": ["import {\n UserInteractionRequired,\n WaitForAppAndVersionDeviceAction,\n} from \"@ledgerhq/device-management-kit\";\nimport { Left, Right } from \"purify-ts\";\nimport { type Mock } from \"vitest\";\nimport { createMachine } from \"xstate\";\n\n/**\n * Mock WaitForAppAndVersionDeviceAction to resolve immediately with either a\n * fresh `{ name, version }` (default) or an error.\n *\n * The mock machine carries an `intermediateValue` in its context (matching the\n * real DA) so the parent's onSnapshot propagation has a defined value to read.\n * Pass `requiredUserInteraction` to have the child emit an interaction (e.g.\n * UnlockDevice for a locked device) before completing.\n */\nexport const setupWaitForAppAndVersionDAMock = (\n result: { name: string; version: string } | { error: unknown } = {\n name: \"Ethereum\",\n version: \"1.15.0\",\n },\n requiredUserInteraction: UserInteractionRequired = UserInteractionRequired.None,\n) => {\n (WaitForAppAndVersionDeviceAction as Mock).mockImplementation(() => ({\n makeStateMachine: vi.fn().mockImplementation(() =>\n createMachine({\n initial: \"pending\",\n context: {\n intermediateValue: { requiredUserInteraction },\n },\n states: {\n pending: {\n after: {\n 0: \"done\",\n },\n },\n done: {\n type: \"final\",\n },\n },\n output: () => (\"error\" in result ? Left(result.error) : Right(result)),\n }),\n ),\n }));\n};\n"],
|
|
5
|
+
"mappings": "yaAAA,IAAAA,EAAA,GAAAC,EAAAD,EAAA,qCAAAE,IAAA,eAAAC,EAAAH,GAAA,IAAAI,EAGO,2CACPC,EAA4B,qBAE5BC,EAA8B,kBAWvB,MAAMJ,EAAkC,CAC7CK,EAAiE,CAC/D,KAAM,WACN,QAAS,QACX,EACAC,EAAmD,0BAAwB,OACxE,CACF,mCAA0C,mBAAmB,KAAO,CACnE,iBAAkB,GAAG,GAAG,EAAE,mBAAmB,OAC3C,iBAAc,CACZ,QAAS,UACT,QAAS,CACP,kBAAmB,CAAE,wBAAAA,CAAwB,CAC/C,EACA,OAAQ,CACN,QAAS,CACP,MAAO,CACL,EAAG,MACL,CACF,EACA,KAAM,CACJ,KAAM,OACR,CACF,EACA,OAAQ,IAAO,UAAWD,KAAS,QAAKA,EAAO,KAAK,KAAI,SAAMA,CAAM,CACtE,CAAC,CACH,CACF,EAAE,CACJ",
|
|
6
|
+
"names": ["setupWaitForAppAndVersionDAMock_exports", "__export", "setupWaitForAppAndVersionDAMock", "__toCommonJS", "import_device_management_kit", "import_purify_ts", "import_xstate", "result", "requiredUserInteraction"]
|
|
7
|
+
}
|
|
@@ -0,0 +1,2 @@
|
|
|
1
|
+
"use strict";var c=Object.defineProperty;var s=Object.getOwnPropertyDescriptor;var l=Object.getOwnPropertyNames;var v=Object.prototype.hasOwnProperty;var A=(t,e)=>{for(var o in e)c(t,o,{get:e[o],enumerable:!0})},d=(t,e,o,i)=>{if(e&&typeof e=="object"||typeof e=="function")for(let r of l(e))!v.call(t,r)&&r!==o&&c(t,r,{get:()=>e[r],enumerable:!(i=s(e,r))||i.enumerable});return t};var m=t=>d(c({},"__esModule",{value:!0}),t);var I={};A(I,{testDeviceActionStates:()=>D});module.exports=m(I);function D(t,e,o,{onDone:i,onError:r}){const a=[],{observable:u,cancel:p}=t._execute(o);return u.subscribe({next:n=>{a.push(n)},error:n=>{r(n)},complete:()=>{try{expect(a).toEqual(e),i()}catch(n){r(n)}}}),{observable:u,cancel:p}}0&&(module.exports={testDeviceActionStates});
|
|
2
|
+
//# sourceMappingURL=testDeviceActionStates.js.map
|
package/lib/cjs/internal/app-binder/device-action/__test-utils__/testDeviceActionStates.js.map
ADDED
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
{
|
|
2
|
+
"version": 3,
|
|
3
|
+
"sources": ["../../../../../../src/internal/app-binder/device-action/__test-utils__/testDeviceActionStates.ts"],
|
|
4
|
+
"sourcesContent": ["import {\n type DeviceAction,\n type DeviceActionIntermediateValue,\n type DeviceActionState,\n type DmkError,\n type InternalApi,\n} from \"@ledgerhq/device-management-kit\";\n\n/**\n * Test that the states emitted by a device action match the expected states.\n * @param deviceAction The device action to test.\n * @param expectedStates The expected states.\n * @param callbacks { onDone, onError } The callbacks to call when the test is done or an error occurs.\n */\nexport function testDeviceActionStates<\n Output,\n Input,\n Error extends DmkError,\n IntermediateValue extends DeviceActionIntermediateValue,\n>(\n deviceAction: DeviceAction<Output, Input, Error, IntermediateValue>,\n expectedStates: Array<DeviceActionState<Output, Error, IntermediateValue>>,\n internalApi: InternalApi,\n {\n onDone,\n onError,\n }: {\n onDone: () => void;\n onError: (error: Error) => void;\n },\n) {\n const observedStates: Array<\n DeviceActionState<Output, Error, IntermediateValue>\n > = [];\n\n const { observable, cancel } = deviceAction._execute(internalApi);\n observable.subscribe({\n next: (state) => {\n observedStates.push(state);\n },\n error: (error) => {\n onError(error);\n },\n complete: () => {\n try {\n expect(observedStates).toEqual(expectedStates);\n onDone();\n } catch (e) {\n onError(e as Error);\n }\n },\n });\n return { observable, cancel };\n}\n"],
|
|
5
|
+
"mappings": "yaAAA,IAAAA,EAAA,GAAAC,EAAAD,EAAA,4BAAAE,IAAA,eAAAC,EAAAH,GAcO,SAASE,EAMdE,EACAC,EACAC,EACA,CACE,OAAAC,EACA,QAAAC,CACF,EAIA,CACA,MAAMC,EAEF,CAAC,EAEC,CAAE,WAAAC,EAAY,OAAAC,CAAO,EAAIP,EAAa,SAASE,CAAW,EAChE,OAAAI,EAAW,UAAU,CACnB,KAAOE,GAAU,CACfH,EAAe,KAAKG,CAAK,CAC3B,EACA,MAAQC,GAAU,CAChBL,EAAQK,CAAK,CACf,EACA,SAAU,IAAM,CACd,GAAI,CACF,OAAOJ,CAAc,EAAE,QAAQJ,CAAc,EAC7CE,EAAO,CACT,OAASO,EAAG,CACVN,EAAQM,CAAU,CACpB,CACF,CACF,CAAC,EACM,CAAE,WAAAJ,EAAY,OAAAC,CAAO,CAC9B",
|
|
6
|
+
"names": ["testDeviceActionStates_exports", "__export", "testDeviceActionStates", "__toCommonJS", "deviceAction", "expectedStates", "internalApi", "onDone", "onError", "observedStates", "observable", "cancel", "state", "error", "e"]
|
|
7
|
+
}
|