@ledgerhq/device-transport-kit-speculos 0.0.0-develop-20250904001204 → 0.0.0-e2e-speculos-20250904104129

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 (38) hide show
  1. package/lib/cjs/package.json +1 -1
  2. package/lib/cjs/src/api/QuietSpeculosTransport.js +2 -0
  3. package/lib/cjs/src/api/QuietSpeculosTransport.js.map +7 -0
  4. package/lib/cjs/src/api/SpeculosTransport.js +1 -1
  5. package/lib/cjs/src/api/SpeculosTransport.js.map +3 -3
  6. package/lib/cjs/src/index.js +1 -1
  7. package/lib/cjs/src/index.js.map +2 -2
  8. package/lib/cjs/src/internal/datasource/HttpLegacySpeculosDatasource.js +2 -0
  9. package/lib/cjs/src/internal/datasource/HttpLegacySpeculosDatasource.js.map +7 -0
  10. package/lib/cjs/src/internal/datasource/HttpSpeculosDatasource.js +1 -1
  11. package/lib/cjs/src/internal/datasource/HttpSpeculosDatasource.js.map +3 -3
  12. package/lib/cjs/src/internal/datasource/SpeculosDatasource.js +1 -1
  13. package/lib/cjs/src/internal/datasource/SpeculosDatasource.js.map +1 -1
  14. package/lib/esm/package.json +1 -1
  15. package/lib/esm/src/api/QuietSpeculosTransport.js +2 -0
  16. package/lib/esm/src/api/QuietSpeculosTransport.js.map +7 -0
  17. package/lib/esm/src/api/SpeculosTransport.js +1 -1
  18. package/lib/esm/src/api/SpeculosTransport.js.map +3 -3
  19. package/lib/esm/src/index.js +1 -1
  20. package/lib/esm/src/index.js.map +2 -2
  21. package/lib/esm/src/internal/datasource/HttpLegacySpeculosDatasource.js +2 -0
  22. package/lib/esm/src/internal/datasource/HttpLegacySpeculosDatasource.js.map +7 -0
  23. package/lib/esm/src/internal/datasource/HttpSpeculosDatasource.js +1 -1
  24. package/lib/esm/src/internal/datasource/HttpSpeculosDatasource.js.map +3 -3
  25. package/lib/types/src/api/QuietSpeculosTransport.d.ts +29 -0
  26. package/lib/types/src/api/QuietSpeculosTransport.d.ts.map +1 -0
  27. package/lib/types/src/api/SpeculosTransport.d.ts +3 -2
  28. package/lib/types/src/api/SpeculosTransport.d.ts.map +1 -1
  29. package/lib/types/src/index.d.ts +1 -0
  30. package/lib/types/src/index.d.ts.map +1 -1
  31. package/lib/types/src/internal/datasource/HttpLegacySpeculosDatasource.d.ts +10 -0
  32. package/lib/types/src/internal/datasource/HttpLegacySpeculosDatasource.d.ts.map +1 -0
  33. package/lib/types/src/internal/datasource/HttpSpeculosDatasource.d.ts +0 -1
  34. package/lib/types/src/internal/datasource/HttpSpeculosDatasource.d.ts.map +1 -1
  35. package/lib/types/src/internal/datasource/SpeculosDatasource.d.ts +0 -1
  36. package/lib/types/src/internal/datasource/SpeculosDatasource.d.ts.map +1 -1
  37. package/lib/types/tsconfig.prod.tsbuildinfo +1 -1
  38. package/package.json +5 -5
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@ledgerhq/device-transport-kit-speculos",
3
- "version": "1.0.0",
3
+ "version": "0.0.1",
4
4
  "license": "Apache-2.0",
5
5
  "private": false,
