@ledgerhq/device-contacts-kit 0.3.0 → 0.4.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (116) hide show
  1. package/README.md +22 -13
  2. package/lib/cjs/api/index.js +1 -1
  3. package/lib/cjs/api/index.js.map +3 -3
  4. package/lib/cjs/api/model/ContactsVersionRequirements.js +1 -1
  5. package/lib/cjs/api/model/ContactsVersionRequirements.js.map +3 -3
  6. package/lib/cjs/api/model/ContactsVersionRequirements.test.js +1 -1
  7. package/lib/cjs/api/model/ContactsVersionRequirements.test.js.map +3 -3
  8. package/lib/cjs/api/model/ProvideContact.js +2 -0
  9. package/lib/cjs/api/model/ProvideContact.js.map +7 -0
  10. package/lib/cjs/internal/app-binder/command/ProvideContactCommand.js +2 -0
  11. package/lib/cjs/internal/app-binder/command/ProvideContactCommand.js.map +7 -0
  12. package/lib/cjs/internal/app-binder/command/ProvideContactCommand.test.js +2 -0
  13. package/lib/cjs/internal/app-binder/command/ProvideContactCommand.test.js.map +7 -0
  14. package/lib/cjs/internal/app-binder/contactsVersionGuards.js +2 -0
  15. package/lib/cjs/internal/app-binder/contactsVersionGuards.js.map +7 -0
  16. package/lib/cjs/internal/app-binder/contactsVersionGuards.test.js +2 -0
  17. package/lib/cjs/internal/app-binder/contactsVersionGuards.test.js.map +7 -0
  18. package/lib/cjs/internal/app-binder/device-action/EditExternalAddressIdentifier/EditExternalAddressIdentifierDeviceAction.js +1 -1
  19. package/lib/cjs/internal/app-binder/device-action/EditExternalAddressIdentifier/EditExternalAddressIdentifierDeviceAction.js.map +3 -3
  20. package/lib/cjs/internal/app-binder/device-action/EditExternalAddressScope/EditExternalAddressScopeDeviceAction.js +1 -1
  21. package/lib/cjs/internal/app-binder/device-action/EditExternalAddressScope/EditExternalAddressScopeDeviceAction.js.map +3 -3
  22. package/lib/cjs/internal/app-binder/device-action/RegisterExternalAddress/RegisterExternalAddressDeviceAction.js +1 -1
  23. package/lib/cjs/internal/app-binder/device-action/RegisterExternalAddress/RegisterExternalAddressDeviceAction.js.map +3 -3
  24. package/lib/cjs/internal/app-binder/device-action/RenameContact/RenameContactDeviceAction.js +1 -1
  25. package/lib/cjs/internal/app-binder/device-action/RenameContact/RenameContactDeviceAction.js.map +3 -3
  26. package/lib/cjs/internal/app-binder/model/contactsConstants.js +1 -1
  27. package/lib/cjs/internal/app-binder/model/contactsConstants.js.map +3 -3
  28. package/lib/cjs/internal/app-binder/services/provideContact.js +2 -0
  29. package/lib/cjs/internal/app-binder/services/provideContact.js.map +7 -0
  30. package/lib/cjs/internal/app-binder/services/provideContact.test.js +2 -0
  31. package/lib/cjs/internal/app-binder/services/provideContact.test.js.map +7 -0
  32. package/lib/cjs/internal/app-binder/task/SendRegisterIdentityTask.js.map +2 -2
  33. package/lib/cjs/internal/app-binder/task/SendRegisterIdentityTask.test.js.map +1 -1
  34. package/lib/cjs/internal/app-binder/task/SendRenameContactTask.js +1 -1
  35. package/lib/cjs/internal/app-binder/task/SendRenameContactTask.js.map +2 -2
  36. package/lib/cjs/internal/app-binder/task/SendRenameContactTask.test.js +1 -1
  37. package/lib/cjs/internal/app-binder/task/SendRenameContactTask.test.js.map +3 -3
  38. package/lib/cjs/package.json +2 -2
  39. package/lib/esm/api/index.js +1 -1
  40. package/lib/esm/api/index.js.map +3 -3
  41. package/lib/esm/api/model/ContactsVersionRequirements.js +1 -1
  42. package/lib/esm/api/model/ContactsVersionRequirements.js.map +3 -3
  43. package/lib/esm/api/model/ContactsVersionRequirements.test.js +1 -1
  44. package/lib/esm/api/model/ContactsVersionRequirements.test.js.map +3 -3
  45. package/lib/esm/api/model/ProvideContact.js +1 -0
  46. package/lib/esm/api/model/ProvideContact.js.map +7 -0
  47. package/lib/esm/internal/app-binder/command/ProvideContactCommand.js +2 -0
  48. package/lib/esm/internal/app-binder/command/ProvideContactCommand.js.map +7 -0
  49. package/lib/esm/internal/app-binder/command/ProvideContactCommand.test.js +2 -0
  50. package/lib/esm/internal/app-binder/command/ProvideContactCommand.test.js.map +7 -0
  51. package/lib/esm/internal/app-binder/contactsVersionGuards.js +2 -0
  52. package/lib/esm/internal/app-binder/contactsVersionGuards.js.map +7 -0
  53. package/lib/esm/internal/app-binder/contactsVersionGuards.test.js +2 -0
  54. package/lib/esm/internal/app-binder/contactsVersionGuards.test.js.map +7 -0
  55. package/lib/esm/internal/app-binder/device-action/EditExternalAddressIdentifier/EditExternalAddressIdentifierDeviceAction.js +1 -1
  56. package/lib/esm/internal/app-binder/device-action/EditExternalAddressIdentifier/EditExternalAddressIdentifierDeviceAction.js.map +3 -3
  57. package/lib/esm/internal/app-binder/device-action/EditExternalAddressScope/EditExternalAddressScopeDeviceAction.js +1 -1
  58. package/lib/esm/internal/app-binder/device-action/EditExternalAddressScope/EditExternalAddressScopeDeviceAction.js.map +3 -3
  59. package/lib/esm/internal/app-binder/device-action/RegisterExternalAddress/RegisterExternalAddressDeviceAction.js +1 -1
  60. package/lib/esm/internal/app-binder/device-action/RegisterExternalAddress/RegisterExternalAddressDeviceAction.js.map +3 -3
  61. package/lib/esm/internal/app-binder/device-action/RenameContact/RenameContactDeviceAction.js +1 -1
  62. package/lib/esm/internal/app-binder/device-action/RenameContact/RenameContactDeviceAction.js.map +2 -2
  63. package/lib/esm/internal/app-binder/model/contactsConstants.js +1 -1
  64. package/lib/esm/internal/app-binder/model/contactsConstants.js.map +3 -3
  65. package/lib/esm/internal/app-binder/services/provideContact.js +2 -0
  66. package/lib/esm/internal/app-binder/services/provideContact.js.map +7 -0
  67. package/lib/esm/internal/app-binder/services/provideContact.test.js +2 -0
  68. package/lib/esm/internal/app-binder/services/provideContact.test.js.map +7 -0
  69. package/lib/esm/internal/app-binder/task/SendRegisterIdentityTask.js.map +2 -2
  70. package/lib/esm/internal/app-binder/task/SendRegisterIdentityTask.test.js.map +1 -1
  71. package/lib/esm/internal/app-binder/task/SendRenameContactTask.js +1 -1
  72. package/lib/esm/internal/app-binder/task/SendRenameContactTask.js.map +3 -3
  73. package/lib/esm/internal/app-binder/task/SendRenameContactTask.test.js +1 -1
  74. package/lib/esm/internal/app-binder/task/SendRenameContactTask.test.js.map +3 -3
  75. package/lib/esm/package.json +2 -2
  76. package/lib/types/api/index.d.ts +4 -1
  77. package/lib/types/api/index.d.ts.map +1 -1
  78. package/lib/types/api/model/ContactsVersionRequirements.d.ts +7 -25
  79. package/lib/types/api/model/ContactsVersionRequirements.d.ts.map +1 -1
  80. package/lib/types/api/model/ProvideContact.d.ts +20 -0
  81. package/lib/types/api/model/ProvideContact.d.ts.map +1 -0
  82. package/lib/types/internal/app-binder/command/ProvideContactCommand.d.ts +18 -0
  83. package/lib/types/internal/app-binder/command/ProvideContactCommand.d.ts.map +1 -0
  84. package/lib/types/internal/app-binder/command/ProvideContactCommand.test.d.ts +2 -0
  85. package/lib/types/internal/app-binder/command/ProvideContactCommand.test.d.ts.map +1 -0
  86. package/lib/types/internal/app-binder/{isContactsSupportedForSession.d.ts → contactsVersionGuards.d.ts} +19 -21
  87. package/lib/types/internal/app-binder/contactsVersionGuards.d.ts.map +1 -0
  88. package/lib/types/internal/app-binder/contactsVersionGuards.test.d.ts +2 -0
  89. package/lib/types/internal/app-binder/contactsVersionGuards.test.d.ts.map +1 -0
  90. package/lib/types/internal/app-binder/device-action/EditExternalAddressIdentifier/EditExternalAddressIdentifierDeviceAction.d.ts +1 -1
  91. package/lib/types/internal/app-binder/device-action/EditExternalAddressIdentifier/EditExternalAddressIdentifierDeviceAction.d.ts.map +1 -1
  92. package/lib/types/internal/app-binder/device-action/EditExternalAddressScope/EditExternalAddressScopeDeviceAction.d.ts +1 -1
  93. package/lib/types/internal/app-binder/device-action/EditExternalAddressScope/EditExternalAddressScopeDeviceAction.d.ts.map +1 -1
  94. package/lib/types/internal/app-binder/device-action/RegisterExternalAddress/RegisterExternalAddressDeviceAction.d.ts +1 -1
  95. package/lib/types/internal/app-binder/device-action/RegisterExternalAddress/RegisterExternalAddressDeviceAction.d.ts.map +1 -1
  96. package/lib/types/internal/app-binder/model/contactsConstants.d.ts +2 -0
  97. package/lib/types/internal/app-binder/model/contactsConstants.d.ts.map +1 -1
  98. package/lib/types/internal/app-binder/services/provideContact.d.ts +15 -0
  99. package/lib/types/internal/app-binder/services/provideContact.d.ts.map +1 -0
  100. package/lib/types/internal/app-binder/services/provideContact.test.d.ts +2 -0
  101. package/lib/types/internal/app-binder/services/provideContact.test.d.ts.map +1 -0
  102. package/lib/types/internal/app-binder/task/SendRegisterIdentityTask.d.ts.map +1 -1
  103. package/lib/types/internal/app-binder/task/SendRenameContactTask.d.ts.map +1 -1
  104. package/lib/types/tsconfig.prod.tsbuildinfo +1 -1
  105. package/package.json +6 -6
  106. package/lib/cjs/internal/app-binder/isContactsSupportedForSession.js +0 -2
  107. package/lib/cjs/internal/app-binder/isContactsSupportedForSession.js.map +0 -7
  108. package/lib/cjs/internal/app-binder/isContactsSupportedForSession.test.js +0 -2
  109. package/lib/cjs/internal/app-binder/isContactsSupportedForSession.test.js.map +0 -7
  110. package/lib/esm/internal/app-binder/isContactsSupportedForSession.js +0 -2
  111. package/lib/esm/internal/app-binder/isContactsSupportedForSession.js.map +0 -7
  112. package/lib/esm/internal/app-binder/isContactsSupportedForSession.test.js +0 -2
  113. package/lib/esm/internal/app-binder/isContactsSupportedForSession.test.js.map +0 -7
  114. package/lib/types/internal/app-binder/isContactsSupportedForSession.d.ts.map +0 -1
  115. package/lib/types/internal/app-binder/isContactsSupportedForSession.test.d.ts +0 -2
  116. package/lib/types/internal/app-binder/isContactsSupportedForSession.test.d.ts.map +0 -1
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "version": 3,
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": "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",
6
- "names": ["import_device_management_kit", "import_RenameContactCommand", "import_SendRenameContactTask", "hexToBytes", "hex", "out", "i", "GROUP_HANDLE", "HMAC_PROOF_IN", "HMAC_PROOF_OUT", "DERIVATION_PATH_TLV", "FRAMED_CHUNK", "makeApiMock", "api", "result", "command", "framedHex"]
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, HMAC_PROOF \u2014\n// with tags >= 0x80 (0xf0/0xf3/0xf6) encoded as the 2-byte DER form [0x81, tag].\n// No DERIVATION_PATH: the SDK removed tag 0x69 from EDIT_CONTACT_NAME_TAGS on\n// 2026-08-10 and rejects payloads carrying it.\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 79\" (2-byte BE total TLV length = 121) + 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// 29 20 <32x dd> HMAC_PROOF\nconst FRAMED_CHUNK = hexToBytes(\n \"0079\" +\n \"01012e\" +\n \"020101\" +\n \"81f003426f62\" +\n \"81f305416c696365\" +\n \"81f640\" +\n \"cc\".repeat(64) +\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(\"does not emit a DERIVATION_PATH tag\", 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 // api-level 27 dropped tag 0x69 from EDIT_CONTACT_NAME_TAGS: a payload\n // carrying it fails to parse and the device answers 0x6a80. HMAC_PROOF\n // (0x29) therefore follows GROUP_HANDLE directly.\n const command = api.sendCommand.mock.calls[0]![0] as RenameContactCommand;\n const framedHex = Buffer.from(command.args.data).toString(\"hex\");\n expect(framedHex).not.toContain(\"691505\");\n expect(\n framedHex.endsWith(\"81f640\" + \"cc\".repeat(64) + \"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": "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",
6
+ "names": ["import_device_management_kit", "import_RenameContactCommand", "import_SendRenameContactTask", "hexToBytes", "hex", "out", "i", "GROUP_HANDLE", "HMAC_PROOF_IN", "HMAC_PROOF_OUT", "FRAMED_CHUNK", "makeApiMock", "api", "result", "command", "framedHex"]
7
7
  }
@@ -36,7 +36,7 @@
36
36
  "license": "Apache-2.0",
37
37
  "name": "@ledgerhq/device-contacts-kit",
38
38
  "peerDependencies": {
39
- "@ledgerhq/device-management-kit": "^1.8.0"
39
+ "@ledgerhq/device-management-kit": "workspace:^"
40
40
  },
41
41
  "private": false,
42
42
  "repository": {
@@ -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.3.0"
61
+ "version": "0.4.0"
62
62
  }
@@ -1,2 +1,2 @@
1
- import{ContactsManagerBuilder as r}from"./ContactsManagerBuilder";import{CONTACTS_VERSION_REQUIREMENTS as d,ETHEREUM_APP_NAME as p,isContactsSupported as s,isVersionAtLeast as a,resolveContactsVersionRequirements as o}from"./model/ContactsVersionRequirements";export{d as CONTACTS_VERSION_REQUIREMENTS,r as ContactsManagerBuilder,p as ETHEREUM_APP_NAME,s as isContactsSupported,a as isVersionAtLeast,o as resolveContactsVersionRequirements};
1
+ import{ContactsManagerBuilder as r}from"./ContactsManagerBuilder";import{CONTACTS_VERSION_REQUIREMENTS as n,ETHEREUM_APP_NAME as p,isVersionAtLeast as o,resolveContactsVersionRequirements as s}from"./model/ContactsVersionRequirements";import{buildProvideContactPayload as i,sendProvideContactPayload as A}from"../internal/app-binder/services/provideContact";export{n as CONTACTS_VERSION_REQUIREMENTS,r as ContactsManagerBuilder,p as ETHEREUM_APP_NAME,i as buildProvideContactPayload,o as isVersionAtLeast,s as resolveContactsVersionRequirements,A as sendProvideContactPayload};
2
2
  //# sourceMappingURL=index.js.map
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "version": 3,
3
3
  "sources": ["../../../src/api/index.ts"],
