@ledgerhq/device-contacts-kit 0.0.0-develop-20260828024102 → 0.0.0-develop-20260829001241
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +29 -2
- package/lib/cjs/api/ContactsManager.js +1 -1
- package/lib/cjs/api/ContactsManager.js.map +1 -1
- package/lib/cjs/api/app-binder/RenameContactDeviceActionTypes.js +2 -0
- package/lib/cjs/api/app-binder/RenameContactDeviceActionTypes.js.map +7 -0
- package/lib/cjs/api/index.js +1 -1
- package/lib/cjs/api/index.js.map +2 -2
- package/lib/cjs/api/model/RenameContact.js +2 -0
- package/lib/cjs/api/model/RenameContact.js.map +7 -0
- package/lib/cjs/internal/DefaultContactsManager.js +1 -1
- package/lib/cjs/internal/DefaultContactsManager.js.map +2 -2
- package/lib/cjs/internal/DefaultContactsManager.test.js +1 -1
- package/lib/cjs/internal/DefaultContactsManager.test.js.map +3 -3
- package/lib/cjs/internal/app-binder/ContactsAppBinder.js +1 -1
- package/lib/cjs/internal/app-binder/ContactsAppBinder.js.map +3 -3
- package/lib/cjs/internal/app-binder/command/RenameContactCommand.js +2 -0
- package/lib/cjs/internal/app-binder/command/RenameContactCommand.js.map +7 -0
- package/lib/cjs/internal/app-binder/command/RenameContactCommand.test.js +2 -0
- package/lib/cjs/internal/app-binder/command/RenameContactCommand.test.js.map +7 -0
- package/lib/cjs/internal/app-binder/device-action/RenameContact/RenameContactDeviceAction.js +2 -0
- package/lib/cjs/internal/app-binder/device-action/RenameContact/RenameContactDeviceAction.js.map +7 -0
- package/lib/cjs/internal/app-binder/device-action/RenameContact/RenameContactDeviceAction.test.js +2 -0
- package/lib/cjs/internal/app-binder/device-action/RenameContact/RenameContactDeviceAction.test.js.map +7 -0
- package/lib/cjs/internal/app-binder/device-action/RenameContact/validateRenameContactInput.js +2 -0
- package/lib/cjs/internal/app-binder/device-action/RenameContact/validateRenameContactInput.js.map +7 -0
- package/lib/cjs/internal/app-binder/device-action/RenameContact/validateRenameContactInput.test.js +2 -0
- package/lib/cjs/internal/app-binder/device-action/RenameContact/validateRenameContactInput.test.js.map +7 -0
- package/lib/cjs/internal/app-binder/device-action/__test-utils__/setupGoToDashboardDAMock.js +2 -0
- package/lib/cjs/internal/app-binder/device-action/__test-utils__/setupGoToDashboardDAMock.js.map +7 -0
- package/lib/cjs/internal/app-binder/isContactsSupportedForSession.js +1 -1
- package/lib/cjs/internal/app-binder/isContactsSupportedForSession.js.map +3 -3
- package/lib/cjs/internal/app-binder/model/contactsConstants.js +1 -1
- package/lib/cjs/internal/app-binder/model/contactsConstants.js.map +3 -3
- package/lib/cjs/internal/app-binder/task/SendRenameContactTask.js +2 -0
- package/lib/cjs/internal/app-binder/task/SendRenameContactTask.js.map +7 -0
- package/lib/cjs/internal/app-binder/task/SendRenameContactTask.test.js +2 -0
- package/lib/cjs/internal/app-binder/task/SendRenameContactTask.test.js.map +7 -0
- package/lib/cjs/internal/di.test.js +1 -1
- package/lib/cjs/internal/di.test.js.map +3 -3
- package/lib/cjs/internal/use-cases/RenameContactUseCase.js +2 -0
- package/lib/cjs/internal/use-cases/RenameContactUseCase.js.map +7 -0
- package/lib/cjs/internal/use-cases/RenameContactUseCase.test.js +2 -0
- package/lib/cjs/internal/use-cases/RenameContactUseCase.test.js.map +7 -0
- package/lib/cjs/internal/use-cases/di/useCaseModule.js +1 -1
- package/lib/cjs/internal/use-cases/di/useCaseModule.js.map +3 -3
- package/lib/cjs/internal/use-cases/di/useCaseTypes.js +1 -1
- package/lib/cjs/internal/use-cases/di/useCaseTypes.js.map +2 -2
- package/lib/cjs/package.json +1 -1
- package/lib/esm/api/app-binder/RenameContactDeviceActionTypes.js +1 -0
- package/lib/esm/api/app-binder/RenameContactDeviceActionTypes.js.map +7 -0
- package/lib/esm/api/index.js +1 -1
- package/lib/esm/api/index.js.map +2 -2
- package/lib/esm/api/model/RenameContact.js +1 -0
- package/lib/esm/api/model/RenameContact.js.map +7 -0
- package/lib/esm/internal/DefaultContactsManager.js +1 -1
- package/lib/esm/internal/DefaultContactsManager.js.map +2 -2
- package/lib/esm/internal/DefaultContactsManager.test.js +1 -1
- package/lib/esm/internal/DefaultContactsManager.test.js.map +3 -3
- package/lib/esm/internal/app-binder/ContactsAppBinder.js +1 -1
- package/lib/esm/internal/app-binder/ContactsAppBinder.js.map +3 -3
- package/lib/esm/internal/app-binder/command/RenameContactCommand.js +2 -0
- package/lib/esm/internal/app-binder/command/RenameContactCommand.js.map +7 -0
- package/lib/esm/internal/app-binder/command/RenameContactCommand.test.js +2 -0
- package/lib/esm/internal/app-binder/command/RenameContactCommand.test.js.map +7 -0
- package/lib/esm/internal/app-binder/device-action/RenameContact/RenameContactDeviceAction.js +2 -0
- package/lib/esm/internal/app-binder/device-action/RenameContact/RenameContactDeviceAction.js.map +7 -0
- package/lib/esm/internal/app-binder/device-action/RenameContact/RenameContactDeviceAction.test.js +2 -0
- package/lib/esm/internal/app-binder/device-action/RenameContact/RenameContactDeviceAction.test.js.map +7 -0
- package/lib/esm/internal/app-binder/device-action/RenameContact/validateRenameContactInput.js +2 -0
- package/lib/esm/internal/app-binder/device-action/RenameContact/validateRenameContactInput.js.map +7 -0
- package/lib/esm/internal/app-binder/device-action/RenameContact/validateRenameContactInput.test.js +2 -0
- package/lib/esm/internal/app-binder/device-action/RenameContact/validateRenameContactInput.test.js.map +7 -0
- package/lib/esm/internal/app-binder/device-action/__test-utils__/setupGoToDashboardDAMock.js +2 -0
- package/lib/esm/internal/app-binder/device-action/__test-utils__/setupGoToDashboardDAMock.js.map +7 -0
- package/lib/esm/internal/app-binder/isContactsSupportedForSession.js +1 -1
- package/lib/esm/internal/app-binder/isContactsSupportedForSession.js.map +3 -3
- package/lib/esm/internal/app-binder/model/contactsConstants.js +1 -1
- package/lib/esm/internal/app-binder/model/contactsConstants.js.map +3 -3
- package/lib/esm/internal/app-binder/task/SendRenameContactTask.js +2 -0
- package/lib/esm/internal/app-binder/task/SendRenameContactTask.js.map +7 -0
- package/lib/esm/internal/app-binder/task/SendRenameContactTask.test.js +2 -0
- package/lib/esm/internal/app-binder/task/SendRenameContactTask.test.js.map +7 -0
- package/lib/esm/internal/di.test.js +1 -1
- package/lib/esm/internal/di.test.js.map +3 -3
- package/lib/esm/internal/use-cases/RenameContactUseCase.js +2 -0
- package/lib/esm/internal/use-cases/RenameContactUseCase.js.map +7 -0
- package/lib/esm/internal/use-cases/RenameContactUseCase.test.js +2 -0
- package/lib/esm/internal/use-cases/RenameContactUseCase.test.js.map +7 -0
- package/lib/esm/internal/use-cases/di/useCaseModule.js +1 -1
- package/lib/esm/internal/use-cases/di/useCaseModule.js.map +3 -3
- package/lib/esm/internal/use-cases/di/useCaseTypes.js +1 -1
- package/lib/esm/internal/use-cases/di/useCaseTypes.js.map +2 -2
- package/lib/esm/package.json +1 -1
- package/lib/types/api/ContactsManager.d.ts +12 -0
- package/lib/types/api/ContactsManager.d.ts.map +1 -1
- package/lib/types/api/app-binder/RenameContactDeviceActionTypes.d.ts +25 -0
- package/lib/types/api/app-binder/RenameContactDeviceActionTypes.d.ts.map +1 -0
- package/lib/types/api/index.d.ts +2 -0
- package/lib/types/api/index.d.ts.map +1 -1
- package/lib/types/api/model/RenameContact.d.ts +39 -0
- package/lib/types/api/model/RenameContact.d.ts.map +1 -0
- package/lib/types/internal/DefaultContactsManager.d.ts +3 -0
- package/lib/types/internal/DefaultContactsManager.d.ts.map +1 -1
- package/lib/types/internal/app-binder/ContactsAppBinder.d.ts +3 -0
- package/lib/types/internal/app-binder/ContactsAppBinder.d.ts.map +1 -1
- package/lib/types/internal/app-binder/command/RenameContactCommand.d.ts +25 -0
- package/lib/types/internal/app-binder/command/RenameContactCommand.d.ts.map +1 -0
- package/lib/types/internal/app-binder/command/RenameContactCommand.test.d.ts +2 -0
- package/lib/types/internal/app-binder/command/RenameContactCommand.test.d.ts.map +1 -0
- package/lib/types/internal/app-binder/device-action/RenameContact/RenameContactDeviceAction.d.ts +13 -0
- package/lib/types/internal/app-binder/device-action/RenameContact/RenameContactDeviceAction.d.ts.map +1 -0
- package/lib/types/internal/app-binder/device-action/RenameContact/RenameContactDeviceAction.test.d.ts +2 -0
- package/lib/types/internal/app-binder/device-action/RenameContact/RenameContactDeviceAction.test.d.ts.map +1 -0
- package/lib/types/internal/app-binder/device-action/RenameContact/validateRenameContactInput.d.ts +12 -0
- package/lib/types/internal/app-binder/device-action/RenameContact/validateRenameContactInput.d.ts.map +1 -0
- package/lib/types/internal/app-binder/device-action/RenameContact/validateRenameContactInput.test.d.ts +2 -0
- package/lib/types/internal/app-binder/device-action/RenameContact/validateRenameContactInput.test.d.ts.map +1 -0
- package/lib/types/internal/app-binder/device-action/__test-utils__/setupGoToDashboardDAMock.d.ts +12 -0
- package/lib/types/internal/app-binder/device-action/__test-utils__/setupGoToDashboardDAMock.d.ts.map +1 -0
- package/lib/types/internal/app-binder/isContactsSupportedForSession.d.ts +15 -0
- package/lib/types/internal/app-binder/isContactsSupportedForSession.d.ts.map +1 -1
- package/lib/types/internal/app-binder/model/contactsConstants.d.ts +15 -0
- package/lib/types/internal/app-binder/model/contactsConstants.d.ts.map +1 -1
- package/lib/types/internal/app-binder/task/SendRenameContactTask.d.ts +20 -0
- package/lib/types/internal/app-binder/task/SendRenameContactTask.d.ts.map +1 -0
- package/lib/types/internal/app-binder/task/SendRenameContactTask.test.d.ts +2 -0
- package/lib/types/internal/app-binder/task/SendRenameContactTask.test.d.ts.map +1 -0
- package/lib/types/internal/use-cases/RenameContactUseCase.d.ts +19 -0
- package/lib/types/internal/use-cases/RenameContactUseCase.d.ts.map +1 -0
- package/lib/types/internal/use-cases/RenameContactUseCase.test.d.ts +2 -0
- package/lib/types/internal/use-cases/RenameContactUseCase.test.d.ts.map +1 -0
- package/lib/types/internal/use-cases/di/useCaseModule.d.ts.map +1 -1
- package/lib/types/internal/use-cases/di/useCaseTypes.d.ts +1 -0
- package/lib/types/internal/use-cases/di/useCaseTypes.d.ts.map +1 -1
- package/lib/types/tsconfig.prod.tsbuildinfo +1 -1
- package/package.json +6 -6
package/lib/esm/internal/app-binder/device-action/__test-utils__/setupGoToDashboardDAMock.js.map
ADDED
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
{
|
|
2
|
+
"version": 3,
|
|
3
|
+
"sources": ["../../../../../../src/internal/app-binder/device-action/__test-utils__/setupGoToDashboardDAMock.ts"],
|
|
4
|
+
"sourcesContent": ["import {\n GoToDashboardDeviceAction,\n UserInteractionRequired,\n} from \"@ledgerhq/device-management-kit\";\nimport { Left, Right } from \"purify-ts\";\nimport { type Mock } from \"vitest\";\nimport { assign, createMachine } from \"xstate\";\n\n/**\n * Mock GoToDashboardDeviceAction to resolve immediately with either success\n * (default) or an error. Emits a single `requiredUserInteraction` snapshot\n * (default `None` \u2014 device assumed unlocked and already ready) so the parent\n * action can surface it, mirroring the real nested device action.\n */\nexport const setupGoToDashboardDAMock = (\n options: {\n error?: unknown;\n requiredUserInteraction?: UserInteractionRequired;\n } = {},\n) => {\n const interaction =\n options.requiredUserInteraction ?? UserInteractionRequired.None;\n (GoToDashboardDeviceAction as Mock).mockImplementation(() => ({\n makeStateMachine: vi.fn().mockImplementation(() =>\n createMachine({\n initial: \"pending\",\n states: {\n pending: {\n entry: assign({\n intermediateValue: {\n requiredUserInteraction: interaction,\n },\n }),\n after: {\n 0: \"done\",\n },\n },\n done: {\n type: \"final\",\n },\n },\n output: () => (options.error ? Left(options.error) : Right(undefined)),\n }),\n ),\n }));\n};\n"],
|
|
5
|
+
"mappings": "AAAA,OACE,6BAAAA,EACA,2BAAAC,MACK,kCACP,OAAS,QAAAC,EAAM,SAAAC,MAAa,YAE5B,OAAS,UAAAC,EAAQ,iBAAAC,MAAqB,SAQ/B,MAAMC,EAA2B,CACtCC,EAGI,CAAC,IACF,CACH,MAAMC,EACJD,EAAQ,yBAA2BN,EAAwB,KAC5DD,EAAmC,mBAAmB,KAAO,CAC5D,iBAAkB,GAAG,GAAG,EAAE,mBAAmB,IAC3CK,EAAc,CACZ,QAAS,UACT,OAAQ,CACN,QAAS,CACP,MAAOD,EAAO,CACZ,kBAAmB,CACjB,wBAAyBI,CAC3B,CACF,CAAC,EACD,MAAO,CACL,EAAG,MACL,CACF,EACA,KAAM,CACJ,KAAM,OACR,CACF,EACA,OAAQ,IAAOD,EAAQ,MAAQL,EAAKK,EAAQ,KAAK,EAAIJ,EAAM,MAAS,CACtE,CAAC,CACH,CACF,EAAE,CACJ",
|
|
6
|
+
"names": ["GoToDashboardDeviceAction", "UserInteractionRequired", "Left", "Right", "assign", "createMachine", "setupGoToDashboardDAMock", "options", "interaction"]
|
|
7
|
+
}
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import{ApplicationChecker as
|
|
1
|
+
import{ApplicationChecker as a}from"@ledgerhq/device-management-kit";import{isVersionAtLeast as s,resolveContactsVersionRequirements as p}from"../../api/model/ContactsVersionRequirements";import{ContactsApplicationResolver as c}from"./ContactsApplicationResolver";function m(r,n){const e=r.getDeviceSessionState(),i=p(e.deviceModelId);if(!i.supported)return!1;const o=i.minAppVersion[n.name];if(o===void 0||!new a(e,{version:n.version},new c).withMinVersionInclusive(o).check())return!1;const t="firmwareVersion"in e?e.firmwareVersion?.os:void 0;return t===void 0?!1:s(t,i.minOsVersion)}function V(r){const n=r.getDeviceSessionState(),e=p(n.deviceModelId);if(!e.supported)return!1;const i="firmwareVersion"in n?n.firmwareVersion?.os:void 0;return i===void 0?!1:s(i,e.minOsVersion)}export{V as isContactsOsSupportedForSession,m as isContactsSupportedForSession};
|
|
2
2
|
//# sourceMappingURL=isContactsSupportedForSession.js.map
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"version": 3,
|
|
3
3
|
"sources": ["../../../../src/internal/app-binder/isContactsSupportedForSession.ts"],
|
|
4
|
-
"sourcesContent": ["import {\n ApplicationChecker,\n type InternalApi,\n} from \"@ledgerhq/device-management-kit\";\n\nimport {\n isVersionAtLeast,\n resolveContactsVersionRequirements,\n} from \"@api/model/ContactsVersionRequirements\";\n\nimport { ContactsApplicationResolver } from \"./ContactsApplicationResolver\";\n\n/** The running app's identity, read freshly from the device. */\nexport type RunningApp = {\n readonly name: string;\n readonly version: string;\n};\n\n/**\n * Session-aware Contacts support check, for internal consumption by Contacts\n * `DeviceAction`s. Resolves the given running app against the static\n * requirements table:\n * - the device model must be supported;\n * - the running app must be known to Contacts and meet its minimum version;\n * - the device OS must meet its minimum version (a dimension `ApplicationChecker`\n * does not cover, so it is checked separately here).\n *\n * The app `name` and `version` are supplied by the caller so they can come from\n * a fresh `WaitForAppAndVersion` result rather than the (potentially stale)\n * device session state; the model and OS come from the session state, which\n * does not change under the caller's feet the way the running app can.\n *\n * @param internalApi - the DeviceAction's internal API for the current session.\n * @param app - the running app's fresh name and version.\n */\nexport function isContactsSupportedForSession(\n internalApi: InternalApi,\n app: RunningApp,\n): boolean {\n const deviceState = internalApi.getDeviceSessionState();\n const requirement = resolveContactsVersionRequirements(\n deviceState.deviceModelId,\n );\n if (!requirement.supported) return false;\n\n const minAppVersion = requirement.minAppVersion[app.name];\n if (minAppVersion === undefined) return false;\n\n const appCompatible = new ApplicationChecker(\n deviceState,\n { version: app.version },\n new ContactsApplicationResolver(),\n )\n .withMinVersionInclusive(minAppVersion)\n .check();\n if (!appCompatible) return false;\n\n const osVersion =\n \"firmwareVersion\" in deviceState\n ? deviceState.firmwareVersion?.os\n : undefined;\n if (osVersion === undefined) return false;\n\n return isVersionAtLeast(osVersion, requirement.minOsVersion);\n}\n"],
|
|
5
|
-
"mappings": "AAAA,OACE,sBAAAA,MAEK,kCAEP,OACE,oBAAAC,EACA,sCAAAC,MACK,yCAEP,OAAS,+BAAAC,MAAmC,gCAyBrC,SAASC,EACdC,EACAC,EACS,CACT,MAAMC,EAAcF,EAAY,sBAAsB,EAChDG,EAAcN,EAClBK,EAAY,aACd,EACA,GAAI,CAACC,EAAY,UAAW,MAAO,GAEnC,MAAMC,EAAgBD,EAAY,cAAcF,EAAI,IAAI,EAUxD,GATIG,IAAkB,QASlB,CAPkB,IAAIT,EACxBO,EACA,CAAE,QAASD,EAAI,OAAQ,EACvB,IAAIH,CACN,EACG,wBAAwBM,CAAa,EACrC,MAAM,EACW,MAAO,GAE3B,MAAMC,EACJ,oBAAqBH,EACjBA,EAAY,iBAAiB,GAC7B,OACN,OAAIG,IAAc,OAAkB,GAE7BT,EAAiBS,EAAWF,EAAY,YAAY,CAC7D",
|
|
6
|
-
"names": ["ApplicationChecker", "isVersionAtLeast", "resolveContactsVersionRequirements", "ContactsApplicationResolver", "isContactsSupportedForSession", "internalApi", "app", "deviceState", "requirement", "minAppVersion", "osVersion"]
|
|
4
|
+
"sourcesContent": ["import {\n ApplicationChecker,\n type InternalApi,\n} from \"@ledgerhq/device-management-kit\";\n\nimport {\n isVersionAtLeast,\n resolveContactsVersionRequirements,\n} from \"@api/model/ContactsVersionRequirements\";\n\nimport { ContactsApplicationResolver } from \"./ContactsApplicationResolver\";\n\n/** The running app's identity, read freshly from the device. */\nexport type RunningApp = {\n readonly name: string;\n readonly version: string;\n};\n\n/**\n * Session-aware Contacts support check, for internal consumption by Contacts\n * `DeviceAction`s. Resolves the given running app against the static\n * requirements table:\n * - the device model must be supported;\n * - the running app must be known to Contacts and meet its minimum version;\n * - the device OS must meet its minimum version (a dimension `ApplicationChecker`\n * does not cover, so it is checked separately here).\n *\n * The app `name` and `version` are supplied by the caller so they can come from\n * a fresh `WaitForAppAndVersion` result rather than the (potentially stale)\n * device session state; the model and OS come from the session state, which\n * does not change under the caller's feet the way the running app can.\n *\n * @param internalApi - the DeviceAction's internal API for the current session.\n * @param app - the running app's fresh name and version.\n */\nexport function isContactsSupportedForSession(\n internalApi: InternalApi,\n app: RunningApp,\n): boolean {\n const deviceState = internalApi.getDeviceSessionState();\n const requirement = resolveContactsVersionRequirements(\n deviceState.deviceModelId,\n );\n if (!requirement.supported) return false;\n\n const minAppVersion = requirement.minAppVersion[app.name];\n if (minAppVersion === undefined) return false;\n\n const appCompatible = new ApplicationChecker(\n deviceState,\n { version: app.version },\n new ContactsApplicationResolver(),\n )\n .withMinVersionInclusive(minAppVersion)\n .check();\n if (!appCompatible) return false;\n\n const osVersion =\n \"firmwareVersion\" in deviceState\n ? deviceState.firmwareVersion?.os\n : undefined;\n if (osVersion === undefined) return false;\n\n return isVersionAtLeast(osVersion, requirement.minOsVersion);\n}\n\n/**\n * OS-only Contacts support check, for internal consumption by dashboard\n * `DeviceAction`s (e.g. Rename Contact, EDIT CONTACT NAME). Dashboard operations\n * are served by the device OS, not the embedded app, so only two dimensions\n * apply:\n * - the device model must be supported;\n * - the device OS must meet its minimum version.\n *\n * The running-app dimension is intentionally skipped: on the dashboard there is\n * no embedded app to gate on (the running \"app\" is BOLOS). The model and OS both\n * come from the session state, which is stable across the operation.\n *\n * @param internalApi - the DeviceAction's internal API for the current session.\n */\nexport function isContactsOsSupportedForSession(\n internalApi: InternalApi,\n): boolean {\n const deviceState = internalApi.getDeviceSessionState();\n const requirement = resolveContactsVersionRequirements(\n deviceState.deviceModelId,\n );\n if (!requirement.supported) return false;\n\n const osVersion =\n \"firmwareVersion\" in deviceState\n ? deviceState.firmwareVersion?.os\n : undefined;\n if (osVersion === undefined) return false;\n\n return isVersionAtLeast(osVersion, requirement.minOsVersion);\n}\n"],
|
|
5
|
+
"mappings": "AAAA,OACE,sBAAAA,MAEK,kCAEP,OACE,oBAAAC,EACA,sCAAAC,MACK,yCAEP,OAAS,+BAAAC,MAAmC,gCAyBrC,SAASC,EACdC,EACAC,EACS,CACT,MAAMC,EAAcF,EAAY,sBAAsB,EAChDG,EAAcN,EAClBK,EAAY,aACd,EACA,GAAI,CAACC,EAAY,UAAW,MAAO,GAEnC,MAAMC,EAAgBD,EAAY,cAAcF,EAAI,IAAI,EAUxD,GATIG,IAAkB,QASlB,CAPkB,IAAIT,EACxBO,EACA,CAAE,QAASD,EAAI,OAAQ,EACvB,IAAIH,CACN,EACG,wBAAwBM,CAAa,EACrC,MAAM,EACW,MAAO,GAE3B,MAAMC,EACJ,oBAAqBH,EACjBA,EAAY,iBAAiB,GAC7B,OACN,OAAIG,IAAc,OAAkB,GAE7BT,EAAiBS,EAAWF,EAAY,YAAY,CAC7D,CAgBO,SAASG,EACdN,EACS,CACT,MAAME,EAAcF,EAAY,sBAAsB,EAChDG,EAAcN,EAClBK,EAAY,aACd,EACA,GAAI,CAACC,EAAY,UAAW,MAAO,GAEnC,MAAME,EACJ,oBAAqBH,EACjBA,EAAY,iBAAiB,GAC7B,OACN,OAAIG,IAAc,OAAkB,GAE7BT,EAAiBS,EAAWF,EAAY,YAAY,CAC7D",
|
|
6
|
+
"names": ["ApplicationChecker", "isVersionAtLeast", "resolveContactsVersionRequirements", "ContactsApplicationResolver", "isContactsSupportedForSession", "internalApi", "app", "deviceState", "requirement", "minAppVersion", "osVersion", "isContactsOsSupportedForSession"]
|
|
7
7
|
}
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
const o=176,t=16,
|
|
1
|
+
const o=176,t=16,_=1,x=224,A=46,e=0,C=64,T=32,n=32,E=32,r={bitcoin:0,ethereum:1,solana:2,polkadot:3,cosmos:4,cardano:5};export{r as BLOCKCHAIN_FAMILY_BY_NAME,o as CONTACTS_APDU_CLA,t as CONTACTS_APDU_INS,C as GROUP_HANDLE_BYTES,E as HMAC_NAME_BYTES,T as HMAC_PROOF_BYTES,n as HMAC_REST_BYTES,x as RENAME_CONTACT_APDU_CLA,A as RENAME_CONTACT_APDU_INS,e as RENAME_CONTACT_P1,_ as SUB_CMD_REGISTER_IDENTITY};
|
|
2
2
|
//# sourceMappingURL=contactsConstants.js.map
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"version": 3,
|
|
3
3
|
"sources": ["../../../../../src/internal/app-binder/model/contactsConstants.ts"],
|
|
4
|
-
"sourcesContent": ["/**\n * Protocol constants shared by the Contacts (Address Book) operations.\n *\n * Wire format and values follow the BOLOS SDK Address Book specification\n * (ledger-secure-sdk/app_features/address_book). Op-specific sub-command bytes\n * and response field sizes live here; TLV tags and struct-type bytes live in\n * {@link ./../services/contactsTlvSerializer}.\n */\n\n/** APDU class/instruction shared by every Address Book sub-command. */\nexport const CONTACTS_APDU_CLA = 0xb0;\nexport const CONTACTS_APDU_INS = 0x10;\n\n/** P1 sub-command selector for REGISTER IDENTITY (register external address). */\nexport const SUB_CMD_REGISTER_IDENTITY = 0x01;\n\n/** Sizes (bytes) of the fields in the REGISTER IDENTITY final-chunk response. */\nexport const GROUP_HANDLE_BYTES = 64;\nexport const HMAC_PROOF_BYTES = 32;\nexport const HMAC_REST_BYTES = 32;\n\n/**\n * Blockchain-family byte encoded in the `BLOCKCHAIN_FAMILY` TLV, keyed by a\n * lowercase family name. v1 ships Ethereum only; the remaining families are\n * listed for completeness and will be enabled as their chains are supported.\n */\nexport const BLOCKCHAIN_FAMILY_BY_NAME: Readonly<Record<string, number>> = {\n bitcoin: 0x00,\n ethereum: 0x01,\n solana: 0x02,\n polkadot: 0x03,\n cosmos: 0x04,\n cardano: 0x05,\n};\n"],
|
|
5
|
-
"mappings": "AAUO,MAAMA,EAAoB,IACpBC,EAAoB,GAGpBC,EAA4B,
|
|
6
|
-
"names": ["CONTACTS_APDU_CLA", "CONTACTS_APDU_INS", "SUB_CMD_REGISTER_IDENTITY", "GROUP_HANDLE_BYTES", "HMAC_PROOF_BYTES", "HMAC_REST_BYTES", "BLOCKCHAIN_FAMILY_BY_NAME"]
|
|
4
|
+
"sourcesContent": ["/**\n * Protocol constants shared by the Contacts (Address Book) operations.\n *\n * Wire format and values follow the BOLOS SDK Address Book specification\n * (ledger-secure-sdk/app_features/address_book). Op-specific sub-command bytes\n * and response field sizes live here; TLV tags and struct-type bytes live in\n * {@link ./../services/contactsTlvSerializer}.\n */\n\n/** APDU class/instruction shared by every Address Book sub-command. */\nexport const CONTACTS_APDU_CLA = 0xb0;\nexport const CONTACTS_APDU_INS = 0x10;\n\n/** P1 sub-command selector for REGISTER IDENTITY (register external address). */\nexport const SUB_CMD_REGISTER_IDENTITY = 0x01;\n\n/**\n * EDIT CONTACT NAME (rename) is a blockchain-agnostic OS/dashboard command with\n * its own CLA/INS \u2014 NOT a sub-command of the address-book app APDU (0xB0/0x10).\n * The OS serves it directly, so it must run on the dashboard. P1 is a fixed\n * 0x00 (there is no sub-command selector for this command); P2 still carries the\n * chunk-continuation flag handled by {@link ./../services/sendFramedContactsPayload}.\n */\nexport const RENAME_CONTACT_APDU_CLA = 0xe0;\nexport const RENAME_CONTACT_APDU_INS = 0x2e;\nexport const RENAME_CONTACT_P1 = 0x00;\n\n/** Sizes (bytes) of the fields in the REGISTER IDENTITY final-chunk response. */\nexport const GROUP_HANDLE_BYTES = 64;\nexport const HMAC_PROOF_BYTES = 32;\nexport const HMAC_REST_BYTES = 32;\n\n/**\n * Size (bytes) of the rotated `hmac_name` returned on the EDIT CONTACT NAME\n * final-chunk response \u2014 the replacement group-level name proof.\n */\nexport const HMAC_NAME_BYTES = 32;\n\n/**\n * Blockchain-family byte encoded in the `BLOCKCHAIN_FAMILY` TLV, keyed by a\n * lowercase family name. v1 ships Ethereum only; the remaining families are\n * listed for completeness and will be enabled as their chains are supported.\n */\nexport const BLOCKCHAIN_FAMILY_BY_NAME: Readonly<Record<string, number>> = {\n bitcoin: 0x00,\n ethereum: 0x01,\n solana: 0x02,\n polkadot: 0x03,\n cosmos: 0x04,\n cardano: 0x05,\n};\n"],
|
|
5
|
+
"mappings": "AAUO,MAAMA,EAAoB,IACpBC,EAAoB,GAGpBC,EAA4B,EAS5BC,EAA0B,IAC1BC,EAA0B,GAC1BC,EAAoB,EAGpBC,EAAqB,GACrBC,EAAmB,GACnBC,EAAkB,GAMlBC,EAAkB,GAOlBC,EAA8D,CACzE,QAAS,EACT,SAAU,EACV,OAAQ,EACR,SAAU,EACV,OAAQ,EACR,QAAS,CACX",
|
|
6
|
+
"names": ["CONTACTS_APDU_CLA", "CONTACTS_APDU_INS", "SUB_CMD_REGISTER_IDENTITY", "RENAME_CONTACT_APDU_CLA", "RENAME_CONTACT_APDU_INS", "RENAME_CONTACT_P1", "GROUP_HANDLE_BYTES", "HMAC_PROOF_BYTES", "HMAC_REST_BYTES", "HMAC_NAME_BYTES", "BLOCKCHAIN_FAMILY_BY_NAME"]
|
|
7
7
|
}
|
|
@@ -0,0 +1,2 @@
|
|
|
1
|
+
import{ByteArrayBuilder as c,DmkResultFactory as n,InvalidStatusWordError as C,isSuccessCommandResult as l}from"@ledgerhq/device-management-kit";import{RenameContactCommand as T}from"../../app-binder/command/RenameContactCommand";import{RENAME_CONTACT_P1 as p}from"../../app-binder/model/contactsConstants";import{CONTACTS_TLV_TAG as e,encodeTlvAscii as m,encodeTlvBuffer as o,encodeTlvUInt8 as s,packDerivationPath as y,STRUCT_TYPE_EDIT_CONTACT_NAME as u,STRUCT_VERSION_VALUE as A}from"../../app-binder/services/contactsTlvSerializer";import{sendFramedContactsPayload as R}from"../../app-binder/services/sendFramedContactsPayload";class S{constructor(a,r){this.api=a;this.args=r}async run(){const a=this.buildPayload(this.args),r=await R(this.api,{payload:a,p1:p,makeCommand:(d,i)=>new T({data:d,p2:i}),logger:this.args.logger,commandTag:"SendRenameContactTask"});if(!l(r))return r;const{hmacProof:t}=r.data;return t?n({data:{hmacProof:t}}):n({error:new C("RenameContact final-chunk response did not carry hmac_name")})}buildPayload(a){const r=new c;return s(r,e.STRUCT_TYPE,u),s(r,e.STRUCT_VERSION,A),m(r,e.CONTACT_NAME,a.newContactName),m(r,e.PREVIOUS_CONTACT_NAME,a.previousContactName),o(r,e.GROUP_HANDLE,a.groupHandle),o(r,e.DERIVATION_PATH,y([2147483692,2147483708,2147483648,0,0])),o(r,e.HMAC_PROOF,a.hmacProof),r.build()}}export{S as SendRenameContactTask};
|
|
2
|
+
//# sourceMappingURL=SendRenameContactTask.js.map
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
{
|
|
2
|
+
"version": 3,
|
|
3
|
+
"sources": ["../../../../../src/internal/app-binder/task/SendRenameContactTask.ts"],
|
|
4
|
+
"sourcesContent": ["// Builds the TLV payload for the Rename Contact (EDIT CONTACT NAME) op and\n// dispatches it via the chunked-framing scheme shared with the other\n// address-book ops (2-byte BE total length + <=255B chunks). Rename is an\n// OS/dashboard command (CLA 0xE0 / INS 0x2E) \u2014 the caller runs this task after\n// navigating to the dashboard (GoToDashboardDeviceAction), never inside an app.\n//\n// The device rotates the contact-level hmac_name and returns the fresh proof on\n// the final chunk; per-entry hmac_rest values are untouched (they bind\n// gid|scope|id|family|chain_id, never the name), so a single APDU regardless of\n// the contact's entry count.\n//\n// Reference: Address Book Final Specifications \u2014 Edit Contact Name. Tag order:\n// STRUCT_TYPE, STRUCT_VERSION, CONTACT_NAME (new), PREVIOUS_CONTACT_NAME\n// (old), GROUP_HANDLE, DERIVATION_PATH, HMAC_PROOF.\nimport {\n ByteArrayBuilder,\n type CommandResult,\n DmkResultFactory,\n type InternalApi,\n InvalidStatusWordError,\n isSuccessCommandResult,\n type LoggerPublisherService,\n} from \"@ledgerhq/device-management-kit\";\n\nimport { RenameContactCommand } from \"@internal/app-binder/command/RenameContactCommand\";\nimport { RENAME_CONTACT_P1 } from \"@internal/app-binder/model/contactsConstants\";\nimport { type ContactsErrorCodes } from \"@internal/app-binder/model/contactsErrors\";\nimport {\n CONTACTS_TLV_TAG,\n encodeTlvAscii,\n encodeTlvBuffer,\n encodeTlvUInt8,\n packDerivationPath,\n STRUCT_TYPE_EDIT_CONTACT_NAME,\n STRUCT_VERSION_VALUE,\n} from \"@internal/app-binder/services/contactsTlvSerializer\";\nimport { sendFramedContactsPayload } from \"@internal/app-binder/services/sendFramedContactsPayload\";\n\nexport type RenameContactProof = {\n readonly hmacProof: Uint8Array;\n};\n\nexport type SendRenameContactTaskArgs = {\n readonly previousContactName: string;\n readonly newContactName: string;\n readonly groupHandle: Uint8Array;\n readonly hmacProof: Uint8Array;\n readonly logger?: LoggerPublisherService;\n};\n\nexport class SendRenameContactTask {\n constructor(\n private readonly api: InternalApi,\n private readonly args: SendRenameContactTaskArgs,\n ) {}\n\n async run(): Promise<CommandResult<RenameContactProof, ContactsErrorCodes>> {\n const payload = this.buildPayload(this.args);\n\n const result = (await sendFramedContactsPayload(this.api, {\n payload,\n p1: RENAME_CONTACT_P1,\n makeCommand: (chunk, p2) => new RenameContactCommand({ data: chunk, p2 }),\n logger: this.args.logger,\n commandTag: \"SendRenameContactTask\",\n })) as CommandResult<\n { readonly hmacProof?: Uint8Array },\n ContactsErrorCodes\n >;\n\n if (!isSuccessCommandResult(result)) {\n return result;\n }\n\n const { hmacProof } = result.data;\n if (!hmacProof) {\n return DmkResultFactory({\n error: new InvalidStatusWordError(\n \"RenameContact final-chunk response did not carry hmac_name\",\n ),\n });\n }\n return DmkResultFactory({ data: { hmacProof } });\n }\n\n private buildPayload(args: SendRenameContactTaskArgs): Uint8Array {\n const builder = new ByteArrayBuilder();\n encodeTlvUInt8(\n builder,\n CONTACTS_TLV_TAG.STRUCT_TYPE,\n STRUCT_TYPE_EDIT_CONTACT_NAME,\n );\n encodeTlvUInt8(\n builder,\n CONTACTS_TLV_TAG.STRUCT_VERSION,\n STRUCT_VERSION_VALUE,\n );\n encodeTlvAscii(builder, CONTACTS_TLV_TAG.CONTACT_NAME, args.newContactName);\n encodeTlvAscii(\n builder,\n CONTACTS_TLV_TAG.PREVIOUS_CONTACT_NAME,\n args.previousContactName,\n );\n encodeTlvBuffer(builder, CONTACTS_TLV_TAG.GROUP_HANDLE, args.groupHandle);\n // The Ethereum app requires DERIVATION_PATH on Edit Contact Name (0x6a80\n // without it), same as Register Identity. Default m/44'/60'/0'/0/0.\n encodeTlvBuffer(\n builder,\n CONTACTS_TLV_TAG.DERIVATION_PATH,\n packDerivationPath([0x8000002c, 0x8000003c, 0x80000000, 0, 0]),\n );\n encodeTlvBuffer(builder, CONTACTS_TLV_TAG.HMAC_PROOF, args.hmacProof);\n\n return builder.build();\n }\n}\n"],
|
|
5
|
+
"mappings": "AAcA,OACE,oBAAAA,EAEA,oBAAAC,EAEA,0BAAAC,EACA,0BAAAC,MAEK,kCAEP,OAAS,wBAAAC,MAA4B,oDACrC,OAAS,qBAAAC,MAAyB,+CAElC,OACE,oBAAAC,EACA,kBAAAC,EACA,mBAAAC,EACA,kBAAAC,EACA,sBAAAC,EACA,iCAAAC,EACA,wBAAAC,MACK,sDACP,OAAS,6BAAAC,MAAiC,0DAcnC,MAAMC,CAAsB,CACjC,YACmBC,EACAC,EACjB,CAFiB,SAAAD,EACA,UAAAC,CAChB,CAEH,MAAM,KAAsE,CAC1E,MAAMC,EAAU,KAAK,aAAa,KAAK,IAAI,EAErCC,EAAU,MAAML,EAA0B,KAAK,IAAK,CACxD,QAAAI,EACA,GAAIZ,EACJ,YAAa,CAACc,EAAOC,IAAO,IAAIhB,EAAqB,CAAE,KAAMe,EAAO,GAAAC,CAAG,CAAC,EACxE,OAAQ,KAAK,KAAK,OAClB,WAAY,uBACd,CAAC,EAKD,GAAI,CAACjB,EAAuBe,CAAM,EAChC,OAAOA,EAGT,KAAM,CAAE,UAAAG,CAAU,EAAIH,EAAO,KAC7B,OAAKG,EAOEpB,EAAiB,CAAE,KAAM,CAAE,UAAAoB,CAAU,CAAE,CAAC,EANtCpB,EAAiB,CACtB,MAAO,IAAIC,EACT,4DACF,CACF,CAAC,CAGL,CAEQ,aAAac,EAA6C,CAChE,MAAMM,EAAU,IAAItB,EACpB,OAAAS,EACEa,EACAhB,EAAiB,YACjBK,CACF,EACAF,EACEa,EACAhB,EAAiB,eACjBM,CACF,EACAL,EAAee,EAAShB,EAAiB,aAAcU,EAAK,cAAc,EAC1ET,EACEe,EACAhB,EAAiB,sBACjBU,EAAK,mBACP,EACAR,EAAgBc,EAAShB,EAAiB,aAAcU,EAAK,WAAW,EAGxER,EACEc,EACAhB,EAAiB,gBACjBI,EAAmB,CAAC,WAAY,WAAY,WAAY,EAAG,CAAC,CAAC,CAC/D,EACAF,EAAgBc,EAAShB,EAAiB,WAAYU,EAAK,SAAS,EAE7DM,EAAQ,MAAM,CACvB,CACF",
|
|
6
|
+
"names": ["ByteArrayBuilder", "DmkResultFactory", "InvalidStatusWordError", "isSuccessCommandResult", "RenameContactCommand", "RENAME_CONTACT_P1", "CONTACTS_TLV_TAG", "encodeTlvAscii", "encodeTlvBuffer", "encodeTlvUInt8", "packDerivationPath", "STRUCT_TYPE_EDIT_CONTACT_NAME", "STRUCT_VERSION_VALUE", "sendFramedContactsPayload", "SendRenameContactTask", "api", "args", "payload", "result", "chunk", "p2", "hmacProof", "builder"]
|
|
7
|
+
}
|
|
@@ -0,0 +1,2 @@
|
|
|
1
|
+
import{CommandResultFactory as t,InvalidStatusWordError as d}from"@ledgerhq/device-management-kit";import{RenameContactCommand as p}from"../../app-binder/command/RenameContactCommand";import{SendRenameContactTask as o}from"./SendRenameContactTask";function s(e){const n=new Uint8Array(e.length/2);for(let a=0;a<e.length;a+=2)n[a/2]=parseInt(e.slice(a,a+2),16);return n}const r=s("cc".repeat(64)),c=s("dd".repeat(32)),i=s("ee".repeat(32)),l="6915058000002c8000003c800000000000000000000000",u=s("009001012e02010181f003426f6281f305416c69636581f640"+"cc".repeat(64)+l+"2920"+"dd".repeat(32));function m(){return{sendCommand:vi.fn()}}describe("SendRenameContactTask",()=>{it("assembles the rename framed chunk and dispatches RenameContactCommand",async()=>{const e=m();e.sendCommand.mockResolvedValueOnce(t({data:{hmacProof:i}}));const n=await new o(e,{previousContactName:"Alice",newContactName:"Bob",groupHandle:r,hmacProof:c}).run();expect(e.sendCommand.mock.calls).toHaveLength(1),expect(e.sendCommand.mock.calls[0][0]).toStrictEqual(new p({data:u,p2:0})),expect(n).toStrictEqual(t({data:{hmacProof:i}}))}),it("emits the DERIVATION_PATH tag immediately before HMAC_PROOF",async()=>{const e=m();e.sendCommand.mockResolvedValueOnce(t({data:{hmacProof:i}})),await new o(e,{previousContactName:"Alice",newContactName:"Bob",groupHandle:r,hmacProof:c}).run();const n=e.sendCommand.mock.calls[0][0],a=Buffer.from(n.args.data).toString("hex");expect(a.endsWith(l+"2920"+"dd".repeat(32))).toBe(!0)}),it("propagates command-level errors",async()=>{const e=m();e.sendCommand.mockResolvedValueOnce(t({error:new d("user cancelled")}));const n=await new o(e,{previousContactName:"Alice",newContactName:"Bob",groupHandle:r,hmacProof:c}).run();expect(n).toStrictEqual(t({error:new d("user cancelled")}))}),it("returns InvalidStatusWordError when the final response carries no hmac_name",async()=>{const e=m();e.sendCommand.mockResolvedValueOnce(t({data:{}}));const n=await new o(e,{previousContactName:"Alice",newContactName:"Bob",groupHandle:r,hmacProof:c}).run();expect(n.status).not.toBe(void 0),"error"in n&&expect(n.error).toBeInstanceOf(d)})});
|
|
2
|
+
//# sourceMappingURL=SendRenameContactTask.test.js.map
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
{
|
|
2
|
+
"version": 3,
|
|
3
|
+
"sources": ["../../../../../src/internal/app-binder/task/SendRenameContactTask.test.ts"],
|
|
4
|
+
"sourcesContent": ["// Validates that the TLV serializer + tag ordering + chunk framing produce the\n// expected wire bytes for the Rename Contact (EDIT CONTACT NAME) op. The framed\n// chunk = 2-byte BE total length + TLV. Tag order: STRUCT_TYPE, STRUCT_VERSION,\n// CONTACT_NAME (new), PREVIOUS_CONTACT_NAME (old), GROUP_HANDLE, DERIVATION_PATH,\n// HMAC_PROOF \u2014 with tags >= 0x80 (0xf0/0xf3/0xf6) encoded as the 2-byte DER form\n// [0x81, tag].\nimport {\n CommandResultFactory,\n type InternalApi,\n InvalidStatusWordError,\n} from \"@ledgerhq/device-management-kit\";\n\nimport { RenameContactCommand } from \"@internal/app-binder/command/RenameContactCommand\";\n\nimport { SendRenameContactTask } from \"./SendRenameContactTask\";\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\nconst GROUP_HANDLE = hexToBytes(\"cc\".repeat(64));\nconst HMAC_PROOF_IN = hexToBytes(\"dd\".repeat(32));\nconst HMAC_PROOF_OUT = hexToBytes(\"ee\".repeat(32));\n\n// Framed chunk = \"00 90\" (2-byte BE total TLV length = 144) + TLV:\n// 01 01 2e STRUCT_TYPE = EDIT_CONTACT_NAME (0x2e)\n// 02 01 01 STRUCT_VERSION = 1\n// 81 f0 03 \"Bob\" CONTACT_NAME (new), tag 0xf0 -> [81 f0]\n// 81 f3 05 \"Alice\" PREVIOUS_CONTACT_NAME (old), tag 0xf3 -> [81 f3]\n// 81 f6 40 <64x cc> GROUP_HANDLE, tag 0xf6 -> [81 f6]\n// 69 15 05 <5x path> DERIVATION_PATH (0x69), m/44'/60'/0'/0/0\n// 29 20 <32x dd> HMAC_PROOF\nconst DERIVATION_PATH_TLV = \"6915058000002c8000003c800000000000000000000000\";\nconst FRAMED_CHUNK = hexToBytes(\n \"0090\" +\n \"01012e\" +\n \"020101\" +\n \"81f003426f62\" +\n \"81f305416c696365\" +\n \"81f640\" +\n \"cc\".repeat(64) +\n DERIVATION_PATH_TLV +\n \"2920\" +\n \"dd\".repeat(32),\n);\n\nfunction makeApiMock(): InternalApi & {\n sendCommand: ReturnType<typeof vi.fn>;\n} {\n return { sendCommand: vi.fn() } as unknown as InternalApi & {\n sendCommand: ReturnType<typeof vi.fn>;\n };\n}\n\ndescribe(\"SendRenameContactTask\", () => {\n it(\"assembles the rename framed chunk and dispatches RenameContactCommand\", async () => {\n const api = makeApiMock();\n api.sendCommand.mockResolvedValueOnce(\n CommandResultFactory({ data: { hmacProof: HMAC_PROOF_OUT } }),\n );\n\n const result = await new SendRenameContactTask(api, {\n previousContactName: \"Alice\",\n newContactName: \"Bob\",\n groupHandle: GROUP_HANDLE,\n hmacProof: HMAC_PROOF_IN,\n }).run();\n\n expect(api.sendCommand.mock.calls).toHaveLength(1);\n expect(api.sendCommand.mock.calls[0]![0]).toStrictEqual(\n new RenameContactCommand({ data: FRAMED_CHUNK, p2: 0x00 }),\n );\n expect(result).toStrictEqual(\n CommandResultFactory({ data: { hmacProof: HMAC_PROOF_OUT } }),\n );\n });\n\n it(\"emits the DERIVATION_PATH tag immediately before HMAC_PROOF\", async () => {\n const api = makeApiMock();\n api.sendCommand.mockResolvedValueOnce(\n CommandResultFactory({ data: { hmacProof: HMAC_PROOF_OUT } }),\n );\n\n await new SendRenameContactTask(api, {\n previousContactName: \"Alice\",\n newContactName: \"Bob\",\n groupHandle: GROUP_HANDLE,\n hmacProof: HMAC_PROOF_IN,\n }).run();\n\n // The Ethereum app requires DERIVATION_PATH (0x69); it sits immediately\n // before HMAC_PROOF (0x29), matching Register Identity.\n const command = api.sendCommand.mock.calls[0]![0] as RenameContactCommand;\n const framedHex = Buffer.from(command.args.data).toString(\"hex\");\n expect(\n framedHex.endsWith(DERIVATION_PATH_TLV + \"2920\" + \"dd\".repeat(32)),\n ).toBe(true);\n });\n\n it(\"propagates command-level errors\", async () => {\n const api = makeApiMock();\n api.sendCommand.mockResolvedValueOnce(\n CommandResultFactory({\n error: new InvalidStatusWordError(\"user cancelled\"),\n }),\n );\n\n const result = await new SendRenameContactTask(api, {\n previousContactName: \"Alice\",\n newContactName: \"Bob\",\n groupHandle: GROUP_HANDLE,\n hmacProof: HMAC_PROOF_IN,\n }).run();\n\n expect(result).toStrictEqual(\n CommandResultFactory({\n error: new InvalidStatusWordError(\"user cancelled\"),\n }),\n );\n });\n\n it(\"returns InvalidStatusWordError when the final response carries no hmac_name\", async () => {\n const api = makeApiMock();\n api.sendCommand.mockResolvedValueOnce(CommandResultFactory({ data: {} }));\n\n const result = await new SendRenameContactTask(api, {\n previousContactName: \"Alice\",\n newContactName: \"Bob\",\n groupHandle: GROUP_HANDLE,\n hmacProof: HMAC_PROOF_IN,\n }).run();\n\n expect(result.status).not.toBe(undefined);\n if (\"error\" in result) {\n expect(result.error).toBeInstanceOf(InvalidStatusWordError);\n }\n });\n});\n"],
|
|
5
|
+
"mappings": "AAMA,OACE,wBAAAA,EAEA,0BAAAC,MACK,kCAEP,OAAS,wBAAAC,MAA4B,oDAErC,OAAS,yBAAAC,MAA6B,0BAEtC,SAASC,EAAWC,EAAyB,CAC3C,MAAMC,EAAM,IAAI,WAAWD,EAAI,OAAS,CAAC,EACzC,QAASE,EAAI,EAAGA,EAAIF,EAAI,OAAQE,GAAK,EACnCD,EAAIC,EAAI,CAAC,EAAI,SAASF,EAAI,MAAME,EAAGA,EAAI,CAAC,EAAG,EAAE,EAE/C,OAAOD,CACT,CAEA,MAAME,EAAeJ,EAAW,KAAK,OAAO,EAAE,CAAC,EACzCK,EAAgBL,EAAW,KAAK,OAAO,EAAE,CAAC,EAC1CM,EAAiBN,EAAW,KAAK,OAAO,EAAE,CAAC,EAU3CO,EAAsB,iDACtBC,EAAeR,EACnB,qDAME,KAAK,OAAO,EAAE,EACdO,EACA,OACA,KAAK,OAAO,EAAE,CAClB,EAEA,SAASE,GAEP,CACA,MAAO,CAAE,YAAa,GAAG,GAAG,CAAE,CAGhC,CAEA,SAAS,wBAAyB,IAAM,CACtC,GAAG,wEAAyE,SAAY,CACtF,MAAMC,EAAMD,EAAY,EACxBC,EAAI,YAAY,sBACdd,EAAqB,CAAE,KAAM,CAAE,UAAWU,CAAe,CAAE,CAAC,CAC9D,EAEA,MAAMK,EAAS,MAAM,IAAIZ,EAAsBW,EAAK,CAClD,oBAAqB,QACrB,eAAgB,MAChB,YAAaN,EACb,UAAWC,CACb,CAAC,EAAE,IAAI,EAEP,OAAOK,EAAI,YAAY,KAAK,KAAK,EAAE,aAAa,CAAC,EACjD,OAAOA,EAAI,YAAY,KAAK,MAAM,CAAC,EAAG,CAAC,CAAC,EAAE,cACxC,IAAIZ,EAAqB,CAAE,KAAMU,EAAc,GAAI,CAAK,CAAC,CAC3D,EACA,OAAOG,CAAM,EAAE,cACbf,EAAqB,CAAE,KAAM,CAAE,UAAWU,CAAe,CAAE,CAAC,CAC9D,CACF,CAAC,EAED,GAAG,8DAA+D,SAAY,CAC5E,MAAMI,EAAMD,EAAY,EACxBC,EAAI,YAAY,sBACdd,EAAqB,CAAE,KAAM,CAAE,UAAWU,CAAe,CAAE,CAAC,CAC9D,EAEA,MAAM,IAAIP,EAAsBW,EAAK,CACnC,oBAAqB,QACrB,eAAgB,MAChB,YAAaN,EACb,UAAWC,CACb,CAAC,EAAE,IAAI,EAIP,MAAMO,EAAUF,EAAI,YAAY,KAAK,MAAM,CAAC,EAAG,CAAC,EAC1CG,EAAY,OAAO,KAAKD,EAAQ,KAAK,IAAI,EAAE,SAAS,KAAK,EAC/D,OACEC,EAAU,SAASN,EAAsB,OAAS,KAAK,OAAO,EAAE,CAAC,CACnE,EAAE,KAAK,EAAI,CACb,CAAC,EAED,GAAG,kCAAmC,SAAY,CAChD,MAAMG,EAAMD,EAAY,EACxBC,EAAI,YAAY,sBACdd,EAAqB,CACnB,MAAO,IAAIC,EAAuB,gBAAgB,CACpD,CAAC,CACH,EAEA,MAAMc,EAAS,MAAM,IAAIZ,EAAsBW,EAAK,CAClD,oBAAqB,QACrB,eAAgB,MAChB,YAAaN,EACb,UAAWC,CACb,CAAC,EAAE,IAAI,EAEP,OAAOM,CAAM,EAAE,cACbf,EAAqB,CACnB,MAAO,IAAIC,EAAuB,gBAAgB,CACpD,CAAC,CACH,CACF,CAAC,EAED,GAAG,8EAA+E,SAAY,CAC5F,MAAMa,EAAMD,EAAY,EACxBC,EAAI,YAAY,sBAAsBd,EAAqB,CAAE,KAAM,CAAC,CAAE,CAAC,CAAC,EAExE,MAAMe,EAAS,MAAM,IAAIZ,EAAsBW,EAAK,CAClD,oBAAqB,QACrB,eAAgB,MAChB,YAAaN,EACb,UAAWC,CACb,CAAC,EAAE,IAAI,EAEP,OAAOM,EAAO,MAAM,EAAE,IAAI,KAAK,MAAS,EACpC,UAAWA,GACb,OAAOA,EAAO,KAAK,EAAE,eAAed,CAAsB,CAE9D,CAAC,CACH,CAAC",
|
|
6
|
+
"names": ["CommandResultFactory", "InvalidStatusWordError", "RenameContactCommand", "SendRenameContactTask", "hexToBytes", "hex", "out", "i", "GROUP_HANDLE", "HMAC_PROOF_IN", "HMAC_PROOF_OUT", "DERIVATION_PATH_TLV", "FRAMED_CHUNK", "makeApiMock", "api", "result", "command", "framedHex"]
|
|
7
|
+
}
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import{ContactsAppBinder as i}from"./app-binder/ContactsAppBinder";import{appBinderTypes as
|
|
1
|
+
import{ContactsAppBinder as i}from"./app-binder/ContactsAppBinder";import{appBinderTypes as r}from"./app-binder/di/appBinderTypes";import{makeContainer as p}from"./di";import{externalTypes as t}from"./externalTypes";import{useCaseTypes as o}from"./use-cases/di/useCaseTypes";import{RegisterExternalAddressUseCase as m}from"./use-cases/RegisterExternalAddressUseCase";import{RenameContactUseCase as c}from"./use-cases/RenameContactUseCase";describe("makeContainer",()=>{const s={},n="session-id",a="Ethereum",e=p({dmk:s,sessionId:n,appName:a});it("binds dmk, sessionId and appName as external values",()=>{expect(e.get(t.Dmk)).toBe(s),expect(e.get(t.SessionId)).toBe(n),expect(e.get(t.AppName)).toBe(a)}),it("binds the ContactsAppBinder",()=>{expect(e.get(r.AppBinder)).toBeInstanceOf(i)}),it("binds the RegisterExternalAddressUseCase",()=>{expect(e.get(o.RegisterExternalAddressUseCase)).toBeInstanceOf(m)}),it("binds the RenameContactUseCase",()=>{expect(e.get(o.RenameContactUseCase)).toBeInstanceOf(c)})});
|
|
2
2
|
//# sourceMappingURL=di.test.js.map
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"version": 3,
|
|
3
3
|
"sources": ["../../../src/internal/di.test.ts"],
|
|
4
|
-
"sourcesContent": ["import { type DeviceManagementKit } from \"@ledgerhq/device-management-kit\";\n\nimport { ContactsAppBinder } from \"@internal/app-binder/ContactsAppBinder\";\nimport { appBinderTypes } from \"@internal/app-binder/di/appBinderTypes\";\nimport { makeContainer } from \"@internal/di\";\nimport { externalTypes } from \"@internal/externalTypes\";\nimport { useCaseTypes } from \"@internal/use-cases/di/useCaseTypes\";\nimport { RegisterExternalAddressUseCase } from \"@internal/use-cases/RegisterExternalAddressUseCase\";\n\ndescribe(\"makeContainer\", () => {\n const dmk = {} as DeviceManagementKit;\n const sessionId = \"session-id\";\n const appName = \"Ethereum\";\n\n const container = makeContainer({ dmk, sessionId, appName });\n\n it(\"binds dmk, sessionId and appName as external values\", () => {\n expect(container.get(externalTypes.Dmk)).toBe(dmk);\n expect(container.get(externalTypes.SessionId)).toBe(sessionId);\n expect(container.get(externalTypes.AppName)).toBe(appName);\n });\n\n it(\"binds the ContactsAppBinder\", () => {\n expect(container.get(appBinderTypes.AppBinder)).toBeInstanceOf(\n ContactsAppBinder,\n );\n });\n\n it(\"binds the RegisterExternalAddressUseCase\", () => {\n expect(\n container.get(useCaseTypes.RegisterExternalAddressUseCase),\n ).toBeInstanceOf(RegisterExternalAddressUseCase);\n });\n});\n"],
|
|
5
|
-
"mappings": "AAEA,OAAS,qBAAAA,MAAyB,yCAClC,OAAS,kBAAAC,MAAsB,yCAC/B,OAAS,iBAAAC,MAAqB,eAC9B,OAAS,iBAAAC,MAAqB,0BAC9B,OAAS,gBAAAC,MAAoB,sCAC7B,OAAS,kCAAAC,MAAsC,
|
|
6
|
-
"names": ["ContactsAppBinder", "appBinderTypes", "makeContainer", "externalTypes", "useCaseTypes", "RegisterExternalAddressUseCase", "dmk", "sessionId", "appName", "container"]
|
|
4
|
+
"sourcesContent": ["import { type DeviceManagementKit } from \"@ledgerhq/device-management-kit\";\n\nimport { ContactsAppBinder } from \"@internal/app-binder/ContactsAppBinder\";\nimport { appBinderTypes } from \"@internal/app-binder/di/appBinderTypes\";\nimport { makeContainer } from \"@internal/di\";\nimport { externalTypes } from \"@internal/externalTypes\";\nimport { useCaseTypes } from \"@internal/use-cases/di/useCaseTypes\";\nimport { RegisterExternalAddressUseCase } from \"@internal/use-cases/RegisterExternalAddressUseCase\";\nimport { RenameContactUseCase } from \"@internal/use-cases/RenameContactUseCase\";\n\ndescribe(\"makeContainer\", () => {\n const dmk = {} as DeviceManagementKit;\n const sessionId = \"session-id\";\n const appName = \"Ethereum\";\n\n const container = makeContainer({ dmk, sessionId, appName });\n\n it(\"binds dmk, sessionId and appName as external values\", () => {\n expect(container.get(externalTypes.Dmk)).toBe(dmk);\n expect(container.get(externalTypes.SessionId)).toBe(sessionId);\n expect(container.get(externalTypes.AppName)).toBe(appName);\n });\n\n it(\"binds the ContactsAppBinder\", () => {\n expect(container.get(appBinderTypes.AppBinder)).toBeInstanceOf(\n ContactsAppBinder,\n );\n });\n\n it(\"binds the RegisterExternalAddressUseCase\", () => {\n expect(\n container.get(useCaseTypes.RegisterExternalAddressUseCase),\n ).toBeInstanceOf(RegisterExternalAddressUseCase);\n });\n\n it(\"binds the RenameContactUseCase\", () => {\n expect(container.get(useCaseTypes.RenameContactUseCase)).toBeInstanceOf(\n RenameContactUseCase,\n );\n });\n});\n"],
|
|
5
|
+
"mappings": "AAEA,OAAS,qBAAAA,MAAyB,yCAClC,OAAS,kBAAAC,MAAsB,yCAC/B,OAAS,iBAAAC,MAAqB,eAC9B,OAAS,iBAAAC,MAAqB,0BAC9B,OAAS,gBAAAC,MAAoB,sCAC7B,OAAS,kCAAAC,MAAsC,qDAC/C,OAAS,wBAAAC,MAA4B,2CAErC,SAAS,gBAAiB,IAAM,CAC9B,MAAMC,EAAM,CAAC,EACPC,EAAY,aACZC,EAAU,WAEVC,EAAYR,EAAc,CAAE,IAAAK,EAAK,UAAAC,EAAW,QAAAC,CAAQ,CAAC,EAE3D,GAAG,sDAAuD,IAAM,CAC9D,OAAOC,EAAU,IAAIP,EAAc,GAAG,CAAC,EAAE,KAAKI,CAAG,EACjD,OAAOG,EAAU,IAAIP,EAAc,SAAS,CAAC,EAAE,KAAKK,CAAS,EAC7D,OAAOE,EAAU,IAAIP,EAAc,OAAO,CAAC,EAAE,KAAKM,CAAO,CAC3D,CAAC,EAED,GAAG,8BAA+B,IAAM,CACtC,OAAOC,EAAU,IAAIT,EAAe,SAAS,CAAC,EAAE,eAC9CD,CACF,CACF,CAAC,EAED,GAAG,2CAA4C,IAAM,CACnD,OACEU,EAAU,IAAIN,EAAa,8BAA8B,CAC3D,EAAE,eAAeC,CAA8B,CACjD,CAAC,EAED,GAAG,iCAAkC,IAAM,CACzC,OAAOK,EAAU,IAAIN,EAAa,oBAAoB,CAAC,EAAE,eACvDE,CACF,CACF,CAAC,CACH,CAAC",
|
|
6
|
+
"names": ["ContactsAppBinder", "appBinderTypes", "makeContainer", "externalTypes", "useCaseTypes", "RegisterExternalAddressUseCase", "RenameContactUseCase", "dmk", "sessionId", "appName", "container"]
|
|
7
7
|
}
|
|
@@ -0,0 +1,2 @@
|
|
|
1
|
+
var d=Object.defineProperty;var u=Object.getOwnPropertyDescriptor;var a=(e,t,n,r)=>{for(var p=r>1?void 0:r?u(t,n):t,i=e.length-1,m;i>=0;i--)(m=e[i])&&(p=(r?m(t,n,p):m(p))||p);return r&&p&&d(t,n,p),p},c=(e,t)=>(n,r)=>t(n,r,e);import{inject as y,injectable as B}from"inversify";import{appBinderTypes as f}from"../app-binder/di/appBinderTypes";let o=class{constructor(t){this.appBinder=t}execute(t){return this.appBinder.renameContact(t)}};o=a([B(),c(0,y(f.AppBinder))],o);export{o as RenameContactUseCase};
|
|
2
|
+
//# sourceMappingURL=RenameContactUseCase.js.map
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
{
|
|
2
|
+
"version": 3,
|
|
3
|
+
"sources": ["../../../../src/internal/use-cases/RenameContactUseCase.ts"],
|
|
4
|
+
"sourcesContent": ["import { inject, injectable } from \"inversify\";\n\nimport { type RenameContactDAReturnType } from \"@api/app-binder/RenameContactDeviceActionTypes\";\nimport { type RenameContactInput } from \"@api/model/RenameContact\";\nimport { ContactsAppBinder } from \"@internal/app-binder/ContactsAppBinder\";\nimport { appBinderTypes } from \"@internal/app-binder/di/appBinderTypes\";\n\n/**\n * Delegates to `ContactsAppBinder`, which uses its injected `dmk` and\n * `sessionId` to construct and execute the `RenameContactDeviceAction`. The\n * injected `appName` is not used: rename is a dashboard operation served by the\n * device OS, not the embedded app.\n *\n * Caller-input validation is intentionally NOT done here: the public API returns\n * a device action, so validation lives inside the device action and surfaces as\n * a typed terminal error state on the observable rather than a synchronous throw.\n */\n@injectable()\nexport class RenameContactUseCase {\n constructor(\n @inject(appBinderTypes.AppBinder)\n private readonly appBinder: ContactsAppBinder,\n ) {}\n\n execute(input: RenameContactInput): RenameContactDAReturnType {\n return this.appBinder.renameContact(input);\n }\n}\n"],
|
|
5
|
+
"mappings": "iOAAA,OAAS,UAAAA,EAAQ,cAAAC,MAAkB,YAKnC,OAAS,kBAAAC,MAAsB,yCAaxB,IAAMC,EAAN,KAA2B,CAChC,YAEmBC,EACjB,CADiB,eAAAA,CAChB,CAEH,QAAQC,EAAsD,CAC5D,OAAO,KAAK,UAAU,cAAcA,CAAK,CAC3C,CACF,EATaF,EAANG,EAAA,CADNC,EAAW,EAGPC,EAAA,EAAAC,EAAOC,EAAe,SAAS,IAFvBP",
|
|
6
|
+
"names": ["inject", "injectable", "appBinderTypes", "RenameContactUseCase", "appBinder", "input", "__decorateClass", "injectable", "__decorateParam", "inject", "appBinderTypes"]
|
|
7
|
+
}
|
|
@@ -0,0 +1,2 @@
|
|
|
1
|
+
import{RenameContactUseCase as c}from"./RenameContactUseCase";function o(){const e=vi.fn().mockReturnValue("DA_RETURN"),t={renameContact:e};return{useCase:new c(t),renameContact:e}}const a={previousContactName:"Alice",newContactName:"Bob",groupHandle:new Uint8Array(64).fill(204),hmacProof:new Uint8Array(32).fill(221)};describe("RenameContactUseCase",()=>{it("delegates to the app binder",()=>{const{useCase:e,renameContact:t}=o(),n=e.execute(a);expect(t).toHaveBeenCalledWith(a),expect(n).toBe("DA_RETURN")}),it("does not validate \u2014 invalid input is forwarded, not thrown",()=>{const{useCase:e,renameContact:t}=o(),n={...a,newContactName:""};expect(()=>e.execute(n)).not.toThrow(),expect(t).toHaveBeenCalledWith(n)})});
|
|
2
|
+
//# sourceMappingURL=RenameContactUseCase.test.js.map
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
{
|
|
2
|
+
"version": 3,
|
|
3
|
+
"sources": ["../../../../src/internal/use-cases/RenameContactUseCase.test.ts"],
|
|
4
|
+
"sourcesContent": ["import { type RenameContactInput } from \"@api/model/RenameContact\";\nimport { type ContactsAppBinder } from \"@internal/app-binder/ContactsAppBinder\";\n\nimport { RenameContactUseCase } from \"./RenameContactUseCase\";\n\nfunction makeUseCase() {\n const renameContact = vi.fn().mockReturnValue(\"DA_RETURN\");\n const appBinder = { renameContact } as unknown as ContactsAppBinder;\n return {\n useCase: new RenameContactUseCase(appBinder),\n renameContact,\n };\n}\n\nconst VALID_INPUT: RenameContactInput = {\n previousContactName: \"Alice\",\n newContactName: \"Bob\",\n groupHandle: new Uint8Array(64).fill(0xcc),\n hmacProof: new Uint8Array(32).fill(0xdd),\n};\n\ndescribe(\"RenameContactUseCase\", () => {\n it(\"delegates to the app binder\", () => {\n const { useCase, renameContact } = makeUseCase();\n\n const result = useCase.execute(VALID_INPUT);\n\n expect(renameContact).toHaveBeenCalledWith(VALID_INPUT);\n expect(result).toBe(\"DA_RETURN\");\n });\n\n it(\"does not validate \u2014 invalid input is forwarded, not thrown\", () => {\n // Validation lives in the device action and surfaces as a typed DA error\n // state; the use case must never throw for bad input.\n const { useCase, renameContact } = makeUseCase();\n\n const invalidInput = { ...VALID_INPUT, newContactName: \"\" };\n expect(() => useCase.execute(invalidInput)).not.toThrow();\n expect(renameContact).toHaveBeenCalledWith(invalidInput);\n });\n});\n"],
|
|
5
|
+
"mappings": "AAGA,OAAS,wBAAAA,MAA4B,yBAErC,SAASC,GAAc,CACrB,MAAMC,EAAgB,GAAG,GAAG,EAAE,gBAAgB,WAAW,EACnDC,EAAY,CAAE,cAAAD,CAAc,EAClC,MAAO,CACL,QAAS,IAAIF,EAAqBG,CAAS,EAC3C,cAAAD,CACF,CACF,CAEA,MAAME,EAAkC,CACtC,oBAAqB,QACrB,eAAgB,MAChB,YAAa,IAAI,WAAW,EAAE,EAAE,KAAK,GAAI,EACzC,UAAW,IAAI,WAAW,EAAE,EAAE,KAAK,GAAI,CACzC,EAEA,SAAS,uBAAwB,IAAM,CACrC,GAAG,8BAA+B,IAAM,CACtC,KAAM,CAAE,QAAAC,EAAS,cAAAH,CAAc,EAAID,EAAY,EAEzCK,EAASD,EAAQ,QAAQD,CAAW,EAE1C,OAAOF,CAAa,EAAE,qBAAqBE,CAAW,EACtD,OAAOE,CAAM,EAAE,KAAK,WAAW,CACjC,CAAC,EAED,GAAG,kEAA8D,IAAM,CAGrE,KAAM,CAAE,QAAAD,EAAS,cAAAH,CAAc,EAAID,EAAY,EAEzCM,EAAe,CAAE,GAAGH,EAAa,eAAgB,EAAG,EAC1D,OAAO,IAAMC,EAAQ,QAAQE,CAAY,CAAC,EAAE,IAAI,QAAQ,EACxD,OAAOL,CAAa,EAAE,qBAAqBK,CAAY,CACzD,CAAC,CACH,CAAC",
|
|
6
|
+
"names": ["RenameContactUseCase", "makeUseCase", "renameContact", "appBinder", "VALID_INPUT", "useCase", "result", "invalidInput"]
|
|
7
|
+
}
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import{ContainerModule as
|
|
1
|
+
import{ContainerModule as o}from"inversify";import{RegisterExternalAddressUseCase as t}from"../../use-cases/RegisterExternalAddressUseCase";import{RenameContactUseCase as r}from"../../use-cases/RenameContactUseCase";import{useCaseTypes as s}from"./useCaseTypes";const i=()=>new o(({bind:e})=>{e(s.RegisterExternalAddressUseCase).to(t),e(s.RenameContactUseCase).to(r)});export{i as useCaseModuleFactory};
|
|
2
2
|
//# sourceMappingURL=useCaseModule.js.map
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"version": 3,
|
|
3
3
|
"sources": ["../../../../../src/internal/use-cases/di/useCaseModule.ts"],
|
|
4
|
-
"sourcesContent": ["import { ContainerModule } from \"inversify\";\n\nimport { RegisterExternalAddressUseCase } from \"@internal/use-cases/RegisterExternalAddressUseCase\";\n\nimport { useCaseTypes } from \"./useCaseTypes\";\n\nexport const useCaseModuleFactory = () =>\n new ContainerModule(({ bind }) => {\n bind(useCaseTypes.RegisterExternalAddressUseCase).to(\n RegisterExternalAddressUseCase,\n );\n });\n"],
|
|
5
|
-
"mappings": "AAAA,OAAS,mBAAAA,MAAuB,YAEhC,OAAS,kCAAAC,MAAsC,
|
|
6
|
-
"names": ["ContainerModule", "RegisterExternalAddressUseCase", "useCaseTypes", "useCaseModuleFactory", "bind"]
|
|
4
|
+
"sourcesContent": ["import { ContainerModule } from \"inversify\";\n\nimport { RegisterExternalAddressUseCase } from \"@internal/use-cases/RegisterExternalAddressUseCase\";\nimport { RenameContactUseCase } from \"@internal/use-cases/RenameContactUseCase\";\n\nimport { useCaseTypes } from \"./useCaseTypes\";\n\nexport const useCaseModuleFactory = () =>\n new ContainerModule(({ bind }) => {\n bind(useCaseTypes.RegisterExternalAddressUseCase).to(\n RegisterExternalAddressUseCase,\n );\n bind(useCaseTypes.RenameContactUseCase).to(RenameContactUseCase);\n });\n"],
|
|
5
|
+
"mappings": "AAAA,OAAS,mBAAAA,MAAuB,YAEhC,OAAS,kCAAAC,MAAsC,qDAC/C,OAAS,wBAAAC,MAA4B,2CAErC,OAAS,gBAAAC,MAAoB,iBAEtB,MAAMC,EAAuB,IAClC,IAAIJ,EAAgB,CAAC,CAAE,KAAAK,CAAK,IAAM,CAChCA,EAAKF,EAAa,8BAA8B,EAAE,GAChDF,CACF,EACAI,EAAKF,EAAa,oBAAoB,EAAE,GAAGD,CAAoB,CACjE,CAAC",
|
|
6
|
+
"names": ["ContainerModule", "RegisterExternalAddressUseCase", "RenameContactUseCase", "useCaseTypes", "useCaseModuleFactory", "bind"]
|
|
7
7
|
}
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
const e={RegisterExternalAddressUseCase:Symbol.for("RegisterExternalAddressUseCase")};export{e as useCaseTypes};
|
|
1
|
+
const e={RegisterExternalAddressUseCase:Symbol.for("RegisterExternalAddressUseCase"),RenameContactUseCase:Symbol.for("RenameContactUseCase")};export{e as useCaseTypes};
|
|
2
2
|
//# sourceMappingURL=useCaseTypes.js.map
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"version": 3,
|
|
3
3
|
"sources": ["../../../../../src/internal/use-cases/di/useCaseTypes.ts"],
|
|
4
|
-
"sourcesContent": ["export const useCaseTypes = {\n RegisterExternalAddressUseCase: Symbol.for(\"RegisterExternalAddressUseCase\"),\n} as const;\n"],
|
|
5
|
-
"mappings": "AAAO,MAAMA,EAAe,CAC1B,+BAAgC,OAAO,IAAI,gCAAgC,
|
|
4
|
+
"sourcesContent": ["export const useCaseTypes = {\n RegisterExternalAddressUseCase: Symbol.for(\"RegisterExternalAddressUseCase\"),\n RenameContactUseCase: Symbol.for(\"RenameContactUseCase\"),\n} as const;\n"],
|
|
5
|
+
"mappings": "AAAO,MAAMA,EAAe,CAC1B,+BAAgC,OAAO,IAAI,gCAAgC,EAC3E,qBAAsB,OAAO,IAAI,sBAAsB,CACzD",
|
|
6
6
|
"names": ["useCaseTypes"]
|
|
7
7
|
}
|
package/lib/esm/package.json
CHANGED
|
@@ -58,5 +58,5 @@
|
|
|
58
58
|
"watch:builds": "pnpm ldmk-tool watch --entryPoints src/index.ts,src/**/*.ts --tsconfig tsconfig.prod.json",
|
|
59
59
|
"watch:types": "concurrently \"tsc --watch -p tsconfig.prod.json\" \"tsc-alias --watch -p tsconfig.prod.json\""
|
|
60
60
|
},
|
|
61
|
-
"version": "0.0.0-develop-
|
|
61
|
+
"version": "0.0.0-develop-20260829001241"
|
|
62
62
|
}
|
|
@@ -1,5 +1,7 @@
|
|
|
1
1
|
import { type RegisterExternalAddressDAReturnType } from "./app-binder/RegisterExternalAddressDeviceActionTypes";
|
|
2
|
+
import { type RenameContactDAReturnType } from "./app-binder/RenameContactDeviceActionTypes";
|
|
2
3
|
import { type RegisterExternalAddressInput } from "./model/RegisterExternalAddress";
|
|
4
|
+
import { type RenameContactInput } from "./model/RenameContact";
|
|
3
5
|
/**
|
|
4
6
|
* Public, stateless Contacts (Address Book) manager.
|
|
5
7
|
*
|
|
@@ -18,5 +20,15 @@ export interface ContactsManager {
|
|
|
18
20
|
* IDENTITY. Returns the device-issued group handle and proofs to persist.
|
|
19
21
|
*/
|
|
20
22
|
registerExternalAddress(input: RegisterExternalAddressInput): RegisterExternalAddressDAReturnType;
|
|
23
|
+
/**
|
|
24
|
+
* Rename an existing contact group (EDIT CONTACT NAME). This is a
|
|
25
|
+
* blockchain-agnostic dashboard operation served by the device OS: it always
|
|
26
|
+
* navigates to the dashboard first (never opens an app), checks the Contacts
|
|
27
|
+
* minimum OS version, then rotates the group's name proof. Pass the current
|
|
28
|
+
* `previousContactName`, the `newContactName`, the group's `groupHandle`, and
|
|
29
|
+
* the existing `hmacProof`; returns the replacement group-level `hmacProof` to
|
|
30
|
+
* persist.
|
|
31
|
+
*/
|
|
32
|
+
renameContact(input: RenameContactInput): RenameContactDAReturnType;
|
|
21
33
|
}
|
|
22
34
|
//# sourceMappingURL=ContactsManager.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ContactsManager.d.ts","sourceRoot":"","sources":["../../../src/api/ContactsManager.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,mCAAmC,EAAE,MAAM,0DAA0D,CAAC;AACpH,OAAO,EAAE,KAAK,4BAA4B,EAAE,MAAM,oCAAoC,CAAC;
|
|
1
|
+
{"version":3,"file":"ContactsManager.d.ts","sourceRoot":"","sources":["../../../src/api/ContactsManager.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,mCAAmC,EAAE,MAAM,0DAA0D,CAAC;AACpH,OAAO,EAAE,KAAK,yBAAyB,EAAE,MAAM,gDAAgD,CAAC;AAChG,OAAO,EAAE,KAAK,4BAA4B,EAAE,MAAM,oCAAoC,CAAC;AACvF,OAAO,EAAE,KAAK,kBAAkB,EAAE,MAAM,0BAA0B,CAAC;AAEnE;;;;;;;GAOG;AACH,MAAM,WAAW,eAAe;IAC9B;;;;;;;OAOG;IACH,uBAAuB,CACrB,KAAK,EAAE,4BAA4B,GAClC,mCAAmC,CAAC;IAEvC;;;;;;;;OAQG;IACH,aAAa,CAAC,KAAK,EAAE,kBAAkB,GAAG,yBAAyB,CAAC;CACrE"}
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
import { type CommandErrorResult, type DeviceActionState, type ExecuteDeviceActionReturnType, type GoToDashboardDAError, type GoToDashboardDARequiredInteraction, type UserInteractionRequired } from "@ledgerhq/device-management-kit";
|
|
2
|
+
import { type RenameContactInput, type RenameContactOutput } from "../model/RenameContact";
|
|
3
|
+
import { type ContactsErrorCodes, type ContactsVersionRequirementError } from "../../internal/app-binder/model/contactsErrors";
|
|
4
|
+
import { type ContactsValidationError } from "../../internal/app-binder/model/contactsValidation";
|
|
5
|
+
/**
|
|
6
|
+
* Rename is a dashboard operation, so the machine input is exactly the public
|
|
7
|
+
* input — no embedded-app name is injected (the OS serves the command; there is
|
|
8
|
+
* no app to open).
|
|
9
|
+
*/
|
|
10
|
+
export type RenameContactDAInput = RenameContactInput;
|
|
11
|
+
export type RenameContactDAOutput = RenameContactOutput;
|
|
12
|
+
export type RenameContactDAError = GoToDashboardDAError | ContactsValidationError | ContactsVersionRequirementError | CommandErrorResult<ContactsErrorCodes>["error"];
|
|
13
|
+
export type RenameContactDARequiredInteraction = GoToDashboardDARequiredInteraction | UserInteractionRequired.RegisterWallet;
|
|
14
|
+
export type RenameContactDAIntermediateValue = {
|
|
15
|
+
readonly requiredUserInteraction: RenameContactDARequiredInteraction;
|
|
16
|
+
};
|
|
17
|
+
export type RenameContactDAState = DeviceActionState<RenameContactDAOutput, RenameContactDAError, RenameContactDAIntermediateValue>;
|
|
18
|
+
export type RenameContactDAInternalState = {
|
|
19
|
+
readonly error: RenameContactDAError | null;
|
|
20
|
+
readonly proof: {
|
|
21
|
+
readonly hmacProof: Uint8Array;
|
|
22
|
+
} | null;
|
|
23
|
+
};
|
|
24
|
+
export type RenameContactDAReturnType = ExecuteDeviceActionReturnType<RenameContactDAOutput, RenameContactDAError, RenameContactDAIntermediateValue>;
|
|
25
|
+
//# sourceMappingURL=RenameContactDeviceActionTypes.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"RenameContactDeviceActionTypes.d.ts","sourceRoot":"","sources":["../../../../src/api/app-binder/RenameContactDeviceActionTypes.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,KAAK,kBAAkB,EACvB,KAAK,iBAAiB,EACtB,KAAK,6BAA6B,EAClC,KAAK,oBAAoB,EACzB,KAAK,kCAAkC,EACvC,KAAK,uBAAuB,EAC7B,MAAM,iCAAiC,CAAC;AAEzC,OAAO,EACL,KAAK,kBAAkB,EACvB,KAAK,mBAAmB,EACzB,MAAM,0BAA0B,CAAC;AAClC,OAAO,EACL,KAAK,kBAAkB,EACvB,KAAK,+BAA+B,EACrC,MAAM,2CAA2C,CAAC;AACnD,OAAO,EAAE,KAAK,uBAAuB,EAAE,MAAM,+CAA+C,CAAC;AAE7F;;;;GAIG;AACH,MAAM,MAAM,oBAAoB,GAAG,kBAAkB,CAAC;AAEtD,MAAM,MAAM,qBAAqB,GAAG,mBAAmB,CAAC;AAExD,MAAM,MAAM,oBAAoB,GAC5B,oBAAoB,GACpB,uBAAuB,GACvB,+BAA+B,GAC/B,kBAAkB,CAAC,kBAAkB,CAAC,CAAC,OAAO,CAAC,CAAC;AAEpD,MAAM,MAAM,kCAAkC,GAC1C,kCAAkC,GAClC,uBAAuB,CAAC,cAAc,CAAC;AAE3C,MAAM,MAAM,gCAAgC,GAAG;IAC7C,QAAQ,CAAC,uBAAuB,EAAE,kCAAkC,CAAC;CACtE,CAAC;AAEF,MAAM,MAAM,oBAAoB,GAAG,iBAAiB,CAClD,qBAAqB,EACrB,oBAAoB,EACpB,gCAAgC,CACjC,CAAC;AAEF,MAAM,MAAM,4BAA4B,GAAG;IACzC,QAAQ,CAAC,KAAK,EAAE,oBAAoB,GAAG,IAAI,CAAC;IAC5C,QAAQ,CAAC,KAAK,EAAE;QACd,QAAQ,CAAC,SAAS,EAAE,UAAU,CAAC;KAChC,GAAG,IAAI,CAAC;CACV,CAAC;AAEF,MAAM,MAAM,yBAAyB,GAAG,6BAA6B,CACnE,qBAAqB,EACrB,oBAAoB,EACpB,gCAAgC,CACjC,CAAC"}
|
package/lib/types/api/index.d.ts
CHANGED
|
@@ -1,6 +1,8 @@
|
|
|
1
1
|
export { type RegisterExternalAddressDAError, type RegisterExternalAddressDAInput, type RegisterExternalAddressDAIntermediateValue, type RegisterExternalAddressDAOutput, type RegisterExternalAddressDARequiredInteraction, type RegisterExternalAddressDAReturnType, type RegisterExternalAddressDAState, } from "./app-binder/RegisterExternalAddressDeviceActionTypes";
|
|
2
|
+
export { type RenameContactDAError, type RenameContactDAInput, type RenameContactDAIntermediateValue, type RenameContactDAOutput, type RenameContactDARequiredInteraction, type RenameContactDAReturnType, type RenameContactDAState, } from "./app-binder/RenameContactDeviceActionTypes";
|
|
2
3
|
export { type ContactsManager } from "./ContactsManager";
|
|
3
4
|
export { ContactsManagerBuilder } from "./ContactsManagerBuilder";
|
|
4
5
|
export { CONTACTS_VERSION_REQUIREMENTS, type ContactsModelRequirement, type ContactsModelSupport, type ContactsModelUnsupported, type ContactsSupportQuery, type ContactsVersionRequirements, ETHEREUM_APP_NAME, isContactsSupported, isVersionAtLeast, resolveContactsVersionRequirements, } from "./model/ContactsVersionRequirements";
|
|
5
6
|
export { type ExistingContactGroup, type RegisterExternalAddressInput, type RegisterExternalAddressMode, type RegisterExternalAddressOutput, } from "./model/RegisterExternalAddress";
|
|
7
|
+
export { type RenameContactInput, type RenameContactOutput, } from "./model/RenameContact";
|
|
6
8
|
//# sourceMappingURL=index.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/api/index.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,KAAK,8BAA8B,EACnC,KAAK,8BAA8B,EACnC,KAAK,0CAA0C,EAC/C,KAAK,+BAA+B,EACpC,KAAK,4CAA4C,EACjD,KAAK,mCAAmC,EACxC,KAAK,8BAA8B,GACpC,MAAM,0DAA0D,CAAC;AAClE,OAAO,EAAE,KAAK,eAAe,EAAE,MAAM,sBAAsB,CAAC;AAC5D,OAAO,EAAE,sBAAsB,EAAE,MAAM,6BAA6B,CAAC;AACrE,OAAO,EACL,6BAA6B,EAC7B,KAAK,wBAAwB,EAC7B,KAAK,oBAAoB,EACzB,KAAK,wBAAwB,EAC7B,KAAK,oBAAoB,EACzB,KAAK,2BAA2B,EAChC,iBAAiB,EACjB,mBAAmB,EACnB,gBAAgB,EAChB,kCAAkC,GACnC,MAAM,wCAAwC,CAAC;AAChD,OAAO,EACL,KAAK,oBAAoB,EACzB,KAAK,4BAA4B,EACjC,KAAK,2BAA2B,EAChC,KAAK,6BAA6B,GACnC,MAAM,oCAAoC,CAAC"}
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/api/index.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,KAAK,8BAA8B,EACnC,KAAK,8BAA8B,EACnC,KAAK,0CAA0C,EAC/C,KAAK,+BAA+B,EACpC,KAAK,4CAA4C,EACjD,KAAK,mCAAmC,EACxC,KAAK,8BAA8B,GACpC,MAAM,0DAA0D,CAAC;AAClE,OAAO,EACL,KAAK,oBAAoB,EACzB,KAAK,oBAAoB,EACzB,KAAK,gCAAgC,EACrC,KAAK,qBAAqB,EAC1B,KAAK,kCAAkC,EACvC,KAAK,yBAAyB,EAC9B,KAAK,oBAAoB,GAC1B,MAAM,gDAAgD,CAAC;AACxD,OAAO,EAAE,KAAK,eAAe,EAAE,MAAM,sBAAsB,CAAC;AAC5D,OAAO,EAAE,sBAAsB,EAAE,MAAM,6BAA6B,CAAC;AACrE,OAAO,EACL,6BAA6B,EAC7B,KAAK,wBAAwB,EAC7B,KAAK,oBAAoB,EACzB,KAAK,wBAAwB,EAC7B,KAAK,oBAAoB,EACzB,KAAK,2BAA2B,EAChC,iBAAiB,EACjB,mBAAmB,EACnB,gBAAgB,EAChB,kCAAkC,GACnC,MAAM,wCAAwC,CAAC;AAChD,OAAO,EACL,KAAK,oBAAoB,EACzB,KAAK,4BAA4B,EACjC,KAAK,2BAA2B,EAChC,KAAK,6BAA6B,GACnC,MAAM,oCAAoC,CAAC;AAC5C,OAAO,EACL,KAAK,kBAAkB,EACvB,KAAK,mBAAmB,GACzB,MAAM,0BAA0B,CAAC"}
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Public input/output types for `ContactsManager.renameContact`.
|
|
3
|
+
*
|
|
4
|
+
* Rename (EDIT CONTACT NAME) is a blockchain-agnostic OS/dashboard operation:
|
|
5
|
+
* it rotates the contact-level `hmacProof` (the device's `hmac_name`) and
|
|
6
|
+
* returns the fresh proof. The per-entry `hmacRest` values are untouched — they
|
|
7
|
+
* bind scope/identifier/family/chainId, never the name — so only the group's
|
|
8
|
+
* name proof needs re-persisting.
|
|
9
|
+
*
|
|
10
|
+
* Proof material (`groupHandle`, `hmacProof`) is passed and returned as raw
|
|
11
|
+
* bytes; the host owns persistence and address-book state. `derivationPath` is
|
|
12
|
+
* kit-internal and not exposed: the Ethereum app requires a path on the wire
|
|
13
|
+
* (a default m/44'/60'/0'/0/0 is sent), but the rename itself is name-only.
|
|
14
|
+
*/
|
|
15
|
+
export type RenameContactInput = {
|
|
16
|
+
/** The contact's current name, proven to the device via `hmacProof`. */
|
|
17
|
+
readonly previousContactName: string;
|
|
18
|
+
/** The new name to assign to the contact group. */
|
|
19
|
+
readonly newContactName: string;
|
|
20
|
+
/** 64-byte group handle returned by the group's Register Identity. */
|
|
21
|
+
readonly groupHandle: Uint8Array;
|
|
22
|
+
/**
|
|
23
|
+
* The existing 32-byte name proof (device `hmac_name`) bound to the current
|
|
24
|
+
* name — passed back so the device can verify continuity before approving the
|
|
25
|
+
* rename. Replaced by the returned `hmacProof` on success.
|
|
26
|
+
*/
|
|
27
|
+
readonly hmacProof: Uint8Array;
|
|
28
|
+
};
|
|
29
|
+
export type RenameContactOutput = {
|
|
30
|
+
/** Echoed previous name, for the host to locate the entry it is replacing. */
|
|
31
|
+
readonly previousContactName: string;
|
|
32
|
+
/** The new name now bound to the contact group. */
|
|
33
|
+
readonly contactName: string;
|
|
34
|
+
/** Echoed group handle, unchanged by the rename. */
|
|
35
|
+
readonly groupHandle: Uint8Array;
|
|
36
|
+
/** The replacement group-level name proof (rotated `hmac_name`) to persist. */
|
|
37
|
+
readonly hmacProof: Uint8Array;
|
|
38
|
+
};
|
|
39
|
+
//# sourceMappingURL=RenameContact.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"RenameContact.d.ts","sourceRoot":"","sources":["../../../../src/api/model/RenameContact.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;GAaG;AAEH,MAAM,MAAM,kBAAkB,GAAG;IAC/B,wEAAwE;IACxE,QAAQ,CAAC,mBAAmB,EAAE,MAAM,CAAC;IACrC,mDAAmD;IACnD,QAAQ,CAAC,cAAc,EAAE,MAAM,CAAC;IAChC,sEAAsE;IACtE,QAAQ,CAAC,WAAW,EAAE,UAAU,CAAC;IACjC;;;;OAIG;IACH,QAAQ,CAAC,SAAS,EAAE,UAAU,CAAC;CAChC,CAAC;AAEF,MAAM,MAAM,mBAAmB,GAAG;IAChC,8EAA8E;IAC9E,QAAQ,CAAC,mBAAmB,EAAE,MAAM,CAAC;IACrC,mDAAmD;IACnD,QAAQ,CAAC,WAAW,EAAE,MAAM,CAAC;IAC7B,oDAAoD;IACpD,QAAQ,CAAC,WAAW,EAAE,UAAU,CAAC;IACjC,+EAA+E;IAC/E,QAAQ,CAAC,SAAS,EAAE,UAAU,CAAC;CAChC,CAAC"}
|
|
@@ -1,8 +1,10 @@
|
|
|
1
1
|
import { type DeviceManagementKit, type DeviceSessionId } from "@ledgerhq/device-management-kit";
|
|
2
2
|
import { type Container } from "inversify";
|
|
3
3
|
import { type RegisterExternalAddressDAReturnType } from "../api/app-binder/RegisterExternalAddressDeviceActionTypes";
|
|
4
|
+
import { type RenameContactDAReturnType } from "../api/app-binder/RenameContactDeviceActionTypes";
|
|
4
5
|
import { type ContactsManager } from "../api/ContactsManager";
|
|
5
6
|
import { type RegisterExternalAddressInput } from "../api/model/RegisterExternalAddress";
|
|
7
|
+
import { type RenameContactInput } from "../api/model/RenameContact";
|
|
6
8
|
type DefaultContactsManagerConstructorArgs = {
|
|
7
9
|
dmk: DeviceManagementKit;
|
|
8
10
|
sessionId: DeviceSessionId;
|
|
@@ -12,6 +14,7 @@ export declare class DefaultContactsManager implements ContactsManager {
|
|
|
12
14
|
private readonly _container;
|
|
13
15
|
constructor({ dmk, sessionId, appName, }: DefaultContactsManagerConstructorArgs);
|
|
14
16
|
registerExternalAddress(input: RegisterExternalAddressInput): RegisterExternalAddressDAReturnType;
|
|
17
|
+
renameContact(input: RenameContactInput): RenameContactDAReturnType;
|
|
15
18
|
/**
|
|
16
19
|
* Exposes the DI container so future operation methods can resolve their
|
|
17
20
|
* `UseCase`. Not part of the public API.
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"DefaultContactsManager.d.ts","sourceRoot":"","sources":["../../../src/internal/DefaultContactsManager.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,KAAK,mBAAmB,EACxB,KAAK,eAAe,EACrB,MAAM,iCAAiC,CAAC;AACzC,OAAO,EAAE,KAAK,SAAS,EAAE,MAAM,WAAW,CAAC;AAE3C,OAAO,EAAE,KAAK,mCAAmC,EAAE,MAAM,0DAA0D,CAAC;AACpH,OAAO,EAAE,KAAK,eAAe,EAAE,MAAM,sBAAsB,CAAC;AAC5D,OAAO,EAAE,KAAK,4BAA4B,EAAE,MAAM,oCAAoC,CAAC;
|
|
1
|
+
{"version":3,"file":"DefaultContactsManager.d.ts","sourceRoot":"","sources":["../../../src/internal/DefaultContactsManager.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,KAAK,mBAAmB,EACxB,KAAK,eAAe,EACrB,MAAM,iCAAiC,CAAC;AACzC,OAAO,EAAE,KAAK,SAAS,EAAE,MAAM,WAAW,CAAC;AAE3C,OAAO,EAAE,KAAK,mCAAmC,EAAE,MAAM,0DAA0D,CAAC;AACpH,OAAO,EAAE,KAAK,yBAAyB,EAAE,MAAM,gDAAgD,CAAC;AAChG,OAAO,EAAE,KAAK,eAAe,EAAE,MAAM,sBAAsB,CAAC;AAC5D,OAAO,EAAE,KAAK,4BAA4B,EAAE,MAAM,oCAAoC,CAAC;AACvF,OAAO,EAAE,KAAK,kBAAkB,EAAE,MAAM,0BAA0B,CAAC;AAMnE,KAAK,qCAAqC,GAAG;IAC3C,GAAG,EAAE,mBAAmB,CAAC;IACzB,SAAS,EAAE,eAAe,CAAC;IAC3B,OAAO,EAAE,MAAM,CAAC;CACjB,CAAC;AAEF,qBAAa,sBAAuB,YAAW,eAAe;IAC5D,OAAO,CAAC,QAAQ,CAAC,UAAU,CAAY;gBAE3B,EACV,GAAG,EACH,SAAS,EACT,OAAO,GACR,EAAE,qCAAqC;IAIxC,uBAAuB,CACrB,KAAK,EAAE,4BAA4B,GAClC,mCAAmC;IAQtC,aAAa,CAAC,KAAK,EAAE,kBAAkB,GAAG,yBAAyB;IAMnE;;;OAGG;IACH,SAAS,KAAK,SAAS,IAAI,SAAS,CAEnC;CACF"}
|
|
@@ -1,6 +1,8 @@
|
|
|
1
1
|
import { type DeviceManagementKit, type DeviceSessionId } from "@ledgerhq/device-management-kit";
|
|
2
2
|
import { type RegisterExternalAddressDAReturnType } from "../../api/app-binder/RegisterExternalAddressDeviceActionTypes";
|
|
3
|
+
import { type RenameContactDAReturnType } from "../../api/app-binder/RenameContactDeviceActionTypes";
|
|
3
4
|
import { type RegisterExternalAddressInput } from "../../api/model/RegisterExternalAddress";
|
|
5
|
+
import { type RenameContactInput } from "../../api/model/RenameContact";
|
|
4
6
|
/**
|
|
5
7
|
* Constructs and executes Contacts `DeviceAction`s using the injected `dmk`,
|
|
6
8
|
* `sessionId`, and `appName`. Each Address Book operation gets one method here.
|
|
@@ -11,5 +13,6 @@ export declare class ContactsAppBinder {
|
|
|
11
13
|
protected readonly appName: string;
|
|
12
14
|
constructor(dmk: DeviceManagementKit, sessionId: DeviceSessionId, appName: string);
|
|
13
15
|
registerExternalAddress(input: RegisterExternalAddressInput): RegisterExternalAddressDAReturnType;
|
|
16
|
+
renameContact(input: RenameContactInput): RenameContactDAReturnType;
|
|
14
17
|
}
|
|
15
18
|
//# sourceMappingURL=ContactsAppBinder.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ContactsAppBinder.d.ts","sourceRoot":"","sources":["../../../../src/internal/app-binder/ContactsAppBinder.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,KAAK,mBAAmB,EACxB,KAAK,eAAe,EACrB,MAAM,iCAAiC,CAAC;AAGzC,OAAO,EAAE,KAAK,mCAAmC,EAAE,MAAM,0DAA0D,CAAC;AACpH,OAAO,EAAE,KAAK,4BAA4B,EAAE,MAAM,oCAAoC,CAAC;
|
|
1
|
+
{"version":3,"file":"ContactsAppBinder.d.ts","sourceRoot":"","sources":["../../../../src/internal/app-binder/ContactsAppBinder.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,KAAK,mBAAmB,EACxB,KAAK,eAAe,EACrB,MAAM,iCAAiC,CAAC;AAGzC,OAAO,EAAE,KAAK,mCAAmC,EAAE,MAAM,0DAA0D,CAAC;AACpH,OAAO,EAAE,KAAK,yBAAyB,EAAE,MAAM,gDAAgD,CAAC;AAChG,OAAO,EAAE,KAAK,4BAA4B,EAAE,MAAM,oCAAoC,CAAC;AACvF,OAAO,EAAE,KAAK,kBAAkB,EAAE,MAAM,0BAA0B,CAAC;AAKnE;;;GAGG;AACH,qBACa,iBAAiB;IAG1B,SAAS,CAAC,QAAQ,CAAC,GAAG,EAAE,mBAAmB;IAE3C,SAAS,CAAC,QAAQ,CAAC,SAAS,EAAE,eAAe;IAE7C,SAAS,CAAC,QAAQ,CAAC,OAAO,EAAE,MAAM;gBAJf,GAAG,EAAE,mBAAmB,EAExB,SAAS,EAAE,eAAe,EAE1B,OAAO,EAAE,MAAM;IAGpC,uBAAuB,CACrB,KAAK,EAAE,4BAA4B,GAClC,mCAAmC;IAStC,aAAa,CAAC,KAAK,EAAE,kBAAkB,GAAG,yBAAyB;CAQpE"}
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
import { type Apdu, type ApduResponse, type Command, type CommandResult } from "@ledgerhq/device-management-kit";
|
|
2
|
+
import { type ContactsErrorCodes } from "../../app-binder/model/contactsErrors";
|
|
3
|
+
export type RenameContactCommandArgs = {
|
|
4
|
+
/** One framed chunk built by sendFramedContactsPayload. */
|
|
5
|
+
readonly data: Uint8Array;
|
|
6
|
+
/** 0x00 for the first/only chunk, 0x80 for continuation chunks. */
|
|
7
|
+
readonly p2: number;
|
|
8
|
+
};
|
|
9
|
+
export type RenameContactCommandResponse = {
|
|
10
|
+
/**
|
|
11
|
+
* Present only on the final chunk — the device returns struct_type(0x2e) +
|
|
12
|
+
* rotated hmac_name(32) there. Intermediate chunks return SW=0x9000 with no
|
|
13
|
+
* data. This is the replacement group-level name proof.
|
|
14
|
+
*/
|
|
15
|
+
readonly hmacProof?: Uint8Array;
|
|
16
|
+
};
|
|
17
|
+
export declare class RenameContactCommand implements Command<RenameContactCommandResponse, RenameContactCommandArgs, ContactsErrorCodes> {
|
|
18
|
+
readonly name = "renameContact";
|
|
19
|
+
readonly args: RenameContactCommandArgs;
|
|
20
|
+
private readonly errorHelper;
|
|
21
|
+
constructor(args: RenameContactCommandArgs);
|
|
22
|
+
getApdu(): Apdu;
|
|
23
|
+
parseResponse(response: ApduResponse): CommandResult<RenameContactCommandResponse, ContactsErrorCodes>;
|
|
24
|
+
}
|
|
25
|
+
//# sourceMappingURL=RenameContactCommand.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"RenameContactCommand.d.ts","sourceRoot":"","sources":["../../../../../src/internal/app-binder/command/RenameContactCommand.ts"],"names":[],"mappings":"AAcA,OAAO,EACL,KAAK,IAAI,EAGT,KAAK,YAAY,EACjB,KAAK,OAAO,EACZ,KAAK,aAAa,EAGnB,MAAM,iCAAiC,CAAC;AAUzC,OAAO,EAGL,KAAK,kBAAkB,EACxB,MAAM,2CAA2C,CAAC;AAGnD,MAAM,MAAM,wBAAwB,GAAG;IACrC,2DAA2D;IAC3D,QAAQ,CAAC,IAAI,EAAE,UAAU,CAAC;IAC1B,mEAAmE;IACnE,QAAQ,CAAC,EAAE,EAAE,MAAM,CAAC;CACrB,CAAC;AAEF,MAAM,MAAM,4BAA4B,GAAG;IACzC;;;;OAIG;IACH,QAAQ,CAAC,SAAS,CAAC,EAAE,UAAU,CAAC;CACjC,CAAC;AAkBF,qBAAa,oBACX,YACE,OAAO,CACL,4BAA4B,EAC5B,wBAAwB,EACxB,kBAAkB,CACnB;IAEH,QAAQ,CAAC,IAAI,mBAAmB;IAChC,QAAQ,CAAC,IAAI,EAAE,wBAAwB,CAAC;IACxC,OAAO,CAAC,QAAQ,CAAC,WAAW,CAGwB;gBAExC,IAAI,EAAE,wBAAwB;IAI1C,OAAO,IAAI,IAAI;IAWf,aAAa,CACX,QAAQ,EAAE,YAAY,GACrB,aAAa,CAAC,4BAA4B,EAAE,kBAAkB,CAAC;CAoCnE"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"RenameContactCommand.test.d.ts","sourceRoot":"","sources":["../../../../../src/internal/app-binder/command/RenameContactCommand.test.ts"],"names":[],"mappings":""}
|
package/lib/types/internal/app-binder/device-action/RenameContact/RenameContactDeviceAction.d.ts
ADDED
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import { type DeviceActionStateMachine, type InternalApi, XStateDeviceAction } from "@ledgerhq/device-management-kit";
|
|
2
|
+
import { type RenameContactDAError, type RenameContactDAInput, type RenameContactDAIntermediateValue, type RenameContactDAInternalState, type RenameContactDAOutput } from "../../../../api/app-binder/RenameContactDeviceActionTypes";
|
|
3
|
+
import { type RenameContactProof, SendRenameContactTask } from "../../../app-binder/task/SendRenameContactTask";
|
|
4
|
+
export type RenameContactMachineDependencies = {
|
|
5
|
+
readonly isOsSupported: () => boolean;
|
|
6
|
+
readonly renameContact: (input: RenameContactDAInput) => Promise<Awaited<ReturnType<SendRenameContactTask["run"]>>>;
|
|
7
|
+
};
|
|
8
|
+
export declare class RenameContactDeviceAction extends XStateDeviceAction<RenameContactDAOutput, RenameContactDAInput, RenameContactDAError, RenameContactDAIntermediateValue, RenameContactDAInternalState> {
|
|
9
|
+
makeStateMachine(internalApi: InternalApi): DeviceActionStateMachine<RenameContactDAOutput, RenameContactDAInput, RenameContactDAError, RenameContactDAIntermediateValue, RenameContactDAInternalState>;
|
|
10
|
+
extractDependencies(internalApi: InternalApi): RenameContactMachineDependencies;
|
|
11
|
+
}
|
|
12
|
+
export type { RenameContactProof };
|
|
13
|
+
//# sourceMappingURL=RenameContactDeviceAction.d.ts.map
|
package/lib/types/internal/app-binder/device-action/RenameContact/RenameContactDeviceAction.d.ts.map
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"RenameContactDeviceAction.d.ts","sourceRoot":"","sources":["../../../../../../src/internal/app-binder/device-action/RenameContact/RenameContactDeviceAction.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,KAAK,wBAAwB,EAE7B,KAAK,WAAW,EAKhB,kBAAkB,EACnB,MAAM,iCAAiC,CAAC;AAIzC,OAAO,EACL,KAAK,oBAAoB,EACzB,KAAK,oBAAoB,EACzB,KAAK,gCAAgC,EACrC,KAAK,4BAA4B,EACjC,KAAK,qBAAqB,EAC3B,MAAM,gDAAgD,CAAC;AAGxD,OAAO,EACL,KAAK,kBAAkB,EACvB,qBAAqB,EACtB,MAAM,iDAAiD,CAAC;AAIzD,MAAM,MAAM,gCAAgC,GAAG;IAC7C,QAAQ,CAAC,aAAa,EAAE,MAAM,OAAO,CAAC;IACtC,QAAQ,CAAC,aAAa,EAAE,CACtB,KAAK,EAAE,oBAAoB,KACxB,OAAO,CAAC,OAAO,CAAC,UAAU,CAAC,qBAAqB,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC;CACjE,CAAC;AAEF,qBAAa,yBAA0B,SAAQ,kBAAkB,CAC/D,qBAAqB,EACrB,oBAAoB,EACpB,oBAAoB,EACpB,gCAAgC,EAChC,4BAA4B,CAC7B;IACC,gBAAgB,CACd,WAAW,EAAE,WAAW,GACvB,wBAAwB,CACzB,qBAAqB,EACrB,oBAAoB,EACpB,oBAAoB,EACpB,gCAAgC,EAChC,4BAA4B,CAC7B;IAgMD,mBAAmB,CACjB,WAAW,EAAE,WAAW,GACvB,gCAAgC;CAepC;AAED,YAAY,EAAE,kBAAkB,EAAE,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"RenameContactDeviceAction.test.d.ts","sourceRoot":"","sources":["../../../../../../src/internal/app-binder/device-action/RenameContact/RenameContactDeviceAction.test.ts"],"names":[],"mappings":""}
|
package/lib/types/internal/app-binder/device-action/RenameContact/validateRenameContactInput.d.ts
ADDED
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import { type RenameContactInput } from "../../../../api/model/RenameContact";
|
|
2
|
+
import { ContactsValidationError } from "../../../app-binder/model/contactsValidation";
|
|
3
|
+
/**
|
|
4
|
+
* Validate the caller input for Rename Contact. Returns the first
|
|
5
|
+
* `ContactsValidationError` found, or `null` when the input is valid.
|
|
6
|
+
*
|
|
7
|
+
* Non-throwing by design: the device action calls this so an invalid input is
|
|
8
|
+
* surfaced as a typed terminal error state on the observable, keeping the public
|
|
9
|
+
* `ContactsManager.renameContact` free of synchronous throws.
|
|
10
|
+
*/
|
|
11
|
+
export declare function validateRenameContactInput(input: RenameContactInput): ContactsValidationError | null;
|
|
12
|
+
//# sourceMappingURL=validateRenameContactInput.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"validateRenameContactInput.d.ts","sourceRoot":"","sources":["../../../../../../src/internal/app-binder/device-action/RenameContact/validateRenameContactInput.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,kBAAkB,EAAE,MAAM,0BAA0B,CAAC;AACnE,OAAO,EAEL,uBAAuB,EAKxB,MAAM,+CAA+C,CAAC;AAEvD;;;;;;;GAOG;AACH,wBAAgB,0BAA0B,CACxC,KAAK,EAAE,kBAAkB,GACxB,uBAAuB,GAAG,IAAI,CA0BhC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"validateRenameContactInput.test.d.ts","sourceRoot":"","sources":["../../../../../../src/internal/app-binder/device-action/RenameContact/validateRenameContactInput.test.ts"],"names":[],"mappings":""}
|
package/lib/types/internal/app-binder/device-action/__test-utils__/setupGoToDashboardDAMock.d.ts
ADDED
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import { UserInteractionRequired } from "@ledgerhq/device-management-kit";
|
|
2
|
+
/**
|
|
3
|
+
* Mock GoToDashboardDeviceAction to resolve immediately with either success
|
|
4
|
+
* (default) or an error. Emits a single `requiredUserInteraction` snapshot
|
|
5
|
+
* (default `None` — device assumed unlocked and already ready) so the parent
|
|
6
|
+
* action can surface it, mirroring the real nested device action.
|
|
7
|
+
*/
|
|
8
|
+
export declare const setupGoToDashboardDAMock: (options?: {
|
|
9
|
+
error?: unknown;
|
|
10
|
+
requiredUserInteraction?: UserInteractionRequired;
|
|
11
|
+
}) => void;
|
|
12
|
+
//# sourceMappingURL=setupGoToDashboardDAMock.d.ts.map
|
package/lib/types/internal/app-binder/device-action/__test-utils__/setupGoToDashboardDAMock.d.ts.map
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"setupGoToDashboardDAMock.d.ts","sourceRoot":"","sources":["../../../../../../src/internal/app-binder/device-action/__test-utils__/setupGoToDashboardDAMock.ts"],"names":[],"mappings":"AAAA,OAAO,EAEL,uBAAuB,EACxB,MAAM,iCAAiC,CAAC;AAKzC;;;;;GAKG;AACH,eAAO,MAAM,wBAAwB,GACnC,UAAS;IACP,KAAK,CAAC,EAAE,OAAO,CAAC;IAChB,uBAAuB,CAAC,EAAE,uBAAuB,CAAC;CAC9C,SA2BP,CAAC"}
|
|
@@ -22,4 +22,19 @@ export type RunningApp = {
|
|
|
22
22
|
* @param app - the running app's fresh name and version.
|
|
23
23
|
*/
|
|
24
24
|
export declare function isContactsSupportedForSession(internalApi: InternalApi, app: RunningApp): boolean;
|
|
25
|
+
/**
|
|
26
|
+
* OS-only Contacts support check, for internal consumption by dashboard
|
|
27
|
+
* `DeviceAction`s (e.g. Rename Contact, EDIT CONTACT NAME). Dashboard operations
|
|
28
|
+
* are served by the device OS, not the embedded app, so only two dimensions
|
|
29
|
+
* apply:
|
|
30
|
+
* - the device model must be supported;
|
|
31
|
+
* - the device OS must meet its minimum version.
|
|
32
|
+
*
|
|
33
|
+
* The running-app dimension is intentionally skipped: on the dashboard there is
|
|
34
|
+
* no embedded app to gate on (the running "app" is BOLOS). The model and OS both
|
|
35
|
+
* come from the session state, which is stable across the operation.
|
|
36
|
+
*
|
|
37
|
+
* @param internalApi - the DeviceAction's internal API for the current session.
|
|
38
|
+
*/
|
|
39
|
+
export declare function isContactsOsSupportedForSession(internalApi: InternalApi): boolean;
|
|
25
40
|
//# sourceMappingURL=isContactsSupportedForSession.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"isContactsSupportedForSession.d.ts","sourceRoot":"","sources":["../../../../src/internal/app-binder/isContactsSupportedForSession.ts"],"names":[],"mappings":"AAAA,OAAO,EAEL,KAAK,WAAW,EACjB,MAAM,iCAAiC,CAAC;AASzC,gEAAgE;AAChE,MAAM,MAAM,UAAU,GAAG;IACvB,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC;CAC1B,CAAC;AAEF;;;;;;;;;;;;;;;;GAgBG;AACH,wBAAgB,6BAA6B,CAC3C,WAAW,EAAE,WAAW,EACxB,GAAG,EAAE,UAAU,GACd,OAAO,CA0BT"}
|
|
1
|
+
{"version":3,"file":"isContactsSupportedForSession.d.ts","sourceRoot":"","sources":["../../../../src/internal/app-binder/isContactsSupportedForSession.ts"],"names":[],"mappings":"AAAA,OAAO,EAEL,KAAK,WAAW,EACjB,MAAM,iCAAiC,CAAC;AASzC,gEAAgE;AAChE,MAAM,MAAM,UAAU,GAAG;IACvB,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC;CAC1B,CAAC;AAEF;;;;;;;;;;;;;;;;GAgBG;AACH,wBAAgB,6BAA6B,CAC3C,WAAW,EAAE,WAAW,EACxB,GAAG,EAAE,UAAU,GACd,OAAO,CA0BT;AAED;;;;;;;;;;;;;GAaG;AACH,wBAAgB,+BAA+B,CAC7C,WAAW,EAAE,WAAW,GACvB,OAAO,CAcT"}
|