6
6
  "exports": {
@@ -0,0 +1,2 @@
1
+ "use strict";var u=Object.defineProperty;var m=Object.getOwnPropertyDescriptor;var y=Object.getOwnPropertyNames;var S=Object.prototype.hasOwnProperty;var b=(s,e)=>{for(var r in e)u(s,r,{get:e[r],enumerable:!0})},f=(s,e,r,o)=>{if(e&&typeof e=="object"||typeof e=="function")for(let t of y(e))!S.call(s,t)&&t!==r&&u(s,t,{get:()=>e[t],enumerable:!(o=m(e,t))||o.enumerable});return s};var T=s=>f(u({},"__esModule",{value:!0}),s);var A={};b(A,{QuietSpeculosTransport:()=>D,quietSpeculosTransportFactory:()=>I});module.exports=T(A);var n=require("@ledgerhq/device-management-kit"),c=require("purify-ts"),l=require("rxjs"),g=require("../internal/datasource/HttpLegacySpeculosDatasource"),v=require("./SpeculosTransport");class D{logger;identifier=v.speculosIdentifier;_speculosDataSource;connectedDevice=null;disconnectInterval=null;speculosDevice={id:"SpeculosID",deviceModel:{id:n.DeviceModelId.STAX,productName:"Speculos - App Name - version",usbProductId:16,bootloaderUsbProductId:1,getBlockSize(){return 32},blockSize:32,usbOnly:!0,memorySize:320*1024,masks:[823132160]},transport:this.identifier};constructor(e,r,o){this.logger=e("QuietSpeculosTransport"),this._speculosDataSource=new g.HttpLegacySpeculosDatasource(o,1e4,"ldmk-transport-speculos")}isSupported(){return!0}getIdentifier(){return this.identifier}listenToAvailableDevices(){return(0,l.from)([[this.speculosDevice]])}startDiscovering(){return this.logger.debug("startDiscovering"),(0,l.from)([this.speculosDevice])}stopDiscovering(){this.logger.debug("stopDiscovering")}async connect(e){this.logger.debug("connect");const r=await this._speculosDataSource.postAdpu("B0010000");this.logger.debug(`Hex Response: ${r}`);const o=this.createApduResponse(r),t=new n.ApduParser(o);t.extract8BitUInt();const i=t.encodeToString(t.extractFieldLVEncoded()),p=t.encodeToString(t.extractFieldLVEncoded());this.logger.debug(`App Name: ${i} and version ${p}`);const d=e.deviceId;try{const a={sendApdu:h=>this.sendApdu(d,e.deviceId,e.onDisconnect,h),deviceModel:{...this.speculosDevice.deviceModel,productName:`Speculos - ${i} - ${p}`,getBlockSize(){return 32}},transport:this.identifier,id:"SpeculosID",type:"USB"};return this.connectedDevice=a,(0,c.Right)(a)}catch(a){return(0,c.Left)(new n.OpeningConnectionError(a))}}async disconnect(e){return this.logger.debug("disconnect"),this.connectedDevice=null,this.disconnectInterval&&clearInterval(this.disconnectInterval),Promise.resolve((0,c.Right)(void 0))}async sendApdu(e,r,o,t){try{const i=(0,n.bufferToHexaString)(t).substring(2).toUpperCase();this.logger.debug(`[QuietSpeculosTransport] send APDU: ${i}`);const p=await this._speculosDataSource.postAdpu(i),d=this.createApduResponse(p);return(0,c.Right)(d)}catch(i){return this.connectedDevice&&(this.logger.debug("disconnecting due to APDU error"),o(r),await this.disconnect({connectedDevice:this.connectedDevice})),(0,c.Left)(new n.GeneralDmkError(i))}}createApduResponse(e){const r=e.slice(-4),o=e.slice(0,-4);return this.logger.debug(`[QuietSpeculosTransport] Status code hex: ${r}`),this.logger.debug(`[QuietSpeculosTransport] data hex: ${o}`),{statusCode:this.fromHexString(r),data:this.fromHexString(o)}}fromHexString(e){return e?new Uint8Array(e.match(/.{1,2}/g).map(r=>parseInt(r,16))):Uint8Array.from([])}}const I=(s="http://127.0.0.1:5000")=>({config:e,loggerServiceFactory:r})=>new D(r,e,s);0&&(module.exports={QuietSpeculosTransport,quietSpeculosTransportFactory});
2
+ //# sourceMappingURL=QuietSpeculosTransport.js.map
@@ -0,0 +1,7 @@
1
+ {
2
+ "version": 3,
3
+ "sources": ["../../../../src/api/QuietSpeculosTransport.ts"],
4
+ "sourcesContent": ["import {\n ApduParser,\n type ApduResponse,\n bufferToHexaString,\n type ConnectError,\n type DeviceId,\n DeviceModelId,\n type DisconnectHandler,\n type DmkConfig,\n type DmkError,\n GeneralDmkError,\n type LoggerPublisherService,\n OpeningConnectionError,\n type Transport,\n type TransportConnectedDevice,\n type TransportDiscoveredDevice,\n type TransportFactory,\n type TransportIdentifier,\n} from \"@ledgerhq/device-management-kit\";\nimport { type Either, Left, Right } from \"purify-ts\";\nimport { from, type Observable } from \"rxjs\";\n\nimport { HttpLegacySpeculosDatasource } from \"@internal/datasource/HttpLegacySpeculosDatasource\";\n\nimport { speculosIdentifier } from \"./SpeculosTransport\";\n\nexport class QuietSpeculosTransport implements Transport {\n private logger: LoggerPublisherService;\n private readonly identifier: TransportIdentifier = speculosIdentifier;\n private readonly _speculosDataSource: HttpLegacySpeculosDatasource;\n\n private connectedDevice: TransportConnectedDevice | null = null;\n private disconnectInterval: NodeJS.Timeout | null = null;\n\n private readonly speculosDevice: TransportDiscoveredDevice = {\n id: \"SpeculosID\",\n deviceModel: {\n id: DeviceModelId.STAX,\n productName: \"Speculos - App Name - version\",\n usbProductId: 0x10,\n bootloaderUsbProductId: 0x0001,\n getBlockSize() {\n return 32;\n },\n blockSize: 32,\n usbOnly: true,\n memorySize: 320 * 1024,\n masks: [0x31100000],\n },\n transport: this.identifier,\n };\n\n constructor(\n loggerServiceFactory: (tag: string) => LoggerPublisherService,\n _config: DmkConfig,\n speculosUrl: string,\n ) {\n this.logger = loggerServiceFactory(\"QuietSpeculosTransport\");\n this._speculosDataSource = new HttpLegacySpeculosDatasource(\n speculosUrl,\n 10000,\n \"ldmk-transport-speculos\",\n );\n }\n\n isSupported(): boolean {\n return true;\n }\n\n getIdentifier(): TransportIdentifier {\n return this.identifier;\n }\n\n listenToAvailableDevices(): Observable<TransportDiscoveredDevice[]> {\n return from([[this.speculosDevice]]);\n }\n\n startDiscovering(): Observable<TransportDiscoveredDevice> {\n this.logger.debug(\"startDiscovering\");\n return from([this.speculosDevice]);\n }\n\n stopDiscovering(): void {\n this.logger.debug(\"stopDiscovering\");\n }\n\n async connect(params: {\n deviceId: DeviceId;\n onDisconnect: DisconnectHandler;\n }): Promise<Either<ConnectError, TransportConnectedDevice>> {\n this.logger.debug(\"connect\");\n\n const hexResponse = await this._speculosDataSource.postAdpu(\"B0010000\");\n this.logger.debug(`Hex Response: ${hexResponse}`);\n\n const apduResponse = this.createApduResponse(hexResponse);\n const parser = new ApduParser(apduResponse);\n\n parser.extract8BitUInt();\n const appName = parser.encodeToString(parser.extractFieldLVEncoded());\n const appVersion = parser.encodeToString(parser.extractFieldLVEncoded());\n\n this.logger.debug(`App Name: ${appName} and version ${appVersion}`);\n\n const sessionId: string = params.deviceId;\n try {\n const connectedDevice: TransportConnectedDevice = {\n sendApdu: (apdu: Uint8Array) =>\n this.sendApdu(sessionId, params.deviceId, params.onDisconnect, apdu),\n deviceModel: {\n ...this.speculosDevice.deviceModel,\n productName: `Speculos - ${appName} - ${appVersion}`,\n getBlockSize() {\n return 32;\n },\n },\n transport: this.identifier,\n id: \"SpeculosID\",\n type: \"USB\",\n };\n\n this.connectedDevice = connectedDevice;\n\n return Right(connectedDevice);\n } catch (error) {\n return Left(new OpeningConnectionError(error as Error));\n }\n }\n\n async disconnect(_params: {\n connectedDevice: TransportConnectedDevice;\n }): Promise<Either<DmkError, void>> {\n this.logger.debug(\"disconnect\");\n this.connectedDevice = null;\n if (this.disconnectInterval) clearInterval(this.disconnectInterval);\n return Promise.resolve(Right(undefined));\n }\n\n async sendApdu(\n _sessionId: string,\n deviceId: DeviceId,\n onDisconnect: DisconnectHandler,\n apdu: Uint8Array,\n ): Promise<Either<DmkError, ApduResponse>> {\n try {\n const hex = bufferToHexaString(apdu).substring(2).toUpperCase();\n this.logger.debug(`[QuietSpeculosTransport] send APDU: ${hex}`);\n const hexResponse = await this._speculosDataSource.postAdpu(hex);\n const resp = this.createApduResponse(hexResponse);\n return Right(resp);\n } catch (error) {\n if (this.connectedDevice) {\n this.logger.debug(\"disconnecting due to APDU error\");\n onDisconnect(deviceId);\n await this.disconnect({ connectedDevice: this.connectedDevice });\n }\n return Left(new GeneralDmkError(error as Error));\n }\n }\n\n private createApduResponse(hexApdu: string): ApduResponse {\n const sw = hexApdu.slice(-4);\n const payload = hexApdu.slice(0, -4);\n this.logger.debug(`[QuietSpeculosTransport] Status code hex: ${sw}`);\n this.logger.debug(`[QuietSpeculosTransport] data hex: ${payload}`);\n return {\n statusCode: this.fromHexString(sw),\n data: this.fromHexString(payload),\n };\n }\n\n private fromHexString(hexString: string): Uint8Array {\n if (!hexString) return Uint8Array.from([]);\n return new Uint8Array(\n hexString.match(/.{1,2}/g)!.map((b) => parseInt(b, 16)),\n );\n }\n}\n\nexport const quietSpeculosTransportFactory: (\n speculosUrl?: string,\n legacyE2ECompatibility?: boolean,\n) => TransportFactory =\n (speculosUrl = \"http://127.0.0.1:5000\") =>\n ({ config, loggerServiceFactory }) =>\n new QuietSpeculosTransport(loggerServiceFactory, config, speculosUrl);\n"],
5
+ "mappings": "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",
6
+ "names": ["QuietSpeculosTransport_exports", "__export", "QuietSpeculosTransport", "quietSpeculosTransportFactory", "__toCommonJS", "import_device_management_kit", "import_purify_ts", "import_rxjs", "import_HttpLegacySpeculosDatasource", "import_SpeculosTransport", "loggerServiceFactory", "_config", "speculosUrl", "params", "hexResponse", "apduResponse", "parser", "appName", "appVersion", "sessionId", "connectedDevice", "apdu", "error", "_params", "_sessionId", "deviceId", "onDisconnect", "hex", "resp", "hexApdu", "sw", "payload", "hexString", "b", "config"]
7
+ }
@@ -1,2 +1,2 @@
1
- "use strict";var l=Object.defineProperty;var S=Object.getOwnPropertyDescriptor;var b=Object.getOwnPropertyNames;var m=Object.prototype.hasOwnProperty;var f=(n,e)=>{for(var t in e)l(n,t,{get:e[t],enumerable:!0})},y=(n,e,t,o)=>{if(e&&typeof e=="object"||typeof e=="function")for(let r of b(e))!m.call(n,r)&&r!==t&&l(n,r,{get:()=>e[r],enumerable:!(o=S(e,r))||o.enumerable});return n};var I=n=>y(l({},"__esModule",{value:!0}),n);var A={};f(A,{SpeculosTransport:()=>D,speculosIdentifier:()=>g,speculosTransportFactory:()=>T});module.exports=I(A);var s=require("@ledgerhq/device-management-kit"),c=require("purify-ts"),u=require("rxjs"),v=require("../internal/datasource/HttpSpeculosDatasource");const g="SPECULOS_HTTP_TRANSPORT";class D{logger;identifier=g;_speculosDataSource;connectedDevice=null;disconnectInterval=null;speculosDevice={id:"SpeculosID",deviceModel:{id:s.DeviceModelId.STAX,productName:"Speculos - App Name - version",usbProductId:16,bootloaderUsbProductId:1,getBlockSize(){return 32},blockSize:32,usbOnly:!0,memorySize:320*1024,masks:[823132160]},transport:this.identifier};constructor(e,t,o){this.logger=e("SpeculosTransport"),this._speculosDataSource=new v.HttpSpeculosDatasource(o)}isSupported(){return!0}getIdentifier(){return this.identifier}listenToAvailableDevices(){return(0,u.from)([[this.speculosDevice]])}startDiscovering(){return this.logger.debug("startDiscovering"),(0,u.from)([this.speculosDevice])}stopDiscovering(){this.logger.debug("stopDiscovering")}async connect(e){this.logger.debug("connect");const t=await this._speculosDataSource.postAdpu("B0010000");this.logger.debug(`Hex Response: ${t}`);const o=this.createApduResponse(t),r=new s.ApduParser(o);r.extract8BitUInt();const i=r.encodeToString(r.extractFieldLVEncoded()),a=r.encodeToString(r.extractFieldLVEncoded());this.logger.debug(`App Name: ${i} and version ${a}`);const p=e.deviceId;try{const d={sendApdu:h=>this.sendApdu(p,e.deviceId,e.onDisconnect,h),deviceModel:{...this.speculosDevice.deviceModel,productName:`Speculos - ${i} - ${a}`,getBlockSize(){return 32}},transport:this.identifier,id:"SpeculosID",type:"USB"};return this.connectedDevice=d,this.listenForDisconnect(e.onDisconnect,e.deviceId),(0,c.Right)(d)}catch(d){return(0,c.Left)(new s.OpeningConnectionError(d))}}async disconnect(e){return this.logger.debug("disconnect"),this.connectedDevice=null,Promise.resolve((0,c.Right)(void 0))}async sendApdu(e,t,o,r){try{const i=(0,s.bufferToHexaString)(r).substring(2);this.logger.debug(`send APDU: ${i}`);const a=await this._speculosDataSource.postAdpu(i),p=this.createApduResponse(a);return(0,c.Right)(p)}catch(i){return this.connectedDevice&&(this.logger.debug("disconnecting"),o(t),this.disconnect({connectedDevice:this.connectedDevice}),this.disconnectInterval&&clearInterval(this.disconnectInterval)),(0,c.Left)(new s.GeneralDmkError(i))}}createApduResponse(e){return this.logger.debug(`Status code hex: ${e.substring(e.length-4,e.length)}`),this.logger.debug(`data hex: ${e.substring(0,e.length-4)}`),{statusCode:this.fromHexString(e.substring(e.length-4,e.length)),data:this.fromHexString(e.substring(0,e.length-4))}}fromHexString(e){return e?new Uint8Array(e.match(/.{1,2}/g).map(t=>parseInt(t,16))):Uint8Array.from([])}listenForDisconnect(e,t){this.disconnectInterval=setInterval(async()=>{await this._speculosDataSource.isServerAvailable()||(this.logger.info(`Speculos server unavailable, disconnecting device ${t}`),e(t),this.connectedDevice&&await this.disconnect({connectedDevice:this.connectedDevice}),this.disconnectInterval&&clearInterval(this.disconnectInterval))},2e3)}}const T=(n="http://127.0.0.1:5000")=>({config:e,loggerServiceFactory:t})=>new D(t,e,n);0&&(module.exports={SpeculosTransport,speculosIdentifier,speculosTransportFactory});
1
+ "use strict";var d=Object.defineProperty;var f=Object.getOwnPropertyDescriptor;var b=Object.getOwnPropertyNames;var S=Object.prototype.hasOwnProperty;var I=(o,e)=>{for(var t in e)d(o,t,{get:e[t],enumerable:!0})},T=(o,e,t,n)=>{if(e&&typeof e=="object"||typeof e=="function")for(let r of b(e))!S.call(o,r)&&r!==t&&d(o,r,{get:()=>e[r],enumerable:!(n=f(e,r))||n.enumerable});return o};var E=o=>T(d({},"__esModule",{value:!0}),o);var C={};I(C,{SpeculosTransport:()=>h,speculosIdentifier:()=>D,speculosTransportFactory:()=>A});module.exports=E(C);var i=require("@ledgerhq/device-management-kit"),u=require("axios"),c=require("purify-ts"),l=require("rxjs"),g=require("../internal/datasource/HttpLegacySpeculosDatasource"),v=require("../internal/datasource/HttpSpeculosDatasource");const D="SPECULOS_HTTP_TRANSPORT";class h{constructor(e,t,n,r){this.legacyE2ECompatibility=r;this.logger=e("SpeculosTransport"),this._speculosDataSource=this.legacyE2ECompatibility?new g.HttpLegacySpeculosDatasource(n):new v.HttpSpeculosDatasource(n)}logger;identifier=D;_speculosDataSource;connectedDevice=null;disconnectInterval=null;speculosDevice={id:"SpeculosID",deviceModel:{id:i.DeviceModelId.STAX,productName:"Speculos - App Name - version",usbProductId:16,bootloaderUsbProductId:1,getBlockSize(){return 32},blockSize:32,usbOnly:!0,memorySize:320*1024,masks:[823132160]},transport:this.identifier};isSupported(){return!0}getIdentifier(){return this.identifier}listenToAvailableDevices(){return(0,l.from)([[this.speculosDevice]])}startDiscovering(){return this.logger.debug("startDiscovering"),(0,l.from)([this.speculosDevice])}stopDiscovering(){this.logger.debug("stopDiscovering")}async connect(e){this.logger.debug("connect");const t=await this._speculosDataSource.postAdpu("B0010000");this.logger.debug(`Hex Response: ${t}`);const n=this.createApduResponse(t),r=new i.ApduParser(n);r.extract8BitUInt();const s=r.encodeToString(r.extractFieldLVEncoded()),a=r.encodeToString(r.extractFieldLVEncoded());this.logger.debug(`App Name: ${s} and version ${a}`);const y=e.deviceId;try{const p={sendApdu:m=>this.sendApdu(y,e.deviceId,e.onDisconnect,m),deviceModel:{...this.speculosDevice.deviceModel,productName:`Speculos - ${s} - ${a}`,getBlockSize(){return 32}},transport:this.identifier,id:"SpeculosID",type:"USB"};return this.connectedDevice=p,this.legacyE2ECompatibility||this.listenForDisconnect(e.onDisconnect,e.deviceId),(0,c.Right)(p)}catch(p){return(0,c.Left)(new i.OpeningConnectionError(p))}}async disconnect(e){return this.logger.debug("disconnect"),this.connectedDevice=null,Promise.resolve((0,c.Right)(void 0))}async sendApdu(e,t,n,r){try{const s=(0,i.bufferToHexaString)(r).substring(2);this.logger.debug(`send APDU: ${s}`);const a=await this._speculosDataSource.postAdpu(s);return(0,c.Right)(this.createApduResponse(a))}catch(s){return this.connectedDevice&&(this.logger.debug("disconnecting"),n(t),this.disconnect({connectedDevice:this.connectedDevice}),this.disconnectInterval&&clearInterval(this.disconnectInterval)),(0,c.Left)(new i.GeneralDmkError(s))}}createApduResponse(e){return this.logger.debug(`Status code hex: ${e.substring(e.length-4,e.length)}`),this.logger.debug(`data hex: ${e.substring(0,e.length-4)}`),{statusCode:this.fromHexString(e.substring(e.length-4,e.length)),data:this.fromHexString(e.substring(0,e.length-4))}}fromHexString(e){return e?new Uint8Array(e.match(/.{1,2}/g).map(t=>parseInt(t,16))):Uint8Array.from([])}listenForDisconnect(e,t){this.disconnectInterval=setInterval(async()=>{try{await this._speculosDataSource.postAdpu("B0010000")}catch(n){if(!(n instanceof u.AxiosError))return;this.logger.info(`Network error, disconnecting speculos device ${t}`),e(t),this.connectedDevice&&await this.disconnect({connectedDevice:this.connectedDevice}),this.disconnectInterval&&clearInterval(this.disconnectInterval)}},2e3)}}const A=(o="http://127.0.0.1:5000",e=!1)=>({config:t,loggerServiceFactory:n})=>new h(n,t,o,e);0&&(module.exports={SpeculosTransport,speculosIdentifier,speculosTransportFactory});
2
2
  //# sourceMappingURL=SpeculosTransport.js.map
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "version": 3,
3
3
  "sources": ["../../../../src/api/SpeculosTransport.ts"],
4
- "sourcesContent": ["import {\n ApduParser,\n type ApduResponse,\n bufferToHexaString,\n type ConnectError,\n type DeviceId,\n DeviceModelId,\n type DisconnectHandler,\n type DmkConfig,\n type DmkError,\n GeneralDmkError,\n type LoggerPublisherService,\n OpeningConnectionError,\n type Transport,\n type TransportConnectedDevice,\n type TransportDiscoveredDevice,\n type TransportFactory,\n type TransportIdentifier,\n} from \"@ledgerhq/device-management-kit\";\nimport { type Either, Left, Right } from \"purify-ts\";\nimport { from, type Observable } from \"rxjs\";\n\nimport { HttpSpeculosDatasource } from \"@internal/datasource/HttpSpeculosDatasource\";\nimport { type SpeculosDatasource } from \"@internal/datasource/SpeculosDatasource\";\n\nexport const speculosIdentifier: TransportIdentifier =\n \"SPECULOS_HTTP_TRANSPORT\";\n\nexport class SpeculosTransport implements Transport {\n private logger: LoggerPublisherService;\n private readonly identifier: TransportIdentifier = speculosIdentifier;\n private readonly _speculosDataSource: SpeculosDatasource;\n private connectedDevice: TransportConnectedDevice | null = null;\n private disconnectInterval: NodeJS.Timeout | null = null;\n private readonly speculosDevice: TransportDiscoveredDevice = {\n id: \"SpeculosID\", //TODO make it dynamic at creation\n deviceModel: {\n id: DeviceModelId.STAX,\n productName: \"Speculos - App Name - version\",\n usbProductId: 0x10,\n bootloaderUsbProductId: 0x0001,\n getBlockSize() {\n return 32;\n },\n blockSize: 32,\n usbOnly: true,\n memorySize: 320 * 1024,\n masks: [0x31100000],\n },\n transport: this.identifier,\n };\n\n constructor(\n loggerServiceFactory: (tag: string) => LoggerPublisherService,\n _config: DmkConfig,\n speculosUrl: string,\n ) {\n this.logger = loggerServiceFactory(\"SpeculosTransport\");\n this._speculosDataSource = new HttpSpeculosDatasource(speculosUrl); // See how to pass properly speculos config.\n }\n\n isSupported(): boolean {\n return true;\n }\n\n getIdentifier(): TransportIdentifier {\n return this.identifier;\n }\n\n listenToAvailableDevices(): Observable<TransportDiscoveredDevice[]> {\n return from([[this.speculosDevice]]);\n }\n\n startDiscovering(): Observable<TransportDiscoveredDevice> {\n this.logger.debug(\"startDiscovering\");\n return from([this.speculosDevice]);\n }\n\n stopDiscovering(): void {\n //DO NOTHING HERE\n this.logger.debug(\"stopDiscovering\");\n }\n\n async connect(params: {\n deviceId: DeviceId;\n onDisconnect: DisconnectHandler;\n }): Promise<Either<ConnectError, TransportConnectedDevice>> {\n this.logger.debug(\"connect\");\n\n const hexResponse = await this._speculosDataSource.postAdpu(\"B0010000\");\n this.logger.debug(`Hex Response: ${hexResponse}`);\n const apduResponse = this.createApduResponse(hexResponse);\n const parser = new ApduParser(apduResponse);\n\n //Copy paste from GetAppAndVersionCommand\n parser.extract8BitUInt(); //Need otherwise parser is not in the right position\n const appName = parser.encodeToString(parser.extractFieldLVEncoded());\n const appVersion = parser.encodeToString(parser.extractFieldLVEncoded());\n\n this.logger.debug(`App Name: ${appName} and version ${appVersion}`);\n\n const sessionId: string = params.deviceId;\n try {\n const connectedDevice: TransportConnectedDevice = {\n sendApdu: (apdu) => {\n return this.sendApdu(\n sessionId,\n params.deviceId,\n params.onDisconnect,\n apdu,\n );\n },\n deviceModel: {\n ...this.speculosDevice.deviceModel,\n productName: `Speculos - ${appName} - ${appVersion}`,\n getBlockSize() {\n return 32;\n },\n },\n transport: this.identifier,\n id: \"SpeculosID\", //TODO make it dynamic at creation\n type: \"USB\",\n };\n\n this.connectedDevice = connectedDevice;\n this.listenForDisconnect(params.onDisconnect, params.deviceId);\n return Right(connectedDevice);\n } catch (error) {\n return Left(new OpeningConnectionError(error as Error));\n }\n }\n\n async disconnect(_params: {\n connectedDevice: TransportConnectedDevice;\n }): Promise<Either<DmkError, void>> {\n this.logger.debug(\"disconnect\");\n this.connectedDevice = null;\n return Promise.resolve(Right(undefined));\n }\n\n async sendApdu(\n _sessionId: string,\n deviceId: DeviceId,\n onDisconnect: DisconnectHandler,\n apdu: Uint8Array,\n ): Promise<Either<DmkError, ApduResponse>> {\n try {\n const hexApdu = bufferToHexaString(apdu).substring(2);\n this.logger.debug(`send APDU: ${hexApdu}`);\n const hexResponse: string =\n await this._speculosDataSource.postAdpu(hexApdu);\n const apduResponse = this.createApduResponse(hexResponse);\n return Right(apduResponse);\n } catch (error) {\n if (this.connectedDevice) {\n this.logger.debug(\"disconnecting\");\n onDisconnect(deviceId);\n this.disconnect({\n connectedDevice: this.connectedDevice,\n });\n\n if (this.disconnectInterval) {\n clearInterval(this.disconnectInterval);\n }\n }\n return Left(new GeneralDmkError(error));\n }\n }\n\n private createApduResponse(hexApdu: string): ApduResponse {\n this.logger.debug(\n `Status code hex: ${hexApdu.substring(hexApdu.length - 4, hexApdu.length)}`,\n );\n this.logger.debug(`data hex: ${hexApdu.substring(0, hexApdu.length - 4)}`);\n\n const apduResponse = {\n statusCode: this.fromHexString(\n hexApdu.substring(hexApdu.length - 4, hexApdu.length),\n ),\n data: this.fromHexString(hexApdu.substring(0, hexApdu.length - 4)),\n };\n return apduResponse;\n }\n\n //TODO: Move this to a helper\n private fromHexString(hexString: string): Uint8Array {\n if (!hexString) {\n return Uint8Array.from([]);\n }\n return new Uint8Array(\n hexString.match(/.{1,2}/g)!.map((byte) => parseInt(byte, 16)),\n );\n }\n\n private listenForDisconnect(\n onDisconnect: DisconnectHandler,\n deviceId: DeviceId,\n ): void {\n this.disconnectInterval = setInterval(async () => {\n const isServerAvailable =\n await this._speculosDataSource.isServerAvailable();\n\n if (!isServerAvailable) {\n this.logger.info(\n `Speculos server unavailable, disconnecting device ${deviceId}`,\n );\n onDisconnect(deviceId);\n\n if (this.connectedDevice) {\n await this.disconnect({\n connectedDevice: this.connectedDevice,\n });\n }\n\n if (this.disconnectInterval) {\n clearInterval(this.disconnectInterval);\n }\n }\n }, 2000);\n }\n}\n\nexport const speculosTransportFactory: (\n speculosUrl?: string,\n) => TransportFactory =\n (speculosUrl = \"http://127.0.0.1:5000\") =>\n ({ config, loggerServiceFactory }) =>\n new SpeculosTransport(loggerServiceFactory, config, speculosUrl);\n"],
5
- "mappings": "yaAAA,IAAAA,EAAA,GAAAC,EAAAD,EAAA,uBAAAE,EAAA,uBAAAC,EAAA,6BAAAC,IAAA,eAAAC,EAAAL,GAAA,IAAAM,EAkBO,2CACPC,EAAyC,qBACzCC,EAAsC,gBAEtCC,EAAuC,uDAGhC,MAAMN,EACX,0BAEK,MAAMD,CAAuC,CAC1C,OACS,WAAkCC,EAClC,oBACT,gBAAmD,KACnD,mBAA4C,KACnC,eAA4C,CAC3D,GAAI,aACJ,YAAa,CACX,GAAI,gBAAc,KAClB,YAAa,gCACb,aAAc,GACd,uBAAwB,EACxB,cAAe,CACb,MAAO,GACT,EACA,UAAW,GACX,QAAS,GACT,WAAY,IAAM,KAClB,MAAO,CAAC,SAAU,CACpB,EACA,UAAW,KAAK,UAClB,EAEA,YACEO,EACAC,EACAC,EACA,CACA,KAAK,OAASF,EAAqB,mBAAmB,EACtD,KAAK,oBAAsB,IAAI,yBAAuBE,CAAW,CACnE,CAEA,aAAuB,CACrB,MAAO,EACT,CAEA,eAAqC,CACnC,OAAO,KAAK,UACd,CAEA,0BAAoE,CAClE,SAAO,QAAK,CAAC,CAAC,KAAK,cAAc,CAAC,CAAC,CACrC,CAEA,kBAA0D,CACxD,YAAK,OAAO,MAAM,kBAAkB,KAC7B,QAAK,CAAC,KAAK,cAAc,CAAC,CACnC,CAEA,iBAAwB,CAEtB,KAAK,OAAO,MAAM,iBAAiB,CACrC,CAEA,MAAM,QAAQC,EAG8C,CAC1D,KAAK,OAAO,MAAM,SAAS,EAE3B,MAAMC,EAAc,MAAM,KAAK,oBAAoB,SAAS,UAAU,EACtE,KAAK,OAAO,MAAM,iBAAiBA,CAAW,EAAE,EAChD,MAAMC,EAAe,KAAK,mBAAmBD,CAAW,EAClDE,EAAS,IAAI,aAAWD,CAAY,EAG1CC,EAAO,gBAAgB,EACvB,MAAMC,EAAUD,EAAO,eAAeA,EAAO,sBAAsB,CAAC,EAC9DE,EAAaF,EAAO,eAAeA,EAAO,sBAAsB,CAAC,EAEvE,KAAK,OAAO,MAAM,aAAaC,CAAO,gBAAgBC,CAAU,EAAE,EAElE,MAAMC,EAAoBN,EAAO,SACjC,GAAI,CACF,MAAMO,EAA4C,CAChD,SAAWC,GACF,KAAK,SACVF,EACAN,EAAO,SACPA,EAAO,aACPQ,CACF,EAEF,YAAa,CACX,GAAG,KAAK,eAAe,YACvB,YAAa,cAAcJ,CAAO,MAAMC,CAAU,GAClD,cAAe,CACb,MAAO,GACT,CACF,EACA,UAAW,KAAK,WAChB,GAAI,aACJ,KAAM,KACR,EAEA,YAAK,gBAAkBE,EACvB,KAAK,oBAAoBP,EAAO,aAAcA,EAAO,QAAQ,KACtD,SAAMO,CAAe,CAC9B,OAASE,EAAO,CACd,SAAO,QAAK,IAAI,yBAAuBA,CAAc,CAAC,CACxD,CACF,CAEA,MAAM,WAAWC,EAEmB,CAClC,YAAK,OAAO,MAAM,YAAY,EAC9B,KAAK,gBAAkB,KAChB,QAAQ,WAAQ,SAAM,MAAS,CAAC,CACzC,CAEA,MAAM,SACJC,EACAC,EACAC,EACAL,EACyC,CACzC,GAAI,CACF,MAAMM,KAAU,sBAAmBN,CAAI,EAAE,UAAU,CAAC,EACpD,KAAK,OAAO,MAAM,eAAeM,CAAO,EAAE,EAC1C,MAAMb,EACJ,MAAM,KAAK,oBAAoB,SAASa,CAAO,EAC3CZ,EAAe,KAAK,mBAAmBD,CAAW,EACxD,SAAO,SAAMC,CAAY,CAC3B,OAASO,EAAO,CACd,OAAI,KAAK,kBACP,KAAK,OAAO,MAAM,eAAe,EACjCI,EAAaD,CAAQ,EACrB,KAAK,WAAW,CACd,gBAAiB,KAAK,eACxB,CAAC,EAEG,KAAK,oBACP,cAAc,KAAK,kBAAkB,MAGlC,QAAK,IAAI,kBAAgBH,CAAK,CAAC,CACxC,CACF,CAEQ,mBAAmBK,EAA+B,CACxD,YAAK,OAAO,MACV,oBAAoBA,EAAQ,UAAUA,EAAQ,OAAS,EAAGA,EAAQ,MAAM,CAAC,EAC3E,EACA,KAAK,OAAO,MAAM,aAAaA,EAAQ,UAAU,EAAGA,EAAQ,OAAS,CAAC,CAAC,EAAE,EAEpD,CACnB,WAAY,KAAK,cACfA,EAAQ,UAAUA,EAAQ,OAAS,EAAGA,EAAQ,MAAM,CACtD,EACA,KAAM,KAAK,cAAcA,EAAQ,UAAU,EAAGA,EAAQ,OAAS,CAAC,CAAC,CACnE,CAEF,CAGQ,cAAcC,EAA+B,CACnD,OAAKA,EAGE,IAAI,WACTA,EAAU,MAAM,SAAS,EAAG,IAAKC,GAAS,SAASA,EAAM,EAAE,CAAC,CAC9D,EAJS,WAAW,KAAK,CAAC,CAAC,CAK7B,CAEQ,oBACNH,EACAD,EACM,CACN,KAAK,mBAAqB,YAAY,SAAY,CAE9C,MAAM,KAAK,oBAAoB,kBAAkB,IAGjD,KAAK,OAAO,KACV,qDAAqDA,CAAQ,EAC/D,EACAC,EAAaD,CAAQ,EAEjB,KAAK,iBACP,MAAM,KAAK,WAAW,CACpB,gBAAiB,KAAK,eACxB,CAAC,EAGC,KAAK,oBACP,cAAc,KAAK,kBAAkB,EAG3C,EAAG,GAAI,CACT,CACF,CAEO,MAAMrB,EAGX,CAACQ,EAAc,0BACf,CAAC,CAAE,OAAAkB,EAAQ,qBAAApB,CAAqB,IAC9B,IAAIR,EAAkBQ,EAAsBoB,EAAQlB,CAAW",
6
- "names": ["SpeculosTransport_exports", "__export", "SpeculosTransport", "speculosIdentifier", "speculosTransportFactory", "__toCommonJS", "import_device_management_kit", "import_purify_ts", "import_rxjs", "import_HttpSpeculosDatasource", "loggerServiceFactory", "_config", "speculosUrl", "params", "hexResponse", "apduResponse", "parser", "appName", "appVersion", "sessionId", "connectedDevice", "apdu", "error", "_params", "_sessionId", "deviceId", "onDisconnect", "hexApdu", "hexString", "byte", "config"]
4
+ "sourcesContent": ["import {\n ApduParser,\n type ApduResponse,\n bufferToHexaString,\n type ConnectError,\n type DeviceId,\n DeviceModelId,\n type DisconnectHandler,\n type DmkConfig,\n type DmkError,\n GeneralDmkError,\n type LoggerPublisherService,\n OpeningConnectionError,\n type Transport,\n type TransportConnectedDevice,\n type TransportDiscoveredDevice,\n type TransportFactory,\n type TransportIdentifier,\n} from \"@ledgerhq/device-management-kit\";\nimport { AxiosError } from \"axios\";\nimport { type Either, Left, Right } from \"purify-ts\";\nimport { from, type Observable } from \"rxjs\";\n\nimport { HttpLegacySpeculosDatasource } from \"@internal/datasource/HttpLegacySpeculosDatasource\";\nimport { HttpSpeculosDatasource } from \"@internal/datasource/HttpSpeculosDatasource\";\nimport { type SpeculosDatasource } from \"@internal/datasource/SpeculosDatasource\";\n\nexport const speculosIdentifier: TransportIdentifier =\n \"SPECULOS_HTTP_TRANSPORT\";\n\nexport class SpeculosTransport implements Transport {\n private logger: LoggerPublisherService;\n private readonly identifier: TransportIdentifier = speculosIdentifier;\n private readonly _speculosDataSource: SpeculosDatasource;\n private connectedDevice: TransportConnectedDevice | null = null;\n private disconnectInterval: NodeJS.Timeout | null = null;\n private readonly speculosDevice: TransportDiscoveredDevice = {\n id: \"SpeculosID\", //TODO make it dynamic at creation\n deviceModel: {\n id: DeviceModelId.STAX,\n productName: \"Speculos - App Name - version\",\n usbProductId: 0x10,\n bootloaderUsbProductId: 0x0001,\n getBlockSize() {\n return 32;\n },\n blockSize: 32,\n usbOnly: true,\n memorySize: 320 * 1024,\n masks: [0x31100000],\n },\n transport: this.identifier,\n };\n\n constructor(\n loggerServiceFactory: (tag: string) => LoggerPublisherService,\n _config: DmkConfig,\n speculosUrl: string,\n private readonly legacyE2ECompatibility: boolean,\n ) {\n this.logger = loggerServiceFactory(\"SpeculosTransport\");\n this._speculosDataSource = this.legacyE2ECompatibility\n ? new HttpLegacySpeculosDatasource(speculosUrl)\n : new HttpSpeculosDatasource(speculosUrl);\n }\n\n isSupported(): boolean {\n return true;\n }\n\n getIdentifier(): TransportIdentifier {\n return this.identifier;\n }\n\n listenToAvailableDevices(): Observable<TransportDiscoveredDevice[]> {\n return from([[this.speculosDevice]]);\n }\n\n startDiscovering(): Observable<TransportDiscoveredDevice> {\n this.logger.debug(\"startDiscovering\");\n return from([this.speculosDevice]);\n }\n\n stopDiscovering(): void {\n //DO NOTHING HERE\n this.logger.debug(\"stopDiscovering\");\n }\n\n async connect(params: {\n deviceId: DeviceId;\n onDisconnect: DisconnectHandler;\n }): Promise<Either<ConnectError, TransportConnectedDevice>> {\n this.logger.debug(\"connect\");\n\n const hexResponse = await this._speculosDataSource.postAdpu(\"B0010000\");\n this.logger.debug(`Hex Response: ${hexResponse}`);\n const apduResponse = this.createApduResponse(hexResponse);\n const parser = new ApduParser(apduResponse);\n\n //Copy paste from GetAppAndVersionCommand\n parser.extract8BitUInt(); //Need otherwise parser is not in the right position\n const appName = parser.encodeToString(parser.extractFieldLVEncoded());\n const appVersion = parser.encodeToString(parser.extractFieldLVEncoded());\n\n this.logger.debug(`App Name: ${appName} and version ${appVersion}`);\n\n const sessionId: string = params.deviceId;\n try {\n const connectedDevice: TransportConnectedDevice = {\n sendApdu: (apdu) => {\n return this.sendApdu(\n sessionId,\n params.deviceId,\n params.onDisconnect,\n apdu,\n );\n },\n deviceModel: {\n ...this.speculosDevice.deviceModel,\n productName: `Speculos - ${appName} - ${appVersion}`,\n getBlockSize() {\n return 32;\n },\n },\n transport: this.identifier,\n id: \"SpeculosID\", //TODO make it dynamic at creation\n type: \"USB\",\n };\n\n this.connectedDevice = connectedDevice;\n if (!this.legacyE2ECompatibility) {\n this.listenForDisconnect(params.onDisconnect, params.deviceId);\n }\n return Right(connectedDevice);\n } catch (error) {\n return Left(new OpeningConnectionError(error as Error));\n }\n }\n\n async disconnect(_params: {\n connectedDevice: TransportConnectedDevice;\n }): Promise<Either<DmkError, void>> {\n this.logger.debug(\"disconnect\");\n this.connectedDevice = null;\n return Promise.resolve(Right(undefined));\n }\n\n async sendApdu(\n _sessionId: string,\n deviceId: DeviceId,\n onDisconnect: DisconnectHandler,\n apdu: Uint8Array,\n ): Promise<Either<DmkError, ApduResponse>> {\n try {\n const hexApdu = bufferToHexaString(apdu).substring(2);\n this.logger.debug(`send APDU: ${hexApdu}`);\n const hexResponse = await this._speculosDataSource.postAdpu(hexApdu);\n return Right(this.createApduResponse(hexResponse));\n } catch (error) {\n if (this.connectedDevice) {\n this.logger.debug(\"disconnecting\");\n onDisconnect(deviceId);\n this.disconnect({\n connectedDevice: this.connectedDevice,\n });\n\n if (this.disconnectInterval) {\n clearInterval(this.disconnectInterval);\n }\n }\n return Left(new GeneralDmkError(error));\n }\n }\n\n private createApduResponse(hexApdu: string): ApduResponse {\n this.logger.debug(\n `Status code hex: ${hexApdu.substring(hexApdu.length - 4, hexApdu.length)}`,\n );\n this.logger.debug(`data hex: ${hexApdu.substring(0, hexApdu.length - 4)}`);\n\n const apduResponse = {\n statusCode: this.fromHexString(\n hexApdu.substring(hexApdu.length - 4, hexApdu.length),\n ),\n data: this.fromHexString(hexApdu.substring(0, hexApdu.length - 4)),\n };\n return apduResponse;\n }\n\n //TODO: Move this to a helper\n private fromHexString(hexString: string): Uint8Array {\n if (!hexString) {\n return Uint8Array.from([]);\n }\n return new Uint8Array(\n hexString.match(/.{1,2}/g)!.map((byte) => parseInt(byte, 16)),\n );\n }\n\n private listenForDisconnect(\n onDisconnect: DisconnectHandler,\n deviceId: DeviceId,\n ): void {\n this.disconnectInterval = setInterval(async () => {\n try {\n await this._speculosDataSource.postAdpu(\"B0010000\");\n } catch (error) {\n if (!(error instanceof AxiosError)) return;\n\n this.logger.info(\n `Network error, disconnecting speculos device ${deviceId}`,\n );\n onDisconnect(deviceId);\n\n if (this.connectedDevice) {\n await this.disconnect({\n connectedDevice: this.connectedDevice,\n });\n }\n\n if (this.disconnectInterval) {\n clearInterval(this.disconnectInterval);\n }\n }\n }, 2000);\n }\n}\n\nexport const speculosTransportFactory: (\n speculosUrl?: string,\n legacyE2ECompatibility?: boolean,\n) => TransportFactory =\n (speculosUrl = \"http://127.0.0.1:5000\", legacyE2ECompatibility = false) =>\n ({ config, loggerServiceFactory }) =>\n new SpeculosTransport(\n loggerServiceFactory,\n config,\n speculosUrl,\n legacyE2ECompatibility,\n );\n"],
5
+ "mappings": "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",
6
+ "names": ["SpeculosTransport_exports", "__export", "SpeculosTransport", "speculosIdentifier", "speculosTransportFactory", "__toCommonJS", "import_device_management_kit", "import_axios", "import_purify_ts", "import_rxjs", "import_HttpLegacySpeculosDatasource", "import_HttpSpeculosDatasource", "loggerServiceFactory", "_config", "speculosUrl", "legacyE2ECompatibility", "params", "hexResponse", "apduResponse", "parser", "appName", "appVersion", "sessionId", "connectedDevice", "apdu", "error", "_params", "_sessionId", "deviceId", "onDisconnect", "hexApdu", "hexString", "byte", "config"]
7
7
  }