4
- "sourcesContent": ["export {\n type EditExternalAddressIdentifierDAError,\n type EditExternalAddressIdentifierDAInput,\n type EditExternalAddressIdentifierDAIntermediateValue,\n type EditExternalAddressIdentifierDAOutput,\n type EditExternalAddressIdentifierDARequiredInteraction,\n type EditExternalAddressIdentifierDAReturnType,\n type EditExternalAddressIdentifierDAState,\n} from \"@api/app-binder/EditExternalAddressIdentifierDeviceActionTypes\";\nexport {\n type EditExternalAddressScopeDAError,\n type EditExternalAddressScopeDAInput,\n type EditExternalAddressScopeDAIntermediateValue,\n type EditExternalAddressScopeDAOutput,\n type EditExternalAddressScopeDARequiredInteraction,\n type EditExternalAddressScopeDAReturnType,\n type EditExternalAddressScopeDAState,\n} from \"@api/app-binder/EditExternalAddressScopeDeviceActionTypes\";\nexport {\n type RegisterExternalAddressDAError,\n type RegisterExternalAddressDAInput,\n type RegisterExternalAddressDAIntermediateValue,\n type RegisterExternalAddressDAOutput,\n type RegisterExternalAddressDARequiredInteraction,\n type RegisterExternalAddressDAReturnType,\n type RegisterExternalAddressDAState,\n} from \"@api/app-binder/RegisterExternalAddressDeviceActionTypes\";\nexport {\n type RenameContactDAError,\n type RenameContactDAInput,\n type RenameContactDAIntermediateValue,\n type RenameContactDAOutput,\n type RenameContactDARequiredInteraction,\n type RenameContactDAReturnType,\n type RenameContactDAState,\n} from \"@api/app-binder/RenameContactDeviceActionTypes\";\nexport { type ContactsManager } from \"@api/ContactsManager\";\nexport { ContactsManagerBuilder } from \"@api/ContactsManagerBuilder\";\nexport {\n CONTACTS_VERSION_REQUIREMENTS,\n type ContactsModelRequirement,\n type ContactsModelSupport,\n type ContactsModelUnsupported,\n type ContactsSupportQuery,\n type ContactsVersionRequirements,\n ETHEREUM_APP_NAME,\n isContactsSupported,\n isVersionAtLeast,\n resolveContactsVersionRequirements,\n} from \"@api/model/ContactsVersionRequirements\";\nexport {\n type EditExternalAddressIdentifierInput,\n type EditExternalAddressIdentifierOutput,\n} from \"@api/model/EditExternalAddressIdentifier\";\nexport {\n type EditExternalAddressScopeInput,\n type EditExternalAddressScopeOutput,\n} from \"@api/model/EditExternalAddressScope\";\nexport {\n type ExistingContactGroup,\n type RegisterExternalAddressInput,\n type RegisterExternalAddressMode,\n type RegisterExternalAddressOutput,\n} from \"@api/model/RegisterExternalAddress\";\nexport {\n type RenameContactInput,\n type RenameContactOutput,\n} from \"@api/model/RenameContact\";\n"],
5
- "mappings": "AAqCA,OAAS,0BAAAA,MAA8B,8BACvC,OACE,iCAAAC,EAMA,qBAAAC,EACA,uBAAAC,EACA,oBAAAC,EACA,sCAAAC,MACK",
6
- "names": ["ContactsManagerBuilder", "CONTACTS_VERSION_REQUIREMENTS", "ETHEREUM_APP_NAME", "isContactsSupported", "isVersionAtLeast", "resolveContactsVersionRequirements"]
4
+ "sourcesContent": ["export {\n type EditExternalAddressIdentifierDAError,\n type EditExternalAddressIdentifierDAInput,\n type EditExternalAddressIdentifierDAIntermediateValue,\n type EditExternalAddressIdentifierDAOutput,\n type EditExternalAddressIdentifierDARequiredInteraction,\n type EditExternalAddressIdentifierDAReturnType,\n type EditExternalAddressIdentifierDAState,\n} from \"@api/app-binder/EditExternalAddressIdentifierDeviceActionTypes\";\nexport {\n type EditExternalAddressScopeDAError,\n type EditExternalAddressScopeDAInput,\n type EditExternalAddressScopeDAIntermediateValue,\n type EditExternalAddressScopeDAOutput,\n type EditExternalAddressScopeDARequiredInteraction,\n type EditExternalAddressScopeDAReturnType,\n type EditExternalAddressScopeDAState,\n} from \"@api/app-binder/EditExternalAddressScopeDeviceActionTypes\";\nexport {\n type RegisterExternalAddressDAError,\n type RegisterExternalAddressDAInput,\n type RegisterExternalAddressDAIntermediateValue,\n type RegisterExternalAddressDAOutput,\n type RegisterExternalAddressDARequiredInteraction,\n type RegisterExternalAddressDAReturnType,\n type RegisterExternalAddressDAState,\n} from \"@api/app-binder/RegisterExternalAddressDeviceActionTypes\";\nexport {\n type RenameContactDAError,\n type RenameContactDAInput,\n type RenameContactDAIntermediateValue,\n type RenameContactDAOutput,\n type RenameContactDARequiredInteraction,\n type RenameContactDAReturnType,\n type RenameContactDAState,\n} from \"@api/app-binder/RenameContactDeviceActionTypes\";\nexport { type ContactsManager } from \"@api/ContactsManager\";\nexport { ContactsManagerBuilder } from \"@api/ContactsManagerBuilder\";\nexport {\n CONTACTS_VERSION_REQUIREMENTS,\n type ContactsModelRequirement,\n type ContactsModelSupport,\n type ContactsModelUnsupported,\n type ContactsVersionRequirements,\n ETHEREUM_APP_NAME,\n isVersionAtLeast,\n resolveContactsVersionRequirements,\n} from \"@api/model/ContactsVersionRequirements\";\nexport {\n type EditExternalAddressIdentifierInput,\n type EditExternalAddressIdentifierOutput,\n} from \"@api/model/EditExternalAddressIdentifier\";\nexport {\n type EditExternalAddressScopeInput,\n type EditExternalAddressScopeOutput,\n} from \"@api/model/EditExternalAddressScope\";\nexport { type ProvideContactInput } from \"@api/model/ProvideContact\";\nexport {\n type ExistingContactGroup,\n type RegisterExternalAddressInput,\n type RegisterExternalAddressMode,\n type RegisterExternalAddressOutput,\n} from \"@api/model/RegisterExternalAddress\";\nexport {\n type RenameContactInput,\n type RenameContactOutput,\n} from \"@api/model/RenameContact\";\nexport { type ContactsErrorCodes } from \"@internal/app-binder/model/contactsErrors\";\nexport {\n buildProvideContactPayload,\n sendProvideContactPayload,\n type SendProvideContactPayloadArgs,\n} from \"@internal/app-binder/services/provideContact\";\n"],
5
+ "mappings": "AAqCA,OAAS,0BAAAA,MAA8B,8BACvC,OACE,iCAAAC,EAKA,qBAAAC,EACA,oBAAAC,EACA,sCAAAC,MACK,yCAqBP,OACE,8BAAAC,EACA,6BAAAC,MAEK",
6
+ "names": ["ContactsManagerBuilder", "CONTACTS_VERSION_REQUIREMENTS", "ETHEREUM_APP_NAME", "isVersionAtLeast", "resolveContactsVersionRequirements", "buildProvideContactPayload", "sendProvideContactPayload"]
7
7
  }
@@ -1,2 +1,2 @@
1
- import{DeviceModelId as o}from"@ledgerhq/device-management-kit";import{coerce as c,gte as V,valid as s}from"semver";const i="Ethereum",d={supported:!1},m="1.5.0",E="1.2.0",M="0.9.0",u="1.15.0",N={[o.NANO_S]:d,[o.NANO_SP]:d,[o.NANO_X]:d,[o.STAX]:{supported:!0,minOsVersion:m,minAppVersion:{[i]:u}},[o.FLEX]:{supported:!0,minOsVersion:E,minAppVersion:{[i]:u}},[o.APEX]:{supported:!0,minOsVersion:M,minAppVersion:{[i]:u}}};function R(e){return N[e]}function l(e,t){const n=s(e)??s(c(e)),r=s(t)??s(c(t));return n===null||r===null?!1:V(n,r)}function A({deviceModelId:e,osVersion:t,appName:n,appVersion:r}){const p=R(e);if(!p.supported||!l(t,p.minOsVersion))return!1;const a=p.minAppVersion[n];return a===void 0?!1:l(r,a)}export{N as CONTACTS_VERSION_REQUIREMENTS,i as ETHEREUM_APP_NAME,A as isContactsSupported,l as isVersionAtLeast,R as resolveContactsVersionRequirements};
1
+ import{DeviceModelId as e}from"@ledgerhq/device-management-kit";import{coerce as p,gte as u,valid as i}from"semver";const o="Ethereum",c={supported:!1},l="1.11.0",N="1.7.0",_="1.2.0",O="2.8.0",a="1.7.0",t="1.23.0",m={[e.NANO_S]:c,[e.NANO_SP]:{supported:!0,minOsVersion:a,minAppVersion:{[o]:t}},[e.NANO_X]:{supported:!0,minOsVersion:O,minAppVersion:{[o]:t}},[e.STAX]:{supported:!0,minOsVersion:l,minAppVersion:{[o]:t}},[e.FLEX]:{supported:!0,minOsVersion:N,minAppVersion:{[o]:t}},[e.APEX]:{supported:!0,minOsVersion:_,minAppVersion:{[o]:t}}};function R(n){return m[n]}function S(n,d){const r=i(p(n)),s=i(p(d));return r===null||s===null?!1:u(r,s)}export{m as CONTACTS_VERSION_REQUIREMENTS,o as ETHEREUM_APP_NAME,S as isVersionAtLeast,R as resolveContactsVersionRequirements};
2
2
  //# sourceMappingURL=ContactsVersionRequirements.js.map
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "version": 3,
3
3
  "sources": ["../../../../src/api/model/ContactsVersionRequirements.ts"],
