@ledgerhq/device-transport-kit-web-ble 0.0.0-webhid-20250124164153 → 0.0.0-wrong-error-when-in-experimental-provider-20251021162636

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 (33) hide show
  1. package/README.md +77 -0
  2. package/lib/esm/api/data/WebBleConfig.js +1 -1
  3. package/lib/esm/api/data/WebBleConfig.js.map +3 -3
  4. package/lib/esm/api/model/BleDevice.stub.js +1 -1
  5. package/lib/esm/api/model/BleDevice.stub.js.map +2 -2
  6. package/lib/esm/api/transport/WebBleApduSender.js +2 -0
  7. package/lib/esm/api/transport/WebBleApduSender.js.map +7 -0
  8. package/lib/esm/api/transport/WebBleApduSender.test.js +2 -0
  9. package/lib/esm/api/transport/WebBleApduSender.test.js.map +7 -0
  10. package/lib/esm/api/transport/WebBleTransport.js +1 -1
  11. package/lib/esm/api/transport/WebBleTransport.js.map +3 -3
  12. package/lib/esm/api/transport/WebBleTransport.test.js +1 -1
  13. package/lib/esm/api/transport/WebBleTransport.test.js.map +3 -3
  14. package/lib/esm/package.json +16 -16
  15. package/lib/types/api/data/WebBleConfig.d.ts +5 -1
  16. package/lib/types/api/data/WebBleConfig.d.ts.map +1 -1
  17. package/lib/types/api/model/BleDevice.stub.d.ts.map +1 -1
  18. package/lib/types/api/transport/WebBleApduSender.d.ts +39 -0
  19. package/lib/types/api/transport/WebBleApduSender.d.ts.map +1 -0
  20. package/lib/types/api/transport/WebBleApduSender.test.d.ts +2 -0
  21. package/lib/types/api/transport/WebBleApduSender.test.d.ts.map +1 -0
  22. package/lib/types/api/transport/WebBleTransport.d.ts +23 -72
  23. package/lib/types/api/transport/WebBleTransport.d.ts.map +1 -1
  24. package/lib/types/tsconfig.prod.tsbuildinfo +1 -1
  25. package/package.json +17 -17
  26. package/lib/esm/api/transport/BleDeviceConnection.js +0 -2
  27. package/lib/esm/api/transport/BleDeviceConnection.js.map +0 -7
  28. package/lib/esm/api/transport/BleDeviceConnection.test.js +0 -2
  29. package/lib/esm/api/transport/BleDeviceConnection.test.js.map +0 -7
  30. package/lib/types/api/transport/BleDeviceConnection.d.ts +0 -98
  31. package/lib/types/api/transport/BleDeviceConnection.d.ts.map +0 -1
  32. package/lib/types/api/transport/BleDeviceConnection.test.d.ts +0 -2
  33. package/lib/types/api/transport/BleDeviceConnection.test.d.ts.map +0 -1
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@ledgerhq/device-transport-kit-web-ble",
3
- "version": "0.0.0-webhid-20250124164153",
3
+ "version": "0.0.0-wrong-error-when-in-experimental-provider-20251021162636",
4
4
  "license": "Apache-2.0",
5
5
  "private": false,
6
6
  "exports": {
@@ -14,39 +14,39 @@
14
14
  "package.json"
15
15
  ],
16
16
  "dependencies": {
17
- "@sentry/minimal": "^6.19.7",
18
- "purify-ts": "^2.1.0",
19
- "uuid": "^11.0.3"
17
+ "@sentry/minimal": "6.19.7",
18
+ "purify-ts": "2.1.0",
19
+ "uuid": "11.0.3"
20
20
  },
21
21
  "devDependencies": {
22
22
  "@types/uuid": "^10.0.0",
23
23
  "@types/web-bluetooth": "^0.0.20",
24
- "rxjs": "^7.8.1",
25
- "ts-node": "^10.9.2",
26
- "@ledgerhq/device-management-kit": "0.0.0-webhid-20250124164153",
24
+ "rxjs": "7.8.2",
25
+ "ts-node": "10.9.2",
26
+ "@ledgerhq/device-management-kit": "0.0.0-wrong-error-when-in-experimental-provider-20251021162636",
27
27
  "@ledgerhq/eslint-config-dsdk": "0.0.2",
28
- "@ledgerhq/esbuild-tools": "0.0.2",
29
- "@ledgerhq/jest-config-dsdk": "1.0.1",
30
28
  "@ledgerhq/prettier-config-dsdk": "0.0.2",
31
- "@ledgerhq/tsconfig-dsdk": "1.0.1"
29
+ "@ledgerhq/ldmk-tool": "0.0.1",
30
+ "@ledgerhq/tsconfig-dsdk": "1.0.1",
31
+ "@ledgerhq/vitest-config-dmk": "0.0.0"
32
32
  },