@@ -1,2 +1,2 @@
1
- "use strict";var a=Object.defineProperty;var b=Object.getOwnPropertyDescriptor;var c=Object.getOwnPropertyNames;var d=Object.prototype.hasOwnProperty;var p=(r,o,f,x)=>{if(o&&typeof o=="object"||typeof o=="function")for(let e of c(o))!d.call(r,e)&&e!==f&&a(r,e,{get:()=>o[e],enumerable:!(x=b(o,e))||x.enumerable});return r},t=(r,o,f)=>(p(r,o,"default"),f&&p(f,o,"default"));var g=r=>p(a({},"__esModule",{value:!0}),r);var m={};module.exports=g(m);t(m,require("./api/SpeculosTransport"),module.exports);0&&(module.exports={...require("./api/SpeculosTransport")});
1
+ "use strict";var a=Object.defineProperty;var b=Object.getOwnPropertyDescriptor;var c=Object.getOwnPropertyNames;var d=Object.prototype.hasOwnProperty;var t=(f,o,p,x)=>{if(o&&typeof o=="object"||typeof o=="function")for(let m of c(o))!d.call(f,m)&&m!==p&&a(f,m,{get:()=>o[m],enumerable:!(x=b(o,m))||x.enumerable});return f},e=(f,o,p)=>(t(f,o,"default"),p&&t(p,o,"default"));var g=f=>t(a({},"__esModule",{value:!0}),f);var r={};module.exports=g(r);e(r,require("./api/QuietSpeculosTransport"),module.exports);e(r,require("./api/SpeculosTransport"),module.exports);0&&(module.exports={...require("./api/QuietSpeculosTransport"),...require("./api/SpeculosTransport")});
2
2
  //# sourceMappingURL=index.js.map
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "version": 3,
3
3
  "sources": ["../../../src/index.ts"],