4
- "sourcesContent": ["import { DeviceModelId } from \"@ledgerhq/device-management-kit\";\nimport { coerce, gte, valid } from \"semver\";\n\n/**\n * Version requirements for a device model on which Contacts (Address Book)\n * operations are supported.\n *\n * Contacts has two independent version axes:\n * - `minOsVersion` gates OS-owned operations (e.g. renaming a contact from the\n * device dashboard), which are served by the device OS.\n * - `minAppVersion` gates app-owned operations (registering / editing external\n * addresses and Ledger accounts), which are served by the embedded app. It is\n * keyed by app name because the required version differs per app; v1 ships\n * Ethereum only.\n */\nexport type ContactsModelSupport = {\n readonly supported: true;\n readonly minOsVersion: string;\n readonly minAppVersion: Readonly<Record<string, string>>;\n};\n\n/** Marks a device model on which Contacts is not supported at all. */\nexport type ContactsModelUnsupported = {\n readonly supported: false;\n};\n\nexport type ContactsModelRequirement =\n | ContactsModelSupport\n | ContactsModelUnsupported;\n\n/**\n * The full, static Contacts version-requirement table, keyed by device model.\n * Serializable plain data with no runtime dependencies, so hosts (e.g. Ledger\n * Wallet) can import and consume it directly when composing their own\n * app-readiness checks, without duplicating the values.\n */\nexport type ContactsVersionRequirements = Readonly<\n Record<DeviceModelId, ContactsModelRequirement>\n>;\n\n/** The name of the Ethereum embedded app (the only app supported in v1). */\nexport const ETHEREUM_APP_NAME = \"Ethereum\";\n\nconst UNSUPPORTED: ContactsModelUnsupported = { supported: false };\n\n// TODO(DSDK-1376): replace these placeholder versions with the real minimums\n// confirmed by the firmware and Ethereum-app owners. The shape and consumers\n// are final; only the version strings below are provisional.\nconst MIN_OS_VERSION_STAX = \"1.5.0\";\nconst MIN_OS_VERSION_FLEX = \"1.2.0\";\nconst MIN_OS_VERSION_APEX = \"0.9.0\";\nconst MIN_ETHEREUM_APP_VERSION = \"1.15.0\";\n\n/**\n * Contacts APDUs are supported only on the touchscreen device models (Stax,\n * Flex, Apex). The Nano models do not support Contacts at all.\n */\nexport const CONTACTS_VERSION_REQUIREMENTS: ContactsVersionRequirements = {\n [DeviceModelId.NANO_S]: UNSUPPORTED,\n [DeviceModelId.NANO_SP]: UNSUPPORTED,\n [DeviceModelId.NANO_X]: UNSUPPORTED,\n [DeviceModelId.STAX]: {\n supported: true,\n minOsVersion: MIN_OS_VERSION_STAX,\n minAppVersion: { [ETHEREUM_APP_NAME]: MIN_ETHEREUM_APP_VERSION },\n },\n [DeviceModelId.FLEX]: {\n supported: true,\n minOsVersion: MIN_OS_VERSION_FLEX,\n minAppVersion: { [ETHEREUM_APP_NAME]: MIN_ETHEREUM_APP_VERSION },\n },\n [DeviceModelId.APEX]: {\n supported: true,\n minOsVersion: MIN_OS_VERSION_APEX,\n minAppVersion: { [ETHEREUM_APP_NAME]: MIN_ETHEREUM_APP_VERSION },\n },\n};\n\n/**\n * Resolve the Contacts version requirements for a device model \u2014 i.e. the\n * minimum supported OS and app versions, or that the model is unsupported.\n */\nexport function resolveContactsVersionRequirements(\n deviceModelId: DeviceModelId,\n): ContactsModelRequirement {\n return CONTACTS_VERSION_REQUIREMENTS[deviceModelId];\n}\n\n/**\n * Whether `actual` is greater than or equal to `minimum`, comparing as semver.\n * Tolerant of non-strict version strings (coerces where possible) and returns\n * `false` (i.e. requirement not met) when either version cannot be parsed, so\n * an unknown version never passes a check.\n */\nexport function isVersionAtLeast(actual: string, minimum: string): boolean {\n const a = valid(actual) ?? valid(coerce(actual));\n const b = valid(minimum) ?? valid(coerce(minimum));\n if (a === null || b === null) return false;\n return gte(a, b);\n}\n\n/** Inputs for {@link isContactsSupported}. */\nexport type ContactsSupportQuery = {\n readonly deviceModelId: DeviceModelId;\n /** The device OS (firmware) version. */\n readonly osVersion: string;\n /** The name of the currently running embedded app. */\n readonly appName: string;\n /** The version of the currently running embedded app. */\n readonly appVersion: string;\n};\n\n/**\n * Whether Contacts app-owned operations are supported for the given device\n * model, OS version, and running app \u2014 checking the model is supported, the OS\n * meets its minimum, the app is known to Contacts, and the app meets its\n * minimum.\n *\n * Pure and dependency-light: hosts can call this directly, or read\n * {@link CONTACTS_VERSION_REQUIREMENTS} to build their own checks.\n */\nexport function isContactsSupported({\n deviceModelId,\n osVersion,\n appName,\n appVersion,\n}: ContactsSupportQuery): boolean {\n const requirement = resolveContactsVersionRequirements(deviceModelId);\n if (!requirement.supported) return false;\n if (!isVersionAtLeast(osVersion, requirement.minOsVersion)) return false;\n\n const minAppVersion = requirement.minAppVersion[appName];\n if (minAppVersion === undefined) return false;\n return isVersionAtLeast(appVersion, minAppVersion);\n}\n"],
5
- "mappings": "AAAA,OAAS,iBAAAA,MAAqB,kCAC9B,OAAS,UAAAC,EAAQ,OAAAC,EAAK,SAAAC,MAAa,SAwC5B,MAAMC,EAAoB,WAE3BC,EAAwC,CAAE,UAAW,EAAM,EAK3DC,EAAsB,QACtBC,EAAsB,QACtBC,EAAsB,QACtBC,EAA2B,SAMpBC,EAA6D,CACxE,CAACV,EAAc,MAAM,EAAGK,EACxB,CAACL,EAAc,OAAO,EAAGK,EACzB,CAACL,EAAc,MAAM,EAAGK,EACxB,CAACL,EAAc,IAAI,EAAG,CACpB,UAAW,GACX,aAAcM,EACd,cAAe,CAAE,CAACF,CAAiB,EAAGK,CAAyB,CACjE,EACA,CAACT,EAAc,IAAI,EAAG,CACpB,UAAW,GACX,aAAcO,EACd,cAAe,CAAE,CAACH,CAAiB,EAAGK,CAAyB,CACjE,EACA,CAACT,EAAc,IAAI,EAAG,CACpB,UAAW,GACX,aAAcQ,EACd,cAAe,CAAE,CAACJ,CAAiB,EAAGK,CAAyB,CACjE,CACF,EAMO,SAASE,EACdC,EAC0B,CAC1B,OAAOF,EAA8BE,CAAa,CACpD,CAQO,SAASC,EAAiBC,EAAgBC,EAA0B,CACzE,MAAMC,EAAIb,EAAMW,CAAM,GAAKX,EAAMF,EAAOa,CAAM,CAAC,EACzCG,EAAId,EAAMY,CAAO,GAAKZ,EAAMF,EAAOc,CAAO,CAAC,EACjD,OAAIC,IAAM,MAAQC,IAAM,KAAa,GAC9Bf,EAAIc,EAAGC,CAAC,CACjB,CAsBO,SAASC,EAAoB,CAClC,cAAAN,EACA,UAAAO,EACA,QAAAC,EACA,WAAAC,CACF,EAAkC,CAChC,MAAMC,EAAcX,EAAmCC,CAAa,EAEpE,GADI,CAACU,EAAY,WACb,CAACT,EAAiBM,EAAWG,EAAY,YAAY,EAAG,MAAO,GAEnE,MAAMC,EAAgBD,EAAY,cAAcF,CAAO,EACvD,OAAIG,IAAkB,OAAkB,GACjCV,EAAiBQ,EAAYE,CAAa,CACnD",
6
- "names": ["DeviceModelId", "coerce", "gte", "valid", "ETHEREUM_APP_NAME", "UNSUPPORTED", "MIN_OS_VERSION_STAX", "MIN_OS_VERSION_FLEX", "MIN_OS_VERSION_APEX", "MIN_ETHEREUM_APP_VERSION", "CONTACTS_VERSION_REQUIREMENTS", "resolveContactsVersionRequirements", "deviceModelId", "isVersionAtLeast", "actual", "minimum", "a", "b", "isContactsSupported", "osVersion", "appName", "appVersion", "requirement", "minAppVersion"]
4
+ "sourcesContent": ["import { DeviceModelId } from \"@ledgerhq/device-management-kit\";\nimport { coerce, gte, valid } from \"semver\";\n\n/**\n * Version requirements for a device model on which Contacts (Address Book)\n * operations are supported.\n *\n * Contacts has two independent version axes:\n * - `minOsVersion` gates OS-owned operations (e.g. renaming a contact from the\n * device dashboard), which are served by the device OS.\n * - `minAppVersion` gates app-owned operations (registering / editing external\n * addresses and Ledger accounts), which are served by the embedded app. It is\n * keyed by app name because the required version differs per app; v1 ships\n * Ethereum only.\n */\nexport type ContactsModelSupport = {\n readonly supported: true;\n readonly minOsVersion: string;\n readonly minAppVersion: Readonly<Record<string, string>>;\n};\n\n/** Marks a device model on which Contacts is not supported at all. */\nexport type ContactsModelUnsupported = {\n readonly supported: false;\n};\n\nexport type ContactsModelRequirement =\n | ContactsModelSupport\n | ContactsModelUnsupported;\n\n/**\n * The full, static Contacts version-requirement table, keyed by device model.\n * Serializable plain data with no runtime dependencies, so hosts (e.g. Ledger\n * Wallet) can import and consume it directly when composing their own\n * app-readiness checks, without duplicating the values.\n */\nexport type ContactsVersionRequirements = Readonly<\n Record<DeviceModelId, ContactsModelRequirement>\n>;\n\n/** The name of the Ethereum embedded app (the only app supported in v1). */\nexport const ETHEREUM_APP_NAME = \"Ethereum\";\n\nconst UNSUPPORTED: ContactsModelUnsupported = { supported: false };\n\nconst MIN_OS_VERSION_STAX = \"1.11.0\";\nconst MIN_OS_VERSION_FLEX = \"1.7.0\";\nconst MIN_OS_VERSION_APEX = \"1.2.0\";\nconst MIN_OS_VERSION_NANO_X = \"2.8.0\";\nconst MIN_OS_VERSION_NANO_SP = \"1.7.0\";\n\nconst MIN_ETHEREUM_APP_VERSION = \"1.23.0\";\n\n/**\n * Contacts APDUs are supported on the touchscreen device models (Stax, Flex,\n * Apex) and on Nano X / Nano SP. Nano S does not support Contacts at all.\n */\nexport const CONTACTS_VERSION_REQUIREMENTS: ContactsVersionRequirements = {\n [DeviceModelId.NANO_S]: UNSUPPORTED,\n [DeviceModelId.NANO_SP]: {\n supported: true,\n minOsVersion: MIN_OS_VERSION_NANO_SP,\n minAppVersion: { [ETHEREUM_APP_NAME]: MIN_ETHEREUM_APP_VERSION },\n },\n [DeviceModelId.NANO_X]: {\n supported: true,\n minOsVersion: MIN_OS_VERSION_NANO_X,\n minAppVersion: { [ETHEREUM_APP_NAME]: MIN_ETHEREUM_APP_VERSION },\n },\n [DeviceModelId.STAX]: {\n supported: true,\n minOsVersion: MIN_OS_VERSION_STAX,\n minAppVersion: { [ETHEREUM_APP_NAME]: MIN_ETHEREUM_APP_VERSION },\n },\n [DeviceModelId.FLEX]: {\n supported: true,\n minOsVersion: MIN_OS_VERSION_FLEX,\n minAppVersion: { [ETHEREUM_APP_NAME]: MIN_ETHEREUM_APP_VERSION },\n },\n [DeviceModelId.APEX]: {\n supported: true,\n minOsVersion: MIN_OS_VERSION_APEX,\n minAppVersion: { [ETHEREUM_APP_NAME]: MIN_ETHEREUM_APP_VERSION },\n },\n};\n\n/**\n * Resolve the Contacts version requirements for a device model \u2014 i.e. the\n * minimum supported OS and app versions, or that the model is unsupported.\n */\nexport function resolveContactsVersionRequirements(\n deviceModelId: DeviceModelId,\n): ContactsModelRequirement {\n return CONTACTS_VERSION_REQUIREMENTS[deviceModelId];\n}\n\n/**\n * Whether `actual` is greater than or equal to `minimum`, comparing as semver.\n * Tolerant of non-strict version strings and prerelease/build tags (coerces\n * both sides, which drops them) so a release candidate such as `1.7.0-rc2`\n * counts as meeting a `1.7.0` minimum. Returns `false` (i.e. requirement not\n * met) when either version cannot be parsed, so an unknown version never\n * passes a check.\n */\nexport function isVersionAtLeast(actual: string, minimum: string): boolean {\n const a = valid(coerce(actual));\n const b = valid(coerce(minimum));\n if (a === null || b === null) return false;\n return gte(a, b);\n}\n"],
5
+ "mappings": "AAAA,OAAS,iBAAAA,MAAqB,kCAC9B,OAAS,UAAAC,EAAQ,OAAAC,EAAK,SAAAC,MAAa,SAwC5B,MAAMC,EAAoB,WAE3BC,EAAwC,CAAE,UAAW,EAAM,EAE3DC,EAAsB,SACtBC,EAAsB,QACtBC,EAAsB,QACtBC,EAAwB,QACxBC,EAAyB,QAEzBC,EAA2B,SAMpBC,EAA6D,CACxE,CAACZ,EAAc,MAAM,EAAGK,EACxB,CAACL,EAAc,OAAO,EAAG,CACvB,UAAW,GACX,aAAcU,EACd,cAAe,CAAE,CAACN,CAAiB,EAAGO,CAAyB,CACjE,EACA,CAACX,EAAc,MAAM,EAAG,CACtB,UAAW,GACX,aAAcS,EACd,cAAe,CAAE,CAACL,CAAiB,EAAGO,CAAyB,CACjE,EACA,CAACX,EAAc,IAAI,EAAG,CACpB,UAAW,GACX,aAAcM,EACd,cAAe,CAAE,CAACF,CAAiB,EAAGO,CAAyB,CACjE,EACA,CAACX,EAAc,IAAI,EAAG,CACpB,UAAW,GACX,aAAcO,EACd,cAAe,CAAE,CAACH,CAAiB,EAAGO,CAAyB,CACjE,EACA,CAACX,EAAc,IAAI,EAAG,CACpB,UAAW,GACX,aAAcQ,EACd,cAAe,CAAE,CAACJ,CAAiB,EAAGO,CAAyB,CACjE,CACF,EAMO,SAASE,EACdC,EAC0B,CAC1B,OAAOF,EAA8BE,CAAa,CACpD,CAUO,SAASC,EAAiBC,EAAgBC,EAA0B,CACzE,MAAMC,EAAIf,EAAMF,EAAOe,CAAM,CAAC,EACxBG,EAAIhB,EAAMF,EAAOgB,CAAO,CAAC,EAC/B,OAAIC,IAAM,MAAQC,IAAM,KAAa,GAC9BjB,EAAIgB,EAAGC,CAAC,CACjB",
6
+ "names": ["DeviceModelId", "coerce", "gte", "valid", "ETHEREUM_APP_NAME", "UNSUPPORTED", "MIN_OS_VERSION_STAX", "MIN_OS_VERSION_FLEX", "MIN_OS_VERSION_APEX", "MIN_OS_VERSION_NANO_X", "MIN_OS_VERSION_NANO_SP", "MIN_ETHEREUM_APP_VERSION", "CONTACTS_VERSION_REQUIREMENTS", "resolveContactsVersionRequirements", "deviceModelId", "isVersionAtLeast", "actual", "minimum", "a", "b"]
7
7
  }
@@ -1,2 +1,2 @@
1
- import{DeviceModelId as t}from"@ledgerhq/device-management-kit";import{CONTACTS_VERSION_REQUIREMENTS as l,ETHEREUM_APP_NAME as p,isContactsSupported as s,isVersionAtLeast as n,resolveContactsVersionRequirements as u}from"./ContactsVersionRequirements";const d="0.0.1",c="999.0.0";function r(e){const o=u(e);if(!o.supported)throw new Error(`expected ${e} to be supported in the test fixture`);return o}function i(e){const o=e.minAppVersion[p];if(o===void 0)throw new Error("expected an Ethereum minimum app version in the fixture");return o}describe("ContactsVersionRequirements",()=>{describe("resolveContactsVersionRequirements",()=>{it("marks every device model, supported or not",()=>{for(const e of Object.values(t))expect(l[e]).toBeDefined()}),it("reports Nano models as unsupported",()=>{expect(u(t.NANO_S)).toEqual({supported:!1}),expect(u(t.NANO_X)).toEqual({supported:!1})}),it("reports touchscreen models as supported with OS and app minimums",()=>{const e=r(t.FLEX);expect(e.minOsVersion).toEqual(expect.any(String)),expect(i(e)).toEqual(expect.any(String))})}),describe("isContactsSupported",()=>{it("returns false for an unsupported device model",()=>{const e=r(t.FLEX);expect(s({deviceModelId:t.NANO_S,osVersion:c,appName:p,appVersion:i(e)})).toBe(!1)}),it("gates on the minimum app version",()=>{const e=r(t.FLEX),o=i(e),a={deviceModelId:t.FLEX,osVersion:e.minOsVersion,appName:p};expect(s({...a,appVersion:d})).toBe(!1),expect(s({...a,appVersion:o})).toBe(!0),expect(s({...a,appVersion:c})).toBe(!0)}),it("returns false for an app that is unknown to Contacts",()=>{const e=r(t.FLEX);expect(s({deviceModelId:t.FLEX,osVersion:e.minOsVersion,appName:"Bitcoin",appVersion:c})).toBe(!1)}),it("gates on the minimum OS version",()=>{const e=r(t.FLEX),o={deviceModelId:t.FLEX,appName:p,appVersion:i(e)};expect(s({...o,osVersion:d})).toBe(!1),expect(s({...o,osVersion:e.minOsVersion})).toBe(!0)})}),describe("isVersionAtLeast",()=>{it("compares versions as semver, inclusive of equality",()=>{expect(n("1.2.0","1.2.0")).toBe(!0),expect(n("1.3.0","1.2.0")).toBe(!0),expect(n("1.1.9","1.2.0")).toBe(!1)}),it("coerces non-strict version strings",()=>{expect(n("1.2","1.2.0")).toBe(!0)}),it("returns false when a version cannot be parsed",()=>{expect(n("not-a-version","1.2.0")).toBe(!1),expect(n("1.2.0","not-a-version")).toBe(!1)})})});
1
+ import{DeviceModelId as t}from"@ledgerhq/device-management-kit";import{CONTACTS_VERSION_REQUIREMENTS as o,ETHEREUM_APP_NAME as r,isVersionAtLeast as e,resolveContactsVersionRequirements as i}from"./ContactsVersionRequirements";describe("ContactsVersionRequirements",()=>{describe("resolveContactsVersionRequirements",()=>{it("marks every device model, supported or not",()=>{for(const s of Object.values(t))expect(o[s]).toBeDefined()}),it("reports Nano S as unsupported",()=>{expect(i(t.NANO_S)).toEqual({supported:!1})}),it("pins the minimum OS and app versions of every supported model",()=>{const s={[r]:"1.23.0"};expect(o).toEqual({[t.NANO_S]:{supported:!1},[t.NANO_SP]:{supported:!0,minOsVersion:"1.7.0",minAppVersion:s},[t.NANO_X]:{supported:!0,minOsVersion:"2.8.0",minAppVersion:s},[t.STAX]:{supported:!0,minOsVersion:"1.11.0",minAppVersion:s},[t.FLEX]:{supported:!0,minOsVersion:"1.7.0",minAppVersion:s},[t.APEX]:{supported:!0,minOsVersion:"1.2.0",minAppVersion:s}})})}),describe("isVersionAtLeast",()=>{it("compares versions as semver, inclusive of equality",()=>{expect(e("1.2.0","1.2.0")).toBe(!0),expect(e("1.3.0","1.2.0")).toBe(!0),expect(e("1.1.9","1.2.0")).toBe(!1)}),it("coerces non-strict version strings",()=>{expect(e("1.2","1.2.0")).toBe(!0)}),it("returns false when a version cannot be parsed",()=>{expect(e("not-a-version","1.2.0")).toBe(!1),expect(e("1.2.0","not-a-version")).toBe(!1)}),it("ignores prerelease and build tags when comparing to the minimum",()=>{expect(e("1.7.0-rc2","1.7.0")).toBe(!0),expect(e("1.23.0-dev","1.23.0")).toBe(!0)}),it("still fails a minimum strictly above the tagged version's core",()=>{expect(e("1.6.9-rc5","1.7.0")).toBe(!1)})})});
2
2
  //# sourceMappingURL=ContactsVersionRequirements.test.js.map
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "version": 3,
3
3
  "sources": ["../../../../src/api/model/ContactsVersionRequirements.test.ts"],
