@ledgerhq/device-transport-kit-speculos 0.0.0-e2e-speculos-20250905084020 → 0.0.0-e2e-speculos-20250908083159
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/lib/cjs/src/api/E2eSpeculosTransport.js +2 -0
- package/lib/cjs/src/api/E2eSpeculosTransport.js.map +7 -0
- package/lib/cjs/src/api/SpeculosTransport.js +1 -1
- package/lib/cjs/src/api/SpeculosTransport.js.map +3 -3
- package/lib/cjs/src/index.js +1 -1
- package/lib/cjs/src/index.js.map +2 -2
- package/lib/cjs/src/internal/datasource/E2eHttpSpeculosDatasource.js +3 -0
- package/lib/cjs/src/internal/datasource/E2eHttpSpeculosDatasource.js.map +7 -0
- package/lib/cjs/src/internal/datasource/E2eSpeculosDatasource.js +2 -0
- package/lib/cjs/src/internal/datasource/E2eSpeculosDatasource.js.map +7 -0
- package/lib/cjs/src/internal/datasource/HttpSpeculosDatasource.js +1 -1
- package/lib/cjs/src/internal/datasource/HttpSpeculosDatasource.js.map +3 -3
- package/lib/cjs/src/internal/datasource/SpeculosDatasource.js +1 -1
- package/lib/cjs/src/internal/datasource/SpeculosDatasource.js.map +1 -1
- package/lib/cjs/src/internal/utils/axiosInstances.js +2 -0
- package/lib/cjs/src/internal/utils/axiosInstances.js.map +7 -0
- package/lib/esm/src/api/E2eSpeculosTransport.js +2 -0
- package/lib/esm/src/api/E2eSpeculosTransport.js.map +7 -0
- package/lib/esm/src/api/SpeculosTransport.js +1 -1
- package/lib/esm/src/api/SpeculosTransport.js.map +3 -3
- package/lib/esm/src/index.js +1 -1
- package/lib/esm/src/index.js.map +2 -2
- package/lib/esm/src/internal/datasource/E2eHttpSpeculosDatasource.js +3 -0
- package/lib/esm/src/internal/datasource/E2eHttpSpeculosDatasource.js.map +7 -0
- package/lib/esm/src/internal/datasource/E2eSpeculosDatasource.js +1 -0
- package/lib/esm/src/internal/datasource/E2eSpeculosDatasource.js.map +7 -0
- package/lib/esm/src/internal/datasource/HttpSpeculosDatasource.js +1 -1
- package/lib/esm/src/internal/datasource/HttpSpeculosDatasource.js.map +3 -3
- package/lib/esm/src/internal/utils/axiosInstances.js +2 -0
- package/lib/esm/src/internal/utils/axiosInstances.js.map +7 -0
- package/lib/types/src/api/{QuietSpeculosTransport.d.ts → E2eSpeculosTransport.d.ts} +3 -3
- package/lib/types/src/api/E2eSpeculosTransport.d.ts.map +1 -0
- package/lib/types/src/api/SpeculosTransport.d.ts +2 -3
- package/lib/types/src/api/SpeculosTransport.d.ts.map +1 -1
- package/lib/types/src/index.d.ts +1 -1
- package/lib/types/src/index.d.ts.map +1 -1
- package/lib/types/src/internal/datasource/{HttpLegacySpeculosDatasource.d.ts → E2eHttpSpeculosDatasource.d.ts} +5 -3
- package/lib/types/src/internal/datasource/E2eHttpSpeculosDatasource.d.ts.map +1 -0
- package/lib/types/src/internal/datasource/E2eSpeculosDatasource.d.ts +7 -0
- package/lib/types/src/internal/datasource/E2eSpeculosDatasource.d.ts.map +1 -0
- package/lib/types/src/internal/datasource/HttpSpeculosDatasource.d.ts +1 -0
- package/lib/types/src/internal/datasource/HttpSpeculosDatasource.d.ts.map +1 -1
- package/lib/types/src/internal/datasource/SpeculosDatasource.d.ts +1 -0
- package/lib/types/src/internal/datasource/SpeculosDatasource.d.ts.map +1 -1
- package/lib/types/src/internal/utils/axiosInstances.d.ts +4 -0
- package/lib/types/src/internal/utils/axiosInstances.d.ts.map +1 -0
- package/lib/types/tsconfig.prod.tsbuildinfo +1 -1
- package/package.json +5 -5
- package/lib/cjs/src/api/QuietSpeculosTransport.js +0 -2
- package/lib/cjs/src/api/QuietSpeculosTransport.js.map +0 -7
- package/lib/cjs/src/internal/datasource/HttpLegacySpeculosDatasource.js +0 -3
- package/lib/cjs/src/internal/datasource/HttpLegacySpeculosDatasource.js.map +0 -7
- package/lib/esm/src/api/QuietSpeculosTransport.js +0 -2
- package/lib/esm/src/api/QuietSpeculosTransport.js.map +0 -7
- package/lib/esm/src/internal/datasource/HttpLegacySpeculosDatasource.js +0 -3
- package/lib/esm/src/internal/datasource/HttpLegacySpeculosDatasource.js.map +0 -7
- package/lib/types/src/api/QuietSpeculosTransport.d.ts.map +0 -1
- package/lib/types/src/internal/datasource/HttpLegacySpeculosDatasource.d.ts.map +0 -1
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@ledgerhq/device-transport-kit-speculos",
|
|
3
|
-
"version": "0.0.0-e2e-speculos-
|
|
3
|
+
"version": "0.0.0-e2e-speculos-20250908083159",
|
|
4
4
|
"license": "Apache-2.0",
|
|
5
5
|
"private": false,
|
|
6
6
|
"exports": {
|
|
@@ -26,16 +26,16 @@
|
|
|
26
26
|
"devDependencies": {
|
|
27
27
|
"rxjs": "^7.8.2",
|
|
28
28
|
"ts-node": "10.9.2",
|
|
29
|
-
"@ledgerhq/device-management-kit": "0.0.0-e2e-speculos-
|
|
29
|
+
"@ledgerhq/device-management-kit": "0.0.0-e2e-speculos-20250908083159",
|
|
30
30
|
"@ledgerhq/eslint-config-dsdk": "0.0.2",
|
|
31
31
|
"@ledgerhq/ldmk-tool": "0.0.1",
|
|
32
32
|
"@ledgerhq/prettier-config-dsdk": "0.0.2",
|
|
33
|
-
"@ledgerhq/
|
|
34
|
-
"@ledgerhq/
|
|
33
|
+
"@ledgerhq/vitest-config-dmk": "0.0.0",
|
|
34
|
+
"@ledgerhq/tsconfig-dsdk": "1.0.1"
|
|
35
35
|
},
|
|
36
36
|
"peerDependencies": {
|
|
37
37
|
"rxjs": "^7.8.2",
|
|
38
|
-
"@ledgerhq/device-management-kit": "0.0.0-e2e-speculos-
|
|
38
|
+
"@ledgerhq/device-management-kit": "0.0.0-e2e-speculos-20250908083159"
|
|
39
39
|
},
|
|
40
40
|
"scripts": {
|
|
41
41
|
"prebuild": "rimraf lib",
|
|
@@ -1,2 +0,0 @@
|
|
|
1
|
-
"use strict";var a=Object.defineProperty;var v=Object.getOwnPropertyDescriptor;var D=Object.getOwnPropertyNames;var h=Object.prototype.hasOwnProperty;var m=(s,e)=>{for(var r in e)a(s,r,{get:e[r],enumerable:!0})},y=(s,e,r,o)=>{if(e&&typeof e=="object"||typeof e=="function")for(let t of D(e))!h.call(s,t)&&t!==r&&a(s,t,{get:()=>e[t],enumerable:!(o=v(e,t))||o.enumerable});return s};var S=s=>y(a({},"__esModule",{value:!0}),s);var f={};m(f,{QuietSpeculosTransport:()=>g,quietSpeculosTransportFactory:()=>b});module.exports=S(f);var n=require("@ledgerhq/device-management-kit"),i=require("purify-ts"),d=require("rxjs"),u=require("../internal/datasource/HttpLegacySpeculosDatasource"),l=require("./SpeculosTransport");class g{logger;identifier=l.speculosIdentifier;_speculosDataSource;connectedDevice=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 u.HttpLegacySpeculosDatasource(o,1e4,"ldmk-transport-speculos")}isSupported(){return!0}getIdentifier(){return this.identifier}listenToAvailableDevices(){return(0,d.from)([[this.speculosDevice]])}startDiscovering(){return this.logger.debug("startDiscovering"),(0,d.from)([this.speculosDevice])}stopDiscovering(){this.logger.debug("stopDiscovering")}async connect(e){this.logger.debug("connect");try{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 c=t.encodeToString(t.extractFieldLVEncoded()),p=t.encodeToString(t.extractFieldLVEncoded());this.logger.debug(`App Name: ${c} and version ${p}`),this.speculosDevice.deviceModel.productName=`Speculos - ${c} - ${p}`}catch{}try{const r={sendApdu:o=>this.sendApdu(e.deviceId,e.onDisconnect,o),deviceModel:this.speculosDevice.deviceModel,transport:this.identifier,id:"SpeculosID",type:"USB"};return this.connectedDevice=r,(0,i.Right)(r)}catch(r){return(0,i.Left)(new n.OpeningConnectionError(r))}}async disconnect(e){return this.logger.debug("disconnect"),this.connectedDevice=null,Promise.resolve((0,i.Right)(void 0))}async sendApdu(e,r,o){try{const t=(0,n.bufferToHexaString)(o).substring(2).toUpperCase();this.logger.debug(`[QuietSpeculosTransport] send APDU: ${t}`);const c=await this._speculosDataSource.postAdpu(t),p=this.createApduResponse(c);return(0,i.Right)(p)}catch(t){return this.connectedDevice&&(this.logger.debug("disconnecting due to APDU error"),r(e),await this.disconnect({connectedDevice:this.connectedDevice})),(0,i.Left)(new n.GeneralDmkError(t))}}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))):new Uint8Array(0)}}const b=(s="http://127.0.0.1:5000")=>({config:e,loggerServiceFactory:r})=>new g(r,e,s);0&&(module.exports={QuietSpeculosTransport,quietSpeculosTransportFactory});
|
|
2
|
-
//# sourceMappingURL=QuietSpeculosTransport.js.map
|
|
@@ -1,7 +0,0 @@
|
|
|
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\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 // Probe app name/version via GET_VERSION (B0010000) if possible\n try {\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 parser.extract8BitUInt();\n const appName = parser.encodeToString(parser.extractFieldLVEncoded());\n const appVersion = parser.encodeToString(parser.extractFieldLVEncoded());\n this.logger.debug(`App Name: ${appName} and version ${appVersion}`);\n\n this.speculosDevice.deviceModel.productName = `Speculos - ${appName} - ${appVersion}`;\n } catch {\n // ignore if the app doesn't support GET_VERSION\n }\n\n try {\n const connectedDevice: TransportConnectedDevice = {\n sendApdu: (apdu: Uint8Array) =>\n this.sendApdu(params.deviceId, params.onDisconnect, apdu),\n deviceModel: this.speculosDevice.deviceModel,\n transport: this.identifier,\n id: \"SpeculosID\",\n type: \"USB\",\n };\n\n this.connectedDevice = connectedDevice;\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 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 new Uint8Array(0);\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) => 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", "connectedDevice", "apdu", "error", "_params", "deviceId", "onDisconnect", "hex", "resp", "hexApdu", "sw", "payload", "hexString", "b", "config"]
|
|
7
|
-
}
|
|
@@ -1,3 +0,0 @@
|
|
|
1
|
-
"use strict";var A=Object.create;var o=Object.defineProperty;var f=Object.getOwnPropertyDescriptor;var x=Object.getOwnPropertyNames;var y=Object.getPrototypeOf,v=Object.prototype.hasOwnProperty;var S=(e,t)=>{for(var n in t)o(e,n,{get:t[n],enumerable:!0})},d=(e,t,n,r)=>{if(t&&typeof t=="object"||typeof t=="function")for(let s of x(t))!v.call(e,s)&&s!==n&&o(e,s,{get:()=>t[s],enumerable:!(r=f(t,s))||r.enumerable});return e};var i=(e,t,n)=>(n=e!=null?A(y(e)):{},d(t||!e||!e.__esModule?o(n,"default",{value:e,enumerable:!0}):n,e)),k=e=>d(o({},"__esModule",{value:!0}),e);var R={};S(R,{HttpLegacySpeculosDatasource:()=>b});module.exports=k(R);var p=i(require("axios")),c=i(require("http")),l=i(require("https"));function h(e,t,n){return p.default.create({baseURL:e.replace(/\/+$/,""),timeout:t,proxy:!1,headers:{"X-Ledger-Client-Version":n,Connection:"close"},httpAgent:new c.default.Agent({keepAlive:!1,maxSockets:1/0}),httpsAgent:new l.default.Agent({keepAlive:!1,maxSockets:1/0}),transitional:{clarifyTimeoutError:!0}})}function C(e,t){return p.default.create({baseURL:e.replace(/\/+$/,""),timeout:0,proxy:!1,headers:{"X-Ledger-Client-Version":t,Connection:"keep-alive"},httpAgent:new c.default.Agent({keepAlive:!0,maxSockets:1,maxFreeSockets:1}),httpsAgent:new l.default.Agent({keepAlive:!0,maxSockets:1,maxFreeSockets:1}),transitional:{clarifyTimeoutError:!0}})}class b{constructor(t,n=1e4,r="ldmk-transport-speculos"){this.baseUrl=t;this.timeoutMs=n;this.apduClient=h(t,n,r),this.buttonClient=h(t,Math.min(n,2e3),r),this.sseClient=C(t,r)}apduClient;buttonClient;sseClient;async postAdpu(t){const{data:n}=await this.apduClient.post("/apdu",{data:t},{timeout:this.timeoutMs});return n.data}async pressButton(t){const r={Ll:"left",Rr:"right",LRlr:"both",left:"left",right:"right",both:"both"}[t]??"right";await this.buttonClient.post(`/button/${r}`,{action:"press-and-release"},{timeout:Math.min(this.timeoutMs,1500)})}async openEventStream(t,n){const s=(await this.sseClient.get("/events",{params:{stream:"true"},responseType:"stream",timeout:0,headers:{Accept:"text/event-stream","Cache-Control":"no-cache",Connection:"keep-alive","Accept-Encoding":"identity"}})).data;s.on("data",g=>{g.toString("utf8").split(`
|
|
2
|
-
`).forEach(u=>{if(u.startsWith("data: ")){const m=u.slice(6);try{t(JSON.parse(m))}catch{t({data:m})}}})});const a=()=>n?.();return s.on("close",a),s.on("end",a),s.on("error",a),s}get base(){return this.baseUrl}}0&&(module.exports={HttpLegacySpeculosDatasource});
|
|
3
|
-
//# sourceMappingURL=HttpLegacySpeculosDatasource.js.map
|
|
@@ -1,7 +0,0 @@
|
|
|
1
|
-
{
|
|
2
|
-
"version": 3,
|
|
3
|
-
"sources": ["../../../../../src/internal/datasource/HttpLegacySpeculosDatasource.ts"],
|
|
4
|
-
"sourcesContent": ["import axios, { type AxiosInstance } from \"axios\";\nimport http from \"http\";\nimport https from \"https\";\n\ntype SpeculosApduDTO = { data: string };\n\nfunction makeNoKeepAliveAxios(\n baseUrl: string,\n timeoutMs: number,\n clientHeader: string,\n): AxiosInstance {\n return axios.create({\n baseURL: baseUrl.replace(/\\/+$/, \"\"),\n timeout: timeoutMs,\n proxy: false,\n headers: {\n \"X-Ledger-Client-Version\": clientHeader,\n Connection: \"close\",\n },\n httpAgent: new http.Agent({ keepAlive: false, maxSockets: Infinity }),\n httpsAgent: new https.Agent({ keepAlive: false, maxSockets: Infinity }),\n transitional: { clarifyTimeoutError: true },\n });\n}\n\nfunction makeKeepAliveAxiosForSSE(\n baseUrl: string,\n clientHeader: string,\n): AxiosInstance {\n return axios.create({\n baseURL: baseUrl.replace(/\\/+$/, \"\"),\n timeout: 0, // long-lived\n proxy: false,\n headers: {\n \"X-Ledger-Client-Version\": clientHeader,\n\n Connection: \"keep-alive\",\n },\n httpAgent: new http.Agent({\n keepAlive: true,\n maxSockets: 1,\n maxFreeSockets: 1,\n }),\n httpsAgent: new https.Agent({\n keepAlive: true,\n maxSockets: 1,\n maxFreeSockets: 1,\n }),\n transitional: { clarifyTimeoutError: true },\n });\n}\n\nexport class HttpLegacySpeculosDatasource {\n private readonly apduClient: AxiosInstance;\n private readonly buttonClient: AxiosInstance;\n private readonly sseClient: AxiosInstance;\n\n constructor(\n private readonly baseUrl: string,\n private readonly timeoutMs: number = 10000,\n clientHeader: string = \"ldmk-transport-speculos\",\n ) {\n this.apduClient = makeNoKeepAliveAxios(baseUrl, timeoutMs, clientHeader);\n this.buttonClient = makeNoKeepAliveAxios(\n baseUrl,\n Math.min(timeoutMs, 2000),\n clientHeader,\n );\n\n this.sseClient = makeKeepAliveAxiosForSSE(baseUrl, clientHeader);\n }\n\n async postAdpu(apdu: string): Promise<string> {\n const { data } = await this.apduClient.post<SpeculosApduDTO>(\n \"/apdu\",\n { data: apdu },\n { timeout: this.timeoutMs },\n );\n return data.data;\n }\n\n async pressButton(\n but: \"Ll\" | \"Rr\" | \"LRlr\" | \"left\" | \"right\" | \"both\",\n ): Promise<void> {\n const map: Record<string, \"left\" | \"right\" | \"both\"> = {\n Ll: \"left\",\n Rr: \"right\",\n LRlr: \"both\",\n left: \"left\",\n right: \"right\",\n both: \"both\",\n };\n const input = map[but] ?? \"right\";\n await this.buttonClient.post(\n `/button/${input}`,\n { action: \"press-and-release\" },\n { timeout: Math.min(this.timeoutMs, 1500) },\n );\n }\n\n async openEventStream(\n onEvent: (json: Record<string, unknown>) => void,\n onClose?: () => void,\n ): Promise<NodeJS.ReadableStream> {\n const response = await this.sseClient.get(\"/events\", {\n params: { stream: \"true\" },\n responseType: \"stream\",\n timeout: 0, // keep SSE alive\n headers: {\n Accept: \"text/event-stream\",\n \"Cache-Control\": \"no-cache\",\n Connection: \"keep-alive\",\n \"Accept-Encoding\": \"identity\",\n },\n });\n\n const stream = response.data as NodeJS.ReadableStream;\n\n stream.on(\"data\", (chunk: Buffer) => {\n const txt = chunk.toString(\"utf8\");\n txt.split(\"\\n\").forEach((line) => {\n if (line.startsWith(\"data: \")) {\n const payload = line.slice(6);\n try {\n onEvent(JSON.parse(payload));\n } catch {\n onEvent({ data: payload });\n }\n }\n });\n });\n\n const end = () => onClose?.();\n stream.on(\"close\", end);\n stream.on(\"end\", end);\n stream.on(\"error\", end);\n\n return stream;\n }\n\n get base(): string {\n return this.baseUrl;\n }\n}\n"],
|
|
5
|
-
"mappings": "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",
|
|
6
|
-
"names": ["HttpLegacySpeculosDatasource_exports", "__export", "HttpLegacySpeculosDatasource", "__toCommonJS", "import_axios", "import_http", "import_https", "makeNoKeepAliveAxios", "baseUrl", "timeoutMs", "clientHeader", "axios", "http", "https", "makeKeepAliveAxiosForSSE", "apdu", "data", "but", "input", "onEvent", "onClose", "stream", "chunk", "line", "payload", "end"]
|
|
7
|
-
}
|
|
@@ -1,2 +0,0 @@
|
|
|
1
|
-
import{ApduParser as d,bufferToHexaString as u,DeviceModelId as l,GeneralDmkError as g,OpeningConnectionError as v}from"@ledgerhq/device-management-kit";import{Left as p,Right as i}from"purify-ts";import{from as a}from"rxjs";import{HttpLegacySpeculosDatasource as D}from"../internal/datasource/HttpLegacySpeculosDatasource";import{speculosIdentifier as h}from"./SpeculosTransport";class m{logger;identifier=h;_speculosDataSource;connectedDevice=null;speculosDevice={id:"SpeculosID",deviceModel:{id:l.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(r,e,t){this.logger=r("QuietSpeculosTransport"),this._speculosDataSource=new D(t,1e4,"ldmk-transport-speculos")}isSupported(){return!0}getIdentifier(){return this.identifier}listenToAvailableDevices(){return a([[this.speculosDevice]])}startDiscovering(){return this.logger.debug("startDiscovering"),a([this.speculosDevice])}stopDiscovering(){this.logger.debug("stopDiscovering")}async connect(r){this.logger.debug("connect");try{const e=await this._speculosDataSource.postAdpu("B0010000");this.logger.debug(`Hex Response: ${e}`);const t=this.createApduResponse(e),o=new d(t);o.extract8BitUInt();const s=o.encodeToString(o.extractFieldLVEncoded()),n=o.encodeToString(o.extractFieldLVEncoded());this.logger.debug(`App Name: ${s} and version ${n}`),this.speculosDevice.deviceModel.productName=`Speculos - ${s} - ${n}`}catch{}try{const e={sendApdu:t=>this.sendApdu(r.deviceId,r.onDisconnect,t),deviceModel:this.speculosDevice.deviceModel,transport:this.identifier,id:"SpeculosID",type:"USB"};return this.connectedDevice=e,i(e)}catch(e){return p(new v(e))}}async disconnect(r){return this.logger.debug("disconnect"),this.connectedDevice=null,Promise.resolve(i(void 0))}async sendApdu(r,e,t){try{const o=u(t).substring(2).toUpperCase();this.logger.debug(`[QuietSpeculosTransport] send APDU: ${o}`);const s=await this._speculosDataSource.postAdpu(o),n=this.createApduResponse(s);return i(n)}catch(o){return this.connectedDevice&&(this.logger.debug("disconnecting due to APDU error"),e(r),await this.disconnect({connectedDevice:this.connectedDevice})),p(new g(o))}}createApduResponse(r){const e=r.slice(-4),t=r.slice(0,-4);return this.logger.debug(`[QuietSpeculosTransport] Status code hex: ${e}`),this.logger.debug(`[QuietSpeculosTransport] data hex: ${t}`),{statusCode:this.fromHexString(e),data:this.fromHexString(t)}}fromHexString(r){return r?new Uint8Array(r.match(/.{1,2}/g).map(e=>parseInt(e,16))):new Uint8Array(0)}}const A=(c="http://127.0.0.1:5000")=>({config:r,loggerServiceFactory:e})=>new m(e,r,c);export{m as QuietSpeculosTransport,A as quietSpeculosTransportFactory};
|
|
2
|
-
//# sourceMappingURL=QuietSpeculosTransport.js.map
|
|
@@ -1,7 +0,0 @@
|
|
|
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\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 // Probe app name/version via GET_VERSION (B0010000) if possible\n try {\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 parser.extract8BitUInt();\n const appName = parser.encodeToString(parser.extractFieldLVEncoded());\n const appVersion = parser.encodeToString(parser.extractFieldLVEncoded());\n this.logger.debug(`App Name: ${appName} and version ${appVersion}`);\n\n this.speculosDevice.deviceModel.productName = `Speculos - ${appName} - ${appVersion}`;\n } catch {\n // ignore if the app doesn't support GET_VERSION\n }\n\n try {\n const connectedDevice: TransportConnectedDevice = {\n sendApdu: (apdu: Uint8Array) =>\n this.sendApdu(params.deviceId, params.onDisconnect, apdu),\n deviceModel: this.speculosDevice.deviceModel,\n transport: this.identifier,\n id: \"SpeculosID\",\n type: \"USB\",\n };\n\n this.connectedDevice = connectedDevice;\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 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 new Uint8Array(0);\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) => 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", "connectedDevice", "apdu", "error", "_params", "deviceId", "onDisconnect", "hex", "resp", "hexApdu", "sw", "payload", "hexString", "b", "quietSpeculosTransportFactory", "config"]
|
|
7
|
-
}
|
|
@@ -1,3 +0,0 @@
|
|
|
1
|
-
import c from"axios";import l from"http";import u from"https";function p(r,t,e){return c.create({baseURL:r.replace(/\/+$/,""),timeout:t,proxy:!1,headers:{"X-Ledger-Client-Version":e,Connection:"close"},httpAgent:new l.Agent({keepAlive:!1,maxSockets:1/0}),httpsAgent:new u.Agent({keepAlive:!1,maxSockets:1/0}),transitional:{clarifyTimeoutError:!0}})}function d(r,t){return c.create({baseURL:r.replace(/\/+$/,""),timeout:0,proxy:!1,headers:{"X-Ledger-Client-Version":t,Connection:"keep-alive"},httpAgent:new l.Agent({keepAlive:!0,maxSockets:1,maxFreeSockets:1}),httpsAgent:new u.Agent({keepAlive:!0,maxSockets:1,maxFreeSockets:1}),transitional:{clarifyTimeoutError:!0}})}class x{constructor(t,e=1e4,n="ldmk-transport-speculos"){this.baseUrl=t;this.timeoutMs=e;this.apduClient=p(t,e,n),this.buttonClient=p(t,Math.min(e,2e3),n),this.sseClient=d(t,n)}apduClient;buttonClient;sseClient;async postAdpu(t){const{data:e}=await this.apduClient.post("/apdu",{data:t},{timeout:this.timeoutMs});return e.data}async pressButton(t){const n={Ll:"left",Rr:"right",LRlr:"both",left:"left",right:"right",both:"both"}[t]??"right";await this.buttonClient.post(`/button/${n}`,{action:"press-and-release"},{timeout:Math.min(this.timeoutMs,1500)})}async openEventStream(t,e){const s=(await this.sseClient.get("/events",{params:{stream:"true"},responseType:"stream",timeout:0,headers:{Accept:"text/event-stream","Cache-Control":"no-cache",Connection:"keep-alive","Accept-Encoding":"identity"}})).data;s.on("data",m=>{m.toString("utf8").split(`
|
|
2
|
-
`).forEach(a=>{if(a.startsWith("data: ")){const i=a.slice(6);try{t(JSON.parse(i))}catch{t({data:i})}}})});const o=()=>e?.();return s.on("close",o),s.on("end",o),s.on("error",o),s}get base(){return this.baseUrl}}export{x as HttpLegacySpeculosDatasource};
|
|
3
|
-
//# sourceMappingURL=HttpLegacySpeculosDatasource.js.map
|
|
@@ -1,7 +0,0 @@
|
|
|
1
|
-
{
|
|
2
|
-
"version": 3,
|
|
3
|
-
"sources": ["../../../../../src/internal/datasource/HttpLegacySpeculosDatasource.ts"],
|
|
4
|
-
"sourcesContent": ["import axios, { type AxiosInstance } from \"axios\";\nimport http from \"http\";\nimport https from \"https\";\n\ntype SpeculosApduDTO = { data: string };\n\nfunction makeNoKeepAliveAxios(\n baseUrl: string,\n timeoutMs: number,\n clientHeader: string,\n): AxiosInstance {\n return axios.create({\n baseURL: baseUrl.replace(/\\/+$/, \"\"),\n timeout: timeoutMs,\n proxy: false,\n headers: {\n \"X-Ledger-Client-Version\": clientHeader,\n Connection: \"close\",\n },\n httpAgent: new http.Agent({ keepAlive: false, maxSockets: Infinity }),\n httpsAgent: new https.Agent({ keepAlive: false, maxSockets: Infinity }),\n transitional: { clarifyTimeoutError: true },\n });\n}\n\nfunction makeKeepAliveAxiosForSSE(\n baseUrl: string,\n clientHeader: string,\n): AxiosInstance {\n return axios.create({\n baseURL: baseUrl.replace(/\\/+$/, \"\"),\n timeout: 0, // long-lived\n proxy: false,\n headers: {\n \"X-Ledger-Client-Version\": clientHeader,\n\n Connection: \"keep-alive\",\n },\n httpAgent: new http.Agent({\n keepAlive: true,\n maxSockets: 1,\n maxFreeSockets: 1,\n }),\n httpsAgent: new https.Agent({\n keepAlive: true,\n maxSockets: 1,\n maxFreeSockets: 1,\n }),\n transitional: { clarifyTimeoutError: true },\n });\n}\n\nexport class HttpLegacySpeculosDatasource {\n private readonly apduClient: AxiosInstance;\n private readonly buttonClient: AxiosInstance;\n private readonly sseClient: AxiosInstance;\n\n constructor(\n private readonly baseUrl: string,\n private readonly timeoutMs: number = 10000,\n clientHeader: string = \"ldmk-transport-speculos\",\n ) {\n this.apduClient = makeNoKeepAliveAxios(baseUrl, timeoutMs, clientHeader);\n this.buttonClient = makeNoKeepAliveAxios(\n baseUrl,\n Math.min(timeoutMs, 2000),\n clientHeader,\n );\n\n this.sseClient = makeKeepAliveAxiosForSSE(baseUrl, clientHeader);\n }\n\n async postAdpu(apdu: string): Promise<string> {\n const { data } = await this.apduClient.post<SpeculosApduDTO>(\n \"/apdu\",\n { data: apdu },\n { timeout: this.timeoutMs },\n );\n return data.data;\n }\n\n async pressButton(\n but: \"Ll\" | \"Rr\" | \"LRlr\" | \"left\" | \"right\" | \"both\",\n ): Promise<void> {\n const map: Record<string, \"left\" | \"right\" | \"both\"> = {\n Ll: \"left\",\n Rr: \"right\",\n LRlr: \"both\",\n left: \"left\",\n right: \"right\",\n both: \"both\",\n };\n const input = map[but] ?? \"right\";\n await this.buttonClient.post(\n `/button/${input}`,\n { action: \"press-and-release\" },\n { timeout: Math.min(this.timeoutMs, 1500) },\n );\n }\n\n async openEventStream(\n onEvent: (json: Record<string, unknown>) => void,\n onClose?: () => void,\n ): Promise<NodeJS.ReadableStream> {\n const response = await this.sseClient.get(\"/events\", {\n params: { stream: \"true\" },\n responseType: \"stream\",\n timeout: 0, // keep SSE alive\n headers: {\n Accept: \"text/event-stream\",\n \"Cache-Control\": \"no-cache\",\n Connection: \"keep-alive\",\n \"Accept-Encoding\": \"identity\",\n },\n });\n\n const stream = response.data as NodeJS.ReadableStream;\n\n stream.on(\"data\", (chunk: Buffer) => {\n const txt = chunk.toString(\"utf8\");\n txt.split(\"\\n\").forEach((line) => {\n if (line.startsWith(\"data: \")) {\n const payload = line.slice(6);\n try {\n onEvent(JSON.parse(payload));\n } catch {\n onEvent({ data: payload });\n }\n }\n });\n });\n\n const end = () => onClose?.();\n stream.on(\"close\", end);\n stream.on(\"end\", end);\n stream.on(\"error\", end);\n\n return stream;\n }\n\n get base(): string {\n return this.baseUrl;\n }\n}\n"],
|
|
5
|
-
"mappings": "AAAA,OAAOA,MAAmC,QAC1C,OAAOC,MAAU,OACjB,OAAOC,MAAW,QAIlB,SAASC,EACPC,EACAC,EACAC,EACe,CACf,OAAON,EAAM,OAAO,CAClB,QAASI,EAAQ,QAAQ,OAAQ,EAAE,EACnC,QAASC,EACT,MAAO,GACP,QAAS,CACP,0BAA2BC,EAC3B,WAAY,OACd,EACA,UAAW,IAAIL,EAAK,MAAM,CAAE,UAAW,GAAO,WAAY,GAAS,CAAC,EACpE,WAAY,IAAIC,EAAM,MAAM,CAAE,UAAW,GAAO,WAAY,GAAS,CAAC,EACtE,aAAc,CAAE,oBAAqB,EAAK,CAC5C,CAAC,CACH,CAEA,SAASK,EACPH,EACAE,EACe,CACf,OAAON,EAAM,OAAO,CAClB,QAASI,EAAQ,QAAQ,OAAQ,EAAE,EACnC,QAAS,EACT,MAAO,GACP,QAAS,CACP,0BAA2BE,EAE3B,WAAY,YACd,EACA,UAAW,IAAIL,EAAK,MAAM,CACxB,UAAW,GACX,WAAY,EACZ,eAAgB,CAClB,CAAC,EACD,WAAY,IAAIC,EAAM,MAAM,CAC1B,UAAW,GACX,WAAY,EACZ,eAAgB,CAClB,CAAC,EACD,aAAc,CAAE,oBAAqB,EAAK,CAC5C,CAAC,CACH,CAEO,MAAMM,CAA6B,CAKxC,YACmBJ,EACAC,EAAoB,IACrCC,EAAuB,0BACvB,CAHiB,aAAAF,EACA,eAAAC,EAGjB,KAAK,WAAaF,EAAqBC,EAASC,EAAWC,CAAY,EACvE,KAAK,aAAeH,EAClBC,EACA,KAAK,IAAIC,EAAW,GAAI,EACxBC,CACF,EAEA,KAAK,UAAYC,EAAyBH,EAASE,CAAY,CACjE,CAjBiB,WACA,aACA,UAiBjB,MAAM,SAASG,EAA+B,CAC5C,KAAM,CAAE,KAAAC,CAAK,EAAI,MAAM,KAAK,WAAW,KACrC,QACA,CAAE,KAAMD,CAAK,EACb,CAAE,QAAS,KAAK,SAAU,CAC5B,EACA,OAAOC,EAAK,IACd,CAEA,MAAM,YACJC,EACe,CASf,MAAMC,EARiD,CACrD,GAAI,OACJ,GAAI,QACJ,KAAM,OACN,KAAM,OACN,MAAO,QACP,KAAM,MACR,EACkBD,CAAG,GAAK,QAC1B,MAAM,KAAK,aAAa,KACtB,WAAWC,CAAK,GAChB,CAAE,OAAQ,mBAAoB,EAC9B,CAAE,QAAS,KAAK,IAAI,KAAK,UAAW,IAAI,CAAE,CAC5C,CACF,CAEA,MAAM,gBACJC,EACAC,EACgC,CAahC,MAAMC,GAZW,MAAM,KAAK,UAAU,IAAI,UAAW,CACnD,OAAQ,CAAE,OAAQ,MAAO,EACzB,aAAc,SACd,QAAS,EACT,QAAS,CACP,OAAQ,oBACR,gBAAiB,WACjB,WAAY,aACZ,kBAAmB,UACrB,CACF,CAAC,GAEuB,KAExBA,EAAO,GAAG,OAASC,GAAkB,CACvBA,EAAM,SAAS,MAAM,EAC7B,MAAM;AAAA,CAAI,EAAE,QAASC,GAAS,CAChC,GAAIA,EAAK,WAAW,QAAQ,EAAG,CAC7B,MAAMC,EAAUD,EAAK,MAAM,CAAC,EAC5B,GAAI,CACFJ,EAAQ,KAAK,MAAMK,CAAO,CAAC,CAC7B,MAAQ,CACNL,EAAQ,CAAE,KAAMK,CAAQ,CAAC,CAC3B,CACF,CACF,CAAC,CACH,CAAC,EAED,MAAMC,EAAM,IAAML,IAAU,EAC5B,OAAAC,EAAO,GAAG,QAASI,CAAG,EACtBJ,EAAO,GAAG,MAAOI,CAAG,EACpBJ,EAAO,GAAG,QAASI,CAAG,EAEfJ,CACT,CAEA,IAAI,MAAe,CACjB,OAAO,KAAK,OACd,CACF",
|
|
6
|
-
"names": ["axios", "http", "https", "makeNoKeepAliveAxios", "baseUrl", "timeoutMs", "clientHeader", "makeKeepAliveAxiosForSSE", "HttpLegacySpeculosDatasource", "apdu", "data", "but", "input", "onEvent", "onClose", "stream", "chunk", "line", "payload", "end"]
|
|
7
|
-
}
|
|
@@ -1 +0,0 @@
|
|
|
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;IAEhE,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;IAoCrD,UAAU,CAAC,OAAO,EAAE;QACxB,eAAe,EAAE,wBAAwB,CAAC;KAC3C,GAAG,OAAO,CAAC,MAAM,CAAC,QAAQ,EAAE,IAAI,CAAC,CAAC;IAM7B,QAAQ,CACZ,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,KACjB,gBAGoE,CAAC"}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"HttpLegacySpeculosDatasource.d.ts","sourceRoot":"","sources":["../../../../../src/internal/datasource/HttpLegacySpeculosDatasource.ts"],"names":[],"mappings":"AAoDA,qBAAa,4BAA4B;IAMrC,OAAO,CAAC,QAAQ,CAAC,OAAO;IACxB,OAAO,CAAC,QAAQ,CAAC,SAAS;IAN5B,OAAO,CAAC,QAAQ,CAAC,UAAU,CAAgB;IAC3C,OAAO,CAAC,QAAQ,CAAC,YAAY,CAAgB;IAC7C,OAAO,CAAC,QAAQ,CAAC,SAAS,CAAgB;gBAGvB,OAAO,EAAE,MAAM,EACf,SAAS,GAAE,MAAc,EAC1C,YAAY,GAAE,MAAkC;IAY5C,QAAQ,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC;IASvC,WAAW,CACf,GAAG,EAAE,IAAI,GAAG,IAAI,GAAG,MAAM,GAAG,MAAM,GAAG,OAAO,GAAG,MAAM,GACpD,OAAO,CAAC,IAAI,CAAC;IAiBV,eAAe,CACnB,OAAO,EAAE,CAAC,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,KAAK,IAAI,EAChD,OAAO,CAAC,EAAE,MAAM,IAAI,GACnB,OAAO,CAAC,MAAM,CAAC,cAAc,CAAC;IAqCjC,IAAI,IAAI,IAAI,MAAM,CAEjB;CACF"}
|