4
- "sourcesContent": ["export * from \"./api/SpeculosTransport\";\n"],
5
- "mappings": "iaAAA,IAAAA,EAAA,kBAAAC,EAAAD,GAAAE,EAAAF,EAAc,mCAAd",
4
+ "sourcesContent": ["export * from \"./api/QuietSpeculosTransport\";\nexport * from \"./api/SpeculosTransport\";\n"],
5
+ "mappings": "iaAAA,IAAAA,EAAA,kBAAAC,EAAAD,GAAAE,EAAAF,EAAc,wCAAd,gBACAE,EAAAF,EAAc,mCADd",
6
6
  "names": ["src_exports", "__toCommonJS", "__reExport"]
7
7
  }
@@ -0,0 +1,2 @@
1
+ "use strict";var p=Object.create;var a=Object.defineProperty;var m=Object.getOwnPropertyDescriptor;var d=Object.getOwnPropertyNames;var h=Object.getPrototypeOf,y=Object.prototype.hasOwnProperty;var g=(e,t)=>{for(var r in t)a(e,r,{get:t[r],enumerable:!0})},c=(e,t,r,i)=>{if(t&&typeof t=="object"||typeof t=="function")for(let s of d(t))!y.call(e,s)&&s!==r&&a(e,s,{get:()=>t[s],enumerable:!(i=m(t,s))||i.enumerable});return e};var w=(e,t,r)=>(r=e!=null?p(h(e)):{},c(t||!e||!e.__esModule?a(r,"default",{value:e,enumerable:!0}):r,e)),f=e=>c(a({},"__esModule",{value:!0}),e);var b={};g(b,{HttpLegacySpeculosDatasource:()=>M});module.exports=f(b);var n=w(require("axios"));class M{constructor(t,r=1e4,i="ldmk-transport-speculos"){this.baseUrl=t;this.timeoutMs=r;this.clientHeader=i;this.client=n.default.create({baseURL:this.baseUrl,timeout:this.timeoutMs,headers:{"X-Ledger-Client-Version":this.clientHeader},transitional:{clarifyTimeoutError:!0}})}client;async postOnce(t,r){const i=new AbortController,s=setTimeout(()=>i.abort(),r);try{const{data:o}=await this.client.post("/apdu",{data:t},{timeout:r,signal:i.signal});return o.data}finally{clearTimeout(s)}}async postAdpu(t){const r=Math.min(1500,this.timeoutMs),i=Math.max(1,Math.floor(this.timeoutMs/r));let s;for(let o=0;o<i;o++)try{return await this.postOnce(t,r)}catch(l){s=l,await new Promise(u=>setTimeout(u,150))}throw s instanceof n.AxiosError||s instanceof Error?s:new Error(String(s))}}0&&(module.exports={HttpLegacySpeculosDatasource});
2
+ //# sourceMappingURL=HttpLegacySpeculosDatasource.js.map
@@ -0,0 +1,7 @@
1
+ {
2
+ "version": 3,
3
+ "sources": ["../../../../../src/internal/datasource/HttpLegacySpeculosDatasource.ts"],
4
+ "sourcesContent": ["import axios, { AxiosError, type AxiosInstance } from \"axios\";\n\nexport class HttpLegacySpeculosDatasource {\n private readonly client: AxiosInstance;\n\n constructor(\n private readonly baseUrl: string,\n private readonly timeoutMs: number = 10000,\n private readonly clientHeader: string = \"ldmk-transport-speculos\",\n ) {\n this.client = axios.create({\n baseURL: this.baseUrl,\n timeout: this.timeoutMs,\n headers: {\n \"X-Ledger-Client-Version\": this.clientHeader,\n },\n transitional: { clarifyTimeoutError: true },\n });\n }\n\n private async postOnce(apdu: string, ms: number): Promise<string> {\n const ac = new AbortController();\n const killer = setTimeout(() => ac.abort(), ms);\n try {\n const { data } = await this.client.post<SpeculosApduDTO>(\n \"/apdu\",\n { data: apdu },\n { timeout: ms, signal: ac.signal },\n );\n return data.data;\n } finally {\n clearTimeout(killer);\n }\n }\n\n async postAdpu(apdu: string): Promise<string> {\n const perTryMs = Math.min(1500, this.timeoutMs);\n const tries = Math.max(1, Math.floor(this.timeoutMs / perTryMs));\n let lastErr: unknown;\n for (let i = 0; i < tries; i++) {\n try {\n return await this.postOnce(apdu, perTryMs);\n } catch (e) {\n lastErr = e;\n await new Promise((r) => setTimeout(r, 150));\n }\n }\n if (lastErr instanceof AxiosError) throw lastErr;\n throw lastErr instanceof Error ? lastErr : new Error(String(lastErr));\n }\n}\n\ntype SpeculosApduDTO = {\n data: string;\n};\n"],
5
+ "mappings": "0jBAAA,IAAAA,EAAA,GAAAC,EAAAD,EAAA,kCAAAE,IAAA,eAAAC,EAAAH,GAAA,IAAAI,EAAsD,oBAE/C,MAAMF,CAA6B,CAGxC,YACmBG,EACAC,EAAoB,IACpBC,EAAuB,0BACxC,CAHiB,aAAAF,EACA,eAAAC,EACA,kBAAAC,EAEjB,KAAK,OAAS,EAAAC,QAAM,OAAO,CACzB,QAAS,KAAK,QACd,QAAS,KAAK,UACd,QAAS,CACP,0BAA2B,KAAK,YAClC,EACA,aAAc,CAAE,oBAAqB,EAAK,CAC5C,CAAC,CACH,CAfiB,OAiBjB,MAAc,SAASC,EAAcC,EAA6B,CAChE,MAAMC,EAAK,IAAI,gBACTC,EAAS,WAAW,IAAMD,EAAG,MAAM,EAAGD,CAAE,EAC9C,GAAI,CACF,KAAM,CAAE,KAAAG,CAAK,EAAI,MAAM,KAAK,OAAO,KACjC,QACA,CAAE,KAAMJ,CAAK,EACb,CAAE,QAASC,EAAI,OAAQC,EAAG,MAAO,CACnC,EACA,OAAOE,EAAK,IACd,QAAE,CACA,aAAaD,CAAM,CACrB,CACF,CAEA,MAAM,SAASH,EAA+B,CAC5C,MAAMK,EAAW,KAAK,IAAI,KAAM,KAAK,SAAS,EACxCC,EAAQ,KAAK,IAAI,EAAG,KAAK,MAAM,KAAK,UAAYD,CAAQ,CAAC,EAC/D,IAAIE,EACJ,QAASC,EAAI,EAAGA,EAAIF,EAAOE,IACzB,GAAI,CACF,OAAO,MAAM,KAAK,SAASR,EAAMK,CAAQ,CAC3C,OAASI,EAAG,CACVF,EAAUE,EACV,MAAM,IAAI,QAASC,GAAM,WAAWA,EAAG,GAAG,CAAC,CAC7C,CAEF,MAAIH,aAAmB,cACjBA,aAAmB,MADgBA,EACE,IAAI,MAAM,OAAOA,CAAO,CAAC,CACtE,CACF",
6
+ "names": ["HttpLegacySpeculosDatasource_exports", "__export", "HttpLegacySpeculosDatasource", "__toCommonJS", "import_axios", "baseUrl", "timeoutMs", "clientHeader", "axios", "apdu", "ms", "ac", "killer", "data", "perTryMs", "tries", "lastErr", "i", "e", "r"]
7
+ }
@@ -1,2 +1,2 @@
1
- "use strict";var i=Object.create;var o=Object.defineProperty;var c=Object.getOwnPropertyDescriptor;var d=Object.getOwnPropertyNames;var m=Object.getPrototypeOf,v=Object.prototype.hasOwnProperty;var y=(e,s)=>{for(var t in s)o(e,t,{get:s[t],enumerable:!0})},p=(e,s,t,a)=>{if(s&&typeof s=="object"||typeof s=="function")for(let r of d(s))!v.call(e,r)&&r!==t&&o(e,r,{get:()=>s[r],enumerable:!(a=c(s,r))||a.enumerable});return e};var l=(e,s,t)=>(t=e!=null?i(m(e)):{},p(s||!e||!e.__esModule?o(t,"default",{value:e,enumerable:!0}):t,e)),S=e=>p(o({},"__esModule",{value:!0}),e);var b={};y(b,{HttpSpeculosDatasource:()=>T});module.exports=S(b);var n=l(require("axios")),u=l(require("../../../package.json"));const D=5e3;class T{constructor(s){this.baseUrl=s}async postAdpu(s){const t={data:s};return(await n.default.request({method:"POST",url:`${this.baseUrl}/apdu`,data:t,headers:{"X-Ledger-Client-Version":`ldmk-transport-speculos/${u.default.version}`}})).data.data}async isServerAvailable(){try{return await n.default.request({method:"GET",url:`${this.baseUrl}/events`,headers:{"X-Ledger-Client-Version":`ldmk-transport-speculos/${u.default.version}`},timeout:D}),!0}catch{return!1}}}0&&(module.exports={HttpSpeculosDatasource});
1
+ "use strict";var i=Object.create;var r=Object.defineProperty;var l=Object.getOwnPropertyDescriptor;var d=Object.getOwnPropertyNames;var m=Object.getPrototypeOf,D=Object.prototype.hasOwnProperty;var S=(s,e)=>{for(var t in e)r(s,t,{get:e[t],enumerable:!0})},p=(s,e,t,a)=>{if(e&&typeof e=="object"||typeof e=="function")for(let o of d(e))!D.call(s,o)&&o!==t&&r(s,o,{get:()=>e[o],enumerable:!(a=l(e,o))||a.enumerable});return s};var u=(s,e,t)=>(t=s!=null?i(m(s)):{},p(e||!s||!s.__esModule?r(t,"default",{value:s,enumerable:!0}):t,s)),g=s=>p(r({},"__esModule",{value:!0}),s);var y={};S(y,{HttpSpeculosDatasource:()=>A});module.exports=g(y);var c=u(require("axios")),n=u(require("../../../package.json"));class A{constructor(e){this.baseUrl=e}async postAdpu(e){const t={data:e};return(await c.default.request({method:"POST",url:`${this.baseUrl}/apdu`,data:t,headers:{"X-Ledger-Client-Version":`ldmk-transport-speculos/${n.default.version}`}})).data.data}}0&&(module.exports={HttpSpeculosDatasource});
2
2
  //# sourceMappingURL=HttpSpeculosDatasource.js.map
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "version": 3,
3
3
  "sources": ["../../../../../src/internal/datasource/HttpSpeculosDatasource.ts"],
4
- "sourcesContent": ["import axios from \"axios\";\n\nimport PACKAGE from \"@root/package.json\";\n\nimport { type SpeculosDatasource } from \"./SpeculosDatasource\";\n\nconst TIMEOUT = 5000; // 5 second timeout for availability check\n\nexport class HttpSpeculosDatasource implements SpeculosDatasource {\n constructor(private readonly baseUrl: string) {}\n\n async postAdpu(apdu: string): Promise<string> {\n const requestDto = {\n data: apdu,\n };\n\n const speculosResponse = await axios.request<SpeculosApduDTO>({\n method: \"POST\",\n url: `${this.baseUrl}/apdu`,\n data: requestDto,\n headers: {\n \"X-Ledger-Client-Version\": `ldmk-transport-speculos/${PACKAGE.version}`,\n },\n });\n\n return speculosResponse.data.data;\n }\n\n async isServerAvailable(): Promise<boolean> {\n try {\n await axios.request<SpeculosEventsDTO>({\n method: \"GET\",\n url: `${this.baseUrl}/events`,\n headers: {\n \"X-Ledger-Client-Version\": `ldmk-transport-speculos/${PACKAGE.version}`,\n },\n timeout: TIMEOUT,\n });\n return true;\n } catch (_error) {\n return false;\n }\n }\n}\n\ntype SpeculosApduDTO = {\n data: string;\n};\n\ntype SpeculosEventsDTO = {\n events: Array<{\n text?: string;\n x?: number;\n y?: number;\n }>;\n};\n"],
5
- "mappings": "0jBAAA,IAAAA,EAAA,GAAAC,EAAAD,EAAA,4BAAAE,IAAA,eAAAC,EAAAH,GAAA,IAAAI,EAAkB,oBAElBC,EAAoB,iCAIpB,MAAMC,EAAU,IAET,MAAMJ,CAAqD,CAChE,YAA6BK,EAAiB,CAAjB,aAAAA,CAAkB,CAE/C,MAAM,SAASC,EAA+B,CAC5C,MAAMC,EAAa,CACjB,KAAMD,CACR,EAWA,OATyB,MAAM,EAAAE,QAAM,QAAyB,CAC5D,OAAQ,OACR,IAAK,GAAG,KAAK,OAAO,QACpB,KAAMD,EACN,QAAS,CACP,0BAA2B,2BAA2B,EAAAE,QAAQ,OAAO,EACvE,CACF,CAAC,GAEuB,KAAK,IAC/B,CAEA,MAAM,mBAAsC,CAC1C,GAAI,CACF,aAAM,EAAAD,QAAM,QAA2B,CACrC,OAAQ,MACR,IAAK,GAAG,KAAK,OAAO,UACpB,QAAS,CACP,0BAA2B,2BAA2B,EAAAC,QAAQ,OAAO,EACvE,EACA,QAASL,CACX,CAAC,EACM,EACT,MAAiB,CACf,MAAO,EACT,CACF,CACF",
6
- "names": ["HttpSpeculosDatasource_exports", "__export", "HttpSpeculosDatasource", "__toCommonJS", "import_axios", "import_package", "TIMEOUT", "baseUrl", "apdu", "requestDto", "axios", "PACKAGE"]
4
+ "sourcesContent": ["import axios from \"axios\";\n\nimport PACKAGE from \"@root/package.json\";\n\nimport { type SpeculosDatasource } from \"./SpeculosDatasource\";\nexport class HttpSpeculosDatasource implements SpeculosDatasource {\n constructor(private readonly baseUrl: string) {}\n\n async postAdpu(apdu: string): Promise<string> {\n const requestDto = {\n data: apdu,\n };\n\n const speculosResponse = await axios.request<SpeculosApduDTO>({\n method: \"POST\",\n url: `${this.baseUrl}/apdu`,\n data: requestDto,\n headers: {\n \"X-Ledger-Client-Version\": `ldmk-transport-speculos/${PACKAGE.version}`,\n },\n });\n\n return speculosResponse.data.data;\n }\n}\n\ntype SpeculosApduDTO = {\n data: string;\n};\n"],
5
+ "mappings": "0jBAAA,IAAAA,EAAA,GAAAC,EAAAD,EAAA,4BAAAE,IAAA,eAAAC,EAAAH,GAAA,IAAAI,EAAkB,oBAElBC,EAAoB,iCAGb,MAAMH,CAAqD,CAChE,YAA6BI,EAAiB,CAAjB,aAAAA,CAAkB,CAE/C,MAAM,SAASC,EAA+B,CAC5C,MAAMC,EAAa,CACjB,KAAMD,CACR,EAWA,OATyB,MAAM,EAAAE,QAAM,QAAyB,CAC5D,OAAQ,OACR,IAAK,GAAG,KAAK,OAAO,QACpB,KAAMD,EACN,QAAS,CACP,0BAA2B,2BAA2B,EAAAE,QAAQ,OAAO,EACvE,CACF,CAAC,GAEuB,KAAK,IAC/B,CACF",
6
+ "names": ["HttpSpeculosDatasource_exports", "__export", "HttpSpeculosDatasource", "__toCommonJS", "import_axios", "import_package", "baseUrl", "apdu", "requestDto", "axios", "PACKAGE"]
7
7
  }
@@ -1,2 +1,2 @@
1
- "use strict";var a=Object.defineProperty;var t=Object.getOwnPropertyDescriptor;var p=Object.getOwnPropertyNames;var l=Object.prototype.hasOwnProperty;var n=(r,e,i,s)=>{if(e&&typeof e=="object"||typeof e=="function")for(let o of p(e))!l.call(r,o)&&o!==i&&a(r,o,{get:()=>e[o],enumerable:!(s=t(e,o))||s.enumerable});return r};var u=r=>n(a({},"__esModule",{value:!0}),r);var c={};module.exports=u(c);
1
+ "use strict";var o=Object.defineProperty;var a=Object.getOwnPropertyDescriptor;var i=Object.getOwnPropertyNames;var u=Object.prototype.hasOwnProperty;var c=(r,e,p,t)=>{if(e&&typeof e=="object"||typeof e=="function")for(let s of i(e))!u.call(r,s)&&s!==p&&o(r,s,{get:()=>e[s],enumerable:!(t=a(e,s))||t.enumerable});return r};var n=r=>c(o({},"__esModule",{value:!0}),r);var d={};module.exports=n(d);
2
2
  //# sourceMappingURL=SpeculosDatasource.js.map
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "version": 3,
3
3
  "sources": ["../../../../../src/internal/datasource/SpeculosDatasource.ts"],
