@bitgo/abstract-cosmos 1.1.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.
@@ -0,0 +1,80 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.CosmosTransactionBuilder = void 0;
4
+ const sdk_core_1 = require("@bitgo/sdk-core");
5
+ const keyPair_1 = require("./keyPair");
6
+ const utils_1 = require("./utils");
7
+ class CosmosTransactionBuilder extends sdk_core_1.BaseTransactionBuilder {
8
+ constructor(_coinConfig) {
9
+ super(_coinConfig);
10
+ }
11
+ /** @inheritdoc */
12
+ get transaction() {
13
+ return this._transaction;
14
+ }
15
+ /** @inheritdoc */
16
+ set transaction(transaction) {
17
+ this._transaction = transaction;
18
+ }
19
+ /** @inheritDoc */
20
+ addSignature(publicKey, signature) {
21
+ this._signature = signature;
22
+ this._publicKey = publicKey.pub;
23
+ }
24
+ /**
25
+ * Sets sequence of this transaction.
26
+ * @param {number} sequence - sequence data for tx signer
27
+ * @returns {TransactionBuilder} This transaction builder
28
+ */
29
+ sequence(sequence) {
30
+ utils_1.default.validateSequence(sequence);
31
+ this._sequence = sequence;
32
+ return this;
33
+ }
34
+ publicKey(publicKey) {
35
+ this._publicKey = publicKey;
36
+ return this;
37
+ }
38
+ accountNumber(accountNumber) {
39
+ this._accountNumber = accountNumber;
40
+ return this;
41
+ }
42
+ chainId(chainId) {
43
+ this._chainId = chainId;
44
+ return this;
45
+ }
46
+ memo(memo) {
47
+ this._memo = memo;
48
+ return this;
49
+ }
50
+ /** @inheritdoc */
51
+ signImplementation(key) {
52
+ this.validateKey(key);
53
+ if (this._accountNumber === undefined) {
54
+ throw new sdk_core_1.SigningError('accountNumber is required before signing');
55
+ }
56
+ if (this._chainId === undefined) {
57
+ throw new sdk_core_1.SigningError('chainId is required before signing');
58
+ }
59
+ this._signer = new keyPair_1.CosmosKeyPair({ prv: key.key });
60
+ this._publicKey = this._signer.getKeys().pub;
61
+ return this.transaction;
62
+ }
63
+ /** @inheritdoc */
64
+ validateValue(value) {
65
+ if (value.isLessThan(0)) {
66
+ throw new sdk_core_1.BuildTransactionError('Value cannot be less than zero');
67
+ }
68
+ }
69
+ /** @inheritdoc */
70
+ validateKey(key) {
71
+ try {
72
+ new keyPair_1.CosmosKeyPair({ prv: key.key });
73
+ }
74
+ catch {
75
+ throw new sdk_core_1.BuildTransactionError(`Key validation failed`);
76
+ }
77
+ }
78
+ }
79
+ exports.CosmosTransactionBuilder = CosmosTransactionBuilder;
80
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoidHJhbnNhY3Rpb25CdWlsZGVyLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vLi4vc3JjL2xpYi90cmFuc2FjdGlvbkJ1aWxkZXIudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6Ijs7O0FBQUEsOENBT3lCO0FBV3pCLHVDQUFxRDtBQUVyRCxtQ0FBNEI7QUFFNUIsTUFBc0Isd0JBQXlCLFNBQVEsaUNBQXNCO0lBWTNFLFlBQVksV0FBaUM7UUFDM0MsS0FBSyxDQUFDLFdBQVcsQ0FBQyxDQUFDO0lBQ3JCLENBQUM7SUFPRCxrQkFBa0I7SUFDbEIsSUFBYyxXQUFXO1FBQ3ZCLE9BQU8sSUFBSSxDQUFDLFlBQVksQ0FBQztJQUMzQixDQUFDO0lBRUQsa0JBQWtCO0lBQ2xCLElBQWMsV0FBVyxDQUFDLFdBQThCO1FBQ3RELElBQUksQ0FBQyxZQUFZLEdBQUcsV0FBVyxDQUFDO0lBQ2xDLENBQUM7SUFFRCxrQkFBa0I7SUFDbEIsWUFBWSxDQUFDLFNBQXdCLEVBQUUsU0FBaUI7UUFDdEQsSUFBSSxDQUFDLFVBQVUsR0FBRyxTQUFTLENBQUM7UUFDNUIsSUFBSSxDQUFDLFVBQVUsR0FBRyxTQUFTLENBQUMsR0FBRyxDQUFDO0lBQ2xDLENBQUM7SUFFRDs7OztPQUlHO0lBQ0gsUUFBUSxDQUFDLFFBQWdCO1FBQ3ZCLGVBQUssQ0FBQyxnQkFBZ0IsQ0FBQyxRQUFRLENBQUMsQ0FBQztRQUNqQyxJQUFJLENBQUMsU0FBUyxHQUFHLFFBQVEsQ0FBQztRQUMxQixPQUFPLElBQUksQ0FBQztJQUNkLENBQUM7SUFhRCxTQUFTLENBQUMsU0FBNkI7UUFDckMsSUFBSSxDQUFDLFVBQVUsR0FBRyxTQUFTLENBQUM7UUFDNUIsT0FBTyxJQUFJLENBQUM7SUFDZCxDQUFDO0lBRUQsYUFBYSxDQUFDLGFBQWlDO1FBQzdDLElBQUksQ0FBQyxjQUFjLEdBQUcsYUFBYSxDQUFDO1FBQ3BDLE9BQU8sSUFBSSxDQUFDO0lBQ2QsQ0FBQztJQUVELE9BQU8sQ0FBQyxPQUEyQjtRQUNqQyxJQUFJLENBQUMsUUFBUSxHQUFHLE9BQU8sQ0FBQztRQUN4QixPQUFPLElBQUksQ0FBQztJQUNkLENBQUM7SUFFRCxJQUFJLENBQUMsSUFBd0I7UUFDM0IsSUFBSSxDQUFDLEtBQUssR0FBRyxJQUFJLENBQUM7UUFDbEIsT0FBTyxJQUFJLENBQUM7SUFDZCxDQUFDO0lBRUQsa0JBQWtCO0lBQ1Isa0JBQWtCLENBQUMsR0FBWTtRQUN2QyxJQUFJLENBQUMsV0FBVyxDQUFDLEdBQUcsQ0FBQyxDQUFDO1FBQ3RCLElBQUksSUFBSSxDQUFDLGNBQWMsS0FBSyxTQUFTLEVBQUU7WUFDckMsTUFBTSxJQUFJLHVCQUFZLENBQUMsMENBQTBDLENBQUMsQ0FBQztTQUNwRTtRQUNELElBQUksSUFBSSxDQUFDLFFBQVEsS0FBSyxTQUFTLEVBQUU7WUFDL0IsTUFBTSxJQUFJLHVCQUFZLENBQUMsb0NBQW9DLENBQUMsQ0FBQztTQUM5RDtRQUNELElBQUksQ0FBQyxPQUFPLEdBQUcsSUFBSSx1QkFBTyxDQUFDLEVBQUUsR0FBRyxFQUFFLEdBQUcsQ0FBQyxHQUFHLEVBQUUsQ0FBQyxDQUFDO1FBQzdDLElBQUksQ0FBQyxVQUFVLEdBQUcsSUFBSSxDQUFDLE9BQU8sQ0FBQyxPQUFPLEVBQUUsQ0FBQyxHQUFHLENBQUM7UUFDN0MsT0FBTyxJQUFJLENBQUMsV0FBVyxDQUFDO0lBQzFCLENBQUM7SUFFRCxrQkFBa0I7SUFDbEIsYUFBYSxDQUFDLEtBQWdCO1FBQzVCLElBQUksS0FBSyxDQUFDLFVBQVUsQ0FBQyxDQUFDLENBQUMsRUFBRTtZQUN2QixNQUFNLElBQUksZ0NBQXFCLENBQUMsZ0NBQWdDLENBQUMsQ0FBQztTQUNuRTtJQUNILENBQUM7SUFFRCxrQkFBa0I7SUFDbEIsV0FBVyxDQUFDLEdBQVk7UUFDdEIsSUFBSTtZQUNGLElBQUksdUJBQU8sQ0FBQyxFQUFFLEdBQUcsRUFBRSxHQUFHLENBQUMsR0FBRyxFQUFFLENBQUMsQ0FBQztTQUMvQjtRQUFDLE1BQU07WUFDTixNQUFNLElBQUksZ0NBQXFCLENBQUMsdUJBQXVCLENBQUMsQ0FBQztTQUMxRDtJQUNILENBQUM7Q0FDRjtBQTVHRCw0REE0R0MiLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQge1xuICBCYXNlS2V5LFxuICBCYXNlVHJhbnNhY3Rpb25CdWlsZGVyLFxuICBCdWlsZFRyYW5zYWN0aW9uRXJyb3IsXG4gIFB1YmxpY0tleSBhcyBCYXNlUHVibGljS2V5LFxuICBTaWduaW5nRXJyb3IsXG4gIFRyYW5zYWN0aW9uVHlwZSxcbn0gZnJvbSAnQGJpdGdvL3Nkay1jb3JlJztcbmltcG9ydCB7IEJhc2VDb2luIGFzIENvaW5Db25maWcgfSBmcm9tICdAYml0Z28vc3RhdGljcyc7XG5pbXBvcnQgQmlnTnVtYmVyIGZyb20gJ2JpZ251bWJlci5qcyc7XG5cbmltcG9ydCB7XG4gIERlbGVnYXRlT3JVbmRlbGVnZXRlTWVzc2FnZSxcbiAgRmVlRGF0YSxcbiAgTWVzc2FnZURhdGEsXG4gIFNlbmRNZXNzYWdlLFxuICBXaXRoZHJhd0RlbGVnYXRvclJld2FyZHNNZXNzYWdlLFxufSBmcm9tICcuL2lmYWNlJztcbmltcG9ydCB7IENvc21vc0tleVBhaXIgYXMgS2V5UGFpciB9IGZyb20gJy4va2V5UGFpcic7XG5pbXBvcnQgeyBDb3Ntb3NUcmFuc2FjdGlvbiB9IGZyb20gJy4vdHJhbnNhY3Rpb24nO1xuaW1wb3J0IHV0aWxzIGZyb20gJy4vdXRpbHMnO1xuXG5leHBvcnQgYWJzdHJhY3QgY2xhc3MgQ29zbW9zVHJhbnNhY3Rpb25CdWlsZGVyIGV4dGVuZHMgQmFzZVRyYW5zYWN0aW9uQnVpbGRlciB7XG4gIHByb3RlY3RlZCBfdHJhbnNhY3Rpb246IENvc21vc1RyYW5zYWN0aW9uO1xuICBwcm90ZWN0ZWQgX3NlcXVlbmNlOiBudW1iZXI7XG4gIHByb3RlY3RlZCBfbWVzc2FnZXM6IE1lc3NhZ2VEYXRhW107XG4gIHByb3RlY3RlZCBfZ2FzQnVkZ2V0OiBGZWVEYXRhO1xuICBwcm90ZWN0ZWQgX2FjY291bnROdW1iZXI/OiBudW1iZXI7XG4gIHByb3RlY3RlZCBfc2lnbmF0dXJlOiBCdWZmZXI7XG4gIHByb3RlY3RlZCBfY2hhaW5JZD86IHN0cmluZztcbiAgcHJvdGVjdGVkIF9wdWJsaWNLZXk/OiBzdHJpbmc7XG4gIHByb3RlY3RlZCBfc2lnbmVyOiBLZXlQYWlyO1xuICBwcm90ZWN0ZWQgX21lbW8/OiBzdHJpbmc7XG5cbiAgY29uc3RydWN0b3IoX2NvaW5Db25maWc6IFJlYWRvbmx5PENvaW5Db25maWc+KSB7XG4gICAgc3VwZXIoX2NvaW5Db25maWcpO1xuICB9XG5cbiAgLyoqXG4gICAqIFRoZSB0cmFuc2FjdGlvbiB0eXBlLlxuICAgKi9cbiAgcHJvdGVjdGVkIGFic3RyYWN0IGdldCB0cmFuc2FjdGlvblR5cGUoKTogVHJhbnNhY3Rpb25UeXBlO1xuXG4gIC8qKiBAaW5oZXJpdGRvYyAqL1xuICBwcm90ZWN0ZWQgZ2V0IHRyYW5zYWN0aW9uKCk6IENvc21vc1RyYW5zYWN0aW9uIHtcbiAgICByZXR1cm4gdGhpcy5fdHJhbnNhY3Rpb247XG4gIH1cblxuICAvKiogQGluaGVyaXRkb2MgKi9cbiAgcHJvdGVjdGVkIHNldCB0cmFuc2FjdGlvbih0cmFuc2FjdGlvbjogQ29zbW9zVHJhbnNhY3Rpb24pIHtcbiAgICB0aGlzLl90cmFuc2FjdGlvbiA9IHRyYW5zYWN0aW9uO1xuICB9XG5cbiAgLyoqIEBpbmhlcml0RG9jICovXG4gIGFkZFNpZ25hdHVyZShwdWJsaWNLZXk6IEJhc2VQdWJsaWNLZXksIHNpZ25hdHVyZTogQnVmZmVyKTogdm9pZCB7XG4gICAgdGhpcy5fc2lnbmF0dXJlID0gc2lnbmF0dXJlO1xuICAgIHRoaXMuX3B1YmxpY0tleSA9IHB1YmxpY0tleS5wdWI7XG4gIH1cblxuICAvKipcbiAgICogU2V0cyBzZXF1ZW5jZSBvZiB0aGlzIHRyYW5zYWN0aW9uLlxuICAgKiBAcGFyYW0ge251bWJlcn0gc2VxdWVuY2UgLSBzZXF1ZW5jZSBkYXRhIGZvciB0eCBzaWduZXJcbiAgICogQHJldHVybnMge1RyYW5zYWN0aW9uQnVpbGRlcn0gVGhpcyB0cmFuc2FjdGlvbiBidWlsZGVyXG4gICAqL1xuICBzZXF1ZW5jZShzZXF1ZW5jZTogbnVtYmVyKTogdGhpcyB7XG4gICAgdXRpbHMudmFsaWRhdGVTZXF1ZW5jZShzZXF1ZW5jZSk7XG4gICAgdGhpcy5fc2VxdWVuY2UgPSBzZXF1ZW5jZTtcbiAgICByZXR1cm4gdGhpcztcbiAgfVxuXG4gIC8qKlxuICAgKiBTZXRzIG1lc3NhZ2VzIHRvIHRoZSB0cmFuc2FjdGlvbiBib2R5LiBNZXNzYWdlIHR5cGUgd2lsbCBiZSBkaWZmZXJlbnQgYmFzZWQgb24gdGhlIHRyYW5zYWN0aW9uIHR5cGVcbiAgICogLSBGb3IgQHNlZSBUcmFuc2FjdGlvblR5cGUuU3Rha2luZ0FjdGl2YXRlIHJlcXVpcmVkIHR5cGUgaXMgQHNlZSBEZWxlZ2F0ZU9yVW5kZWxlZ2V0ZU1lc3NhZ2VcbiAgICogLSBGb3IgQHNlZSBUcmFuc2FjdGlvblR5cGUuU3Rha2luZ0RlYWN0aXZhdGUgcmVxdWlyZWQgdHlwZSBpcyBAc2VlIERlbGVnYXRlT3JVbmRlbGVnZXRlTWVzc2FnZVxuICAgKiAtIEZvciBAc2VlIFRyYW5zYWN0aW9uVHlwZS5TZW5kIHJlcXVpcmVkIHR5cGUgaXMgQHNlZSBTZW5kTWVzc2FnZVxuICAgKiAtIEZvciBAc2VlIFRyYW5zYWN0aW9uVHlwZS5TdGFraW5nV2l0aGRyYXcgcmVxdWlyZWQgdHlwZSBpcyBAc2VlIFdpdGhkcmF3RGVsZWdhdG9yUmV3YXJkc01lc3NhZ2VcbiAgICogQHBhcmFtIHsoU2VuZE1lc3NhZ2UgfCBEZWxlZ2F0ZU9yVW5kZWxlZ2V0ZU1lc3NhZ2UgfCBXaXRoZHJhd0RlbGVnYXRvclJld2FyZHNNZXNzYWdlKVtdfSBtZXNzYWdlc1xuICAgKiBAcmV0dXJucyB7VHJhbnNhY3Rpb25CdWlsZGVyfSBUaGlzIHRyYW5zYWN0aW9uIGJ1aWxkZXJcbiAgICovXG4gIGFic3RyYWN0IG1lc3NhZ2VzKG1lc3NhZ2VzOiAoU2VuZE1lc3NhZ2UgfCBEZWxlZ2F0ZU9yVW5kZWxlZ2V0ZU1lc3NhZ2UgfCBXaXRoZHJhd0RlbGVnYXRvclJld2FyZHNNZXNzYWdlKVtdKTogdGhpcztcblxuICBwdWJsaWNLZXkocHVibGljS2V5OiBzdHJpbmcgfCB1bmRlZmluZWQpOiB0aGlzIHtcbiAgICB0aGlzLl9wdWJsaWNLZXkgPSBwdWJsaWNLZXk7XG4gICAgcmV0dXJuIHRoaXM7XG4gIH1cblxuICBhY2NvdW50TnVtYmVyKGFjY291bnROdW1iZXI6IG51bWJlciB8IHVuZGVmaW5lZCk6IHRoaXMge1xuICAgIHRoaXMuX2FjY291bnROdW1iZXIgPSBhY2NvdW50TnVtYmVyO1xuICAgIHJldHVybiB0aGlzO1xuICB9XG5cbiAgY2hhaW5JZChjaGFpbklkOiBzdHJpbmcgfCB1bmRlZmluZWQpOiB0aGlzIHtcbiAgICB0aGlzLl9jaGFpbklkID0gY2hhaW5JZDtcbiAgICByZXR1cm4gdGhpcztcbiAgfVxuXG4gIG1lbW8obWVtbzogc3RyaW5nIHwgdW5kZWZpbmVkKTogdGhpcyB7XG4gICAgdGhpcy5fbWVtbyA9IG1lbW87XG4gICAgcmV0dXJuIHRoaXM7XG4gIH1cblxuICAvKiogQGluaGVyaXRkb2MgKi9cbiAgcHJvdGVjdGVkIHNpZ25JbXBsZW1lbnRhdGlvbihrZXk6IEJhc2VLZXkpOiBDb3Ntb3NUcmFuc2FjdGlvbiB7XG4gICAgdGhpcy52YWxpZGF0ZUtleShrZXkpO1xuICAgIGlmICh0aGlzLl9hY2NvdW50TnVtYmVyID09PSB1bmRlZmluZWQpIHtcbiAgICAgIHRocm93IG5ldyBTaWduaW5nRXJyb3IoJ2FjY291bnROdW1iZXIgaXMgcmVxdWlyZWQgYmVmb3JlIHNpZ25pbmcnKTtcbiAgICB9XG4gICAgaWYgKHRoaXMuX2NoYWluSWQgPT09IHVuZGVmaW5lZCkge1xuICAgICAgdGhyb3cgbmV3IFNpZ25pbmdFcnJvcignY2hhaW5JZCBpcyByZXF1aXJlZCBiZWZvcmUgc2lnbmluZycpO1xuICAgIH1cbiAgICB0aGlzLl9zaWduZXIgPSBuZXcgS2V5UGFpcih7IHBydjoga2V5LmtleSB9KTtcbiAgICB0aGlzLl9wdWJsaWNLZXkgPSB0aGlzLl9zaWduZXIuZ2V0S2V5cygpLnB1YjtcbiAgICByZXR1cm4gdGhpcy50cmFuc2FjdGlvbjtcbiAgfVxuXG4gIC8qKiBAaW5oZXJpdGRvYyAqL1xuICB2YWxpZGF0ZVZhbHVlKHZhbHVlOiBCaWdOdW1iZXIpOiB2b2lkIHtcbiAgICBpZiAodmFsdWUuaXNMZXNzVGhhbigwKSkge1xuICAgICAgdGhyb3cgbmV3IEJ1aWxkVHJhbnNhY3Rpb25FcnJvcignVmFsdWUgY2Fubm90IGJlIGxlc3MgdGhhbiB6ZXJvJyk7XG4gICAgfVxuICB9XG5cbiAgLyoqIEBpbmhlcml0ZG9jICovXG4gIHZhbGlkYXRlS2V5KGtleTogQmFzZUtleSk6IHZvaWQge1xuICAgIHRyeSB7XG4gICAgICBuZXcgS2V5UGFpcih7IHBydjoga2V5LmtleSB9KTtcbiAgICB9IGNhdGNoIHtcbiAgICAgIHRocm93IG5ldyBCdWlsZFRyYW5zYWN0aW9uRXJyb3IoYEtleSB2YWxpZGF0aW9uIGZhaWxlZGApO1xuICAgIH1cbiAgfVxufVxuIl19
@@ -0,0 +1,144 @@
1
+ import { BaseUtils, TransactionType } from '@bitgo/sdk-core';
2
+ import { DecodedTxRaw } from '@cosmjs/proto-signing';
3
+ import { SignDoc, TxRaw } from 'cosmjs-types/cosmos/tx/v1beta1/tx';
4
+ import { CosmosLikeTransaction, FeeData, MessageData } from './iface';
5
+ export declare class CosmosLikeUtils implements BaseUtils {
6
+ private registry;
7
+ /** @inheritdoc */
8
+ isValidBlockId(hash: string): boolean;
9
+ /** @inheritdoc */
10
+ isValidPrivateKey(key: string): boolean;
11
+ /** @inheritdoc */
12
+ isValidPublicKey(key: string): boolean;
13
+ /** @inheritdoc */
14
+ isValidSignature(signature: string): boolean;
15
+ /** @inheritdoc */
16
+ isValidTransactionId(txId: string): boolean;
17
+ /**
18
+ * Checks if transaction hash is in valid black2b format
19
+ */
20
+ validateBlake2b(hash: string): boolean;
21
+ /**
22
+ * Validates whether amounts are in range
23
+ *
24
+ * @param {number[]} amounts - the amounts to validate
25
+ * @returns {boolean} - the validation result
26
+ */
27
+ isValidAmounts(amounts: number[]): boolean;
28
+ /**
29
+ * Validates whether amount is in range
30
+ * @param {number} amount
31
+ * @returns {boolean} the validation result
32
+ */
33
+ isValidAmount(amount: number): boolean;
34
+ /**
35
+ * Decodes raw tx data into messages, signing info, and fee data
36
+ * @param {string} txHex - raw base64 tx
37
+ * @returns {DecodedTxRaw} Decoded transaction
38
+ */
39
+ getDecodedTxFromRawBase64(txRaw: string): DecodedTxRaw;
40
+ /**
41
+ * Returns the array of messages in the body of the decoded transaction
42
+ * @param {DecodedTxRaw} decodedTx
43
+ * @returns {EncodeObject[]} messages along with type url
44
+ */
45
+ private getEncodedMessagesFromDecodedTx;
46
+ validateSequence(sequence: number): void;
47
+ /**
48
+ * Pulls the sequence number from a DecodedTxRaw AuthInfo property
49
+ * @param {DecodedTxRaw} decodedTx
50
+ * @returns {number} sequence
51
+ */
52
+ getSequenceFromDecodedTx(decodedTx: DecodedTxRaw): number;
53
+ /**
54
+ * Pulls the typeUrl from the encoded message of a DecodedTxRaw
55
+ * @param {DecodedTxRaw} decodedTx
56
+ * @returns {string} osmosis proto type url
57
+ */
58
+ getTypeUrlFromDecodedTx(decodedTx: DecodedTxRaw): string;
59
+ /**
60
+ * Returns the fee data from the decoded transaction
61
+ * @param {DecodedTxRaw} decodedTx
62
+ * @returns {FeeData} fee data
63
+ */
64
+ getGasBudgetFromDecodedTx(decodedTx: DecodedTxRaw): FeeData;
65
+ /**
66
+ * Returns the publicKey from the decoded transaction
67
+ * @param {DecodedTxRaw} decodedTx
68
+ * @returns {string | undefined} publicKey in hex format if it exists, undefined otherwise
69
+ */
70
+ getPublicKeyFromDecodedTx(decodedTx: DecodedTxRaw): string | undefined;
71
+ /**
72
+ * Returns the array of MessageData[] from the decoded transaction
73
+ * @param {DecodedTxRaw} decodedTx
74
+ * @returns {MessageData[]} Send transaction message data
75
+ */
76
+ protected getSendMessageDataFromDecodedTx(decodedTx: DecodedTxRaw): MessageData[];
77
+ /**
78
+ * Returns the array of MessageData[] from the decoded transaction
79
+ * @param {DecodedTxRaw} decodedTx
80
+ * @returns {MessageData[]} Delegate of undelegate transaction message data
81
+ */
82
+ getDelegateOrUndelegateMessageDataFromDecodedTx(decodedTx: DecodedTxRaw): MessageData[];
83
+ /**
84
+ * Returns the array of MessageData[] from the decoded transaction
85
+ * @param {DecodedTxRaw} decodedTx
86
+ * @returns {MessageData[]} WithdrawDelegatorRewards transaction message data
87
+ */
88
+ getWithdrawRewardsMessageDataFromDecodedTx(decodedTx: DecodedTxRaw): MessageData[];
89
+ /**
90
+ * Returns the array of MessageData[] from the decoded transaction
91
+ * @param {DecodedTxRaw} decodedTx
92
+ * @returns {MessageData[]} Delegate of undelegate transaction message data
93
+ */
94
+ getWithdrawDelegatorRewardsMessageDataFromDecodedTx(decodedTx: DecodedTxRaw): MessageData[];
95
+ /**
96
+ * Determines bitgo transaction type based on osmosis proto type url
97
+ * @param {string} typeUrl
98
+ * @returns {TransactionType | undefined} TransactionType if url is supported else undefined
99
+ */
100
+ getTransactionTypeFromTypeUrl(typeUrl: string): TransactionType | undefined;
101
+ /**
102
+ * Creates a txRaw from an cosmos like transaction @see CosmosLikeTransaction
103
+ * @Precondition cosmosLikeTransaction.publicKey must be defined
104
+ * @param {CosmosLikeTransaction} cosmosLikeTransaction
105
+ * @returns {TxRaw} Unsigned raw transaction
106
+ */
107
+ createTxRawFromCosmosLikeTransaction(cosmosLikeTransaction: CosmosLikeTransaction): TxRaw;
108
+ /**
109
+ * Encodes a signature into a txRaw
110
+ * @param {string} publicKeyHex publicKey in hex encoded string format
111
+ * @param {string} signatureHex signature in hex encoded string format
112
+ * @param {TxRaw} unsignedTx raw transaction
113
+ * @returns {TxRaw} Signed raw transaction
114
+ */
115
+ createSignedTxRaw(publicKeyHex: string, signatureHex: string, unsignedTx: {
116
+ bodyBytes: Uint8Array;
117
+ authInfoBytes: Uint8Array;
118
+ }): TxRaw;
119
+ /**
120
+ * Decodes a raw transaction into a DecodedTxRaw and checks if it has non empty signatures
121
+ * @param {string} rawTransaction
122
+ * @returns {boolean} true if transaction is signed else false
123
+ */
124
+ isSignedRawTx(rawTransaction: string): boolean;
125
+ validatePublicKey(publicKey: string | undefined): void;
126
+ /**
127
+ * Validates if the address matches with regex @see accountAddressRegex
128
+ *
129
+ * @param {string} address
130
+ * @returns {boolean} - the validation result
131
+ */
132
+ isValidAddress(address: string): boolean;
133
+ /**
134
+ * Creates a sign doc from an cosmos like transaction @see CosmosLikeTransaction
135
+ * @Precondition cosmosLikeTransaction.accountNumber and cosmosLikeTransaction.chainId must be defined
136
+ * @param {CosmosLikeTransaction} cosmosLikeTransaction
137
+ * @returns {SignDoc} sign doc
138
+ */
139
+ createSignDoc(cosmosLikeTransaction: CosmosLikeTransaction, accountNumber: number | undefined, chainId: string | undefined): SignDoc;
140
+ isValidHexString(hexString: string): boolean;
141
+ }
142
+ declare const utils: CosmosLikeUtils;
143
+ export default utils;
144
+ //# sourceMappingURL=utils.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"utils.d.ts","sourceRoot":"","sources":["../../../src/lib/utils.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,SAAS,EAIT,eAAe,EAChB,MAAM,iBAAiB,CAAC;AAGzB,OAAO,EACL,YAAY,EAQb,MAAM,uBAAuB,CAAC;AAG/B,OAAO,EAAE,OAAO,EAAE,KAAK,EAAE,MAAM,mCAAmC,CAAC;AAInE,OAAO,EAAE,qBAAqB,EAAE,OAAO,EAAE,WAAW,EAAE,MAAM,SAAS,CAAC;AAGtE,qBAAa,eAAgB,YAAW,SAAS;IAC/C,OAAO,CAAC,QAAQ,CAA2C;IAE3D,kBAAkB;IAClB,cAAc,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO;IAIrC,kBAAkB;IAClB,iBAAiB,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO;IASvC,kBAAkB;IAClB,gBAAgB,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO;IAStC,kBAAkB;IAClB,gBAAgB,CAAC,SAAS,EAAE,MAAM,GAAG,OAAO;IAI5C,kBAAkB;IAClB,oBAAoB,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO;IAI3C;;OAEG;IACH,eAAe,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO;IAOtC;;;;;OAKG;IACH,cAAc,CAAC,OAAO,EAAE,MAAM,EAAE,GAAG,OAAO;IAS1C;;;;OAIG;IACH,aAAa,CAAC,MAAM,EAAE,MAAM,GAAG,OAAO;IAQtC;;;;OAIG;IACH,yBAAyB,CAAC,KAAK,EAAE,MAAM,GAAG,YAAY;IAQtD;;;;OAIG;IACH,OAAO,CAAC,+BAA+B;IAIvC,gBAAgB,CAAC,QAAQ,EAAE,MAAM;IAMjC;;;;OAIG;IACH,wBAAwB,CAAC,SAAS,EAAE,YAAY,GAAG,MAAM;IAIzD;;;;OAIG;IACH,uBAAuB,CAAC,SAAS,EAAE,YAAY,GAAG,MAAM;IAKxD;;;;OAIG;IACH,yBAAyB,CAAC,SAAS,EAAE,YAAY,GAAG,OAAO;IAO3D;;;;OAIG;IACH,yBAAyB,CAAC,SAAS,EAAE,YAAY,GAAG,MAAM,GAAG,SAAS;IAQtE;;;;OAIG;IACH,SAAS,CAAC,+BAA+B,CAAC,SAAS,EAAE,YAAY,GAAG,WAAW,EAAE;IAcjF;;;;OAIG;IACH,+CAA+C,CAAC,SAAS,EAAE,YAAY,GAAG,WAAW,EAAE;IAcvF;;;;OAIG;IACH,0CAA0C,CAAC,SAAS,EAAE,YAAY,GAAG,WAAW,EAAE;IAalF;;;;OAIG;IACH,mDAAmD,CAAC,SAAS,EAAE,YAAY,GAAG,WAAW,EAAE;IAa3F;;;;OAIG;IACH,6BAA6B,CAAC,OAAO,EAAE,MAAM,GAAG,eAAe,GAAG,SAAS;IAe3E;;;;;OAKG;IACH,oCAAoC,CAAC,qBAAqB,EAAE,qBAAqB,GAAG,KAAK;IAkCzF;;;;;;OAMG;IACH,iBAAiB,CACf,YAAY,EAAE,MAAM,EACpB,YAAY,EAAE,MAAM,EACpB,UAAU,EAAE;QAAE,SAAS,EAAE,UAAU,CAAC;QAAC,aAAa,EAAE,UAAU,CAAA;KAAE,GAC/D,KAAK;IASR;;;;OAIG;IACH,aAAa,CAAC,cAAc,EAAE,MAAM,GAAG,OAAO;IAQ9C,iBAAiB,CAAC,SAAS,EAAE,MAAM,GAAG,SAAS;IAU/C;;;;;OAKG;IACH,cAAc,CAAC,OAAO,EAAE,MAAM,GAAG,OAAO;IAIxC;;;;;OAKG;IACH,aAAa,CACX,qBAAqB,EAAE,qBAAqB,EAC5C,aAAa,EAAE,MAAM,GAAG,SAAS,EACjC,OAAO,EAAE,MAAM,GAAG,SAAS,GAC1B,OAAO;IAcV,gBAAgB,CAAC,SAAS,EAAE,MAAM,GAAG,OAAO;CAG7C;AAED,QAAA,MAAM,KAAK,iBAAwB,CAAC;AAEpC,eAAe,KAAK,CAAC"}
@@ -0,0 +1,345 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.CosmosLikeUtils = void 0;
4
+ const sdk_core_1 = require("@bitgo/sdk-core");
5
+ const amino_1 = require("@cosmjs/amino");
6
+ const encoding_1 = require("@cosmjs/encoding");
7
+ const proto_signing_1 = require("@cosmjs/proto-signing");
8
+ const stargate_1 = require("@cosmjs/stargate");
9
+ const bignumber_js_1 = require("bignumber.js");
10
+ const tx_1 = require("cosmjs-types/cosmos/tx/v1beta1/tx");
11
+ const constants = require("./constants");
12
+ const keyPair_1 = require("./keyPair");
13
+ class CosmosLikeUtils {
14
+ constructor() {
15
+ this.registry = new proto_signing_1.Registry([...stargate_1.defaultRegistryTypes]);
16
+ }
17
+ /** @inheritdoc */
18
+ isValidBlockId(hash) {
19
+ return this.validateBlake2b(hash);
20
+ }
21
+ /** @inheritdoc */
22
+ isValidPrivateKey(key) {
23
+ try {
24
+ new keyPair_1.CosmosKeyPair({ prv: key });
25
+ return true;
26
+ }
27
+ catch {
28
+ return false;
29
+ }
30
+ }
31
+ /** @inheritdoc */
32
+ isValidPublicKey(key) {
33
+ try {
34
+ new keyPair_1.CosmosKeyPair({ pub: key });
35
+ return true;
36
+ }
37
+ catch {
38
+ return false;
39
+ }
40
+ }
41
+ /** @inheritdoc */
42
+ isValidSignature(signature) {
43
+ throw new sdk_core_1.NotImplementedError('isValidSignature not implemented');
44
+ }
45
+ /** @inheritdoc */
46
+ isValidTransactionId(txId) {
47
+ return this.validateBlake2b(txId);
48
+ }
49
+ /**
50
+ * Checks if transaction hash is in valid black2b format
51
+ */
52
+ validateBlake2b(hash) {
53
+ if ((hash === null || hash === void 0 ? void 0 : hash.length) !== 64) {
54
+ return false;
55
+ }
56
+ return hash.match(/^[a-zA-Z0-9]+$/) !== null;
57
+ }
58
+ /**
59
+ * Validates whether amounts are in range
60
+ *
61
+ * @param {number[]} amounts - the amounts to validate
62
+ * @returns {boolean} - the validation result
63
+ */
64
+ isValidAmounts(amounts) {
65
+ for (const amount of amounts) {
66
+ if (!this.isValidAmount(amount)) {
67
+ return false;
68
+ }
69
+ }
70
+ return true;
71
+ }
72
+ /**
73
+ * Validates whether amount is in range
74
+ * @param {number} amount
75
+ * @returns {boolean} the validation result
76
+ */
77
+ isValidAmount(amount) {
78
+ const bigNumberAmount = new bignumber_js_1.default(amount);
79
+ if (!bigNumberAmount.isInteger() || bigNumberAmount.isLessThanOrEqualTo(0)) {
80
+ return false;
81
+ }
82
+ return true;
83
+ }
84
+ /**
85
+ * Decodes raw tx data into messages, signing info, and fee data
86
+ * @param {string} txHex - raw base64 tx
87
+ * @returns {DecodedTxRaw} Decoded transaction
88
+ */
89
+ getDecodedTxFromRawBase64(txRaw) {
90
+ try {
91
+ return proto_signing_1.decodeTxRaw(encoding_1.fromBase64(txRaw));
92
+ }
93
+ catch (e) {
94
+ throw new sdk_core_1.ParseTransactionError('Error decoding TxRaw base64 encoded string: ' + e.message);
95
+ }
96
+ }
97
+ /**
98
+ * Returns the array of messages in the body of the decoded transaction
99
+ * @param {DecodedTxRaw} decodedTx
100
+ * @returns {EncodeObject[]} messages along with type url
101
+ */
102
+ getEncodedMessagesFromDecodedTx(decodedTx) {
103
+ return decodedTx.body.messages;
104
+ }
105
+ validateSequence(sequence) {
106
+ if (sequence < 0) {
107
+ throw new sdk_core_1.InvalidTransactionError('Invalid sequence: less than zero');
108
+ }
109
+ }
110
+ /**
111
+ * Pulls the sequence number from a DecodedTxRaw AuthInfo property
112
+ * @param {DecodedTxRaw} decodedTx
113
+ * @returns {number} sequence
114
+ */
115
+ getSequenceFromDecodedTx(decodedTx) {
116
+ return Number(decodedTx.authInfo.signerInfos[0].sequence);
117
+ }
118
+ /**
119
+ * Pulls the typeUrl from the encoded message of a DecodedTxRaw
120
+ * @param {DecodedTxRaw} decodedTx
121
+ * @returns {string} osmosis proto type url
122
+ */
123
+ getTypeUrlFromDecodedTx(decodedTx) {
124
+ const encodedMessage = this.getEncodedMessagesFromDecodedTx(decodedTx)[0];
125
+ return encodedMessage.typeUrl;
126
+ }
127
+ /**
128
+ * Returns the fee data from the decoded transaction
129
+ * @param {DecodedTxRaw} decodedTx
130
+ * @returns {FeeData} fee data
131
+ */
132
+ getGasBudgetFromDecodedTx(decodedTx) {
133
+ var _a, _b;
134
+ return {
135
+ amount: (_a = decodedTx.authInfo.fee) === null || _a === void 0 ? void 0 : _a.amount,
136
+ gasLimit: Number((_b = decodedTx.authInfo.fee) === null || _b === void 0 ? void 0 : _b.gasLimit),
137
+ };
138
+ }
139
+ /**
140
+ * Returns the publicKey from the decoded transaction
141
+ * @param {DecodedTxRaw} decodedTx
142
+ * @returns {string | undefined} publicKey in hex format if it exists, undefined otherwise
143
+ */
144
+ getPublicKeyFromDecodedTx(decodedTx) {
145
+ var _a, _b, _c, _d;
146
+ const publicKeyUInt8Array = (_b = (_a = decodedTx.authInfo.signerInfos) === null || _a === void 0 ? void 0 : _a[0].publicKey) === null || _b === void 0 ? void 0 : _b.value;
147
+ if (publicKeyUInt8Array) {
148
+ return encoding_1.toHex(encoding_1.fromBase64((_d = proto_signing_1.decodePubkey((_c = decodedTx.authInfo.signerInfos) === null || _c === void 0 ? void 0 : _c[0].publicKey)) === null || _d === void 0 ? void 0 : _d.value));
149
+ }
150
+ return undefined;
151
+ }
152
+ /**
153
+ * Returns the array of MessageData[] from the decoded transaction
154
+ * @param {DecodedTxRaw} decodedTx
155
+ * @returns {MessageData[]} Send transaction message data
156
+ */
157
+ getSendMessageDataFromDecodedTx(decodedTx) {
158
+ return decodedTx.body.messages.map((message) => {
159
+ const value = this.registry.decode(message);
160
+ return {
161
+ value: {
162
+ fromAddress: value.fromAddress,
163
+ toAddress: value.toAddress,
164
+ amount: value.amount,
165
+ },
166
+ typeUrl: message.typeUrl,
167
+ };
168
+ });
169
+ }
170
+ /**
171
+ * Returns the array of MessageData[] from the decoded transaction
172
+ * @param {DecodedTxRaw} decodedTx
173
+ * @returns {MessageData[]} Delegate of undelegate transaction message data
174
+ */
175
+ getDelegateOrUndelegateMessageDataFromDecodedTx(decodedTx) {
176
+ return decodedTx.body.messages.map((message) => {
177
+ const value = this.registry.decode(message);
178
+ return {
179
+ value: {
180
+ delegatorAddress: value.delegatorAddress,
181
+ validatorAddress: value.validatorAddress,
182
+ amount: value.amount,
183
+ },
184
+ typeUrl: message.typeUrl,
185
+ };
186
+ });
187
+ }
188
+ /**
189
+ * Returns the array of MessageData[] from the decoded transaction
190
+ * @param {DecodedTxRaw} decodedTx
191
+ * @returns {MessageData[]} WithdrawDelegatorRewards transaction message data
192
+ */
193
+ getWithdrawRewardsMessageDataFromDecodedTx(decodedTx) {
194
+ return decodedTx.body.messages.map((message) => {
195
+ const value = this.registry.decode(message);
196
+ return {
197
+ value: {
198
+ delegatorAddress: value.delegatorAddress,
199
+ validatorAddress: value.validatorAddress,
200
+ },
201
+ typeUrl: message.typeUrl,
202
+ };
203
+ });
204
+ }
205
+ /**
206
+ * Returns the array of MessageData[] from the decoded transaction
207
+ * @param {DecodedTxRaw} decodedTx
208
+ * @returns {MessageData[]} Delegate of undelegate transaction message data
209
+ */
210
+ getWithdrawDelegatorRewardsMessageDataFromDecodedTx(decodedTx) {
211
+ return decodedTx.body.messages.map((message) => {
212
+ const value = this.registry.decode(message);
213
+ return {
214
+ value: {
215
+ delegatorAddress: value.delegatorAddress,
216
+ validatorAddress: value.validatorAddress,
217
+ },
218
+ typeUrl: message.typeUrl,
219
+ };
220
+ });
221
+ }
222
+ /**
223
+ * Determines bitgo transaction type based on osmosis proto type url
224
+ * @param {string} typeUrl
225
+ * @returns {TransactionType | undefined} TransactionType if url is supported else undefined
226
+ */
227
+ getTransactionTypeFromTypeUrl(typeUrl) {
228
+ switch (typeUrl) {
229
+ case constants.sendMsgTypeUrl:
230
+ return sdk_core_1.TransactionType.Send;
231
+ case constants.delegateMsgTypeUrl:
232
+ return sdk_core_1.TransactionType.StakingActivate;
233
+ case constants.undelegateMsgTypeUrl:
234
+ return sdk_core_1.TransactionType.StakingDeactivate;
235
+ case constants.withdrawDelegatorRewardMsgTypeUrl:
236
+ return sdk_core_1.TransactionType.StakingWithdraw;
237
+ default:
238
+ return undefined;
239
+ }
240
+ }
241
+ /**
242
+ * Creates a txRaw from an cosmos like transaction @see CosmosLikeTransaction
243
+ * @Precondition cosmosLikeTransaction.publicKey must be defined
244
+ * @param {CosmosLikeTransaction} cosmosLikeTransaction
245
+ * @returns {TxRaw} Unsigned raw transaction
246
+ */
247
+ createTxRawFromCosmosLikeTransaction(cosmosLikeTransaction) {
248
+ if (!cosmosLikeTransaction.publicKey) {
249
+ throw new Error('publicKey is required to create a txRaw');
250
+ }
251
+ const encodedPublicKey = proto_signing_1.encodePubkey(amino_1.encodeSecp256k1Pubkey(encoding_1.fromHex(cosmosLikeTransaction.publicKey)));
252
+ const messages = cosmosLikeTransaction.sendMessages;
253
+ let txBodyValue;
254
+ if (cosmosLikeTransaction.memo) {
255
+ txBodyValue = {
256
+ memo: cosmosLikeTransaction.memo,
257
+ messages: messages,
258
+ };
259
+ }
260
+ else {
261
+ txBodyValue = {
262
+ messages: messages,
263
+ };
264
+ }
265
+ const txBodyBytes = this.registry.encodeTxBody(txBodyValue);
266
+ const sequence = cosmosLikeTransaction.sequence;
267
+ const authInfoBytes = proto_signing_1.makeAuthInfoBytes([{ pubkey: encodedPublicKey, sequence }], cosmosLikeTransaction.gasBudget.amount, cosmosLikeTransaction.gasBudget.gasLimit, undefined, undefined, undefined);
268
+ return tx_1.TxRaw.fromPartial({
269
+ bodyBytes: txBodyBytes,
270
+ authInfoBytes: authInfoBytes,
271
+ });
272
+ }
273
+ /**
274
+ * Encodes a signature into a txRaw
275
+ * @param {string} publicKeyHex publicKey in hex encoded string format
276
+ * @param {string} signatureHex signature in hex encoded string format
277
+ * @param {TxRaw} unsignedTx raw transaction
278
+ * @returns {TxRaw} Signed raw transaction
279
+ */
280
+ createSignedTxRaw(publicKeyHex, signatureHex, unsignedTx) {
281
+ const stdSignature = amino_1.encodeSecp256k1Signature(encoding_1.fromHex(publicKeyHex), encoding_1.fromHex(signatureHex));
282
+ return tx_1.TxRaw.fromPartial({
283
+ bodyBytes: unsignedTx.bodyBytes,
284
+ authInfoBytes: unsignedTx.authInfoBytes,
285
+ signatures: [encoding_1.fromBase64(stdSignature.signature)],
286
+ });
287
+ }
288
+ /**
289
+ * Decodes a raw transaction into a DecodedTxRaw and checks if it has non empty signatures
290
+ * @param {string} rawTransaction
291
+ * @returns {boolean} true if transaction is signed else false
292
+ */
293
+ isSignedRawTx(rawTransaction) {
294
+ const decodedTx = this.getDecodedTxFromRawBase64(rawTransaction);
295
+ if (decodedTx.signatures.length > 0) {
296
+ return true;
297
+ }
298
+ return false;
299
+ }
300
+ validatePublicKey(publicKey) {
301
+ if (publicKey !== undefined) {
302
+ try {
303
+ new keyPair_1.CosmosKeyPair({ pub: publicKey });
304
+ }
305
+ catch {
306
+ throw new sdk_core_1.InvalidTransactionError(`Key validation failed`);
307
+ }
308
+ }
309
+ }
310
+ /**
311
+ * Validates if the address matches with regex @see accountAddressRegex
312
+ *
313
+ * @param {string} address
314
+ * @returns {boolean} - the validation result
315
+ */
316
+ isValidAddress(address) {
317
+ throw new sdk_core_1.NotImplementedError('isValidAddress not implemented');
318
+ }
319
+ /**
320
+ * Creates a sign doc from an cosmos like transaction @see CosmosLikeTransaction
321
+ * @Precondition cosmosLikeTransaction.accountNumber and cosmosLikeTransaction.chainId must be defined
322
+ * @param {CosmosLikeTransaction} cosmosLikeTransaction
323
+ * @returns {SignDoc} sign doc
324
+ */
325
+ createSignDoc(cosmosLikeTransaction, accountNumber, chainId) {
326
+ if (!accountNumber) {
327
+ throw new Error('accountNumber is required to create a sign doc');
328
+ }
329
+ if (!chainId) {
330
+ throw new Error('chainId is required to create a sign doc');
331
+ }
332
+ if (!cosmosLikeTransaction) {
333
+ throw new Error('cosmosLikeTransaction is required to create a sign doc');
334
+ }
335
+ const txRaw = utils.createTxRawFromCosmosLikeTransaction(cosmosLikeTransaction);
336
+ return proto_signing_1.makeSignDoc(txRaw.bodyBytes, txRaw.authInfoBytes, chainId, accountNumber);
337
+ }
338
+ isValidHexString(hexString) {
339
+ return /^[0-9A-Fa-f]*$/.test(hexString);
340
+ }
341
+ }
342
+ exports.CosmosLikeUtils = CosmosLikeUtils;
343
+ const utils = new CosmosLikeUtils();
344
+ exports.default = utils;
345
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoidXRpbHMuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi9zcmMvbGliL3V0aWxzLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiI7OztBQUFBLDhDQU15QjtBQUN6Qix5Q0FBZ0Y7QUFDaEYsK0NBQThEO0FBQzlELHlEQVMrQjtBQUMvQiwrQ0FBOEQ7QUFDOUQsK0NBQXFDO0FBQ3JDLDBEQUFtRTtBQUduRSx5Q0FBeUM7QUFFekMsdUNBQXFEO0FBRXJELE1BQWEsZUFBZTtJQUE1QjtRQUNVLGFBQVEsR0FBRyxJQUFJLHdCQUFRLENBQUMsQ0FBQyxHQUFHLCtCQUFvQixDQUFDLENBQUMsQ0FBQztJQXlXN0QsQ0FBQztJQXZXQyxrQkFBa0I7SUFDbEIsY0FBYyxDQUFDLElBQVk7UUFDekIsT0FBTyxJQUFJLENBQUMsZUFBZSxDQUFDLElBQUksQ0FBQyxDQUFDO0lBQ3BDLENBQUM7SUFFRCxrQkFBa0I7SUFDbEIsaUJBQWlCLENBQUMsR0FBVztRQUMzQixJQUFJO1lBQ0YsSUFBSSx1QkFBTyxDQUFDLEVBQUUsR0FBRyxFQUFFLEdBQUcsRUFBRSxDQUFDLENBQUM7WUFDMUIsT0FBTyxJQUFJLENBQUM7U0FDYjtRQUFDLE1BQU07WUFDTixPQUFPLEtBQUssQ0FBQztTQUNkO0lBQ0gsQ0FBQztJQUVELGtCQUFrQjtJQUNsQixnQkFBZ0IsQ0FBQyxHQUFXO1FBQzFCLElBQUk7WUFDRixJQUFJLHVCQUFPLENBQUMsRUFBRSxHQUFHLEVBQUUsR0FBRyxFQUFFLENBQUMsQ0FBQztZQUMxQixPQUFPLElBQUksQ0FBQztTQUNiO1FBQUMsTUFBTTtZQUNOLE9BQU8sS0FBSyxDQUFDO1NBQ2Q7SUFDSCxDQUFDO0lBRUQsa0JBQWtCO0lBQ2xCLGdCQUFnQixDQUFDLFNBQWlCO1FBQ2hDLE1BQU0sSUFBSSw4QkFBbUIsQ0FBQyxrQ0FBa0MsQ0FBQyxDQUFDO0lBQ3BFLENBQUM7SUFFRCxrQkFBa0I7SUFDbEIsb0JBQW9CLENBQUMsSUFBWTtRQUMvQixPQUFP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QWEsRUFBRTtZQUNsQixNQUFNLElBQUksS0FBSyxDQUFDLGdEQUFnRCxDQUFDLENBQUM7U0FDbkU7UUFDRCxJQUFJLENBQUMsT0FBTyxFQUFFO1lBQ1osTUFBTSxJQUFJLEtBQUssQ0FBQywwQ0FBMEMsQ0FBQyxDQUFDO1NBQzdEO1FBQ0QsSUFBSSxDQUFDLHFCQUFxQixFQUFFO1lBQzFCLE1BQU0sSUFBSSxLQUFLLENBQUMsd0RBQXdELENBQUMsQ0FBQztTQUMzRTtRQUNELE1BQU0sS0FBSyxHQUFHLEtBQUssQ0FBQyxvQ0FBb0MsQ0FBQyxxQkFBcUIsQ0FBQyxDQUFDO1FBQ2hGLE9BQU8sMkJBQVcsQ0FBQyxLQUFLLENBQUMsU0FBUyxFQUFFLEtBQUssQ0FBQyxhQUFhLEVBQUUsT0FBTyxFQUFFLGFBQWEsQ0FBQyxDQUFDO0lBQ25GLENBQUM7SUFFRCxnQkFBZ0IsQ0FBQyxTQUFpQjtRQUNoQyxPQUFPLGdCQUFnQixDQUFDLElBQUksQ0FBQyxTQUFTLENBQUMsQ0FBQztJQUMxQyxDQUFDO0NBQ0Y7QUExV0QsMENBMFdDO0FBRUQsTUFBTSxLQUFLLEdBQUcsSUFBSSxlQUFlLEVBQUUsQ0FBQztBQUVwQyxrQkFBZSxLQUFLLENBQUMiLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQge1xuICBCYXNlVXRpbHMsXG4gIEludmFsaWRUcmFuc2FjdGlvbkVycm9yLFxuICBOb3RJbXBsZW1lbnRlZEVycm9yLFxuICBQYXJzZVRyYW5zYWN0aW9uRXJyb3IsXG4gIFRyYW5zYWN0aW9uVHlwZSxcbn0gZnJvbSAnQGJpdGdvL3Nkay1jb3JlJztcbmltcG9ydCB7IGVuY29kZVNlY3AyNTZrMVB1YmtleSwgZW5jb2RlU2VjcDI1NmsxU2lnbmF0dXJlIH0gZnJvbSAnQGNvc21qcy9hbWlubyc7XG5pbXBvcnQgeyBmcm9tQmFzZTY0LCBmcm9tSGV4LCB0b0hleCB9IGZyb20gJ0Bjb3NtanMvZW5jb2RpbmcnO1xuaW1wb3J0IHtcbiAgRGVjb2RlZFR4UmF3LFxuICBkZWNvZGVQdWJrZXksXG4gIGRlY29kZVR4UmF3LFxuICBFbmNvZGVPYmplY3QsXG4gIGVuY29kZVB1YmtleSxcbiAgbWFrZUF1dGhJbmZvQnl0ZXMsXG4gIG1ha2VTaWduRG9jLFxuICBSZWdpc3RyeSxcbn0gZnJvbSAnQGNvc21qcy9wcm90by1zaWduaW5nJztcbmltcG9ydCB7IENvaW4sIGRlZmF1bHRSZWdpc3RyeVR5cGVzIH0gZnJvbSAnQGNvc21qcy9zdGFyZ2F0ZSc7XG5pbXBvcnQgQmlnTnVtYmVyIGZyb20gJ2JpZ251bWJlci5qcyc7XG5pbXBvcnQgeyBTaWduRG9jLCBUeFJhdyB9IGZyb20gJ2Nvc21qcy10eXBlcy9jb3Ntb3MvdHgvdjFiZXRhMS90eCc7XG5pbXBvcnQgeyBBbnkgfSBmcm9tICdjb3NtanMtdHlwZXMvZ29vZ2xlL3Byb3RvYnVmL2FueSc7XG5cbmltcG9ydCAqIGFzIGNvbnN0YW50cyBmcm9tICcuL2NvbnN0YW50cyc7XG5pbXBvcnQgeyBDb3Ntb3NMaWtlVHJhbnNhY3Rpb24sIEZlZURhdGEsIE1lc3NhZ2VEYXRhIH0gZnJvbSAnLi9pZmFjZSc7XG5pbXBvcnQgeyBDb3Ntb3NLZXlQYWlyIGFzIEtleVBhaXIgfSBmcm9tICcuL2tleVBhaXInO1xuXG5leHBvcnQgY2xhc3MgQ29zbW9zTGlrZVV0aWxzIGltcGxlbWVudHMgQmFzZVV0aWxzIHtcbiAgcHJpdmF0ZSByZWdpc3RyeSA9IG5ldyBSZWdpc3RyeShbLi4uZGVmYXVsdFJlZ2lzdHJ5VHlwZXNdKTtcblxuICAvKiogQGluaGVyaXRkb2MgKi9cbiAgaXNWYWxpZEJsb2NrSWQoaGFzaDogc3RyaW5nKTogYm9vbGVhbiB7XG4gICAgcmV0dXJuIHRoaXMudmFsaWRhdGVCbGFrZTJiKGhhc2gpO1xuICB9XG5cbiAgLyoqIEBpbmhlcml0ZG9jICovXG4gIGlzVmFsaWRQcml2YXRlS2V5KGtleTogc3RyaW5nKTogYm9vbGVhbiB7XG4gICAgdHJ5IHtcbiAgICAgIG5ldyBLZXlQYWlyKHsgcHJ2OiBrZXkgfSk7XG4gICAgICByZXR1cm4gdHJ1ZTtcbiAgICB9IGNhdGNoIHtcbiAgICAgIHJldHVybiBmYWxzZTtcbiAgICB9XG4gIH1cblxuICAvKiogQGluaGVyaXRkb2MgKi9cbiAgaXNWYWxpZFB1YmxpY0tleShrZXk6IHN0cmluZyk6IGJvb2xlYW4ge1xuICAgIHRyeSB7XG4gICAgICBuZXcgS2V5UGFpcih7IHB1Yjoga2V5IH0pO1xuICAgICAgcmV0dXJuIHRydWU7XG4gICAgfSBjYXRjaCB7XG4gICAgICByZXR1cm4gZmFsc2U7XG4gICAgfVxuICB9XG5cbiAgLyoqIEBpbmhlcml0ZG9jICovXG4gIGlzVmFsaWRTaWduYXR1cmUoc2lnbmF0dXJlOiBzdHJpbmcpOiBib29sZWFuIHtcbiAgICB0aHJvdyBuZXcgTm90SW1wbGVtZW50ZWRFcnJvcignaXNWYWxpZFNpZ25hdHVyZSBub3QgaW1wbGVtZW50ZWQnKTtcbiAgfVxuXG4gIC8qKiBAaW5oZXJpdGRvYyAqL1xuICBpc1ZhbGlkVHJhbnNhY3Rpb25JZCh0eElkOiBzdHJpbmcpOiBib29sZWFuIHtcbiAgICByZXR1cm4gdGhpcy52YWxpZGF0ZUJsYWtlMmIodHhJZCk7XG4gIH1cblxuICAvKipcbiAgICogQ2hlY2tzIGlmIHRyYW5zYWN0aW9uIGhhc2ggaXMgaW4gdmFsaWQgYmxhY2syYiBmb3JtYXRcbiAgICovXG4gIHZhbGlkYXRlQmxha2UyYihoYXNoOiBzdHJpbmcpOiBib29sZWFuIHtcbiAgICBpZiAoaGFzaD8ubGVuZ3RoICE9PSA2NCkge1xuICAgICAgcmV0dXJuIGZhbHNlO1xuICAgIH1cbiAgICByZXR1cm4gaGFzaC5tYXRjaCgvXlthLXpBLVowLTldKyQvKSAhPT0gbnVsbDtcbiAgfVxuXG4gIC8qKlxuICAgKiBWYWxpZGF0ZXMgd2hldGhlciBhbW91bnRzIGFyZSBpbiByYW5nZVxuICAgKlxuICAgKiBAcGFyYW0ge251bWJlcltdfSBhbW91bnRzIC0gdGhlIGFtb3VudHMgdG8gdmFsaWRhdGVcbiAgICogQHJldHVybnMge2Jvb2xlYW59IC0gdGhlIHZhbGlkYXRpb24gcmVzdWx0XG4gICAqL1xuICBpc1ZhbGlkQW1vdW50cyhhbW91bnRzOiBudW1iZXJbXSk6IGJvb2xlYW4ge1xuICAgIGZvciAoY29uc3QgYW1vdW50IG9mIGFtb3VudHMpIHtcbiAgICAgIGlmICghdGhpcy5pc1ZhbGlkQW1vdW50KGFtb3VudCkpIHtcbiAgICAgICAgcmV0dXJuIGZhbHNlO1xuICAgICAgfVxuICAgIH1cbiAgICByZXR1cm4gdHJ1ZTtcbiAgfVxuXG4gIC8qKlxuICAgKiBWYWxpZGF0ZXMgd2hldGhlciBhbW91bnQgaXMgaW4gcmFuZ2VcbiAgICogQHBhcmFtIHtudW1iZXJ9IGFtb3VudFxuICAgKiBAcmV0dXJucyB7Ym9vbGVhbn0gdGhlIHZhbGlkYXRpb24gcmVzdWx0XG4gICAqL1xuICBpc1ZhbGlkQW1vdW50KGFtb3VudDogbnVtYmVyKTogYm9vbGVhbiB7XG4gICAgY29uc3QgYmlnTnVtYmVyQW1vdW50ID0gbmV3IEJpZ051bWJlcihhbW91bnQpO1xuICAgIGlmICghYmlnTnVtYmVyQW1vdW50LmlzSW50ZWdlcigpIHx8IGJpZ051bWJlckFtb3VudC5pc0xlc3NUaGFuT3JFcXVhbFRvKDApKSB7XG4gICAgICByZXR1cm4gZmFsc2U7XG4gICAgfVxuICAgIHJldHVybiB0cnVlO1xuICB9XG5cbiAgLyoqXG4gICAqIERlY29kZXMgcmF3IHR4IGRhdGEgaW50byBtZXNzYWdlcywgc2lnbmluZyBpbmZvLCBhbmQgZmVlIGRhdGFcbiAgICogQHBhcmFtIHtzdHJpbmd9IHR4SGV4IC0gcmF3IGJhc2U2NCB0eFxuICAgKiBAcmV0dXJucyB7RGVjb2RlZFR4UmF3fSBEZWNvZGVkIHRyYW5zYWN0aW9uXG4gICAqL1xuICBnZXREZWNvZGVkVHhGcm9tUmF3QmFzZTY0KHR4UmF3OiBzdHJpbmcpOiBEZWNvZGVkVHhSYXcge1xuICAgIHRyeSB7XG4gICAgICByZXR1cm4gZGVjb2RlVHhSYXcoZnJvbUJhc2U2NCh0eFJhdykpO1xuICAgIH0gY2F0Y2ggKGUpIHtcbiAgICAgIHRocm93IG5ldyBQYXJzZVRyYW5zYWN0aW9uRXJyb3IoJ0Vycm9yIGRlY29kaW5nIFR4UmF3IGJhc2U2NCBlbmNvZGVkIHN0cmluZzogJyArIGUubWVzc2FnZSk7XG4gICAgfVxuICB9XG5cbiAgLyoqXG4gICAqIFJldHVybnMgdGhlIGFycmF5IG9mIG1lc3NhZ2VzIGluIHRoZSBib2R5IG9mIHRoZSBkZWNvZGVkIHRyYW5zYWN0aW9uXG4gICAqIEBwYXJhbSB7RGVjb2RlZFR4UmF3fSBkZWNvZGVkVHhcbiAgICogQHJldHVybnMge0VuY29kZU9iamVjdFtdfSBtZXNzYWdlcyBhbG9uZyB3aXRoIHR5cGUgdXJsXG4gICAqL1xuICBwcml2YXRlIGdldEVuY29kZWRNZXNzYWdlc0Zyb21EZWNvZGVkVHgoZGVjb2RlZFR4OiBEZWNvZGVkVHhSYXcpOiBFbmNvZGVPYmplY3RbXSB7XG4gICAgcmV0dXJuIGRlY29kZWRUeC5ib2R5Lm1lc3NhZ2VzO1xuICB9XG5cbiAgdmFsaWRhdGVTZXF1ZW5jZShzZXF1ZW5jZTogbnVtYmVyKSB7XG4gICAgaWYgKHNlcXVlbmNlIDwgMCkge1xuICAgICAgdGhyb3cgbmV3IEludmFsaWRUcmFuc2FjdGlvbkVycm9yKCdJbnZhbGlkIHNlcXVlbmNlOiBsZXNzIHRoYW4gemVybycpO1xuICAgIH1cbiAgfVxuXG4gIC8qKlxuICAgKiBQdWxscyB0aGUgc2VxdWVuY2UgbnVtYmVyIGZyb20gYSBEZWNvZGVkVHhSYXcgQXV0aEluZm8gcHJvcGVydHlcbiAgICogQHBhcmFtIHtEZWNvZGVkVHhSYXd9IGRlY29kZWRUeFxuICAgKiBAcmV0dXJucyB7bnVtYmVyfSBzZXF1ZW5jZVxuICAgKi9cbiAgZ2V0U2VxdWVuY2VGcm9tRGVjb2RlZFR4KGRlY29kZWRUeDogRGVjb2RlZFR4UmF3KTogbnVtYmVyIHtcbiAgICByZXR1cm4gTnVtYmVyKGRlY29kZWRUeC5hdXRoSW5mby5zaWduZXJJbmZvc1swXS5zZXF1ZW5jZSk7XG4gIH1cblxuICAvKipcbiAgICogUHVsbHMgdGhlIHR5cGVVcmwgZnJvbSB0aGUgZW5jb2RlZCBtZXNzYWdlIG9mIGEgRGVjb2RlZFR4UmF3XG4gICAqIEBwYXJhbSB7RGVjb2RlZFR4UmF3fSBkZWNvZGVkVHhcbiAgICogQHJldHVybnMge3N0cmluZ30gb3Ntb3NpcyBwcm90byB0eXBlIHVybFxuICAgKi9cbiAgZ2V0VHlwZVVybEZyb21EZWNvZGVkVHgoZGVjb2RlZFR4OiBEZWNvZGVkVHhSYXcpOiBzdHJpbmcge1xuICAgIGNvbnN0IGVuY29kZWRNZXNzYWdlID0gdGhpcy5nZXRFbmNvZGVkTWVzc2FnZXNGcm9tRGVjb2RlZFR4KGRlY29kZWRUeClbMF07XG4gICAgcmV0dXJuIGVuY29kZWRNZXNzYWdlLnR5cGVVcmw7XG4gIH1cblxuICAvKipcbiAgICogUmV0dXJucyB0aGUgZmVlIGRhdGEgZnJvbSB0aGUgZGVjb2RlZCB0cmFuc2FjdGlvblxuICAgKiBAcGFyYW0ge0RlY29kZWRUeFJhd30gZGVjb2RlZFR4XG4gICAqIEByZXR1cm5zIHtGZWVEYXRhfSBmZWUgZGF0YVxuICAgKi9cbiAgZ2V0R2FzQnVkZ2V0RnJvbURlY29kZWRUeChkZWNvZGVkVHg6IERlY29kZWRUeFJhdyk6IEZlZURhdGEge1xuICAgIHJldHVybiB7XG4gICAgICBhbW91bnQ6IGRlY29kZWRUeC5hdXRoSW5mby5mZWU/LmFtb3VudCBhcyBDb2luW10sXG4gICAgICBnYXNMaW1pdDogTnVtYmVyKGRlY29kZWRUeC5hdXRoSW5mby5mZWU/Lmdhc0xpbWl0KSxcbiAgICB9O1xuICB9XG5cbiAgLyoqXG4gICAqIFJldHVybnMgdGhlIHB1YmxpY0tleSBmcm9tIHRoZSBkZWNvZGVkIHRyYW5zYWN0aW9uXG4gICAqIEBwYXJhbSB7RGVjb2RlZFR4UmF3fSBkZWNvZGVkVHhcbiAgICogQHJldHVybnMge3N0cmluZyB8IHVuZGVmaW5lZH0gcHVibGljS2V5IGluIGhleCBmb3JtYXQgaWYgaXQgZXhpc3RzLCB1bmRlZmluZWQgb3RoZXJ3aXNlXG4gICAqL1xuICBnZXRQdWJsaWNLZXlGcm9tRGVjb2RlZFR4KGRlY29kZWRUeDogRGVjb2RlZFR4UmF3KTogc3RyaW5nIHwgdW5kZWZpbmVkIHtcbiAgICBjb25zdCBwdWJsaWNLZXlVSW50OEFycmF5ID0gZGVjb2RlZFR4LmF1dGhJbmZvLnNpZ25lckluZm9zPy5bMF0ucHVibGljS2V5Py52YWx1ZTtcbiAgICBpZiAocHVibGljS2V5VUludDhBcnJheSkge1xuICAgICAgcmV0dXJuIHRvSGV4KGZyb21CYXNlNjQoZGVjb2RlUHVia2V5KGRlY29kZWRUeC5hdXRoSW5mby5zaWduZXJJbmZvcz8uWzBdLnB1YmxpY0tleSk/LnZhbHVlKSk7XG4gICAgfVxuICAgIHJldHVybiB1bmRlZmluZWQ7XG4gIH1cblxuICAvKipcbiAgICogUmV0dXJucyB0aGUgYXJyYXkgb2YgTWVzc2FnZURhdGFbXSBmcm9tIHRoZSBkZWNvZGVkIHRyYW5zYWN0aW9uXG4gICAqIEBwYXJhbSB7RGVjb2RlZFR4UmF3fSBkZWNvZGVkVHhcbiAgICogQHJldHVybnMge01lc3NhZ2VEYXRhW119IFNlbmQgdHJhbnNhY3Rpb24gbWVzc2FnZSBkYXRhXG4gICAqL1xuICBwcm90ZWN0ZWQgZ2V0U2VuZE1lc3NhZ2VEYXRhRnJvbURlY29kZWRUeChkZWNvZGVkVHg6IERlY29kZWRUeFJhdyk6IE1lc3NhZ2VEYXRhW10ge1xuICAgIHJldHVybiBkZWNvZGVkVHguYm9keS5tZXNzYWdlcy5tYXAoKG1lc3NhZ2UpID0+IHtcbiAgICAgIGNvbnN0IHZhbHVlID0gdGhpcy5yZWdpc3RyeS5kZWNvZGUobWVzc2FnZSk7XG4gICAgICByZXR1cm4ge1xuICAgICAgICB2YWx1ZToge1xuICAgICAgICAgIGZyb21BZGRyZXNzOiB2YWx1ZS5mcm9tQWRkcmVzcyxcbiAgICAgICAgICB0b0FkZHJlc3M6IHZhbHVlLnRvQWRkcmVzcyxcbiAgICAgICAgICBhbW91bnQ6IHZhbHVlLmFtb3VudCxcbiAgICAgICAgfSxcbiAgICAgICAgdHlwZVVybDogbWVzc2FnZS50eXBlVXJsLFxuICAgICAgfTtcbiAgICB9KTtcbiAgfVxuXG4gIC8qKlxuICAgKiBSZXR1cm5zIHRoZSBhcnJheSBvZiBNZXNzYWdlRGF0YVtdIGZyb20gdGhlIGRlY29kZWQgdHJhbnNhY3Rpb25cbiAgICogQHBhcmFtIHtEZWNvZGVkVHhSYXd9IGRlY29kZWRUeFxuICAgKiBAcmV0dXJucyB7TWVzc2FnZURhdGFbXX0gRGVsZWdhdGUgb2YgdW5kZWxlZ2F0ZSB0cmFuc2FjdGlvbiBtZXNzYWdlIGRhdGFcbiAgICovXG4gIGdldERlbGVnYXRlT3JVbmRlbGVnYXRlTWVzc2FnZURhdGFGcm9tRGVjb2RlZFR4KGRlY29kZWRUeDogRGVjb2RlZFR4UmF3KTogTWVzc2FnZURhdGFbXSB7XG4gICAgcmV0dXJuIGRlY29kZWRUeC5ib2R5Lm1lc3NhZ2VzLm1hcCgobWVzc2FnZSkgPT4ge1xuICAgICAgY29uc3QgdmFsdWUgPSB0aGlzLnJlZ2lzdHJ5LmRlY29kZShtZXNzYWdlKTtcbiAgICAgIHJldHVybiB7XG4gICAgICAgIHZhbHVlOiB7XG4gICAgICAgICAgZGVsZWdhdG9yQWRkcmVzczogdmFsdWUuZGVsZWdhdG9yQWRkcmVzcyxcbiAgICAgICAgICB2YWxpZGF0b3JBZGRyZXNzOiB2YWx1ZS52YWxpZGF0b3JBZGRyZXNzLFxuICAgICAgICAgIGFtb3VudDogdmFsdWUuYW1vdW50LFxuICAgICAgICB9LFxuICAgICAgICB0eXBlVXJsOiBtZXNzYWdlLnR5cGVVcmwsXG4gICAgICB9O1xuICAgIH0pO1xuICB9XG5cbiAgLyoqXG4gICAqIFJldHVybnMgdGhlIGFycmF5IG9mIE1lc3NhZ2VEYXRhW10gZnJvbSB0aGUgZGVjb2RlZCB0cmFuc2FjdGlvblxuICAgKiBAcGFyYW0ge0RlY29kZWRUeFJhd30gZGVjb2RlZFR4XG4gICAqIEByZXR1cm5zIHtNZXNzYWdlRGF0YVtdfSBXaXRoZHJhd0RlbGVnYXRvclJld2FyZHMgdHJhbnNhY3Rpb24gbWVzc2FnZSBkYXRhXG4gICAqL1xuICBnZXRXaXRoZHJhd1Jld2FyZHNNZXNzYWdlRGF0YUZyb21EZWNvZGVkVHgoZGVjb2RlZFR4OiBEZWNvZGVkVHhSYXcpOiBNZXNzYWdlRGF0YVtdIHtcbiAgICByZXR1cm4gZGVjb2RlZFR4LmJvZHkubWVzc2FnZXMubWFwKChtZXNzYWdlKSA9PiB7XG4gICAgICBjb25zdCB2YWx1ZSA9IHRoaXMucmVnaXN0cnkuZGVjb2RlKG1lc3NhZ2UpO1xuICAgICAgcmV0dXJuIHtcbiAgICAgICAgdmFsdWU6IHtcbiAgICAgICAgICBkZWxlZ2F0b3JBZGRyZXNzOiB2YWx1ZS5kZWxlZ2F0b3JBZGRyZXNzLFxuICAgICAgICAgIHZhbGlkYXRvckFkZHJlc3M6IHZhbHVlLnZhbGlkYXRvckFkZHJlc3MsXG4gICAgICAgIH0sXG4gICAgICAgIHR5cGVVcmw6IG1lc3NhZ2UudHlwZVVybCxcbiAgICAgIH07XG4gICAgfSk7XG4gIH1cblxuICAvKipcbiAgICogUmV0dXJucyB0aGUgYXJyYXkgb2YgTWVzc2FnZURhdGFbXSBmcm9tIHRoZSBkZWNvZGVkIHRyYW5zYWN0aW9uXG4gICAqIEBwYXJhbSB7RGVjb2RlZFR4UmF3fSBkZWNvZGVkVHhcbiAgICogQHJldHVybnMge01lc3NhZ2VEYXRhW119IERlbGVnYXRlIG9mIHVuZGVsZWdhdGUgdHJhbnNhY3Rpb24gbWVzc2FnZSBkYXRhXG4gICAqL1xuICBnZXRXaXRoZHJhd0RlbGVnYXRvclJld2FyZHNNZXNzYWdlRGF0YUZyb21EZWNvZGVkVHgoZGVjb2RlZFR4OiBEZWNvZGVkVHhSYXcpOiBNZXNzYWdlRGF0YVtdIHtcbiAgICByZXR1cm4gZGVjb2RlZFR4LmJvZHkubWVzc2FnZXMubWFwKChtZXNzYWdlKSA9PiB7XG4gICAgICBjb25zdCB2YWx1ZSA9IHRoaXMucmVnaXN0cnkuZGVjb2RlKG1lc3NhZ2UpO1xuICAgICAgcmV0dXJuIHtcbiAgICAgICAgdmFsdWU6IHtcbiAgICAgICAgICBkZWxlZ2F0b3JBZGRyZXNzOiB2YWx1ZS5kZWxlZ2F0b3JBZGRyZXNzLFxuICAgICAgICAgIHZhbGlkYXRvckFkZHJlc3M6IHZhbHVlLnZhbGlkYXRvckFkZHJlc3MsXG4gICAgICAgIH0sXG4gICAgICAgIHR5cGVVcmw6IG1lc3NhZ2UudHlwZVVybCxcbiAgICAgIH07XG4gICAgfSk7XG4gIH1cblxuICAvKipcbiAgICogRGV0ZXJtaW5lcyBiaXRnbyB0cmFuc2FjdGlvbiB0eXBlIGJhc2VkIG9uIG9zbW9zaXMgcHJvdG8gdHlwZSB1cmxcbiAgICogQHBhcmFtIHtzdHJpbmd9IHR5cGVVcmxcbiAgICogQHJldHVybnMge1RyYW5zYWN0aW9uVHlwZSB8IHVuZGVmaW5lZH0gVHJhbnNhY3Rpb25UeXBlIGlmIHVybCBpcyBzdXBwb3J0ZWQgZWxzZSB1bmRlZmluZWRcbiAgICovXG4gIGdldFRyYW5zYWN0aW9uVHlwZUZyb21UeXBlVXJsKHR5cGVVcmw6IHN0cmluZyk6IFRyYW5zYWN0aW9uVHlwZSB8IHVuZGVmaW5lZCB7XG4gICAgc3dpdGNoICh0eXBlVXJsKSB7XG4gICAgICBjYXNlIGNvbnN0YW50cy5zZW5kTXNnVHlwZVVybDpcbiAgICAgICAgcmV0dXJuIFRyYW5zYWN0aW9uVHlwZS5TZW5kO1xuICAgICAgY2FzZSBjb25zdGFudHMuZGVsZWdhdGVNc2dUeXBlVXJsOlxuICAgICAgICByZXR1cm4gVHJhbnNhY3Rpb25UeXBlLlN0YWtpbmdBY3RpdmF0ZTtcbiAgICAgIGNhc2UgY29uc3RhbnRzLnVuZGVsZWdhdGVNc2dUeXBlVXJsOlxuICAgICAgICByZXR1cm4gVHJhbnNhY3Rpb25UeXBlLlN0YWtpbmdEZWFjdGl2YXRlO1xuICAgICAgY2FzZSBjb25zdGFudHMud2l0aGRyYXdEZWxlZ2F0b3JSZXdhcmRNc2dUeXBlVXJsOlxuICAgICAgICByZXR1cm4gVHJhbnNhY3Rpb25UeXBlLlN0YWtpbmdXaXRoZHJhdztcbiAgICAgIGRlZmF1bHQ6XG4gICAgICAgIHJldHVybiB1bmRlZmluZWQ7XG4gICAgfVxuICB9XG5cbiAgLyoqXG4gICAqIENyZWF0ZXMgYSB0eFJhdyBmcm9tIGFuIGNvc21vcyBsaWtlIHRyYW5zYWN0aW9uIEBzZWUgQ29zbW9zTGlrZVRyYW5zYWN0aW9uXG4gICAqIEBQcmVjb25kaXRpb24gY29zbW9zTGlrZVRyYW5zYWN0aW9uLnB1YmxpY0tleSBtdXN0IGJlIGRlZmluZWRcbiAgICogQHBhcmFtIHtDb3Ntb3NMaWtlVHJhbnNhY3Rpb259IGNvc21vc0xpa2VUcmFuc2FjdGlvblxuICAgKiBAcmV0dXJucyB7VHhSYXd9IFVuc2lnbmVkIHJhdyB0cmFuc2FjdGlvblxuICAgKi9cbiAgY3JlYXRlVHhSYXdGcm9tQ29zbW9zTGlrZVRyYW5zYWN0aW9uKGNvc21vc0xpa2VUcmFuc2FjdGlvbjogQ29zbW9zTGlrZVRyYW5zYWN0aW9uKTogVHhSYXcge1xuICAgIGlmICghY29zbW9zTGlrZVRyYW5zYWN0aW9uLnB1YmxpY0tleSkge1xuICAgICAgdGhyb3cgbmV3IEVycm9yKCdwdWJsaWNLZXkgaXMgcmVxdWlyZWQgdG8gY3JlYXRlIGEgdHhSYXcnKTtcbiAgICB9XG4gICAgY29uc3QgZW5jb2RlZFB1YmxpY0tleTogQW55ID0gZW5jb2RlUHVia2V5KGVuY29kZVNlY3AyNTZrMVB1YmtleShmcm9tSGV4KGNvc21vc0xpa2VUcmFuc2FjdGlvbi5wdWJsaWNLZXkpKSk7XG4gICAgY29uc3QgbWVzc2FnZXMgPSBjb3Ntb3NMaWtlVHJhbnNhY3Rpb24uc2VuZE1lc3NhZ2VzIGFzIHVua25vd24gYXMgQW55W107XG4gICAgbGV0IHR4Qm9keVZhbHVlO1xuICAgIGlmIChjb3Ntb3NMaWtlVHJhbnNhY3Rpb24ubWVtbykge1xuICAgICAgdHhCb2R5VmFsdWUgPSB7XG4gICAgICAgIG1lbW86IGNvc21vc0xpa2VUcmFuc2FjdGlvbi5tZW1vLFxuICAgICAgICBtZXNzYWdlczogbWVzc2FnZXMsXG4gICAgICB9O1xuICAgIH0gZWxzZSB7XG4gICAgICB0eEJvZHlWYWx1ZSA9IHtcbiAgICAgICAgbWVzc2FnZXM6IG1lc3NhZ2VzLFxuICAgICAgfTtcbiAgICB9XG5cbiAgICBjb25zdCB0eEJvZHlCeXRlcyA9IHRoaXMucmVnaXN0cnkuZW5jb2RlVHhCb2R5KHR4Qm9keVZhbHVlKTtcbiAgICBjb25zdCBzZXF1ZW5jZSA9IGNvc21vc0xpa2VUcmFuc2FjdGlvbi5zZXF1ZW5jZTtcbiAgICBjb25zdCBhdXRoSW5mb0J5dGVzID0gbWFrZUF1dGhJbmZvQnl0ZXMoXG4gICAgICBbeyBwdWJrZXk6IGVuY29kZWRQdWJsaWNLZXksIHNlcXVlbmNlIH1dLFxuICAgICAgY29zbW9zTGlrZVRyYW5zYWN0aW9uLmdhc0J1ZGdldC5hbW91bnQsXG4gICAgICBjb3Ntb3NMaWtlVHJhbnNhY3Rpb24uZ2FzQnVkZ2V0Lmdhc0xpbWl0LFxuICAgICAgdW5kZWZpbmVkLFxuICAgICAgdW5kZWZpbmVkLFxuICAgICAgdW5kZWZpbmVkXG4gICAgKTtcbiAgICByZXR1cm4gVHhSYXcuZnJvbVBhcnRpYWwoe1xuICAgICAgYm9keUJ5dGVzOiB0eEJvZHlCeXRlcyxcbiAgICAgIGF1dGhJbmZvQnl0ZXM6IGF1dGhJbmZvQnl0ZXMsXG4gICAgfSk7XG4gIH1cblxuICAvKipcbiAgICogRW5jb2RlcyBhIHNpZ25hdHVyZSBpbnRvIGEgdHhSYXdcbiAgICogQHBhcmFtIHtzdHJpbmd9IHB1YmxpY0tleUhleCBwdWJsaWNLZXkgaW4gaGV4IGVuY29kZWQgc3RyaW5nIGZvcm1hdFxuICAgKiBAcGFyYW0ge3N0cmluZ30gc2lnbmF0dXJlSGV4IHNpZ25hdHVyZSBpbiBoZXggZW5jb2RlZCBzdHJpbmcgZm9ybWF0XG4gICAqIEBwYXJhbSB7VHhSYXd9IHVuc2lnbmVkVHggcmF3IHRyYW5zYWN0aW9uXG4gICAqIEByZXR1cm5zIHtUeFJhd30gU2lnbmVkIHJhdyB0cmFuc2FjdGlvblxuICAgKi9cbiAgY3JlYXRlU2lnbmVkVHhSYXcoXG4gICAgcHVibGljS2V5SGV4OiBzdHJpbmcsXG4gICAgc2lnbmF0dXJlSGV4OiBzdHJpbmcsXG4gICAgdW5zaWduZWRUeDogeyBib2R5Qnl0ZXM6IFVpbnQ4QXJyYXk7IGF1dGhJbmZvQnl0ZXM6IFVpbnQ4QXJyYXkgfVxuICApOiBUeFJhdyB7XG4gICAgY29uc3Qgc3RkU2lnbmF0dXJlID0gZW5jb2RlU2VjcDI1NmsxU2lnbmF0dXJlKGZyb21IZXgocHVibGljS2V5SGV4KSwgZnJvbUhleChzaWduYXR1cmVIZXgpKTtcbiAgICByZXR1cm4gVHhSYXcuZnJvbVBhcnRpYWwoe1xuICAgICAgYm9keUJ5dGVzOiB1bnNpZ25lZFR4LmJvZHlCeXRlcyxcbiAgICAgIGF1dGhJbmZvQnl0ZXM6IHVuc2lnbmVkVHguYXV0aEluZm9CeXRlcyxcbiAgICAgIHNpZ25hdHVyZXM6IFtmcm9tQmFzZTY0KHN0ZFNpZ25hdHVyZS5zaWduYXR1cmUpXSxcbiAgICB9KTtcbiAgfVxuXG4gIC8qKlxuICAgKiBEZWNvZGVzIGEgcmF3IHRyYW5zYWN0aW9uIGludG8gYSBEZWNvZGVkVHhSYXcgYW5kIGNoZWNrcyBpZiBpdCBoYXMgbm9uIGVtcHR5IHNpZ25hdHVyZXNcbiAgICogQHBhcmFtIHtzdHJpbmd9IHJhd1RyYW5zYWN0aW9uXG4gICAqIEByZXR1cm5zIHtib29sZWFufSB0cnVlIGlmIHRyYW5zYWN0aW9uIGlzIHNpZ25lZCBlbHNlIGZhbHNlXG4gICAqL1xuICBpc1NpZ25lZFJhd1R4KHJhd1RyYW5zYWN0aW9uOiBzdHJpbmcpOiBib29sZWFuIHtcbiAgICBjb25zdCBkZWNvZGVkVHggPSB0aGlzLmdldERlY29kZWRUeEZyb21SYXdCYXNlNjQocmF3VHJhbnNhY3Rpb24pO1xuICAgIGlmIChkZWNvZGVkVHguc2lnbmF0dXJlcy5sZW5ndGggPiAwKSB7XG4gICAgICByZXR1cm4gdHJ1ZTtcbiAgICB9XG4gICAgcmV0dXJuIGZhbHNlO1xuICB9XG5cbiAgdmFsaWRhdGVQdWJsaWNLZXkocHVibGljS2V5OiBzdHJpbmcgfCB1bmRlZmluZWQpIHtcbiAgICBpZiAocHVibGljS2V5ICE9PSB1bmRlZmluZWQpIHtcbiAgICAgIHRyeSB7XG4gICAgICAgIG5ldyBLZXlQYWlyKHsgcHViOiBwdWJsaWNLZXkgfSk7XG4gICAgICB9IGNhdGNoIHtcbiAgICAgICAgdGhyb3cgbmV3IEludmFsaWRUcmFuc2FjdGlvbkVycm9yKGBLZXkgdmFsaWRhdGlvbiBmYWlsZWRgKTtcbiAgICAgIH1cbiAgICB9XG4gIH1cblxuICAvKipcbiAgICogVmFsaWRhdGVzIGlmIHRoZSBhZGRyZXNzIG1hdGNoZXMgd2l0aCByZWdleCBAc2VlIGFjY291bnRBZGRyZXNzUmVnZXhcbiAgICpcbiAgICogQHBhcmFtIHtzdHJpbmd9IGFkZHJlc3NcbiAgICogQHJldHVybnMge2Jvb2xlYW59IC0gdGhlIHZhbGlkYXRpb24gcmVzdWx0XG4gICAqL1xuICBpc1ZhbGlkQWRkcmVzcyhhZGRyZXNzOiBzdHJpbmcpOiBib29sZWFuIHtcbiAgICB0aHJvdyBuZXcgTm90SW1wbGVtZW50ZWRFcnJvcignaXNWYWxpZEFkZHJlc3Mgbm90IGltcGxlbWVudGVkJyk7XG4gIH1cblxuICAvKipcbiAgICogQ3JlYXRlcyBhIHNpZ24gZG9jIGZyb20gYW4gY29zbW9zIGxpa2UgdHJhbnNhY3Rpb24gQHNlZSBDb3Ntb3NMaWtlVHJhbnNhY3Rpb25cbiAgICogQFByZWNvbmRpdGlvbiBjb3Ntb3NMaWtlVHJhbnNhY3Rpb24uYWNjb3VudE51bWJlciBhbmQgY29zbW9zTGlrZVRyYW5zYWN0aW9uLmNoYWluSWQgbXVzdCBiZSBkZWZpbmVkXG4gICAqIEBwYXJhbSB7Q29zbW9zTGlrZVRyYW5zYWN0aW9ufSBjb3Ntb3NMaWtlVHJhbnNhY3Rpb25cbiAgICogQHJldHVybnMge1NpZ25Eb2N9IHNpZ24gZG9jXG4gICAqL1xuICBjcmVhdGVTaWduRG9jKFxuICAgIGNvc21vc0xpa2VUcmFuc2FjdGlvbjogQ29zbW9zTGlrZVRyYW5zYWN0aW9uLFxuICAgIGFjY291bnROdW1iZXI6IG51bWJlciB8IHVuZGVmaW5lZCxcbiAgICBjaGFpbklkOiBzdHJpbmcgfCB1bmRlZmluZWRcbiAgKTogU2lnbkRvYyB7XG4gICAgaWYgKCFhY2NvdW50TnVtYmVyKSB7XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoJ2FjY291bnROdW1iZXIgaXMgcmVxdWlyZWQgdG8gY3JlYXRlIGEgc2lnbiBkb2MnKTtcbiAgICB9XG4gICAgaWYgKCFjaGFpbklkKSB7XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoJ2NoYWluSWQgaXMgcmVxdWlyZWQgdG8gY3JlYXRlIGEgc2lnbiBkb2MnKTtcbiAgICB9XG4gICAgaWYgKCFjb3Ntb3NMaWtlVHJhbnNhY3Rpb24pIHtcbiAgICAgIHRocm93IG5ldyBFcnJvcignY29zbW9zTGlrZVRyYW5zYWN0aW9uIGlzIHJlcXVpcmVkIHRvIGNyZWF0ZSBhIHNpZ24gZG9jJyk7XG4gICAgfVxuICAgIGNvbnN0IHR4UmF3ID0gdXRpbHMuY3JlYXRlVHhSYXdGcm9tQ29zbW9zTGlrZVRyYW5zYWN0aW9uKGNvc21vc0xpa2VUcmFuc2FjdGlvbik7XG4gICAgcmV0dXJuIG1ha2VTaWduRG9jKHR4UmF3LmJvZHlCeXRlcywgdHhSYXcuYXV0aEluZm9CeXRlcywgY2hhaW5JZCwgYWNjb3VudE51bWJlcik7XG4gIH1cblxuICBpc1ZhbGlkSGV4U3RyaW5nKGhleFN0cmluZzogc3RyaW5nKTogYm9vbGVhbiB7XG4gICAgcmV0dXJuIC9eWzAtOUEtRmEtZl0qJC8udGVzdChoZXhTdHJpbmcpO1xuICB9XG59XG5cbmNvbnN0IHV0aWxzID0gbmV3IENvc21vc0xpa2VVdGlscygpO1xuXG5leHBvcnQgZGVmYXVsdCB1dGlscztcbiJdfQ==