@bitgo-beta/abstract-utxo 1.1.1-beta.2296 → 1.1.1-beta.2298
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/cjs/src/recovery/index.d.ts +1 -0
- package/dist/cjs/src/recovery/index.d.ts.map +1 -1
- package/dist/cjs/src/recovery/index.js +2 -1
- package/dist/cjs/src/recovery/safeRecovery.d.ts +19 -0
- package/dist/cjs/src/recovery/safeRecovery.d.ts.map +1 -0
- package/dist/cjs/src/recovery/safeRecovery.js +70 -0
- package/dist/cjs/test/unit/recovery/safeRecovery.d.ts +2 -0
- package/dist/cjs/test/unit/recovery/safeRecovery.d.ts.map +1 -0
- package/dist/cjs/test/unit/recovery/safeRecovery.js +187 -0
- package/dist/cjs/tsconfig.tsbuildinfo +1 -1
- package/dist/esm/recovery/index.d.ts +1 -0
- package/dist/esm/recovery/index.d.ts.map +1 -1
- package/dist/esm/recovery/index.js +2 -1
- package/dist/esm/recovery/safeRecovery.d.ts +19 -0
- package/dist/esm/recovery/safeRecovery.d.ts.map +1 -0
- package/dist/esm/recovery/safeRecovery.js +66 -0
- package/package.json +11 -10
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../src/recovery/index.ts"],"names":[],"mappings":"AAAA,cAAc,oBAAoB,CAAC;AACnC,cAAc,qBAAqB,CAAC;AACpC,cAAc,WAAW,CAAC;AAC1B,cAAc,gBAAgB,CAAC;AAC/B,cAAc,sBAAsB,CAAC;AACrC,cAAc,cAAc,CAAC"}
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../src/recovery/index.ts"],"names":[],"mappings":"AAAA,cAAc,oBAAoB,CAAC;AACnC,cAAc,qBAAqB,CAAC;AACpC,cAAc,WAAW,CAAC;AAC1B,cAAc,gBAAgB,CAAC;AAC/B,cAAc,sBAAsB,CAAC;AACrC,cAAc,cAAc,CAAC;AAC7B,cAAc,gBAAgB,CAAC"}
|
|
@@ -20,4 +20,5 @@ __exportStar(require("./baseApi"), exports);
|
|
|
20
20
|
__exportStar(require("./coingeckoApi"), exports);
|
|
21
21
|
__exportStar(require("./crossChainRecovery"), exports);
|
|
22
22
|
__exportStar(require("./mempoolApi"), exports);
|
|
23
|
-
|
|
23
|
+
__exportStar(require("./safeRecovery"), exports);
|
|
24
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiaW5kZXguanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi8uLi9zcmMvcmVjb3ZlcnkvaW5kZXgudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6Ijs7Ozs7Ozs7Ozs7Ozs7OztBQUFBLHFEQUFtQztBQUNuQyxzREFBb0M7QUFDcEMsNENBQTBCO0FBQzFCLGlEQUErQjtBQUMvQix1REFBcUM7QUFDckMsK0NBQTZCO0FBQzdCLGlEQUErQiIsInNvdXJjZXNDb250ZW50IjpbImV4cG9ydCAqIGZyb20gJy4vUmVjb3ZlcnlQcm92aWRlcic7XG5leHBvcnQgKiBmcm9tICcuL2JhY2t1cEtleVJlY292ZXJ5JztcbmV4cG9ydCAqIGZyb20gJy4vYmFzZUFwaSc7XG5leHBvcnQgKiBmcm9tICcuL2NvaW5nZWNrb0FwaSc7XG5leHBvcnQgKiBmcm9tICcuL2Nyb3NzQ2hhaW5SZWNvdmVyeSc7XG5leHBvcnQgKiBmcm9tICcuL21lbXBvb2xBcGknO1xuZXhwb3J0ICogZnJvbSAnLi9zYWZlUmVjb3ZlcnknO1xuIl19
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @prettier
|
|
3
|
+
*
|
|
4
|
+
* Safe (slot-1) UTXO recovery adapter: maps a Safe child triplet onto the existing
|
|
5
|
+
* `backupKeyRecovery` engine for funding checks and recovery.
|
|
6
|
+
*/
|
|
7
|
+
import { SafeChildTriplet, SafeChildTripletPubs } from '@bitgo-beta/sdk-lib-safes';
|
|
8
|
+
import { AbstractUtxoCoin } from '../abstractUtxoCoin';
|
|
9
|
+
import { backupKeyRecovery, RecoverParams } from './backupKeyRecovery';
|
|
10
|
+
export type SafeWalletFundingStatus = 'funded' | 'empty' | 'unknown';
|
|
11
|
+
export type SafeWalletRecoveryMode = 'signed' | 'unsigned';
|
|
12
|
+
export type SafeRecoveryOptionsBase = Pick<RecoverParams, 'scan' | 'apiKey' | 'recoveryProvider'>;
|
|
13
|
+
export type RecoverSafeWalletOptions = {
|
|
14
|
+
mode: SafeWalletRecoveryMode;
|
|
15
|
+
recoveryDestination: string;
|
|
16
|
+
} & SafeRecoveryOptionsBase & Pick<RecoverParams, 'feeRate'>;
|
|
17
|
+
export declare function determineSafeWalletFunding(coin: AbstractUtxoCoin, triplet: SafeChildTripletPubs, options?: SafeRecoveryOptionsBase): Promise<SafeWalletFundingStatus>;
|
|
18
|
+
export declare function recoverSafeWallet(coin: AbstractUtxoCoin, triplet: SafeChildTriplet, options: RecoverSafeWalletOptions): ReturnType<typeof backupKeyRecovery>;
|
|
19
|
+
//# sourceMappingURL=safeRecovery.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"safeRecovery.d.ts","sourceRoot":"","sources":["../../../../src/recovery/safeRecovery.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AACH,OAAO,EACL,gBAAgB,EAChB,oBAAoB,EAGrB,MAAM,2BAA2B,CAAC;AAInC,OAAO,EAAE,gBAAgB,EAAE,MAAM,qBAAqB,CAAC;AAGvD,OAAO,EAAE,iBAAiB,EAAyC,aAAa,EAAE,MAAM,qBAAqB,CAAC;AAE9G,MAAM,MAAM,uBAAuB,GAAG,QAAQ,GAAG,OAAO,GAAG,SAAS,CAAC;AACrE,MAAM,MAAM,sBAAsB,GAAG,QAAQ,GAAG,UAAU,CAAC;AAE3D,MAAM,MAAM,uBAAuB,GAAG,IAAI,CAAC,aAAa,EAAE,MAAM,GAAG,QAAQ,GAAG,kBAAkB,CAAC,CAAC;AAElG,MAAM,MAAM,wBAAwB,GAAG;IACrC,IAAI,EAAE,sBAAsB,CAAC;IAC7B,mBAAmB,EAAE,MAAM,CAAC;CAC7B,GAAG,uBAAuB,GACzB,IAAI,CAAC,aAAa,EAAE,SAAS,CAAC,CAAC;AAgCjC,wBAAsB,0BAA0B,CAC9C,IAAI,EAAE,gBAAgB,EACtB,OAAO,EAAE,oBAAoB,EAC7B,OAAO,GAAE,uBAA4B,GACpC,OAAO,CAAC,uBAAuB,CAAC,CAqBlC;AAED,wBAAsB,iBAAiB,CACrC,IAAI,EAAE,gBAAgB,EACtB,OAAO,EAAE,gBAAgB,EACzB,OAAO,EAAE,wBAAwB,GAChC,UAAU,CAAC,OAAO,iBAAiB,CAAC,CActC"}
|
|
@@ -0,0 +1,70 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.determineSafeWalletFunding = determineSafeWalletFunding;
|
|
4
|
+
exports.recoverSafeWallet = recoverSafeWallet;
|
|
5
|
+
/**
|
|
6
|
+
* @prettier
|
|
7
|
+
*
|
|
8
|
+
* Safe (slot-1) UTXO recovery adapter: maps a Safe child triplet onto the existing
|
|
9
|
+
* `backupKeyRecovery` engine for funding checks and recovery.
|
|
10
|
+
*/
|
|
11
|
+
const sdk_lib_safes_1 = require("@bitgo-beta/sdk-lib-safes");
|
|
12
|
+
const sdk_core_1 = require("@bitgo-beta/sdk-core");
|
|
13
|
+
const wasm_utxo_1 = require("@bitgo/wasm-utxo");
|
|
14
|
+
const address_1 = require("../address");
|
|
15
|
+
const backupKeyRecovery_1 = require("./backupKeyRecovery");
|
|
16
|
+
function withSafeRecoveryGuard(coin, options, fn) {
|
|
17
|
+
(0, sdk_lib_safes_1.assertSafeRecoverySupported)((0, sdk_lib_safes_1.onchainSlotForCoin)(coin.getChain()), 'utxo', coin.getChain());
|
|
18
|
+
if (options.scan !== undefined && options.scan <= 0) {
|
|
19
|
+
throw new Error('scan must be a positive integer');
|
|
20
|
+
}
|
|
21
|
+
return fn();
|
|
22
|
+
}
|
|
23
|
+
/**
|
|
24
|
+
* Derive the wallet's own first external address to satisfy `backupKeyRecovery`'s
|
|
25
|
+
* destination validation. Never broadcast, never returned to the caller.
|
|
26
|
+
*/
|
|
27
|
+
function synthesizeDestination(coin, triplet) {
|
|
28
|
+
const walletKeys = wasm_utxo_1.fixedScriptWallet.RootWalletKeys.from({
|
|
29
|
+
triple: [triplet.user.pub, triplet.backup.pub, triplet.bitgo.pub].map((pub) => wasm_utxo_1.BIP32.from(pub)),
|
|
30
|
+
derivationPrefixes: ['m/0/0', 'm/0/0', 'm/0/0'],
|
|
31
|
+
});
|
|
32
|
+
return (0, address_1.generateAddressWithChainAndIndex)(coin.wasmName, walletKeys, wasm_utxo_1.fixedScriptWallet.ChainCode.value('p2sh', 'external'), 0, undefined);
|
|
33
|
+
}
|
|
34
|
+
async function determineSafeWalletFunding(coin, triplet, options = {}) {
|
|
35
|
+
return withSafeRecoveryGuard(coin, options, async () => {
|
|
36
|
+
const recoveryParams = {
|
|
37
|
+
...options,
|
|
38
|
+
recoveryDestination: synthesizeDestination(coin, triplet),
|
|
39
|
+
userKey: triplet.user.pub,
|
|
40
|
+
backupKey: triplet.backup.pub,
|
|
41
|
+
bitgoKey: triplet.bitgo.pub,
|
|
42
|
+
ignoreAddressTypes: [],
|
|
43
|
+
feeRate: backupKeyRecovery_1.DEFAULT_RECOVERY_FEERATE_SAT_VBYTE_V2,
|
|
44
|
+
};
|
|
45
|
+
try {
|
|
46
|
+
const result = await coin.recover(recoveryParams);
|
|
47
|
+
return result && 'txHex' in result && typeof result.txHex === 'string' && result.txHex.length > 0
|
|
48
|
+
? 'funded'
|
|
49
|
+
: 'unknown';
|
|
50
|
+
}
|
|
51
|
+
catch (err) {
|
|
52
|
+
return err instanceof sdk_core_1.ErrorNoInputToRecover ? 'empty' : 'unknown';
|
|
53
|
+
}
|
|
54
|
+
});
|
|
55
|
+
}
|
|
56
|
+
async function recoverSafeWallet(coin, triplet, options) {
|
|
57
|
+
return withSafeRecoveryGuard(coin, options, async () => {
|
|
58
|
+
const { mode, recoveryDestination, ...rest } = options;
|
|
59
|
+
const recoveryParams = {
|
|
60
|
+
...rest,
|
|
61
|
+
recoveryDestination,
|
|
62
|
+
userKey: mode === 'signed' ? triplet.user.prv : triplet.user.pub,
|
|
63
|
+
backupKey: mode === 'signed' ? triplet.backup.prv : triplet.backup.pub,
|
|
64
|
+
bitgoKey: triplet.bitgo.pub,
|
|
65
|
+
ignoreAddressTypes: [],
|
|
66
|
+
};
|
|
67
|
+
return coin.recover(recoveryParams);
|
|
68
|
+
});
|
|
69
|
+
}
|
|
70
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoic2FmZVJlY292ZXJ5LmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vLi4vLi4vc3JjL3JlY292ZXJ5L3NhZmVSZWNvdmVyeS50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiOztBQTZEQSxnRUF5QkM7QUFFRCw4Q0FrQkM7QUExR0Q7Ozs7O0dBS0c7QUFDSCw2REFLbUM7QUFDbkMsbURBQXFFO0FBQ3JFLGdEQUE0RDtBQUc1RCx3Q0FBOEQ7QUFFOUQsMkRBQThHO0FBYTlHLFNBQVMscUJBQXFCLENBQzVCLElBQXNCLEVBQ3RCLE9BQWdDLEVBQ2hDLEVBQW9CO0lBRXBCLElBQUEsMkNBQTJCLEVBQUMsSUFBQSxrQ0FBa0IsRUFBQyxJQUFJLENBQUMsUUFBUSxFQUFFLENBQUMsRUFBRSxNQUFNLEVBQUUsSUFBSSxDQUFDLFFBQVEsRUFBRSxDQUFDLENBQUM7SUFDMUYsSUFBSSxPQUFPLENBQUMsSUFBSSxLQUFLLFNBQVMsSUFBSSxPQUFPLENBQUMsSUFBSSxJQUFJLENBQUMsRUFBRSxDQUFDO1FBQ3BELE1BQU0sSUFBSSxLQUFLLENBQUMsaUNBQWlDLENBQUMsQ0FBQztJQUNyRCxDQUFDO0lBQ0QsT0FBTyxFQUFFLEVBQUUsQ0FBQztBQUNkLENBQUM7QUFFRDs7O0dBR0c7QUFDSCxTQUFTLHFCQUFxQixDQUFDLElBQXNCLEVBQUUsT0FBNkI7SUFDbEYsTUFBTSxVQUFVLEdBQUcsNkJBQWlCLENBQUMsY0FBYyxDQUFDLElBQUksQ0FBQztRQUN2RCxNQUFNLEVBQUUsQ0FBQyxPQUFPLENBQUMsSUFBSSxDQUFDLEdBQUcsRUFBRSxPQUFPLENBQUMsTUFBTSxDQUFDLEdBQUcsRUFBRSxPQUFPLENBQUMsS0FBSyxDQUFDLEdBQUcsQ0FBQyxDQUFDLEdBQUcsQ0FBQyxDQUFDLEdBQUcsRUFBRSxFQUFFLENBQUMsaUJBQUssQ0FBQyxJQUFJLENBQUMsR0FBRyxDQUFDLENBQWtCO1FBQ2hILGtCQUFrQixFQUFFLENBQUMsT0FBTyxFQUFFLE9BQU8sRUFBRSxPQUFPLENBQUM7S0FDaEQsQ0FBQyxDQUFDO0lBQ0gsT0FBTyxJQUFBLDBDQUFnQyxFQUNyQyxJQUFJLENBQUMsUUFBUSxFQUNiLFVBQVUsRUFDViw2QkFBaUIsQ0FBQyxTQUFTLENBQUMsS0FBSyxDQUFDLE1BQU0sRUFBRSxVQUFVLENBQUMsRUFDckQsQ0FBQyxFQUNELFNBQVMsQ0FDVixDQUFDO0FBQ0osQ0FBQztBQUVNLEtBQUssVUFBVSwwQkFBMEIsQ0FDOUMsSUFBc0IsRUFDdEIsT0FBNkIsRUFDN0IsVUFBbUMsRUFBRTtJQUVyQyxPQUFPLHFCQUFxQixDQUFDLElBQUksRUFBRSxPQUFPLEVBQUUsS0FBSyxJQUFJLEVBQUU7UUFDckQsTUFBTSxjQUFjLEdBQWtCO1lBQ3BDLEdBQUcsT0FBTztZQUNWLG1CQUFtQixFQUFFLHFCQUFxQixDQUFDLElBQUksRUFBRSxPQUFPLENBQUM7WUFDekQsT0FBTyxFQUFFLE9BQU8sQ0FBQyxJQUFJLENBQUMsR0FBRztZQUN6QixTQUFTLEVBQUUsT0FBTyxDQUFDLE1BQU0sQ0FBQyxHQUFHO1lBQzdCLFFBQVEsRUFBRSxPQUFPLENBQUMsS0FBSyxDQUFDLEdBQUc7WUFDM0Isa0JBQWtCLEVBQUUsRUFBRTtZQUN0QixPQUFPLEVBQUUseURBQXFDO1NBQy9DLENBQUM7UUFFRixJQUFJLENBQUM7WUFDSCxNQUFNLE1BQU0sR0FBRyxNQUFNLElBQUksQ0FBQyxPQUFPLENBQUMsY0FBYyxDQUFDLENBQUM7WUFDbEQsT0FBTyxNQUFNLElBQUksT0FBTyxJQUFJLE1BQU0sSUFBSSxPQUFPLE1BQU0sQ0FBQyxLQUFLLEtBQUssUUFBUSxJQUFJLE1BQU0sQ0FBQyxLQUFLLENBQUMsTUFBTSxHQUFHLENBQUM7Z0JBQy9GLENBQUMsQ0FBQyxRQUFRO2dCQUNWLENBQUMsQ0FBQyxTQUFTLENBQUM7UUFDaEIsQ0FBQztRQUFDLE9BQU8sR0FBRyxFQUFFLENBQUM7WUFDYixPQUFPLEdBQUcsWUFBWSxnQ0FBcUIsQ0FBQyxDQUFDLENBQUMsT0FBTyxDQUFDLENBQUMsQ0FBQyxTQUFTLENBQUM7UUFDcEUsQ0FBQztJQUNILENBQUMsQ0FBQyxDQUFDO0FBQ0wsQ0FBQztBQUVNLEtBQUssVUFBVSxpQkFBaUIsQ0FDckMsSUFBc0IsRUFDdEIsT0FBeUIsRUFDekIsT0FBaUM7SUFFakMsT0FBTyxxQkFBcUIsQ0FBQyxJQUFJLEVBQUUsT0FBTyxFQUFFLEtBQUssSUFBSSxFQUFFO1FBQ3JELE1BQU0sRUFBRSxJQUFJLEVBQUUsbUJBQW1CLEVBQUUsR0FBRyxJQUFJLEVBQUUsR0FBRyxPQUFPLENBQUM7UUFDdkQsTUFBTSxjQUFjLEdBQWtCO1lBQ3BDLEdBQUcsSUFBSTtZQUNQLG1CQUFtQjtZQUNuQixPQUFPLEVBQUUsSUFBSSxLQUFLLFFBQVEsQ0FBQyxDQUFDLENBQUMsT0FBTyxDQUFDLElBQUksQ0FBQyxHQUFHLENBQUMsQ0FBQyxDQUFDLE9BQU8sQ0FBQyxJQUFJLENBQUMsR0FBRztZQUNoRSxTQUFTLEVBQUUsSUFBSSxLQUFLLFFBQVEsQ0FBQyxDQUFDLENBQUMsT0FBTyxDQUFDLE1BQU0sQ0FBQyxHQUFHLENBQUMsQ0FBQyxDQUFDLE9BQU8sQ0FBQyxNQUFNLENBQUMsR0FBRztZQUN0RSxRQUFRLEVBQUUsT0FBTyxDQUFDLEtBQUssQ0FBQyxHQUFHO1lBQzNCLGtCQUFrQixFQUFFLEVBQUU7U0FDdkIsQ0FBQztRQUVGLE9BQU8sSUFBSSxDQUFDLE9BQU8sQ0FBQyxjQUFjLENBQUMsQ0FBQztJQUN0QyxDQUFDLENBQUMsQ0FBQztBQUNMLENBQUMiLCJzb3VyY2VzQ29udGVudCI6WyIvKipcbiAqIEBwcmV0dGllclxuICpcbiAqIFNhZmUgKHNsb3QtMSkgVVRYTyByZWNvdmVyeSBhZGFwdGVyOiBtYXBzIGEgU2FmZSBjaGlsZCB0cmlwbGV0IG9udG8gdGhlIGV4aXN0aW5nXG4gKiBgYmFja3VwS2V5UmVjb3ZlcnlgIGVuZ2luZSBmb3IgZnVuZGluZyBjaGVja3MgYW5kIHJlY292ZXJ5LlxuICovXG5pbXBvcnQge1xuICBTYWZlQ2hpbGRUcmlwbGV0LFxuICBTYWZlQ2hpbGRUcmlwbGV0UHVicyxcbiAgYXNzZXJ0U2FmZVJlY292ZXJ5U3VwcG9ydGVkLFxuICBvbmNoYWluU2xvdEZvckNvaW4sXG59IGZyb20gJ0BiaXRnby1iZXRhL3Nkay1saWItc2FmZXMnO1xuaW1wb3J0IHsgRXJyb3JOb0lucHV0VG9SZWNvdmVyLCBUcmlwbGUgfSBmcm9tICdAYml0Z28tYmV0YS9zZGstY29yZSc7XG5pbXBvcnQgeyBCSVAzMiwgZml4ZWRTY3JpcHRXYWxsZXQgfSBmcm9tICdAYml0Z28vd2FzbS11dHhvJztcblxuaW1wb3J0IHsgQWJzdHJhY3RVdHhvQ29pbiB9IGZyb20gJy4uL2Fic3RyYWN0VXR4b0NvaW4nO1xuaW1wb3J0IHsgZ2VuZXJhdGVBZGRyZXNzV2l0aENoYWluQW5kSW5kZXggfSBmcm9tICcuLi9hZGRyZXNzJztcblxuaW1wb3J0IHsgYmFja3VwS2V5UmVjb3ZlcnksIERFRkFVTFRfUkVDT1ZFUllfRkVFUkFURV9TQVRfVkJZVEVfVjIsIFJlY292ZXJQYXJhbXMgfSBmcm9tICcuL2JhY2t1cEtleVJlY292ZXJ5JztcblxuZXhwb3J0IHR5cGUgU2FmZVdhbGxldEZ1bmRpbmdTdGF0dXMgPSAnZnVuZGVkJyB8ICdlbXB0eScgfCAndW5rbm93bic7XG5leHBvcnQgdHlwZSBTYWZlV2FsbGV0UmVjb3ZlcnlNb2RlID0gJ3NpZ25lZCcgfCAndW5zaWduZWQnO1xuXG5leHBvcnQgdHlwZSBTYWZlUmVjb3ZlcnlPcHRpb25zQmFzZSA9IFBpY2s8UmVjb3ZlclBhcmFtcywgJ3NjYW4nIHwgJ2FwaUtleScgfCAncmVjb3ZlcnlQcm92aWRlcic+O1xuXG5leHBvcnQgdHlwZSBSZWNvdmVyU2FmZVdhbGxldE9wdGlvbnMgPSB7XG4gIG1vZGU6IFNhZmVXYWxsZXRSZWNvdmVyeU1vZGU7XG4gIHJlY292ZXJ5RGVzdGluYXRpb246IHN0cmluZztcbn0gJiBTYWZlUmVjb3ZlcnlPcHRpb25zQmFzZSAmXG4gIFBpY2s8UmVjb3ZlclBhcmFtcywgJ2ZlZVJhdGUnPjtcblxuZnVuY3Rpb24gd2l0aFNhZmVSZWNvdmVyeUd1YXJkPFQ+KFxuICBjb2luOiBBYnN0cmFjdFV0eG9Db2luLFxuICBvcHRpb25zOiBTYWZlUmVjb3ZlcnlPcHRpb25zQmFzZSxcbiAgZm46ICgpID0+IFByb21pc2U8VD5cbik6IFByb21pc2U8VD4ge1xuICBhc3NlcnRTYWZlUmVjb3ZlcnlTdXBwb3J0ZWQob25jaGFpblNsb3RGb3JDb2luKGNvaW4uZ2V0Q2hhaW4oKSksICd1dHhvJywgY29pbi5nZXRDaGFpbigpKTtcbiAgaWYgKG9wdGlvbnMuc2NhbiAhPT0gdW5kZWZpbmVkICYmIG9wdGlvbnMuc2NhbiA8PSAwKSB7XG4gICAgdGhyb3cgbmV3IEVycm9yKCdzY2FuIG11c3QgYmUgYSBwb3NpdGl2ZSBpbnRlZ2VyJyk7XG4gIH1cbiAgcmV0dXJuIGZuKCk7XG59XG5cbi8qKlxuICogRGVyaXZlIHRoZSB3YWxsZXQncyBvd24gZmlyc3QgZXh0ZXJuYWwgYWRkcmVzcyB0byBzYXRpc2Z5IGBiYWNrdXBLZXlSZWNvdmVyeWAnc1xuICogZGVzdGluYXRpb24gdmFsaWRhdGlvbi4gTmV2ZXIgYnJvYWRjYXN0LCBuZXZlciByZXR1cm5lZCB0byB0aGUgY2FsbGVyLlxuICovXG5mdW5jdGlvbiBzeW50aGVzaXplRGVzdGluYXRpb24oY29pbjogQWJzdHJhY3RVdHhvQ29pbiwgdHJpcGxldDogU2FmZUNoaWxkVHJpcGxldFB1YnMpOiBzdHJpbmcge1xuICBjb25zdCB3YWxsZXRLZXlzID0gZml4ZWRTY3JpcHRXYWxsZXQuUm9vdFdhbGxldEtleXMuZnJvbSh7XG4gICAgdHJpcGxlOiBbdHJpcGxldC51c2VyLnB1YiwgdHJpcGxldC5iYWNrdXAucHViLCB0cmlwbGV0LmJpdGdvLnB1Yl0ubWFwKChwdWIpID0+IEJJUDMyLmZyb20ocHViKSkgYXMgVHJpcGxlPEJJUDMyPixcbiAgICBkZXJpdmF0aW9uUHJlZml4ZXM6IFsnbS8wLzAnLCAnbS8wLzAnLCAnbS8wLzAnXSxcbiAgfSk7XG4gIHJldHVybiBnZW5lcmF0ZUFkZHJlc3NXaXRoQ2hhaW5BbmRJbmRleChcbiAgICBjb2luLndhc21OYW1lLFxuICAgIHdhbGxldEtleXMsXG4gICAgZml4ZWRTY3JpcHRXYWxsZXQuQ2hhaW5Db2RlLnZhbHVlKCdwMnNoJywgJ2V4dGVybmFsJyksXG4gICAgMCxcbiAgICB1bmRlZmluZWRcbiAgKTtcbn1cblxuZXhwb3J0IGFzeW5jIGZ1bmN0aW9uIGRldGVybWluZVNhZmVXYWxsZXRGdW5kaW5nKFxuICBjb2luOiBBYnN0cmFjdFV0eG9Db2luLFxuICB0cmlwbGV0OiBTYWZlQ2hpbGRUcmlwbGV0UHVicyxcbiAgb3B0aW9uczogU2FmZVJlY292ZXJ5T3B0aW9uc0Jhc2UgPSB7fVxuKTogUHJvbWlzZTxTYWZlV2FsbGV0RnVuZGluZ1N0YXR1cz4ge1xuICByZXR1cm4gd2l0aFNhZmVSZWNvdmVyeUd1YXJkKGNvaW4sIG9wdGlvbnMsIGFzeW5jICgpID0+IHtcbiAgICBjb25zdCByZWNvdmVyeVBhcmFtczogUmVjb3ZlclBhcmFtcyA9IHtcbiAgICAgIC4uLm9wdGlvbnMsXG4gICAgICByZWNvdmVyeURlc3RpbmF0aW9uOiBzeW50aGVzaXplRGVzdGluYXRpb24oY29pbiwgdHJpcGxldCksXG4gICAgICB1c2VyS2V5OiB0cmlwbGV0LnVzZXIucHViLFxuICAgICAgYmFja3VwS2V5OiB0cmlwbGV0LmJhY2t1cC5wdWIsXG4gICAgICBiaXRnb0tleTogdHJpcGxldC5iaXRnby5wdWIsXG4gICAgICBpZ25vcmVBZGRyZXNzVHlwZXM6IFtdLFxuICAgICAgZmVlUmF0ZTogREVGQVVMVF9SRUNPVkVSWV9GRUVSQVRFX1NBVF9WQllURV9WMixcbiAgICB9O1xuXG4gICAgdHJ5IHtcbiAgICAgIGNvbnN0IHJlc3VsdCA9IGF3YWl0IGNvaW4ucmVjb3ZlcihyZWNvdmVyeVBhcmFtcyk7XG4gICAgICByZXR1cm4gcmVzdWx0ICYmICd0eEhleCcgaW4gcmVzdWx0ICYmIHR5cGVvZiByZXN1bHQudHhIZXggPT09ICdzdHJpbmcnICYmIHJlc3VsdC50eEhleC5sZW5ndGggPiAwXG4gICAgICAgID8gJ2Z1bmRlZCdcbiAgICAgICAgOiAndW5rbm93bic7XG4gICAgfSBjYXRjaCAoZXJyKSB7XG4gICAgICByZXR1cm4gZXJyIGluc3RhbmNlb2YgRXJyb3JOb0lucHV0VG9SZWNvdmVyID8gJ2VtcHR5JyA6ICd1bmtub3duJztcbiAgICB9XG4gIH0pO1xufVxuXG5leHBvcnQgYXN5bmMgZnVuY3Rpb24gcmVjb3ZlclNhZmVXYWxsZXQoXG4gIGNvaW46IEFic3RyYWN0VXR4b0NvaW4sXG4gIHRyaXBsZXQ6IFNhZmVDaGlsZFRyaXBsZXQsXG4gIG9wdGlvbnM6IFJlY292ZXJTYWZlV2FsbGV0T3B0aW9uc1xuKTogUmV0dXJuVHlwZTx0eXBlb2YgYmFja3VwS2V5UmVjb3Zlcnk+IHtcbiAgcmV0dXJuIHdpdGhTYWZlUmVjb3ZlcnlHdWFyZChjb2luLCBvcHRpb25zLCBhc3luYyAoKSA9PiB7XG4gICAgY29uc3QgeyBtb2RlLCByZWNvdmVyeURlc3RpbmF0aW9uLCAuLi5yZXN0IH0gPSBvcHRpb25zO1xuICAgIGNvbnN0IHJlY292ZXJ5UGFyYW1zOiBSZWNvdmVyUGFyYW1zID0ge1xuICAgICAgLi4ucmVzdCxcbiAgICAgIHJlY292ZXJ5RGVzdGluYXRpb24sXG4gICAgICB1c2VyS2V5OiBtb2RlID09PSAnc2lnbmVkJyA/IHRyaXBsZXQudXNlci5wcnYgOiB0cmlwbGV0LnVzZXIucHViLFxuICAgICAgYmFja3VwS2V5OiBtb2RlID09PSAnc2lnbmVkJyA/IHRyaXBsZXQuYmFja3VwLnBydiA6IHRyaXBsZXQuYmFja3VwLnB1YixcbiAgICAgIGJpdGdvS2V5OiB0cmlwbGV0LmJpdGdvLnB1YixcbiAgICAgIGlnbm9yZUFkZHJlc3NUeXBlczogW10sXG4gICAgfTtcblxuICAgIHJldHVybiBjb2luLnJlY292ZXIocmVjb3ZlcnlQYXJhbXMpO1xuICB9KTtcbn1cbiJdfQ==
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"safeRecovery.d.ts","sourceRoot":"","sources":["../../../../../test/unit/recovery/safeRecovery.ts"],"names":[],"mappings":""}
|
|
@@ -0,0 +1,187 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
3
|
+
if (k2 === undefined) k2 = k;
|
|
4
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
5
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
6
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
7
|
+
}
|
|
8
|
+
Object.defineProperty(o, k2, desc);
|
|
9
|
+
}) : (function(o, m, k, k2) {
|
|
10
|
+
if (k2 === undefined) k2 = k;
|
|
11
|
+
o[k2] = m[k];
|
|
12
|
+
}));
|
|
13
|
+
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
|
14
|
+
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
|
15
|
+
}) : function(o, v) {
|
|
16
|
+
o["default"] = v;
|
|
17
|
+
});
|
|
18
|
+
var __importStar = (this && this.__importStar) || (function () {
|
|
19
|
+
var ownKeys = function(o) {
|
|
20
|
+
ownKeys = Object.getOwnPropertyNames || function (o) {
|
|
21
|
+
var ar = [];
|
|
22
|
+
for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
|
|
23
|
+
return ar;
|
|
24
|
+
};
|
|
25
|
+
return ownKeys(o);
|
|
26
|
+
};
|
|
27
|
+
return function (mod) {
|
|
28
|
+
if (mod && mod.__esModule) return mod;
|
|
29
|
+
var result = {};
|
|
30
|
+
if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
|
|
31
|
+
__setModuleDefault(result, mod);
|
|
32
|
+
return result;
|
|
33
|
+
};
|
|
34
|
+
})();
|
|
35
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
36
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
37
|
+
};
|
|
38
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
39
|
+
const assert_1 = __importDefault(require("assert"));
|
|
40
|
+
const sinon = __importStar(require("sinon"));
|
|
41
|
+
const nock = require("nock");
|
|
42
|
+
const src_1 = require("../../../src");
|
|
43
|
+
const util_1 = require("../util");
|
|
44
|
+
const mock_1 = require("./mock");
|
|
45
|
+
nock.disableNetConnect();
|
|
46
|
+
const { walletKeys: wasmWalletKeys } = (0, util_1.getDefaultWasmWalletKeys)();
|
|
47
|
+
function tripletPubs() {
|
|
48
|
+
return {
|
|
49
|
+
user: { pub: util_1.keychainsBase58[0].pub },
|
|
50
|
+
backup: { pub: util_1.keychainsBase58[1].pub },
|
|
51
|
+
bitgo: { pub: util_1.keychainsBase58[2].pub },
|
|
52
|
+
};
|
|
53
|
+
}
|
|
54
|
+
const throwingProvider = {
|
|
55
|
+
getUnspentsForAddresses: async () => {
|
|
56
|
+
throw new Error('provider down');
|
|
57
|
+
},
|
|
58
|
+
getAddressInfo: async () => {
|
|
59
|
+
throw new Error('provider down');
|
|
60
|
+
},
|
|
61
|
+
getTransactionHex: async () => {
|
|
62
|
+
throw new Error('provider down');
|
|
63
|
+
},
|
|
64
|
+
getTransactionIO: async () => {
|
|
65
|
+
throw new Error('provider down');
|
|
66
|
+
},
|
|
67
|
+
};
|
|
68
|
+
describe('determineSafeWalletFunding', function () {
|
|
69
|
+
it('returns funded when the wallet has unspents', async function () {
|
|
70
|
+
const coin = (0, util_1.getUtxoCoin)('btc');
|
|
71
|
+
const unspents = [(0, util_1.toUnspentWithPrevTx)({ scriptType: 'p2sh', value: BigInt(1e8) }, 0, coin.name, wasmWalletKeys)];
|
|
72
|
+
const status = await (0, src_1.determineSafeWalletFunding)(coin, tripletPubs(), {
|
|
73
|
+
recoveryProvider: new mock_1.MockRecoveryProvider(unspents),
|
|
74
|
+
});
|
|
75
|
+
assert_1.default.strictEqual(status, 'funded');
|
|
76
|
+
});
|
|
77
|
+
(0, util_1.getMinUtxoCoins)().forEach((coin) => {
|
|
78
|
+
it(`returns empty when the wallet has no unspents [${coin.getChain()}]`, async function () {
|
|
79
|
+
const status = await (0, src_1.determineSafeWalletFunding)(coin, tripletPubs(), {
|
|
80
|
+
recoveryProvider: new mock_1.MockRecoveryProvider([]),
|
|
81
|
+
});
|
|
82
|
+
assert_1.default.strictEqual(status, 'empty');
|
|
83
|
+
});
|
|
84
|
+
it(`returns unknown when the provider fails [${coin.getChain()}]`, async function () {
|
|
85
|
+
const status = await (0, src_1.determineSafeWalletFunding)(coin, tripletPubs(), {
|
|
86
|
+
recoveryProvider: throwingProvider,
|
|
87
|
+
});
|
|
88
|
+
assert_1.default.strictEqual(status, 'unknown');
|
|
89
|
+
});
|
|
90
|
+
});
|
|
91
|
+
it('returns unknown when the engine resolves without a valid txHex', async function () {
|
|
92
|
+
const coin = (0, util_1.getUtxoCoin)('btc');
|
|
93
|
+
const malformedResult = {
|
|
94
|
+
txHex: '',
|
|
95
|
+
txInfo: {},
|
|
96
|
+
feeInfo: {},
|
|
97
|
+
coin: coin.getChain(),
|
|
98
|
+
};
|
|
99
|
+
const stub = sinon.stub(coin, 'recover').resolves(malformedResult);
|
|
100
|
+
try {
|
|
101
|
+
const status = await (0, src_1.determineSafeWalletFunding)(coin, tripletPubs());
|
|
102
|
+
assert_1.default.strictEqual(status, 'unknown');
|
|
103
|
+
}
|
|
104
|
+
finally {
|
|
105
|
+
stub.restore();
|
|
106
|
+
}
|
|
107
|
+
});
|
|
108
|
+
it('rejects scan: 0', async function () {
|
|
109
|
+
const coin = (0, util_1.getUtxoCoin)('btc');
|
|
110
|
+
await assert_1.default.rejects(() => (0, src_1.determineSafeWalletFunding)(coin, tripletPubs(), { scan: 0 }), /scan must be a positive integer/);
|
|
111
|
+
});
|
|
112
|
+
});
|
|
113
|
+
describe('recoverSafeWallet', function () {
|
|
114
|
+
const coin = (0, util_1.getUtxoCoin)('btc');
|
|
115
|
+
const { walletKeys: externalWallet } = (0, util_1.createWasmWalletKeys)('external');
|
|
116
|
+
const recoveryDestination = (0, util_1.getWalletAddress)(coin.name, externalWallet);
|
|
117
|
+
const unspents = [(0, util_1.toUnspentWithPrevTx)({ scriptType: 'p2sh', value: BigInt(1e8) }, 0, coin.name, wasmWalletKeys)];
|
|
118
|
+
function fullTriplet() {
|
|
119
|
+
return {
|
|
120
|
+
index: 0,
|
|
121
|
+
user: { prv: util_1.keychainsBase58[0].prv, pub: util_1.keychainsBase58[0].pub },
|
|
122
|
+
backup: { prv: util_1.keychainsBase58[1].prv, pub: util_1.keychainsBase58[1].pub },
|
|
123
|
+
bitgo: { pub: util_1.keychainsBase58[2].pub },
|
|
124
|
+
};
|
|
125
|
+
}
|
|
126
|
+
it('returns an unsigned transaction when mode is unsigned', async function () {
|
|
127
|
+
const result = await (0, src_1.recoverSafeWallet)(coin, fullTriplet(), {
|
|
128
|
+
mode: 'unsigned',
|
|
129
|
+
recoveryDestination,
|
|
130
|
+
feeRate: 100,
|
|
131
|
+
recoveryProvider: new mock_1.MockRecoveryProvider(unspents),
|
|
132
|
+
});
|
|
133
|
+
assert_1.default.ok('txHex' in result && typeof result.txHex === 'string' && result.txHex.length > 0);
|
|
134
|
+
assert_1.default.ok('txInfo' in result && typeof result.txInfo === 'object');
|
|
135
|
+
assert_1.default.ok('feeInfo' in result && typeof result.feeInfo === 'object');
|
|
136
|
+
assert_1.default.strictEqual(result.coin, coin.getChain());
|
|
137
|
+
});
|
|
138
|
+
it('returns a signed transaction when mode is signed', async function () {
|
|
139
|
+
const result = await (0, src_1.recoverSafeWallet)(coin, fullTriplet(), {
|
|
140
|
+
mode: 'signed',
|
|
141
|
+
recoveryDestination,
|
|
142
|
+
feeRate: 100,
|
|
143
|
+
recoveryProvider: new mock_1.MockRecoveryProvider(unspents),
|
|
144
|
+
});
|
|
145
|
+
assert_1.default.ok('transactionHex' in result && typeof result.transactionHex === 'string' && result.transactionHex.length > 0);
|
|
146
|
+
assert_1.default.ok('inputs' in result && Array.isArray(result.inputs) && result.inputs.length > 0);
|
|
147
|
+
});
|
|
148
|
+
it('recovers signed transaction on tbtc with mainnet xprv/xpub child keys', async function () {
|
|
149
|
+
const tbtcCoin = (0, util_1.getUtxoCoin)('tbtc');
|
|
150
|
+
const tbtcDestination = (0, util_1.getWalletAddress)(tbtcCoin.name, externalWallet);
|
|
151
|
+
const tbtcUnspents = [
|
|
152
|
+
(0, util_1.toUnspentWithPrevTx)({ scriptType: 'p2sh', value: BigInt(1e8) }, 0, tbtcCoin.name, wasmWalletKeys),
|
|
153
|
+
];
|
|
154
|
+
const result = await (0, src_1.recoverSafeWallet)(tbtcCoin, fullTriplet(), {
|
|
155
|
+
mode: 'signed',
|
|
156
|
+
recoveryDestination: tbtcDestination,
|
|
157
|
+
feeRate: 100,
|
|
158
|
+
recoveryProvider: new mock_1.MockRecoveryProvider(tbtcUnspents),
|
|
159
|
+
});
|
|
160
|
+
assert_1.default.ok('transactionHex' in result && typeof result.transactionHex === 'string' && result.transactionHex.length > 0);
|
|
161
|
+
assert_1.default.ok('inputs' in result && Array.isArray(result.inputs) && result.inputs.length > 0);
|
|
162
|
+
});
|
|
163
|
+
it('produces a byte-identical result to backupKeyRecovery (signed)', async function () {
|
|
164
|
+
const triplet = fullTriplet();
|
|
165
|
+
const provider = new mock_1.MockRecoveryProvider(unspents);
|
|
166
|
+
const viaSafe = await (0, src_1.recoverSafeWallet)(coin, triplet, {
|
|
167
|
+
mode: 'signed',
|
|
168
|
+
recoveryDestination,
|
|
169
|
+
feeRate: 100,
|
|
170
|
+
recoveryProvider: provider,
|
|
171
|
+
});
|
|
172
|
+
const viaDirect = await (0, src_1.backupKeyRecovery)(coin, util_1.defaultBitGo, {
|
|
173
|
+
userKey: triplet.user.prv,
|
|
174
|
+
backupKey: triplet.backup.prv,
|
|
175
|
+
bitgoKey: triplet.bitgo.pub,
|
|
176
|
+
recoveryDestination,
|
|
177
|
+
ignoreAddressTypes: [],
|
|
178
|
+
feeRate: 100,
|
|
179
|
+
recoveryProvider: provider,
|
|
180
|
+
});
|
|
181
|
+
assert_1.default.deepStrictEqual(viaSafe, viaDirect);
|
|
182
|
+
});
|
|
183
|
+
it('rejects scan: 0', async function () {
|
|
184
|
+
await assert_1.default.rejects(() => (0, src_1.recoverSafeWallet)(coin, fullTriplet(), { mode: 'unsigned', recoveryDestination, scan: 0 }), /scan must be a positive integer/);
|
|
185
|
+
});
|
|
186
|
+
});
|
|
187
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoic2FmZVJlY292ZXJ5LmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vLi4vLi4vLi4vdGVzdC91bml0L3JlY292ZXJ5L3NhZmVSZWNvdmVyeS50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiOzs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7OztBQUFBLG9EQUE0QjtBQUU1Qiw2Q0FBK0I7QUFDL0IsNkJBQThCO0FBRzlCLHNDQUFrSDtBQUNsSCxrQ0FTaUI7QUFFakIsaUNBQThDO0FBRTlDLElBQUksQ0FBQyxpQkFBaUIsRUFBRSxDQUFDO0FBRXpCLE1BQU0sRUFBRSxVQUFVLEVBQUUsY0FBYyxFQUFFLEdBQUcsSUFBQSwrQkFBd0IsR0FBRSxDQUFDO0FBRWxFLFNBQVMsV0FBVztJQUNsQixPQUFPO1FBQ0wsSUFBSSxFQUFFLEVBQUUsR0FBRyxFQUFFLHNCQUFlLENBQUMsQ0FBQyxDQUFDLENBQUMsR0FBRyxFQUFFO1FBQ3JDLE1BQU0sRUFBRSxFQUFFLEdBQUcsRUFBRSxzQkFBZSxDQUFDLENBQUMsQ0FBQyxDQUFDLEdBQUcsRUFBRTtRQUN2QyxLQUFLLEVBQUUsRUFBRSxHQUFHLEVBQUUsc0JBQWUsQ0FBQyxDQUFDLENBQUMsQ0FBQyxHQUFHLEVBQUU7S0FDdkMsQ0FBQztBQUNKLENBQUM7QUFFRCxNQUFNLGdCQUFnQixHQUFxQjtJQUN6Qyx1QkFBdUIsRUFBRSxLQUFLLElBQUksRUFBRTtRQUNsQyxNQUFNLElBQUksS0FBSyxDQUFDLGVBQWUsQ0FBQyxDQUFDO0lBQ25DLENBQUM7SUFDRCxjQUFjLEVBQUUsS0FBSyxJQUFJLEVBQUU7UUFDekIsTUFBTSxJQUFJLEtBQUssQ0FBQyxlQUFlLENBQUMsQ0FBQztJQUNuQyxDQUFDO0lBQ0QsaUJBQWlCLEVBQUUsS0FBSyxJQUFJLEVBQUU7UUFDNUIsTUFBTSxJQUFJLEtBQUssQ0FBQyxlQUFlLENBQUMsQ0FBQztJQUNuQyxDQUFDO0lBQ0QsZ0JBQWdCLEVBQUUsS0FBSyxJQUFJ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LENBQUMsQ0FBQyxDQUFDO0FBQ0wsQ0FBQyxDQUFDLENBQUMiLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQgYXNzZXJ0IGZyb20gJ2Fzc2VydCc7XG5cbmltcG9ydCAqIGFzIHNpbm9uIGZyb20gJ3Npbm9uJztcbmltcG9ydCBub2NrID0gcmVxdWlyZSgnbm9jaycpO1xuaW1wb3J0IHsgU2FmZUNoaWxkVHJpcGxldCwgU2FmZUNoaWxkVHJpcGxldFB1YnMgfSBmcm9tICdAYml0Z28tYmV0YS9zZGstbGliLXNhZmVzJztcblxuaW1wb3J0IHsgYmFja3VwS2V5UmVjb3ZlcnksIGRldGVybWluZVNhZmVXYWxsZXRGdW5kaW5nLCByZWNvdmVyU2FmZVdhbGxldCwgUmVjb3ZlcnlQcm92aWRlciB9IGZyb20gJy4uLy4uLy4uL3NyYyc7XG5pbXBvcnQge1xuICBjcmVhdGVXYXNtV2FsbGV0S2V5cyxcbiAgZGVmYXVsdEJpdEdvLFxuICBnZXREZWZhdWx0V2FzbVdhbGxldEtleXMsXG4gIGdldE1pblV0eG9Db2lucyxcbiAgZ2V0VXR4b0NvaW4sXG4gIGdldFdhbGxldEFkZHJlc3MsXG4gIGtleWNoYWluc0Jhc2U1OCxcbiAgdG9VbnNwZW50V2l0aFByZXZUeCxcbn0gZnJvbSAnLi4vdXRpbCc7XG5cbmltcG9ydCB7IE1vY2tSZWNvdmVyeVByb3ZpZGVyIH0gZnJvbSAnLi9tb2NrJztcblxubm9jay5kaXNhYmxlTmV0Q29ubmVjdCgpO1xuXG5jb25zdCB7IHdhbGxldEtleXM6IHdhc21XYWxsZXRLZXlzIH0gPSBnZXREZWZhdWx0V2FzbVdhbGxldEtleXMoKTtcblxuZnVuY3Rpb24gdHJpcGxldFB1YnMoKTogU2FmZUNoaWxkVHJpcGxldFB1YnMge1xuICByZXR1cm4ge1xuICAgIHVzZXI6IHsgcHViOiBrZXljaGFpbnNCYXNlNThbMF0ucHViIH0sXG4gICAgYmFja3VwOiB7IHB1Yjoga2V5Y2hhaW5zQmFzZTU4WzFdLnB1YiB9LFxuICAgIGJpdGdvOiB7IHB1Yjoga2V5Y2hhaW5zQmFzZTU4WzJdLnB1YiB9LFxuICB9O1xufVxuXG5jb25zdCB0aHJvd2luZ1Byb3ZpZGVyOiBSZWNvdmVyeVByb3ZpZGVyID0ge1xuICBnZXRVbnNwZW50c0ZvckFkZHJlc3NlczogYXN5bmMgKCkgPT4ge1xuICAgIHRocm93IG5ldyBFcnJvcigncHJvdmlkZXIgZG93bicpO1xuICB9LFxuICBnZXRBZGRyZXNzSW5mbzogYXN5bmMgKCkgPT4ge1xuICAgIHRocm93IG5ldyBFcnJvcigncHJvdmlkZXIgZG93bicpO1xuICB9LFxuICBnZXRUcmFuc2FjdGlvbkhleDogYXN5bmMgKCkgPT4ge1xuICAgIHRocm93IG5ldyBFcnJvcigncHJvdmlkZXIgZG93bicpO1xuICB9LFxuICBnZXRUcmFuc2FjdGlvbklPOiBhc3luYyAoKSA9PiB7XG4gICAgdGhyb3cgbmV3IEVycm9yKCdwcm92aWRlciBkb3duJyk7XG4gIH0sXG59O1xuXG5kZXNjcmliZSgnZGV0ZXJtaW5lU2FmZVdhbGxldEZ1bmRpbmcnLCBmdW5jdGlvbiAoKSB7XG4gIGl0KCdyZXR1cm5zIGZ1bmRlZCB3aGVuIHRoZSB3YWxsZXQgaGFzIHVuc3BlbnRzJywgYXN5bmMgZnVuY3Rpb24gKCkge1xuICAgIGNvbnN0IGNvaW4gPSBnZXRVdHhvQ29pbignYnRjJyk7XG4gICAgY29uc3QgdW5zcGVudHMgPSBbdG9VbnNwZW50V2l0aFByZXZUeCh7IHNjcmlwdFR5cGU6ICdwMnNoJywgdmFsdWU6IEJpZ0ludCgxZTgpIH0sIDAsIGNvaW4ubmFtZSwgd2FzbVdhbGxldEtleXMpXTtcbiAgICBjb25zdCBzdGF0dXMgPSBhd2FpdCBkZXRlcm1pbmVTYWZlV2FsbGV0RnVuZGluZyhjb2luLCB0cmlwbGV0UHVicygpLCB7XG4gICAgICByZWNvdmVyeVByb3ZpZGVyOiBuZXcgTW9ja1JlY292ZXJ5UHJvdmlkZXIodW5zcGVudHMpLFxuICAgIH0pO1xuICAgIGFzc2VydC5zdHJpY3RFcXVhbChzdGF0dXMsICdmdW5kZWQnKTtcbiAgfSk7XG5cbiAgZ2V0TWluVXR4b0NvaW5zKCkuZm9yRWFjaCgoY29pbikgPT4ge1xuICAgIGl0KGByZXR1cm5zIGVtcHR5IHdoZW4gdGhlIHdhbGxldCBoYXMgbm8gdW5zcGVudHMgWyR7Y29pbi5nZXRDaGFpbigpfV1gLCBhc3luYyBmdW5jdGlvbiAoKSB7XG4gICAgICBjb25zdCBzdGF0dXMgPSBhd2FpdCBkZXRlcm1pbmVTYWZlV2FsbGV0RnVuZGluZyhjb2luLCB0cmlwbGV0UHVicygpLCB7XG4gICAgICAgIHJlY292ZXJ5UHJvdmlkZXI6IG5ldyBNb2NrUmVjb3ZlcnlQcm92aWRlcihbXSksXG4gICAgICB9KTtcbiAgICAgIGFzc2VydC5zdHJpY3RFcXVhbChzdGF0dXMsICdlbXB0eScpO1xuICAgIH0pO1xuXG4gICAgaXQoYHJldHVybnMgdW5rbm93biB3aGVuIHRoZSBwcm92aWRlciBmYWlscyBbJHtjb2luLmdldENoYWluKCl9XWAsIGFzeW5jIGZ1bmN0aW9uICgpIHtcbiAgICAgIGNvbnN0IHN0YXR1cyA9IGF3YWl0IGRldGVybWluZVNhZmVXYWxsZXRGdW5kaW5nKGNvaW4sIHRyaXBsZXRQdWJzKCksIHtcbiAgICAgICAgcmVjb3ZlcnlQcm92aWRlcjogdGhyb3dpbmdQcm92aWRlcixcbiAgICAgIH0pO1xuICAgICAgYXNzZXJ0LnN0cmljdEVxdWFsKHN0YXR1cywgJ3Vua25vd24nKTtcbiAgICB9KTtcbiAgfSk7XG5cbiAgaXQoJ3JldHVybnMgdW5rbm93biB3aGVuIHRoZSBlbmdpbmUgcmVzb2x2ZXMgd2l0aG91dCBhIHZhbGlkIHR4SGV4JywgYXN5bmMgZnVuY3Rpb24gKCkge1xuICAgIGNvbnN0IGNvaW4gPSBnZXRVdHhvQ29pbignYnRjJyk7XG4gICAgdHlwZSBSZWNvdmVyUmV0dXJuID0gQXdhaXRlZDxSZXR1cm5UeXBlPHR5cGVvZiBjb2luLnJlY292ZXI+PjtcbiAgICBjb25zdCBtYWxmb3JtZWRSZXN1bHQgPSB7XG4gICAgICB0eEhleDogJycsXG4gICAgICB0eEluZm86IHt9LFxuICAgICAgZmVlSW5mbzoge30sXG4gICAgICBjb2luOiBjb2luLmdldENoYWluKCksXG4gICAgfSBhcyBSZWNvdmVyUmV0dXJuO1xuXG4gICAgY29uc3Qgc3R1YiA9IHNpbm9uLnN0dWIoY29pbiwgJ3JlY292ZXInKS5yZXNvbHZlcyhtYWxmb3JtZWRSZXN1bHQpO1xuICAgIHRyeSB7XG4gICAgICBjb25zdCBzdGF0dXMgPSBhd2FpdCBkZXRlcm1pbmVTYWZlV2FsbGV0RnVuZGluZyhjb2luLCB0cmlwbGV0UHVicygpKTtcbiAgICAgIGFzc2VydC5zdHJpY3RFcXVhbChzdGF0dXMsICd1bmtub3duJyk7XG4gICAgfSBmaW5hbGx5IHtcbiAgICAgIHN0dWIucmVzdG9yZSgpO1xuICAgIH1cbiAgfSk7XG5cbiAgaXQoJ3JlamVjdHMgc2NhbjogMCcsIGFzeW5jIGZ1bmN0aW9uICgpIHtcbiAgICBjb25zdCBjb2luID0gZ2V0VXR4b0NvaW4oJ2J0YycpO1xuICAgIGF3YWl0IGFzc2VydC5yZWplY3RzKFxuICAgICAgKCkgPT4gZGV0ZXJtaW5lU2FmZVdhbGxldEZ1bmRpbmcoY29pbiwgdHJpcGxldFB1YnMoKSwgeyBzY2FuOiAwIH0pLFxuICAgICAgL3NjYW4gbXVzdCBiZSBhIHBvc2l0aXZlIGludGVnZXIvXG4gICAgKTtcbiAgfSk7XG59KTtcblxuZGVzY3JpYmUoJ3JlY292ZXJTYWZlV2FsbGV0JywgZnVuY3Rpb24gKCkge1xuICBjb25zdCBjb2luID0gZ2V0VXR4b0NvaW4oJ2J0YycpO1xuICBjb25zdCB7IHdhbGxldEtleXM6IGV4dGVybmFsV2FsbGV0IH0gPSBjcmVhdGVXYXNtV2FsbGV0S2V5cygnZXh0ZXJuYWwnKTtcbiAgY29uc3QgcmVjb3ZlcnlEZXN0aW5hdGlvbiA9IGdldFdhbGxldEFkZHJlc3MoY29pbi5uYW1lLCBleHRlcm5hbFdhbGxldCk7XG4gIGNvbnN0IHVuc3BlbnRzID0gW3RvVW5zcGVudFdpdGhQcmV2VHgoeyBzY3JpcHRUeXBlOiAncDJzaCcsIHZhbHVlOiBCaWdJbnQoMWU4KSB9LCAwLCBjb2luLm5hbWUsIHdhc21XYWxsZXRLZXlzKV07XG5cbiAgZnVuY3Rpb24gZnVsbFRyaXBsZXQoKTogU2FmZUNoaWxkVHJpcGxldCB7XG4gICAgcmV0dXJuIHtcbiAgICAgIGluZGV4OiAwLFxuICAgICAgdXNlcjogeyBwcnY6IGtleWNoYWluc0Jhc2U1OFswXS5wcnYsIHB1Yjoga2V5Y2hhaW5zQmFzZTU4WzBdLnB1YiB9LFxuICAgICAgYmFja3VwOiB7IHBydjoga2V5Y2hhaW5zQmFzZTU4WzFdLnBydiwgcHViOiBrZXljaGFpbnNCYXNlNThbMV0ucHViIH0sXG4gICAgICBiaXRnbzogeyBwdWI6IGtleWNoYWluc0Jhc2U1OFsyXS5wdWIgfSxcbiAgICB9O1xuICB9XG5cbiAgaXQoJ3JldHVybnMgYW4gdW5zaWduZWQgdHJhbnNhY3Rpb24gd2hlbiBtb2RlIGlzIHVuc2lnbmVkJywgYXN5bmMgZnVuY3Rpb24gKCkge1xuICAgIGNvbnN0IHJlc3VsdCA9IGF3YWl0IHJlY292ZXJTYWZlV2FsbGV0KGNvaW4sIGZ1bGxUcmlwbGV0KCksIHtcbiAgICAgIG1vZGU6ICd1bnNpZ25lZCcsXG4gICAgICByZWNvdmVyeURlc3RpbmF0aW9uLFxuICAgICAgZmVlUmF0ZTogMTAwLFxuICAgICAgcmVjb3ZlcnlQcm92aWRlcjogbmV3IE1vY2tSZWNvdmVyeVByb3ZpZGVyKHVuc3BlbnRzKSxcbiAgICB9KTtcbiAgICBhc3NlcnQub2soJ3R4SGV4JyBpbiByZXN1bHQgJiYgdHlwZW9mIHJlc3VsdC50eEhleCA9PT0gJ3N0cmluZycgJiYgcmVzdWx0LnR4SGV4Lmxlbmd0aCA+IDApO1xuICAgIGFzc2VydC5vaygndHhJbmZvJyBpbiByZXN1bHQgJiYgdHlwZW9mIHJlc3VsdC50eEluZm8gPT09ICdvYmplY3QnKTtcbiAgICBhc3NlcnQub2soJ2ZlZUluZm8nIGluIHJlc3VsdCAmJiB0eXBlb2YgcmVzdWx0LmZlZUluZm8gPT09ICdvYmplY3QnKTtcbiAgICBhc3NlcnQuc3RyaWN0RXF1YWwocmVzdWx0LmNvaW4sIGNvaW4uZ2V0Q2hhaW4oKSk7XG4gIH0pO1xuXG4gIGl0KCdyZXR1cm5zIGEgc2lnbmVkIHRyYW5zYWN0aW9uIHdoZW4gbW9kZSBpcyBzaWduZWQnLCBhc3luYyBmdW5jdGlvbiAoKSB7XG4gICAgY29uc3QgcmVzdWx0ID0gYXdhaXQgcmVjb3ZlclNhZmVXYWxsZXQoY29pbiwgZnVsbFRyaXBsZXQoKSwge1xuICAgICAgbW9kZTogJ3NpZ25lZCcsXG4gICAgICByZWNvdmVyeURlc3RpbmF0aW9uLFxuICAgICAgZmVlUmF0ZTogMTAwLFxuICAgICAgcmVjb3ZlcnlQcm92aWRlcjogbmV3IE1vY2tSZWNvdmVyeVByb3ZpZGVyKHVuc3BlbnRzKSxcbiAgICB9KTtcbiAgICBhc3NlcnQub2soXG4gICAgICAndHJhbnNhY3Rpb25IZXgnIGluIHJlc3VsdCAmJiB0eXBlb2YgcmVzdWx0LnRyYW5zYWN0aW9uSGV4ID09PSAnc3RyaW5nJyAmJiByZXN1bHQudHJhbnNhY3Rpb25IZXgubGVuZ3RoID4gMFxuICAgICk7XG4gICAgYXNzZXJ0Lm9rKCdpbnB1dHMnIGluIHJlc3VsdCAmJiBBcnJheS5pc0FycmF5KHJlc3VsdC5pbnB1dHMpICYmIHJlc3VsdC5pbnB1dHMubGVuZ3RoID4gMCk7XG4gIH0pO1xuXG4gIGl0KCdyZWNvdmVycyBzaWduZWQgdHJhbnNhY3Rpb24gb24gdGJ0YyB3aXRoIG1haW5uZXQgeHBydi94cHViIGNoaWxkIGtleXMnLCBhc3luYyBmdW5jdGlvbiAoKSB7XG4gICAgY29uc3QgdGJ0Y0NvaW4gPSBnZXRVdHhvQ29pbigndGJ0YycpO1xuICAgIGNvbnN0IHRidGNEZXN0aW5hdGlvbiA9IGdldFdhbGxldEFkZHJlc3ModGJ0Y0NvaW4ubmFtZSwgZXh0ZXJuYWxXYWxsZXQpO1xuICAgIGNvbnN0IHRidGNVbnNwZW50cyA9IFtcbiAgICAgIHRvVW5zcGVudFdpdGhQcmV2VHgoeyBzY3JpcHRUeXBlOiAncDJzaCcsIHZhbHVlOiBCaWdJbnQoMWU4KSB9LCAwLCB0YnRjQ29pbi5uYW1lLCB3YXNtV2FsbGV0S2V5cyksXG4gICAgXTtcblxuICAgIGNvbnN0IHJlc3VsdCA9IGF3YWl0IHJlY292ZXJTYWZlV2FsbGV0KHRidGNDb2luLCBmdWxsVHJpcGxldCgpLCB7XG4gICAgICBtb2RlOiAnc2lnbmVkJyxcbiAgICAgIHJlY292ZXJ5RGVzdGluYXRpb246IHRidGNEZXN0aW5hdGlvbixcbiAgICAgIGZlZVJhdGU6IDEwMCxcbiAgICAgIHJlY292ZXJ5UHJvdmlkZXI6IG5ldyBNb2NrUmVjb3ZlcnlQcm92aWRlcih0YnRjVW5zcGVudHMpLFxuICAgIH0pO1xuICAgIGFzc2VydC5vayhcbiAgICAgICd0cmFuc2FjdGlvbkhleCcgaW4gcmVzdWx0ICYmIHR5cGVvZiByZXN1bHQudHJhbnNhY3Rpb25IZXggPT09ICdzdHJpbmcnICYmIHJlc3VsdC50cmFuc2FjdGlvbkhleC5sZW5ndGggPiAwXG4gICAgKTtcbiAgICBhc3NlcnQub2soJ2lucHV0cycgaW4gcmVzdWx0ICYmIEFycmF5LmlzQXJyYXkocmVzdWx0LmlucHV0cykgJiYgcmVzdWx0LmlucHV0cy5sZW5ndGggPiAwKTtcbiAgfSk7XG5cbiAgaXQoJ3Byb2R1Y2VzIGEgYnl0ZS1pZGVudGljYWwgcmVzdWx0IHRvIGJhY2t1cEtleVJlY292ZXJ5IChzaWduZWQpJywgYXN5bmMgZnVuY3Rpb24gKCkge1xuICAgIGNvbnN0IHRyaXBsZXQgPSBmdWxsVHJpcGxldCgpO1xuICAgIGNvbnN0IHByb3ZpZGVyID0gbmV3IE1vY2tSZWNvdmVyeVByb3ZpZGVyKHVuc3BlbnRzKTtcblxuICAgIGNvbnN0IHZpYVNhZmUgPSBhd2FpdCByZWNvdmVyU2FmZVdhbGxldChjb2luLCB0cmlwbGV0LCB7XG4gICAgICBtb2RlOiAnc2lnbmVkJyxcbiAgICAgIHJlY292ZXJ5RGVzdGluYXRpb24sXG4gICAgICBmZWVSYXRlOiAxMDAsXG4gICAgICByZWNvdmVyeVByb3ZpZGVyOiBwcm92aWRlcixcbiAgICB9KTtcblxuICAgIGNvbnN0IHZpYURpcmVjdCA9IGF3YWl0IGJhY2t1cEtleVJlY292ZXJ5KGNvaW4sIGRlZmF1bHRCaXRHbywge1xuICAgICAgdXNlcktleTogdHJpcGxldC51c2VyLnBydixcbiAgICAgIGJhY2t1cEtleTogdHJpcGxldC5iYWNrdXAucHJ2LFxuICAgICAgYml0Z29LZXk6IHRyaXBsZXQuYml0Z28ucHViLFxuICAgICAgcmVjb3ZlcnlEZXN0aW5hdGlvbixcbiAgICAgIGlnbm9yZUFkZHJlc3NUeXBlczogW10sXG4gICAgICBmZWVSYXRlOiAxMDAsXG4gICAgICByZWNvdmVyeVByb3ZpZGVyOiBwcm92aWRlcixcbiAgICB9KTtcblxuICAgIGFzc2VydC5kZWVwU3RyaWN0RXF1YWwodmlhU2FmZSwgdmlhRGlyZWN0KTtcbiAgfSk7XG5cbiAgaXQoJ3JlamVjdHMgc2NhbjogMCcsIGFzeW5jIGZ1bmN0aW9uICgpIHtcbiAgICBhd2FpdCBhc3NlcnQucmVqZWN0cyhcbiAgICAgICgpID0+IHJlY292ZXJTYWZlV2FsbGV0KGNvaW4sIGZ1bGxUcmlwbGV0KCksIHsgbW9kZTogJ3Vuc2lnbmVkJywgcmVjb3ZlcnlEZXN0aW5hdGlvbiwgc2NhbjogMCB9KSxcbiAgICAgIC9zY2FuIG11c3QgYmUgYSBwb3NpdGl2ZSBpbnRlZ2VyL1xuICAgICk7XG4gIH0pO1xufSk7XG4iXX0=
|