4
- "sourcesContent": ["export interface SpeculosDatasource {\n postAdpu(apdu: string): Promise<string>;\n isServerAvailable(): Promise<boolean>;\n}\n"],
4
+ "sourcesContent": ["export interface SpeculosDatasource {\n postAdpu(apdu: string): Promise<string>;\n}\n"],
5
5
  "mappings": "+WAAA,IAAAA,EAAA,kBAAAC,EAAAD",
6
6
  "names": ["SpeculosDatasource_exports", "__toCommonJS"]
7
7
  }
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@ledgerhq/device-transport-kit-speculos",
3
- "version": "1.0.0",
3
+ "version": "0.0.1",
4
4
  "license": "Apache-2.0",
5
5
  "private": false,
6
6
  "exports": {
@@ -0,0 +1,2 @@
1
+ import{ApduParser as g,bufferToHexaString as v,DeviceModelId as D,GeneralDmkError as h,OpeningConnectionError as m}from"@ledgerhq/device-management-kit";import{Left as d,Right as p}from"purify-ts";import{from as u}from"rxjs";import{HttpLegacySpeculosDatasource as y}from"../internal/datasource/HttpLegacySpeculosDatasource";import{speculosIdentifier as S}from"./SpeculosTransport";class b{logger;identifier=S;_speculosDataSource;connectedDevice=null;disconnectInterval=null;speculosDevice={id:"SpeculosID",deviceModel:{id:D.STAX,productName:"Speculos - App Name - version",usbProductId:16,bootloaderUsbProductId:1,getBlockSize(){return 32},blockSize:32,usbOnly:!0,memorySize:320*1024,masks:[823132160]},transport:this.identifier};constructor(e,r,t){this.logger=e("QuietSpeculosTransport"),this._speculosDataSource=new y(t,1e4,"ldmk-transport-speculos")}isSupported(){return!0}getIdentifier(){return this.identifier}listenToAvailableDevices(){return u([[this.speculosDevice]])}startDiscovering(){return this.logger.debug("startDiscovering"),u([this.speculosDevice])}stopDiscovering(){this.logger.debug("stopDiscovering")}async connect(e){this.logger.debug("connect");const r=await this._speculosDataSource.postAdpu("B0010000");this.logger.debug(`Hex Response: ${r}`);const t=this.createApduResponse(r),o=new g(t);o.extract8BitUInt();const s=o.encodeToString(o.extractFieldLVEncoded()),n=o.encodeToString(o.extractFieldLVEncoded());this.logger.debug(`App Name: ${s} and version ${n}`);const c=e.deviceId;try{const i={sendApdu:l=>this.sendApdu(c,e.deviceId,e.onDisconnect,l),deviceModel:{...this.speculosDevice.deviceModel,productName:`Speculos - ${s} - ${n}`,getBlockSize(){return 32}},transport:this.identifier,id:"SpeculosID",type:"USB"};return this.connectedDevice=i,p(i)}catch(i){return d(new m(i))}}async disconnect(e){return this.logger.debug("disconnect"),this.connectedDevice=null,this.disconnectInterval&&clearInterval(this.disconnectInterval),Promise.resolve(p(void 0))}async sendApdu(e,r,t,o){try{const s=v(o).substring(2).toUpperCase();this.logger.debug(`[QuietSpeculosTransport] send APDU: ${s}`);const n=await this._speculosDataSource.postAdpu(s),c=this.createApduResponse(n);return p(c)}catch(s){return this.connectedDevice&&(this.logger.debug("disconnecting due to APDU error"),t(r),await this.disconnect({connectedDevice:this.connectedDevice})),d(new h(s))}}createApduResponse(e){const r=e.slice(-4),t=e.slice(0,-4);return this.logger.debug(`[QuietSpeculosTransport] Status code hex: ${r}`),this.logger.debug(`[QuietSpeculosTransport] data hex: ${t}`),{statusCode:this.fromHexString(r),data:this.fromHexString(t)}}fromHexString(e){return e?new Uint8Array(e.match(/.{1,2}/g).map(r=>parseInt(r,16))):Uint8Array.from([])}}const x=(a="http://127.0.0.1:5000")=>({config:e,loggerServiceFactory:r})=>new b(r,e,a);export{b as QuietSpeculosTransport,x as quietSpeculosTransportFactory};
2
+ //# sourceMappingURL=QuietSpeculosTransport.js.map
@@ -0,0 +1,7 @@
1
+ {
2
+ "version": 3,
3
+ "sources": ["../../../../src/api/QuietSpeculosTransport.ts"],
4
+ "sourcesContent": ["import {\n ApduParser,\n type ApduResponse,\n bufferToHexaString,\n type ConnectError,\n type DeviceId,\n DeviceModelId,\n type DisconnectHandler,\n type DmkConfig,\n type DmkError,\n GeneralDmkError,\n type LoggerPublisherService,\n OpeningConnectionError,\n type Transport,\n type TransportConnectedDevice,\n type TransportDiscoveredDevice,\n type TransportFactory,\n type TransportIdentifier,\n} from \"@ledgerhq/device-management-kit\";\nimport { type Either, Left, Right } from \"purify-ts\";\nimport { from, type Observable } from \"rxjs\";\n\nimport { HttpLegacySpeculosDatasource } from \"@internal/datasource/HttpLegacySpeculosDatasource\";\n\nimport { speculosIdentifier } from \"./SpeculosTransport\";\n\nexport class QuietSpeculosTransport implements Transport {\n private logger: LoggerPublisherService;\n private readonly identifier: TransportIdentifier = speculosIdentifier;\n private readonly _speculosDataSource: HttpLegacySpeculosDatasource;\n\n private connectedDevice: TransportConnectedDevice | null = null;\n private disconnectInterval: NodeJS.Timeout | null = null;\n\n private readonly speculosDevice: TransportDiscoveredDevice = {\n id: \"SpeculosID\",\n deviceModel: {\n id: DeviceModelId.STAX,\n productName: \"Speculos - App Name - version\",\n usbProductId: 0x10,\n bootloaderUsbProductId: 0x0001,\n getBlockSize() {\n return 32;\n },\n blockSize: 32,\n usbOnly: true,\n memorySize: 320 * 1024,\n masks: [0x31100000],\n },\n transport: this.identifier,\n };\n\n constructor(\n loggerServiceFactory: (tag: string) => LoggerPublisherService,\n _config: DmkConfig,\n speculosUrl: string,\n ) {\n this.logger = loggerServiceFactory(\"QuietSpeculosTransport\");\n this._speculosDataSource = new HttpLegacySpeculosDatasource(\n speculosUrl,\n 10000,\n \"ldmk-transport-speculos\",\n );\n }\n\n isSupported(): boolean {\n return true;\n }\n\n getIdentifier(): TransportIdentifier {\n return this.identifier;\n }\n\n listenToAvailableDevices(): Observable<TransportDiscoveredDevice[]> {\n return from([[this.speculosDevice]]);\n }\n\n startDiscovering(): Observable<TransportDiscoveredDevice> {\n this.logger.debug(\"startDiscovering\");\n return from([this.speculosDevice]);\n }\n\n stopDiscovering(): void {\n this.logger.debug(\"stopDiscovering\");\n }\n\n async connect(params: {\n deviceId: DeviceId;\n onDisconnect: DisconnectHandler;\n }): Promise<Either<ConnectError, TransportConnectedDevice>> {\n this.logger.debug(\"connect\");\n\n const hexResponse = await this._speculosDataSource.postAdpu(\"B0010000\");\n this.logger.debug(`Hex Response: ${hexResponse}`);\n\n const apduResponse = this.createApduResponse(hexResponse);\n const parser = new ApduParser(apduResponse);\n\n parser.extract8BitUInt();\n const appName = parser.encodeToString(parser.extractFieldLVEncoded());\n const appVersion = parser.encodeToString(parser.extractFieldLVEncoded());\n\n this.logger.debug(`App Name: ${appName} and version ${appVersion}`);\n\n const sessionId: string = params.deviceId;\n try {\n const connectedDevice: TransportConnectedDevice = {\n sendApdu: (apdu: Uint8Array) =>\n this.sendApdu(sessionId, params.deviceId, params.onDisconnect, apdu),\n deviceModel: {\n ...this.speculosDevice.deviceModel,\n productName: `Speculos - ${appName} - ${appVersion}`,\n getBlockSize() {\n return 32;\n },\n },\n transport: this.identifier,\n id: \"SpeculosID\",\n type: \"USB\",\n };\n\n this.connectedDevice = connectedDevice;\n\n return Right(connectedDevice);\n } catch (error) {\n return Left(new OpeningConnectionError(error as Error));\n }\n }\n\n async disconnect(_params: {\n connectedDevice: TransportConnectedDevice;\n }): Promise<Either<DmkError, void>> {\n this.logger.debug(\"disconnect\");\n this.connectedDevice = null;\n if (this.disconnectInterval) clearInterval(this.disconnectInterval);\n return Promise.resolve(Right(undefined));\n }\n\n async sendApdu(\n _sessionId: string,\n deviceId: DeviceId,\n onDisconnect: DisconnectHandler,\n apdu: Uint8Array,\n ): Promise<Either<DmkError, ApduResponse>> {\n try {\n const hex = bufferToHexaString(apdu).substring(2).toUpperCase();\n this.logger.debug(`[QuietSpeculosTransport] send APDU: ${hex}`);\n const hexResponse = await this._speculosDataSource.postAdpu(hex);\n const resp = this.createApduResponse(hexResponse);\n return Right(resp);\n } catch (error) {\n if (this.connectedDevice) {\n this.logger.debug(\"disconnecting due to APDU error\");\n onDisconnect(deviceId);\n await this.disconnect({ connectedDevice: this.connectedDevice });\n }\n return Left(new GeneralDmkError(error as Error));\n }\n }\n\n private createApduResponse(hexApdu: string): ApduResponse {\n const sw = hexApdu.slice(-4);\n const payload = hexApdu.slice(0, -4);\n this.logger.debug(`[QuietSpeculosTransport] Status code hex: ${sw}`);\n this.logger.debug(`[QuietSpeculosTransport] data hex: ${payload}`);\n return {\n statusCode: this.fromHexString(sw),\n data: this.fromHexString(payload),\n };\n }\n\n private fromHexString(hexString: string): Uint8Array {\n if (!hexString) return Uint8Array.from([]);\n return new Uint8Array(\n hexString.match(/.{1,2}/g)!.map((b) => parseInt(b, 16)),\n );\n }\n}\n\nexport const quietSpeculosTransportFactory: (\n speculosUrl?: string,\n legacyE2ECompatibility?: boolean,\n) => TransportFactory =\n (speculosUrl = \"http://127.0.0.1:5000\") =>\n ({ config, loggerServiceFactory }) =>\n new QuietSpeculosTransport(loggerServiceFactory, config, speculosUrl);\n"],
5
+ "mappings": "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",
6
+ "names": ["ApduParser", "bufferToHexaString", "DeviceModelId", "GeneralDmkError", "OpeningConnectionError", "Left", "Right", "from", "HttpLegacySpeculosDatasource", "speculosIdentifier", "QuietSpeculosTransport", "loggerServiceFactory", "_config", "speculosUrl", "params", "hexResponse", "apduResponse", "parser", "appName", "appVersion", "sessionId", "connectedDevice", "apdu", "error", "_params", "_sessionId", "deviceId", "onDisconnect", "hex", "resp", "hexApdu", "sw", "payload", "hexString", "b", "quietSpeculosTransportFactory", "config"]
7
+ }
@@ -1,2 +1,2 @@
1
- import{ApduParser as v,bufferToHexaString as g,DeviceModelId as D,GeneralDmkError as h,OpeningConnectionError as S}from"@ledgerhq/device-management-kit";import{Left as p,Right as a}from"purify-ts";import{from as l}from"rxjs";import{HttpSpeculosDatasource as b}from"../internal/datasource/HttpSpeculosDatasource";const m="SPECULOS_HTTP_TRANSPORT";class f{logger;identifier=m;_speculosDataSource;connectedDevice=null;disconnectInterval=null;speculosDevice={id:"SpeculosID",deviceModel:{id:D.STAX,productName:"Speculos - App Name - version",usbProductId:16,bootloaderUsbProductId:1,getBlockSize(){return 32},blockSize:32,usbOnly:!0,memorySize:320*1024,masks:[823132160]},transport:this.identifier};constructor(e,t,s){this.logger=e("SpeculosTransport"),this._speculosDataSource=new b(s)}isSupported(){return!0}getIdentifier(){return this.identifier}listenToAvailableDevices(){return l([[this.speculosDevice]])}startDiscovering(){return this.logger.debug("startDiscovering"),l([this.speculosDevice])}stopDiscovering(){this.logger.debug("stopDiscovering")}async connect(e){this.logger.debug("connect");const t=await this._speculosDataSource.postAdpu("B0010000");this.logger.debug(`Hex Response: ${t}`);const s=this.createApduResponse(t),r=new v(s);r.extract8BitUInt();const n=r.encodeToString(r.extractFieldLVEncoded()),o=r.encodeToString(r.extractFieldLVEncoded());this.logger.debug(`App Name: ${n} and version ${o}`);const c=e.deviceId;try{const i={sendApdu:u=>this.sendApdu(c,e.deviceId,e.onDisconnect,u),deviceModel:{...this.speculosDevice.deviceModel,productName:`Speculos - ${n} - ${o}`,getBlockSize(){return 32}},transport:this.identifier,id:"SpeculosID",type:"USB"};return this.connectedDevice=i,this.listenForDisconnect(e.onDisconnect,e.deviceId),a(i)}catch(i){return p(new S(i))}}async disconnect(e){return this.logger.debug("disconnect"),this.connectedDevice=null,Promise.resolve(a(void 0))}async sendApdu(e,t,s,r){try{const n=g(r).substring(2);this.logger.debug(`send APDU: ${n}`);const o=await this._speculosDataSource.postAdpu(n),c=this.createApduResponse(o);return a(c)}catch(n){return this.connectedDevice&&(this.logger.debug("disconnecting"),s(t),this.disconnect({connectedDevice:this.connectedDevice}),this.disconnectInterval&&clearInterval(this.disconnectInterval)),p(new h(n))}}createApduResponse(e){return this.logger.debug(`Status code hex: ${e.substring(e.length-4,e.length)}`),this.logger.debug(`data hex: ${e.substring(0,e.length-4)}`),{statusCode:this.fromHexString(e.substring(e.length-4,e.length)),data:this.fromHexString(e.substring(0,e.length-4))}}fromHexString(e){return e?new Uint8Array(e.match(/.{1,2}/g).map(t=>parseInt(t,16))):Uint8Array.from([])}listenForDisconnect(e,t){this.disconnectInterval=setInterval(async()=>{await this._speculosDataSource.isServerAvailable()||(this.logger.info(`Speculos server unavailable, disconnecting device ${t}`),e(t),this.connectedDevice&&await this.disconnect({connectedDevice:this.connectedDevice}),this.disconnectInterval&&clearInterval(this.disconnectInterval))},2e3)}}const R=(d="http://127.0.0.1:5000")=>({config:e,loggerServiceFactory:t})=>new f(t,e,d);export{f as SpeculosTransport,m as speculosIdentifier,R as speculosTransportFactory};
1
+ import{ApduParser as g,bufferToHexaString as v,DeviceModelId as D,GeneralDmkError as h,OpeningConnectionError as y}from"@ledgerhq/device-management-kit";import{AxiosError as m}from"axios";import{Left as p,Right as c}from"purify-ts";import{from as d}from"rxjs";import{HttpLegacySpeculosDatasource as f}from"../internal/datasource/HttpLegacySpeculosDatasource";import{HttpSpeculosDatasource as b}from"../internal/datasource/HttpSpeculosDatasource";const S="SPECULOS_HTTP_TRANSPORT";class I{constructor(e,t,r,n){this.legacyE2ECompatibility=n;this.logger=e("SpeculosTransport"),this._speculosDataSource=this.legacyE2ECompatibility?new f(r):new b(r)}logger;identifier=S;_speculosDataSource;connectedDevice=null;disconnectInterval=null;speculosDevice={id:"SpeculosID",deviceModel:{id:D.STAX,productName:"Speculos - App Name - version",usbProductId:16,bootloaderUsbProductId:1,getBlockSize(){return 32},blockSize:32,usbOnly:!0,memorySize:320*1024,masks:[823132160]},transport:this.identifier};isSupported(){return!0}getIdentifier(){return this.identifier}listenToAvailableDevices(){return d([[this.speculosDevice]])}startDiscovering(){return this.logger.debug("startDiscovering"),d([this.speculosDevice])}stopDiscovering(){this.logger.debug("stopDiscovering")}async connect(e){this.logger.debug("connect");const t=await this._speculosDataSource.postAdpu("B0010000");this.logger.debug(`Hex Response: ${t}`);const r=this.createApduResponse(t),n=new g(r);n.extract8BitUInt();const o=n.encodeToString(n.extractFieldLVEncoded()),i=n.encodeToString(n.extractFieldLVEncoded());this.logger.debug(`App Name: ${o} and version ${i}`);const l=e.deviceId;try{const s={sendApdu:u=>this.sendApdu(l,e.deviceId,e.onDisconnect,u),deviceModel:{...this.speculosDevice.deviceModel,productName:`Speculos - ${o} - ${i}`,getBlockSize(){return 32}},transport:this.identifier,id:"SpeculosID",type:"USB"};return this.connectedDevice=s,this.legacyE2ECompatibility||this.listenForDisconnect(e.onDisconnect,e.deviceId),c(s)}catch(s){return p(new y(s))}}async disconnect(e){return this.logger.debug("disconnect"),this.connectedDevice=null,Promise.resolve(c(void 0))}async sendApdu(e,t,r,n){try{const o=v(n).substring(2);this.logger.debug(`send APDU: ${o}`);const i=await this._speculosDataSource.postAdpu(o);return c(this.createApduResponse(i))}catch(o){return this.connectedDevice&&(this.logger.debug("disconnecting"),r(t),this.disconnect({connectedDevice:this.connectedDevice}),this.disconnectInterval&&clearInterval(this.disconnectInterval)),p(new h(o))}}createApduResponse(e){return this.logger.debug(`Status code hex: ${e.substring(e.length-4,e.length)}`),this.logger.debug(`data hex: ${e.substring(0,e.length-4)}`),{statusCode:this.fromHexString(e.substring(e.length-4,e.length)),data:this.fromHexString(e.substring(0,e.length-4))}}fromHexString(e){return e?new Uint8Array(e.match(/.{1,2}/g).map(t=>parseInt(t,16))):Uint8Array.from([])}listenForDisconnect(e,t){this.disconnectInterval=setInterval(async()=>{try{await this._speculosDataSource.postAdpu("B0010000")}catch(r){if(!(r instanceof m))return;this.logger.info(`Network error, disconnecting speculos device ${t}`),e(t),this.connectedDevice&&await this.disconnect({connectedDevice:this.connectedDevice}),this.disconnectInterval&&clearInterval(this.disconnectInterval)}},2e3)}}const w=(a="http://127.0.0.1:5000",e=!1)=>({config:t,loggerServiceFactory:r})=>new I(r,t,a,e);export{I as SpeculosTransport,S as speculosIdentifier,w as speculosTransportFactory};
2
2
  //# sourceMappingURL=SpeculosTransport.js.map
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "version": 3,
3
3
  "sources": ["../../../../src/api/SpeculosTransport.ts"],
4
- "sourcesContent": ["import {\n ApduParser,\n type ApduResponse,\n bufferToHexaString,\n type ConnectError,\n type DeviceId,\n DeviceModelId,\n type DisconnectHandler,\n type DmkConfig,\n type DmkError,\n GeneralDmkError,\n type LoggerPublisherService,\n OpeningConnectionError,\n type Transport,\n type TransportConnectedDevice,\n type TransportDiscoveredDevice,\n type TransportFactory,\n type TransportIdentifier,\n} from \"@ledgerhq/device-management-kit\";\nimport { type Either, Left, Right } from \"purify-ts\";\nimport { from, type Observable } from \"rxjs\";\n\nimport { HttpSpeculosDatasource } from \"@internal/datasource/HttpSpeculosDatasource\";\nimport { type SpeculosDatasource } from \"@internal/datasource/SpeculosDatasource\";\n\nexport const speculosIdentifier: TransportIdentifier =\n \"SPECULOS_HTTP_TRANSPORT\";\n\nexport class SpeculosTransport implements Transport {\n private logger: LoggerPublisherService;\n private readonly identifier: TransportIdentifier = speculosIdentifier;\n private readonly _speculosDataSource: SpeculosDatasource;\n private connectedDevice: TransportConnectedDevice | null = null;\n private disconnectInterval: NodeJS.Timeout | null = null;\n private readonly speculosDevice: TransportDiscoveredDevice = {\n id: \"SpeculosID\", //TODO make it dynamic at creation\n deviceModel: {\n id: DeviceModelId.STAX,\n productName: \"Speculos - App Name - version\",\n usbProductId: 0x10,\n bootloaderUsbProductId: 0x0001,\n getBlockSize() {\n return 32;\n },\n blockSize: 32,\n usbOnly: true,\n memorySize: 320 * 1024,\n masks: [0x31100000],\n },\n transport: this.identifier,\n };\n\n constructor(\n loggerServiceFactory: (tag: string) => LoggerPublisherService,\n _config: DmkConfig,\n speculosUrl: string,\n ) {\n this.logger = loggerServiceFactory(\"SpeculosTransport\");\n this._speculosDataSource = new HttpSpeculosDatasource(speculosUrl); // See how to pass properly speculos config.\n }\n\n isSupported(): boolean {\n return true;\n }\n\n getIdentifier(): TransportIdentifier {\n return this.identifier;\n }\n\n listenToAvailableDevices(): Observable<TransportDiscoveredDevice[]> {\n return from([[this.speculosDevice]]);\n }\n\n startDiscovering(): Observable<TransportDiscoveredDevice> {\n this.logger.debug(\"startDiscovering\");\n return from([this.speculosDevice]);\n }\n\n stopDiscovering(): void {\n //DO NOTHING HERE\n this.logger.debug(\"stopDiscovering\");\n }\n\n async connect(params: {\n deviceId: DeviceId;\n onDisconnect: DisconnectHandler;\n }): Promise<Either<ConnectError, TransportConnectedDevice>> {\n this.logger.debug(\"connect\");\n\n const hexResponse = await this._speculosDataSource.postAdpu(\"B0010000\");\n this.logger.debug(`Hex Response: ${hexResponse}`);\n const apduResponse = this.createApduResponse(hexResponse);\n const parser = new ApduParser(apduResponse);\n\n //Copy paste from GetAppAndVersionCommand\n parser.extract8BitUInt(); //Need otherwise parser is not in the right position\n const appName = parser.encodeToString(parser.extractFieldLVEncoded());\n const appVersion = parser.encodeToString(parser.extractFieldLVEncoded());\n\n this.logger.debug(`App Name: ${appName} and version ${appVersion}`);\n\n const sessionId: string = params.deviceId;\n try {\n const connectedDevice: TransportConnectedDevice = {\n sendApdu: (apdu) => {\n return this.sendApdu(\n sessionId,\n params.deviceId,\n params.onDisconnect,\n apdu,\n );\n },\n deviceModel: {\n ...this.speculosDevice.deviceModel,\n productName: `Speculos - ${appName} - ${appVersion}`,\n getBlockSize() {\n return 32;\n },\n },\n transport: this.identifier,\n id: \"SpeculosID\", //TODO make it dynamic at creation\n type: \"USB\",\n };\n\n this.connectedDevice = connectedDevice;\n this.listenForDisconnect(params.onDisconnect, params.deviceId);\n return Right(connectedDevice);\n } catch (error) {\n return Left(new OpeningConnectionError(error as Error));\n }\n }\n\n async disconnect(_params: {\n connectedDevice: TransportConnectedDevice;\n }): Promise<Either<DmkError, void>> {\n this.logger.debug(\"disconnect\");\n this.connectedDevice = null;\n return Promise.resolve(Right(undefined));\n }\n\n async sendApdu(\n _sessionId: string,\n deviceId: DeviceId,\n onDisconnect: DisconnectHandler,\n apdu: Uint8Array,\n ): Promise<Either<DmkError, ApduResponse>> {\n try {\n const hexApdu = bufferToHexaString(apdu).substring(2);\n this.logger.debug(`send APDU: ${hexApdu}`);\n const hexResponse: string =\n await this._speculosDataSource.postAdpu(hexApdu);\n const apduResponse = this.createApduResponse(hexResponse);\n return Right(apduResponse);\n } catch (error) {\n if (this.connectedDevice) {\n this.logger.debug(\"disconnecting\");\n onDisconnect(deviceId);\n this.disconnect({\n connectedDevice: this.connectedDevice,\n });\n\n if (this.disconnectInterval) {\n clearInterval(this.disconnectInterval);\n }\n }\n return Left(new GeneralDmkError(error));\n }\n }\n\n private createApduResponse(hexApdu: string): ApduResponse {\n this.logger.debug(\n `Status code hex: ${hexApdu.substring(hexApdu.length - 4, hexApdu.length)}`,\n );\n this.logger.debug(`data hex: ${hexApdu.substring(0, hexApdu.length - 4)}`);\n\n const apduResponse = {\n statusCode: this.fromHexString(\n hexApdu.substring(hexApdu.length - 4, hexApdu.length),\n ),\n data: this.fromHexString(hexApdu.substring(0, hexApdu.length - 4)),\n };\n return apduResponse;\n }\n\n //TODO: Move this to a helper\n private fromHexString(hexString: string): Uint8Array {\n if (!hexString) {\n return Uint8Array.from([]);\n }\n return new Uint8Array(\n hexString.match(/.{1,2}/g)!.map((byte) => parseInt(byte, 16)),\n );\n }\n\n private listenForDisconnect(\n onDisconnect: DisconnectHandler,\n deviceId: DeviceId,\n ): void {\n this.disconnectInterval = setInterval(async () => {\n const isServerAvailable =\n await this._speculosDataSource.isServerAvailable();\n\n if (!isServerAvailable) {\n this.logger.info(\n `Speculos server unavailable, disconnecting device ${deviceId}`,\n );\n onDisconnect(deviceId);\n\n if (this.connectedDevice) {\n await this.disconnect({\n connectedDevice: this.connectedDevice,\n });\n }\n\n if (this.disconnectInterval) {\n clearInterval(this.disconnectInterval);\n }\n }\n }, 2000);\n }\n}\n\nexport const speculosTransportFactory: (\n speculosUrl?: string,\n) => TransportFactory =\n (speculosUrl = \"http://127.0.0.1:5000\") =>\n ({ config, loggerServiceFactory }) =>\n new SpeculosTransport(loggerServiceFactory, config, speculosUrl);\n"],
5
- "mappings": "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",
6
- "names": ["ApduParser", "bufferToHexaString", "DeviceModelId", "GeneralDmkError", "OpeningConnectionError", "Left", "Right", "from", "HttpSpeculosDatasource", "speculosIdentifier", "SpeculosTransport", "loggerServiceFactory", "_config", "speculosUrl", "params", "hexResponse", "apduResponse", "parser", "appName", "appVersion", "sessionId", "connectedDevice", "apdu", "error", "_params", "_sessionId", "deviceId", "onDisconnect", "hexApdu", "hexString", "byte", "speculosTransportFactory", "config"]
4
+ "sourcesContent": ["import {\n ApduParser,\n type ApduResponse,\n bufferToHexaString,\n type ConnectError,\n type DeviceId,\n DeviceModelId,\n type DisconnectHandler,\n type DmkConfig,\n type DmkError,\n GeneralDmkError,\n type LoggerPublisherService,\n OpeningConnectionError,\n type Transport,\n type TransportConnectedDevice,\n type TransportDiscoveredDevice,\n type TransportFactory,\n type TransportIdentifier,\n} from \"@ledgerhq/device-management-kit\";\nimport { AxiosError } from \"axios\";\nimport { type Either, Left, Right } from \"purify-ts\";\nimport { from, type Observable } from \"rxjs\";\n\nimport { HttpLegacySpeculosDatasource } from \"@internal/datasource/HttpLegacySpeculosDatasource\";\nimport { HttpSpeculosDatasource } from \"@internal/datasource/HttpSpeculosDatasource\";\nimport { type SpeculosDatasource } from \"@internal/datasource/SpeculosDatasource\";\n\nexport const speculosIdentifier: TransportIdentifier =\n \"SPECULOS_HTTP_TRANSPORT\";\n\nexport class SpeculosTransport implements Transport {\n private logger: LoggerPublisherService;\n private readonly identifier: TransportIdentifier = speculosIdentifier;\n private readonly _speculosDataSource: SpeculosDatasource;\n private connectedDevice: TransportConnectedDevice | null = null;\n private disconnectInterval: NodeJS.Timeout | null = null;\n private readonly speculosDevice: TransportDiscoveredDevice = {\n id: \"SpeculosID\", //TODO make it dynamic at creation\n deviceModel: {\n id: DeviceModelId.STAX,\n productName: \"Speculos - App Name - version\",\n usbProductId: 0x10,\n bootloaderUsbProductId: 0x0001,\n getBlockSize() {\n return 32;\n },\n blockSize: 32,\n usbOnly: true,\n memorySize: 320 * 1024,\n masks: [0x31100000],\n },\n transport: this.identifier,\n };\n\n constructor(\n loggerServiceFactory: (tag: string) => LoggerPublisherService,\n _config: DmkConfig,\n speculosUrl: string,\n private readonly legacyE2ECompatibility: boolean,\n ) {\n this.logger = loggerServiceFactory(\"SpeculosTransport\");\n this._speculosDataSource = this.legacyE2ECompatibility\n ? new HttpLegacySpeculosDatasource(speculosUrl)\n : new HttpSpeculosDatasource(speculosUrl);\n }\n\n isSupported(): boolean {\n return true;\n }\n\n getIdentifier(): TransportIdentifier {\n return this.identifier;\n }\n\n listenToAvailableDevices(): Observable<TransportDiscoveredDevice[]> {\n return from([[this.speculosDevice]]);\n }\n\n startDiscovering(): Observable<TransportDiscoveredDevice> {\n this.logger.debug(\"startDiscovering\");\n return from([this.speculosDevice]);\n }\n\n stopDiscovering(): void {\n //DO NOTHING HERE\n this.logger.debug(\"stopDiscovering\");\n }\n\n async connect(params: {\n deviceId: DeviceId;\n onDisconnect: DisconnectHandler;\n }): Promise<Either<ConnectError, TransportConnectedDevice>> {\n this.logger.debug(\"connect\");\n\n const hexResponse = await this._speculosDataSource.postAdpu(\"B0010000\");\n this.logger.debug(`Hex Response: ${hexResponse}`);\n const apduResponse = this.createApduResponse(hexResponse);\n const parser = new ApduParser(apduResponse);\n\n //Copy paste from GetAppAndVersionCommand\n parser.extract8BitUInt(); //Need otherwise parser is not in the right position\n const appName = parser.encodeToString(parser.extractFieldLVEncoded());\n const appVersion = parser.encodeToString(parser.extractFieldLVEncoded());\n\n this.logger.debug(`App Name: ${appName} and version ${appVersion}`);\n\n const sessionId: string = params.deviceId;\n try {\n const connectedDevice: TransportConnectedDevice = {\n sendApdu: (apdu) => {\n return this.sendApdu(\n sessionId,\n params.deviceId,\n params.onDisconnect,\n apdu,\n );\n },\n deviceModel: {\n ...this.speculosDevice.deviceModel,\n productName: `Speculos - ${appName} - ${appVersion}`,\n getBlockSize() {\n return 32;\n },\n },\n transport: this.identifier,\n id: \"SpeculosID\", //TODO make it dynamic at creation\n type: \"USB\",\n };\n\n this.connectedDevice = connectedDevice;\n if (!this.legacyE2ECompatibility) {\n this.listenForDisconnect(params.onDisconnect, params.deviceId);\n }\n return Right(connectedDevice);\n } catch (error) {\n return Left(new OpeningConnectionError(error as Error));\n }\n }\n\n async disconnect(_params: {\n connectedDevice: TransportConnectedDevice;\n }): Promise<Either<DmkError, void>> {\n this.logger.debug(\"disconnect\");\n this.connectedDevice = null;\n return Promise.resolve(Right(undefined));\n }\n\n async sendApdu(\n _sessionId: string,\n deviceId: DeviceId,\n onDisconnect: DisconnectHandler,\n apdu: Uint8Array,\n ): Promise<Either<DmkError, ApduResponse>> {\n try {\n const hexApdu = bufferToHexaString(apdu).substring(2);\n this.logger.debug(`send APDU: ${hexApdu}`);\n const hexResponse = await this._speculosDataSource.postAdpu(hexApdu);\n return Right(this.createApduResponse(hexResponse));\n } catch (error) {\n if (this.connectedDevice) {\n this.logger.debug(\"disconnecting\");\n onDisconnect(deviceId);\n this.disconnect({\n connectedDevice: this.connectedDevice,\n });\n\n if (this.disconnectInterval) {\n clearInterval(this.disconnectInterval);\n }\n }\n return Left(new GeneralDmkError(error));\n }\n }\n\n private createApduResponse(hexApdu: string): ApduResponse {\n this.logger.debug(\n `Status code hex: ${hexApdu.substring(hexApdu.length - 4, hexApdu.length)}`,\n );\n this.logger.debug(`data hex: ${hexApdu.substring(0, hexApdu.length - 4)}`);\n\n const apduResponse = {\n statusCode: this.fromHexString(\n hexApdu.substring(hexApdu.length - 4, hexApdu.length),\n ),\n data: this.fromHexString(hexApdu.substring(0, hexApdu.length - 4)),\n };\n return apduResponse;\n }\n\n //TODO: Move this to a helper\n private fromHexString(hexString: string): Uint8Array {\n if (!hexString) {\n return Uint8Array.from([]);\n }\n return new Uint8Array(\n hexString.match(/.{1,2}/g)!.map((byte) => parseInt(byte, 16)),\n );\n }\n\n private listenForDisconnect(\n onDisconnect: DisconnectHandler,\n deviceId: DeviceId,\n ): void {\n this.disconnectInterval = setInterval(async () => {\n try {\n await this._speculosDataSource.postAdpu(\"B0010000\");\n } catch (error) {\n if (!(error instanceof AxiosError)) return;\n\n this.logger.info(\n `Network error, disconnecting speculos device ${deviceId}`,\n );\n onDisconnect(deviceId);\n\n if (this.connectedDevice) {\n await this.disconnect({\n connectedDevice: this.connectedDevice,\n });\n }\n\n if (this.disconnectInterval) {\n clearInterval(this.disconnectInterval);\n }\n }\n }, 2000);\n }\n}\n\nexport const speculosTransportFactory: (\n speculosUrl?: string,\n legacyE2ECompatibility?: boolean,\n) => TransportFactory =\n (speculosUrl = \"http://127.0.0.1:5000\", legacyE2ECompatibility = false) =>\n ({ config, loggerServiceFactory }) =>\n new SpeculosTransport(\n loggerServiceFactory,\n config,\n speculosUrl,\n legacyE2ECompatibility,\n );\n"],
5
+ "mappings": "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",
6
+ "names": ["ApduParser", "bufferToHexaString", "DeviceModelId", "GeneralDmkError", "OpeningConnectionError", "AxiosError", "Left", "Right", "from", "HttpLegacySpeculosDatasource", "HttpSpeculosDatasource", "speculosIdentifier", "SpeculosTransport", "loggerServiceFactory", "_config", "speculosUrl", "legacyE2ECompatibility", "params", "hexResponse", "apduResponse", "parser", "appName", "appVersion", "sessionId", "connectedDevice", "apdu", "error", "_params", "_sessionId", "deviceId", "onDisconnect", "hexApdu", "hexString", "byte", "speculosTransportFactory", "config"]
7
7
  }