33
33
  "peerDependencies": {
34
- "rxjs": "^7.8.1",
35
- "@ledgerhq/device-management-kit": "0.0.0-webhid-20250124164153"
34
+ "rxjs": "7.8.2",
35
+ "@ledgerhq/device-management-kit": "0.0.0-wrong-error-when-in-experimental-provider-20251021162636"
36
36
  },
37
37
  "scripts": {
38
38
  "prebuild": "rimraf lib",
39
- "build": "pnpm lmdk-build --entryPoints src/index.ts,src/**/*.ts --tsconfig tsconfig.prod.json --platform web",
39
+ "build": "pnpm ldmk-tool build --entryPoints src/index.ts,src/**/*.ts --tsconfig tsconfig.prod.json --platform web",
40
40
  "dev": "concurrently \"pnpm watch:builds\" \"pnpm watch:types\"",
41
- "watch:builds": "pnpm lmdk-watch --entryPoints src/index.ts,src/**/*.ts --tsconfig tsconfig.prod.json --platform web",
41
+ "watch:builds": "pnpm ldmk-tool watch --entryPoints src/index.ts,src/**/*.ts --tsconfig tsconfig.prod.json --platform web",
42
42
  "watch:types": "concurrently \"tsc --watch -p tsconfig.prod.json\" \"tsc-alias --watch -p tsconfig.prod.json\"",
43
43
  "lint": "eslint",
44
44
  "lint:fix": "pnpm lint --fix",
45
45
  "prettier": "prettier . --check",
46
46
  "prettier:fix": "prettier . --write",
47
47
  "typecheck": "tsc --noEmit",
48
- "test": "jest --passWithNoTests",
49
- "test:watch": "pnpm test -- --watch",
50
- "test:coverage": "pnpm test -- --coverage"
48
+ "test": "vitest run",
49
+ "test:watch": "vitest",
50
+ "test:coverage": "vitest run --coverage"
51
51
  }
52
52
  }
