@bitgo/sdk-api 1.0.1-dev.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/package.json +66 -0
- package/dist/src/api.d.ts +49 -0
- package/dist/src/api.d.ts.map +1 -0
- package/dist/src/api.js +208 -0
- package/dist/src/bitgoAPI.d.ts +111 -0
- package/dist/src/bitgoAPI.d.ts.map +1 -0
- package/dist/src/bitgoAPI.js +435 -0
- package/dist/src/index.d.ts +5 -0
- package/dist/src/index.d.ts.map +1 -0
- package/dist/src/index.js +17 -0
- package/dist/src/types.d.ts +95 -0
- package/dist/src/types.d.ts.map +1 -0
- package/dist/src/types.js +17 -0
- package/dist/src/util.d.ts +12 -0
- package/dist/src/util.d.ts.map +1 -0
- package/dist/src/util.js +30 -0
- package/dist/tsconfig.tsbuildinfo +4296 -0
- package/dist/web/index.html +1 -0
- package/dist/web/main.js +2 -0
- package/dist/web/main.js.LICENSE.txt +32 -0
- package/package.json +66 -0
|
@@ -0,0 +1,66 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@bitgo/sdk-api",
|
|
3
|
+
"version": "1.0.1-dev.0",
|
|
4
|
+
"description": "REST wrapper for BitGoJS",
|
|
5
|
+
"main": "./dist/src/index.js",
|
|
6
|
+
"web": "./dist/web/main.js",
|
|
7
|
+
"types": "./dist/src/index.d.ts",
|
|
8
|
+
"scripts": {
|
|
9
|
+
"build": "yarn tsc --build --incremental --verbose .",
|
|
10
|
+
"fmt": "prettier --write .",
|
|
11
|
+
"check-fmt": "prettier --check .",
|
|
12
|
+
"clean": "rm -r ./dist",
|
|
13
|
+
"precommit": "lint-staged",
|
|
14
|
+
"prepare": "npm run build",
|
|
15
|
+
"build-web": "webpack",
|
|
16
|
+
"build-web-prod": "webpack --mode=production --node-env=production",
|
|
17
|
+
"prepublishOnly": "npm run build-web-prod"
|
|
18
|
+
},
|
|
19
|
+
"author": "BitGo Inc.",
|
|
20
|
+
"license": "MIT",
|
|
21
|
+
"repository": {
|
|
22
|
+
"type": "git",
|
|
23
|
+
"url": "https://github.com/BitGo/BitGoJS.git",
|
|
24
|
+
"directory": "modules/statics"
|
|
25
|
+
},
|
|
26
|
+
"husky": {
|
|
27
|
+
"hooks": {
|
|
28
|
+
"pre-commit": "lint-staged"
|
|
29
|
+
}
|
|
30
|
+
},
|
|
31
|
+
"lint-staged": {
|
|
32
|
+
"**/*.ts": [
|
|
33
|
+
"prettier --write",
|
|
34
|
+
"git add"
|
|
35
|
+
]
|
|
36
|
+
},
|
|
37
|
+
"publishConfig": {
|
|
38
|
+
"access": "public"
|
|
39
|
+
},
|
|
40
|
+
"nyc": {
|
|
41
|
+
"extension": [
|
|
42
|
+
".ts"
|
|
43
|
+
]
|
|
44
|
+
},
|
|
45
|
+
"dependencies": {
|
|
46
|
+
"@bitgo/sdk-core": "^1.0.1-dev.0",
|
|
47
|
+
"@bitgo/sjcl": "^1.0.1-dev.0",
|
|
48
|
+
"@bitgo/utxo-lib": "^2.2.2-dev.0",
|
|
49
|
+
"@types/superagent": "4.1.15",
|
|
50
|
+
"debug": "3.1.0",
|
|
51
|
+
"sanitize-html": "^1.27.5",
|
|
52
|
+
"superagent": "3.8.3",
|
|
53
|
+
"superagent-proxy": "3.0.0"
|
|
54
|
+
},
|
|
55
|
+
"devDependencies": {
|
|
56
|
+
"@babel/core": "^7.17.8",
|
|
57
|
+
"@babel/preset-env": "^7.16.11",
|
|
58
|
+
"@webpack-cli/generators": "^2.4.2",
|
|
59
|
+
"babel-loader": "^8.2.4",
|
|
60
|
+
"html-webpack-plugin": "^5.5.0",
|
|
61
|
+
"webpack": "^5.70.0",
|
|
62
|
+
"webpack-cli": "^4.9.2",
|
|
63
|
+
"webpack-dev-server": "^4.7.4"
|
|
64
|
+
},
|
|
65
|
+
"gitHead": "e9d78e8064169cd03f12c111af18603de5c29e1b"
|
|
66
|
+
}
|
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
import * as superagent from 'superagent';
|
|
2
|
+
import { VerifyResponseOptions } from './types';
|
|
3
|
+
import { BitGoAPI } from './bitgoAPI';
|
|
4
|
+
export interface BitGoRequest<ResultType = any> extends superagent.SuperAgentRequest {
|
|
5
|
+
result: (optionalField?: string) => Promise<ResultType>;
|
|
6
|
+
}
|
|
7
|
+
/**
|
|
8
|
+
* Add the bitgo-specific result() function on a superagent request.
|
|
9
|
+
*
|
|
10
|
+
* If the server response is successful, the `result()` function will return either the entire response body,
|
|
11
|
+
* or the field from the response body specified by the `optionalField` parameter if it is provided.
|
|
12
|
+
*
|
|
13
|
+
* If the server response with an error, `result()` will handle HTTP errors appropriately by
|
|
14
|
+
* rethrowing them as an `ApiResponseError` if possible, and otherwise rethrowing the underlying response error.
|
|
15
|
+
*
|
|
16
|
+
* @param req
|
|
17
|
+
*/
|
|
18
|
+
export declare function toBitgoRequest<ResponseResultType = any>(req: superagent.SuperAgentRequest): BitGoRequest<ResponseResultType>;
|
|
19
|
+
/**
|
|
20
|
+
* Return a function which extracts the specified response body property from the response if successful,
|
|
21
|
+
* otherwise throw an `ApiErrorResponse` parsed from the response body.
|
|
22
|
+
* @param optionalField
|
|
23
|
+
*/
|
|
24
|
+
export declare function handleResponseResult<ResponseResultType>(optionalField?: string): (res: superagent.Response) => ResponseResultType;
|
|
25
|
+
/**
|
|
26
|
+
* Handle an error or an error containing an HTTP response and use it to throw a well-formed error object.
|
|
27
|
+
*
|
|
28
|
+
* @param e
|
|
29
|
+
*/
|
|
30
|
+
export declare function handleResponseError(e: Error & {
|
|
31
|
+
response?: superagent.Response;
|
|
32
|
+
}): never;
|
|
33
|
+
/**
|
|
34
|
+
* Serialize request data based on the request content type
|
|
35
|
+
* Note: Not sure this is still needed or even useful. Consider removing.
|
|
36
|
+
* @param req
|
|
37
|
+
*/
|
|
38
|
+
export declare function serializeRequestData(req: superagent.Request): string | undefined;
|
|
39
|
+
/**
|
|
40
|
+
* Set the superagent query string correctly for browsers or node.
|
|
41
|
+
* @param req
|
|
42
|
+
*/
|
|
43
|
+
export declare function setRequestQueryString(req: superagent.SuperAgentRequest): void;
|
|
44
|
+
/**
|
|
45
|
+
* Verify that the response received from the server is signed correctly.
|
|
46
|
+
* Right now, it is very permissive with the timestamp variance.
|
|
47
|
+
*/
|
|
48
|
+
export declare function verifyResponse(bitgo: BitGoAPI, token: string | undefined, method: VerifyResponseOptions['method'], req: superagent.SuperAgentRequest, response: superagent.Response): superagent.Response;
|
|
49
|
+
//# sourceMappingURL=api.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"api.d.ts","sourceRoot":"","sources":["../../src/api.ts"],"names":[],"mappings":"AAOA,OAAO,KAAK,UAAU,MAAM,YAAY,CAAC;AAIzC,OAAO,EAAoB,qBAAqB,EAAE,MAAM,SAAS,CAAC;AAClE,OAAO,EAAE,QAAQ,EAAE,MAAM,YAAY,CAAC;AAItC,MAAM,WAAW,YAAY,CAAC,UAAU,GAAG,GAAG,CAAE,SAAQ,UAAU,CAAC,iBAAiB;IAClF,MAAM,EAAE,CAAC,aAAa,CAAC,EAAE,MAAM,KAAK,OAAO,CAAC,UAAU,CAAC,CAAC;CACzD;AAED;;;;;;;;;;GAUG;AACH,wBAAgB,cAAc,CAAC,kBAAkB,GAAG,GAAG,EACrD,GAAG,EAAE,UAAU,CAAC,iBAAiB,GAChC,YAAY,CAAC,kBAAkB,CAAC,CASlC;AAED;;;;GAIG;AACH,wBAAgB,oBAAoB,CAAC,kBAAkB,EACrD,aAAa,CAAC,EAAE,MAAM,GACrB,CAAC,GAAG,EAAE,UAAU,CAAC,QAAQ,KAAK,kBAAkB,CAOlD;AAkBD;;;;GAIG;AACH,wBAAgB,mBAAmB,CAAC,CAAC,EAAE,KAAK,GAAG;IAAE,QAAQ,CAAC,EAAE,UAAU,CAAC,QAAQ,CAAA;CAAE,GAAG,KAAK,CAKxF;AAgCD;;;;GAIG;AACH,wBAAgB,oBAAoB,CAAC,GAAG,EAAE,UAAU,CAAC,OAAO,GAAG,MAAM,GAAG,SAAS,CAkBhF;AAED;;;GAGG;AACH,wBAAgB,qBAAqB,CAAC,GAAG,EAAE,UAAU,CAAC,iBAAiB,GAAG,IAAI,CAwB7E;AAED;;;GAGG;AACH,wBAAgB,cAAc,CAC5B,KAAK,EAAE,QAAQ,EACf,KAAK,EAAE,MAAM,GAAG,SAAS,EACzB,MAAM,EAAE,qBAAqB,CAAC,QAAQ,CAAC,EACvC,GAAG,EAAE,UAAU,CAAC,iBAAiB,EACjC,QAAQ,EAAE,UAAU,CAAC,QAAQ,GAC5B,UAAU,CAAC,QAAQ,CA+CrB"}
|
package/dist/src/api.js
ADDED
|
@@ -0,0 +1,208 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.verifyResponse = exports.setRequestQueryString = exports.serializeRequestData = exports.handleResponseError = exports.handleResponseResult = exports.toBitgoRequest = void 0;
|
|
4
|
+
/**
|
|
5
|
+
* @prettier
|
|
6
|
+
*/
|
|
7
|
+
const debug_1 = require("debug");
|
|
8
|
+
const eol = require("eol");
|
|
9
|
+
const _ = require("lodash");
|
|
10
|
+
const sanitizeHtml = require("sanitize-html");
|
|
11
|
+
const superagent = require("superagent");
|
|
12
|
+
const urlLib = require("url");
|
|
13
|
+
const querystring = require("querystring");
|
|
14
|
+
const types_1 = require("./types");
|
|
15
|
+
const debug = debug_1.default('bitgo:api');
|
|
16
|
+
/**
|
|
17
|
+
* Add the bitgo-specific result() function on a superagent request.
|
|
18
|
+
*
|
|
19
|
+
* If the server response is successful, the `result()` function will return either the entire response body,
|
|
20
|
+
* or the field from the response body specified by the `optionalField` parameter if it is provided.
|
|
21
|
+
*
|
|
22
|
+
* If the server response with an error, `result()` will handle HTTP errors appropriately by
|
|
23
|
+
* rethrowing them as an `ApiResponseError` if possible, and otherwise rethrowing the underlying response error.
|
|
24
|
+
*
|
|
25
|
+
* @param req
|
|
26
|
+
*/
|
|
27
|
+
function toBitgoRequest(req) {
|
|
28
|
+
return Object.assign(req, {
|
|
29
|
+
result(optionalField) {
|
|
30
|
+
return req.then((response) => handleResponseResult(optionalField)(response), (error) => handleResponseError(error));
|
|
31
|
+
},
|
|
32
|
+
});
|
|
33
|
+
}
|
|
34
|
+
exports.toBitgoRequest = toBitgoRequest;
|
|
35
|
+
/**
|
|
36
|
+
* Return a function which extracts the specified response body property from the response if successful,
|
|
37
|
+
* otherwise throw an `ApiErrorResponse` parsed from the response body.
|
|
38
|
+
* @param optionalField
|
|
39
|
+
*/
|
|
40
|
+
function handleResponseResult(optionalField) {
|
|
41
|
+
return function (res) {
|
|
42
|
+
if (_.isNumber(res.status) && res.status >= 200 && res.status < 300) {
|
|
43
|
+
return optionalField ? res.body[optionalField] : res.body;
|
|
44
|
+
}
|
|
45
|
+
throw errFromResponse(res);
|
|
46
|
+
};
|
|
47
|
+
}
|
|
48
|
+
exports.handleResponseResult = handleResponseResult;
|
|
49
|
+
/**
|
|
50
|
+
* Extract relevant information from a successful response (that is, a response with an HTTP status code
|
|
51
|
+
* between 200 and 299), but which resulted in an application specific error and use it to construct and
|
|
52
|
+
* throw an `ApiErrorResponse`.
|
|
53
|
+
*
|
|
54
|
+
* @param res
|
|
55
|
+
*/
|
|
56
|
+
function errFromResponse(res) {
|
|
57
|
+
const message = createResponseErrorString(res);
|
|
58
|
+
const status = res.status;
|
|
59
|
+
const result = res.body;
|
|
60
|
+
const invalidToken = _.has(res.header, 'x-auth-required') && res.header['x-auth-required'] === 'true';
|
|
61
|
+
const needsOtp = res.body.needsOTP !== undefined;
|
|
62
|
+
return new types_1.ApiResponseError(message, status, result, invalidToken, needsOtp);
|
|
63
|
+
}
|
|
64
|
+
/**
|
|
65
|
+
* Handle an error or an error containing an HTTP response and use it to throw a well-formed error object.
|
|
66
|
+
*
|
|
67
|
+
* @param e
|
|
68
|
+
*/
|
|
69
|
+
function handleResponseError(e) {
|
|
70
|
+
if (e.response) {
|
|
71
|
+
throw errFromResponse(e.response);
|
|
72
|
+
}
|
|
73
|
+
throw e;
|
|
74
|
+
}
|
|
75
|
+
exports.handleResponseError = handleResponseError;
|
|
76
|
+
/**
|
|
77
|
+
* There are many ways a request can fail, and may ways information on that failure can be
|
|
78
|
+
* communicated to the client. This function tries to handle those cases and create a sane error string
|
|
79
|
+
* @param res Response from an HTTP request
|
|
80
|
+
*/
|
|
81
|
+
function createResponseErrorString(res) {
|
|
82
|
+
var _a;
|
|
83
|
+
let errString = res.status.toString(); // at the very least we'll have the status code
|
|
84
|
+
if ((_a = res.body) === null || _a === void 0 ? void 0 : _a.error) {
|
|
85
|
+
// this is the case we hope for, where the server gives us a nice error from the JSON body
|
|
86
|
+
errString = res.body.error;
|
|
87
|
+
}
|
|
88
|
+
else if (res.text) {
|
|
89
|
+
// if the response came back as text, we try to parse it as HTML and remove all tags, leaving us
|
|
90
|
+
// just the bare text, which we then trim of excessive newlines and limit to a certain length
|
|
91
|
+
try {
|
|
92
|
+
let sanitizedText = sanitizeHtml(res.text, { allowedTags: [] });
|
|
93
|
+
sanitizedText = sanitizedText.trim();
|
|
94
|
+
sanitizedText = eol.lf(sanitizedText); // use '\n' for all newlines
|
|
95
|
+
sanitizedText = _.replace(sanitizedText, /\n[ |\t]{1,}\n/g, '\n\n'); // remove the spaces/tabs between newlines
|
|
96
|
+
sanitizedText = _.replace(sanitizedText, /[\n]{3,}/g, '\n\n'); // have at most 2 consecutive newlines
|
|
97
|
+
sanitizedText = sanitizedText.substring(0, 5000); // prevent message from getting too large
|
|
98
|
+
errString = errString + '\n' + sanitizedText; // add it to our existing errString (at this point the more info the better!)
|
|
99
|
+
}
|
|
100
|
+
catch (e) {
|
|
101
|
+
// do nothing, the response's HTML was too wacky to be parsed cleanly
|
|
102
|
+
debug('got error with message "%s" while creating response error string from response: %s', e.message, res.text);
|
|
103
|
+
}
|
|
104
|
+
}
|
|
105
|
+
return errString;
|
|
106
|
+
}
|
|
107
|
+
/**
|
|
108
|
+
* Serialize request data based on the request content type
|
|
109
|
+
* Note: Not sure this is still needed or even useful. Consider removing.
|
|
110
|
+
* @param req
|
|
111
|
+
*/
|
|
112
|
+
function serializeRequestData(req) {
|
|
113
|
+
let data = req._data;
|
|
114
|
+
if (typeof data !== 'string') {
|
|
115
|
+
let contentType = req.get('Content-Type');
|
|
116
|
+
// Parse out just the content type from the header (ignore the charset)
|
|
117
|
+
if (contentType) {
|
|
118
|
+
contentType = contentType.split(';')[0];
|
|
119
|
+
}
|
|
120
|
+
let serialize = superagent.serialize[contentType];
|
|
121
|
+
if (!serialize && /[\/+]json\b/.test(contentType)) {
|
|
122
|
+
serialize = superagent.serialize['application/json'];
|
|
123
|
+
}
|
|
124
|
+
if (serialize) {
|
|
125
|
+
data = serialize(data);
|
|
126
|
+
req._data = data;
|
|
127
|
+
return data;
|
|
128
|
+
}
|
|
129
|
+
}
|
|
130
|
+
}
|
|
131
|
+
exports.serializeRequestData = serializeRequestData;
|
|
132
|
+
/**
|
|
133
|
+
* Set the superagent query string correctly for browsers or node.
|
|
134
|
+
* @param req
|
|
135
|
+
*/
|
|
136
|
+
function setRequestQueryString(req) {
|
|
137
|
+
const urlDetails = urlLib.parse(req.url);
|
|
138
|
+
let queryString;
|
|
139
|
+
const query = req._query;
|
|
140
|
+
const qs = req.qs;
|
|
141
|
+
if (query && query.length > 0) {
|
|
142
|
+
// browser version
|
|
143
|
+
queryString = query.join('&');
|
|
144
|
+
req._query = [];
|
|
145
|
+
}
|
|
146
|
+
else if (qs) {
|
|
147
|
+
// node version
|
|
148
|
+
queryString = querystring.stringify(qs);
|
|
149
|
+
req.qs = null;
|
|
150
|
+
}
|
|
151
|
+
if (queryString) {
|
|
152
|
+
if (urlDetails.search) {
|
|
153
|
+
urlDetails.search += '&' + queryString;
|
|
154
|
+
}
|
|
155
|
+
else {
|
|
156
|
+
urlDetails.search = '?' + queryString;
|
|
157
|
+
}
|
|
158
|
+
req.url = urlLib.format(urlDetails);
|
|
159
|
+
}
|
|
160
|
+
}
|
|
161
|
+
exports.setRequestQueryString = setRequestQueryString;
|
|
162
|
+
/**
|
|
163
|
+
* Verify that the response received from the server is signed correctly.
|
|
164
|
+
* Right now, it is very permissive with the timestamp variance.
|
|
165
|
+
*/
|
|
166
|
+
function verifyResponse(bitgo, token, method, req, response) {
|
|
167
|
+
// we can't verify the response if we're not authenticated
|
|
168
|
+
if (!req.isV2Authenticated || !req.authenticationToken) {
|
|
169
|
+
return response;
|
|
170
|
+
}
|
|
171
|
+
const verificationResponse = bitgo.verifyResponse({
|
|
172
|
+
url: req.url,
|
|
173
|
+
hmac: response.header.hmac,
|
|
174
|
+
statusCode: response.status,
|
|
175
|
+
text: response.text,
|
|
176
|
+
timestamp: response.header.timestamp,
|
|
177
|
+
token: req.authenticationToken,
|
|
178
|
+
method,
|
|
179
|
+
});
|
|
180
|
+
if (!verificationResponse.isValid) {
|
|
181
|
+
// calculate the HMAC
|
|
182
|
+
const receivedHmac = response.header.hmac;
|
|
183
|
+
const expectedHmac = verificationResponse.expectedHmac;
|
|
184
|
+
const signatureSubject = verificationResponse.signatureSubject;
|
|
185
|
+
// Log only the first 10 characters of the token to ensure the full token isn't logged.
|
|
186
|
+
const partialBitgoToken = token ? token.substring(0, 10) : '';
|
|
187
|
+
const errorDetails = {
|
|
188
|
+
expectedHmac,
|
|
189
|
+
receivedHmac,
|
|
190
|
+
hmacInput: signatureSubject,
|
|
191
|
+
requestToken: req.authenticationToken,
|
|
192
|
+
bitgoToken: partialBitgoToken,
|
|
193
|
+
};
|
|
194
|
+
debug('Invalid response HMAC: %O', errorDetails);
|
|
195
|
+
throw new types_1.ApiResponseError('invalid response HMAC, possible man-in-the-middle-attack', 511, errorDetails);
|
|
196
|
+
}
|
|
197
|
+
if (bitgo.getAuthVersion() === 3 && !verificationResponse.isInResponseValidityWindow) {
|
|
198
|
+
const errorDetails = {
|
|
199
|
+
timestamp: response.header.timestamp,
|
|
200
|
+
verificationTime: verificationResponse.verificationTime,
|
|
201
|
+
};
|
|
202
|
+
debug('Server response outside response validity time window: %O', errorDetails);
|
|
203
|
+
throw new types_1.ApiResponseError('server response outside response validity time window, possible man-in-the-middle-attack', 511, errorDetails);
|
|
204
|
+
}
|
|
205
|
+
return response;
|
|
206
|
+
}
|
|
207
|
+
exports.verifyResponse = verifyResponse;
|
|
208
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiYXBpLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vc3JjL2FwaS50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiOzs7QUFBQTs7R0FFRztBQUNILGlDQUEwQjtBQUMxQiwyQkFBMkI7QUFDM0IsNEJBQTRCO0FBQzVCLDhDQUE4QztBQUM5Qyx5Q0FBeUM7QUFDekMsOEJBQThCO0FBQzlCLDJDQUEyQztBQUUzQyxtQ0FBa0U7QUFHbEUsTUFBTSxLQUFLLEdBQUcsZUFBSyxDQUFDLFdBQVcsQ0FBQyxDQUFDO0FBTWpDOzs7Ozs7Ozs7O0dBVUc7QUFDSCxTQUFnQixjQUFjLENBQzVCLEdBQWlDO0lBRWpDLE9BQU8sTUFBTSxDQUFDLE1BQU0sQ0FBQyxHQUFHLEVBQUU7UUFDeEIsTUFBTSxDQUFDLGFBQXNCO1lBQzNCLE9BQU8sR0FBRyxDQUFDLElBQUksQ0FDYixDQUFDLFFBQVEsRUFBRSxFQUFFLENBQUMsb0JBQW9CLENBQXFCLGFBQWEsQ0FBQyxDQUFDLFFBQVEsQ0FBQyxFQUMvRSxDQUFDLEtBQUssRUFBRSxFQUFFLENBQUMsbUJBQW1CLENBQUMsS0FBSyxDQUFDLENBQ3RDLENBQUM7UUFDSixDQUFDO0tBQ0YsQ0FBQyxDQUFDO0FBQ0wsQ0FBQztBQVhELHdDQVdDO0FBRUQ7Ozs7R0FJRztBQUNILFNBQWdCLG9CQUFvQixDQUNsQyxhQUFzQjtJQUV0QixPQUFPLFVBQVUsR0FBd0I7UUFDdkMsSUFBSSxDQUFDLENBQUMsUUFBUSxDQUFDLEdBQUcsQ0FBQyxNQUFNLENBQUMsSUFBSSxHQUFHLENBQUMsTUFBTSxJQUFJLEdBQUcsSUFBSSxHQUFHLENBQUMsTUFBTSxHQUFHLEdBQUcsRUFBRTtZQUNuRSxPQUFPLGFBQWEsQ0FBQyxDQUFDLENBQUMsR0FBRyxDQUFDLElBQUksQ0FBQyxhQUFhLENBQUMsQ0FBQyxDQUFDLENBQUMsR0FBRyxDQUFDLElBQUksQ0FBQztTQUMzRDtRQUNELE1BQU0sZUFBZSxDQUFDLEdBQUcsQ0FBQyxDQUFDO0lBQzdCLENBQUMsQ0FBQztBQUNKLENBQUM7QUFURCxvREFTQztBQUVEOzs7Ozs7R0FNRztBQUNILFNBQVMsZUFBZSxDQUFtQixHQUF3QjtJQUNqRSxNQUFNLE9BQU8sR0FBRyx5QkFBeUIsQ0FBQyxHQUFHLENBQUMsQ0FBQztJQUMvQyxNQUFNLE1BQU0sR0FBRyxHQUFHLENBQUMsTUFBTSxDQUFDO0lBQzFCLE1BQU0sTUFBTSxHQUFHLEdBQUcsQ0FBQyxJQUF3QixDQUFDO0lBQzVDLE1BQU0sWUFBWSxHQUFHLENBQUMsQ0FBQyxHQUFHLENBQUMsR0FBRyxDQUFDLE1BQU0sRUFBRSxpQkFBaUIsQ0FBQyxJQUFJLEdBQUcsQ0FBQyxNQUFNLENBQUMsaUJBQWlCLENBQUMsS0FBSyxNQUFNLENBQUM7SUFDdEcsTUFBTSxRQUFRLEdBQUcsR0FBRyxDQUFDLElBQUksQ0FBQyxRQUFRLEtBQUssU0FBUyxDQUFDO0lBQ2pELE9BQU8sSUFBSSx3QkFBZ0IsQ0FBQyxPQUFPLEVBQUUsTUFBTSxFQUFFLE1BQU0sRUFBRSxZQUFZLEVBQUUsUUFBUSxDQUFDLENBQUM7QUFDL0UsQ0FBQztBQUVEOzs7O0dBSUc7QUFDSCxTQUFnQixtQkFBbUIsQ0FBQyxDQUE2QztJQUMvRSxJQUFJLENBQUMsQ0FBQyxRQUFRLEVBQUU7UUFDZCxNQUFNLGVBQWUsQ0FBQyxDQUFDLENBQUMsUUFBUSxDQUFDLENBQUM7S0FDbkM7SUFDRCxNQUFNLENBQUMsQ0FBQztBQUNWLENBQUM7QUFMRCxrREFLQztBQUVEOzs7O0dBSUc7QUFDSCxTQUFTLHlCQUF5QixDQUFDLEdBQXdCOztJQUN6RCxJQUFJLFNBQVMsR0FBRyxHQUFHLENBQUMsTUFBTSxDQUFDLFFBQVEsRUFBRSxDQUFDLENBQUMsK0NBQStDO0lBQ3RGLElBQUksTUFBQSxHQUFHLENBQUMsSUFBSSwwQ0FBRSxLQUFLLEVBQUU7UUFDbkIsMEZBQTBGO1FBQzFGLFNBQVMsR0FBRyxHQUFHLENBQUMsSUFBSSxDQUFDLEtBQUssQ0FBQztLQUM1QjtTQUFNLElBQUksR0FBRyxDQUFDLElBQUksRUFBRTtRQUNuQixnR0FBZ0c7UUFDaEcsNkZBQTZGO1FBQzdGLElBQUk7WUFDRixJQUFJLGFBQWEsR0FBRyxZQUFZLENBQUMsR0FBRyxDQUFDLElBQUksRUFBRSxFQUFFLFdBQVcsRUFBRSxFQUFFLEVBQUUsQ0FBQyxDQUFDO1lBQ2hFLGFBQWEsR0FBRyxhQUFhLENBQUMsSUFBSSxFQUFFLENBQUM7WUFDckMsYUFBYSxHQUFHLEdBQUcsQ0FBQyxFQUFFLENBQUMsYUFBYSxDQUFDLENBQUMsQ0FBQyw0QkFBNEI7WUFDbkUsYUFBYSxHQUFHLENBQUMsQ0FBQyxPQUFPLENBQUMsYUFBYSxFQUFFLGlCQUFpQixFQUFFLE1BQU0sQ0FBQyxDQUFDLENBQUMsMENBQTBDO1lBQy9HLGFBQWEsR0FBRyxDQUFDLENBQUMsT0FBTyxDQUFDLGFBQWEsRUFBRSxXQUFXLEVBQUUsTUFBTSxDQUFDLENBQUMsQ0FBQyxzQ0FBc0M7WUFDckcsYUFBYSxHQUFHLGFBQWEsQ0FBQyxTQUFTLENBQUMsQ0FBQyxFQUFFLElBQUksQ0FBQyxDQUFDLENBQUMseUNBQXlDO1lBQzNGLFNBQVMsR0FBRyxTQUFTLEdBQUcsSUFBSSxHQUFHLGFBQWEsQ0FBQyxDQUFDLDZFQUE2RTtTQUM1SDtRQUFDLE9BQU8sQ0FBQyxFQUFFO1lBQ1YscUVBQXFFO1lBQ3JFLEtBQUssQ0FBQyxvRkFBb0YsRUFBRSxDQUFDLENBQUMsT0FBTyxFQUFFLEdBQUcsQ0FBQyxJQUFJLENBQUMsQ0FBQztTQUNsSDtLQUNGO0lBRUQsT0FBTyxTQUFTLENBQUM7QUFDbkIsQ0FBQztBQUVEOzs7O0dBSUc7QUFDSCxTQUFnQixvQkFBb0IsQ0FBQyxHQUF1QjtJQUMxRCxJQUFJLElBQUksR0FBc0MsR0FBVyxDQUFDLEtBQUssQ0FBQztJQUNoRSxJQUFJLE9BQU8sSUFBSSxLQUFLLFFBQVEsRUFBRTtRQUM1QixJQUFJLFdBQVcsR0FBRyxHQUFHLENBQUMsR0FBRyxDQUFDLGNBQWMsQ0FBQyxDQUFDO1FBQzFDLHVFQUF1RTtRQUN2RSxJQUFJLFdBQVcsRUFBRTtZQUNmLFdBQVcsR0FBRyxXQUFXLENBQUMsS0FBSyxDQUFDLEdBQUcsQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDO1NBQ3pDO1FBQ0QsSUFBSSxTQUFTLEdBQUcsVUFBVSxDQUFDLFNBQVMsQ0FBQyxXQUFXLENBQUMsQ0FBQztRQUNsRCxJQUFJLENBQUMsU0FBUyxJQUFJLGFBQWEsQ0FBQyxJQUFJLENBQUMsV0FBVyxDQUFDLEVBQUU7WUFDakQsU0FBUyxHQUFHLFVBQVUsQ0FBQyxTQUFTLENBQUMsa0JBQWtCLENBQUMsQ0FBQztTQUN0RDtRQUNELElBQUksU0FBUyxFQUFFO1lBQ2IsSUFBSSxHQUFHLFNBQVMsQ0FBQyxJQUFJLENBQUMsQ0FBQztZQUN0QixHQUFXLENBQUMsS0FBSyxHQUFHLElBQUksQ0FBQztZQUMxQixPQUFPLElBQUksQ0FBQztTQUNiO0tBQ0Y7QUFDSCxDQUFDO0FBbEJELG9EQWtCQztBQUVEOzs7R0FHRztBQUNILFNBQWdCLHFCQUFxQixDQUFDLEdBQWlDO0lBQ3JFLE1BQU0sVUFBVSxHQUFHLE1BQU0sQ0FBQyxLQUFLLENBQUMsR0FBRyxDQUFDLEdBQUcsQ0FBQyxDQUFDO0lBRXpDLElBQUksV0FBK0IsQ0FBQztJQUNwQyxNQUFNLEtBQUssR0FBYyxHQUFXLENBQUMsTUFBTSxDQUFDO0lBQzVDLE1BQU0sRUFBRSxHQUErQixHQUFXLENBQUMsRUFBRSxDQUFDO0lBQ3RELElBQUksS0FBSyxJQUFJLEtBQUssQ0FBQyxNQUFNLEdBQUcsQ0FBQyxFQUFFO1FBQzdCLGtCQUFrQjtRQUNsQixXQUFXLEdBQUcsS0FBSyxDQUFDLElBQUksQ0FBQyxHQUFHLENBQUMsQ0FBQztRQUM3QixHQUFXLENBQUMsTUFBTSxHQUFHLEVBQUUsQ0FBQztLQUMxQjtTQUFNLElBQUksRUFBRSxFQUFFO1FBQ2IsZUFBZTtRQUNmLFdBQVcsR0FBRyxXQUFXLENBQUMsU0FBUyxDQUFDLEVBQUUsQ0FBQyxDQUFDO1FBQ3ZDLEdBQVcsQ0FBQyxFQUFFLEdBQUcsSUFBSSxDQUFDO0tBQ3hCO0lBRUQsSUFBSSxXQUFXLEVBQUU7UUFDZixJQUFJLFVBQVUsQ0FBQyxNQUFNLEVBQUU7WUFDckIsVUFBVSxDQUFDLE1BQU0sSUFBSSxHQUFHLEdBQUcsV0FBVyxDQUFDO1NBQ3hDO2FBQU07WUFDTCxVQUFVLENBQUMsTUFBTSxHQUFHLEdBQUcsR0FBRyxXQUFXLENBQUM7U0FDdkM7UUFDRCxHQUFHLENBQUMsR0FBRyxHQUFHLE1BQU0sQ0FBQyxNQUFNLENBQUMsVUFBVSxDQUFDLENBQUM7S0FDckM7QUFDSCxDQUFDO0FBeEJELHNEQXdCQztBQUVEOzs7R0FHRztBQUNILFNBQWdCLGNBQWMsQ0FDNUIsS0FBZSxFQUNmLEtBQXlCLEVBQ3pCLE1BQXVDLEVBQ3ZDLEdBQWlDLEVBQ2pDLFFBQTZCO0lBRTdCLDBEQUEwRDtJQUMxRCxJQUFJLENBQUMsR0FBRyxDQUFDLGlCQUFpQixJQUFJLENBQUMsR0FBRyxDQUFDLG1CQUFtQixFQUFFO1FBQ3RELE9BQU8sUUFBUSxDQUFDO0tBQ2pCO0lBRUQsTUFBTSxvQkFBb0IsR0FBRyxLQUFLLENBQUMsY0FBYyxDQUFDO1FBQ2hELEdBQUcsRUFBRSxHQUFHLENBQUMsR0FBRztRQUNaLElBQUksRUFBRSxRQUFRLENBQUMsTUFBTSxDQUFDLElBQUk7UUFDMUIsVUFBVSxFQUFFLFFBQVEsQ0FBQyxNQUFNO1FBQzNCLElBQUksRUFBRSxRQUFRLENBQUMsSUFBSTtRQUNuQixTQUFTLEVBQUUsUUFBUSxDQUFDLE1BQU0sQ0FBQyxTQUFTO1FBQ3BDLEtBQUssRUFBRSxHQUFHLENBQUMsbUJBQW1CO1FBQzlCLE1BQU07S0FDUCxDQUFDLENBQUM7SUFFSCxJQUFJLENBQUMsb0JBQW9CLENBQUMsT0FBTyxFQUFFO1FBQ2pDLHFCQUFxQjtRQUNyQixNQUFNLFlBQVksR0FBRyxRQUFRLENBQUMsTUFBTSxDQUFDLElBQUksQ0FBQztRQUMxQyxNQUFNLFlBQVksR0FBRyxvQkFBb0IsQ0FBQyxZQUFZLENBQUM7UUFDdkQsTUFBTSxnQkFBZ0IsR0FBRyxvQkFBb0IsQ0FBQyxnQkFBZ0IsQ0FBQztRQUMvRCx1RkFBdUY7UUFDdkYsTUFBTSxpQkFBaUIsR0FBRyxLQUFLLENBQUMsQ0FBQyxDQUFDLEtBQUssQ0FBQyxTQUFTLENBQUMsQ0FBQyxFQUFFLEVBQUUsQ0FBQyxDQUFDLENBQUMsQ0FBQyxFQUFFLENBQUM7UUFDOUQsTUFBTSxZQUFZLEdBQUc7WUFDbkIsWUFBWTtZQUNaLFlBQVk7WUFDWixTQUFTLEVBQUUsZ0JBQWdCO1lBQzNCLFlBQVksRUFBRSxHQUFHLENBQUMsbUJBQW1CO1lBQ3JDLFVBQVUsRUFBRSxpQkFBaUI7U0FDOUIsQ0FBQztRQUNGLEtBQUssQ0FBQywyQkFBMkIsRUFBRSxZQUFZLENBQUMsQ0FBQztRQUNqRCxNQUFNLElBQUksd0JBQWdCLENBQUMsMERBQTBELEVBQUUsR0FBRyxFQUFFLFlBQVksQ0FBQyxDQUFDO0tBQzNHO0lBRUQsSUFBSSxLQUFLLENBQUMsY0FBYyxFQUFFLEtBQUssQ0FBQyxJQUFJLENBQUMsb0JBQW9CLENBQUMsMEJBQTBCLEVBQUU7UUFDcEYsTUFBTSxZQUFZLEdBQUc7WUFDbkIsU0FBUyxFQUFFLFFBQVEsQ0FBQyxNQUFNLENBQUMsU0FBUztZQUNwQyxnQkFBZ0IsRUFBRSxvQkFBb0IsQ0FBQyxnQkFBZ0I7U0FDeEQsQ0FBQztRQUNGLEtBQUssQ0FBQywyREFBMkQsRUFBRSxZQUFZLENBQUMsQ0FBQztRQUNqRixNQUFNLElBQUksd0JBQWdCLENBQ3hCLDBGQUEwRixFQUMxRixHQUFHLEVBQ0gsWUFBWSxDQUNiLENBQUM7S0FDSDtJQUNELE9BQU8sUUFBUSxDQUFDO0FBQ2xCLENBQUM7QUFyREQsd0NBcURDIiwic291cmNlc0NvbnRlbnQiOlsiLyoqXG4gKiBAcHJldHRpZXJcbiAqL1xuaW1wb3J0IERlYnVnIGZyb20gJ2RlYnVnJztcbmltcG9ydCAqIGFzIGVvbCBmcm9tICdlb2wnO1xuaW1wb3J0ICogYXMgXyBmcm9tICdsb2Rhc2gnO1xuaW1wb3J0ICogYXMgc2FuaXRpemVIdG1sIGZyb20gJ3Nhbml0aXplLWh0bWwnO1xuaW1wb3J0ICogYXMgc3VwZXJhZ2VudCBmcm9tICdzdXBlcmFnZW50JztcbmltcG9ydCAqIGFzIHVybExpYiBmcm9tICd1cmwnO1xuaW1wb3J0ICogYXMgcXVlcnlzdHJpbmcgZnJvbSAncXVlcnlzdHJpbmcnO1xuXG5pbXBvcnQgeyBBcGlSZXNwb25zZUVycm9yLCBWZXJpZnlSZXNwb25zZU9wdGlvbnMgfSBmcm9tICcuL3R5cGVzJztcbmltcG9ydCB7IEJpdEdvQVBJIH0gZnJvbSAnLi9iaXRnb0FQSSc7XG5cbmNvbnN0IGRlYnVnID0gRGVidWcoJ2JpdGdvOmFwaScpO1xuXG5leHBvcnQgaW50ZXJmYWNlIEJpdEdvUmVxdWVzdDxSZXN1bHRUeXBlID0gYW55PiBleHRlbmRzIHN1cGVyYWdlbnQuU3VwZXJBZ2VudFJlcXVlc3Qge1xuICByZXN1bHQ6IChvcHRpb25hbEZpZWxkPzogc3RyaW5nKSA9PiBQcm9taXNlPFJlc3VsdFR5cGU+O1xufVxuXG4vKipcbiAqIEFkZCB0aGUgYml0Z28tc3BlY2lmaWMgcmVzdWx0KCkgZnVuY3Rpb24gb24gYSBzdXBlcmFnZW50IHJlcXVlc3QuXG4gKlxuICogSWYgdGhlIHNlcnZlciByZXNwb25zZSBpcyBzdWNjZXNzZnVsLCB0aGUgYHJlc3VsdCgpYCBmdW5jdGlvbiB3aWxsIHJldHVybiBlaXRoZXIgdGhlIGVudGlyZSByZXNwb25zZSBib2R5LFxuICogb3IgdGhlIGZpZWxkIGZyb20gdGhlIHJlc3BvbnNlIGJvZHkgc3BlY2lmaWVkIGJ5IHRoZSBgb3B0aW9uYWxGaWVsZGAgcGFyYW1ldGVyIGlmIGl0IGlzIHByb3ZpZGVkLlxuICpcbiAqIElmIHRoZSBzZXJ2ZXIgcmVzcG9uc2Ugd2l0aCBhbiBlcnJvciwgYHJlc3VsdCgpYCB3aWxsIGhhbmRsZSBIVFRQIGVycm9ycyBhcHByb3ByaWF0ZWx5IGJ5XG4gKiByZXRocm93aW5nIHRoZW0gYXMgYW4gYEFwaVJlc3BvbnNlRXJyb3JgIGlmIHBvc3NpYmxlLCBhbmQgb3RoZXJ3aXNlIHJldGhyb3dpbmcgdGhlIHVuZGVybHlpbmcgcmVzcG9uc2UgZXJyb3IuXG4gKlxuICogQHBhcmFtIHJlcVxuICovXG5leHBvcnQgZnVuY3Rpb24gdG9CaXRnb1JlcXVlc3Q8UmVzcG9uc2VSZXN1bHRUeXBlID0gYW55PihcbiAgcmVxOiBzdXBlcmFnZW50LlN1cGVyQWdlbnRSZXF1ZXN0XG4pOiBCaXRHb1JlcXVlc3Q8UmVzcG9uc2VSZXN1bHRUeXBlPiB7XG4gIHJldHVybiBPYmplY3QuYXNzaWduKHJlcSwge1xuICAgIHJlc3VsdChvcHRpb25hbEZpZWxkPzogc3RyaW5nKSB7XG4gICAgICByZXR1cm4gcmVxLnRoZW4oXG4gICAgICAgIChyZXNwb25zZSkgPT4gaGFuZGxlUmVzcG9uc2VSZXN1bHQ8UmVzcG9uc2VSZXN1bHRUeXBlPihvcHRpb25hbEZpZWxkKShyZXNwb25zZSksXG4gICAgICAgIChlcnJvcikgPT4gaGFuZGxlUmVzcG9uc2VFcnJvcihlcnJvcilcbiAgICAgICk7XG4gICAgfSxcbiAgfSk7XG59XG5cbi8qKlxuICogUmV0dXJuIGEgZnVuY3Rpb24gd2hpY2ggZXh0cmFjdHMgdGhlIHNwZWNpZmllZCByZXNwb25zZSBib2R5IHByb3BlcnR5IGZyb20gdGhlIHJlc3BvbnNlIGlmIHN1Y2Nlc3NmdWwsXG4gKiBvdGhlcndpc2UgdGhyb3cgYW4gYEFwaUVycm9yUmVzcG9uc2VgIHBhcnNlZCBmcm9tIHRoZSByZXNwb25zZSBib2R5LlxuICogQHBhcmFtIG9wdGlvbmFsRmllbGRcbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIGhhbmRsZVJlc3BvbnNlUmVzdWx0PFJlc3BvbnNlUmVzdWx0VHlwZT4oXG4gIG9wdGlvbmFsRmllbGQ/OiBzdHJpbmdcbik6IChyZXM6IHN1cGVyYWdlbnQuUmVzcG9uc2UpID0+IFJlc3BvbnNlUmVzdWx0VHlwZSB7XG4gIHJldHVybiBmdW5jdGlvbiAocmVzOiBzdXBlcmFnZW50LlJlc3BvbnNlKTogUmVzcG9uc2VSZXN1bHRUeXBlIHtcbiAgICBpZiAoXy5pc051bWJlcihyZXMuc3RhdHVzKSAmJiByZXMuc3RhdHVzID49IDIwMCAmJiByZXMuc3RhdHVzIDwgMzAwKSB7XG4gICAgICByZXR1cm4gb3B0aW9uYWxGaWVsZCA/IHJlcy5ib2R5W29wdGlvbmFsRmllbGRdIDogcmVzLmJvZHk7XG4gICAgfVxuICAgIHRocm93IGVyckZyb21SZXNwb25zZShyZXMpO1xuICB9O1xufVxuXG4vKipcbiAqIEV4dHJhY3QgcmVsZXZhbnQgaW5mb3JtYXRpb24gZnJvbSBhIHN1Y2Nlc3NmdWwgcmVzcG9uc2UgKHRoYXQgaXMsIGEgcmVzcG9uc2Ugd2l0aCBhbiBIVFRQIHN0YXR1cyBjb2RlXG4gKiBiZXR3ZWVuIDIwMCBhbmQgMjk5KSwgYnV0IHdoaWNoIHJlc3VsdGVkIGluIGFuIGFwcGxpY2F0aW9uIHNwZWNpZmljIGVycm9yIGFuZCB1c2UgaXQgdG8gY29uc3RydWN0IGFuZFxuICogdGhyb3cgYW4gYEFwaUVycm9yUmVzcG9uc2VgLlxuICpcbiAqIEBwYXJhbSByZXNcbiAqL1xuZnVuY3Rpb24gZXJyRnJvbVJlc3BvbnNlPFJlc3BvbnNlQm9keVR5cGU+KHJlczogc3VwZXJhZ2VudC5SZXNwb25zZSk6IEFwaVJlc3BvbnNlRXJyb3Ige1xuICBjb25zdCBtZXNzYWdlID0gY3JlYXRlUmVzcG9uc2VFcnJvclN0cmluZyhyZXMpO1xuICBjb25zdCBzdGF0dXMgPSByZXMuc3RhdHVzO1xuICBjb25zdCByZXN1bHQgPSByZXMuYm9keSBhcyBSZXNwb25zZUJvZHlUeXBlO1xuICBjb25zdCBpbnZhbGlkVG9rZW4gPSBfLmhhcyhyZXMuaGVhZGVyLCAneC1hdXRoLXJlcXVpcmVkJykgJiYgcmVzLmhlYWRlclsneC1hdXRoLXJlcXVpcmVkJ10gPT09ICd0cnVlJztcbiAgY29uc3QgbmVlZHNPdHAgPSByZXMuYm9keS5uZWVkc09UUCAhPT0gdW5kZWZpbmVkO1xuICByZXR1cm4gbmV3IEFwaVJlc3BvbnNlRXJyb3IobWVzc2FnZSwgc3RhdHVzLCByZXN1bHQsIGludmFsaWRUb2tlbiwgbmVlZHNPdHApO1xufVxuXG4vKipcbiAqIEhhbmRsZSBhbiBlcnJvciBvciBhbiBlcnJvciBjb250YWluaW5nIGFuIEhUVFAgcmVzcG9uc2UgYW5kIHVzZSBpdCB0byB0aHJvdyBhIHdlbGwtZm9ybWVkIGVycm9yIG9iamVjdC5cbiAqXG4gKiBAcGFyYW0gZVxuICovXG5leHBvcnQgZnVuY3Rpb24gaGFuZGxlUmVzcG9uc2VFcnJvcihlOiBFcnJvciAmIHsgcmVzcG9uc2U/OiBzdXBlcmFnZW50LlJlc3BvbnNlIH0pOiBuZXZlciB7XG4gIGlmIChlLnJlc3BvbnNlKSB7XG4gICAgdGhyb3cgZXJyRnJvbVJlc3BvbnNlKGUucmVzcG9uc2UpO1xuICB9XG4gIHRocm93IGU7XG59XG5cbi8qKlxuICogVGhlcmUgYXJlIG1hbnkgd2F5cyBhIHJlcXVlc3QgY2FuIGZhaWwsIGFuZCBtYXkgd2F5cyBpbmZvcm1hdGlvbiBvbiB0aGF0IGZhaWx1cmUgY2FuIGJlXG4gKiBjb21tdW5pY2F0ZWQgdG8gdGhlIGNsaWVudC4gVGhpcyBmdW5jdGlvbiB0cmllcyB0byBoYW5kbGUgdGhvc2UgY2FzZXMgYW5kIGNyZWF0ZSBhIHNhbmUgZXJyb3Igc3RyaW5nXG4gKiBAcGFyYW0gcmVzIFJlc3BvbnNlIGZyb20gYW4gSFRUUCByZXF1ZXN0XG4gKi9cbmZ1bmN0aW9uIGNyZWF0ZVJlc3BvbnNlRXJyb3JTdHJpbmcocmVzOiBzdXBlcmFnZW50LlJlc3BvbnNlKTogc3RyaW5nIHtcbiAgbGV0IGVyclN0cmluZyA9IHJlcy5zdGF0dXMudG9TdHJpbmcoKTsgLy8gYXQgdGhlIHZlcnkgbGVhc3Qgd2UnbGwgaGF2ZSB0aGUgc3RhdHVzIGNvZGVcbiAgaWYgKHJlcy5ib2R5Py5lcnJvcikge1xuICAgIC8vIHRoaXMgaXMgdGhlIGNhc2Ugd2UgaG9wZSBmb3IsIHdoZXJlIHRoZSBzZXJ2ZXIgZ2l2ZXMgdXMgYSBuaWNlIGVycm9yIGZyb20gdGhlIEpTT04gYm9keVxuICAgIGVyclN0cmluZyA9IHJlcy5ib2R5LmVycm9yO1xuICB9IGVsc2UgaWYgKHJlcy50ZXh0KSB7XG4gICAgLy8gaWYgdGhlIHJlc3BvbnNlIGNhbWUgYmFjayBhcyB0ZXh0LCB3ZSB0cnkgdG8gcGFyc2UgaXQgYXMgSFRNTCBhbmQgcmVtb3ZlIGFsbCB0YWdzLCBsZWF2aW5nIHVzXG4gICAgLy8ganVzdCB0aGUgYmFyZSB0ZXh0LCB3aGljaCB3ZSB0aGVuIHRyaW0gb2YgZXhjZXNzaXZlIG5ld2xpbmVzIGFuZCBsaW1pdCB0byBhIGNlcnRhaW4gbGVuZ3RoXG4gICAgdHJ5IHtcbiAgICAgIGxldCBzYW5pdGl6ZWRUZXh0ID0gc2FuaXRpemVIdG1sKHJlcy50ZXh0LCB7IGFsbG93ZWRUYWdzOiBbXSB9KTtcbiAgICAgIHNhbml0aXplZFRleHQgPSBzYW5pdGl6ZWRUZXh0LnRyaW0oKTtcbiAgICAgIHNhbml0aXplZFRleHQgPSBlb2wubGYoc2FuaXRpemVkVGV4dCk7IC8vIHVzZSAnXFxuJyBmb3IgYWxsIG5ld2xpbmVzXG4gICAgICBzYW5pdGl6ZWRUZXh0ID0gXy5yZXBsYWNlKHNhbml0aXplZFRleHQsIC9cXG5bIHxcXHRdezEsfVxcbi9nLCAnXFxuXFxuJyk7IC8vIHJlbW92ZSB0aGUgc3BhY2VzL3RhYnMgYmV0d2VlbiBuZXdsaW5lc1xuICAgICAgc2FuaXRpemVkVGV4dCA9IF8ucmVwbGFjZShzYW5pdGl6ZWRUZXh0LCAvW1xcbl17Myx9L2csICdcXG5cXG4nKTsgLy8gaGF2ZSBhdCBtb3N0IDIgY29uc2VjdXRpdmUgbmV3bGluZXNcbiAgICAgIHNhbml0aXplZFRleHQgPSBzYW5pdGl6ZWRUZXh0LnN1YnN0cmluZygwLCA1MDAwKTsgLy8gcHJldmVudCBtZXNzYWdlIGZyb20gZ2V0dGluZyB0b28gbGFyZ2VcbiAgICAgIGVyclN0cmluZyA9IGVyclN0cmluZyArICdcXG4nICsgc2FuaXRpemVkVGV4dDsgLy8gYWRkIGl0IHRvIG91ciBleGlzdGluZyBlcnJTdHJpbmcgKGF0IHRoaXMgcG9pbnQgdGhlIG1vcmUgaW5mbyB0aGUgYmV0dGVyISlcbiAgICB9IGNhdGNoIChlKSB7XG4gICAgICAvLyBkbyBub3RoaW5nLCB0aGUgcmVzcG9uc2UncyBIVE1MIHdhcyB0b28gd2Fja3kgdG8gYmUgcGFyc2VkIGNsZWFubHlcbiAgICAgIGRlYnVnKCdnb3QgZXJyb3Igd2l0aCBtZXNzYWdlIFwiJXNcIiB3aGlsZSBjcmVhdGluZyByZXNwb25zZSBlcnJvciBzdHJpbmcgZnJvbSByZXNwb25zZTogJXMnLCBlLm1lc3NhZ2UsIHJlcy50ZXh0KTtcbiAgICB9XG4gIH1cblxuICByZXR1cm4gZXJyU3RyaW5nO1xufVxuXG4vKipcbiAqIFNlcmlhbGl6ZSByZXF1ZXN0IGRhdGEgYmFzZWQgb24gdGhlIHJlcXVlc3QgY29udGVudCB0eXBlXG4gKiBOb3RlOiBOb3Qgc3VyZSB0aGlzIGlzIHN0aWxsIG5lZWRlZCBvciBldmVuIHVzZWZ1bC4gQ29uc2lkZXIgcmVtb3ZpbmcuXG4gKiBAcGFyYW0gcmVxXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBzZXJpYWxpemVSZXF1ZXN0RGF0YShyZXE6IHN1cGVyYWdlbnQuUmVxdWVzdCk6IHN0cmluZyB8IHVuZGVmaW5lZCB7XG4gIGxldCBkYXRhOiBzdHJpbmcgfCBSZWNvcmQ8c3RyaW5nLCB1bmtub3duPiA9IChyZXEgYXMgYW55KS5fZGF0YTtcbiAgaWYgKHR5cGVvZiBkYXRhICE9PSAnc3RyaW5nJykge1xuICAgIGxldCBjb250ZW50VHlwZSA9IHJlcS5nZXQoJ0NvbnRlbnQtVHlwZScpO1xuICAgIC8vIFBhcnNlIG91dCBqdXN0IHRoZSBjb250ZW50IHR5cGUgZnJvbSB0aGUgaGVhZGVyIChpZ25vcmUgdGhlIGNoYXJzZXQpXG4gICAgaWYgKGNvbnRlbnRUeXBlKSB7XG4gICAgICBjb250ZW50VHlwZSA9IGNvbnRlbnRUeXBlLnNwbGl0KCc7JylbMF07XG4gICAgfVxuICAgIGxldCBzZXJpYWxpemUgPSBzdXBlcmFnZW50LnNlcmlhbGl6ZVtjb250ZW50VHlwZV07XG4gICAgaWYgKCFzZXJpYWxpemUgJiYgL1tcXC8rXWpzb25cXGIvLnRlc3QoY29udGVudFR5cGUpKSB7XG4gICAgICBzZXJpYWxpemUgPSBzdXBlcmFnZW50LnNlcmlhbGl6ZVsnYXBwbGljYXRpb24vanNvbiddO1xuICAgIH1cbiAgICBpZiAoc2VyaWFsaXplKSB7XG4gICAgICBkYXRhID0gc2VyaWFsaXplKGRhdGEpO1xuICAgICAgKHJlcSBhcyBhbnkpLl9kYXRhID0gZGF0YTtcbiAgICAgIHJldHVybiBkYXRhO1xuICAgIH1cbiAgfVxufVxuXG4vKipcbiAqIFNldCB0aGUgc3VwZXJhZ2VudCBxdWVyeSBzdHJpbmcgY29ycmVjdGx5IGZvciBicm93c2VycyBvciBub2RlLlxuICogQHBhcmFtIHJlcVxuICovXG5leHBvcnQgZnVuY3Rpb24gc2V0UmVxdWVzdFF1ZXJ5U3RyaW5nKHJlcTogc3VwZXJhZ2VudC5TdXBlckFnZW50UmVxdWVzdCk6IHZvaWQge1xuICBjb25zdCB1cmxEZXRhaWxzID0gdXJsTGliLnBhcnNlKHJlcS51cmwpO1xuXG4gIGxldCBxdWVyeVN0cmluZzogc3RyaW5nIHwgdW5kZWZpbmVkO1xuICBjb25zdCBxdWVyeTogc3RyaW5nW10gPSAocmVxIGFzIGFueSkuX3F1ZXJ5O1xuICBjb25zdCBxczogeyBba2V5OiBzdHJpbmddOiBzdHJpbmcgfSA9IChyZXEgYXMgYW55KS5xcztcbiAgaWYgKHF1ZXJ5ICYmIHF1ZXJ5Lmxlbmd0aCA+IDApIHtcbiAgICAvLyBicm93c2VyIHZlcnNpb25cbiAgICBxdWVyeVN0cmluZyA9IHF1ZXJ5LmpvaW4oJyYnKTtcbiAgICAocmVxIGFzIGFueSkuX3F1ZXJ5ID0gW107XG4gIH0gZWxzZSBpZiAocXMpIHtcbiAgICAvLyBub2RlIHZlcnNpb25cbiAgICBxdWVyeVN0cmluZyA9IHF1ZXJ5c3RyaW5nLnN0cmluZ2lmeShxcyk7XG4gICAgKHJlcSBhcyBhbnkpLnFzID0gbnVsbDtcbiAgfVxuXG4gIGlmIChxdWVyeVN0cmluZykge1xuICAgIGlmICh1cmxEZXRhaWxzLnNlYXJjaCkge1xuICAgICAgdXJsRGV0YWlscy5zZWFyY2ggKz0gJyYnICsgcXVlcnlTdHJpbmc7XG4gICAgfSBlbHNlIHtcbiAgICAgIHVybERldGFpbHMuc2VhcmNoID0gJz8nICsgcXVlcnlTdHJpbmc7XG4gICAgfVxuICAgIHJlcS51cmwgPSB1cmxMaWIuZm9ybWF0KHVybERldGFpbHMpO1xuICB9XG59XG5cbi8qKlxuICogVmVyaWZ5IHRoYXQgdGhlIHJlc3BvbnNlIHJlY2VpdmVkIGZyb20gdGhlIHNlcnZlciBpcyBzaWduZWQgY29ycmVjdGx5LlxuICogUmlnaHQgbm93LCBpdCBpcyB2ZXJ5IHBlcm1pc3NpdmUgd2l0aCB0aGUgdGltZXN0YW1wIHZhcmlhbmNlLlxuICovXG5leHBvcnQgZnVuY3Rpb24gdmVyaWZ5UmVzcG9uc2UoXG4gIGJpdGdvOiBCaXRHb0FQSSxcbiAgdG9rZW46IHN0cmluZyB8IHVuZGVmaW5lZCxcbiAgbWV0aG9kOiBWZXJpZnlSZXNwb25zZU9wdGlvbnNbJ21ldGhvZCddLFxuICByZXE6IHN1cGVyYWdlbnQuU3VwZXJBZ2VudFJlcXVlc3QsXG4gIHJlc3BvbnNlOiBzdXBlcmFnZW50LlJlc3BvbnNlXG4pOiBzdXBlcmFnZW50LlJlc3BvbnNlIHtcbiAgLy8gd2UgY2FuJ3QgdmVyaWZ5IHRoZSByZXNwb25zZSBpZiB3ZSdyZSBub3QgYXV0aGVudGljYXRlZFxuICBpZiAoIXJlcS5pc1YyQXV0aGVudGljYXRlZCB8fCAhcmVxLmF1dGhlbnRpY2F0aW9uVG9rZW4pIHtcbiAgICByZXR1cm4gcmVzcG9uc2U7XG4gIH1cblxuICBjb25zdCB2ZXJpZmljYXRpb25SZXNwb25zZSA9IGJpdGdvLnZlcmlmeVJlc3BvbnNlKHtcbiAgICB1cmw6IHJlcS51cmwsXG4gICAgaG1hYzogcmVzcG9uc2UuaGVhZGVyLmhtYWMsXG4gICAgc3RhdHVzQ29kZTogcmVzcG9uc2Uuc3RhdHVzLFxuICAgIHRleHQ6IHJlc3BvbnNlLnRleHQsXG4gICAgdGltZXN0YW1wOiByZXNwb25zZS5oZWFkZXIudGltZXN0YW1wLFxuICAgIHRva2VuOiByZXEuYXV0aGVudGljYXRpb25Ub2tlbixcbiAgICBtZXRob2QsXG4gIH0pO1xuXG4gIGlmICghdmVyaWZpY2F0aW9uUmVzcG9uc2UuaXNWYWxpZCkge1xuICAgIC8vIGNhbGN1bGF0ZSB0aGUgSE1BQ1xuICAgIGNvbnN0IHJlY2VpdmVkSG1hYyA9IHJlc3BvbnNlLmhlYWRlci5obWFjO1xuICAgIGNvbnN0IGV4cGVjdGVkSG1hYyA9IHZlcmlmaWNhdGlvblJlc3BvbnNlLmV4cGVjdGVkSG1hYztcbiAgICBjb25zdCBzaWduYXR1cmVTdWJqZWN0ID0gdmVyaWZpY2F0aW9uUmVzcG9uc2Uuc2lnbmF0dXJlU3ViamVjdDtcbiAgICAvLyBMb2cgb25seSB0aGUgZmlyc3QgMTAgY2hhcmFjdGVycyBvZiB0aGUgdG9rZW4gdG8gZW5zdXJlIHRoZSBmdWxsIHRva2VuIGlzbid0IGxvZ2dlZC5cbiAgICBjb25zdCBwYXJ0aWFsQml0Z29Ub2tlbiA9IHRva2VuID8gdG9rZW4uc3Vic3RyaW5nKDAsIDEwKSA6ICcnO1xuICAgIGNvbnN0IGVycm9yRGV0YWlscyA9IHtcbiAgICAgIGV4cGVjdGVkSG1hYyxcbiAgICAgIHJlY2VpdmVkSG1hYyxcbiAgICAgIGhtYWNJbnB1dDogc2lnbmF0dXJlU3ViamVjdCxcbiAgICAgIHJlcXVlc3RUb2tlbjogcmVxLmF1dGhlbnRpY2F0aW9uVG9rZW4sXG4gICAgICBiaXRnb1Rva2VuOiBwYXJ0aWFsQml0Z29Ub2tlbixcbiAgICB9O1xuICAgIGRlYnVnKCdJbnZhbGlkIHJlc3BvbnNlIEhNQUM6ICVPJywgZXJyb3JEZXRhaWxzKTtcbiAgICB0aHJvdyBuZXcgQXBpUmVzcG9uc2VFcnJvcignaW52YWxpZCByZXNwb25zZSBITUFDLCBwb3NzaWJsZSBtYW4taW4tdGhlLW1pZGRsZS1hdHRhY2snLCA1MTEsIGVycm9yRGV0YWlscyk7XG4gIH1cblxuICBpZiAoYml0Z28uZ2V0QXV0aFZlcnNpb24oKSA9PT0gMyAmJiAhdmVyaWZpY2F0aW9uUmVzcG9uc2UuaXNJblJlc3BvbnNlVmFsaWRpdHlXaW5kb3cpIHtcbiAgICBjb25zdCBlcnJvckRldGFpbHMgPSB7XG4gICAgICB0aW1lc3RhbXA6IHJlc3BvbnNlLmhlYWRlci50aW1lc3RhbXAsXG4gICAgICB2ZXJpZmljYXRpb25UaW1lOiB2ZXJpZmljYXRpb25SZXNwb25zZS52ZXJpZmljYXRpb25UaW1lLFxuICAgIH07XG4gICAgZGVidWcoJ1NlcnZlciByZXNwb25zZSBvdXRzaWRlIHJlc3BvbnNlIHZhbGlkaXR5IHRpbWUgd2luZG93OiAlTycsIGVycm9yRGV0YWlscyk7XG4gICAgdGhyb3cgbmV3IEFwaVJlc3BvbnNlRXJyb3IoXG4gICAgICAnc2VydmVyIHJlc3BvbnNlIG91dHNpZGUgcmVzcG9uc2UgdmFsaWRpdHkgdGltZSB3aW5kb3csIHBvc3NpYmxlIG1hbi1pbi10aGUtbWlkZGxlLWF0dGFjaycsXG4gICAgICA1MTEsXG4gICAgICBlcnJvckRldGFpbHNcbiAgICApO1xuICB9XG4gIHJldHVybiByZXNwb25zZTtcbn1cbiJdfQ==
|
|
@@ -0,0 +1,111 @@
|
|
|
1
|
+
import { BitGoRequest } from './api';
|
|
2
|
+
import * as utxolib from '@bitgo/utxo-lib';
|
|
3
|
+
import { EnvironmentName } from '@bitgo/sdk-core';
|
|
4
|
+
import { AccessTokenOptions, IRequestTracer, PingOptions, AuthenticateOptions, CalculateHmacSubjectOptions, CalculateRequestHeadersOptions, CalculateRequestHmacOptions, ProcessedAuthenticationOptions, RequestHeaders, VerifyResponseInfo, VerifyResponseOptions, BitGoAPIOptions } from './types';
|
|
5
|
+
export declare abstract class BitGoAPI {
|
|
6
|
+
protected static _constants: any;
|
|
7
|
+
protected static _constantsExpire: any;
|
|
8
|
+
protected static _testnetWarningMessage: boolean;
|
|
9
|
+
readonly env: EnvironmentName;
|
|
10
|
+
protected readonly _baseUrl: string;
|
|
11
|
+
protected readonly _baseApiUrl: string;
|
|
12
|
+
protected readonly _baseApiUrlV2: string;
|
|
13
|
+
protected readonly _env: EnvironmentName;
|
|
14
|
+
protected readonly _authVersion: Exclude<BitGoAPIOptions['authVersion'], undefined>;
|
|
15
|
+
protected _hmacVerification: boolean;
|
|
16
|
+
protected readonly _proxy?: string;
|
|
17
|
+
protected _extensionKey?: utxolib.ECPair.ECPairInterface;
|
|
18
|
+
protected _reqId?: IRequestTracer;
|
|
19
|
+
protected _token?: string;
|
|
20
|
+
protected _version: string;
|
|
21
|
+
protected _userAgent?: string;
|
|
22
|
+
constructor(params?: BitGoAPIOptions);
|
|
23
|
+
/**
|
|
24
|
+
* Return the current BitGo environment
|
|
25
|
+
*/
|
|
26
|
+
getEnv(): EnvironmentName;
|
|
27
|
+
/**
|
|
28
|
+
* Return the current auth version used for requests to the BitGo server
|
|
29
|
+
*/
|
|
30
|
+
getAuthVersion(): number;
|
|
31
|
+
/**
|
|
32
|
+
* This is a patching function which can apply our authorization
|
|
33
|
+
* headers to any outbound request.
|
|
34
|
+
* @param method
|
|
35
|
+
*/
|
|
36
|
+
private requestPatch;
|
|
37
|
+
get(url: string): BitGoRequest;
|
|
38
|
+
post(url: string): BitGoRequest;
|
|
39
|
+
put(url: string): BitGoRequest;
|
|
40
|
+
del(url: string): BitGoRequest;
|
|
41
|
+
patch(url: string): BitGoRequest;
|
|
42
|
+
/**
|
|
43
|
+
* Calculate the HMAC for the given key and message
|
|
44
|
+
* @param key {String} - the key to use for the HMAC
|
|
45
|
+
* @param message {String} - the actual message to HMAC
|
|
46
|
+
* @returns {*} - the result of the HMAC operation
|
|
47
|
+
*/
|
|
48
|
+
calculateHMAC(key: string, message: string): string;
|
|
49
|
+
/**
|
|
50
|
+
* Calculate the subject string that is to be HMAC'ed for a HTTP request or response
|
|
51
|
+
* @param urlPath request url, including query params
|
|
52
|
+
* @param text request body text
|
|
53
|
+
* @param timestamp request timestamp from `Date.now()`
|
|
54
|
+
* @param statusCode Only set for HTTP responses, leave blank for requests
|
|
55
|
+
* @param method request method
|
|
56
|
+
* @returns {string}
|
|
57
|
+
*/
|
|
58
|
+
calculateHMACSubject({ urlPath, text, timestamp, statusCode, method }: CalculateHmacSubjectOptions): string;
|
|
59
|
+
/**
|
|
60
|
+
* Calculate the HMAC for an HTTP request
|
|
61
|
+
*/
|
|
62
|
+
calculateRequestHMAC({ url: urlPath, text, timestamp, token, method }: CalculateRequestHmacOptions): string;
|
|
63
|
+
/**
|
|
64
|
+
* Calculate request headers with HMAC
|
|
65
|
+
*/
|
|
66
|
+
calculateRequestHeaders({ url, text, token, method }: CalculateRequestHeadersOptions): RequestHeaders;
|
|
67
|
+
/**
|
|
68
|
+
* Verify the HMAC for an HTTP response
|
|
69
|
+
*/
|
|
70
|
+
verifyResponse({ url: urlPath, statusCode, text, timestamp, token, hmac, method, }: VerifyResponseOptions): VerifyResponseInfo;
|
|
71
|
+
/**
|
|
72
|
+
* Process the username, password and otp into an object containing the username and hashed password, ready to
|
|
73
|
+
* send to bitgo for authentication.
|
|
74
|
+
*/
|
|
75
|
+
preprocessAuthenticationParams({ username, password, otp, forceSMS, extensible, trust, }: AuthenticateOptions): ProcessedAuthenticationOptions;
|
|
76
|
+
/**
|
|
77
|
+
* Fetch useful constant values from the BitGo server.
|
|
78
|
+
* These values do change infrequently, so they need to be fetched,
|
|
79
|
+
* but are unlikely to change during the lifetime of a BitGo object,
|
|
80
|
+
* so they can safely cached.
|
|
81
|
+
*/
|
|
82
|
+
fetchConstants(): Promise<any>;
|
|
83
|
+
/**
|
|
84
|
+
* Create a url for calling BitGo platform APIs
|
|
85
|
+
* @param path
|
|
86
|
+
* @param version
|
|
87
|
+
*/
|
|
88
|
+
url(path: string, version?: number): string;
|
|
89
|
+
/**
|
|
90
|
+
* Create a url for calling BitGo microservice APIs
|
|
91
|
+
*/
|
|
92
|
+
microservicesUrl(path: string): string;
|
|
93
|
+
/**
|
|
94
|
+
* Gets the version of the BitGoJS package
|
|
95
|
+
*/
|
|
96
|
+
version(): string;
|
|
97
|
+
/**
|
|
98
|
+
* Synchronous method for activating an access token.
|
|
99
|
+
*/
|
|
100
|
+
authenticateWithAccessToken({ accessToken }: AccessTokenOptions): void;
|
|
101
|
+
/**
|
|
102
|
+
* Test connectivity to the server
|
|
103
|
+
* @param params
|
|
104
|
+
*/
|
|
105
|
+
ping({ reqId }?: PingOptions): Promise<any>;
|
|
106
|
+
/**
|
|
107
|
+
* Set a request tracer to provide request IDs during multi-request workflows
|
|
108
|
+
*/
|
|
109
|
+
setRequestTracer(reqTracer: IRequestTracer): void;
|
|
110
|
+
}
|
|
111
|
+
//# sourceMappingURL=bitgoAPI.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"bitgoAPI.d.ts","sourceRoot":"","sources":["../../src/bitgoAPI.ts"],"names":[],"mappings":"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"}
|