4
- "sourcesContent": ["import { DeviceModelId } from \"@ledgerhq/device-management-kit\";\n\nimport {\n CONTACTS_VERSION_REQUIREMENTS,\n type ContactsModelSupport,\n ETHEREUM_APP_NAME,\n isContactsSupported,\n isVersionAtLeast,\n resolveContactsVersionRequirements,\n} from \"./ContactsVersionRequirements\";\n\nconst BELOW_ANY_VERSION = \"0.0.1\";\nconst ABOVE_ANY_VERSION = \"999.0.0\";\n\nfunction supportOf(modelId: DeviceModelId): ContactsModelSupport {\n const requirement = resolveContactsVersionRequirements(modelId);\n if (!requirement.supported) {\n throw new Error(`expected ${modelId} to be supported in the test fixture`);\n }\n return requirement;\n}\n\nfunction ethAppVersionOf(support: ContactsModelSupport): string {\n const version = support.minAppVersion[ETHEREUM_APP_NAME];\n if (version === undefined) {\n throw new Error(\"expected an Ethereum minimum app version in the fixture\");\n }\n return version;\n}\n\ndescribe(\"ContactsVersionRequirements\", () => {\n describe(\"resolveContactsVersionRequirements\", () => {\n it(\"marks every device model, supported or not\", () => {\n for (const modelId of Object.values(DeviceModelId)) {\n expect(CONTACTS_VERSION_REQUIREMENTS[modelId]).toBeDefined();\n }\n });\n\n it(\"reports Nano models as unsupported\", () => {\n expect(resolveContactsVersionRequirements(DeviceModelId.NANO_S)).toEqual({\n supported: false,\n });\n expect(resolveContactsVersionRequirements(DeviceModelId.NANO_X)).toEqual({\n supported: false,\n });\n });\n\n it(\"reports touchscreen models as supported with OS and app minimums\", () => {\n const flex = supportOf(DeviceModelId.FLEX);\n expect(flex.minOsVersion).toEqual(expect.any(String));\n expect(ethAppVersionOf(flex)).toEqual(expect.any(String));\n });\n });\n\n describe(\"isContactsSupported\", () => {\n it(\"returns false for an unsupported device model\", () => {\n const flex = supportOf(DeviceModelId.FLEX);\n expect(\n isContactsSupported({\n deviceModelId: DeviceModelId.NANO_S,\n osVersion: ABOVE_ANY_VERSION,\n appName: ETHEREUM_APP_NAME,\n appVersion: ethAppVersionOf(flex),\n }),\n ).toBe(false);\n });\n\n // App-version requirement.\n it(\"gates on the minimum app version\", () => {\n const flex = supportOf(DeviceModelId.FLEX);\n const minAppVersion = ethAppVersionOf(flex);\n const base = {\n deviceModelId: DeviceModelId.FLEX,\n osVersion: flex.minOsVersion,\n appName: ETHEREUM_APP_NAME,\n };\n\n expect(\n isContactsSupported({ ...base, appVersion: BELOW_ANY_VERSION }),\n ).toBe(false);\n expect(isContactsSupported({ ...base, appVersion: minAppVersion })).toBe(\n true,\n );\n expect(\n isContactsSupported({ ...base, appVersion: ABOVE_ANY_VERSION }),\n ).toBe(true);\n });\n\n it(\"returns false for an app that is unknown to Contacts\", () => {\n const flex = supportOf(DeviceModelId.FLEX);\n expect(\n isContactsSupported({\n deviceModelId: DeviceModelId.FLEX,\n osVersion: flex.minOsVersion,\n appName: \"Bitcoin\",\n appVersion: ABOVE_ANY_VERSION,\n }),\n ).toBe(false);\n });\n\n // OS-version requirement.\n it(\"gates on the minimum OS version\", () => {\n const flex = supportOf(DeviceModelId.FLEX);\n const base = {\n deviceModelId: DeviceModelId.FLEX,\n appName: ETHEREUM_APP_NAME,\n appVersion: ethAppVersionOf(flex),\n };\n\n expect(\n isContactsSupported({ ...base, osVersion: BELOW_ANY_VERSION }),\n ).toBe(false);\n expect(\n isContactsSupported({ ...base, osVersion: flex.minOsVersion }),\n ).toBe(true);\n });\n });\n\n describe(\"isVersionAtLeast\", () => {\n it(\"compares versions as semver, inclusive of equality\", () => {\n expect(isVersionAtLeast(\"1.2.0\", \"1.2.0\")).toBe(true);\n expect(isVersionAtLeast(\"1.3.0\", \"1.2.0\")).toBe(true);\n expect(isVersionAtLeast(\"1.1.9\", \"1.2.0\")).toBe(false);\n });\n\n it(\"coerces non-strict version strings\", () => {\n expect(isVersionAtLeast(\"1.2\", \"1.2.0\")).toBe(true);\n });\n\n it(\"returns false when a version cannot be parsed\", () => {\n expect(isVersionAtLeast(\"not-a-version\", \"1.2.0\")).toBe(false);\n expect(isVersionAtLeast(\"1.2.0\", \"not-a-version\")).toBe(false);\n });\n });\n});\n"],
5
- "mappings": "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",
6
- "names": ["DeviceModelId", "CONTACTS_VERSION_REQUIREMENTS", "ETHEREUM_APP_NAME", "isContactsSupported", "isVersionAtLeast", "resolveContactsVersionRequirements", "BELOW_ANY_VERSION", "ABOVE_ANY_VERSION", "supportOf", "modelId", "requirement", "ethAppVersionOf", "support", "version", "flex", "minAppVersion", "base"]
4
+ "sourcesContent": ["import { DeviceModelId } from \"@ledgerhq/device-management-kit\";\n\nimport {\n CONTACTS_VERSION_REQUIREMENTS,\n ETHEREUM_APP_NAME,\n isVersionAtLeast,\n resolveContactsVersionRequirements,\n} from \"./ContactsVersionRequirements\";\n\ndescribe(\"ContactsVersionRequirements\", () => {\n describe(\"resolveContactsVersionRequirements\", () => {\n it(\"marks every device model, supported or not\", () => {\n for (const modelId of Object.values(DeviceModelId)) {\n expect(CONTACTS_VERSION_REQUIREMENTS[modelId]).toBeDefined();\n }\n });\n\n it(\"reports Nano S as unsupported\", () => {\n expect(resolveContactsVersionRequirements(DeviceModelId.NANO_S)).toEqual({\n supported: false,\n });\n });\n\n // Pins the minimums themselves, not just their shape: each OS version is\n // the release whose changelog introduces the Address Book feature, so a\n // change here has to be a deliberate one, reviewed against that release.\n it(\"pins the minimum OS and app versions of every supported model\", () => {\n const ethereum = { [ETHEREUM_APP_NAME]: \"1.23.0\" };\n\n expect(CONTACTS_VERSION_REQUIREMENTS).toEqual({\n [DeviceModelId.NANO_S]: { supported: false },\n [DeviceModelId.NANO_SP]: {\n supported: true,\n minOsVersion: \"1.7.0\",\n minAppVersion: ethereum,\n },\n [DeviceModelId.NANO_X]: {\n supported: true,\n minOsVersion: \"2.8.0\",\n minAppVersion: ethereum,\n },\n [DeviceModelId.STAX]: {\n supported: true,\n minOsVersion: \"1.11.0\",\n minAppVersion: ethereum,\n },\n [DeviceModelId.FLEX]: {\n supported: true,\n minOsVersion: \"1.7.0\",\n minAppVersion: ethereum,\n },\n [DeviceModelId.APEX]: {\n supported: true,\n minOsVersion: \"1.2.0\",\n minAppVersion: ethereum,\n },\n });\n });\n });\n\n describe(\"isVersionAtLeast\", () => {\n it(\"compares versions as semver, inclusive of equality\", () => {\n expect(isVersionAtLeast(\"1.2.0\", \"1.2.0\")).toBe(true);\n expect(isVersionAtLeast(\"1.3.0\", \"1.2.0\")).toBe(true);\n expect(isVersionAtLeast(\"1.1.9\", \"1.2.0\")).toBe(false);\n });\n\n it(\"coerces non-strict version strings\", () => {\n expect(isVersionAtLeast(\"1.2\", \"1.2.0\")).toBe(true);\n });\n\n it(\"returns false when a version cannot be parsed\", () => {\n expect(isVersionAtLeast(\"not-a-version\", \"1.2.0\")).toBe(false);\n expect(isVersionAtLeast(\"1.2.0\", \"not-a-version\")).toBe(false);\n });\n\n it(\"ignores prerelease and build tags when comparing to the minimum\", () => {\n expect(isVersionAtLeast(\"1.7.0-rc2\", \"1.7.0\")).toBe(true);\n expect(isVersionAtLeast(\"1.23.0-dev\", \"1.23.0\")).toBe(true);\n });\n\n it(\"still fails a minimum strictly above the tagged version's core\", () => {\n expect(isVersionAtLeast(\"1.6.9-rc5\", \"1.7.0\")).toBe(false);\n });\n });\n});\n"],
5
+ "mappings": "AAAA,OAAS,iBAAAA,MAAqB,kCAE9B,OACE,iCAAAC,EACA,qBAAAC,EACA,oBAAAC,EACA,sCAAAC,MACK,gCAEP,SAAS,8BAA+B,IAAM,CAC5C,SAAS,qCAAsC,IAAM,CACnD,GAAG,6CAA8C,IAAM,CACrD,UAAWC,KAAW,OAAO,OAAOL,CAAa,EAC/C,OAAOC,EAA8BI,CAAO,CAAC,EAAE,YAAY,CAE/D,CAAC,EAED,GAAG,gCAAiC,IAAM,CACxC,OAAOD,EAAmCJ,EAAc,MAAM,CAAC,EAAE,QAAQ,CACvE,UAAW,EACb,CAAC,CACH,CAAC,EAKD,GAAG,gEAAiE,IAAM,CACxE,MAAMM,EAAW,CAAE,CAACJ,CAAiB,EAAG,QAAS,EAEjD,OAAOD,CAA6B,EAAE,QAAQ,CAC5C,CAACD,EAAc,MAAM,EAAG,CAAE,UAAW,EAAM,EAC3C,CAACA,EAAc,OAAO,EAAG,CACvB,UAAW,GACX,aAAc,QACd,cAAeM,CACjB,EACA,CAACN,EAAc,MAAM,EAAG,CACtB,UAAW,GACX,aAAc,QACd,cAAeM,CACjB,EACA,CAACN,EAAc,IAAI,EAAG,CACpB,UAAW,GACX,aAAc,SACd,cAAeM,CACjB,EACA,CAACN,EAAc,IAAI,EAAG,CACpB,UAAW,GACX,aAAc,QACd,cAAeM,CACjB,EACA,CAACN,EAAc,IAAI,EAAG,CACpB,UAAW,GACX,aAAc,QACd,cAAeM,CACjB,CACF,CAAC,CACH,CAAC,CACH,CAAC,EAED,SAAS,mBAAoB,IAAM,CACjC,GAAG,qDAAsD,IAAM,CAC7D,OAAOH,EAAiB,QAAS,OAAO,CAAC,EAAE,KAAK,EAAI,EACpD,OAAOA,EAAiB,QAAS,OAAO,CAAC,EAAE,KAAK,EAAI,EACpD,OAAOA,EAAiB,QAAS,OAAO,CAAC,EAAE,KAAK,EAAK,CACvD,CAAC,EAED,GAAG,qCAAsC,IAAM,CAC7C,OAAOA,EAAiB,MAAO,OAAO,CAAC,EAAE,KAAK,EAAI,CACpD,CAAC,EAED,GAAG,gDAAiD,IAAM,CACxD,OAAOA,EAAiB,gBAAiB,OAAO,CAAC,EAAE,KAAK,EAAK,EAC7D,OAAOA,EAAiB,QAAS,eAAe,CAAC,EAAE,KAAK,EAAK,CAC/D,CAAC,EAED,GAAG,kEAAmE,IAAM,CAC1E,OAAOA,EAAiB,YAAa,OAAO,CAAC,EAAE,KAAK,EAAI,EACxD,OAAOA,EAAiB,aAAc,QAAQ,CAAC,EAAE,KAAK,EAAI,CAC5D,CAAC,EAED,GAAG,iEAAkE,IAAM,CACzE,OAAOA,EAAiB,YAAa,OAAO,CAAC,EAAE,KAAK,EAAK,CAC3D,CAAC,CACH,CAAC,CACH,CAAC",
6
+ "names": ["DeviceModelId", "CONTACTS_VERSION_REQUIREMENTS", "ETHEREUM_APP_NAME", "isVersionAtLeast", "resolveContactsVersionRequirements", "modelId", "ethereum"]
7
7
  }