@@ -1,2 +1,2 @@
1
- export*from"./api/SpeculosTransport";
1
+ export*from"./api/QuietSpeculosTransport";export*from"./api/SpeculosTransport";
2
2
  //# sourceMappingURL=index.js.map
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "version": 3,
3
3
  "sources": ["../../../src/index.ts"],
4
- "sourcesContent": ["export * from \"./api/SpeculosTransport\";\n"],
5
- "mappings": "AAAA,WAAc",
4
+ "sourcesContent": ["export * from \"./api/QuietSpeculosTransport\";\nexport * from \"./api/SpeculosTransport\";\n"],
5
+ "mappings": "AAAA,WAAc,+BACd,WAAc",
6
6
  "names": []
7
7
  }
@@ -0,0 +1,2 @@
1
+ import n,{AxiosError as c}from"axios";class p{constructor(s,e=1e4,r="ldmk-transport-speculos"){this.baseUrl=s;this.timeoutMs=e;this.clientHeader=r;this.client=n.create({baseURL:this.baseUrl,timeout:this.timeoutMs,headers:{"X-Ledger-Client-Version":this.clientHeader},transitional:{clarifyTimeoutError:!0}})}client;async postOnce(s,e){const r=new AbortController,t=setTimeout(()=>r.abort(),e);try{const{data:i}=await this.client.post("/apdu",{data:s},{timeout:e,signal:r.signal});return i.data}finally{clearTimeout(t)}}async postAdpu(s){const e=Math.min(1500,this.timeoutMs),r=Math.max(1,Math.floor(this.timeoutMs/e));let t;for(let i=0;i<r;i++)try{return await this.postOnce(s,e)}catch(o){t=o,await new Promise(a=>setTimeout(a,150))}throw t instanceof c||t instanceof Error?t:new Error(String(t))}}export{p as HttpLegacySpeculosDatasource};
2
+ //# sourceMappingURL=HttpLegacySpeculosDatasource.js.map
@@ -0,0 +1,7 @@
1
+ {
2
+ "version": 3,
3
+ "sources": ["../../../../../src/internal/datasource/HttpLegacySpeculosDatasource.ts"],
4
+ "sourcesContent": ["import axios, { AxiosError, type AxiosInstance } from \"axios\";\n\nexport class HttpLegacySpeculosDatasource {\n private readonly client: AxiosInstance;\n\n constructor(\n private readonly baseUrl: string,\n private readonly timeoutMs: number = 10000,\n private readonly clientHeader: string = \"ldmk-transport-speculos\",\n ) {\n this.client = axios.create({\n baseURL: this.baseUrl,\n timeout: this.timeoutMs,\n headers: {\n \"X-Ledger-Client-Version\": this.clientHeader,\n },\n transitional: { clarifyTimeoutError: true },\n });\n }\n\n private async postOnce(apdu: string, ms: number): Promise<string> {\n const ac = new AbortController();\n const killer = setTimeout(() => ac.abort(), ms);\n try {\n const { data } = await this.client.post<SpeculosApduDTO>(\n \"/apdu\",\n { data: apdu },\n { timeout: ms, signal: ac.signal },\n );\n return data.data;\n } finally {\n clearTimeout(killer);\n }\n }\n\n async postAdpu(apdu: string): Promise<string> {\n const perTryMs = Math.min(1500, this.timeoutMs);\n const tries = Math.max(1, Math.floor(this.timeoutMs / perTryMs));\n let lastErr: unknown;\n for (let i = 0; i < tries; i++) {\n try {\n return await this.postOnce(apdu, perTryMs);\n } catch (e) {\n lastErr = e;\n await new Promise((r) => setTimeout(r, 150));\n }\n }\n if (lastErr instanceof AxiosError) throw lastErr;\n throw lastErr instanceof Error ? lastErr : new Error(String(lastErr));\n }\n}\n\ntype SpeculosApduDTO = {\n data: string;\n};\n"],
5
+ "mappings": "AAAA,OAAOA,GAAS,cAAAC,MAAsC,QAE/C,MAAMC,CAA6B,CAGxC,YACmBC,EACAC,EAAoB,IACpBC,EAAuB,0BACxC,CAHiB,aAAAF,EACA,eAAAC,EACA,kBAAAC,EAEjB,KAAK,OAASL,EAAM,OAAO,CACzB,QAAS,KAAK,QACd,QAAS,KAAK,UACd,QAAS,CACP,0BAA2B,KAAK,YAClC,EACA,aAAc,CAAE,oBAAqB,EAAK,CAC5C,CAAC,CACH,CAfiB,OAiBjB,MAAc,SAASM,EAAcC,EAA6B,CAChE,MAAMC,EAAK,IAAI,gBACTC,EAAS,WAAW,IAAMD,EAAG,MAAM,EAAGD,CAAE,EAC9C,GAAI,CACF,KAAM,CAAE,KAAAG,CAAK,EAAI,MAAM,KAAK,OAAO,KACjC,QACA,CAAE,KAAMJ,CAAK,EACb,CAAE,QAASC,EAAI,OAAQC,EAAG,MAAO,CACnC,EACA,OAAOE,EAAK,IACd,QAAE,CACA,aAAaD,CAAM,CACrB,CACF,CAEA,MAAM,SAASH,EAA+B,CAC5C,MAAMK,EAAW,KAAK,IAAI,KAAM,KAAK,SAAS,EACxCC,EAAQ,KAAK,IAAI,EAAG,KAAK,MAAM,KAAK,UAAYD,CAAQ,CAAC,EAC/D,IAAIE,EACJ,QAAS,EAAI,EAAG,EAAID,EAAO,IACzB,GAAI,CACF,OAAO,MAAM,KAAK,SAASN,EAAMK,CAAQ,CAC3C,OAASG,EAAG,CACVD,EAAUC,EACV,MAAM,IAAI,QAASC,GAAM,WAAWA,EAAG,GAAG,CAAC,CAC7C,CAEF,MAAIF,aAAmBZ,GACjBY,aAAmB,MADgBA,EACE,IAAI,MAAM,OAAOA,CAAO,CAAC,CACtE,CACF",
6
+ "names": ["axios", "AxiosError", "HttpLegacySpeculosDatasource", "baseUrl", "timeoutMs", "clientHeader", "apdu", "ms", "ac", "killer", "data", "perTryMs", "tries", "lastErr", "e", "r"]
7
+ }
@@ -1,2 +1,2 @@
1
- import s from"axios";import t from"../../../package.json";const o=5e3;class l{constructor(e){this.baseUrl=e}async postAdpu(e){const r={data:e};return(await s.request({method:"POST",url:`${this.baseUrl}/apdu`,data:r,headers:{"X-Ledger-Client-Version":`ldmk-transport-speculos/${t.version}`}})).data.data}async isServerAvailable(){try{return await s.request({method:"GET",url:`${this.baseUrl}/events`,headers:{"X-Ledger-Client-Version":`ldmk-transport-speculos/${t.version}`},timeout:o}),!0}catch{return!1}}}export{l as HttpSpeculosDatasource};
1
+ import t from"axios";import o from"../../../package.json";class c{constructor(s){this.baseUrl=s}async postAdpu(s){const e={data:s};return(await t.request({method:"POST",url:`${this.baseUrl}/apdu`,data:e,headers:{"X-Ledger-Client-Version":`ldmk-transport-speculos/${o.version}`}})).data.data}}export{c as HttpSpeculosDatasource};
2
2
  //# sourceMappingURL=HttpSpeculosDatasource.js.map
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "version": 3,
3
3
  "sources": ["../../../../../src/internal/datasource/HttpSpeculosDatasource.ts"],
