@bitgo-beta/utxo-staking 1.1.1-beta.91 → 1.1.1-beta.911
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/scripts/babylon-sync.d.ts +2 -0
- package/dist/cjs/scripts/babylon-sync.d.ts.map +1 -0
- package/dist/cjs/scripts/babylon-sync.js +126 -0
- package/dist/cjs/src/babylon/delegationMessage.d.ts +38 -0
- package/dist/cjs/src/babylon/delegationMessage.d.ts.map +1 -0
- package/dist/cjs/src/babylon/delegationMessage.js +285 -0
- package/dist/cjs/src/babylon/descriptor.d.ts +48 -0
- package/dist/cjs/src/babylon/descriptor.d.ts.map +1 -0
- package/dist/cjs/src/babylon/descriptor.js +97 -0
- package/dist/cjs/src/babylon/index.d.ts +8 -0
- package/dist/cjs/src/babylon/index.d.ts.map +1 -0
- package/dist/cjs/src/babylon/index.js +51 -0
- package/dist/cjs/src/babylon/network.d.ts +7 -0
- package/dist/cjs/src/babylon/network.d.ts.map +1 -0
- package/dist/cjs/src/babylon/network.js +66 -0
- package/dist/cjs/src/babylon/params.mainnet.json +152 -0
- package/dist/cjs/src/babylon/params.testnet.json +212 -0
- package/dist/cjs/src/babylon/parseDescriptor.d.ts +26 -0
- package/dist/cjs/src/babylon/parseDescriptor.d.ts.map +1 -0
- package/dist/cjs/src/babylon/parseDescriptor.js +159 -0
- package/dist/cjs/src/babylon/stakingManager.d.ts +6 -0
- package/dist/cjs/src/babylon/stakingManager.d.ts.map +1 -0
- package/dist/cjs/src/babylon/stakingManager.js +120 -0
- package/dist/cjs/src/babylon/stakingParams.d.ts +40 -0
- package/dist/cjs/src/babylon/stakingParams.d.ts.map +1 -0
- package/dist/cjs/src/babylon/stakingParams.js +132 -0
- package/dist/cjs/src/babylon/undelegation/UndelegationResponse.d.ts +24 -0
- package/dist/cjs/src/babylon/undelegation/UndelegationResponse.d.ts.map +1 -0
- package/dist/cjs/src/babylon/undelegation/UndelegationResponse.js +55 -0
- package/dist/cjs/src/babylon/undelegation/index.d.ts +3 -0
- package/dist/cjs/src/babylon/undelegation/index.d.ts.map +1 -0
- package/dist/{src → cjs/src/babylon/undelegation}/index.js +3 -4
- package/dist/cjs/src/babylon/undelegation/unbonding.d.ts +16 -0
- package/dist/cjs/src/babylon/undelegation/unbonding.d.ts.map +1 -0
- package/dist/cjs/src/babylon/undelegation/unbonding.js +111 -0
- package/dist/cjs/src/coreDao/descriptor.d.ts.map +1 -0
- package/dist/cjs/src/coreDao/descriptor.js +38 -0
- package/dist/cjs/src/coreDao/index.d.ts.map +1 -0
- package/dist/{src → cjs/src}/coreDao/index.js +1 -1
- package/dist/cjs/src/coreDao/opReturn.d.ts.map +1 -0
- package/dist/cjs/src/coreDao/opReturn.js +183 -0
- package/dist/{src → cjs/src}/coreDao/transaction.d.ts +16 -7
- package/dist/cjs/src/coreDao/transaction.d.ts.map +1 -0
- package/dist/cjs/src/coreDao/transaction.js +34 -0
- package/dist/cjs/src/index.d.ts +3 -0
- package/dist/cjs/src/index.d.ts.map +1 -0
- package/dist/cjs/src/index.js +39 -0
- package/dist/cjs/test/unit/babylon/bug71.d.ts +2 -0
- package/dist/cjs/test/unit/babylon/bug71.d.ts.map +1 -0
- package/dist/cjs/test/unit/babylon/bug71.js +108 -0
- package/dist/cjs/test/unit/babylon/key.utils.d.ts +6 -0
- package/dist/cjs/test/unit/babylon/key.utils.d.ts.map +1 -0
- package/dist/cjs/test/unit/babylon/key.utils.js +68 -0
- package/dist/cjs/test/unit/babylon/transactions.d.ts +2 -0
- package/dist/cjs/test/unit/babylon/transactions.d.ts.map +1 -0
- package/dist/cjs/test/unit/babylon/transactions.js +338 -0
- package/dist/cjs/test/unit/babylon/undelegation.d.ts +2 -0
- package/dist/cjs/test/unit/babylon/undelegation.d.ts.map +1 -0
- package/dist/cjs/test/unit/babylon/undelegation.js +156 -0
- package/dist/cjs/test/unit/babylon/vendor.utils.d.ts +13 -0
- package/dist/cjs/test/unit/babylon/vendor.utils.d.ts.map +1 -0
- package/dist/cjs/test/unit/babylon/vendor.utils.js +78 -0
- package/dist/cjs/test/unit/coreDao/descriptor.d.ts +2 -0
- package/dist/cjs/test/unit/coreDao/descriptor.d.ts.map +1 -0
- package/dist/cjs/test/unit/coreDao/descriptor.js +144 -0
- package/dist/cjs/test/unit/coreDao/opReturn.d.ts +2 -0
- package/dist/cjs/test/unit/coreDao/opReturn.d.ts.map +1 -0
- package/dist/cjs/test/unit/coreDao/opReturn.js +275 -0
- package/dist/cjs/test/unit/coreDao/utils.d.ts +5 -0
- package/dist/cjs/test/unit/coreDao/utils.d.ts.map +1 -0
- package/dist/cjs/test/unit/coreDao/utils.js +54 -0
- package/dist/cjs/test/unit/fixtures.utils.d.ts +9 -0
- package/dist/cjs/test/unit/fixtures.utils.d.ts.map +1 -0
- package/dist/cjs/test/unit/fixtures.utils.js +91 -0
- package/dist/cjs/tsconfig.tsbuildinfo +1 -0
- package/dist/esm/babylon/delegationMessage.d.ts +38 -0
- package/dist/esm/babylon/delegationMessage.d.ts.map +1 -0
- package/dist/esm/babylon/delegationMessage.js +239 -0
- package/dist/esm/babylon/descriptor.d.ts +48 -0
- package/dist/esm/babylon/descriptor.d.ts.map +1 -0
- package/dist/esm/babylon/descriptor.js +91 -0
- package/dist/esm/babylon/index.d.ts +8 -0
- package/dist/esm/babylon/index.d.ts.map +1 -0
- package/dist/esm/babylon/index.js +13 -0
- package/dist/esm/babylon/network.d.ts +7 -0
- package/dist/esm/babylon/network.d.ts.map +1 -0
- package/dist/esm/babylon/network.js +29 -0
- package/dist/esm/babylon/params.mainnet.json +152 -0
- package/dist/esm/babylon/params.testnet.json +212 -0
- package/dist/esm/babylon/parseDescriptor.d.ts +26 -0
- package/dist/esm/babylon/parseDescriptor.d.ts.map +1 -0
- package/dist/esm/babylon/parseDescriptor.js +155 -0
- package/dist/esm/babylon/stakingManager.d.ts +6 -0
- package/dist/esm/babylon/stakingManager.d.ts.map +1 -0
- package/dist/esm/babylon/stakingManager.js +83 -0
- package/dist/esm/babylon/stakingParams.d.ts +40 -0
- package/dist/esm/babylon/stakingParams.d.ts.map +1 -0
- package/dist/esm/babylon/stakingParams.js +86 -0
- package/dist/esm/babylon/undelegation/UndelegationResponse.d.ts +24 -0
- package/dist/esm/babylon/undelegation/UndelegationResponse.d.ts.map +1 -0
- package/dist/esm/babylon/undelegation/UndelegationResponse.js +18 -0
- package/dist/esm/babylon/undelegation/index.d.ts +3 -0
- package/dist/esm/babylon/undelegation/index.d.ts.map +1 -0
- package/dist/esm/babylon/undelegation/index.js +3 -0
- package/dist/esm/babylon/undelegation/unbonding.d.ts +16 -0
- package/dist/esm/babylon/undelegation/unbonding.d.ts.map +1 -0
- package/dist/esm/babylon/undelegation/unbonding.js +70 -0
- package/dist/esm/coreDao/descriptor.d.ts +18 -0
- package/dist/{src → esm}/coreDao/descriptor.d.ts.map +1 -1
- package/dist/esm/coreDao/descriptor.js +35 -0
- package/dist/esm/coreDao/index.d.ts +4 -0
- package/dist/esm/coreDao/index.js +4 -0
- package/dist/esm/coreDao/opReturn.d.ts +41 -0
- package/dist/esm/coreDao/opReturn.js +175 -0
- package/dist/esm/coreDao/transaction.d.ts +28 -0
- package/dist/esm/coreDao/transaction.d.ts.map +1 -0
- package/dist/esm/coreDao/transaction.js +30 -0
- package/dist/esm/index.d.ts +3 -0
- package/dist/{src → esm}/index.d.ts.map +1 -1
- package/dist/esm/index.js +3 -0
- package/package.json +42 -12
- package/.eslintignore +0 -5
- package/.mocharc.yml +0 -8
- package/CHANGELOG.md +0 -63
- package/dist/src/coreDao/descriptor.js +0 -37
- package/dist/src/coreDao/opReturn.js +0 -183
- package/dist/src/coreDao/transaction.d.ts.map +0 -1
- package/dist/src/coreDao/transaction.js +0 -26
- package/dist/src/index.d.ts +0 -3
- package/dist/src/transaction.d.ts +0 -32
- package/dist/src/transaction.d.ts.map +0 -1
- package/dist/src/transaction.js +0 -54
- /package/dist/{src → cjs/src}/coreDao/descriptor.d.ts +0 -0
- /package/dist/{src → cjs/src}/coreDao/index.d.ts +0 -0
- /package/dist/{src → cjs/src}/coreDao/opReturn.d.ts +0 -0
- /package/dist/{src → esm}/coreDao/index.d.ts.map +0 -0
- /package/dist/{src → esm}/coreDao/opReturn.d.ts.map +0 -0
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"vendor.utils.d.ts","sourceRoot":"","sources":["../../../../../test/unit/babylon/vendor.utils.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,YAAY,MAAM,eAAe,CAAC;AAC9C,OAAO,EAAE,eAAe,EAAE,MAAM,sBAAsB,CAAC;AACvD,OAAO,KAAK,MAAM,MAAM,2CAA2C,CAAC;AACpE,OAAO,KAAK,eAAe,MAAM,kCAAkC,CAAC;AAIpE,OAAO,EACL,wBAAwB,EAGxB,gBAAgB,EACjB,MAAM,sBAAsB,CAAC;AAI9B,KAAK,MAAM,GAAG;IACZ,qBAAqB,EAAE,gBAAgB,CAAC,eAAe,CAAC,YAAY,CAAC,sBAAsB,CAAC,CAAC;IAC7F,SAAS,EAAE,YAAY,CAAC,WAAW,CAAC;CACrC,CAAC;AAEF,wBAAsB,yCAAyC,CAC7D,OAAO,EAAE,YAAY,CAAC,OAAO,EAC7B,SAAS,EAAE,eAAe,EAC1B,gBAAgB,EAAE,eAAe,EACjC,iBAAiB,EAAE,wBAAwB,EAC3C,aAAa,EAAE,MAAM,CAAC,sBAAsB,EAAE,EAC9C,aAAa,EAAE,MAAM,EACrB,MAAM,EAAE,MAAM,EACd,IAAI,EAAE,MAAM,CAAC,IAAI,EACjB,WAAW,EAAE,MAAM,EACnB,WAAW,EAAE,MAAM,GAClB,OAAO,CAAC,MAAM,CAAC,CAoBjB;AAED,wBAAsB,+BAA+B,CACnD,OAAO,EAAE,YAAY,CAAC,OAAO,EAC7B,SAAS,EAAE,eAAe,EAC1B,gBAAgB,EAAE,eAAe,EACjC,iBAAiB,EAAE,wBAAwB,EAC3C,aAAa,EAAE,MAAM,CAAC,sBAAsB,EAAE,EAC9C,aAAa,EAAE,MAAM,EACrB,MAAM,EAAE,MAAM,EACd,IAAI,EAAE,MAAM,CAAC,IAAI,EACjB,WAAW,EAAE,MAAM,EACnB,WAAW,EAAE,MAAM,GAClB,OAAO,CAAC,MAAM,CAAC,CAuCjB"}
|
|
@@ -0,0 +1,78 @@
|
|
|
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
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
36
|
+
exports.getBitGoUtxoStakingMsgCreateBtcDelegation = getBitGoUtxoStakingMsgCreateBtcDelegation;
|
|
37
|
+
exports.getVendorMsgCreateBtcDelegation = getVendorMsgCreateBtcDelegation;
|
|
38
|
+
const vendor = __importStar(require("@bitgo-beta/babylonlabs-io-btc-staking-ts"));
|
|
39
|
+
const babylonProtobuf = __importStar(require("@babylonlabs-io/babylon-proto-ts"));
|
|
40
|
+
const address_1 = require("bitcoinjs-lib/src/address");
|
|
41
|
+
const babylonlabs_io_btc_staking_ts_1 = require("@bitgo-beta/babylonlabs-io-btc-staking-ts");
|
|
42
|
+
const babylon_1 = require("../../../src/babylon");
|
|
43
|
+
const key_utils_1 = require("./key.utils");
|
|
44
|
+
async function getBitGoUtxoStakingMsgCreateBtcDelegation(network, stakerKey, finalityProvider, descriptorBuilder, stakingParams, changeAddress, amount, utxo, feeRateSatB, blockHeight) {
|
|
45
|
+
return await (0, babylon_1.createUnsignedPreStakeRegistrationBabylonTransactionWithBtcProvider)((0, babylon_1.getBtcProviderForECKey)(descriptorBuilder, stakerKey), network, {
|
|
46
|
+
address: changeAddress,
|
|
47
|
+
publicKeyNoCoordHex: (0, key_utils_1.getXOnlyPubkey)(stakerKey).toString('hex'),
|
|
48
|
+
}, {
|
|
49
|
+
finalityProviderPksNoCoordHex: [(0, key_utils_1.getXOnlyPubkey)(finalityProvider).toString('hex')],
|
|
50
|
+
stakingAmountSat: amount,
|
|
51
|
+
stakingTimelock: (0, babylonlabs_io_btc_staking_ts_1.getBabylonParamByBtcHeight)(blockHeight, stakingParams).minStakingTimeBlocks,
|
|
52
|
+
}, 800000, [utxo], feeRateSatB, (0, address_1.toBech32)(Buffer.from('test'), 0, 'bbn'), 'delegation:create', stakingParams);
|
|
53
|
+
}
|
|
54
|
+
async function getVendorMsgCreateBtcDelegation(network, stakerKey, finalityProvider, descriptorBuilder, stakingParams, changeAddress, amount, utxo, feeRateSatB, blockHeight) {
|
|
55
|
+
const babylonProvider = {
|
|
56
|
+
async signTransaction(msg) {
|
|
57
|
+
// return unsigned payload
|
|
58
|
+
return babylonProtobuf.btcstakingtx.MsgCreateBTCDelegation.encode(msg.value).finish();
|
|
59
|
+
},
|
|
60
|
+
};
|
|
61
|
+
const manager = new vendor.BabylonBtcStakingManager(network, stakingParams, (0, babylon_1.getBtcProviderForECKey)(descriptorBuilder, stakerKey), babylonProvider);
|
|
62
|
+
const result = await manager.preStakeRegistrationBabylonTransaction({
|
|
63
|
+
address: changeAddress,
|
|
64
|
+
publicKeyNoCoordHex: (0, key_utils_1.getXOnlyPubkey)(stakerKey).toString('hex'),
|
|
65
|
+
}, {
|
|
66
|
+
finalityProviderPksNoCoordHex: [(0, key_utils_1.getXOnlyPubkey)(finalityProvider).toString('hex')],
|
|
67
|
+
stakingAmountSat: amount,
|
|
68
|
+
stakingTimelock: (0, babylonlabs_io_btc_staking_ts_1.getBabylonParamByBtcHeight)(blockHeight, stakingParams).minStakingTimeBlocks,
|
|
69
|
+
}, blockHeight, [utxo], feeRateSatB, (0, address_1.toBech32)(Buffer.from('test'), 0, 'bbn'));
|
|
70
|
+
return {
|
|
71
|
+
unsignedDelegationMsg: {
|
|
72
|
+
typeUrl: '/babylon.btcstaking.v1.MsgCreateBTCDelegation',
|
|
73
|
+
value: babylonProtobuf.btcstakingtx.MsgCreateBTCDelegation.decode(result.signedBabylonTx),
|
|
74
|
+
},
|
|
75
|
+
stakingTx: result.stakingTx,
|
|
76
|
+
};
|
|
77
|
+
}
|
|
78
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoidmVuZG9yLnV0aWxzLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vLi4vLi4vLi4vdGVzdC91bml0L2JhYnlsb24vdmVuZG9yLnV0aWxzLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiI7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7O0FBcUJBLDhGQStCQztBQUVELDBFQWtEQztBQXRHRCxrRkFBb0U7QUFDcEUsa0ZBQW9FO0FBQ3BFLHVEQUFxRDtBQUNyRCw2RkFBdUY7QUFFdkYsa0RBSzhCO0FBRTlCLDJDQUE2QztBQU90QyxLQUFLLFVBQVUseUNBQXlDLENBQzdELE9BQTZCLEVBQzdCLFNBQTBCLEVBQzFCLGdCQUFpQyxFQUNqQyxpQkFBMkMsRUFDM0MsYUFBOEMsRUFDOUMsYUFBcUIsRUFDckIsTUFBYyxFQUNkLElBQWlCLEVBQ2pCLFdBQW1CLEVBQ25CLFdBQW1CO0lBRW5CLE9BQU8sTUFBTSxJQUFBLDZFQUFtRSxFQUM5RSxJQUFBLGdDQUFzQixFQUFDLGlCQUFpQixFQUFFLFNBQVMsQ0FBQyxFQUNwRCxPQUFPLEVBQ1A7UUFDRSxPQUFPLEVBQUUsYUFBYTtRQUN0QixtQkFBbUIsRUFBRSxJQUFBLDBCQUFjLEVBQUMsU0FBUyxDQUFDLENBQUMsUUFBUSxDQUFDLEtBQUssQ0FBQztLQUMvRCxFQUNEO1FBQ0UsNkJBQTZCLEVBQUUsQ0FBQyxJQUFBLDBCQUFjLEVBQUMsZ0JBQWdCLENBQUMsQ0FBQyxRQUFRLENBQUMsS0FBSyxDQUFDLENBQUM7UUFDakYsZ0JBQWdCLEVBQUUsTUFBTTtRQUN4QixlQUFlLEVBQUUsSUFBQSwwREFBMEIsRUFBQyxXQUFXLEVBQUUsYUFBYSxDQUFDLENBQUMsb0JBQW9CO0tBQzdGLEVBQ0QsTUFBTyxFQUNQLENBQUMsSUFBSSxDQUFDLEVBQ04sV0FBVyxFQUNYLElBQUEsa0JBQVEsRUFBQyxNQUFNLENBQUMsSUFBSSxDQUFDLE1BQU0sQ0FBQyxFQUFFLENBQUMsRUFBRSxLQUFLLENBQUMsRUFDdkMsbUJBQW1CLEVBQ25CLGFBQWEsQ0FDZCxDQUFDO0FBQ0osQ0FBQztBQUVNLEtBQUssVUFBVSwrQkFBK0IsQ0FDbkQsT0FBNkIsRUFDN0IsU0FBMEIsRUFDMUIsZ0JBQWlDLEVBQ2pDLGlCQUEyQyxFQUMzQyxhQUE4QyxFQUM5QyxhQUFxQixFQUNyQixNQUFjLEVBQ2QsSUFBaUIsRUFDakIsV0FBbUIsRUFDbkIsV0FBbUI7SUFFbkIsTUFBTSxlQUFlLEdBQTJCO1FBQzlDLEtBQUssQ0FBQyxlQUFlLENBQUMsR0FBRztZQUN2QiwwQkFBMEI7WUFDMUIsT0FBTyxlQUFlLENBQUMsWUFBWSxDQUFDLHNCQUFzQixDQUFDLE1BQU0sQ0FDL0QsR0FBRyxDQUFDLEtBQTRELENBQ2pFLENBQUMsTUFBTSxFQUFFLENBQUM7UUFDYixDQUFDO0tBQ0YsQ0FBQztJQUNGLE1BQU0sT0FBTyxHQUFHLElBQUksTUFBTSxDQUFDLHdCQUF3QixDQUNqRCxPQUFPLEVBQ1AsYUFBYSxFQUNiLElBQUEsZ0NBQXNCLEVBQUMsaUJBQWlCLEVBQUUsU0FBUyxDQUFDLEVBQ3BELGVBQWUsQ0FDaEIsQ0FBQztJQUVGLE1BQU0sTUFBTSxHQUFHLE1BQU0sT0FBTyxDQUFDLHNDQUFzQyxDQUNqRTtRQUNFLE9BQU8sRUFBRSxhQUFhO1FBQ3RCLG1CQUFtQixFQUFFLElBQUEsMEJBQWMsRUFBQyxTQUFTLENBQUMsQ0FBQyxRQUFRLENBQUMsS0FBSyxDQUFDO0tBQy9ELEVBQ0Q7UUFDRSw2QkFBNkIsRUFBRSxDQUFDLElBQUEsMEJBQWMsRUFBQyxnQkFBZ0IsQ0FBQyxDQUFDLFFBQVEsQ0FBQyxLQUFLLENBQUMsQ0FBQztRQUNqRixnQkFBZ0IsRUFBRSxNQUFNO1FBQ3hCLGVBQWUsRUFBRSxJQUFBLDBEQUEwQixFQUFDLFdBQVcsRUFBRSxhQUFhLENBQUMsQ0FBQyxvQkFBb0I7S0FDN0YsRUFDRCxXQUFXLEVBQ1gsQ0FBQyxJQUFJLENBQUMsRUFDTixXQUFXLEVBQ1gsSUFBQSxrQkFBUSxFQUFDLE1BQU0sQ0FBQyxJQUFJLENBQUMsTUFBTSxDQUFDLEVBQUUsQ0FBQyxFQUFFLEtBQUssQ0FBQyxDQUN4QyxDQUFDO0lBRUYsT0FBTztRQUNMLHFCQUFxQixFQUFFO1lBQ3JCLE9BQU8sRUFBRSwrQ0FBK0M7WUFDeEQsS0FBSyxFQUFFLGVBQWUsQ0FBQyxZQUFZLENBQUMsc0JBQXNCLENBQUMsTUFBTSxDQUFDLE1BQU0sQ0FBQyxlQUFlLENBQUM7U0FDMUY7UUFDRCxTQUFTLEVBQUUsTUFBTSxDQUFDLFNBQVM7S0FDNUIsQ0FBQztBQUNKLENBQUMiLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQgKiBhcyBiaXRjb2luanNsaWIgZnJvbSAnYml0Y29pbmpzLWxpYic7XG5pbXBvcnQgeyBFQ1BhaXJJbnRlcmZhY2UgfSBmcm9tICdAYml0Z28tYmV0YS91dHhvLWxpYic7XG5pbXBvcnQgKiBhcyB2ZW5kb3IgZnJvbSAnQGJpdGdvLWJldGEvYmFieWxvbmxhYnMtaW8tYnRjLXN0YWtpbmctdHMnO1xuaW1wb3J0ICogYXMgYmFieWxvblByb3RvYnVmIGZyb20gJ0BiYWJ5bG9ubGFicy1pby9iYWJ5bG9uLXByb3RvLXRzJztcbmltcG9ydCB7IHRvQmVjaDMyIH0gZnJvbSAnYml0Y29pbmpzLWxpYi9zcmMvYWRkcmVzcyc7XG5pbXBvcnQgeyBnZXRCYWJ5bG9uUGFyYW1CeUJ0Y0hlaWdodCB9IGZyb20gJ0BiaXRnby1iZXRhL2JhYnlsb25sYWJzLWlvLWJ0Yy1zdGFraW5nLXRzJztcblxuaW1wb3J0IHtcbiAgQmFieWxvbkRlc2NyaXB0b3JCdWlsZGVyLFxuICBjcmVhdGVVbnNpZ25lZFByZVN0YWtlUmVnaXN0cmF0aW9uQmFieWxvblRyYW5zYWN0aW9uV2l0aEJ0Y1Byb3ZpZGVyLFxuICBnZXRCdGNQcm92aWRlckZvckVDS2V5LFxuICBWYWx1ZVdpdGhUeXBlVXJsLFxufSBmcm9tICcuLi8uLi8uLi9zcmMvYmFieWxvbic7XG5cbmltcG9ydCB7IGdldFhPbmx5UHVia2V5IH0gZnJvbSAnLi9rZXkudXRpbHMnO1xuXG50eXBlIFJlc3VsdCA9IHtcbiAgdW5zaWduZWREZWxlZ2F0aW9uTXNnOiBWYWx1ZVdpdGhUeXBlVXJsPGJhYnlsb25Qcm90b2J1Zi5idGNzdGFraW5ndHguTXNnQ3JlYXRlQlRDRGVsZWdhdGlvbj47XG4gIHN0YWtpbmdUeDogYml0Y29pbmpzbGliLlRyYW5zYWN0aW9uO1xufTtcblxuZXhwb3J0IGFzeW5jIGZ1bmN0aW9uIGdldEJpdEdvVXR4b1N0YWtpbmdNc2dDcmVhdGVCdGNEZWxlZ2F0aW9uKFxuICBuZXR3b3JrOiBiaXRjb2luanNsaWIuTmV0d29yayxcbiAgc3Rha2VyS2V5OiBFQ1BhaXJJbnRlcmZhY2UsXG4gIGZpbmFsaXR5UHJvdmlkZXI6IEVDUGFpckludGVyZmFjZSxcbiAgZGVzY3JpcHRvckJ1aWxkZXI6IEJhYnlsb25EZXNjcmlwdG9yQnVpbGRlcixcbiAgc3Rha2luZ1BhcmFtczogdmVuZG9yLlZlcnNpb25lZFN0YWtpbmdQYXJhbXNbXSxcbiAgY2hhbmdlQWRkcmVzczogc3RyaW5nLFxuICBhbW91bnQ6IG51bWJlcixcbiAgdXR4bzogdmVuZG9yLlVUWE8sXG4gIGZlZVJhdGVTYXRCOiBudW1iZXIsXG4gIGJsb2NrSGVpZ2h0OiBudW1iZXJcbik6IFByb21pc2U8UmVzdWx0PiB7XG4gIHJldHVybiBhd2FpdCBjcmVhdGVVbnNpZ25lZFByZVN0YWtlUmVnaXN0cmF0aW9uQmFieWxvblRyYW5zYWN0aW9uV2l0aEJ0Y1Byb3ZpZGVyKFxuICAgIGdldEJ0Y1Byb3ZpZGVyRm9yRUNLZXkoZGVzY3JpcHRvckJ1aWxkZXIsIHN0YWtlcktleSksXG4gICAgbmV0d29yayxcbiAgICB7XG4gICAgICBhZGRyZXNzOiBjaGFuZ2VBZGRyZXNzLFxuICAgICAgcHVibGljS2V5Tm9Db29yZEhleDogZ2V0WE9ubHlQdWJrZXkoc3Rha2VyS2V5KS50b1N0cmluZygnaGV4JyksXG4gICAgfSxcbiAgICB7XG4gICAgICBmaW5hbGl0eVByb3ZpZGVyUGtzTm9Db29yZEhleDogW2dldFhPbmx5UHVia2V5KGZpbmFsaXR5UHJvdmlkZXIpLnRvU3RyaW5nKCdoZXgnKV0sXG4gICAgICBzdGFraW5nQW1vdW50U2F0OiBhbW91bnQsXG4gICAgICBzdGFraW5nVGltZWxvY2s6IGdldEJhYnlsb25QYXJhbUJ5QnRjSGVpZ2h0KGJsb2NrSGVpZ2h0LCBzdGFraW5nUGFyYW1zKS5taW5TdGFraW5nVGltZUJsb2NrcyxcbiAgICB9LFxuICAgIDgwMF8wMDAsXG4gICAgW3V0eG9dLFxuICAgIGZlZVJhdGVTYXRCLFxuICAgIHRvQmVjaDMyKEJ1ZmZlci5mcm9tKCd0ZXN0JyksIDAsICdiYm4nKSxcbiAgICAnZGVsZWdhdGlvbjpjcmVhdGUnLFxuICAgIHN0YWtpbmdQYXJhbXNcbiAgKTtcbn1cblxuZXhwb3J0IGFzeW5jIGZ1bmN0aW9uIGdldFZlbmRvck1zZ0NyZWF0ZUJ0Y0RlbGVnYXRpb24oXG4gIG5ldHdvcms6IGJpdGNvaW5qc2xpYi5OZXR3b3JrLFxuICBzdGFrZXJLZXk6IEVDUGFpckludGVyZmFjZSxcbiAgZmluYWxpdHlQcm92aWRlcjogRUNQYWlySW50ZXJmYWNlLFxuICBkZXNjcmlwdG9yQnVpbGRlcjogQmFieWxvbkRlc2NyaXB0b3JCdWlsZGVyLFxuICBzdGFraW5nUGFyYW1zOiB2ZW5kb3IuVmVyc2lvbmVkU3Rha2luZ1BhcmFtc1tdLFxuICBjaGFuZ2VBZGRyZXNzOiBzdHJpbmcsXG4gIGFtb3VudDogbnVtYmVyLFxuICB1dHhvOiB2ZW5kb3IuVVRYTyxcbiAgZmVlUmF0ZVNhdEI6IG51bWJlcixcbiAgYmxvY2tIZWlnaHQ6IG51bWJlclxuKTogUHJvbWlzZTxSZXN1bHQ+IHtcbiAgY29uc3QgYmFieWxvblByb3ZpZGVyOiB2ZW5kb3IuQmFieWxvblByb3ZpZGVyID0ge1xuICAgIGFzeW5jIHNpZ25UcmFuc2FjdGlvbihtc2cpIHtcbiAgICAgIC8vIHJldHVybiB1bnNpZ25lZCBwYXlsb2FkXG4gICAgICByZXR1cm4gYmFieWxvblByb3RvYnVmLmJ0Y3N0YWtpbmd0eC5Nc2dDcmVhdGVCVENEZWxlZ2F0aW9uLmVuY29kZShcbiAgICAgICAgbXNnLnZhbHVlIGFzIGJhYnlsb25Qcm90b2J1Zi5idGNzdGFraW5ndHguTXNnQ3JlYXRlQlRDRGVsZWdhdGlvblxuICAgICAgKS5maW5pc2goKTtcbiAgICB9LFxuICB9O1xuICBjb25zdCBtYW5hZ2VyID0gbmV3IHZlbmRvci5CYWJ5bG9uQnRjU3Rha2luZ01hbmFnZXIoXG4gICAgbmV0d29yayxcbiAgICBzdGFraW5nUGFyYW1zLFxuICAgIGdldEJ0Y1Byb3ZpZGVyRm9yRUNLZXkoZGVzY3JpcHRvckJ1aWxkZXIsIHN0YWtlcktleSksXG4gICAgYmFieWxvblByb3ZpZGVyXG4gICk7XG5cbiAgY29uc3QgcmVzdWx0ID0gYXdhaXQgbWFuYWdlci5wcmVTdGFrZVJlZ2lzdHJhdGlvbkJhYnlsb25UcmFuc2FjdGlvbihcbiAgICB7XG4gICAgICBhZGRyZXNzOiBjaGFuZ2VBZGRyZXNzLFxuICAgICAgcHVibGljS2V5Tm9Db29yZEhleDogZ2V0WE9ubHlQdWJrZXkoc3Rha2VyS2V5KS50b1N0cmluZygnaGV4JyksXG4gICAgfSxcbiAgICB7XG4gICAgICBmaW5hbGl0eVByb3ZpZGVyUGtzTm9Db29yZEhleDogW2dldFhPbmx5UHVia2V5KGZpbmFsaXR5UHJvdmlkZXIpLnRvU3RyaW5nKCdoZXgnKV0sXG4gICAgICBzdGFraW5nQW1vdW50U2F0OiBhbW91bnQsXG4gICAgICBzdGFraW5nVGltZWxvY2s6IGdldEJhYnlsb25QYXJhbUJ5QnRjSGVpZ2h0KGJsb2NrSGVpZ2h0LCBzdGFraW5nUGFyYW1zKS5taW5TdGFraW5nVGltZUJsb2NrcyxcbiAgICB9LFxuICAgIGJsb2NrSGVpZ2h0LFxuICAgIFt1dHhvXSxcbiAgICBmZWVSYXRlU2F0QixcbiAgICB0b0JlY2gzMihCdWZmZXIuZnJvbSgndGVzdCcpLCAwLCAnYmJuJylcbiAgKTtcblxuICByZXR1cm4ge1xuICAgIHVuc2lnbmVkRGVsZWdhdGlvbk1zZzoge1xuICAgICAgdHlwZVVybDogJy9iYWJ5bG9uLmJ0Y3N0YWtpbmcudjEuTXNnQ3JlYXRlQlRDRGVsZWdhdGlvbicsXG4gICAgICB2YWx1ZTogYmFieWxvblByb3RvYnVmLmJ0Y3N0YWtpbmd0eC5Nc2dDcmVhdGVCVENEZWxlZ2F0aW9uLmRlY29kZShyZXN1bHQuc2lnbmVkQmFieWxvblR4KSxcbiAgICB9LFxuICAgIHN0YWtpbmdUeDogcmVzdWx0LnN0YWtpbmdUeCxcbiAgfTtcbn1cbiJdfQ==
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"descriptor.d.ts","sourceRoot":"","sources":["../../../../../test/unit/coreDao/descriptor.ts"],"names":[],"mappings":""}
|
|
@@ -0,0 +1,144 @@
|
|
|
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
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
36
|
+
const assert = __importStar(require("assert"));
|
|
37
|
+
const utxolib = __importStar(require("@bitgo-beta/utxo-lib"));
|
|
38
|
+
const wasm_utxo_1 = require("@bitgo/wasm-utxo");
|
|
39
|
+
const testutil_1 = require("@bitgo-beta/utxo-core/testutil");
|
|
40
|
+
const coreDao_1 = require("../../../src/coreDao");
|
|
41
|
+
const utils_1 = require("./utils");
|
|
42
|
+
describe('descriptor', function () {
|
|
43
|
+
const baseFixturePath = 'test/fixtures/coreDao/descriptor/';
|
|
44
|
+
const rootWalletKeys = utxolib.testutil.getDefaultWalletKeys();
|
|
45
|
+
const key1 = rootWalletKeys.triple[0];
|
|
46
|
+
const key2 = rootWalletKeys.triple[1];
|
|
47
|
+
const key3 = rootWalletKeys.triple[2];
|
|
48
|
+
const validLocktime = 2048;
|
|
49
|
+
it('should fail if m is longer than the number of keys or not at least 1', function () {
|
|
50
|
+
assert.throws(() => {
|
|
51
|
+
(0, coreDao_1.createMultiSigDescriptor)('sh', validLocktime, 3, [key1, key2], false);
|
|
52
|
+
});
|
|
53
|
+
assert.throws(() => {
|
|
54
|
+
(0, coreDao_1.createMultiSigDescriptor)('sh', validLocktime, 0, [key1, key2], false);
|
|
55
|
+
});
|
|
56
|
+
});
|
|
57
|
+
it('should fail if locktime is invalid', function () {
|
|
58
|
+
assert.throws(() => {
|
|
59
|
+
(0, coreDao_1.createMultiSigDescriptor)('sh', 0, 2, [key1, key2], false);
|
|
60
|
+
});
|
|
61
|
+
});
|
|
62
|
+
async function runTestForParams(scriptType, m, keys) {
|
|
63
|
+
const fixturePath = baseFixturePath + `${scriptType}-${m}of${keys.length}`;
|
|
64
|
+
describe(`should create a ${m} of ${keys.length} multi-sig ${scriptType} descriptor`, function () {
|
|
65
|
+
it('has expected descriptor string', async function () {
|
|
66
|
+
const descriptorString = (0, coreDao_1.createMultiSigDescriptor)(scriptType, validLocktime, m, keys, false);
|
|
67
|
+
assert.strictEqual(descriptorString, await (0, testutil_1.getFixture)(fixturePath + `-string.txt`, descriptorString), descriptorString);
|
|
68
|
+
});
|
|
69
|
+
it('has expected AST', async function () {
|
|
70
|
+
const descriptor = wasm_utxo_1.Descriptor.fromString((0, coreDao_1.createMultiSigDescriptor)(scriptType, validLocktime, m, keys, false), 'derivable');
|
|
71
|
+
assert.deepStrictEqual(descriptor.node(), await (0, testutil_1.getFixture)(fixturePath + '-ast.json', descriptor.node()));
|
|
72
|
+
});
|
|
73
|
+
it('has expected asm', async function () {
|
|
74
|
+
const descriptor = wasm_utxo_1.Descriptor.fromString((0, coreDao_1.createMultiSigDescriptor)(scriptType, validLocktime, m, keys, false), 'derivable');
|
|
75
|
+
const asmString = descriptor.atDerivationIndex(0).toAsmString();
|
|
76
|
+
assert.strictEqual(asmString, await (0, testutil_1.getFixture)(fixturePath + '-asm.txt', asmString), asmString);
|
|
77
|
+
});
|
|
78
|
+
it('can be signed', async function () {
|
|
79
|
+
// Derive the script from the descriptor
|
|
80
|
+
const descriptor = wasm_utxo_1.Descriptor.fromString((0, coreDao_1.createMultiSigDescriptor)(scriptType, validLocktime, m, keys, false), 'derivable');
|
|
81
|
+
const descriptorAt0 = descriptor.atDerivationIndex(0);
|
|
82
|
+
const script = Buffer.from(descriptorAt0.scriptPubkey());
|
|
83
|
+
// Make the prevTx
|
|
84
|
+
const prevPsbt = utxolib.testutil.constructPsbt([{ scriptType: 'p2wsh', value: BigInt(1.1e8) }], [{ script: script.toString('hex'), value: BigInt(1e8) }], utxolib.networks.bitcoin, rootWalletKeys, 'fullsigned');
|
|
85
|
+
const prevTx = prevPsbt.finalizeAllInputs().extractTransaction();
|
|
86
|
+
// Create the PSBT and sign
|
|
87
|
+
const psbt = Object.assign(new utxolib.Psbt({ network: utxolib.networks.bitcoin }), {
|
|
88
|
+
locktime: validLocktime,
|
|
89
|
+
});
|
|
90
|
+
psbt.addInput({
|
|
91
|
+
hash: prevTx.getId(),
|
|
92
|
+
index: 0,
|
|
93
|
+
sequence: 0xfffffffe,
|
|
94
|
+
});
|
|
95
|
+
if (scriptType === 'sh-wsh') {
|
|
96
|
+
psbt.updateInput(0, { witnessUtxo: { script, value: BigInt(1e8) } });
|
|
97
|
+
}
|
|
98
|
+
else {
|
|
99
|
+
psbt.updateInput(0, { nonWitnessUtxo: prevTx.toBuffer() });
|
|
100
|
+
}
|
|
101
|
+
psbt.addOutput({ script, value: BigInt(0.9e8) });
|
|
102
|
+
(0, utils_1.updateInputWithDescriptor)(psbt, 0, descriptorAt0);
|
|
103
|
+
keys.forEach((signer, i) => {
|
|
104
|
+
if (i >= m) {
|
|
105
|
+
return;
|
|
106
|
+
}
|
|
107
|
+
psbt.signAllInputsHD(signer);
|
|
108
|
+
});
|
|
109
|
+
// Get the fully signed transaction and check
|
|
110
|
+
const signedTx = (0, utils_1.finalizePsbt)(psbt).extractTransaction().toBuffer();
|
|
111
|
+
assert.strictEqual(signedTx.toString('hex'), await (0, testutil_1.getFixture)(fixturePath + '-tx.txt', signedTx.toString('hex')));
|
|
112
|
+
});
|
|
113
|
+
});
|
|
114
|
+
}
|
|
115
|
+
runTestForParams('sh', 2, [key1, key2]);
|
|
116
|
+
runTestForParams('sh-wsh', 2, [key1, key2]);
|
|
117
|
+
runTestForParams('sh', 3, [key1, key2, key3]);
|
|
118
|
+
runTestForParams('wsh', 3, [key1, key2, key3]);
|
|
119
|
+
it('should recreate the script used in testnet staking transaction', function () {
|
|
120
|
+
// Source: https://mempool.space/testnet/address/2MxTi2EhHKgdJFKRTBttVGGxir9ZzjmKCXw
|
|
121
|
+
// 2 of 2 multisig
|
|
122
|
+
const timelock = 'fce4cb66';
|
|
123
|
+
const pubkey1 = '03ecb6d4b7f5d56962e547fc52dd588359f5729c0ba856d6978b84723895a16691';
|
|
124
|
+
const pubkey2 = '024aaea25d82b1db2be030a05b641d6302e48ed652b1ca9cb08a67267fcbb56747';
|
|
125
|
+
const redeemScriptASM = [
|
|
126
|
+
'OP_PUSHBYTES_4',
|
|
127
|
+
timelock,
|
|
128
|
+
'OP_CLTV',
|
|
129
|
+
'OP_DROP',
|
|
130
|
+
'OP_PUSHNUM_2',
|
|
131
|
+
'OP_PUSHBYTES_33',
|
|
132
|
+
pubkey1,
|
|
133
|
+
'OP_PUSHBYTES_33',
|
|
134
|
+
pubkey2,
|
|
135
|
+
'OP_PUSHNUM_2',
|
|
136
|
+
'OP_CHECKMULTISIG',
|
|
137
|
+
].join(' ');
|
|
138
|
+
const decodedTimelock = (0, coreDao_1.decodeTimelock)(Buffer.from(timelock, 'hex'));
|
|
139
|
+
const descriptor = (0, coreDao_1.createMultiSigDescriptor)('sh', decodedTimelock, 2, [Buffer.from(pubkey1, 'hex'), Buffer.from(pubkey2, 'hex')], false);
|
|
140
|
+
const descriptorASM = wasm_utxo_1.Descriptor.fromString(descriptor, 'definite').toAsmString();
|
|
141
|
+
assert.deepStrictEqual(redeemScriptASM, descriptorASM);
|
|
142
|
+
});
|
|
143
|
+
});
|
|
144
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiZGVzY3JpcHRvci5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uLy4uLy4uL3Rlc3QvdW5pdC9jb3JlRGFvL2Rlc2NyaXB0b3IudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6Ijs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7QUFBQSwrQ0FBaUM7QUFFakMsOERBQWdEO0FBQ2hELGdEQUE4QztBQUM5Qyw2REFBNEQ7QUFFNUQsa0RBQWdGO0FBRWhGLG1DQUFrRTtBQUVsRSxRQUFRLENBQUMsWUFBWSxFQUFFO0lBQ3JCLE1BQU0sZUFBZSxHQUFHLG1DQUFtQyxDQUFDO0lBQzVELE1BQU0sY0FBYyxHQUFHLE9BQU8sQ0FBQyxRQUFRLENBQUMsb0JBQW9CLEVBQUUsQ0FBQztJQUMvRCxNQUFNLElBQUksR0FBRyxjQUFjLENBQUMsTUFBTSxDQUFDLENBQUMsQ0FBQyxDQUFDO0lBQ3RDLE1BQU0sSUFBSSxHQUFHLGNBQWMsQ0FBQyxNQUFNLENBQUMsQ0FBQyxDQUFDLENBQUM7SUFDdEMsTUFBTSxJQUFJLEdBQUcsY0FBYyxDQUFDLE1BQU0sQ0FBQyxDQUFDLENBQUMsQ0FBQztJQUN0QyxNQUFNLGFBQWEsR0FBRyxJQUFJLENBQUM7SUFFM0IsRUFBRSxDQUFDLHNFQUFzRSxFQUFFO1FBQ3pFLE1BQU0sQ0FBQyxNQUFNLENBQUMsR0FBRyxFQUFFO1lBQ2pCLElBQUEsa0NBQXdCLEVBQUMsSUFBSSxFQUFFLGFBQWEsRUFBRSxDQUFDLEVBQUUsQ0FBQyxJQUFJLEVBQUUsSUFBSSxDQUFDLEVBQUUsS0FBSyxDQUFDLENBQUM7UUFDeEUsQ0FBQyxDQUFDLENBQUM7UUFFSCxNQUFNLENBQUMsTUFBTSxDQUFDLEdBQUcsRUFBRTtZQUNqQixJQUFBLGtDQUF3QixFQUFDLElBQUksRUFBRSxhQUFhLEVBQUUsQ0FBQyxFQUFFLENBQUMsSUFBSSxFQUFFLElBQUksQ0FBQyxFQUFFLEtBQUssQ0FBQyxDQUFDO1FBQ3hFLENBQUMsQ0FBQyxDQUFD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O1FBQ2xCLE1BQU0sUUFBUSxHQUFHLFVBQVUsQ0FBQztRQUM1QixNQUFNLE9BQU8sR0FBRyxvRUFBb0UsQ0FBQztRQUNyRixNQUFNLE9BQU8sR0FBRyxvRUFBb0UsQ0FBQztRQUNyRixNQUFNLGVBQWUsR0FBRztZQUN0QixnQkFBZ0I7WUFDaEIsUUFBUTtZQUNSLFNBQVM7WUFDVCxTQUFTO1lBQ1QsY0FBYztZQUNkLGlCQUFpQjtZQUNqQixPQUFPO1lBQ1AsaUJBQWlCO1lBQ2pCLE9BQU87WUFDUCxjQUFjO1lBQ2Qsa0JBQWtCO1NBQ25CLENBQUMsSUFBSSxDQUFDLEdBQUcsQ0FBQyxDQUFDO1FBRVosTUFBTSxlQUFlLEdBQUcsSUFBQSx3QkFBYyxFQUFDLE1BQU0sQ0FBQyxJQUFJLENBQUMsUUFBUSxFQUFFLEtBQUssQ0FBQyxDQUFDLENBQUM7UUFDckUsTUFBTSxVQUFVLEdBQUcsSUFBQSxrQ0FBd0IsRUFDekMsSUFBSSxFQUNKLGVBQWUsRUFDZixDQUFDLEVBQ0QsQ0FBQyxNQUFNLENBQUMsSUFBSSxDQUFDLE9BQU8sRUFBRSxLQUFLLENBQUMsRUFBRSxNQUFNLENBQUMsSUFBSSxDQUFDLE9BQU8sRUFBRSxLQUFLLENBQUMsQ0FBQyxFQUMxRCxLQUFLLENBQ04sQ0FBQztRQUNGLE1BQU0sYUFBYSxHQUFHLHNCQUFVLENBQUMsVUFBVSxDQUFDLFVBQVUsRUFBRSxVQUFVLENBQUMsQ0FBQyxXQUFXLEVBQUUsQ0FBQztRQUNsRixNQUFNLENBQUMsZUFBZSxDQUFDLGVBQWUsRUFBRSxhQUFhLENBQUMsQ0FBQztJQUN6RCxDQUFDLENBQUMsQ0FBQztBQUNMLENBQUMsQ0FBQyxDQUFDIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0ICogYXMgYXNzZXJ0IGZyb20gJ2Fzc2VydCc7XG5cbmltcG9ydCAqIGFzIHV0eG9saWIgZnJvbSAnQGJpdGdvLWJldGEvdXR4by1saWInO1xuaW1wb3J0IHsgRGVzY3JpcHRvciB9IGZyb20gJ0BiaXRnby93YXNtLXV0eG8nO1xuaW1wb3J0IHsgZ2V0Rml4dHVyZSB9IGZyb20gJ0BiaXRnby1iZXRhL3V0eG8tY29yZS90ZXN0dXRpbCc7XG5cbmltcG9ydCB7IGNyZWF0ZU11bHRpU2lnRGVzY3JpcHRvciwgZGVjb2RlVGltZWxvY2sgfSBmcm9tICcuLi8uLi8uLi9zcmMvY29yZURhbyc7XG5cbmltcG9ydCB7IGZpbmFsaXplUHNidCwgdXBkYXRlSW5wdXRXaXRoRGVzY3JpcHRvciB9IGZyb20gJy4vdXRpbHMnO1xuXG5kZXNjcmliZSgnZGVzY3JpcHRvcicsIGZ1bmN0aW9uICgpIHtcbiAgY29uc3QgYmFzZUZpeHR1cmVQYXRoID0gJ3Rlc3QvZml4dHVyZXMvY29yZURhby9kZXNjcmlwdG9yLyc7XG4gIGNvbnN0IHJvb3RXYWxsZXRLZXlzID0gdXR4b2xpYi50ZXN0dXRpbC5nZXREZWZhdWx0V2FsbGV0S2V5cygpO1xuICBjb25zdCBrZXkxID0gcm9vdFdhbGxldEtleXMudHJpcGxlWzBdO1xuICBjb25zdCBrZXkyID0gcm9vdFdhbGxldEtleXMudHJpcGxlWzFdO1xuICBjb25zdCBrZXkzID0gcm9vdFdhbGxldEtleXMudHJpcGxlWzJdO1xuICBjb25zdCB2YWxpZExvY2t0aW1lID0gMjA0ODtcblxuICBpdCgnc2hvdWxkIGZhaWwgaWYgbSBpcyBsb25nZXIgdGhhbiB0aGUgbnVtYmVyIG9mIGtleXMgb3Igbm90IGF0IGxlYXN0IDEnLCBmdW5jdGlvbiAoKSB7XG4gICAgYXNzZXJ0LnRocm93cygoKSA9PiB7XG4gICAgICBjcmVhdGVNdWx0aVNpZ0Rlc2NyaXB0b3IoJ3NoJywgdmFsaWRMb2NrdGltZSwgMywgW2tleTEsIGtleTJdLCBmYWxzZSk7XG4gICAgfSk7XG5cbiAgICBhc3NlcnQudGhyb3dzKCgpID0+IHtcbiAgICAgIGNyZWF0ZU11bHRpU2lnRGVzY3JpcHRvcignc2gnLCB2YWxpZExvY2t0aW1lLCAwLCBba2V5MSwga2V5Ml0sIGZhbHNlKTtcbiAgICB9KTtcbiAgfSk7XG5cbiAgaXQoJ3Nob3VsZCBmYWlsIGlmIGxvY2t0aW1lIGlzIGludmFsaWQnLCBmdW5jdGlvbiAoKSB7XG4gICAgYXNzZXJ0LnRocm93cygoKSA9PiB7XG4gICAgICBjcmVhdGVNdWx0aVNpZ0Rlc2NyaXB0b3IoJ3NoJywgMCwgMiwgW2tleTEsIGtleTJdLCBmYWxzZSk7XG4gICAgfSk7XG4gIH0pO1xuXG4gIGFzeW5jIGZ1bmN0aW9uIHJ1blRlc3RGb3JQYXJhbXMoc2NyaXB0VHlwZTogJ3NoJyB8ICdzaC13c2gnIHwgJ3dzaCcsIG06IG51bWJlciwga2V5czogdXR4b2xpYi5CSVAzMkludGVyZmFjZVtdKSB7XG4gICAgY29uc3QgZml4dHVyZVBhdGggPSBiYXNlRml4dHVyZVBhdGggKyBgJHtzY3JpcHRUeXBlfS0ke219b2Yke2tleXMubGVuZ3RofWA7XG4gICAgZGVzY3JpYmUoYHNob3VsZCBjcmVhdGUgYSAke219IG9mICR7a2V5cy5sZW5ndGh9IG11bHRpLXNpZyAke3NjcmlwdFR5cGV9IGRlc2NyaXB0b3JgLCBmdW5jdGlvbiAoKSB7XG4gICAgICBpdCgnaGFzIGV4cGVjdGVkIGRlc2NyaXB0b3Igc3RyaW5nJywgYXN5bmMgZnVuY3Rpb24gKCkge1xuICAgICAgICBjb25zdCBkZXNjcmlwdG9yU3RyaW5nID0gY3JlYXRlTXVsdGlTaWdEZXNjcmlwdG9yKHNjcmlwdFR5cGUsIHZhbGlkTG9ja3RpbWUsIG0sIGtleXMsIGZhbHNlKTtcbiAgICAgICAgYXNzZXJ0LnN0cmljdEVxdWFsKFxuICAgICAgICAgIGRlc2NyaXB0b3JTdHJpbmcsXG4gICAgICAgICAgYXdhaXQgZ2V0Rml4dHVyZShmaXh0dXJlUGF0aCArIGAtc3RyaW5nLnR4dGAsIGRlc2NyaXB0b3JTdHJpbmcpLFxuICAgICAgICAgIGRlc2NyaXB0b3JTdHJpbmdcbiAgICAgICAgKTtcbiAgICAgIH0pO1xuXG4gICAgICBpdCgnaGFzIGV4cGVjdGVkIEFTVCcsIGFzeW5jIGZ1bmN0aW9uICgpIHtcbiAgICAgICAgY29uc3QgZGVzY3JpcHRvciA9IERlc2NyaXB0b3IuZnJvbVN0cmluZyhcbiAgICAgICAgICBjcmVhdGVNdWx0aVNpZ0Rlc2NyaXB0b3Ioc2NyaXB0VHlwZSwgdmFsaWRMb2NrdGltZSwgbSwga2V5cywgZmFsc2UpLFxuICAgICAgICAgICdkZXJpdmFibGUnXG4gICAgICAgICk7XG5cbiAgICAgICAgYXNzZXJ0LmRlZXBTdHJpY3RFcXVhbChkZXNjcmlwdG9yLm5vZGUoKSwgYXdhaXQgZ2V0Rml4dHVyZShmaXh0dXJlUGF0aCArICctYXN0Lmpzb24nLCBkZXNjcmlwdG9yLm5vZGUoKSkpO1xuICAgICAgfSk7XG5cbiAgICAgIGl0KCdoYXMgZXhwZWN0ZWQgYXNtJywgYXN5bmMgZnVuY3Rpb24gKCkge1xuICAgICAgICBjb25zdCBkZXNjcmlwdG9yID0gRGVzY3JpcHRvci5mcm9tU3RyaW5nKFxuICAgICAgICAgIGNyZWF0ZU11bHRpU2lnRGVzY3JpcHRvcihzY3JpcHRUeXBlLCB2YWxpZExvY2t0aW1lLCBtLCBrZXlzLCBmYWxzZSksXG4gICAgICAgICAgJ2Rlcml2YWJsZSdcbiAgICAgICAgKTtcbiAgICAgICAgY29uc3QgYXNtU3RyaW5nID0gZGVzY3JpcHRvci5hdERlcml2YXRpb25JbmRleCgwKS50b0FzbVN0cmluZygpO1xuICAgICAgICBhc3NlcnQuc3RyaWN0RXF1YWwoYXNtU3RyaW5nLCBhd2FpdCBnZXRGaXh0dXJlKGZpeHR1cmVQYXRoICsgJy1hc20udHh0JywgYXNtU3RyaW5nKSwgYXNtU3RyaW5nKTtcbiAgICAgIH0pO1xuXG4gICAgICBpdCgnY2FuIGJlIHNpZ25lZCcsIGFzeW5jIGZ1bmN0aW9uICgpIHtcbiAgICAgICAgLy8gRGVyaXZlIHRoZSBzY3JpcHQgZnJvbSB0aGUgZGVzY3JpcHRvclxuICAgICAgICBjb25zdCBkZXNjcmlwdG9yID0gRGVzY3JpcHRvci5mcm9tU3RyaW5nKFxuICAgICAgICAgIGNyZWF0ZU11bHRpU2lnRGVzY3JpcHRvcihzY3JpcHRUeXBlLCB2YWxpZExvY2t0aW1lLCBtLCBrZXlzLCBmYWxzZSksXG4gICAgICAgICAgJ2Rlcml2YWJsZSdcbiAgICAgICAgKTtcbiAgICAgICAgY29uc3QgZGVzY3JpcHRvckF0MCA9IGRlc2NyaXB0b3IuYXREZXJpdmF0aW9uSW5kZXgoMCk7XG4gICAgICAgIGNvbnN0IHNjcmlwdCA9IEJ1ZmZlci5mcm9tKGRlc2NyaXB0b3JBdDAuc2NyaXB0UHVia2V5KCkpO1xuXG4gICAgICAgIC8vIE1ha2UgdGhlIHByZXZUeFxuICAgICAgICBjb25zdCBwcmV2UHNidCA9IHV0eG9saWIudGVzdHV0aWwuY29uc3RydWN0UHNidChcbiAgICAgICAgICBbeyBzY3JpcHRUeXBlOiAncDJ3c2gnLCB2YWx1ZTogQmlnSW50KDEuMWU4KSB9XSxcbiAgICAgICAgICBbeyBzY3JpcHQ6IHNjcmlwdC50b1N0cmluZygnaGV4JyksIHZhbHVlOiBCaWdJbnQoMWU4KSB9XSxcbiAgICAgICAgICB1dHhvbGliLm5ldHdvcmtzLmJpdGNvaW4sXG4gICAgICAgICAgcm9vdFdhbGxldEtleXMsXG4gICAgICAgICAgJ2Z1bGxzaWduZWQnXG4gICAgICAgICk7XG4gICAgICAgIGNvbnN0IHByZXZUeCA9IHByZXZQc2J0LmZpbmFsaXplQWxsSW5wdXRzKCkuZXh0cmFjdFRyYW5zYWN0aW9uKCk7XG5cbiAgICAgICAgLy8gQ3JlYXRlIHRoZSBQU0JUIGFuZCBzaWduXG4gICAgICAgIGNvbnN0IHBzYnQgPSBPYmplY3QuYXNzaWduKG5ldyB1dHhvbGliLlBzYnQoeyBuZXR3b3JrOiB1dHhvbGliLm5ldHdvcmtzLmJpdGNvaW4gfSksIHtcbiAgICAgICAgICBsb2NrdGltZTogdmFsaWRMb2NrdGltZSxcbiAgICAgICAgfSk7XG4gICAgICAgIHBzYnQuYWRkSW5wdXQoe1xuICAgICAgICAgIGhhc2g6IHByZXZUeC5nZXRJZCgpLFxuICAgICAgICAgIGluZGV4OiAwLFxuICAgICAgICAgIHNlcXVlbmNlOiAweGZmZmZmZmZlLFxuICAgICAgICB9KTtcbiAgICAgICAgaWYgKHNjcmlwdFR5cGUgPT09ICdzaC13c2gnKSB7XG4gICAgICAgICAgcHNidC51cGRhdGVJbnB1dCgwLCB7IHdpdG5lc3NVdHhvOiB7IHNjcmlwdCwgdmFsdWU6IEJpZ0ludCgxZTgpIH0gfSk7XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgcHNidC51cGRhdGVJbnB1dCgwLCB7IG5vbldpdG5lc3NVdHhvOiBwcmV2VHgudG9CdWZmZXIoKSB9KTtcbiAgICAgICAgfVxuICAgICAgICBwc2J0LmFkZE91dHB1dCh7IHNjcmlwdCwgdmFsdWU6IEJpZ0ludCgwLjllOCkgfSk7XG4gICAgICAgIHVwZGF0ZUlucHV0V2l0aERlc2NyaXB0b3IocHNidCwgMCwgZGVzY3JpcHRvckF0MCk7XG4gICAgICAgIGtleXMuZm9yRWFjaCgoc2lnbmVyLCBpKSA9PiB7XG4gICAgICAgICAgaWYgKGkgPj0gbSkge1xuICAgICAgICAgICAgcmV0dXJuO1xuICAgICAgICAgIH1cbiAgICAgICAgICBwc2J0LnNpZ25BbGxJbnB1dHNIRChzaWduZXIpO1xuICAgICAgICB9KTtcblxuICAgICAgICAvLyBHZXQgdGhlIGZ1bGx5IHNpZ25lZCB0cmFuc2FjdGlvbiBhbmQgY2hlY2tcbiAgICAgICAgY29uc3Qgc2lnbmVkVHggPSBmaW5hbGl6ZVBzYnQocHNidCkuZXh0cmFjdFRyYW5zYWN0aW9uKCkudG9CdWZmZXIoKTtcbiAgICAgICAgYXNzZXJ0LnN0cmljdEVxdWFsKFxuICAgICAgICAgIHNpZ25lZFR4LnRvU3RyaW5nKCdoZXgnKSxcbiAgICAgICAgICBhd2FpdCBnZXRGaXh0dXJlKGZpeHR1cmVQYXRoICsgJy10eC50eHQnLCBzaWduZWRUeC50b1N0cmluZygnaGV4JykpXG4gICAgICAgICk7XG4gICAgICB9KTtcbiAgICB9KTtcbiAgfVxuXG4gIHJ1blRlc3RGb3JQYXJhbXMoJ3NoJywgMiwgW2tleTEsIGtleTJdKTtcbiAgcnVuVGVzdEZvclBhcmFtcygnc2gtd3NoJywgMiwgW2tleTEsIGtleTJdKTtcbiAgcnVuVGVzdEZvclBhcmFtcygnc2gnLCAzLCBba2V5MSwga2V5Miwga2V5M10pO1xuICBydW5UZXN0Rm9yUGFyYW1zKCd3c2gnLCAzLCBba2V5MSwga2V5Miwga2V5M10pO1xuXG4gIGl0KCdzaG91bGQgcmVjcmVhdGUgdGhlIHNjcmlwdCB1c2VkIGluIHRlc3RuZXQgc3Rha2luZyB0cmFuc2FjdGlvbicsIGZ1bmN0aW9uICgpIHtcbiAgICAvLyBTb3VyY2U6IGh0dHBzOi8vbWVtcG9vbC5zcGFjZS90ZXN0bmV0L2FkZHJlc3MvMk14VGkyRWhIS2dkSkZLUlRCdHRWR0d4aXI5WnpqbUtDWHdcbiAgICAvLyAyIG9mIDIgbXVsdGlzaWdcbiAgICBjb25zdCB0aW1lbG9jayA9ICdmY2U0Y2I2Nic7XG4gICAgY29uc3QgcHVia2V5MSA9ICcwM2VjYjZkNGI3ZjVkNTY5NjJlNTQ3ZmM1MmRkNTg4MzU5ZjU3MjljMGJhODU2ZDY5NzhiODQ3MjM4OTVhMTY2OTEnO1xuICAgIGNvbnN0IHB1YmtleTIgPSAnMDI0YWFlYTI1ZDgyYjFkYjJiZTAzMGEwNWI2NDFkNjMwMmU0OGVkNjUyYjFjYTljYjA4YTY3MjY3ZmNiYjU2NzQ3JztcbiAgICBjb25zdCByZWRlZW1TY3JpcHRBU00gPSBbXG4gICAgICAnT1BfUFVTSEJZVEVTXzQnLFxuICAgICAgdGltZWxvY2ssXG4gICAgICAnT1BfQ0xUVicsXG4gICAgICAnT1BfRFJPUCcsXG4gICAgICAnT1BfUFVTSE5VTV8yJyxcbiAgICAgICdPUF9QVVNIQllURVNfMzMnLFxuICAgICAgcHVia2V5MSxcbiAgICAgICdPUF9QVVNIQllURVNfMzMnLFxuICAgICAgcHVia2V5MixcbiAgICAgICdPUF9QVVNITlVNXzInLFxuICAgICAgJ09QX0NIRUNLTVVMVElTSUcnLFxuICAgIF0uam9pbignICcpO1xuXG4gICAgY29uc3QgZGVjb2RlZFRpbWVsb2NrID0gZGVjb2RlVGltZWxvY2soQnVmZmVyLmZyb20odGltZWxvY2ssICdoZXgnKSk7XG4gICAgY29uc3QgZGVzY3JpcHRvciA9IGNyZWF0ZU11bHRpU2lnRGVzY3JpcHRvcihcbiAgICAgICdzaCcsXG4gICAgICBkZWNvZGVkVGltZWxvY2ssXG4gICAgICAyLFxuICAgICAgW0J1ZmZlci5mcm9tKHB1YmtleTEsICdoZXgnKSwgQnVmZmVyLmZyb20ocHVia2V5MiwgJ2hleCcpXSxcbiAgICAgIGZhbHNlXG4gICAgKTtcbiAgICBjb25zdCBkZXNjcmlwdG9yQVNNID0gRGVzY3JpcHRvci5mcm9tU3RyaW5nKGRlc2NyaXB0b3IsICdkZWZpbml0ZScpLnRvQXNtU3RyaW5nKCk7XG4gICAgYXNzZXJ0LmRlZXBTdHJpY3RFcXVhbChyZWRlZW1TY3JpcHRBU00sIGRlc2NyaXB0b3JBU00pO1xuICB9KTtcbn0pO1xuIl19
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"opReturn.d.ts","sourceRoot":"","sources":["../../../../../test/unit/coreDao/opReturn.ts"],"names":[],"mappings":""}
|
|
@@ -0,0 +1,275 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
3
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
|
+
};
|
|
5
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
+
const assert_1 = __importDefault(require("assert"));
|
|
7
|
+
const utxo_lib_1 = require("@bitgo-beta/utxo-lib");
|
|
8
|
+
const testutil_1 = require("@bitgo-beta/utxo-core/testutil");
|
|
9
|
+
const coreDao_1 = require("../../../src/coreDao");
|
|
10
|
+
describe('OP_RETURN', function () {
|
|
11
|
+
const validVersion = 2;
|
|
12
|
+
const validChainId = coreDao_1.CORE_DAO_MAINNET_CHAIN_ID;
|
|
13
|
+
// random 20 byte buffers
|
|
14
|
+
const validDelegator = Buffer.alloc(20, utxo_lib_1.testutil.getKey('wasm-possum').publicKey);
|
|
15
|
+
const validValidator = Buffer.alloc(20, utxo_lib_1.testutil.getKey('possum-wasm').publicKey);
|
|
16
|
+
const validFee = 1;
|
|
17
|
+
const validRedeemScript = Buffer.from('522103a8295453660d5e212d55556666666666666666666666666666666666', 'hex');
|
|
18
|
+
const validTimelock = 800800;
|
|
19
|
+
let defaultScript;
|
|
20
|
+
before(async function () {
|
|
21
|
+
// https://docs.coredao.org/docs/Learn/products/btc-staking/design#op_return-output-1
|
|
22
|
+
const script = await (0, testutil_1.getFixture)('test/fixtures/coreDao/opReturn/documentation.txt', undefined);
|
|
23
|
+
(0, assert_1.default)(typeof script === 'string');
|
|
24
|
+
defaultScript = script;
|
|
25
|
+
});
|
|
26
|
+
describe('createCoreDaoOpReturnOutputScript', function () {
|
|
27
|
+
it('should throw if invalid parameters are passed', function () {
|
|
28
|
+
assert_1.default.throws(() => (0, coreDao_1.createCoreDaoOpReturnOutputScript)({
|
|
29
|
+
version: 292,
|
|
30
|
+
chainId: validChainId,
|
|
31
|
+
delegator: validDelegator,
|
|
32
|
+
validator: validValidator,
|
|
33
|
+
fee: validFee,
|
|
34
|
+
timelock: validTimelock,
|
|
35
|
+
}));
|
|
36
|
+
assert_1.default.throws(() => (0, coreDao_1.createCoreDaoOpReturnOutputScript)({
|
|
37
|
+
version: validVersion,
|
|
38
|
+
chainId: Buffer.alloc(32, 0),
|
|
39
|
+
delegator: validDelegator,
|
|
40
|
+
validator: validValidator,
|
|
41
|
+
fee: validFee,
|
|
42
|
+
timelock: validTimelock,
|
|
43
|
+
}));
|
|
44
|
+
assert_1.default.throws(() => (0, coreDao_1.createCoreDaoOpReturnOutputScript)({
|
|
45
|
+
version: validVersion,
|
|
46
|
+
chainId: validChainId,
|
|
47
|
+
delegator: Buffer.alloc(19, 0),
|
|
48
|
+
validator: validValidator,
|
|
49
|
+
fee: validFee,
|
|
50
|
+
timelock: validTimelock,
|
|
51
|
+
}));
|
|
52
|
+
assert_1.default.throws(() => (0, coreDao_1.createCoreDaoOpReturnOutputScript)({
|
|
53
|
+
version: validVersion,
|
|
54
|
+
chainId: validChainId,
|
|
55
|
+
delegator: validDelegator,
|
|
56
|
+
validator: Buffer.alloc(19, 0),
|
|
57
|
+
fee: validFee,
|
|
58
|
+
timelock: validTimelock,
|
|
59
|
+
}));
|
|
60
|
+
assert_1.default.throws(() => (0, coreDao_1.createCoreDaoOpReturnOutputScript)({
|
|
61
|
+
version: validVersion,
|
|
62
|
+
chainId: validChainId,
|
|
63
|
+
delegator: validDelegator,
|
|
64
|
+
validator: validValidator,
|
|
65
|
+
fee: 256,
|
|
66
|
+
timelock: validTimelock,
|
|
67
|
+
}));
|
|
68
|
+
assert_1.default.throws(() => (0, coreDao_1.createCoreDaoOpReturnOutputScript)({
|
|
69
|
+
version: validVersion,
|
|
70
|
+
chainId: validChainId,
|
|
71
|
+
delegator: validDelegator,
|
|
72
|
+
validator: validValidator,
|
|
73
|
+
fee: validFee,
|
|
74
|
+
timelock: -1,
|
|
75
|
+
}));
|
|
76
|
+
});
|
|
77
|
+
it('should throw if the length of the script is too long', function () {
|
|
78
|
+
assert_1.default.throws(() => (0, coreDao_1.createCoreDaoOpReturnOutputScript)({
|
|
79
|
+
version: validVersion,
|
|
80
|
+
chainId: validChainId,
|
|
81
|
+
delegator: validDelegator,
|
|
82
|
+
validator: validValidator,
|
|
83
|
+
fee: validFee,
|
|
84
|
+
redeemScript: Buffer.alloc(100),
|
|
85
|
+
}));
|
|
86
|
+
});
|
|
87
|
+
it('should return a buffer with the correct length', function () {
|
|
88
|
+
const script = (0, coreDao_1.createCoreDaoOpReturnOutputScript)({
|
|
89
|
+
version: validVersion,
|
|
90
|
+
chainId: validChainId,
|
|
91
|
+
delegator: validDelegator,
|
|
92
|
+
validator: validValidator,
|
|
93
|
+
fee: validFee,
|
|
94
|
+
timelock: validTimelock,
|
|
95
|
+
});
|
|
96
|
+
// Make sure that the first byte is the OP_RETURN opcode
|
|
97
|
+
assert_1.default.strictEqual(script[0], 0x6a);
|
|
98
|
+
// Make sure that the length of the script matches what is in the buffer
|
|
99
|
+
assert_1.default.strictEqual(
|
|
100
|
+
// We do not count the OP_RETURN opcode or the bytes for the length
|
|
101
|
+
script.length - 2, script[1]);
|
|
102
|
+
});
|
|
103
|
+
it('should have the correct placement of the values provided with a redeem script', function () {
|
|
104
|
+
// This should produce an Op_RETURN that needs the extra push bytes for the length
|
|
105
|
+
const script = (0, coreDao_1.createCoreDaoOpReturnOutputScript)({
|
|
106
|
+
version: validVersion,
|
|
107
|
+
chainId: validChainId,
|
|
108
|
+
delegator: validDelegator,
|
|
109
|
+
validator: validValidator,
|
|
110
|
+
fee: validFee,
|
|
111
|
+
redeemScript: validRedeemScript,
|
|
112
|
+
});
|
|
113
|
+
// Make sure that the first byte is the OP_RETURN opcode
|
|
114
|
+
assert_1.default.strictEqual(script[0], 0x6a);
|
|
115
|
+
// Make sure that the length of the script matches what is in the buffer
|
|
116
|
+
assert_1.default.strictEqual(script[1], 0x4c);
|
|
117
|
+
assert_1.default.strictEqual(
|
|
118
|
+
// We do not count the OP_RETURN opcode or the length + pushbytes
|
|
119
|
+
script.length - 3, script[2]);
|
|
120
|
+
// Satoshi plus identifier
|
|
121
|
+
assert_1.default.deepStrictEqual(script.subarray(3, 7).toString('hex'), coreDao_1.CORE_DAO_SATOSHI_PLUS_IDENTIFIER.toString('hex'));
|
|
122
|
+
// Make sure that the version is correct
|
|
123
|
+
assert_1.default.strictEqual(script[7], validVersion);
|
|
124
|
+
// Make sure that the chainId is correct
|
|
125
|
+
assert_1.default.deepStrictEqual(script.subarray(8, 10).toString('hex'), validChainId.toString('hex'));
|
|
126
|
+
// Make sure that the delegator is correct
|
|
127
|
+
assert_1.default.deepStrictEqual(script.subarray(10, 30).toString('hex'), validDelegator.toString('hex'));
|
|
128
|
+
// Make sure that the validator is correct
|
|
129
|
+
assert_1.default.deepStrictEqual(script.subarray(30, 50).toString('hex'), validValidator.toString('hex'));
|
|
130
|
+
// Make sure that the fee is correct
|
|
131
|
+
assert_1.default.strictEqual(script[50], validFee);
|
|
132
|
+
// Make sure that the redeemScript is correct
|
|
133
|
+
assert_1.default.deepStrictEqual(script.subarray(51, 51 + validRedeemScript.length).toString('hex'), validRedeemScript.toString('hex'));
|
|
134
|
+
});
|
|
135
|
+
it('should have the correct placement of the values provided with a blockheight timelock', function () {
|
|
136
|
+
// This should produce an Op_RETURN that needs the extra push bytes for the length
|
|
137
|
+
const script = (0, coreDao_1.createCoreDaoOpReturnOutputScript)({
|
|
138
|
+
version: validVersion,
|
|
139
|
+
chainId: validChainId,
|
|
140
|
+
delegator: validDelegator,
|
|
141
|
+
validator: validValidator,
|
|
142
|
+
fee: validFee,
|
|
143
|
+
timelock: validTimelock,
|
|
144
|
+
});
|
|
145
|
+
// Make sure that the first byte is the OP_RETURN opcode
|
|
146
|
+
assert_1.default.strictEqual(script[0], 0x6a);
|
|
147
|
+
// Make sure that the length of the script matches what is in the buffer
|
|
148
|
+
assert_1.default.strictEqual(
|
|
149
|
+
// We do not count the OP_RETURN opcode or the length
|
|
150
|
+
script.length - 2, script[1]);
|
|
151
|
+
// Satoshi plus identifier
|
|
152
|
+
assert_1.default.deepStrictEqual(script.subarray(2, 6).toString('hex'), coreDao_1.CORE_DAO_SATOSHI_PLUS_IDENTIFIER.toString('hex'));
|
|
153
|
+
// Make sure that the version is correct
|
|
154
|
+
assert_1.default.strictEqual(script[6], validVersion);
|
|
155
|
+
// Make sure that the chainId is correct
|
|
156
|
+
assert_1.default.deepStrictEqual(script.subarray(7, 9).toString('hex'), validChainId.toString('hex'));
|
|
157
|
+
// Make sure that the delegator is correct
|
|
158
|
+
assert_1.default.deepStrictEqual(script.subarray(9, 29).toString('hex'), validDelegator.toString('hex'));
|
|
159
|
+
// Make sure that the validator is correct
|
|
160
|
+
assert_1.default.deepStrictEqual(script.subarray(29, 49).toString('hex'), validValidator.toString('hex'));
|
|
161
|
+
// Make sure that the fee is correct
|
|
162
|
+
assert_1.default.strictEqual(script[49], validFee);
|
|
163
|
+
// Make sure that the redeemScript is correct
|
|
164
|
+
assert_1.default.deepStrictEqual(script.subarray(50, 54).toString('hex'), (0, coreDao_1.encodeTimelock)(validTimelock).toString('hex'));
|
|
165
|
+
assert_1.default.deepStrictEqual((0, coreDao_1.decodeTimelock)(script.subarray(50, 54)), validTimelock);
|
|
166
|
+
});
|
|
167
|
+
it('should have the correct placement of the values provided with a time timelock', function () {
|
|
168
|
+
// This should produce an Op_RETURN that needs the extra push bytes for the length
|
|
169
|
+
const timelock = new Date('2022-01-01T00:00:00Z').getTime() / 1000;
|
|
170
|
+
const script = (0, coreDao_1.createCoreDaoOpReturnOutputScript)({
|
|
171
|
+
version: validVersion,
|
|
172
|
+
chainId: validChainId,
|
|
173
|
+
delegator: validDelegator,
|
|
174
|
+
validator: validValidator,
|
|
175
|
+
fee: validFee,
|
|
176
|
+
timelock,
|
|
177
|
+
});
|
|
178
|
+
// Make sure that the first byte is the OP_RETURN opcode
|
|
179
|
+
assert_1.default.strictEqual(script[0], 0x6a);
|
|
180
|
+
// Make sure that the length of the script matches what is in the buffer
|
|
181
|
+
assert_1.default.strictEqual(
|
|
182
|
+
// We do not count the OP_RETURN opcode or the length
|
|
183
|
+
script.length - 2, script[1]);
|
|
184
|
+
// Satoshi plus identifier
|
|
185
|
+
assert_1.default.deepStrictEqual(script.subarray(2, 6).toString('hex'), coreDao_1.CORE_DAO_SATOSHI_PLUS_IDENTIFIER.toString('hex'));
|
|
186
|
+
// Make sure that the version is correct
|
|
187
|
+
assert_1.default.strictEqual(script[6], validVersion);
|
|
188
|
+
// Make sure that the chainId is correct
|
|
189
|
+
assert_1.default.deepStrictEqual(script.subarray(7, 9).toString('hex'), validChainId.toString('hex'));
|
|
190
|
+
// Make sure that the delegator is correct
|
|
191
|
+
assert_1.default.deepStrictEqual(script.subarray(9, 29).toString('hex'), validDelegator.toString('hex'));
|
|
192
|
+
// Make sure that the validator is correct
|
|
193
|
+
assert_1.default.deepStrictEqual(script.subarray(29, 49).toString('hex'), validValidator.toString('hex'));
|
|
194
|
+
// Make sure that the fee is correct
|
|
195
|
+
assert_1.default.strictEqual(script[49], validFee);
|
|
196
|
+
// Make sure that the redeemScript is correct
|
|
197
|
+
assert_1.default.deepStrictEqual(script.subarray(50, 54).toString('hex'), (0, coreDao_1.encodeTimelock)(timelock).toString('hex'));
|
|
198
|
+
assert_1.default.deepStrictEqual((0, coreDao_1.decodeTimelock)(script.subarray(50, 54)), timelock);
|
|
199
|
+
});
|
|
200
|
+
it('should recreate the example OP_RETURN correctly', function () {
|
|
201
|
+
assert_1.default.deepStrictEqual((0, coreDao_1.createCoreDaoOpReturnOutputScript)({
|
|
202
|
+
version: 1,
|
|
203
|
+
chainId: Buffer.from('045b', 'hex'),
|
|
204
|
+
delegator: Buffer.from('de60b7d0e6b758ca5dd8c61d377a2c5f1af51ec1', 'hex'),
|
|
205
|
+
validator: Buffer.from('a9e209f5ea0036c8c2f41078a3cebee57d8a47d5', 'hex'),
|
|
206
|
+
fee: 1,
|
|
207
|
+
redeemScript: Buffer.from('041f5e0e66b17576a914c4b8ae927ff2b9ce218e20bf06d425d6b68424fd88ac', 'hex'),
|
|
208
|
+
}).toString('hex'), defaultScript);
|
|
209
|
+
});
|
|
210
|
+
});
|
|
211
|
+
describe('parseCoreDaoOpReturnOutputScript', function () {
|
|
212
|
+
it('should parse a valid script with a timelock', function () {
|
|
213
|
+
const script = (0, coreDao_1.createCoreDaoOpReturnOutputScript)({
|
|
214
|
+
version: validVersion,
|
|
215
|
+
chainId: validChainId,
|
|
216
|
+
delegator: validDelegator,
|
|
217
|
+
validator: validValidator,
|
|
218
|
+
fee: validFee,
|
|
219
|
+
timelock: validTimelock,
|
|
220
|
+
});
|
|
221
|
+
const parsed = (0, coreDao_1.parseCoreDaoOpReturnOutputScript)(script);
|
|
222
|
+
assert_1.default.strictEqual(parsed.version, validVersion);
|
|
223
|
+
assert_1.default.deepStrictEqual(parsed.chainId, validChainId);
|
|
224
|
+
assert_1.default.deepStrictEqual(parsed.delegator, validDelegator);
|
|
225
|
+
assert_1.default.deepStrictEqual(parsed.validator, validValidator);
|
|
226
|
+
assert_1.default.strictEqual(parsed.fee, validFee);
|
|
227
|
+
(0, assert_1.default)('timelock' in parsed);
|
|
228
|
+
assert_1.default.deepStrictEqual(parsed.timelock, validTimelock);
|
|
229
|
+
});
|
|
230
|
+
it('should parse a valid script with a redeem script', function () {
|
|
231
|
+
const script = (0, coreDao_1.createCoreDaoOpReturnOutputScript)({
|
|
232
|
+
version: validVersion,
|
|
233
|
+
chainId: validChainId,
|
|
234
|
+
delegator: validDelegator,
|
|
235
|
+
validator: validValidator,
|
|
236
|
+
fee: validFee,
|
|
237
|
+
redeemScript: validRedeemScript,
|
|
238
|
+
});
|
|
239
|
+
const parsed = (0, coreDao_1.parseCoreDaoOpReturnOutputScript)(script);
|
|
240
|
+
assert_1.default.strictEqual(parsed.version, validVersion);
|
|
241
|
+
assert_1.default.deepStrictEqual(parsed.chainId, validChainId);
|
|
242
|
+
assert_1.default.deepStrictEqual(parsed.delegator, validDelegator);
|
|
243
|
+
assert_1.default.deepStrictEqual(parsed.validator, validValidator);
|
|
244
|
+
assert_1.default.strictEqual(parsed.fee, validFee);
|
|
245
|
+
(0, assert_1.default)('redeemScript' in parsed);
|
|
246
|
+
assert_1.default.deepStrictEqual(parsed.redeemScript, validRedeemScript);
|
|
247
|
+
});
|
|
248
|
+
it('should parse valid opreturn script from testnet', async function () {
|
|
249
|
+
// Source: https://mempool.space/testnet/tx/66ed4cea26a410248a6d87f14b2bca514f33920c54d4af63ed46a903793115d5
|
|
250
|
+
const baseFixturePath = 'test/fixtures/coreDao/opReturn/66ed4cea26a410248a6d87f14b2bca514f33920c54d4af63ed46a903793115d5';
|
|
251
|
+
const opReturnHex = await (0, testutil_1.getFixture)(baseFixturePath + '.txt', undefined);
|
|
252
|
+
(0, assert_1.default)(typeof opReturnHex === 'string');
|
|
253
|
+
const parsed = (0, coreDao_1.parseCoreDaoOpReturnOutputScript)(Buffer.from(opReturnHex, 'hex'));
|
|
254
|
+
const parsedFixture = await (0, testutil_1.getFixture)(baseFixturePath + '.json', JSON.parse((0, coreDao_1.toString)(parsed)));
|
|
255
|
+
assert_1.default.deepStrictEqual((0, coreDao_1.toString)(parsed), JSON.stringify(parsedFixture));
|
|
256
|
+
});
|
|
257
|
+
it('should fail if there is an invalid op-return', function () {
|
|
258
|
+
const script = defaultScript.replace('6a4c50', '6b4c50');
|
|
259
|
+
assert_1.default.throws(() => (0, coreDao_1.parseCoreDaoOpReturnOutputScript)(Buffer.from(script, 'hex')));
|
|
260
|
+
});
|
|
261
|
+
it('should fail if the length is incorrect', function () {
|
|
262
|
+
const script = defaultScript.replace('4c50', '4c51');
|
|
263
|
+
assert_1.default.throws(() => (0, coreDao_1.parseCoreDaoOpReturnOutputScript)(Buffer.from(script, 'hex')));
|
|
264
|
+
});
|
|
265
|
+
it('should fail if the satoshi+ identifier is incorrect', function () {
|
|
266
|
+
const script = defaultScript.replace('5341542b', '5341532b');
|
|
267
|
+
assert_1.default.throws(() => (0, coreDao_1.parseCoreDaoOpReturnOutputScript)(Buffer.from(script, 'hex')));
|
|
268
|
+
});
|
|
269
|
+
it('should fail if the chainId is incorrect', function () {
|
|
270
|
+
const script = defaultScript.replace('045b', '0454');
|
|
271
|
+
assert_1.default.throws(() => (0, coreDao_1.parseCoreDaoOpReturnOutputScript)(Buffer.from(script, 'hex')));
|
|
272
|
+
});
|
|
273
|
+
});
|
|
274
|
+
});
|
|
275
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoib3BSZXR1cm4uanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi8uLi8uLi90ZXN0L3VuaXQvY29yZURhby9vcFJldHVybi50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiOzs7OztBQUFBLG9EQUE0QjtBQUU1QixtREFBZ0Q7QUFDaEQsNkRBQTREO0FBRTVELGtEQVE4QjtBQUU5QixRQUFRLENBQUMsV0FBVyxFQUFFO0lBQ3BCLE1BQU0sWUFBWSxHQUFHLENBQUMsQ0FBQztJQUN2QixNQUFNLFlBQVksR0FBRyxtQ0FBeUIsQ0FBQztJQUMvQyx5QkFBeUI7SUFDekIsTUFBTSxjQUFjLEdBQUcsTUFBTSxDQUFDLEtBQUssQ0FBQyxFQUFFLEVBQUUsbUJBQVEsQ0FBQyxNQUFNLENBQUMsYUFBYSxDQUFDLENBQUMsU0FBUyxDQUFDLENBQUM7SUFDbEYsTUFBTSxjQUFjLEdBQUcsTUFBTSxDQUFDLEtBQUssQ0FBQyxFQUFFLEVBQUUsbUJBQVEsQ0FBQyxNQUFNLENBQUMsYUFBYSxDQUFDLENBQUMsU0FBUyxDQUFDLENBQUM7SUFDbEYsTUFBTSxRQUFRLEdBQUcsQ0FBQyxDQUFDO0lBQ25CLE1BQU0saUJBQWlCLEdBQUcsTUFBTSxDQUFDLElBQUksQ0FBQyxnRUFBZ0UsRUFBRSxLQUFLLENBQUMsQ0FBQztJQUMvRyxNQUFNLGFBQWEsR0FBRyxNQUFNLENBQUM7SUFDN0IsSUFBSSxhQUFxQixDQUFDO0lBRTFCLE1BQU0sQ0FBQyxLQUFLO1FBQ1YscUZBQXFGO1FBQ3JGLE1BQU0sTUFBTSxHQUFHLE1BQU0sSUFBQSxxQkFBVSxFQUFDLGtEQUFrRCxFQUFFLFNBQVMsQ0FBQyxDQUFDO1FBQy9GLElBQUEsZ0JBQU0sRUFBQyxPQUFPLE1BQU0sS0FBSyxRQUFRLENBQUMsQ0FBQztRQUNuQyxhQUFhLEdBQUcsTUFBTSxDQUFDO0lBQ3pCLENBQUMsQ0FBQyxDQUFDO0lBRUgsUUFBUSxDQUFDLG1DQUFtQyxFQUFFO1FBQzVDLEVBQUUsQ0FBQywrQ0FBK0Ms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LENBQUM7UUFFSCxFQUFFLENBQUMsOENBQThDLEVBQUU7WUFDakQsTUFBTSxNQUFNLEdBQUcsYUFBYSxDQUFDLE9BQU8sQ0FBQyxRQUFRLEVBQUUsUUFBUSxDQUFDLENBQUM7WUFDekQsZ0JBQU0sQ0FBQyxNQUFNLENBQUMsR0FBRyxFQUFFLENBQUMsSUFBQSwwQ0FBZ0MsRUFBQyxNQUFNLENBQUMsSUFBSSxDQUFDLE1BQU0sRUFBRSxLQUFLLENBQUMsQ0FBQyxDQUFDLENBQUM7UUFDcEYsQ0FBQyxDQUFDLENBQUM7UUFFSCxFQUFFLENBQUMsd0NBQXdDLEVBQUU7WUFDM0MsTUFBTSxNQUFNLEdBQUcsYUFBYSxDQUFDLE9BQU8sQ0FBQyxNQUFNLEVBQUUsTUFBTSxDQUFDLENBQUM7WUFDckQsZ0JBQU0sQ0FBQyxNQUFNLENBQUMsR0FBRyxFQUFFLENBQUMsSUFBQSwwQ0FBZ0MsRUFBQyxNQUFNLENBQUMsSUFBSSxDQUFDLE1BQU0sRUFBRSxLQUFLLENBQUMsQ0FBQyxDQUFDLENBQUM7UUFDcEYsQ0FBQyxDQUFDLENBQUM7UUFFSCxFQUFFLENBQUMscURBQXFELEVBQUU7WUFDeEQsTUFBTSxNQUFNLEdBQUcsYUFBYSxDQUFDLE9BQU8sQ0FBQyxVQUFVLEVBQUUsVUFBVSxDQUFDLENBQUM7WUFDN0QsZ0JBQU0sQ0FBQyxNQUFNLENBQUMsR0FBRyxFQUFFLENBQUMsSUFBQSwwQ0FBZ0MsRUFBQyxNQUFNLENBQUMsSUFBSSxDQUFDLE1BQU0sRUFBRSxLQUFLLENBQUMsQ0FBQyxDQUFDLENBQUM7UUFDcEYsQ0FBQyxDQUFDLENBQUM7UUFFSCxFQUFFLENBQUMseUNBQXlDLEVBQUU7WUFDNUMsTUFBTSxNQUFNLEdBQUcsYUFBYSxDQUFDLE9BQU8sQ0FBQyxNQUFNLEVBQUUsTUFBTSxDQUFDLENBQUM7WUFDckQsZ0JBQU0sQ0FBQyxNQUFNLENBQUMsR0FBRyxFQUFFLENBQUMsSUFBQSwwQ0FBZ0MsRUFBQyxNQUFNLENBQUMsSUFBSSxDQUFDLE1BQU0sRUFBRSxLQUFLLENBQUMsQ0FBQyxDQUFDLENBQUM7UUFDcEYsQ0FBQyxDQUFDLENBQUM7SUFDTCxDQUFDLENBQUMsQ0FBQztBQUNMLENBQUMsQ0FBQyxDQUFDIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IGFzc2VydCBmcm9tICdhc3NlcnQnO1xuXG5pbXBvcnQgeyB0ZXN0dXRpbCB9IGZyb20gJ0BiaXRnby1iZXRhL3V0eG8tbGliJztcbmltcG9ydCB7IGdldEZpeHR1cmUgfSBmcm9tICdAYml0Z28tYmV0YS91dHhvLWNvcmUvdGVzdHV0aWwnO1xuXG5pbXBvcnQge1xuICBDT1JFX0RBT19NQUlOTkVUX0NIQUlOX0lELFxuICBDT1JFX0RBT19TQVRPU0hJX1BMVVNfSURFTlRJRklFUixcbiAgY3JlYXRlQ29yZURhb09wUmV0dXJuT3V0cHV0U2NyaXB0LFxuICBkZWNvZGVUaW1lbG9jayxcbiAgZW5jb2RlVGltZWxvY2ssXG4gIHBhcnNlQ29yZURhb09wUmV0dXJuT3V0cHV0U2NyaXB0LFxuICB0b1N0cmluZyxcbn0gZnJvbSAnLi4vLi4vLi4vc3JjL2NvcmVEYW8nO1xuXG5kZXNjcmliZSgnT1BfUkVUVVJOJywgZnVuY3Rpb24gKCkge1xuICBjb25zdCB2YWxpZFZlcnNpb24gPSAyO1xuICBjb25zdCB2YWxpZENoYWluSWQgPSBDT1JFX0RBT19NQUlOTkVUX0NIQUlOX0lEO1xuICAvLyByYW5kb20gMjAgYnl0ZSBidWZmZXJzXG4gIGNvbnN0IHZhbGlkRGVsZWdhdG9yID0gQnVmZmVyLmFsbG9jKDIwLCB0ZXN0dXRpbC5nZXRLZXkoJ3dhc20tcG9zc3VtJykucHVibGljS2V5KTtcbiAgY29uc3QgdmFsaWRWYWxpZGF0b3IgPSBCdWZmZXIuYWxsb2MoMjAsIHRlc3R1dGlsLmdldEtleSgncG9zc3VtLXdhc20nKS5wdWJsaWNLZXkpO1xuICBjb25zdCB2YWxpZEZlZSA9IDE7XG4gIGNvbnN0IHZhbGlkUmVkZWVtU2NyaXB0ID0gQnVmZmVyLmZyb20oJzUyMjEwM2E4Mjk1NDUzNjYwZDVlMjEyZDU1NTU2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2JywgJ2hleCcpO1xuICBjb25zdCB2YWxpZFRpbWVsb2NrID0gODAwODAwO1xuICBsZXQgZGVmYXVsdFNjcmlwdDogc3RyaW5nO1xuXG4gIGJlZm9yZShhc3luYyBmdW5jdGlvbiAoKSB7XG4gICAgLy8gaHR0cHM6Ly9kb2NzLmNvcmVkYW8ub3JnL2RvY3MvTGVhcm4vcHJvZHVjdHMvYnRjLXN0YWtpbmcvZGVzaWduI29wX3JldHVybi1vdXRwdXQtMVxuICAgIGNvbnN0IHNjcmlwdCA9IGF3YWl0IGdldEZpeHR1cmUoJ3Rlc3QvZml4dHVyZXMvY29yZURhby9vcFJldHVybi9kb2N1bWVudGF0aW9uLnR4dCcsIHVuZGVmaW5lZCk7XG4gICAgYXNzZXJ0KHR5cGVvZiBzY3JpcHQgPT09ICdzdHJpbmcnKTtcbiAgICBkZWZhdWx0U2NyaXB0ID0gc2NyaXB0O1xuICB9KTtcblxuICBkZXNjcmliZSgnY3JlYXRlQ29yZURhb09wUmV0dXJuT3V0cHV0U2NyaXB0JywgZnVuY3Rpb24gKCkge1xuICAgIGl0KCdzaG91bGQgdGhyb3cgaWYgaW52YWxpZCBwYXJhbWV0ZXJzIGFyZSBwYXNzZWQnLCBmdW5jdGlvbiAoKSB7XG4gICAgICBhc3NlcnQudGhyb3dzKCgpID0+XG4gICAgICAgIGNyZWF0ZUNvcmVEYW9PcFJldHVybk91dHB1dFNjcmlwdCh7XG4gICAgICAgICAgdmVyc2lvbjogMjkyLFxuICAgICAgICAgIGNoYWluSWQ6IHZhbGlkQ2hhaW5JZCxcbiAgICAgICAgICBkZWxlZ2F0b3I6IHZhbGlkRGVsZWdhdG9yLFxuICAgICAgICAgIHZhbGlkYXRvcjogdmFsaWRWYWxpZGF0b3IsXG4gICAgICAgICAgZmVlOiB2YWxpZEZlZSxcbiAgICAgICAgICB0aW1lbG9jazogdmFsaWRUaW1lbG9jayxcbiAgICAgICAgfSlcbiAgICAgICk7XG4gICAgICBhc3NlcnQudGhyb3dzKCgpID0+XG4gICAgICAgIGNyZWF0ZUNvcmVEYW9PcFJldHVybk91dHB1dFNjcmlwdCh7XG4gICAgICAgICAgdmVyc2lvbjogdmFsaWRWZXJzaW9uLFxuICAgICAgICAgIGNoYWluSWQ6IEJ1ZmZlci5hbGxvYygzMiwgMCksXG4gICAgICAgICAgZGVsZWdhdG9yOiB2YWxpZERlbGVnYXRvcixcbiAgICAgICAgICB2YWxpZGF0b3I6IHZhbGlkVmFsaWRhdG9yLFxuICAgICAgICAgIGZlZTogdmFsaWRGZWUsXG4gICAgICAgICAgdGltZWxvY2s6IHZhbGlkVGltZWxvY2ssXG4gICAgICAgIH0pXG4gICAgICApO1xuICAgICAgYXNzZXJ0LnRocm93cygoKSA9PlxuICAgICAgICBjcmVhdGVDb3JlRGFvT3BSZXR1cm5PdXRwdXRTY3JpcHQoe1xuICAgICAgICAgIHZlcnNpb246IHZhbGlkVmVyc2lvbixcbiAgICAgICAgICBjaGFpbklkOiB2YWxpZENoYWluSWQsXG4gICAgICAgICAgZGVsZWdhdG9yOiBCdWZmZXIuYWxsb2MoMTksIDApLFxuICAgICAgICAgIHZhbGlkYXRvcjogdmFsaWRWYWxpZGF0b3IsXG4gICAgICAgICAgZmVlOiB2YWxpZEZlZSxcbiAgICAgICAgICB0aW1lbG9jazogdmFsaWRUaW1lbG9jayxcbiAgICAgICAgfSlcbiAgICAgICk7XG4gICAgICBhc3NlcnQudGhyb3dzKCgpID0+XG4gICAgICAgIGNyZWF0ZUNvcmVEYW9PcFJldHVybk91dHB1dFNjcmlwdCh7XG4gICAgICAgICAgdmVyc2lvbjogdmFsaWRWZXJzaW9uLFxuICAgICAgICAgIGNoYWluSWQ6IHZhbGlkQ2hhaW5JZCxcbiAgICAgICAgICBkZWxlZ2F0b3I6IHZhbGlkRGVsZWdhdG9yLFxuICAgICAgICAgIHZhbGlkYXRvcjogQnVmZmVyLmFsbG9jKDE5LCAwKSxcbiAgICAgICAgICBmZWU6IHZhbGlkRmVlLFxuICAgICAgICAgIHRpbWVsb2NrOiB2YWxpZFRpbWVsb2NrLFxuICAgICAgICB9KVxuICAgICAgKTtcbiAgICAgIGFzc2VydC50aHJvd3MoKCkgPT5cbiAgICAgICAgY3JlYXRlQ29yZURhb09wUmV0dXJuT3V0cHV0U2NyaXB0KHtcbiAgICAgICAgICB2ZXJzaW9uOiB2YWxpZFZlcnNpb24sXG4gICAgICAgICAgY2hhaW5JZDogdmFsaWRDaGFpbklkLFxuICAgICAgICAgIGRlbGVnYXRvcjogdmFsaWREZWxlZ2F0b3IsXG4gICAgICAgICAgdmFsaWRhdG9yOiB2YWxpZFZhbGlkYXRvcixcbiAgICAgICAgICBmZWU6IDI1NixcbiAgICAgICAgICB0aW1lbG9jazogdmFsaWRUaW1lbG9jayxcbiAgICAgICAgfSlcbiAgICAgICk7XG4gICAgICBhc3NlcnQudGhyb3dzKCgpID0+XG4gICAgICAgIGNyZWF0ZUNvcmVEYW9PcFJldHVybk91dHB1dFNjcmlwdCh7XG4gICAgICAgICAgdmVyc2lvbjogdmFsaWRWZXJzaW9uLFxuICAgICAgICAgIGNoYWluSWQ6IHZhbGlkQ2hhaW5JZCxcbiAgICAgICAgICBkZWxlZ2F0b3I6IHZhbGlkRGVsZWdhdG9yLFxuICAgICAgICAgIHZhbGlkYXRvcjogdmFsaWRWYWxpZGF0b3IsXG4gICAgICAgICAgZmVlOiB2YWxpZEZlZSxcbiAgICAgICAgICB0aW1lbG9jazogLTEsXG4gICAgICAgIH0pXG4gICAgICApO1xuICAgIH0pO1xuXG4gICAgaXQoJ3Nob3VsZCB0aHJvdyBpZiB0aGUgbGVuZ3RoIG9mIHRoZSBzY3JpcHQgaXMgdG9vIGxvbmcnLCBmdW5jdGlvbiAoKSB7XG4gICAgICBhc3NlcnQudGhyb3dzKCgpID0+XG4gICAgICAgIGNyZWF0ZUNvcmVEYW9PcFJldHVybk91dHB1dFNjcmlwdCh7XG4gICAgICAgICAgdmVyc2lvbjogdmFsaWRWZXJzaW9uLFxuICAgICAgICAgIGNoYWluSWQ6IHZhbGlkQ2hhaW5JZCxcbiAgICAgICAgICBkZWxlZ2F0b3I6IHZhbGlkRGVsZWdhdG9yLFxuICAgICAgICAgIHZhbGlkYXRvcjogdmFsaWRWYWxpZGF0b3IsXG4gICAgICAgICAgZmVlOiB2YWxpZEZlZSxcbiAgICAgICAgICByZWRlZW1TY3JpcHQ6IEJ1ZmZlci5hbGxvYygxMDApLFxuICAgICAgICB9KVxuICAgICAgKTtcbiAgICB9KTtcblxuICAgIGl0KCdzaG91bGQgcmV0dXJuIGEgYnVmZmVyIHdpdGggdGhlIGNvcnJlY3QgbGVuZ3RoJywgZnVuY3Rpb24gKCkge1xuICAgICAgY29uc3Qgc2NyaXB0ID0gY3JlYXRlQ29yZURhb09wUmV0dXJuT3V0cHV0U2NyaXB0KHtcbiAgICAgICAgdmVyc2lvbjogdmFsaWRWZXJzaW9uLFxuICAgICAgICBjaGFpbklkOiB2YWxpZENoYWluSWQsXG4gICAgICAgIGRlbGVnYXRvcjogdmFsaWREZWxlZ2F0b3IsXG4gICAgICAgIHZhbGlkYXRvcjogdmFsaWRWYWxpZGF0b3IsXG4gICAgICAgIGZlZTogdmFsaWRGZWUsXG4gICAgICAgIHRpbWVsb2NrOiB2YWxpZFRpbWVsb2NrLFxuICAgICAgfSk7XG4gICAgICAvLyBNYWtlIHN1cmUgdGhhdCB0aGUgZmlyc3QgYnl0ZSBpcyB0aGUgT1BfUkVUVVJOIG9wY29kZVxuICAgICAgYXNzZXJ0LnN0cmljdEVxdWFsKHNjcmlwdFswXSwgMHg2YSk7XG4gICAgICAvLyBNYWtlIHN1cmUgdGhhdCB0aGUgbGVuZ3RoIG9mIHRoZSBzY3JpcHQgbWF0Y2hlcyB3aGF0IGlzIGluIHRoZSBidWZmZXJcbiAgICAgIGFzc2VydC5zdHJpY3RFcXVhbChcbiAgICAgICAgLy8gV2UgZG8gbm90IGNvdW50IHRoZSBPUF9SRVRVUk4gb3Bjb2RlIG9yIHRoZSBieXRlcyBmb3IgdGhlIGxlbmd0aFxuICAgICAgICBzY3JpcHQubGVuZ3RoIC0gMixcbiAgICAgICAgc2NyaXB0WzFdXG4gICAgICApO1xuICAgIH0pO1xuXG4gICAgaXQoJ3Nob3VsZCBoYXZlIHRoZSBjb3JyZWN0IHBsYWNlbWVudCBvZiB0aGUgdmFsdWVzIHByb3ZpZGVkIHdpdGggYSByZWRlZW0gc2NyaXB0JywgZnVuY3Rpb24gKCkge1xuICAgICAgLy8gVGhpcyBzaG91bGQgcHJvZHVjZSBhbiBPcF9SRVRVUk4gdGhhdCBuZWVkcyB0aGUgZXh0cmEgcHVzaCBieXRlcyBmb3IgdGhlIGxlbmd0aFxuICAgICAgY29uc3Qgc2NyaXB0ID0gY3JlYXRlQ29yZURhb09wUmV0dXJuT3V0cHV0U2NyaXB0KHtcbiAgICAgICAgdmVyc2lvbjogdmFsaWRWZXJzaW9uLFxuICAgICAgICBjaGFpbklkOiB2YWxpZENoYWluSWQsXG4gICAgICAgIGRlbGVnYXRvcjogdmFsaWREZWxlZ2F0b3IsXG4gICAgICAgIHZhbGlkYXRvcjogdmFsaWRWYWxpZGF0b3IsXG4gICAgICAgIGZlZTogdmFsaWRGZWUsXG4gICAgICAgIHJlZGVlbVNjcmlwdDogdmFsaWRSZWRlZW1TY3JpcHQsXG4gICAgICB9KTtcbiAgICAgIC8vIE1ha2Ugc3VyZSB0aGF0IHRoZSBmaXJzdCBieXRlIGlzIHRoZSBPUF9SRVRVUk4gb3Bjb2RlXG4gICAgICBhc3NlcnQuc3RyaWN0RXF1YWwoc2NyaXB0WzBdLCAweDZhKTtcbiAgICAgIC8vIE1ha2Ugc3VyZSB0aGF0IHRoZSBsZW5ndGggb2YgdGhlIHNjcmlwdCBtYXRjaGVzIHdoYXQgaXMgaW4gdGhlIGJ1ZmZlclxuICAgICAgYXNzZXJ0LnN0cmljdEVxdWFsKHNjcmlwdFsxXSwgMHg0Yyk7XG4gICAgICBhc3NlcnQuc3RyaWN0RXF1YWwoXG4gICAgICAgIC8vIFdlIGRvIG5vdCBjb3VudCB0aGUgT1BfUkVUVVJOIG9wY29kZSBvciB0aGUgbGVuZ3RoICsgcHVzaGJ5dGVzXG4gICAgICAgIHNjcmlwdC5sZW5ndGggLSAzLFxuICAgICAgICBzY3JpcHRbMl1cbiAgICAgICk7XG4gICAgICAvLyBTYXRvc2hpIHBsdXMgaWRlbnRpZmllclxuICAgICAgYXNzZXJ0LmRlZXBTdHJpY3RFcXVhbChzY3JpcHQuc3ViYXJyYXkoMywgNykudG9TdHJpbmcoJ2hleCcpLCBDT1JFX0RBT19TQVRPU0hJX1BMVVNfSURFTlRJRklFUi50b1N0cmluZygnaGV4JykpO1xuICAgICAgLy8gTWFrZSBzdXJlIHRoYXQgdGhlIHZlcnNpb24gaXMgY29ycmVjdFxuICAgICAgYXNzZXJ0LnN0cmljdEVxdWFsKHNjcmlwdFs3XSwgdmFsaWRWZXJzaW9uKTtcbiAgICAgIC8vIE1ha2Ugc3VyZSB0aGF0IHRoZSBjaGFpbklkIGlzIGNvcnJlY3RcbiAgICAgIGFzc2VydC5kZWVwU3RyaWN0RXF1YWwoc2NyaXB0LnN1YmFycmF5KDgsIDEwKS50b1N0cmluZygnaGV4JyksIHZhbGlkQ2hhaW5JZC50b1N0cmluZygnaGV4JykpO1xuICAgICAgLy8gTWFrZSBzdXJlIHRoYXQgdGhlIGRlbGVnYXRvciBpcyBjb3JyZWN0XG4gICAgICBhc3NlcnQuZGVlcFN0cmljdEVxdWFsKHNjcmlwdC5zdWJhcnJheSgxMCwgMzApLnRvU3RyaW5nKCdoZXgnKSwgdmFsaWREZWxlZ2F0b3IudG9TdHJpbmcoJ2hleCcpKTtcbiAgICAgIC8vIE1ha2Ugc3VyZSB0aGF0IHRoZSB2YWxpZGF0b3IgaXMgY29ycmVjdFxuICAgICAgYXNzZXJ0LmRlZXBTdHJpY3RFcXVhbChzY3JpcHQuc3ViYXJyYXkoMzAsIDUwKS50b1N0cmluZygnaGV4JyksIHZhbGlkVmFsaWRhdG9yLnRvU3RyaW5nKCdoZXgnKSk7XG4gICAgICAvLyBNYWtlIHN1cmUgdGhhdCB0aGUgZmVlIGlzIGNvcnJlY3RcbiAgICAgIGFzc2VydC5zdHJpY3RFcXVhbChzY3JpcHRbNTBdLCB2YWxpZEZlZSk7XG4gICAgICAvLyBNYWtlIHN1cmUgdGhhdCB0aGUgcmVkZWVtU2NyaXB0IGlzIGNvcnJlY3RcbiAgICAgIGFzc2VydC5kZWVwU3RyaWN0RXF1YWwoXG4gICAgICAgIHNjcmlwdC5zdWJhcnJheSg1MSwgNTEgKyB2YWxpZFJlZGVlbVNjcmlwdC5sZW5ndGgpLnRvU3RyaW5nKCdoZXgnKSxcbiAgICAgICAgdmFsaWRSZWRlZW1TY3JpcHQudG9TdHJpbmcoJ2hleCcpXG4gICAgICApO1xuICAgIH0pO1xuXG4gICAgaXQoJ3Nob3VsZCBoYXZlIHRoZSBjb3JyZWN0IHBsYWNlbWVudCBvZiB0aGUgdmFsdWVzIHByb3ZpZGVkIHdpdGggYSBibG9ja2hlaWdodCB0aW1lbG9jaycsIGZ1bmN0aW9uICgpIHtcbiAgICAgIC8vIFRoaXMgc2hvdWxkIHByb2R1Y2UgYW4gT3BfUkVUVVJOIHRoYXQgbmVlZHMgdGhlIGV4dHJhIHB1c2ggYnl0ZXMgZm9yIHRoZSBsZW5ndGhcbiAgICAgIGNvbnN0IHNjcmlwdCA9IGNyZWF0ZUNvcmVEYW9PcFJldHVybk91dHB1dFNjcmlwdCh7XG4gICAgICAgIHZlcnNpb246IHZhbGlkVmVyc2lvbixcbiAgICAgICAgY2hhaW5JZDogdmFsaWRDaGFpbklkLFxuICAgICAgICBkZWxlZ2F0b3I6IHZhbGlkRGVsZWdhdG9yLFxuICAgICAgICB2YWxpZGF0b3I6IHZhbGlkVmFsaWRhdG9yLFxuICAgICAgICBmZWU6IHZhbGlkRmVlLFxuICAgICAgICB0aW1lbG9jazogdmFsaWRUaW1lbG9jayxcbiAgICAgIH0pO1xuICAgICAgLy8gTWFrZSBzdXJlIHRoYXQgdGhlIGZpcnN0IGJ5dGUgaXMgdGhlIE9QX1JFVFVSTiBvcGNvZGVcbiAgICAgIGFzc2VydC5zdHJpY3RFcXVhbChzY3JpcHRbMF0sIDB4NmEpO1xuICAgICAgLy8gTWFrZSBzdXJlIHRoYXQgdGhlIGxlbmd0aCBvZiB0aGUgc2NyaXB0IG1hdGNoZXMgd2hhdCBpcyBpbiB0aGUgYnVmZmVyXG4gICAgICBhc3NlcnQuc3RyaWN0RXF1YWwoXG4gICAgICAgIC8vIFdlIGRvIG5vdCBjb3VudCB0aGUgT1BfUkVUVVJOIG9wY29kZSBvciB0aGUgbGVuZ3RoXG4gICAgICAgIHNjcmlwdC5sZW5ndGggLSAyLFxuICAgICAgICBzY3JpcHRbMV1cbiAgICAgICk7XG4gICAgICAvLyBTYXRvc2hpIHBsdXMgaWRlbnRpZmllclxuICAgICAgYXNzZXJ0LmRlZXBTdHJpY3RFcXVhbChzY3JpcHQuc3ViYXJyYXkoMiwgNikudG9TdHJpbmcoJ2hleCcpLCBDT1JFX0RBT19TQVRPU0hJX1BMVVNfSURFTlRJRklFUi50b1N0cmluZygnaGV4JykpO1xuICAgICAgLy8gTWFrZSBzdXJlIHRoYXQgdGhlIHZlcnNpb24gaXMgY29ycmVjdFxuICAgICAgYXNzZXJ0LnN0cmljdEVxdWFsKHNjcmlwdFs2XSwgdmFsaWRWZXJzaW9uKTtcbiAgICAgIC8vIE1ha2Ugc3VyZSB0aGF0IHRoZSBjaGFpbklkIGlzIGNvcnJlY3RcbiAgICAgIGFzc2VydC5kZWVwU3RyaWN0RXF1YWwoc2NyaXB0LnN1YmFycmF5KDcsIDkpLnRvU3RyaW5nKCdoZXgnKSwgdmFsaWRDaGFpbklkLnRvU3RyaW5nKCdoZXgnKSk7XG4gICAgICAvLyBNYWtlIHN1cmUgdGhhdCB0aGUgZGVsZWdhdG9yIGlzIGNvcnJlY3RcbiAgICAgIGFzc2VydC5kZWVwU3RyaWN0RXF1YWwoc2NyaXB0LnN1YmFycmF5KDksIDI5KS50b1N0cmluZygnaGV4JyksIHZhbGlkRGVsZWdhdG9yLnRvU3RyaW5nKCdoZXgnKSk7XG4gICAgICAvLyBNYWtlIHN1cmUgdGhhdCB0aGUgdmFsaWRhdG9yIGlzIGNvcnJlY3RcbiAgICAgIGFzc2VydC5kZWVwU3RyaWN0RXF1YWwoc2NyaXB0LnN1YmFycmF5KDI5LCA0OSkudG9TdHJpbmcoJ2hleCcpLCB2YWxpZFZhbGlkYXRvci50b1N0cmluZygnaGV4JykpO1xuICAgICAgLy8gTWFrZSBzdXJlIHRoYXQgdGhlIGZlZSBpcyBjb3JyZWN0XG4gICAgICBhc3NlcnQuc3RyaWN0RXF1YWwoc2NyaXB0WzQ5XSwgdmFsaWRGZWUpO1xuICAgICAgLy8gTWFrZSBzdXJlIHRoYXQgdGhlIHJlZGVlbVNjcmlwdCBpcyBjb3JyZWN0XG4gICAgICBhc3NlcnQuZGVlcFN0cmljdEVxdWFsKHNjcmlwdC5zdWJhcnJheSg1MCwgNTQpLnRvU3RyaW5nKCdoZXgnKSwgZW5jb2RlVGltZWxvY2sodmFsaWRUaW1lbG9jaykudG9TdHJpbmcoJ2hleCcpKTtcbiAgICAgIGFzc2VydC5kZWVwU3RyaWN0RXF1YWwoZGVjb2RlVGltZWxvY2soc2NyaXB0LnN1YmFycmF5KDUwLCA1NCkpLCB2YWxpZFRpbWVsb2NrKTtcbiAgICB9KTtcblxuICAgIGl0KCdzaG91bGQgaGF2ZSB0aGUgY29ycmVjdCBwbGFjZW1lbnQgb2YgdGhlIHZhbHVlcyBwcm92aWRlZCB3aXRoIGEgdGltZSB0aW1lbG9jaycsIGZ1bmN0aW9uICgpIHtcbiAgICAgIC8vIFRoaXMgc2hvdWxkIHByb2R1Y2UgYW4gT3BfUkVUVVJOIHRoYXQgbmVlZHMgdGhlIGV4dHJhIHB1c2ggYnl0ZXMgZm9yIHRoZSBsZW5ndGhcbiAgICAgIGNvbnN0IHRpbWVsb2NrID0gbmV3IERhdGUoJzIwMjItMDEtMDFUMDA6MDA6MDBaJykuZ2V0VGltZSgpIC8gMTAwMDtcbiAgICAgIGNvbnN0IHNjcmlwdCA9IGNyZWF0ZUNvcmVEYW9PcFJldHVybk91dHB1dFNjcmlwdCh7XG4gICAgICAgIHZlcnNpb246IHZhbGlkVmVyc2lvbixcbiAgICAgICAgY2hhaW5JZDogdmFsaWRDaGFpbklkLFxuICAgICAgICBkZWxlZ2F0b3I6IHZhbGlkRGVsZWdhdG9yLFxuICAgICAgICB2YWxpZGF0b3I6IHZhbGlkVmFsaWRhdG9yLFxuICAgICAgICBmZWU6IHZhbGlkRmVlLFxuICAgICAgICB0aW1lbG9jayxcbiAgICAgIH0pO1xuICAgICAgLy8gTWFrZSBzdXJlIHRoYXQgdGhlIGZpcnN0IGJ5dGUgaXMgdGhlIE9QX1JFVFVSTiBvcGNvZGVcbiAgICAgIGFzc2VydC5zdHJpY3RFcXVhbChzY3JpcHRbMF0sIDB4NmEpO1xuICAgICAgLy8gTWFrZSBzdXJlIHRoYXQgdGhlIGxlbmd0aCBvZiB0aGUgc2NyaXB0IG1hdGNoZXMgd2hhdCBpcyBpbiB0aGUgYnVmZmVyXG4gICAgICBhc3NlcnQuc3RyaWN0RXF1YWwoXG4gICAgICAgIC8vIFdlIGRvIG5vdCBjb3VudCB0aGUgT1BfUkVUVVJOIG9wY29kZSBvciB0aGUgbGVuZ3RoXG4gICAgICAgIHNjcmlwdC5sZW5ndGggLSAyLFxuICAgICAgICBzY3JpcHRbMV1cbiAgICAgICk7XG4gICAgICAvLyBTYXRvc2hpIHBsdXMgaWRlbnRpZmllclxuICAgICAgYXNzZXJ0LmRlZXBTdHJpY3RFcXVhbChzY3JpcHQuc3ViYXJyYXkoMiwgNikudG9TdHJpbmcoJ2hleCcpLCBDT1JFX0RBT19TQVRPU0hJX1BMVVNfSURFTlRJRklFUi50b1N0cmluZygnaGV4JykpO1xuICAgICAgLy8gTWFrZSBzdXJlIHRoYXQgdGhlIHZlcnNpb24gaXMgY29ycmVjdFxuICAgICAgYXNzZXJ0LnN0cmljdEVxdWFsKHNjcmlwdFs2XSwgdmFsaWRWZXJzaW9uKTtcbiAgICAgIC8vIE1ha2Ugc3VyZSB0aGF0IHRoZSBjaGFpbklkIGlzIGNvcnJlY3RcbiAgICAgIGFzc2VydC5kZWVwU3RyaWN0RXF1YWwoc2NyaXB0LnN1YmFycmF5KDcsIDkpLnRvU3RyaW5nKCdoZXgnKSwgdmFsaWRDaGFpbklkLnRvU3RyaW5nKCdoZXgnKSk7XG4gICAgICAvLyBNYWtlIHN1cmUgdGhhdCB0aGUgZGVsZWdhdG9yIGlzIGNvcnJlY3RcbiAgICAgIGFzc2VydC5kZWVwU3RyaWN0RXF1YWwoc2NyaXB0LnN1YmFycmF5KDksIDI5KS50b1N0cmluZygnaGV4JyksIHZhbGlkRGVsZWdhdG9yLnRvU3RyaW5nKCdoZXgnKSk7XG4gICAgICAvLyBNYWtlIHN1cmUgdGhhdCB0aGUgdmFsaWRhdG9yIGlzIGNvcnJlY3RcbiAgICAgIGFzc2VydC5kZWVwU3RyaWN0RXF1YWwoc2NyaXB0LnN1YmFycmF5KDI5LCA0OSkudG9TdHJpbmcoJ2hleCcpLCB2YWxpZFZhbGlkYXRvci50b1N0cmluZygnaGV4JykpO1xuICAgICAgLy8gTWFrZSBzdXJlIHRoYXQgdGhlIGZlZSBpcyBjb3JyZWN0XG4gICAgICBhc3NlcnQuc3RyaWN0RXF1YWwoc2NyaXB0WzQ5XSwgdmFsaWRGZWUpO1xuICAgICAgLy8gTWFrZSBzdXJlIHRoYXQgdGhlIHJlZGVlbVNjcmlwdCBpcyBjb3JyZWN0XG4gICAgICBhc3NlcnQuZGVlcFN0cmljdEVxdWFsKHNjcmlwdC5zdWJhcnJheSg1MCwgNTQpLnRvU3RyaW5nKCdoZXgnKSwgZW5jb2RlVGltZWxvY2sodGltZWxvY2spLnRvU3RyaW5nKCdoZXgnKSk7XG4gICAgICBhc3NlcnQuZGVlcFN0cmljdEVxdWFsKGRlY29kZVRpbWVsb2NrKHNjcmlwdC5zdWJhcnJheSg1MCwgNTQpKSwgdGltZWxvY2spO1xuICAgIH0pO1xuXG4gICAgaXQoJ3Nob3VsZCByZWNyZWF0ZSB0aGUgZXhhbXBsZSBPUF9SRVRVUk4gY29ycmVjdGx5JywgZnVuY3Rpb24gKCkge1xuICAgICAgYXNzZXJ0LmRlZXBTdHJpY3RFcXVhbChcbiAgICAgICAgY3JlYXRlQ29yZURhb09wUmV0dXJuT3V0cHV0U2NyaXB0KHtcbiAgICAgICAgICB2ZXJzaW9uOiAxLFxuICAgICAgICAgIGNoYWluSWQ6IEJ1ZmZlci5mcm9tKCcwNDViJywgJ2hleCcpLFxuICAgICAgICAgIGRlbGVnYXRvcjogQnVmZmVyLmZyb20oJ2RlNjBiN2QwZTZiNzU4Y2E1ZGQ4YzYxZDM3N2EyYzVmMWFmNTFlYzEnLCAnaGV4JyksXG4gICAgICAgICAgdmFsaWRhdG9yOiBCdWZmZXIuZnJvbSgnYTllMjA5ZjVlYTAwMzZjOGMyZjQxMDc4YTNjZWJlZTU3ZDhhNDdkNScsICdoZXgnKSxcbiAgICAgICAgICBmZWU6IDEsXG4gICAgICAgICAgcmVkZWVtU2NyaXB0OiBCdWZmZXIuZnJvbSgnMDQxZjVlMGU2NmIxNzU3NmE5MTRjNGI4YWU5MjdmZjJiOWNlMjE4ZTIwYmYwNmQ0MjVkNmI2ODQyNGZkODhhYycsICdoZXgnKSxcbiAgICAgICAgfSkudG9TdHJpbmcoJ2hleCcpLFxuICAgICAgICBkZWZhdWx0U2NyaXB0XG4gICAgICApO1xuICAgIH0pO1xuICB9KTtcblxuICBkZXNjcmliZSgncGFyc2VDb3JlRGFvT3BSZXR1cm5PdXRwdXRTY3JpcHQnLCBmdW5jdGlvbiAoKSB7XG4gICAgaXQoJ3Nob3VsZCBwYXJzZSBhIHZhbGlkIHNjcmlwdCB3aXRoIGEgdGltZWxvY2snLCBmdW5jdGlvbiAoKSB7XG4gICAgICBjb25zdCBzY3JpcHQgPSBjcmVhdGVDb3JlRGFvT3BSZXR1cm5PdXRwdXRTY3JpcHQoe1xuICAgICAgICB2ZXJzaW9uOiB2YWxpZFZlcnNpb24sXG4gICAgICAgIGNoYWluSWQ6IHZhbGlkQ2hhaW5JZCxcbiAgICAgICAgZGVsZWdhdG9yOiB2YWxpZERlbGVnYXRvcixcbiAgICAgICAgdmFsaWRhdG9yOiB2YWxpZFZhbGlkYXRvcixcbiAgICAgICAgZmVlOiB2YWxpZEZlZSxcbiAgICAgICAgdGltZWxvY2s6IHZhbGlkVGltZWxvY2ssXG4gICAgICB9KTtcbiAgICAgIGNvbnN0IHBhcnNlZCA9IHBhcnNlQ29yZURhb09wUmV0dXJuT3V0cHV0U2NyaXB0KHNjcmlwdCk7XG4gICAgICBhc3NlcnQuc3RyaWN0RXF1YWwocGFyc2VkLnZlcnNpb24sIHZhbGlkVmVyc2lvbik7XG4gICAgICBhc3NlcnQuZGVlcFN0cmljdEVxdWFsKHBhcnNlZC5jaGFpbklkLCB2YWxpZENoYWluSWQpO1xuICAgICAgYXNzZXJ0LmRlZXBTdHJpY3RFcXVhbChwYXJzZWQuZGVsZWdhdG9yLCB2YWxpZERlbGVnYXRvcik7XG4gICAgICBhc3NlcnQuZGVlcFN0cmljdEVxdWFsKHBhcnNlZC52YWxpZGF0b3IsIHZhbGlkVmFsaWRhdG9yKTtcbiAgICAgIGFzc2VydC5zdHJpY3RFcXVhbChwYXJzZWQuZmVlLCB2YWxpZEZlZSk7XG4gICAgICBhc3NlcnQoJ3RpbWVsb2NrJyBpbiBwYXJzZWQpO1xuICAgICAgYXNzZXJ0LmRlZXBTdHJpY3RFcXVhbChwYXJzZWQudGltZWxvY2ssIHZhbGlkVGltZWxvY2spO1xuICAgIH0pO1xuXG4gICAgaXQoJ3Nob3VsZCBwYXJzZSBhIHZhbGlkIHNjcmlwdCB3aXRoIGEgcmVkZWVtIHNjcmlwdCcsIGZ1bmN0aW9uICgpIHtcbiAgICAgIGNvbnN0IHNjcmlwdCA9IGNyZWF0ZUNvcmVEYW9PcFJldHVybk91dHB1dFNjcmlwdCh7XG4gICAgICAgIHZlcnNpb246IHZhbGlkVmVyc2lvbixcbiAgICAgICAgY2hhaW5JZDogdmFsaWRDaGFpbklkLFxuICAgICAgICBkZWxlZ2F0b3I6IHZhbGlkRGVsZWdhdG9yLFxuICAgICAgICB2YWxpZGF0b3I6IHZhbGlkVmFsaWRhdG9yLFxuICAgICAgICBmZWU6IHZhbGlkRmVlLFxuICAgICAgICByZWRlZW1TY3JpcHQ6IHZhbGlkUmVkZWVtU2NyaXB0LFxuICAgICAgfSk7XG4gICAgICBjb25zdCBwYXJzZWQgPSBwYXJzZUNvcmVEYW9PcFJldHVybk91dHB1dFNjcmlwdChzY3JpcHQpO1xuICAgICAgYXNzZXJ0LnN0cmljdEVxdWFsKHBhcnNlZC52ZXJzaW9uLCB2YWxpZFZlcnNpb24pO1xuICAgICAgYXNzZXJ0LmRlZXBTdHJpY3RFcXVhbChwYXJzZWQuY2hhaW5JZCwgdmFsaWRDaGFpbklkKTtcbiAgICAgIGFzc2VydC5kZWVwU3RyaWN0RXF1YWwocGFyc2VkLmRlbGVnYXRvciwgdmFsaWREZWxlZ2F0b3IpO1xuICAgICAgYXNzZXJ0LmRlZXBTdHJpY3RFcXVhbChwYXJzZWQudmFsaWRhdG9yLCB2YWxpZFZhbGlkYXRvcik7XG4gICAgICBhc3NlcnQuc3RyaWN0RXF1YWwocGFyc2VkLmZlZSwgdmFsaWRGZWUpO1xuICAgICAgYXNzZXJ0KCdyZWRlZW1TY3JpcHQnIGluIHBhcnNlZCk7XG4gICAgICBhc3NlcnQuZGVlcFN0cmljdEVxdWFsKHBhcnNlZC5yZWRlZW1TY3JpcHQsIHZhbGlkUmVkZWVtU2NyaXB0KTtcbiAgICB9KTtcblxuICAgIGl0KCdzaG91bGQgcGFyc2UgdmFsaWQgb3ByZXR1cm4gc2NyaXB0IGZyb20gdGVzdG5ldCcsIGFzeW5jIGZ1bmN0aW9uICgpIHtcbiAgICAgIC8vIFNvdXJjZTogaHR0cHM6Ly9tZW1wb29sLnNwYWNlL3Rlc3RuZXQvdHgvNjZlZDRjZWEyNmE0MTAyNDhhNmQ4N2YxNGIyYmNhNTE0ZjMzOTIwYzU0ZDRhZjYzZWQ0NmE5MDM3OTMxMTVkNVxuICAgICAgY29uc3QgYmFzZUZpeHR1cmVQYXRoID1cbiAgICAgICAgJ3Rlc3QvZml4dHVyZXMvY29yZURhby9vcFJldHVybi82NmVkNGNlYTI2YTQxMDI0OGE2ZDg3ZjE0YjJiY2E1MTRmMzM5MjBjNTRkNGFmNjNlZDQ2YTkwMzc5MzExNWQ1JztcbiAgICAgIGNvbnN0IG9wUmV0dXJuSGV4ID0gYXdhaXQgZ2V0Rml4dHVyZShiYXNlRml4dHVyZVBhdGggKyAnLnR4dCcsIHVuZGVmaW5lZCk7XG4gICAgICBhc3NlcnQodHlwZW9mIG9wUmV0dXJuSGV4ID09PSAnc3RyaW5nJyk7XG4gICAgICBjb25zdCBwYXJzZWQgPSBwYXJzZUNvcmVEYW9PcFJldHVybk91dHB1dFNjcmlwdChCdWZmZXIuZnJvbShvcFJldHVybkhleCwgJ2hleCcpKTtcbiAgICAgIGNvbnN0IHBhcnNlZEZpeHR1cmUgPSBhd2FpdCBnZXRGaXh0dXJlKGJhc2VGaXh0dXJlUGF0aCArICcuanNvbicsIEpTT04ucGFyc2UodG9TdHJpbmcocGFyc2VkKSkpO1xuICAgICAgYXNzZXJ0LmRlZXBTdHJpY3RFcXVhbCh0b1N0cmluZyhwYXJzZWQpLCBKU09OLnN0cmluZ2lmeShwYXJzZWRGaXh0dXJlKSk7XG4gICAgfSk7XG5cbiAgICBpdCgnc2hvdWxkIGZhaWwgaWYgdGhlcmUgaXMgYW4gaW52YWxpZCBvcC1yZXR1cm4nLCBmdW5jdGlvbiAoKSB7XG4gICAgICBjb25zdCBzY3JpcHQgPSBkZWZhdWx0U2NyaXB0LnJlcGxhY2UoJzZhNGM1MCcsICc2YjRjNTAnKTtcbiAgICAgIGFzc2VydC50aHJvd3MoKCkgPT4gcGFyc2VDb3JlRGFvT3BSZXR1cm5PdXRwdXRTY3JpcHQoQnVmZmVyLmZyb20oc2NyaXB0LCAnaGV4JykpKTtcbiAgICB9KTtcblxuICAgIGl0KCdzaG91bGQgZmFpbCBpZiB0aGUgbGVuZ3RoIGlzIGluY29ycmVjdCcsIGZ1bmN0aW9uICgpIHtcbiAgICAgIGNvbnN0IHNjcmlwdCA9IGRlZmF1bHRTY3JpcHQucmVwbGFjZSgnNGM1MCcsICc0YzUxJyk7XG4gICAgICBhc3NlcnQudGhyb3dzKCgpID0+IHBhcnNlQ29yZURhb09wUmV0dXJuT3V0cHV0U2NyaXB0KEJ1ZmZlci5mcm9tKHNjcmlwdCwgJ2hleCcpKSk7XG4gICAgfSk7XG5cbiAgICBpdCgnc2hvdWxkIGZhaWwgaWYgdGhlIHNhdG9zaGkrIGlkZW50aWZpZXIgaXMgaW5jb3JyZWN0JywgZnVuY3Rpb24gKCkge1xuICAgICAgY29uc3Qgc2NyaXB0ID0gZGVmYXVsdFNjcmlwdC5yZXBsYWNlKCc1MzQxNTQyYicsICc1MzQxNTMyYicpO1xuICAgICAgYXNzZXJ0LnRocm93cygoKSA9PiBwYXJzZUNvcmVEYW9PcFJldHVybk91dHB1dFNjcmlwdChCdWZmZXIuZnJvbShzY3JpcHQsICdoZXgnKSkpO1xuICAgIH0pO1xuXG4gICAgaXQoJ3Nob3VsZCBmYWlsIGlmIHRoZSBjaGFpbklkIGlzIGluY29ycmVjdCcsIGZ1bmN0aW9uICgpIHtcbiAgICAgIGNvbnN0IHNjcmlwdCA9IGRlZmF1bHRTY3JpcHQucmVwbGFjZSgnMDQ1YicsICcwNDU0Jyk7XG4gICAgICBhc3NlcnQudGhyb3dzKCgpID0+IHBhcnNlQ29yZURhb09wUmV0dXJuT3V0cHV0U2NyaXB0KEJ1ZmZlci5mcm9tKHNjcmlwdCwgJ2hleCcpKSk7XG4gICAgfSk7XG4gIH0pO1xufSk7XG4iXX0=
|