@@ -0,0 +1 @@
1
+ //# sourceMappingURL=ProvideContact.js.map
@@ -0,0 +1,7 @@
1
+ {
2
+ "version": 3,
3
+ "sources": [],
4
+ "sourcesContent": [],
5
+ "mappings": "",
6
+ "names": []
7
+ }
@@ -0,0 +1,2 @@
1
+ import{ApduBuilder as r,CommandResultFactory as e}from"@ledgerhq/device-management-kit";import{CommandErrorHelper as t}from"@ledgerhq/signer-utils";import{Maybe as a}from"purify-ts";import{CONTACTS_APDU_CLA as n,CONTACTS_APDU_INS as d,SUB_CMD_PROVIDE_CONTACT as m}from"../../app-binder/model/contactsConstants";import{CONTACTS_APP_ERRORS as s,contactsCommandErrorFactory as C}from"../../app-binder/model/contactsErrors";class y{name="provideContact";args;errorHelper=new t(s,C);constructor(o){this.args=o}getApdu(){return new r({cla:n,ins:d,p1:m,p2:this.args.p2}).addBufferToData(this.args.data).build()}parseResponse(o){return a.fromNullable(this.errorHelper.getError(o)).orDefaultLazy(()=>e({data:void 0}))}}export{y as ProvideContactCommand};
2
+ //# sourceMappingURL=ProvideContactCommand.js.map
@@ -0,0 +1,7 @@
1
+ {
2
+ "version": 3,
3
+ "sources": ["../../../../../src/internal/app-binder/command/ProvideContactCommand.ts"],
4
+ "sourcesContent": ["// Provide Contact \u2014 sub-command P1=0x20 of the address-book APDU (CLA 0xB0 /\n// INS 0x10). Sent before a signing APDU so the device renders a registered\n// contact name in place of the raw recipient address. Caller\n// (sendProvideContactPayload) assembles the TLV, prepends the 2-byte BE total\n// length and slices into <=255B chunks; this command frames one chunk. Every\n// chunk answers with SW=0x9000 and no data \u2014 the outcome is a device-side\n// effect, not a returned value.\n// Protocol: Address Book Final Specifications \u2014 Provide Contact.\nimport {\n type Apdu,\n ApduBuilder,\n type ApduResponse,\n type Command,\n type CommandResult,\n CommandResultFactory,\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 SUB_CMD_PROVIDE_CONTACT,\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 ProvideContactCommandArgs = {\n /** One framed chunk built by sendProvideContactPayload. */\n readonly data: Uint8Array;\n /** 0x00 for the first/only chunk, 0x80 for continuation chunks. */\n readonly p2: number;\n};\n\nexport type ProvideContactCommandResponse = void;\n\nexport class ProvideContactCommand\n implements\n Command<\n ProvideContactCommandResponse,\n ProvideContactCommandArgs,\n ContactsErrorCodes\n >\n{\n readonly name = \"provideContact\";\n readonly args: ProvideContactCommandArgs;\n private readonly errorHelper = new CommandErrorHelper<\n ProvideContactCommandResponse,\n ContactsErrorCodes\n >(CONTACTS_APP_ERRORS, contactsCommandErrorFactory);\n\n constructor(args: ProvideContactCommandArgs) {\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_PROVIDE_CONTACT,\n p2: this.args.p2,\n })\n .addBufferToData(this.args.data)\n .build();\n }\n\n parseResponse(\n response: ApduResponse,\n ): CommandResult<ProvideContactCommandResponse, ContactsErrorCodes> {\n return Maybe.fromNullable(\n this.errorHelper.getError(response),\n ).orDefaultLazy(() =>\n CommandResultFactory<ProvideContactCommandResponse, ContactsErrorCodes>({\n data: undefined,\n }),\n );\n }\n}\n"],
5
+ "mappings": "AAQA,OAEE,eAAAA,EAIA,wBAAAC,MACK,kCACP,OAAS,sBAAAC,MAA0B,yBACnC,OAAS,SAAAC,MAAa,YAEtB,OACE,qBAAAC,EACA,qBAAAC,EACA,2BAAAC,MACK,+CACP,OACE,uBAAAC,EACA,+BAAAC,MAEK,4CAWA,MAAMC,CAOb,CACW,KAAO,iBACP,KACQ,YAAc,IAAIP,EAGjCK,EAAqBC,CAA2B,EAElD,YAAYE,EAAiC,CAC3C,KAAK,KAAOA,CACd,CAEA,SAAgB,CACd,OAAO,IAAIV,EAAY,CACrB,IAAKI,EACL,IAAKC,EACL,GAAIC,EACJ,GAAI,KAAK,KAAK,EAChB,CAAC,EACE,gBAAgB,KAAK,KAAK,IAAI,EAC9B,MAAM,CACX,CAEA,cACEK,EACkE,CAClE,OAAOR,EAAM,aACX,KAAK,YAAY,SAASQ,CAAQ,CACpC,EAAE,cAAc,IACdV,EAAwE,CACtE,KAAM,MACR,CAAC,CACH,CACF,CACF",
6
+ "names": ["ApduBuilder", "CommandResultFactory", "CommandErrorHelper", "Maybe", "CONTACTS_APDU_CLA", "CONTACTS_APDU_INS", "SUB_CMD_PROVIDE_CONTACT", "CONTACTS_APP_ERRORS", "contactsCommandErrorFactory", "ProvideContactCommand", "args", "response"]
7
+ }
@@ -0,0 +1,2 @@
1
+ import{CommandResultStatus as r}from"@ledgerhq/device-management-kit";import{CONTACT_SEED_MISMATCH_ERROR_CODE as o,ContactsCommandError as s}from"../../app-binder/model/contactsErrors";import{ProvideContactCommand as e}from"./ProvideContactCommand";describe("ProvideContactCommand",()=>{describe("getApdu",()=>{it("wraps the framed chunk under B0 10 20 with P2=0x00 for the first/only chunk",()=>{const t=Uint8Array.from([0,3,170,187,204]),a=new e({data:t,p2:0}).getApdu();expect(a.getRawApdu()).toStrictEqual(Uint8Array.from([176,16,32,0,5,0,3,170,187,204]))}),it("uses P2=0x80 for continuation chunks",()=>{const t=Uint8Array.from([170,187]),a=new e({data:t,p2:128}).getApdu();expect(a.getRawApdu()).toStrictEqual(Uint8Array.from([176,16,32,128,2,170,187]))})}),describe("parseResponse",()=>{it("succeeds with no data on SW=0x9000",()=>{const t=new e({data:new Uint8Array,p2:0}).parseResponse({data:Buffer.from([]),statusCode:Buffer.from([144,0])});expect(t).toStrictEqual({status:r.Success,data:void 0})}),it("maps SW=0x6982 to a seed-mismatch ContactsCommandError",()=>{const t=new e({data:new Uint8Array,p2:0}).parseResponse({data:Buffer.from([]),statusCode:Buffer.from([105,130])});expect(t.status).toBe(r.Error),t.status===r.Error&&(expect(t.error).toBeInstanceOf(s),expect(t.error.errorCode).toBe(o))}),it("maps SW=0x6a80 to a ContactsCommandError",()=>{const t=new e({data:new Uint8Array,p2:0}).parseResponse({data:Buffer.from([]),statusCode:Buffer.from([106,128])});expect(t.status).toBe(r.Error),t.status===r.Error&&expect(t.error.errorCode).toBe("6a80")})})});
2
+ //# sourceMappingURL=ProvideContactCommand.test.js.map
@@ -0,0 +1,7 @@
1
+ {
2
+ "version": 3,
3
+ "sources": ["../../../../../src/internal/app-binder/command/ProvideContactCommand.test.ts"],
4
+ "sourcesContent": ["import { CommandResultStatus } from \"@ledgerhq/device-management-kit\";\n\nimport {\n CONTACT_SEED_MISMATCH_ERROR_CODE,\n ContactsCommandError,\n} from \"@internal/app-binder/model/contactsErrors\";\n\nimport { ProvideContactCommand } from \"./ProvideContactCommand\";\n\ndescribe(\"ProvideContactCommand\", () => {\n describe(\"getApdu\", () => {\n it(\"wraps the framed chunk under B0 10 20 with P2=0x00 for the first/only chunk\", () => {\n const data = Uint8Array.from([0x00, 0x03, 0xaa, 0xbb, 0xcc]);\n\n const apdu = new ProvideContactCommand({ data, p2: 0x00 }).getApdu();\n\n expect(apdu.getRawApdu()).toStrictEqual(\n Uint8Array.from([\n 0xb0, 0x10, 0x20, 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 ProvideContactCommand({ data, p2: 0x80 }).getApdu();\n\n expect(apdu.getRawApdu()).toStrictEqual(\n Uint8Array.from([0xb0, 0x10, 0x20, 0x80, 0x02, 0xaa, 0xbb]),\n );\n });\n });\n\n describe(\"parseResponse\", () => {\n it(\"succeeds with no data on SW=0x9000\", () => {\n const result = new ProvideContactCommand({\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: undefined,\n });\n });\n\n it(\"maps SW=0x6982 to a seed-mismatch ContactsCommandError\", () => {\n const result = new ProvideContactCommand({\n data: new Uint8Array(),\n p2: 0x00,\n }).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 it(\"maps SW=0x6a80 to a ContactsCommandError\", () => {\n const result = new ProvideContactCommand({\n data: new Uint8Array(),\n p2: 0x00,\n }).parseResponse({\n data: Buffer.from([]),\n statusCode: Buffer.from([0x6a, 0x80]),\n });\n\n expect(result.status).toBe(CommandResultStatus.Error);\n if (result.status === CommandResultStatus.Error) {\n expect((result.error as ContactsCommandError).errorCode).toBe(\"6a80\");\n }\n });\n });\n});\n"],
5
+ "mappings": "AAAA,OAAS,uBAAAA,MAA2B,kCAEpC,OACE,oCAAAC,EACA,wBAAAC,MACK,4CAEP,OAAS,yBAAAC,MAA6B,0BAEtC,SAAS,wBAAyB,IAAM,CACtC,SAAS,UAAW,IAAM,CACxB,GAAG,8EAA+E,IAAM,CACtF,MAAMC,EAAO,WAAW,KAAK,CAAC,EAAM,EAAM,IAAM,IAAM,GAAI,CAAC,EAErDC,EAAO,IAAIF,EAAsB,CAAE,KAAAC,EAAM,GAAI,CAAK,CAAC,EAAE,QAAQ,EAEnE,OAAOC,EAAK,WAAW,CAAC,EAAE,cACxB,WAAW,KAAK,CACd,IAAM,GAAM,GAAM,EAAM,EAAM,EAAM,EAAM,IAAM,IAAM,GACxD,CAAC,CACH,CACF,CAAC,EAED,GAAG,uCAAwC,IAAM,CAC/C,MAAMD,EAAO,WAAW,KAAK,CAAC,IAAM,GAAI,CAAC,EAEnCC,EAAO,IAAIF,EAAsB,CAAE,KAAAC,EAAM,GAAI,GAAK,CAAC,EAAE,QAAQ,EAEnE,OAAOC,EAAK,WAAW,CAAC,EAAE,cACxB,WAAW,KAAK,CAAC,IAAM,GAAM,GAAM,IAAM,EAAM,IAAM,GAAI,CAAC,CAC5D,CACF,CAAC,CACH,CAAC,EAED,SAAS,gBAAiB,IAAM,CAC9B,GAAG,qCAAsC,IAAM,CAC7C,MAAMC,EAAS,IAAIH,EAAsB,CACvC,KAAM,IAAI,WACV,GAAI,CACN,CAAC,EAAE,cAAc,CACf,KAAM,OAAO,KAAK,CAAC,CAAC,EACpB,WAAY,OAAO,KAAK,CAAC,IAAM,CAAI,CAAC,CACtC,CAAC,EAED,OAAOG,CAAM,EAAE,cAAc,CAC3B,OAAQN,EAAoB,QAC5B,KAAM,MACR,CAAC,CACH,CAAC,EAED,GAAG,yDAA0D,IAAM,CACjE,MAAMM,EAAS,IAAIH,EAAsB,CACvC,KAAM,IAAI,WACV,GAAI,CACN,CAAC,EAAE,cAAc,CACf,KAAM,OAAO,KAAK,CAAC,CAAC,EACpB,WAAY,OAAO,KAAK,CAAC,IAAM,GAAI,CAAC,CACtC,CAAC,EAED,OAAOG,EAAO,MAAM,EAAE,KAAKN,EAAoB,KAAK,EAChDM,EAAO,SAAWN,EAAoB,QACxC,OAAOM,EAAO,KAAK,EAAE,eAAeJ,CAAoB,EACxD,OAAQI,EAAO,MAA+B,SAAS,EAAE,KACvDL,CACF,EAEJ,CAAC,EAED,GAAG,2CAA4C,IAAM,CACnD,MAAMK,EAAS,IAAIH,EAAsB,CACvC,KAAM,IAAI,WACV,GAAI,CACN,CAAC,EAAE,cAAc,CACf,KAAM,OAAO,KAAK,CAAC,CAAC,EACpB,WAAY,OAAO,KAAK,CAAC,IAAM,GAAI,CAAC,CACtC,CAAC,EAED,OAAOG,EAAO,MAAM,EAAE,KAAKN,EAAoB,KAAK,EAChDM,EAAO,SAAWN,EAAoB,OACxC,OAAQM,EAAO,MAA+B,SAAS,EAAE,KAAK,MAAM,CAExE,CAAC,CACH,CAAC,CACH,CAAC",
6
+ "names": ["CommandResultStatus", "CONTACT_SEED_MISMATCH_ERROR_CODE", "ContactsCommandError", "ProvideContactCommand", "data", "apdu", "result"]
7
+ }
@@ -0,0 +1,2 @@
1
+ import{ApplicationChecker as p}from"@ledgerhq/device-management-kit";import{isVersionAtLeast as c,resolveContactsVersionRequirements as i}from"../../api/model/ContactsVersionRequirements";import{ContactsApplicationResolver as a}from"./ContactsApplicationResolver";function s(n){return n.supported}function f(n){const e=n.getDeviceSessionState(),t=i(e.deviceModelId);if(!s(t))return!1;const o="firmwareVersion"in e?e.firmwareVersion?.os:void 0;return o===void 0?!1:c(o,t.minOsVersion)}function m(n,e){const t=n.getDeviceSessionState(),o=i(t.deviceModelId);if(!s(o))return!1;const r=o.minAppVersion[e.name];return r===void 0?!1:new p(t,{version:e.version},new a).withMinVersionInclusiveAcceptingPrerelease(r).check()}export{m as isContactsAppVersionSupportedForSession,f as isContactsOsSupportedForSession};
2
+ //# sourceMappingURL=contactsVersionGuards.js.map
@@ -0,0 +1,7 @@
1
+ {
2
+ "version": 3,
3
+ "sources": ["../../../../src/internal/app-binder/contactsVersionGuards.ts"],
4
+ "sourcesContent": ["import {\n ApplicationChecker,\n type InternalApi,\n} from \"@ledgerhq/device-management-kit\";\n\nimport {\n type ContactsModelRequirement,\n type ContactsModelSupport,\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/** Narrows a resolved requirement to the case where Contacts is supported at all on this device model. */\nfunction isContactsModelSupported(\n requirement: ContactsModelRequirement,\n): requirement is ContactsModelSupport {\n return requirement.supported;\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).\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 (!isContactsModelSupported(requirement)) 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 * Session-aware Contacts support check, for internal consumption by app-owned\n * Contacts `DeviceAction`s (registering / editing external addresses). These\n * operations are served by the embedded app, not the device OS, so only two\n * dimensions apply:\n * - the device model must be supported;\n * - the running app must be known to Contacts and meet its minimum version.\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 comes from the session state, which does\n * 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 isContactsAppVersionSupportedForSession(\n internalApi: InternalApi,\n app: RunningApp,\n): boolean {\n const deviceState = internalApi.getDeviceSessionState();\n const requirement = resolveContactsVersionRequirements(\n deviceState.deviceModelId,\n );\n if (!isContactsModelSupported(requirement)) return false;\n\n const minAppVersion = requirement.minAppVersion[app.name];\n if (minAppVersion === undefined) return false;\n\n return new ApplicationChecker(\n deviceState,\n { version: app.version },\n new ContactsApplicationResolver(),\n )\n .withMinVersionInclusiveAcceptingPrerelease(minAppVersion)\n .check();\n}\n"],
5
+ "mappings": "AAAA,OACE,sBAAAA,MAEK,kCAEP,OAGE,oBAAAC,EACA,sCAAAC,MACK,yCAEP,OAAS,+BAAAC,MAAmC,gCAS5C,SAASC,EACPC,EACqC,CACrC,OAAOA,EAAY,SACrB,CAeO,SAASC,EACdC,EACS,CACT,MAAMC,EAAcD,EAAY,sBAAsB,EAChDF,EAAcH,EAClBM,EAAY,aACd,EACA,GAAI,CAACJ,EAAyBC,CAAW,EAAG,MAAO,GAEnD,MAAMI,EACJ,oBAAqBD,EACjBA,EAAY,iBAAiB,GAC7B,OACN,OAAIC,IAAc,OAAkB,GAE7BR,EAAiBQ,EAAWJ,EAAY,YAAY,CAC7D,CAkBO,SAASK,EACdH,EACAI,EACS,CACT,MAAMH,EAAcD,EAAY,sBAAsB,EAChDF,EAAcH,EAClBM,EAAY,aACd,EACA,GAAI,CAACJ,EAAyBC,CAAW,EAAG,MAAO,GAEnD,MAAMO,EAAgBP,EAAY,cAAcM,EAAI,IAAI,EACxD,OAAIC,IAAkB,OAAkB,GAEjC,IAAIZ,EACTQ,EACA,CAAE,QAASG,EAAI,OAAQ,EACvB,IAAIR,CACN,EACG,2CAA2CS,CAAa,EACxD,MAAM,CACX",
6
+ "names": ["ApplicationChecker", "isVersionAtLeast", "resolveContactsVersionRequirements", "ContactsApplicationResolver", "isContactsModelSupported", "requirement", "isContactsOsSupportedForSession", "internalApi", "deviceState", "osVersion", "isContactsAppVersionSupportedForSession", "app", "minAppVersion"]
7
+ }
@@ -0,0 +1,2 @@
1
+ import{DeviceModelId as r,DeviceSessionStateType as u,DeviceStatus as d}from"@ledgerhq/device-management-kit";import{ETHEREUM_APP_NAME as a,resolveContactsVersionRequirements as f}from"../../api/model/ContactsVersionRequirements";import{isContactsAppVersionSupportedForSession as s,isContactsOsSupportedForSession as i}from"./contactsVersionGuards";const l=(()=>{const e=f(r.FLEX);if(!e.supported)throw new Error("Flex must be supported");return e})(),m=l.minOsVersion,S=(()=>{const e=l.minAppVersion[a];if(e===void 0)throw new Error("Ethereum min version required");return e})(),p="0.0.1";function n({osVersion:e=m,modelId:c=r.FLEX}={}){return{sessionStateType:u.ReadyWithoutSecureChannel,deviceStatus:d.CONNECTED,installedApps:[],currentApp:{name:a,version:"0.0.0"},deviceModelId:c,firmwareVersion:{mcu:"1.0.0",bootloader:"1.0.0",os:e},isSecureConnectionAllowed:!1}}function t(e){return{getDeviceSessionState:()=>e}}function o(e=a,c=S){return{name:e,version:c}}describe("isContactsAppVersionSupportedForSession",()=>{it("returns true when the model and app version meet the minimums",()=>{const e=t(n());expect(s(e,o())).toBe(!0)}),it("returns true regardless of OS version, since app-owned operations are not gated by it",()=>{const e=t(n({osVersion:p}));expect(s(e,o())).toBe(!0)}),it("returns false on an unsupported device model",()=>{const e=t(n({modelId:r.NANO_S}));expect(s(e,o())).toBe(!1)}),it("returns false when the app version is below the minimum",()=>{const e=t(n());expect(s(e,o(a,p))).toBe(!1)}),it("returns false when the running app is unknown to Contacts",()=>{const e=t(n());expect(s(e,o("Bitcoin"))).toBe(!1)}),it("returns true for a prerelease build of the minimum app version",()=>{const e=t(n());expect(s(e,o(a,`${S}-rc2`))).toBe(!0)}),it("returns false when the device session has no running app",()=>{const e=t({sessionStateType:u.Connected,deviceStatus:d.CONNECTED,deviceModelId:r.FLEX});expect(s(e,o())).toBe(!1)})});describe("isContactsOsSupportedForSession",()=>{it("returns true when the model and OS version meet the minimums",()=>{const e=t(n());expect(i(e)).toBe(!0)}),it("returns false on an unsupported device model",()=>{const e=t(n({modelId:r.NANO_S}));expect(i(e)).toBe(!1)}),it("returns false when the OS version is below the minimum",()=>{const e=t(n({osVersion:p}));expect(i(e)).toBe(!1)}),it("returns true for a release candidate of the minimum OS version",()=>{const e=t(n({osVersion:`${m}-rc2`}));expect(i(e)).toBe(!0)}),it("returns false for a release candidate below the minimum OS version",()=>{const e=t(n({osVersion:`${p}-rc2`}));expect(i(e)).toBe(!1)}),it("returns false when the device session has no firmware version",()=>{const e=t({sessionStateType:u.Connected,deviceStatus:d.CONNECTED,deviceModelId:r.FLEX});expect(i(e)).toBe(!1)})});
2
+ //# sourceMappingURL=contactsVersionGuards.test.js.map
@@ -0,0 +1,7 @@
1
+ {
2
+ "version": 3,
3
+ "sources": ["../../../../src/internal/app-binder/contactsVersionGuards.test.ts"],
4
+ "sourcesContent": ["import {\n DeviceModelId,\n DeviceSessionStateType,\n DeviceStatus,\n type InternalApi,\n} from \"@ledgerhq/device-management-kit\";\n\nimport {\n ETHEREUM_APP_NAME,\n resolveContactsVersionRequirements,\n} from \"@api/model/ContactsVersionRequirements\";\n\nimport {\n isContactsAppVersionSupportedForSession,\n isContactsOsSupportedForSession,\n type RunningApp,\n} from \"./contactsVersionGuards\";\n\nconst flexSupport = (() => {\n const requirement = resolveContactsVersionRequirements(DeviceModelId.FLEX);\n if (!requirement.supported) throw new Error(\"Flex must be supported\");\n return requirement;\n})();\n\nconst MIN_OS_VERSION = flexSupport.minOsVersion;\nconst MIN_APP_VERSION = (() => {\n const version = flexSupport.minAppVersion[ETHEREUM_APP_NAME];\n if (version === undefined) throw new Error(\"Ethereum min version required\");\n return version;\n})();\nconst BELOW_ANY_VERSION = \"0.0.1\";\n\ntype ReadyStateOptions = {\n osVersion?: string;\n modelId?: DeviceModelId;\n};\n\nfunction createReadyState({\n osVersion = MIN_OS_VERSION,\n modelId = DeviceModelId.FLEX,\n}: ReadyStateOptions = {}) {\n return {\n sessionStateType: DeviceSessionStateType.ReadyWithoutSecureChannel,\n deviceStatus: DeviceStatus.CONNECTED,\n installedApps: [],\n currentApp: { name: ETHEREUM_APP_NAME, version: \"0.0.0\" },\n deviceModelId: modelId,\n firmwareVersion: { mcu: \"1.0.0\", bootloader: \"1.0.0\", os: osVersion },\n isSecureConnectionAllowed: false,\n };\n}\n\nfunction createInternalApi(deviceState: object): InternalApi {\n return {\n getDeviceSessionState: () => deviceState,\n } as unknown as InternalApi;\n}\n\n// The running app identity now comes from the caller (a fresh\n// WaitForAppAndVersion result), not the device session state.\nfunction runningApp(\n name = ETHEREUM_APP_NAME,\n version = MIN_APP_VERSION,\n): RunningApp {\n return { name, version };\n}\n\ndescribe(\"isContactsAppVersionSupportedForSession\", () => {\n it(\"returns true when the model and app version meet the minimums\", () => {\n const api = createInternalApi(createReadyState());\n expect(isContactsAppVersionSupportedForSession(api, runningApp())).toBe(\n true,\n );\n });\n\n it(\"returns true regardless of OS version, since app-owned operations are not gated by it\", () => {\n const api = createInternalApi(\n createReadyState({ osVersion: BELOW_ANY_VERSION }),\n );\n expect(isContactsAppVersionSupportedForSession(api, runningApp())).toBe(\n true,\n );\n });\n\n it(\"returns false on an unsupported device model\", () => {\n const api = createInternalApi(\n createReadyState({ modelId: DeviceModelId.NANO_S }),\n );\n expect(isContactsAppVersionSupportedForSession(api, runningApp())).toBe(\n false,\n );\n });\n\n it(\"returns false when the app version is below the minimum\", () => {\n const api = createInternalApi(createReadyState());\n expect(\n isContactsAppVersionSupportedForSession(\n api,\n runningApp(ETHEREUM_APP_NAME, BELOW_ANY_VERSION),\n ),\n ).toBe(false);\n });\n\n it(\"returns false when the running app is unknown to Contacts\", () => {\n const api = createInternalApi(createReadyState());\n expect(\n isContactsAppVersionSupportedForSession(api, runningApp(\"Bitcoin\")),\n ).toBe(false);\n });\n\n it(\"returns true for a prerelease build of the minimum app version\", () => {\n const api = createInternalApi(createReadyState());\n expect(\n isContactsAppVersionSupportedForSession(\n api,\n runningApp(ETHEREUM_APP_NAME, `${MIN_APP_VERSION}-rc2`),\n ),\n ).toBe(true);\n });\n\n it(\"returns false when the device session has no running app\", () => {\n const api = createInternalApi({\n sessionStateType: DeviceSessionStateType.Connected,\n deviceStatus: DeviceStatus.CONNECTED,\n deviceModelId: DeviceModelId.FLEX,\n });\n expect(isContactsAppVersionSupportedForSession(api, runningApp())).toBe(\n false,\n );\n });\n});\n\ndescribe(\"isContactsOsSupportedForSession\", () => {\n it(\"returns true when the model and OS version meet the minimums\", () => {\n const api = createInternalApi(createReadyState());\n expect(isContactsOsSupportedForSession(api)).toBe(true);\n });\n\n it(\"returns false on an unsupported device model\", () => {\n const api = createInternalApi(\n createReadyState({ modelId: DeviceModelId.NANO_S }),\n );\n expect(isContactsOsSupportedForSession(api)).toBe(false);\n });\n\n it(\"returns false when the OS version is below the minimum\", () => {\n const api = createInternalApi(\n createReadyState({ osVersion: BELOW_ANY_VERSION }),\n );\n expect(isContactsOsSupportedForSession(api)).toBe(false);\n });\n\n it(\"returns true for a release candidate of the minimum OS version\", () => {\n const api = createInternalApi(\n createReadyState({ osVersion: `${MIN_OS_VERSION}-rc2` }),\n );\n expect(isContactsOsSupportedForSession(api)).toBe(true);\n });\n\n it(\"returns false for a release candidate below the minimum OS version\", () => {\n const api = createInternalApi(\n createReadyState({ osVersion: `${BELOW_ANY_VERSION}-rc2` }),\n );\n expect(isContactsOsSupportedForSession(api)).toBe(false);\n });\n\n it(\"returns false when the device session has no firmware version\", () => {\n const api = createInternalApi({\n sessionStateType: DeviceSessionStateType.Connected,\n deviceStatus: DeviceStatus.CONNECTED,\n deviceModelId: DeviceModelId.FLEX,\n });\n expect(isContactsOsSupportedForSession(api)).toBe(false);\n });\n});\n"],
5
+ "mappings": "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",
6
+ "names": ["DeviceModelId", "DeviceSessionStateType", "DeviceStatus", "ETHEREUM_APP_NAME", "resolveContactsVersionRequirements", "isContactsAppVersionSupportedForSession", "isContactsOsSupportedForSession", "flexSupport", "requirement", "MIN_OS_VERSION", "MIN_APP_VERSION", "version", "BELOW_ANY_VERSION", "createReadyState", "osVersion", "modelId", "createInternalApi", "deviceState", "runningApp", "name", "api"]
7
+ }
@@ -1,2 +1,2 @@
1
- import{isSuccessCommandResult as c,OpenAppDeviceAction as u,UnknownDAError as l,UserInteractionRequired as s,WaitForAppAndVersionDeviceAction as A,XStateDeviceAction as E}from"@ledgerhq/device-management-kit";import{Left as I,Right as f}from"purify-ts";import{assign as n,fromPromise as m,setup as S}from"xstate";import{isContactsSupportedForSession as h}from"../../../app-binder/isContactsSupportedForSession";import{ContactsVersionRequirementError as g}from"../../../app-binder/model/contactsErrors";import{SendEditExternalAddressIdentifierTask as D}from"../../../app-binder/task/SendEditExternalAddressIdentifierTask";import{validateEditExternalAddressIdentifierInput as x}from"./validateEditExternalAddressIdentifierInput";class O extends E{makeStateMachine(d){const{isSupported:o,editIdentifier:p}=this.extractDependencies(d),r=this.input.appName;return S({types:{input:{},context:{},output:{}},actors:{openAppStateMachine:new u({input:{appName:r}}).makeStateMachine(d),waitForAppAndVersionStateMachine:new A({input:{}}).makeStateMachine(d),editIdentifier:m(({input:e})=>p(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&&o(t)}},actions:{assignValidationError:n({_internalState:({context:e})=>{const t=x(e.input);return t?{...e._internalState,error:t}:e._internalState}}),assignVersionError:n({_internalState:({context:e})=>({...e._internalState,error:new g})}),assignErrorFromEvent:n({_internalState:({context:e,event:t})=>({...e._internalState,error:new l(t.error instanceof Error?t.error.message:String(t.error))})})}}).createMachine({id:"EditExternalAddressIdentifierDeviceAction",initial:"InitialState",context:({input:e})=>({input:e,intermediateValue:{requiredUserInteraction:s.None},_internalState:{error:null,appAndVersion:null,hmacRest:null}}),states:{InitialState:{always:[{target:"ValidateInput",guard:"skipOpenApp"},{target:"OpenAppDeviceAction"}]},OpenAppDeviceAction:{invoke:{id:"openAppStateMachine",src:"openAppStateMachine",input:()=>({appName:r}),onSnapshot:{actions:n({intermediateValue:({event:e})=>e.snapshot.context.intermediateValue})},onDone:{target:"CheckOpenAppResult",actions:n({_internalState:({event:e,context:t})=>e.output.caseOf({Right:()=>t._internalState,Left:i=>({...t._internalState,error:i})})})}}},CheckOpenAppResult:{always:[{target:"ValidateInput",guard:"noInternalError"},{target:"Error"}]},ValidateInput:{entry:"assignValidationError",always:[{target:"WaitForAppAndVersion",guard:"noInternalError"},{target:"Error"}]},WaitForAppAndVersion:{entry:n({intermediateValue:{requiredUserInteraction:s.None}}),invoke:{id:"waitForAppAndVersion",src:"waitForAppAndVersionStateMachine",input:()=>({}),onSnapshot:{actions:n({intermediateValue:({event:e})=>e.snapshot.context.intermediateValue})},onDone:{target:"CheckAppAndVersion",actions:n({_internalState:({event:e,context:t})=>e.output.caseOf({Right:i=>({...t._internalState,appAndVersion:{name:i.name,version:i.version}}),Left:i=>({...t._internalState,error:i})})})}}},CheckAppAndVersion:{always:[{target:"VersionGuard",guard:"noInternalError"},{target:"Error"}]},VersionGuard:{always:[{target:"EditIdentifier",guard:"contactsSupported"},{target:"Error",actions:"assignVersionError"}]},EditIdentifier:{entry:n({intermediateValue:{requiredUserInteraction:s.RegisterWallet}}),exit:n({intermediateValue:{requiredUserInteraction:s.None}}),invoke:{id:"editIdentifier",src:"editIdentifier",input:({context:e})=>e.input,onDone:{target:"EditIdentifierResultCheck",actions:n({_internalState:({event:e,context:t})=>c(e.output)?{...t._internalState,hmacRest:e.output.data.hmacRest}:{...t._internalState,error:e.output.error}})},onError:{target:"Error",actions:"assignErrorFromEvent"}}},EditIdentifierResultCheck:{always:[{target:"Success",guard:"noInternalError"},{target:"Error"}]},Success:{type:"final"},Error:{type:"final"}},output:({context:e})=>{const{hmacRest:t,error:i}=e._internalState;if(t){const{input:a}=e;return f({contactName:a.contactName,scope:a.scope,previousIdentifier:a.previousIdentifier,identifier:a.newIdentifier,blockchainFamily:a.blockchainFamily,chainId:a.chainId,groupHandle:a.groupHandle,hmacProof:a.hmacProof,hmacRest:t})}return I(i??new l("No error in final state"))}})}extractDependencies(d){return{isSupported:r=>h(d,r),editIdentifier:r=>new D(d,{contactName:r.contactName,scope:r.scope,previousIdentifier:r.previousIdentifier,newIdentifier:r.newIdentifier,blockchainFamily:r.blockchainFamily,chainId:r.chainId,groupHandle:r.groupHandle,hmacProof:r.hmacProof,hmacRest:r.hmacRest}).run()}}}export{O as EditExternalAddressIdentifierDeviceAction};
1
+ import{isSuccessCommandResult as c,OpenAppDeviceAction as u,UnknownDAError as l,UserInteractionRequired as s,WaitForAppAndVersionDeviceAction as A,XStateDeviceAction as E}from"@ledgerhq/device-management-kit";import{Left as I,Right as f}from"purify-ts";import{assign as n,fromPromise as m,setup as S}from"xstate";import{isContactsAppVersionSupportedForSession as h}from"../../../app-binder/contactsVersionGuards";import{ContactsVersionRequirementError as g}from"../../../app-binder/model/contactsErrors";import{SendEditExternalAddressIdentifierTask as D}from"../../../app-binder/task/SendEditExternalAddressIdentifierTask";import{validateEditExternalAddressIdentifierInput as x}from"./validateEditExternalAddressIdentifierInput";class O extends E{makeStateMachine(d){const{isSupported:o,editIdentifier:p}=this.extractDependencies(d),r=this.input.appName;return S({types:{input:{},context:{},output:{}},actors:{openAppStateMachine:new u({input:{appName:r}}).makeStateMachine(d),waitForAppAndVersionStateMachine:new A({input:{}}).makeStateMachine(d),editIdentifier:m(({input:e})=>p(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&&o(t)}},actions:{assignValidationError:n({_internalState:({context:e})=>{const t=x(e.input);return t?{...e._internalState,error:t}:e._internalState}}),assignVersionError:n({_internalState:({context:e})=>({...e._internalState,error:new g})}),assignErrorFromEvent:n({_internalState:({context:e,event:t})=>({...e._internalState,error:new l(t.error instanceof Error?t.error.message:String(t.error))})})}}).createMachine({id:"EditExternalAddressIdentifierDeviceAction",initial:"InitialState",context:({input:e})=>({input:e,intermediateValue:{requiredUserInteraction:s.None},_internalState:{error:null,appAndVersion:null,hmacRest:null}}),states:{InitialState:{always:[{target:"ValidateInput",guard:"skipOpenApp"},{target:"OpenAppDeviceAction"}]},OpenAppDeviceAction:{invoke:{id:"openAppStateMachine",src:"openAppStateMachine",input:()=>({appName:r}),onSnapshot:{actions:n({intermediateValue:({event:e})=>e.snapshot.context.intermediateValue})},onDone:{target:"CheckOpenAppResult",actions:n({_internalState:({event:e,context:t})=>e.output.caseOf({Right:()=>t._internalState,Left:i=>({...t._internalState,error:i})})})}}},CheckOpenAppResult:{always:[{target:"ValidateInput",guard:"noInternalError"},{target:"Error"}]},ValidateInput:{entry:"assignValidationError",always:[{target:"WaitForAppAndVersion",guard:"noInternalError"},{target:"Error"}]},WaitForAppAndVersion:{entry:n({intermediateValue:{requiredUserInteraction:s.None}}),invoke:{id:"waitForAppAndVersion",src:"waitForAppAndVersionStateMachine",input:()=>({}),onSnapshot:{actions:n({intermediateValue:({event:e})=>e.snapshot.context.intermediateValue})},onDone:{target:"CheckAppAndVersion",actions:n({_internalState:({event:e,context:t})=>e.output.caseOf({Right:i=>({...t._internalState,appAndVersion:{name:i.name,version:i.version}}),Left:i=>({...t._internalState,error:i})})})}}},CheckAppAndVersion:{always:[{target:"VersionGuard",guard:"noInternalError"},{target:"Error"}]},VersionGuard:{always:[{target:"EditIdentifier",guard:"contactsSupported"},{target:"Error",actions:"assignVersionError"}]},EditIdentifier:{entry:n({intermediateValue:{requiredUserInteraction:s.RegisterWallet}}),exit:n({intermediateValue:{requiredUserInteraction:s.None}}),invoke:{id:"editIdentifier",src:"editIdentifier",input:({context:e})=>e.input,onDone:{target:"EditIdentifierResultCheck",actions:n({_internalState:({event:e,context:t})=>c(e.output)?{...t._internalState,hmacRest:e.output.data.hmacRest}:{...t._internalState,error:e.output.error}})},onError:{target:"Error",actions:"assignErrorFromEvent"}}},EditIdentifierResultCheck:{always:[{target:"Success",guard:"noInternalError"},{target:"Error"}]},Success:{type:"final"},Error:{type:"final"}},output:({context:e})=>{const{hmacRest:t,error:i}=e._internalState;if(t){const{input:a}=e;return f({contactName:a.contactName,scope:a.scope,previousIdentifier:a.previousIdentifier,identifier:a.newIdentifier,blockchainFamily:a.blockchainFamily,chainId:a.chainId,groupHandle:a.groupHandle,hmacProof:a.hmacProof,hmacRest:t})}return I(i??new l("No error in final state"))}})}extractDependencies(d){return{isSupported:r=>h(d,r),editIdentifier:r=>new D(d,{contactName:r.contactName,scope:r.scope,previousIdentifier:r.previousIdentifier,newIdentifier:r.newIdentifier,blockchainFamily:r.blockchainFamily,chainId:r.chainId,groupHandle:r.groupHandle,hmacProof:r.hmacProof,hmacRest:r.hmacRest}).run()}}}export{O as EditExternalAddressIdentifierDeviceAction};
2
2
  //# sourceMappingURL=EditExternalAddressIdentifierDeviceAction.js.map
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "version": 3,
3
3
  "sources": ["../../../../../../src/internal/app-binder/device-action/EditExternalAddressIdentifier/EditExternalAddressIdentifierDeviceAction.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 EditExternalAddressIdentifierDAError,\n type EditExternalAddressIdentifierDAInput,\n type EditExternalAddressIdentifierDAIntermediateValue,\n type EditExternalAddressIdentifierDAInternalState,\n type EditExternalAddressIdentifierDAOutput,\n} from \"@api/app-binder/EditExternalAddressIdentifierDeviceActionTypes\";\nimport {\n isContactsSupportedForSession,\n type RunningApp,\n} from \"@internal/app-binder/isContactsSupportedForSession\";\nimport { ContactsVersionRequirementError } from \"@internal/app-binder/model/contactsErrors\";\nimport {\n type EditIdentifierProof,\n SendEditExternalAddressIdentifierTask,\n} from \"@internal/app-binder/task/SendEditExternalAddressIdentifierTask\";\n\nimport { validateEditExternalAddressIdentifierInput } from \"./validateEditExternalAddressIdentifierInput\";\n\nexport type EditExternalAddressIdentifierMachineDependencies = {\n readonly isSupported: (app: RunningApp) => boolean;\n readonly editIdentifier: (\n input: EditExternalAddressIdentifierDAInput,\n ) => Promise<\n Awaited<ReturnType<SendEditExternalAddressIdentifierTask[\"run\"]>>\n >;\n};\n\nexport class EditExternalAddressIdentifierDeviceAction extends XStateDeviceAction<\n EditExternalAddressIdentifierDAOutput,\n EditExternalAddressIdentifierDAInput,\n EditExternalAddressIdentifierDAError,\n EditExternalAddressIdentifierDAIntermediateValue,\n EditExternalAddressIdentifierDAInternalState\n> {\n makeStateMachine(\n internalApi: InternalApi,\n ): DeviceActionStateMachine<\n EditExternalAddressIdentifierDAOutput,\n EditExternalAddressIdentifierDAInput,\n EditExternalAddressIdentifierDAError,\n EditExternalAddressIdentifierDAIntermediateValue,\n EditExternalAddressIdentifierDAInternalState\n > {\n type types = StateMachineTypes<\n EditExternalAddressIdentifierDAOutput,\n EditExternalAddressIdentifierDAInput,\n EditExternalAddressIdentifierDAError,\n EditExternalAddressIdentifierDAIntermediateValue,\n EditExternalAddressIdentifierDAInternalState\n >;\n\n const { isSupported, editIdentifier } =\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 editIdentifier: fromPromise(\n ({ input }: { input: EditExternalAddressIdentifierDAInput }) =>\n editIdentifier(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 = validateEditExternalAddressIdentifierInput(\n context.input,\n );\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: \"EditExternalAddressIdentifierDeviceAction\",\n initial: \"InitialState\",\n context: ({ input }) => ({\n input,\n intermediateValue: {\n requiredUserInteraction: UserInteractionRequired.None,\n },\n _internalState: {\n error: null,\n appAndVersion: null,\n hmacRest: 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<EditExternalAddressIdentifierDAInternalState>(\n {\n Right: () => context._internalState,\n Left: (error) => ({ ...context._internalState, error }),\n },\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<EditExternalAddressIdentifierDAInternalState>(\n {\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 },\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: \"EditIdentifier\", guard: \"contactsSupported\" },\n { target: \"Error\", actions: \"assignVersionError\" },\n ],\n },\n EditIdentifier: {\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: \"editIdentifier\",\n src: \"editIdentifier\",\n input: ({ context }) => context.input,\n onDone: {\n target: \"EditIdentifierResultCheck\",\n actions: assign({\n _internalState: ({ event, context }) =>\n isSuccessCommandResult(event.output)\n ? {\n ...context._internalState,\n hmacRest: event.output.data.hmacRest,\n }\n : {\n ...context._internalState,\n error: event.output.error,\n },\n }),\n },\n onError: {\n target: \"Error\",\n actions: \"assignErrorFromEvent\",\n },\n },\n },\n EditIdentifierResultCheck: {\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 { hmacRest, error } = context._internalState;\n if (hmacRest) {\n const { input } = context;\n return Right({\n contactName: input.contactName,\n scope: input.scope,\n previousIdentifier: input.previousIdentifier,\n identifier: input.newIdentifier,\n blockchainFamily: input.blockchainFamily,\n chainId: input.chainId,\n groupHandle: input.groupHandle,\n // Preserved: the group-level name proof is untouched by an identifier\n // edit \u2014 only `hmacRest` (the address-level proof) rotates.\n hmacProof: input.hmacProof,\n hmacRest,\n });\n }\n return Left(error ?? new UnknownDAError(\"No error in final state\"));\n },\n });\n }\n\n extractDependencies(\n internalApi: InternalApi,\n ): EditExternalAddressIdentifierMachineDependencies {\n const isSupported = (app: RunningApp) =>\n isContactsSupportedForSession(internalApi, app);\n\n const editIdentifier = (\n input: EditExternalAddressIdentifierDAInput,\n ): Promise<\n Awaited<ReturnType<SendEditExternalAddressIdentifierTask[\"run\"]>>\n > =>\n new SendEditExternalAddressIdentifierTask(internalApi, {\n contactName: input.contactName,\n scope: input.scope,\n previousIdentifier: input.previousIdentifier,\n newIdentifier: input.newIdentifier,\n blockchainFamily: input.blockchainFamily,\n chainId: input.chainId,\n groupHandle: input.groupHandle,\n hmacProof: input.hmacProof,\n hmacRest: input.hmacRest,\n }).run();\n\n return { isSupported, editIdentifier };\n }\n}\n\nexport type { EditIdentifierProof };\n"],
5
- "mappings": "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",
6
- "names": ["isSuccessCommandResult", "OpenAppDeviceAction", "UnknownDAError", "UserInteractionRequired", "WaitForAppAndVersionDeviceAction", "XStateDeviceAction", "Left", "Right", "assign", "fromPromise", "setup", "isContactsSupportedForSession", "ContactsVersionRequirementError", "SendEditExternalAddressIdentifierTask", "validateEditExternalAddressIdentifierInput", "EditExternalAddressIdentifierDeviceAction", "internalApi", "isSupported", "editIdentifier", "appName", "input", "context", "appAndVersion", "error", "event", "hmacRest", "app"]
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 EditExternalAddressIdentifierDAError,\n type EditExternalAddressIdentifierDAInput,\n type EditExternalAddressIdentifierDAIntermediateValue,\n type EditExternalAddressIdentifierDAInternalState,\n type EditExternalAddressIdentifierDAOutput,\n} from \"@api/app-binder/EditExternalAddressIdentifierDeviceActionTypes\";\nimport {\n isContactsAppVersionSupportedForSession,\n type RunningApp,\n} from \"@internal/app-binder/contactsVersionGuards\";\nimport { ContactsVersionRequirementError } from \"@internal/app-binder/model/contactsErrors\";\nimport {\n type EditIdentifierProof,\n SendEditExternalAddressIdentifierTask,\n} from \"@internal/app-binder/task/SendEditExternalAddressIdentifierTask\";\n\nimport { validateEditExternalAddressIdentifierInput } from \"./validateEditExternalAddressIdentifierInput\";\n\nexport type EditExternalAddressIdentifierMachineDependencies = {\n readonly isSupported: (app: RunningApp) => boolean;\n readonly editIdentifier: (\n input: EditExternalAddressIdentifierDAInput,\n ) => Promise<\n Awaited<ReturnType<SendEditExternalAddressIdentifierTask[\"run\"]>>\n >;\n};\n\nexport class EditExternalAddressIdentifierDeviceAction extends XStateDeviceAction<\n EditExternalAddressIdentifierDAOutput,\n EditExternalAddressIdentifierDAInput,\n EditExternalAddressIdentifierDAError,\n EditExternalAddressIdentifierDAIntermediateValue,\n EditExternalAddressIdentifierDAInternalState\n> {\n makeStateMachine(\n internalApi: InternalApi,\n ): DeviceActionStateMachine<\n EditExternalAddressIdentifierDAOutput,\n EditExternalAddressIdentifierDAInput,\n EditExternalAddressIdentifierDAError,\n EditExternalAddressIdentifierDAIntermediateValue,\n EditExternalAddressIdentifierDAInternalState\n > {\n type types = StateMachineTypes<\n EditExternalAddressIdentifierDAOutput,\n EditExternalAddressIdentifierDAInput,\n EditExternalAddressIdentifierDAError,\n EditExternalAddressIdentifierDAIntermediateValue,\n EditExternalAddressIdentifierDAInternalState\n >;\n\n const { isSupported, editIdentifier } =\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 editIdentifier: fromPromise(\n ({ input }: { input: EditExternalAddressIdentifierDAInput }) =>\n editIdentifier(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 = validateEditExternalAddressIdentifierInput(\n context.input,\n );\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: \"EditExternalAddressIdentifierDeviceAction\",\n initial: \"InitialState\",\n context: ({ input }) => ({\n input,\n intermediateValue: {\n requiredUserInteraction: UserInteractionRequired.None,\n },\n _internalState: {\n error: null,\n appAndVersion: null,\n hmacRest: 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<EditExternalAddressIdentifierDAInternalState>(\n {\n Right: () => context._internalState,\n Left: (error) => ({ ...context._internalState, error }),\n },\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<EditExternalAddressIdentifierDAInternalState>(\n {\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 },\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: \"EditIdentifier\", guard: \"contactsSupported\" },\n { target: \"Error\", actions: \"assignVersionError\" },\n ],\n },\n EditIdentifier: {\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: \"editIdentifier\",\n src: \"editIdentifier\",\n input: ({ context }) => context.input,\n onDone: {\n target: \"EditIdentifierResultCheck\",\n actions: assign({\n _internalState: ({ event, context }) =>\n isSuccessCommandResult(event.output)\n ? {\n ...context._internalState,\n hmacRest: event.output.data.hmacRest,\n }\n : {\n ...context._internalState,\n error: event.output.error,\n },\n }),\n },\n onError: {\n target: \"Error\",\n actions: \"assignErrorFromEvent\",\n },\n },\n },\n EditIdentifierResultCheck: {\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 { hmacRest, error } = context._internalState;\n if (hmacRest) {\n const { input } = context;\n return Right({\n contactName: input.contactName,\n scope: input.scope,\n previousIdentifier: input.previousIdentifier,\n identifier: input.newIdentifier,\n blockchainFamily: input.blockchainFamily,\n chainId: input.chainId,\n groupHandle: input.groupHandle,\n // Preserved: the group-level name proof is untouched by an identifier\n // edit \u2014 only `hmacRest` (the address-level proof) rotates.\n hmacProof: input.hmacProof,\n hmacRest,\n });\n }\n return Left(error ?? new UnknownDAError(\"No error in final state\"));\n },\n });\n }\n\n extractDependencies(\n internalApi: InternalApi,\n ): EditExternalAddressIdentifierMachineDependencies {\n const isSupported = (app: RunningApp) =>\n isContactsAppVersionSupportedForSession(internalApi, app);\n\n const editIdentifier = (\n input: EditExternalAddressIdentifierDAInput,\n ): Promise<\n Awaited<ReturnType<SendEditExternalAddressIdentifierTask[\"run\"]>>\n > =>\n new SendEditExternalAddressIdentifierTask(internalApi, {\n contactName: input.contactName,\n scope: input.scope,\n previousIdentifier: input.previousIdentifier,\n newIdentifier: input.newIdentifier,\n blockchainFamily: input.blockchainFamily,\n chainId: input.chainId,\n groupHandle: input.groupHandle,\n hmacProof: input.hmacProof,\n hmacRest: input.hmacRest,\n }).run();\n\n return { isSupported, editIdentifier };\n }\n}\n\nexport type { EditIdentifierProof };\n"],
5
+ "mappings": "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",
6
+ "names": ["isSuccessCommandResult", "OpenAppDeviceAction", "UnknownDAError", "UserInteractionRequired", "WaitForAppAndVersionDeviceAction", "XStateDeviceAction", "Left", "Right", "assign", "fromPromise", "setup", "isContactsAppVersionSupportedForSession", "ContactsVersionRequirementError", "SendEditExternalAddressIdentifierTask", "validateEditExternalAddressIdentifierInput", "EditExternalAddressIdentifierDeviceAction", "internalApi", "isSupported", "editIdentifier", "appName", "input", "context", "appAndVersion", "error", "event", "hmacRest", "app"]
7
7
  }