4
- "sourcesContent": ["import axios from \"axios\";\n\nimport PACKAGE from \"@root/package.json\";\n\nimport { type SpeculosDatasource } from \"./SpeculosDatasource\";\n\nconst TIMEOUT = 5000; // 5 second timeout for availability check\n\nexport class HttpSpeculosDatasource implements SpeculosDatasource {\n constructor(private readonly baseUrl: string) {}\n\n async postAdpu(apdu: string): Promise<string> {\n const requestDto = {\n data: apdu,\n };\n\n const speculosResponse = await axios.request<SpeculosApduDTO>({\n method: \"POST\",\n url: `${this.baseUrl}/apdu`,\n data: requestDto,\n headers: {\n \"X-Ledger-Client-Version\": `ldmk-transport-speculos/${PACKAGE.version}`,\n },\n });\n\n return speculosResponse.data.data;\n }\n\n async isServerAvailable(): Promise<boolean> {\n try {\n await axios.request<SpeculosEventsDTO>({\n method: \"GET\",\n url: `${this.baseUrl}/events`,\n headers: {\n \"X-Ledger-Client-Version\": `ldmk-transport-speculos/${PACKAGE.version}`,\n },\n timeout: TIMEOUT,\n });\n return true;\n } catch (_error) {\n return false;\n }\n }\n}\n\ntype SpeculosApduDTO = {\n data: string;\n};\n\ntype SpeculosEventsDTO = {\n events: Array<{\n text?: string;\n x?: number;\n y?: number;\n }>;\n};\n"],
5
- "mappings": "AAAA,OAAOA,MAAW,QAElB,OAAOC,MAAa,qBAIpB,MAAMC,EAAU,IAET,MAAMC,CAAqD,CAChE,YAA6BC,EAAiB,CAAjB,aAAAA,CAAkB,CAE/C,MAAM,SAASC,EAA+B,CAC5C,MAAMC,EAAa,CACjB,KAAMD,CACR,EAWA,OATyB,MAAML,EAAM,QAAyB,CAC5D,OAAQ,OACR,IAAK,GAAG,KAAK,OAAO,QACpB,KAAMM,EACN,QAAS,CACP,0BAA2B,2BAA2BL,EAAQ,OAAO,EACvE,CACF,CAAC,GAEuB,KAAK,IAC/B,CAEA,MAAM,mBAAsC,CAC1C,GAAI,CACF,aAAMD,EAAM,QAA2B,CACrC,OAAQ,MACR,IAAK,GAAG,KAAK,OAAO,UACpB,QAAS,CACP,0BAA2B,2BAA2BC,EAAQ,OAAO,EACvE,EACA,QAASC,CACX,CAAC,EACM,EACT,MAAiB,CACf,MAAO,EACT,CACF,CACF",
6
- "names": ["axios", "PACKAGE", "TIMEOUT", "HttpSpeculosDatasource", "baseUrl", "apdu", "requestDto"]
4
+ "sourcesContent": ["import axios from \"axios\";\n\nimport PACKAGE from \"@root/package.json\";\n\nimport { type SpeculosDatasource } from \"./SpeculosDatasource\";\nexport class HttpSpeculosDatasource implements SpeculosDatasource {\n constructor(private readonly baseUrl: string) {}\n\n async postAdpu(apdu: string): Promise<string> {\n const requestDto = {\n data: apdu,\n };\n\n const speculosResponse = await axios.request<SpeculosApduDTO>({\n method: \"POST\",\n url: `${this.baseUrl}/apdu`,\n data: requestDto,\n headers: {\n \"X-Ledger-Client-Version\": `ldmk-transport-speculos/${PACKAGE.version}`,\n },\n });\n\n return speculosResponse.data.data;\n }\n}\n\ntype SpeculosApduDTO = {\n data: string;\n};\n"],
5
+ "mappings": "AAAA,OAAOA,MAAW,QAElB,OAAOC,MAAa,qBAGb,MAAMC,CAAqD,CAChE,YAA6BC,EAAiB,CAAjB,aAAAA,CAAkB,CAE/C,MAAM,SAASC,EAA+B,CAC5C,MAAMC,EAAa,CACjB,KAAMD,CACR,EAWA,OATyB,MAAMJ,EAAM,QAAyB,CAC5D,OAAQ,OACR,IAAK,GAAG,KAAK,OAAO,QACpB,KAAMK,EACN,QAAS,CACP,0BAA2B,2BAA2BJ,EAAQ,OAAO,EACvE,CACF,CAAC,GAEuB,KAAK,IAC/B,CACF",
6
+ "names": ["axios", "PACKAGE", "HttpSpeculosDatasource", "baseUrl", "apdu", "requestDto"]
7
7
  }
