UNPKG

3.86 kBJavaScriptView Raw
1/* @flow */
2
3'use strict';
4
5import semvercmp from 'semver-compare';
6import {request as http, setFetch as rSetFetch} from './http';
7import type {AcquireInput, TrezorDeviceInfoWithSession, MessageFromTrezor} from '../transport';
8import * as check from '../highlevel-checks';
9
10import {debugInOut} from '../debug-decorator';
11
12const DEFAULT_URL = `https://localback.net:21324`;
13const DEFAULT_VERSION_URL = `https://wallet.mytrezor.com/data/bridge/latest.txt`;
14
15type IncompleteRequestOptions = {
16 body?: ?(Array<any> | Object | string);
17 url: string;
18};
19
20export default class BridgeTransport {
21 name: string = `BridgeTransport`;
22 version: string = ``;
23 configured: boolean = false;
24 isOutdated: boolean;
25
26 url: string;
27 newestVersionUrl: string;
28 debug: boolean = false;
29
30 constructor(url?: ?string, newestVersionUrl?: ?string) {
31 this.url = url == null ? DEFAULT_URL : url;
32 this.newestVersionUrl = newestVersionUrl == null ? DEFAULT_VERSION_URL : newestVersionUrl;
33 }
34
35 async _post(options: IncompleteRequestOptions): Promise<mixed> {
36 return await http({ ...options, method: `POST`, url: this.url + options.url });
37 }
38
39 async _get(options: IncompleteRequestOptions): Promise<mixed> {
40 return await http({ ...options, method: `GET`, url: this.url + options.url });
41 }
42
43 @debugInOut
44 async init(debug: ?boolean): Promise<void> {
45 this.debug = !!debug;
46 await this._silentInit();
47 }
48
49 async _silentInit(): Promise<void> {
50 const infoS: mixed = await http({
51 url: this.url,
52 method: `GET`,
53 });
54 const info = check.info(infoS);
55 this.version = info.version;
56 this.configured = info.configured;
57 const newVersion = check.version(await http({
58 url: this.newestVersionUrl,
59 method: `GET`,
60 }));
61 this.isOutdated = semvercmp(this.version, newVersion) < 0;
62 }
63
64 @debugInOut
65 async configure(config: string): Promise<void> {
66 await this._post({
67 url: `/configure`,
68 body: config,
69 });
70 // we should reload configured after configure
71 await this._silentInit();
72 }
73
74 @debugInOut
75 async listen(old: ?Array<TrezorDeviceInfoWithSession>): Promise<Array<TrezorDeviceInfoWithSession>> {
76 const devicesS: mixed = await (
77 old == null
78 ? this._get({url: `/listen`})
79 : this._post({
80 url: `/listen`,
81 body: old.map(device => {
82 return {
83 ...device,
84 // hack for old trezord
85 product: 1,
86 vendor: 21324,
87 };
88 }),
89 })
90 );
91 const devices = check.devices(devicesS);
92 return devices;
93 }
94
95 @debugInOut
96 async enumerate(): Promise<Array<TrezorDeviceInfoWithSession>> {
97 const devicesS: mixed = await this._get({url: `/enumerate`});
98 const devices = check.devices(devicesS);
99 return devices;
100 }
101
102 async _acquireMixed(input: AcquireInput): Promise<mixed> {
103 const checkPrevious = input.checkPrevious && (semvercmp(this.version, `1.1.3`) >= 0);
104 if (checkPrevious) {
105 const previousStr = input.previous == null ? `null` : input.previous;
106 const url = `/acquire/` + input.path + `/` + previousStr;
107 return this._post({url: url});
108 } else {
109 return this._post({url: `/acquire/` + input.path});
110 }
111 }
112
113 @debugInOut
114 async acquire(input: AcquireInput): Promise<string> {
115 const acquireS = await this._acquireMixed(input);
116 return check.acquire(acquireS);
117 }
118
119 @debugInOut
120 async release(session: string): Promise<void> {
121 await this._post({url: `/release/` + session});
122 }
123
124 @debugInOut
125 async call(session: string, name: string, data: Object): Promise<MessageFromTrezor> {
126 const res = await this._post({
127 url: `/call/` + session,
128 body: {
129 type: name,
130 message: data,
131 },
132 });
133 return check.call(res);
134 }
135
136 static setFetch(fetch: any) {
137 rSetFetch(fetch);
138 }
139}