@@ -1,2 +1,2 @@
1
- import{isSuccessCommandResult as l,OpenAppDeviceAction as u,UnknownDAError as c,UserInteractionRequired as p,WaitForAppAndVersionDeviceAction as S,XStateDeviceAction as A}from"@ledgerhq/device-management-kit";import{Left as E,Right as m}from"purify-ts";import{assign as n,fromPromise as h,setup as g}from"xstate";import{isContactsSupportedForSession as D}from"../../../app-binder/isContactsSupportedForSession";import{ContactsVersionRequirementError as I}from"../../../app-binder/model/contactsErrors";import{SendEditExternalAddressScopeTask as x}from"../../../app-binder/task/SendEditExternalAddressScopeTask";import{validateEditExternalAddressScopeInput as y}from"./validateEditExternalAddressScopeInput";class O extends A{makeStateMachine(o){const{isSupported:s,editScope:d}=this.extractDependencies(o),r=this.input.appName;return g({types:{input:{},context:{},output:{}},actors:{openAppStateMachine:new u({input:{appName:r}}).makeStateMachine(o),waitForAppAndVersionStateMachine:new S({input:{}}).makeStateMachine(o),editScope:h(({input:e})=>d(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&&s(t)}},actions:{assignValidationError:n({_internalState:({context:e})=>{const t=y(e.input);return t?{...e._internalState,error:t}:e._internalState}}),assignVersionError:n({_internalState:({context:e})=>({...e._internalState,error:new I})}),assignErrorFromEvent:n({_internalState:({context:e,event:t})=>({...e._internalState,error:new c(t.error instanceof Error?t.error.message:String(t.error))})})}}).createMachine({id:"EditExternalAddressScopeDeviceAction",initial:"InitialState",context:({input:e})=>({input:e,intermediateValue:{requiredUserInteraction:p.None},_internalState:{error:null,appAndVersion:null,hmacRest:null}}),states:{InitialState:{always:[{target:"ValidateInput",guard:"skipOpenApp"},{target:"OpenAppDeviceAction"}]},OpenAppDeviceAction:{invoke:{id:"openAppStateMachine",src:"openAppStateMachine",input:()=>({appName:r}),onSnapshot:{actions:n({intermediateValue:({event:e})=>e.snapshot.context.intermediateValue})},onDone:{target:"CheckOpenAppResult",actions:n({_internalState:({event:e,context:t})=>e.output.caseOf({Right:()=>t._internalState,Left:a=>({...t._internalState,error:a})})})}}},CheckOpenAppResult:{always:[{target:"ValidateInput",guard:"noInternalError"},{target:"Error"}]},ValidateInput:{entry:"assignValidationError",always:[{target:"WaitForAppAndVersion",guard:"noInternalError"},{target:"Error"}]},WaitForAppAndVersion:{entry:n({intermediateValue:{requiredUserInteraction:p.None}}),invoke:{id:"waitForAppAndVersion",src:"waitForAppAndVersionStateMachine",input:()=>({}),onSnapshot:{actions:n({intermediateValue:({event:e})=>e.snapshot.context.intermediateValue})},onDone:{target:"CheckAppAndVersion",actions:n({_internalState:({event:e,context:t})=>e.output.caseOf({Right:a=>({...t._internalState,appAndVersion:{name:a.name,version:a.version}}),Left:a=>({...t._internalState,error:a})})})}}},CheckAppAndVersion:{always:[{target:"VersionGuard",guard:"noInternalError"},{target:"Error"}]},VersionGuard:{always:[{target:"EditScope",guard:"contactsSupported"},{target:"Error",actions:"assignVersionError"}]},EditScope:{entry:n({intermediateValue:{requiredUserInteraction:p.RegisterWallet}}),exit:n({intermediateValue:{requiredUserInteraction:p.None}}),invoke:{id:"editScope",src:"editScope",input:({context:e})=>e.input,onDone:{target:"EditScopeResultCheck",actions:n({_internalState:({event:e,context:t})=>l(e.output)?{...t._internalState,hmacRest:e.output.data.hmacRest}:{...t._internalState,error:e.output.error}})},onError:{target:"Error",actions:"assignErrorFromEvent"}}},EditScopeResultCheck:{always:[{target:"Success",guard:"noInternalError"},{target:"Error"}]},Success:{type:"final"},Error:{type:"final"}},output:({context:e})=>{const{hmacRest:t,error:a}=e._internalState;if(t){const{input:i}=e;return m({contactName:i.contactName,previousScope:i.previousScope,scope:i.newScope,identifier:i.identifier,blockchainFamily:i.blockchainFamily,chainId:i.chainId,groupHandle:i.groupHandle,hmacProof:i.hmacProof,hmacRest:t})}return E(a??new c("No error in final state"))}})}extractDependencies(o){return{isSupported:r=>D(o,r),editScope:r=>new x(o,{contactName:r.contactName,previousScope:r.previousScope,newScope:r.newScope,identifier:r.identifier,blockchainFamily:r.blockchainFamily,chainId:r.chainId,groupHandle:r.groupHandle,hmacProof:r.hmacProof,hmacRest:r.hmacRest}).run()}}}export{O as EditExternalAddressScopeDeviceAction};
1
+ import{isSuccessCommandResult as l,OpenAppDeviceAction as u,UnknownDAError as c,UserInteractionRequired as p,WaitForAppAndVersionDeviceAction as S,XStateDeviceAction as A}from"@ledgerhq/device-management-kit";import{Left as E,Right as m}from"purify-ts";import{assign as n,fromPromise as h,setup as g}from"xstate";import{isContactsAppVersionSupportedForSession as D}from"../../../app-binder/contactsVersionGuards";import{ContactsVersionRequirementError as I}from"../../../app-binder/model/contactsErrors";import{SendEditExternalAddressScopeTask as x}from"../../../app-binder/task/SendEditExternalAddressScopeTask";import{validateEditExternalAddressScopeInput as y}from"./validateEditExternalAddressScopeInput";class O extends A{makeStateMachine(o){const{isSupported:s,editScope:d}=this.extractDependencies(o),r=this.input.appName;return g({types:{input:{},context:{},output:{}},actors:{openAppStateMachine:new u({input:{appName:r}}).makeStateMachine(o),waitForAppAndVersionStateMachine:new S({input:{}}).makeStateMachine(o),editScope:h(({input:e})=>d(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&&s(t)}},actions:{assignValidationError:n({_internalState:({context:e})=>{const t=y(e.input);return t?{...e._internalState,error:t}:e._internalState}}),assignVersionError:n({_internalState:({context:e})=>({...e._internalState,error:new I})}),assignErrorFromEvent:n({_internalState:({context:e,event:t})=>({...e._internalState,error:new c(t.error instanceof Error?t.error.message:String(t.error))})})}}).createMachine({id:"EditExternalAddressScopeDeviceAction",initial:"InitialState",context:({input:e})=>({input:e,intermediateValue:{requiredUserInteraction:p.None},_internalState:{error:null,appAndVersion:null,hmacRest:null}}),states:{InitialState:{always:[{target:"ValidateInput",guard:"skipOpenApp"},{target:"OpenAppDeviceAction"}]},OpenAppDeviceAction:{invoke:{id:"openAppStateMachine",src:"openAppStateMachine",input:()=>({appName:r}),onSnapshot:{actions:n({intermediateValue:({event:e})=>e.snapshot.context.intermediateValue})},onDone:{target:"CheckOpenAppResult",actions:n({_internalState:({event:e,context:t})=>e.output.caseOf({Right:()=>t._internalState,Left:a=>({...t._internalState,error:a})})})}}},CheckOpenAppResult:{always:[{target:"ValidateInput",guard:"noInternalError"},{target:"Error"}]},ValidateInput:{entry:"assignValidationError",always:[{target:"WaitForAppAndVersion",guard:"noInternalError"},{target:"Error"}]},WaitForAppAndVersion:{entry:n({intermediateValue:{requiredUserInteraction:p.None}}),invoke:{id:"waitForAppAndVersion",src:"waitForAppAndVersionStateMachine",input:()=>({}),onSnapshot:{actions:n({intermediateValue:({event:e})=>e.snapshot.context.intermediateValue})},onDone:{target:"CheckAppAndVersion",actions:n({_internalState:({event:e,context:t})=>e.output.caseOf({Right:a=>({...t._internalState,appAndVersion:{name:a.name,version:a.version}}),Left:a=>({...t._internalState,error:a})})})}}},CheckAppAndVersion:{always:[{target:"VersionGuard",guard:"noInternalError"},{target:"Error"}]},VersionGuard:{always:[{target:"EditScope",guard:"contactsSupported"},{target:"Error",actions:"assignVersionError"}]},EditScope:{entry:n({intermediateValue:{requiredUserInteraction:p.RegisterWallet}}),exit:n({intermediateValue:{requiredUserInteraction:p.None}}),invoke:{id:"editScope",src:"editScope",input:({context:e})=>e.input,onDone:{target:"EditScopeResultCheck",actions:n({_internalState:({event:e,context:t})=>l(e.output)?{...t._internalState,hmacRest:e.output.data.hmacRest}:{...t._internalState,error:e.output.error}})},onError:{target:"Error",actions:"assignErrorFromEvent"}}},EditScopeResultCheck:{always:[{target:"Success",guard:"noInternalError"},{target:"Error"}]},Success:{type:"final"},Error:{type:"final"}},output:({context:e})=>{const{hmacRest:t,error:a}=e._internalState;if(t){const{input:i}=e;return m({contactName:i.contactName,previousScope:i.previousScope,scope:i.newScope,identifier:i.identifier,blockchainFamily:i.blockchainFamily,chainId:i.chainId,groupHandle:i.groupHandle,hmacProof:i.hmacProof,hmacRest:t})}return E(a??new c("No error in final state"))}})}extractDependencies(o){return{isSupported:r=>D(o,r),editScope:r=>new x(o,{contactName:r.contactName,previousScope:r.previousScope,newScope:r.newScope,identifier:r.identifier,blockchainFamily:r.blockchainFamily,chainId:r.chainId,groupHandle:r.groupHandle,hmacProof:r.hmacProof,hmacRest:r.hmacRest}).run()}}}export{O as EditExternalAddressScopeDeviceAction};
2
2
  //# sourceMappingURL=EditExternalAddressScopeDeviceAction.js.map