@@ -0,0 +1,29 @@
1
+ import { type ApduResponse, type ConnectError, type DeviceId, type DisconnectHandler, type DmkConfig, type DmkError, type LoggerPublisherService, type Transport, type TransportConnectedDevice, type TransportDiscoveredDevice, type TransportFactory, type TransportIdentifier } from "@ledgerhq/device-management-kit";
2
+ import { type Either } from "purify-ts";
3
+ import { type Observable } from "rxjs";
4
+ export declare class QuietSpeculosTransport implements Transport {
5
+ private logger;
6
+ private readonly identifier;
7
+ private readonly _speculosDataSource;
8
+ private connectedDevice;
9
+ private disconnectInterval;
10
+ private readonly speculosDevice;
11
+ constructor(loggerServiceFactory: (tag: string) => LoggerPublisherService, _config: DmkConfig, speculosUrl: string);
12
+ isSupported(): boolean;
13
+ getIdentifier(): TransportIdentifier;
14
+ listenToAvailableDevices(): Observable<TransportDiscoveredDevice[]>;
15
+ startDiscovering(): Observable<TransportDiscoveredDevice>;
16
+ stopDiscovering(): void;
17
+ connect(params: {
18
+ deviceId: DeviceId;
19
+ onDisconnect: DisconnectHandler;
20
+ }): Promise<Either<ConnectError, TransportConnectedDevice>>;
21
+ disconnect(_params: {
22
+ connectedDevice: TransportConnectedDevice;
23
+ }): Promise<Either<DmkError, void>>;
24
+ sendApdu(_sessionId: string, deviceId: DeviceId, onDisconnect: DisconnectHandler, apdu: Uint8Array): Promise<Either<DmkError, ApduResponse>>;
25
+ private createApduResponse;
26
+ private fromHexString;
27
+ }
28
+ export declare const quietSpeculosTransportFactory: (speculosUrl?: string, legacyE2ECompatibility?: boolean) => TransportFactory;
29
+ //# sourceMappingURL=QuietSpeculosTransport.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"QuietSpeculosTransport.d.ts","sourceRoot":"","sources":["../../../../src/api/QuietSpeculosTransport.ts"],"names":[],"mappings":"AAAA,OAAO,EAEL,KAAK,YAAY,EAEjB,KAAK,YAAY,EACjB,KAAK,QAAQ,EAEb,KAAK,iBAAiB,EACtB,KAAK,SAAS,EACd,KAAK,QAAQ,EAEb,KAAK,sBAAsB,EAE3B,KAAK,SAAS,EACd,KAAK,wBAAwB,EAC7B,KAAK,yBAAyB,EAC9B,KAAK,gBAAgB,EACrB,KAAK,mBAAmB,EACzB,MAAM,iCAAiC,CAAC;AACzC,OAAO,EAAE,KAAK,MAAM,EAAe,MAAM,WAAW,CAAC;AACrD,OAAO,EAAQ,KAAK,UAAU,EAAE,MAAM,MAAM,CAAC;AAM7C,qBAAa,sBAAuB,YAAW,SAAS;IACtD,OAAO,CAAC,MAAM,CAAyB;IACvC,OAAO,CAAC,QAAQ,CAAC,UAAU,CAA2C;IACtE,OAAO,CAAC,QAAQ,CAAC,mBAAmB,CAA+B;IAEnE,OAAO,CAAC,eAAe,CAAyC;IAChE,OAAO,CAAC,kBAAkB,CAA+B;IAEzD,OAAO,CAAC,QAAQ,CAAC,cAAc,CAgB7B;gBAGA,oBAAoB,EAAE,CAAC,GAAG,EAAE,MAAM,KAAK,sBAAsB,EAC7D,OAAO,EAAE,SAAS,EAClB,WAAW,EAAE,MAAM;IAUrB,WAAW,IAAI,OAAO;IAItB,aAAa,IAAI,mBAAmB;IAIpC,wBAAwB,IAAI,UAAU,CAAC,yBAAyB,EAAE,CAAC;IAInE,gBAAgB,IAAI,UAAU,CAAC,yBAAyB,CAAC;IAKzD,eAAe,IAAI,IAAI;IAIjB,OAAO,CAAC,MAAM,EAAE;QACpB,QAAQ,EAAE,QAAQ,CAAC;QACnB,YAAY,EAAE,iBAAiB,CAAC;KACjC,GAAG,OAAO,CAAC,MAAM,CAAC,YAAY,EAAE,wBAAwB,CAAC,CAAC;IAwCrD,UAAU,CAAC,OAAO,EAAE;QACxB,eAAe,EAAE,wBAAwB,CAAC;KAC3C,GAAG,OAAO,CAAC,MAAM,CAAC,QAAQ,EAAE,IAAI,CAAC,CAAC;IAO7B,QAAQ,CACZ,UAAU,EAAE,MAAM,EAClB,QAAQ,EAAE,QAAQ,EAClB,YAAY,EAAE,iBAAiB,EAC/B,IAAI,EAAE,UAAU,GACf,OAAO,CAAC,MAAM,CAAC,QAAQ,EAAE,YAAY,CAAC,CAAC;IAiB1C,OAAO,CAAC,kBAAkB;IAW1B,OAAO,CAAC,aAAa;CAMtB;AAED,eAAO,MAAM,6BAA6B,EAAE,CAC1C,WAAW,CAAC,EAAE,MAAM,EACpB,sBAAsB,CAAC,EAAE,OAAO,KAC7B,gBAGoE,CAAC"}
@@ -3,13 +3,14 @@ import { type Either } from "purify-ts";
3
3
  import { type Observable } from "rxjs";
4
4
  export declare const speculosIdentifier: TransportIdentifier;
5
5
  export declare class SpeculosTransport implements Transport {
6
+ private readonly legacyE2ECompatibility;
6
7
  private logger;
7
8
  private readonly identifier;
8
9
  private readonly _speculosDataSource;
9
10
  private connectedDevice;
10
11
  private disconnectInterval;
11
12
  private readonly speculosDevice;
12
- constructor(loggerServiceFactory: (tag: string) => LoggerPublisherService, _config: DmkConfig, speculosUrl: string);
13
+ constructor(loggerServiceFactory: (tag: string) => LoggerPublisherService, _config: DmkConfig, speculosUrl: string, legacyE2ECompatibility: boolean);
13
14
  isSupported(): boolean;
14
15
  getIdentifier(): TransportIdentifier;
15
16
  listenToAvailableDevices(): Observable<TransportDiscoveredDevice[]>;
@@ -27,5 +28,5 @@ export declare class SpeculosTransport implements Transport {
27
28
  private fromHexString;
28
29
  private listenForDisconnect;
29
30
  }
30
- export declare const speculosTransportFactory: (speculosUrl?: string) => TransportFactory;
31
+ export declare const speculosTransportFactory: (speculosUrl?: string, legacyE2ECompatibility?: boolean) => TransportFactory;
31
32
  //# sourceMappingURL=SpeculosTransport.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"SpeculosTransport.d.ts","sourceRoot":"","sources":["../../../../src/api/SpeculosTransport.ts"],"names":[],"mappings":"AAAA,OAAO,EAEL,KAAK,YAAY,EAEjB,KAAK,YAAY,EACjB,KAAK,QAAQ,EAEb,KAAK,iBAAiB,EACtB,KAAK,SAAS,EACd,KAAK,QAAQ,EAEb,KAAK,sBAAsB,EAE3B,KAAK,SAAS,EACd,KAAK,wBAAwB,EAC7B,KAAK,yBAAyB,EAC9B,KAAK,gBAAgB,EACrB,KAAK,mBAAmB,EACzB,MAAM,iCAAiC,CAAC;AACzC,OAAO,EAAE,KAAK,MAAM,EAAe,MAAM,WAAW,CAAC;AACrD,OAAO,EAAQ,KAAK,UAAU,EAAE,MAAM,MAAM,CAAC;AAK7C,eAAO,MAAM,kBAAkB,EAAE,mBACN,CAAC;AAE5B,qBAAa,iBAAkB,YAAW,SAAS;IACjD,OAAO,CAAC,MAAM,CAAyB;IACvC,OAAO,CAAC,QAAQ,CAAC,UAAU,CAA2C;IACtE,OAAO,CAAC,QAAQ,CAAC,mBAAmB,CAAqB;IACzD,OAAO,CAAC,eAAe,CAAyC;IAChE,OAAO,CAAC,kBAAkB,CAA+B;IACzD,OAAO,CAAC,QAAQ,CAAC,cAAc,CAgB7B;gBAGA,oBAAoB,EAAE,CAAC,GAAG,EAAE,MAAM,KAAK,sBAAsB,EAC7D,OAAO,EAAE,SAAS,EAClB,WAAW,EAAE,MAAM;IAMrB,WAAW,IAAI,OAAO;IAItB,aAAa,IAAI,mBAAmB;IAIpC,wBAAwB,IAAI,UAAU,CAAC,yBAAyB,EAAE,CAAC;IAInE,gBAAgB,IAAI,UAAU,CAAC,yBAAyB,CAAC;IAKzD,eAAe,IAAI,IAAI;IAKjB,OAAO,CAAC,MAAM,EAAE;QACpB,QAAQ,EAAE,QAAQ,CAAC;QACnB,YAAY,EAAE,iBAAiB,CAAC;KACjC,GAAG,OAAO,CAAC,MAAM,CAAC,YAAY,EAAE,wBAAwB,CAAC,CAAC;IA8CrD,UAAU,CAAC,OAAO,EAAE;QACxB,eAAe,EAAE,wBAAwB,CAAC;KAC3C,GAAG,OAAO,CAAC,MAAM,CAAC,QAAQ,EAAE,IAAI,CAAC,CAAC;IAM7B,QAAQ,CACZ,UAAU,EAAE,MAAM,EAClB,QAAQ,EAAE,QAAQ,EAClB,YAAY,EAAE,iBAAiB,EAC/B,IAAI,EAAE,UAAU,GACf,OAAO,CAAC,MAAM,CAAC,QAAQ,EAAE,YAAY,CAAC,CAAC;IAwB1C,OAAO,CAAC,kBAAkB;IAgB1B,OAAO,CAAC,aAAa;IASrB,OAAO,CAAC,mBAAmB;CA0B5B;AAED,eAAO,MAAM,wBAAwB,EAAE,CACrC,WAAW,CAAC,EAAE,MAAM,KACjB,gBAG+D,CAAC"}
1
+ {"version":3,"file":"SpeculosTransport.d.ts","sourceRoot":"","sources":["../../../../src/api/SpeculosTransport.ts"],"names":[],"mappings":"AAAA,OAAO,EAEL,KAAK,YAAY,EAEjB,KAAK,YAAY,EACjB,KAAK,QAAQ,EAEb,KAAK,iBAAiB,EACtB,KAAK,SAAS,EACd,KAAK,QAAQ,EAEb,KAAK,sBAAsB,EAE3B,KAAK,SAAS,EACd,KAAK,wBAAwB,EAC7B,KAAK,yBAAyB,EAC9B,KAAK,gBAAgB,EACrB,KAAK,mBAAmB,EACzB,MAAM,iCAAiC,CAAC;AAEzC,OAAO,EAAE,KAAK,MAAM,EAAe,MAAM,WAAW,CAAC;AACrD,OAAO,EAAQ,KAAK,UAAU,EAAE,MAAM,MAAM,CAAC;AAM7C,eAAO,MAAM,kBAAkB,EAAE,mBACN,CAAC;AAE5B,qBAAa,iBAAkB,YAAW,SAAS;IA4B/C,OAAO,CAAC,QAAQ,CAAC,sBAAsB;IA3BzC,OAAO,CAAC,MAAM,CAAyB;IACvC,OAAO,CAAC,QAAQ,CAAC,UAAU,CAA2C;IACtE,OAAO,CAAC,QAAQ,CAAC,mBAAmB,CAAqB;IACzD,OAAO,CAAC,eAAe,CAAyC;IAChE,OAAO,CAAC,kBAAkB,CAA+B;IACzD,OAAO,CAAC,QAAQ,CAAC,cAAc,CAgB7B;gBAGA,oBAAoB,EAAE,CAAC,GAAG,EAAE,MAAM,KAAK,sBAAsB,EAC7D,OAAO,EAAE,SAAS,EAClB,WAAW,EAAE,MAAM,EACF,sBAAsB,EAAE,OAAO;IAQlD,WAAW,IAAI,OAAO;IAItB,aAAa,IAAI,mBAAmB;IAIpC,wBAAwB,IAAI,UAAU,CAAC,yBAAyB,EAAE,CAAC;IAInE,gBAAgB,IAAI,UAAU,CAAC,yBAAyB,CAAC;IAKzD,eAAe,IAAI,IAAI;IAKjB,OAAO,CAAC,MAAM,EAAE;QACpB,QAAQ,EAAE,QAAQ,CAAC;QACnB,YAAY,EAAE,iBAAiB,CAAC;KACjC,GAAG,OAAO,CAAC,MAAM,CAAC,YAAY,EAAE,wBAAwB,CAAC,CAAC;IAgDrD,UAAU,CAAC,OAAO,EAAE;QACxB,eAAe,EAAE,wBAAwB,CAAC;KAC3C,GAAG,OAAO,CAAC,MAAM,CAAC,QAAQ,EAAE,IAAI,CAAC,CAAC;IAM7B,QAAQ,CACZ,UAAU,EAAE,MAAM,EAClB,QAAQ,EAAE,QAAQ,EAClB,YAAY,EAAE,iBAAiB,EAC/B,IAAI,EAAE,UAAU,GACf,OAAO,CAAC,MAAM,CAAC,QAAQ,EAAE,YAAY,CAAC,CAAC;IAsB1C,OAAO,CAAC,kBAAkB;IAgB1B,OAAO,CAAC,aAAa;IASrB,OAAO,CAAC,mBAAmB;CA2B5B;AAED,eAAO,MAAM,wBAAwB,EAAE,CACrC,WAAW,CAAC,EAAE,MAAM,EACpB,sBAAsB,CAAC,EAAE,OAAO,KAC7B,gBAQA,CAAC"}
@@ -1,2 +1,3 @@
1
+ export * from "./api/QuietSpeculosTransport";
1
2
  export * from "./api/SpeculosTransport";
2
3
  //# sourceMappingURL=index.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/index.ts"],"names":[],"mappings":"AAAA,cAAc,yBAAyB,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/index.ts"],"names":[],"mappings":"AAAA,cAAc,8BAA8B,CAAC;AAC7C,cAAc,yBAAyB,CAAC"}
@@ -0,0 +1,10 @@
1
+ export declare class HttpLegacySpeculosDatasource {
2
+ private readonly baseUrl;
3
+ private readonly timeoutMs;
4
+ private readonly clientHeader;
5
+ private readonly client;
6
+ constructor(baseUrl: string, timeoutMs?: number, clientHeader?: string);
7
+ private postOnce;
8
+ postAdpu(apdu: string): Promise<string>;
9
+ }
10
+ //# sourceMappingURL=HttpLegacySpeculosDatasource.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"HttpLegacySpeculosDatasource.d.ts","sourceRoot":"","sources":["../../../../../src/internal/datasource/HttpLegacySpeculosDatasource.ts"],"names":[],"mappings":"AAEA,qBAAa,4BAA4B;IAIrC,OAAO,CAAC,QAAQ,CAAC,OAAO;IACxB,OAAO,CAAC,QAAQ,CAAC,SAAS;IAC1B,OAAO,CAAC,QAAQ,CAAC,YAAY;IAL/B,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAgB;gBAGpB,OAAO,EAAE,MAAM,EACf,SAAS,GAAE,MAAc,EACzB,YAAY,GAAE,MAAkC;YAYrD,QAAQ;IAehB,QAAQ,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC;CAe9C"}
@@ -3,6 +3,5 @@ export declare class HttpSpeculosDatasource implements SpeculosDatasource {
3
3
  private readonly baseUrl;
4
4
  constructor(baseUrl: string);
5
5
  postAdpu(apdu: string): Promise<string>;
6
- isServerAvailable(): Promise<boolean>;
7
6
  }
8
7
  //# sourceMappingURL=HttpSpeculosDatasource.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"HttpSpeculosDatasource.d.ts","sourceRoot":"","sources":["../../../../../src/internal/datasource/HttpSpeculosDatasource.ts"],"names":[],"mappings":"AAIA,OAAO,EAAE,KAAK,kBAAkB,EAAE,MAAM,sBAAsB,CAAC;AAI/D,qBAAa,sBAAuB,YAAW,kBAAkB;IACnD,OAAO,CAAC,QAAQ,CAAC,OAAO;gBAAP,OAAO,EAAE,MAAM;IAEtC,QAAQ,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC;IAiBvC,iBAAiB,IAAI,OAAO,CAAC,OAAO,CAAC;CAe5C"}
1
+ {"version":3,"file":"HttpSpeculosDatasource.d.ts","sourceRoot":"","sources":["../../../../../src/internal/datasource/HttpSpeculosDatasource.ts"],"names":[],"mappings":"AAIA,OAAO,EAAE,KAAK,kBAAkB,EAAE,MAAM,sBAAsB,CAAC;AAC/D,qBAAa,sBAAuB,YAAW,kBAAkB;IACnD,OAAO,CAAC,QAAQ,CAAC,OAAO;gBAAP,OAAO,EAAE,MAAM;IAEtC,QAAQ,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC;CAgB9C"}
@@ -1,5 +1,4 @@
1
1
  export interface SpeculosDatasource {
2
2
  postAdpu(apdu: string): Promise<string>;
3
- isServerAvailable(): Promise<boolean>;
4
3
  }
5
4
  //# sourceMappingURL=SpeculosDatasource.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"SpeculosDatasource.d.ts","sourceRoot":"","sources":["../../../../../src/internal/datasource/SpeculosDatasource.ts"],"names":[],"mappings":"AAAA,MAAM,WAAW,kBAAkB;IACjC,QAAQ,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC,CAAC;IACxC,iBAAiB,IAAI,OAAO,CAAC,OAAO,CAAC,CAAC;CACvC"}
1
+ {"version":3,"file":"SpeculosDatasource.d.ts","sourceRoot":"","sources":["../../../../../src/internal/datasource/SpeculosDatasource.ts"],"names":[],"mappings":"AAAA,MAAM,WAAW,kBAAkB;IACjC,QAAQ,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC,CAAC;CACzC"}