@@ -1,2 +0,0 @@
1
- import{CommandUtils as u,DeviceNotInitializedError as p,ReconnectionFailedError as d}from"@ledgerhq/device-management-kit";import{Left as c,Maybe as o,Nothing as v,Right as n}from"purify-ts";class y{_writeCharacteristic;_notifyCharacteristic;_logger;_apduSender;_apduSenderFactory;_apduReceiver;_isDeviceReady;_sendApduPromiseResolver;_settleReconnectionPromiseResolvers;constructor({writeCharacteristic:e,notifyCharacteristic:t,apduSenderFactory:i,apduReceiverFactory:s},a){this._apduSenderFactory=i,this._apduSender=v,this._apduReceiver=s(),this._logger=a("BleDeviceConnection"),this._writeCharacteristic=e,this._notifyCharacteristic=t,this._notifyCharacteristic.oncharacteristicvaluechanged=this.onNotifyCharacteristicValueChanged,this._isDeviceReady=!1,this._sendApduPromiseResolver=o.zero(),this._settleReconnectionPromiseResolvers=o.zero()}set notifyCharacteristic(e){this._notifyCharacteristic=e,this._notifyCharacteristic.oncharacteristicvaluechanged=this.onNotifyCharacteristicValueChanged}set writeCharacteristic(e){this._writeCharacteristic=e}onReceiveSetupApduResponse(e){const t=new Uint8Array(e),[i]=t.slice(5);i&&(this._apduSender=o.of(this._apduSenderFactory({frameSize:i})),this._settleReconnectionPromiseResolvers.ifJust(s=>{s.resolve(),this._settleReconnectionPromiseResolvers=o.zero()}),this._isDeviceReady=!0)}onNotifyCharacteristicValueChanged=e=>{if(!this.isDataViewEvent(e))return;const{target:{value:{buffer:t}}}=e;t instanceof ArrayBuffer&&(this._isDeviceReady?this.receiveApdu(t):this.onReceiveSetupApduResponse(t))};async setup(){const e=Uint8Array.from([8,0,0,0,0]);await this._notifyCharacteristic.startNotifications(),await this._writeCharacteristic.writeValueWithoutResponse(e)}receiveApdu(e){this._apduReceiver.handleFrame(new Uint8Array(e)).map(i=>{i.map(s=>{this._logger.debug("Received APDU Response",{data:{response:s}}),this._sendApduPromiseResolver.map(({resolve:a})=>a(n(s)))})}).mapLeft(i=>{this._sendApduPromiseResolver.map(({resolve:s})=>s(c(i)))})}async sendApdu(e,t){if(!this._isDeviceReady)return Promise.resolve(c(new p("Unknown MTU")));const i=new Promise(r=>{this._sendApduPromiseResolver=o.of({resolve:r})}),s=this._apduSender.mapOrDefault(r=>r.getFrames(e),[]);for(const r of s)try{this._logger.debug("Sending Frame",{data:{frame:r.getRawData()}}),await this._writeCharacteristic.writeValueWithoutResponse(r.getRawData())}catch(h){this._logger.error("Error sending frame",{data:{error:h}})}const a=await i;return this._sendApduPromiseResolver=o.zero(),a.caseOf({Right:async r=>t&&u.isSuccessResponse(r)?(await this.setupWaitForReconnection()).map(()=>r):n(r),Left:async r=>Promise.resolve(c(r))})}isDataViewEvent(e){return e.target!==null&&"value"in e.target&&e.target.value instanceof DataView}setupWaitForReconnection(){return new Promise(e=>{this._settleReconnectionPromiseResolvers=o.of({resolve:()=>e(n(void 0)),reject:t=>e(c(t))})})}async reconnect(e,t){this._isDeviceReady=!1,this.notifyCharacteristic=t,this.writeCharacteristic=e,await this.setup()}disconnect(){this._settleReconnectionPromiseResolvers.ifJust(e=>{e.reject(new d),this._settleReconnectionPromiseResolvers=o.zero()}),this._isDeviceReady=!1}}export{y as BleDeviceConnection};
2
- //# sourceMappingURL=BleDeviceConnection.js.map
@@ -1,7 +0,0 @@
1
- {
2
- "version": 3,
3
- "sources": ["../../../../src/api/transport/BleDeviceConnection.ts"],
4
- "sourcesContent": ["import {\n type ApduReceiverService,\n type ApduReceiverServiceFactory,\n type ApduResponse,\n type ApduSenderService,\n type ApduSenderServiceFactory,\n CommandUtils,\n type DeviceConnection,\n DeviceNotInitializedError,\n type DmkError,\n type LoggerPublisherService,\n ReconnectionFailedError,\n} from \"@ledgerhq/device-management-kit\";\nimport { type Either, Left, Maybe, Nothing, Right } from \"purify-ts\";\n\ntype BleDeviceConnectionConstructorArgs = {\n writeCharacteristic: BluetoothRemoteGATTCharacteristic;\n notifyCharacteristic: BluetoothRemoteGATTCharacteristic;\n apduSenderFactory: ApduSenderServiceFactory;\n apduReceiverFactory: ApduReceiverServiceFactory;\n};\n\nexport type DataViewEvent = Event & {\n target: {\n value: DataView;\n };\n};\n\nexport class BleDeviceConnection implements DeviceConnection {\n private _writeCharacteristic: BluetoothRemoteGATTCharacteristic;\n private _notifyCharacteristic: BluetoothRemoteGATTCharacteristic;\n private readonly _logger: LoggerPublisherService;\n private _apduSender: Maybe<ApduSenderService>;\n private readonly _apduSenderFactory: ApduSenderServiceFactory;\n private readonly _apduReceiver: ApduReceiverService;\n private _isDeviceReady: boolean;\n private _sendApduPromiseResolver: Maybe<{\n resolve(value: Either<DmkError, ApduResponse>): void;\n }>;\n private _settleReconnectionPromiseResolvers: Maybe<{\n resolve(): void;\n reject(err: DmkError): void;\n }>;\n\n constructor(\n {\n writeCharacteristic,\n notifyCharacteristic,\n apduSenderFactory,\n apduReceiverFactory,\n }: BleDeviceConnectionConstructorArgs,\n loggerServiceFactory: (tag: string) => LoggerPublisherService,\n ) {\n this._apduSenderFactory = apduSenderFactory;\n this._apduSender = Nothing;\n this._apduReceiver = apduReceiverFactory();\n this._logger = loggerServiceFactory(\"BleDeviceConnection\");\n this._writeCharacteristic = writeCharacteristic;\n this._notifyCharacteristic = notifyCharacteristic;\n this._notifyCharacteristic.oncharacteristicvaluechanged =\n this.onNotifyCharacteristicValueChanged;\n this._isDeviceReady = false;\n this._sendApduPromiseResolver = Maybe.zero();\n this._settleReconnectionPromiseResolvers = Maybe.zero();\n }\n\n /**\n * NotifyCharacteristic setter\n * Register a listener on characteristic value change\n * @param notifyCharacteristic\n * @private\n */\n private set notifyCharacteristic(\n notifyCharacteristic: BluetoothRemoteGATTCharacteristic,\n ) {\n this._notifyCharacteristic = notifyCharacteristic;\n this._notifyCharacteristic.oncharacteristicvaluechanged =\n this.onNotifyCharacteristicValueChanged;\n }\n\n /**\n * WriteCharacteristic setter\n * @param writeCharacteristic\n * @private\n */\n private set writeCharacteristic(\n writeCharacteristic: BluetoothRemoteGATTCharacteristic,\n ) {\n this._writeCharacteristic = writeCharacteristic;\n }\n\n /**\n * Event handler to setup the mtu size in response of 0x0800000000 APDU\n * @param value\n * @private\n */\n private onReceiveSetupApduResponse(value: ArrayBuffer) {\n const mtuResponse = new Uint8Array(value);\n // the mtu is the 5th byte of the response\n const [frameSize] = mtuResponse.slice(5);\n if (frameSize) {\n this._apduSender = Maybe.of(this._apduSenderFactory({ frameSize }));\n this._settleReconnectionPromiseResolvers.ifJust((promise) => {\n promise.resolve();\n this._settleReconnectionPromiseResolvers = Maybe.zero();\n });\n this._isDeviceReady = true;\n }\n }\n\n /**\n * Main event handler for BLE notify characteristic\n * Call _onReceiveSetupApduResponse if device mtu is not set\n * Call receiveApdu otherwise\n * @param event\n */\n private onNotifyCharacteristicValueChanged = (event: Event) => {\n if (!this.isDataViewEvent(event)) {\n return;\n }\n const {\n target: {\n value: { buffer },\n },\n } = event;\n if (buffer instanceof ArrayBuffer) {\n if (!this._isDeviceReady) {\n this.onReceiveSetupApduResponse(buffer);\n } else {\n this.receiveApdu(buffer);\n }\n }\n };\n\n /**\n * Setup BleDeviceConnection\n *\n * The device is considered as ready once the mtu had been set\n * APDU 0x0800000000 is used to get this mtu size\n */\n public async setup() {\n const requestMtuApdu = Uint8Array.from([0x08, 0x00, 0x00, 0x00, 0x00]);\n\n await this._notifyCharacteristic.startNotifications();\n await this._writeCharacteristic.writeValueWithoutResponse(requestMtuApdu);\n }\n\n /**\n * Receive APDU response\n * Resolve sendApdu promise once the framer receives all the frames of the response\n * @param data\n */\n receiveApdu(data: ArrayBuffer) {\n const response = this._apduReceiver.handleFrame(new Uint8Array(data));\n\n response\n .map((maybeApduResponse) => {\n maybeApduResponse.map((apduResponse) => {\n this._logger.debug(\"Received APDU Response\", {\n data: { response: apduResponse },\n });\n this._sendApduPromiseResolver.map(({ resolve }) =>\n resolve(Right(apduResponse)),\n );\n });\n })\n .mapLeft((error) => {\n this._sendApduPromiseResolver.map(({ resolve }) =>\n resolve(Left(error)),\n );\n });\n }\n\n /**\n * Send apdu if the mtu had been set\n *\n * Get all frames for a given APDU\n * Save a promise that would be completed once the response had been received\n * @param apdu\n * @param triggersDisconnection\n */\n async sendApdu(\n apdu: Uint8Array,\n triggersDisconnection?: boolean,\n ): Promise<Either<DmkError, ApduResponse>> {\n if (!this._isDeviceReady) {\n return Promise.resolve(\n Left(new DeviceNotInitializedError(\"Unknown MTU\")),\n );\n }\n // Create a promise that would be resolved once the response had been received\n const resultPromise = new Promise<Either<DmkError, ApduResponse>>(\n (resolve) => {\n this._sendApduPromiseResolver = Maybe.of({\n resolve,\n });\n },\n );\n const frames = this._apduSender.mapOrDefault(\n (apduSender) => apduSender.getFrames(apdu),\n [],\n );\n for (const frame of frames) {\n try {\n this._logger.debug(\"Sending Frame\", {\n data: { frame: frame.getRawData() },\n });\n await this._writeCharacteristic.writeValueWithoutResponse(\n frame.getRawData(),\n );\n } catch (error) {\n this._logger.error(\"Error sending frame\", { data: { error } });\n }\n }\n const response = await resultPromise;\n this._sendApduPromiseResolver = Maybe.zero();\n return response.caseOf({\n Right: async (apduResponse) => {\n if (\n triggersDisconnection &&\n CommandUtils.isSuccessResponse(apduResponse)\n ) {\n const reconnectionRes = await this.setupWaitForReconnection();\n return reconnectionRes.map(() => apduResponse);\n } else {\n return Right(apduResponse);\n }\n },\n Left: async (error) => Promise.resolve(Left(error)),\n });\n }\n\n /**\n * Typeguard to check if an event contains target value of type DataView\n *\n * @param event\n * @private\n */\n private isDataViewEvent(event: Event): event is DataViewEvent {\n return (\n event.target !== null &&\n \"value\" in event.target &&\n event.target.value instanceof DataView\n );\n }\n\n /**\n * Setup a promise that would be resolved once the device is reconnected\n *\n * @private\n */\n private setupWaitForReconnection(): Promise<Either<DmkError, void>> {\n return new Promise<Either<DmkError, void>>((resolve) => {\n this._settleReconnectionPromiseResolvers = Maybe.of({\n resolve: () => resolve(Right(undefined)),\n reject: (error: DmkError) => resolve(Left(error)),\n });\n });\n }\n\n /**\n * Reconnect to the device by resetting new ble characteristics\n * @param writeCharacteristic\n * @param notifyCharacteristic\n */\n public async reconnect(\n writeCharacteristic: BluetoothRemoteGATTCharacteristic,\n notifyCharacteristic: BluetoothRemoteGATTCharacteristic,\n ) {\n this._isDeviceReady = false;\n this.notifyCharacteristic = notifyCharacteristic;\n this.writeCharacteristic = writeCharacteristic;\n await this.setup();\n }\n\n /**\n * Disconnect from the device\n */\n public disconnect() {\n // if a reconnection promise is pending, reject it\n this._settleReconnectionPromiseResolvers.ifJust((promise) => {\n promise.reject(new ReconnectionFailedError());\n this._settleReconnectionPromiseResolvers = Maybe.zero();\n });\n this._isDeviceReady = false;\n }\n}\n"],
5
- "mappings": "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",
6
- "names": ["CommandUtils", "DeviceNotInitializedError", "ReconnectionFailedError", "Left", "Maybe", "Nothing", "Right", "BleDeviceConnection", "writeCharacteristic", "notifyCharacteristic", "apduSenderFactory", "apduReceiverFactory", "loggerServiceFactory", "value", "mtuResponse", "frameSize", "promise", "event", "buffer", "requestMtuApdu", "data", "maybeApduResponse", "apduResponse", "resolve", "error", "apdu", "triggersDisconnection", "resultPromise", "frames", "apduSender", "frame", "response"]
7
- }
@@ -1,2 +0,0 @@
1
- import{ApduResponse as p,defaultApduReceiverServiceStubBuilder as l,defaultApduSenderServiceStubBuilder as S,DeviceNotInitializedError as f}from"@ledgerhq/device-management-kit";import{Left as h,Right as v}from"purify-ts";import{bleCharacteristicStubBuilder as u}from"../model/BleDevice.stub";import{BleDeviceConnection as s}from"./BleDeviceConnection";const A=new Uint8Array([8,0,0,0,0]),d=new Uint8Array([0,0,0,0,0,66]),x=Uint8Array.from([0,0,0,0,0,0,0,0]);class w{subscribers=[];tag;constructor(i,r){this.subscribers=i,this.tag=r}error=jest.fn();warn=jest.fn();info=jest.fn();debug=jest.fn()}describe("BleDeviceConnection",()=>{let t,i,r,o;const n=e=>new w([],e);beforeEach(()=>{t=u(),i=u(),r=jest.fn(()=>S(void 0,n)),o=jest.fn(()=>l(void 0,n))});function a(e,c=Uint8Array.from([])){e.onNotifyCharacteristicValueChanged({target:{value:new DataView(c.buffer)}})}describe("sendApdu",()=>{it("should return an error if the device isn't setup",async()=>{const c=await new s({writeCharacteristic:t,notifyCharacteristic:i,apduSenderFactory:r,apduReceiverFactory:o},n).sendApdu(Uint8Array.from([]));expect(c).toStrictEqual(h(new f("Unknown MTU")))}),it("should send apdu without error if device is setup",async()=>{const e=new s({writeCharacteristic:t,notifyCharacteristic:i,apduSenderFactory:r,apduReceiverFactory:o},n);a(e,d);const c=e.sendApdu(new Uint8Array([]));a(e,x),expect(t.writeValueWithoutResponse).toHaveBeenCalledTimes(1),expect(await c).toStrictEqual(v(new p({statusCode:Uint8Array.from([]),data:Uint8Array.from([])})))})}),describe("setup",()=>{it("should send the apdu 0x0800000000 to get mtu size",async()=>{await new s({writeCharacteristic:t,notifyCharacteristic:i,apduSenderFactory:r,apduReceiverFactory:o},n).setup(),expect(t.writeValueWithoutResponse).toHaveBeenCalledWith(new Uint8Array(A))}),it("should setup apduSender with the correct mtu size",()=>{const e=new s({writeCharacteristic:t,notifyCharacteristic:i,apduSenderFactory:r,apduReceiverFactory:o},n);a(e,d),expect(r).toHaveBeenCalledWith({frameSize:66})})})});
2
- //# sourceMappingURL=BleDeviceConnection.test.js.map
@@ -1,7 +0,0 @@
1
- {
2
- "version": 3,
3
- "sources": ["../../../../src/api/transport/BleDeviceConnection.test.ts"],
4
- "sourcesContent": ["import {\n type ApduReceiverService,\n ApduResponse,\n type ApduSenderService,\n defaultApduReceiverServiceStubBuilder,\n defaultApduSenderServiceStubBuilder,\n DeviceNotInitializedError,\n type LoggerPublisherService,\n type LoggerSubscriberService,\n} from \"@ledgerhq/device-management-kit\";\nimport { Left, Right } from \"purify-ts\";\n\nimport { bleCharacteristicStubBuilder } from \"@api/model/BleDevice.stub\";\n\nimport { BleDeviceConnection, type DataViewEvent } from \"./BleDeviceConnection\";\n\nconst GET_MTU_APDU = new Uint8Array([0x08, 0x00, 0x00, 0x00, 0x00]);\nconst GET_MTU_APDU_RESPONSE = new Uint8Array([\n 0x00, 0x00, 0x00, 0x00, 0x00, 0x42,\n]);\nconst EMPTY_APDU_RESPONSE = Uint8Array.from([\n 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n]);\n\nclass LoggerPublisherServiceStub implements LoggerPublisherService {\n subscribers: LoggerSubscriberService[] = [];\n tag: string;\n constructor(subscribers: LoggerSubscriberService[], tag: string) {\n this.subscribers = subscribers;\n this.tag = tag;\n }\n error = jest.fn();\n warn = jest.fn();\n info = jest.fn();\n debug = jest.fn();\n}\n\ndescribe(\"BleDeviceConnection\", () => {\n let writeCharacteristic: BluetoothRemoteGATTCharacteristic;\n let notifyCharacteristic: BluetoothRemoteGATTCharacteristic;\n let apduSenderFactory: () => ApduSenderService;\n let apduReceiverFactory: () => ApduReceiverService;\n const logger = (tag: string) => new LoggerPublisherServiceStub([], tag);\n\n beforeEach(() => {\n writeCharacteristic = bleCharacteristicStubBuilder();\n notifyCharacteristic = bleCharacteristicStubBuilder();\n apduSenderFactory = jest.fn(() =>\n defaultApduSenderServiceStubBuilder(undefined, logger),\n );\n apduReceiverFactory = jest.fn(() =>\n defaultApduReceiverServiceStubBuilder(undefined, logger),\n );\n });\n\n function receiveApdu(\n connection: BleDeviceConnection,\n buffer: Uint8Array = Uint8Array.from([]),\n ) {\n // @ts-expect-error private function call to mock web ble response\n connection.onNotifyCharacteristicValueChanged({\n target: {\n value: new DataView(buffer.buffer),\n },\n } as DataViewEvent);\n }\n\n describe(\"sendApdu\", () => {\n it(\"should return an error if the device isn't setup\", async () => {\n // given\n const connection = new BleDeviceConnection(\n {\n writeCharacteristic,\n notifyCharacteristic,\n apduSenderFactory,\n apduReceiverFactory,\n },\n logger,\n );\n // when\n const errorOrApduResponse = await connection.sendApdu(\n Uint8Array.from([]),\n );\n // then\n expect(errorOrApduResponse).toStrictEqual(\n Left(new DeviceNotInitializedError(\"Unknown MTU\")),\n );\n });\n\n it(\"should send apdu without error if device is setup\", async () => {\n // given\n const connection = new BleDeviceConnection(\n {\n writeCharacteristic,\n notifyCharacteristic,\n apduSenderFactory,\n apduReceiverFactory,\n },\n logger,\n );\n // when\n receiveApdu(connection, GET_MTU_APDU_RESPONSE);\n const response = connection.sendApdu(new Uint8Array([]));\n receiveApdu(connection, EMPTY_APDU_RESPONSE);\n // then\n expect(\n writeCharacteristic.writeValueWithoutResponse,\n ).toHaveBeenCalledTimes(1);\n expect(await response).toStrictEqual(\n Right(\n new ApduResponse({\n statusCode: Uint8Array.from([]),\n data: Uint8Array.from([]),\n }),\n ),\n );\n });\n });\n describe(\"setup\", () => {\n it(\"should send the apdu 0x0800000000 to get mtu size\", async () => {\n // given\n const connection = new BleDeviceConnection(\n {\n writeCharacteristic,\n notifyCharacteristic,\n apduSenderFactory,\n apduReceiverFactory,\n },\n logger,\n );\n // when\n await connection.setup();\n // then\n expect(\n writeCharacteristic.writeValueWithoutResponse,\n ).toHaveBeenCalledWith(new Uint8Array(GET_MTU_APDU));\n });\n it(\"should setup apduSender with the correct mtu size\", () => {\n // given\n const connection = new BleDeviceConnection(\n {\n writeCharacteristic,\n notifyCharacteristic,\n apduSenderFactory,\n apduReceiverFactory,\n },\n logger,\n );\n // when\n receiveApdu(connection, GET_MTU_APDU_RESPONSE);\n // then\n expect(apduSenderFactory).toHaveBeenCalledWith({ frameSize: 0x42 });\n });\n });\n});\n"],
5
- "mappings": "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",
6
- "names": ["ApduResponse", "defaultApduReceiverServiceStubBuilder", "defaultApduSenderServiceStubBuilder", "DeviceNotInitializedError", "Left", "Right", "bleCharacteristicStubBuilder", "BleDeviceConnection", "GET_MTU_APDU", "GET_MTU_APDU_RESPONSE", "EMPTY_APDU_RESPONSE", "LoggerPublisherServiceStub", "subscribers", "tag", "writeCharacteristic", "notifyCharacteristic", "apduSenderFactory", "apduReceiverFactory", "logger", "receiveApdu", "connection", "buffer", "errorOrApduResponse", "response"]
7
- }
@@ -1,98 +0,0 @@
1
- import { type ApduReceiverServiceFactory, type ApduResponse, type ApduSenderServiceFactory, type DeviceConnection, type DmkError, type LoggerPublisherService } from "@ledgerhq/device-management-kit";
2
- import { type Either } from "purify-ts";
3
- type BleDeviceConnectionConstructorArgs = {
4
- writeCharacteristic: BluetoothRemoteGATTCharacteristic;
5
- notifyCharacteristic: BluetoothRemoteGATTCharacteristic;
6
- apduSenderFactory: ApduSenderServiceFactory;
7
- apduReceiverFactory: ApduReceiverServiceFactory;
8
- };
9
- export type DataViewEvent = Event & {
10
- target: {
11
- value: DataView;
12
- };
13
- };
14
- export declare class BleDeviceConnection implements DeviceConnection {
15
- private _writeCharacteristic;
16
- private _notifyCharacteristic;
17
- private readonly _logger;
18
- private _apduSender;
19
- private readonly _apduSenderFactory;
20
- private readonly _apduReceiver;
21
- private _isDeviceReady;
22
- private _sendApduPromiseResolver;
23
- private _settleReconnectionPromiseResolvers;
24
- constructor({ writeCharacteristic, notifyCharacteristic, apduSenderFactory, apduReceiverFactory, }: BleDeviceConnectionConstructorArgs, loggerServiceFactory: (tag: string) => LoggerPublisherService);
25
- /**
26
- * NotifyCharacteristic setter
27
- * Register a listener on characteristic value change
28
- * @param notifyCharacteristic
29
- * @private
30
- */
31
- private set notifyCharacteristic(value);
32
- /**
33
- * WriteCharacteristic setter
34
- * @param writeCharacteristic
35
- * @private
36
- */
37
- private set writeCharacteristic(value);
38
- /**
39
- * Event handler to setup the mtu size in response of 0x0800000000 APDU
40
- * @param value
41
- * @private
42
- */
43
- private onReceiveSetupApduResponse;
44
- /**
45
- * Main event handler for BLE notify characteristic
46
- * Call _onReceiveSetupApduResponse if device mtu is not set
47
- * Call receiveApdu otherwise
48
- * @param event
49
- */
50
- private onNotifyCharacteristicValueChanged;
51
- /**
52
- * Setup BleDeviceConnection
53
- *
54
- * The device is considered as ready once the mtu had been set
55
- * APDU 0x0800000000 is used to get this mtu size
56
- */
57
- setup(): Promise<void>;
58
- /**
59
- * Receive APDU response
60
- * Resolve sendApdu promise once the framer receives all the frames of the response
61
- * @param data
62
- */
63
- receiveApdu(data: ArrayBuffer): void;
64
- /**
65
- * Send apdu if the mtu had been set
66
- *
67
- * Get all frames for a given APDU
68
- * Save a promise that would be completed once the response had been received
69
- * @param apdu
70
- * @param triggersDisconnection
71
- */
72
- sendApdu(apdu: Uint8Array, triggersDisconnection?: boolean): Promise<Either<DmkError, ApduResponse>>;
73
- /**
74
- * Typeguard to check if an event contains target value of type DataView
75
- *
76
- * @param event
77
- * @private
78
- */
79
- private isDataViewEvent;
80
- /**
81
- * Setup a promise that would be resolved once the device is reconnected
82
- *
83
- * @private
84
- */
85
- private setupWaitForReconnection;
86
- /**
87
- * Reconnect to the device by resetting new ble characteristics
88
- * @param writeCharacteristic
89
- * @param notifyCharacteristic
90
- */
91
- reconnect(writeCharacteristic: BluetoothRemoteGATTCharacteristic, notifyCharacteristic: BluetoothRemoteGATTCharacteristic): Promise<void>;
92
- /**
93
- * Disconnect from the device
94
- */
95
- disconnect(): void;
96
- }
97
- export {};
98
- //# sourceMappingURL=BleDeviceConnection.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"BleDeviceConnection.d.ts","sourceRoot":"","sources":["../../../../src/api/transport/BleDeviceConnection.ts"],"names":[],"mappings":"AAAA,OAAO,EAEL,KAAK,0BAA0B,EAC/B,KAAK,YAAY,EAEjB,KAAK,wBAAwB,EAE7B,KAAK,gBAAgB,EAErB,KAAK,QAAQ,EACb,KAAK,sBAAsB,EAE5B,MAAM,iCAAiC,CAAC;AACzC,OAAO,EAAE,KAAK,MAAM,EAA+B,MAAM,WAAW,CAAC;AAErE,KAAK,kCAAkC,GAAG;IACxC,mBAAmB,EAAE,iCAAiC,CAAC;IACvD,oBAAoB,EAAE,iCAAiC,CAAC;IACxD,iBAAiB,EAAE,wBAAwB,CAAC;IAC5C,mBAAmB,EAAE,0BAA0B,CAAC;CACjD,CAAC;AAEF,MAAM,MAAM,aAAa,GAAG,KAAK,GAAG;IAClC,MAAM,EAAE;QACN,KAAK,EAAE,QAAQ,CAAC;KACjB,CAAC;CACH,CAAC;AAEF,qBAAa,mBAAoB,YAAW,gBAAgB;IAC1D,OAAO,CAAC,oBAAoB,CAAoC;IAChE,OAAO,CAAC,qBAAqB,CAAoC;IACjE,OAAO,CAAC,QAAQ,CAAC,OAAO,CAAyB;IACjD,OAAO,CAAC,WAAW,CAA2B;IAC9C,OAAO,CAAC,QAAQ,CAAC,kBAAkB,CAA2B;IAC9D,OAAO,CAAC,QAAQ,CAAC,aAAa,CAAsB;IACpD,OAAO,CAAC,cAAc,CAAU;IAChC,OAAO,CAAC,wBAAwB,CAE7B;IACH,OAAO,CAAC,mCAAmC,CAGxC;gBAGD,EACE,mBAAmB,EACnB,oBAAoB,EACpB,iBAAiB,EACjB,mBAAmB,GACpB,EAAE,kCAAkC,EACrC,oBAAoB,EAAE,CAAC,GAAG,EAAE,MAAM,KAAK,sBAAsB;IAe/D;;;;;OAKG;IACH,OAAO,KAAK,oBAAoB,QAM/B;IAED;;;;OAIG;IACH,OAAO,KAAK,mBAAmB,QAI9B;IAED;;;;OAIG;IACH,OAAO,CAAC,0BAA0B;IAclC;;;;;OAKG;IACH,OAAO,CAAC,kCAAkC,CAgBxC;IAEF;;;;;OAKG;IACU,KAAK;IAOlB;;;;OAIG;IACH,WAAW,CAAC,IAAI,EAAE,WAAW;IAqB7B;;;;;;;OAOG;IACG,QAAQ,CACZ,IAAI,EAAE,UAAU,EAChB,qBAAqB,CAAC,EAAE,OAAO,GAC9B,OAAO,CAAC,MAAM,CAAC,QAAQ,EAAE,YAAY,CAAC,CAAC;IAgD1C;;;;;OAKG;IACH,OAAO,CAAC,eAAe;IAQvB;;;;OAIG;IACH,OAAO,CAAC,wBAAwB;IAShC;;;;OAIG;IACU,SAAS,CACpB,mBAAmB,EAAE,iCAAiC,EACtD,oBAAoB,EAAE,iCAAiC;IAQzD;;OAEG;IACI,UAAU;CAQlB"}
@@ -1,2 +0,0 @@
1
- export {};
2
- //# sourceMappingURL=BleDeviceConnection.test.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"BleDeviceConnection.test.d.ts","sourceRoot":"","sources":["../../../../src/api/transport/BleDeviceConnection.test.ts"],"names":[],"mappings":""}