@bitgo-beta/sdk-core 8.2.1-beta.199 → 8.2.1-beta.1990
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/src/account-lib/baseCoin/baseTransaction.d.ts +0 -1
- package/dist/src/account-lib/baseCoin/baseTransaction.d.ts.map +1 -1
- package/dist/src/account-lib/baseCoin/baseTransactionBuilder.d.ts +3 -3
- package/dist/src/account-lib/baseCoin/baseTransactionBuilder.d.ts.map +1 -1
- package/dist/src/account-lib/baseCoin/baseTransactionBuilder.js +4 -3
- package/dist/src/account-lib/baseCoin/ed25519KeyPair.d.ts +1 -0
- package/dist/src/account-lib/baseCoin/ed25519KeyPair.d.ts.map +1 -1
- package/dist/src/account-lib/baseCoin/ed25519KeyPair.js +41 -29
- package/dist/src/account-lib/baseCoin/enum.d.ts +57 -5
- package/dist/src/account-lib/baseCoin/enum.d.ts.map +1 -1
- package/dist/src/account-lib/baseCoin/enum.js +107 -10
- package/dist/src/account-lib/baseCoin/errors.d.ts +3 -0
- package/dist/src/account-lib/baseCoin/errors.d.ts.map +1 -1
- package/dist/src/account-lib/baseCoin/errors.js +8 -2
- package/dist/src/account-lib/baseCoin/iface.d.ts +19 -35
- package/dist/src/account-lib/baseCoin/iface.d.ts.map +1 -1
- package/dist/src/account-lib/baseCoin/iface.js +26 -18
- package/dist/src/account-lib/baseCoin/index.d.ts +1 -1
- package/dist/src/account-lib/baseCoin/index.d.ts.map +1 -1
- package/dist/src/account-lib/baseCoin/index.js +8 -5
- package/dist/src/account-lib/baseCoin/messages/baseMessage.d.ts +88 -0
- package/dist/src/account-lib/baseCoin/messages/baseMessage.d.ts.map +1 -0
- package/dist/src/account-lib/baseCoin/messages/baseMessage.js +154 -0
- package/dist/src/account-lib/baseCoin/messages/baseMessageBuilder.d.ts +67 -0
- package/dist/src/account-lib/baseCoin/messages/baseMessageBuilder.d.ts.map +1 -0
- package/dist/src/account-lib/baseCoin/messages/baseMessageBuilder.js +144 -0
- package/dist/src/account-lib/baseCoin/messages/baseMessageBuilderFactory.d.ts +33 -0
- package/dist/src/account-lib/baseCoin/messages/baseMessageBuilderFactory.d.ts.map +1 -0
- package/dist/src/account-lib/baseCoin/messages/baseMessageBuilderFactory.js +45 -0
- package/dist/src/account-lib/baseCoin/messages/iface.d.ts +164 -0
- package/dist/src/account-lib/baseCoin/messages/iface.d.ts.map +1 -0
- package/dist/src/account-lib/baseCoin/messages/iface.js +3 -0
- package/dist/src/account-lib/baseCoin/messages/index.d.ts +6 -0
- package/dist/src/account-lib/baseCoin/messages/index.d.ts.map +1 -0
- package/dist/src/account-lib/baseCoin/messages/index.js +22 -0
- package/dist/src/account-lib/baseCoin/messages/simple/index.d.ts +3 -0
- package/dist/src/account-lib/baseCoin/messages/simple/index.d.ts.map +1 -0
- package/dist/src/account-lib/baseCoin/messages/simple/index.js +19 -0
- package/dist/src/account-lib/baseCoin/messages/simple/simpleMessage.d.ts +13 -0
- package/dist/src/account-lib/baseCoin/messages/simple/simpleMessage.d.ts.map +1 -0
- package/dist/src/account-lib/baseCoin/messages/simple/simpleMessage.js +28 -0
- package/dist/src/account-lib/baseCoin/messages/simple/simpleMessageBuilder.d.ts +21 -0
- package/dist/src/account-lib/baseCoin/messages/simple/simpleMessageBuilder.d.ts.map +1 -0
- package/dist/src/account-lib/baseCoin/messages/simple/simpleMessageBuilder.js +28 -0
- package/dist/src/account-lib/baseCoin/secp256k1ExtendedKeyPair.d.ts +1 -2
- package/dist/src/account-lib/baseCoin/secp256k1ExtendedKeyPair.d.ts.map +1 -1
- package/dist/src/account-lib/baseCoin/secp256k1ExtendedKeyPair.js +38 -26
- package/dist/src/account-lib/index.js +23 -9
- package/dist/src/account-lib/mpc/index.d.ts +1 -1
- package/dist/src/account-lib/mpc/index.d.ts.map +1 -1
- package/dist/src/account-lib/mpc/index.js +6 -2
- package/dist/src/account-lib/mpc/tss/ecdsa/ecdsa.d.ts +2 -3
- package/dist/src/account-lib/mpc/tss/ecdsa/ecdsa.d.ts.map +1 -1
- package/dist/src/account-lib/mpc/tss/ecdsa/ecdsa.js +376 -354
- package/dist/src/account-lib/mpc/tss/ecdsa/index.js +23 -9
- package/dist/src/account-lib/mpc/tss/ecdsa/rangeproof.d.ts +2 -2
- package/dist/src/account-lib/mpc/tss/ecdsa/rangeproof.d.ts.map +1 -1
- package/dist/src/account-lib/mpc/tss/ecdsa/rangeproof.js +3 -3
- package/dist/src/account-lib/mpc/tss/ecdsa/types.d.ts +46 -53
- package/dist/src/account-lib/mpc/tss/ecdsa/types.d.ts.map +1 -1
- package/dist/src/account-lib/mpc/tss/ecdsa/types.js +1 -1
- package/dist/src/account-lib/mpc/tss/eddsa/eddsa.d.ts +0 -1
- package/dist/src/account-lib/mpc/tss/eddsa/eddsa.d.ts.map +1 -1
- package/dist/src/account-lib/mpc/tss/eddsa/eddsa.js +66 -69
- package/dist/src/account-lib/mpc/tss/eddsa/index.js +23 -9
- package/dist/src/account-lib/mpc/tss/eddsa/types.d.ts +1 -1
- package/dist/src/account-lib/mpc/tss/eddsa/types.d.ts.map +1 -1
- package/dist/src/account-lib/mpc/tss/eddsa/types.js +1 -1
- package/dist/src/account-lib/mpc/tss/index.js +23 -9
- package/dist/src/account-lib/mpc/util.d.ts +7 -1
- package/dist/src/account-lib/mpc/util.d.ts.map +1 -1
- package/dist/src/account-lib/mpc/util.js +24 -1
- package/dist/src/account-lib/staking/index.js +6 -2
- package/dist/src/account-lib/staking/utils.js +3 -3
- package/dist/src/account-lib/util/crypto.d.ts +8 -2
- package/dist/src/account-lib/util/crypto.d.ts.map +1 -1
- package/dist/src/account-lib/util/crypto.js +69 -38
- package/dist/src/account-lib/util/ed25519KeyDeriver.d.ts +2 -1
- package/dist/src/account-lib/util/ed25519KeyDeriver.d.ts.map +1 -1
- package/dist/src/account-lib/util/ed25519KeyDeriver.js +5 -3
- package/dist/src/api/bip32path.js +2 -3
- package/dist/src/api/index.js +6 -2
- package/dist/src/api/types.d.ts +31 -0
- package/dist/src/api/types.d.ts.map +1 -1
- package/dist/src/api/types.js +1 -1
- package/dist/src/bitgo/address-book/address-book.d.ts.map +1 -1
- package/dist/src/bitgo/address-book/address-book.js +20 -12
- package/dist/src/bitgo/address-book/index.js +6 -2
- package/dist/src/bitgo/address-book/types.d.ts +36 -36
- package/dist/src/bitgo/address-book/types.d.ts.map +1 -1
- package/dist/src/bitgo/baseCoin/baseCoin.d.ts +121 -12
- package/dist/src/bitgo/baseCoin/baseCoin.d.ts.map +1 -1
- package/dist/src/bitgo/baseCoin/baseCoin.js +203 -16
- package/dist/src/bitgo/baseCoin/iBaseCoin.d.ts +279 -27
- package/dist/src/bitgo/baseCoin/iBaseCoin.d.ts.map +1 -1
- package/dist/src/bitgo/baseCoin/iBaseCoin.js +14 -3
- package/dist/src/bitgo/baseCoin/index.js +6 -2
- package/dist/src/bitgo/bip32util.d.ts +3 -16
- package/dist/src/bitgo/bip32util.d.ts.map +1 -1
- package/dist/src/bitgo/bip32util.js +4 -56
- package/dist/src/bitgo/bitcoin.d.ts +0 -1
- package/dist/src/bitgo/bitcoin.d.ts.map +1 -1
- package/dist/src/bitgo/bitcoin.js +26 -13
- package/dist/src/bitgo/bitgoBase.d.ts +17 -4
- package/dist/src/bitgo/bitgoBase.d.ts.map +1 -1
- package/dist/src/bitgo/bitgoBase.js +1 -1
- package/dist/src/bitgo/coinFactory.d.ts +17 -3
- package/dist/src/bitgo/coinFactory.d.ts.map +1 -1
- package/dist/src/bitgo/coinFactory.js +26 -3
- package/dist/src/bitgo/config.d.ts +3 -95
- package/dist/src/bitgo/config.d.ts.map +1 -1
- package/dist/src/bitgo/config.js +26 -15
- package/dist/src/bitgo/defi/defiVault.d.ts +137 -0
- package/dist/src/bitgo/defi/defiVault.d.ts.map +1 -0
- package/dist/src/bitgo/defi/defiVault.js +379 -0
- package/dist/src/bitgo/defi/iDefiVault.d.ts +81 -0
- package/dist/src/bitgo/defi/iDefiVault.d.ts.map +1 -0
- package/dist/src/bitgo/defi/iDefiVault.js +6 -0
- package/dist/src/bitgo/defi/index.d.ts +3 -0
- package/dist/src/bitgo/defi/index.d.ts.map +1 -0
- package/dist/src/bitgo/defi/index.js +22 -0
- package/dist/src/bitgo/ecdh.d.ts +0 -1
- package/dist/src/bitgo/ecdh.d.ts.map +1 -1
- package/dist/src/bitgo/ecdh.js +26 -13
- package/dist/src/bitgo/enterprise/enterprise.d.ts +9 -4
- package/dist/src/bitgo/enterprise/enterprise.d.ts.map +1 -1
- package/dist/src/bitgo/enterprise/enterprise.js +47 -21
- package/dist/src/bitgo/enterprise/enterprises.js +27 -13
- package/dist/src/bitgo/enterprise/iEnterprise.d.ts +5 -3
- package/dist/src/bitgo/enterprise/iEnterprise.d.ts.map +1 -1
- package/dist/src/bitgo/enterprise/iEnterprise.js +1 -1
- package/dist/src/bitgo/enterprise/index.js +6 -2
- package/dist/src/bitgo/environments.d.ts +68 -3
- package/dist/src/bitgo/environments.d.ts.map +1 -1
- package/dist/src/bitgo/environments.js +414 -34
- package/dist/src/bitgo/errors.d.ts +182 -1
- package/dist/src/bitgo/errors.d.ts.map +1 -1
- package/dist/src/bitgo/errors.js +177 -3
- package/dist/src/bitgo/evm/evmUtils.d.ts +26 -0
- package/dist/src/bitgo/evm/evmUtils.d.ts.map +1 -0
- package/dist/src/bitgo/evm/evmUtils.js +50 -0
- package/dist/src/bitgo/index.d.ts +5 -1
- package/dist/src/bitgo/index.d.ts.map +1 -1
- package/dist/src/bitgo/index.js +31 -11
- package/dist/src/bitgo/inscriptionBuilder/iInscriptionBuilder.d.ts +3 -3
- package/dist/src/bitgo/inscriptionBuilder/iInscriptionBuilder.d.ts.map +1 -1
- package/dist/src/bitgo/inscriptionBuilder/iInscriptionBuilder.js +1 -1
- package/dist/src/bitgo/inscriptionBuilder/index.js +6 -2
- package/dist/src/bitgo/internal/index.js +6 -2
- package/dist/src/bitgo/internal/internal.js +5 -6
- package/dist/src/bitgo/internal/keycard.d.ts +12 -8
- package/dist/src/bitgo/internal/keycard.d.ts.map +1 -1
- package/dist/src/bitgo/internal/keycard.js +60 -48
- package/dist/src/bitgo/keychain/decryptKeychain.d.ts +14 -0
- package/dist/src/bitgo/keychain/decryptKeychain.d.ts.map +1 -0
- package/dist/src/bitgo/keychain/decryptKeychain.js +36 -0
- package/dist/src/bitgo/keychain/iKeychains.d.ts +128 -11
- package/dist/src/bitgo/keychain/iKeychains.d.ts.map +1 -1
- package/dist/src/bitgo/keychain/iKeychains.js +2 -2
- package/dist/src/bitgo/keychain/index.d.ts +1 -0
- package/dist/src/bitgo/keychain/index.d.ts.map +1 -1
- package/dist/src/bitgo/keychain/index.js +7 -2
- package/dist/src/bitgo/keychain/keychains.d.ts +55 -7
- package/dist/src/bitgo/keychain/keychains.d.ts.map +1 -1
- package/dist/src/bitgo/keychain/keychains.js +262 -52
- package/dist/src/bitgo/keychain/ovcJsonCodec.d.ts +3 -3
- package/dist/src/bitgo/keychain/ovcJsonCodec.d.ts.map +1 -1
- package/dist/src/bitgo/keychain/ovcJsonCodec.js +23 -9
- package/dist/src/bitgo/legacyBitcoin.d.ts +0 -1
- package/dist/src/bitgo/legacyBitcoin.d.ts.map +1 -1
- package/dist/src/bitgo/legacyBitcoin.js +27 -13
- package/dist/src/bitgo/lightning/lightningWalletUtil.d.ts +7 -0
- package/dist/src/bitgo/lightning/lightningWalletUtil.d.ts.map +1 -0
- package/dist/src/bitgo/lightning/lightningWalletUtil.js +25 -0
- package/dist/src/bitgo/market/iMarkets.d.ts +2 -2
- package/dist/src/bitgo/market/iMarkets.d.ts.map +1 -1
- package/dist/src/bitgo/market/index.js +6 -2
- package/dist/src/bitgo/market/markets.js +23 -9
- package/dist/src/bitgo/pendingApproval/iPendingApproval.d.ts +5 -1
- package/dist/src/bitgo/pendingApproval/iPendingApproval.d.ts.map +1 -1
- package/dist/src/bitgo/pendingApproval/iPendingApproval.js +4 -4
- package/dist/src/bitgo/pendingApproval/index.js +6 -2
- package/dist/src/bitgo/pendingApproval/pendingApproval.d.ts +20 -8
- package/dist/src/bitgo/pendingApproval/pendingApproval.d.ts.map +1 -1
- package/dist/src/bitgo/pendingApproval/pendingApproval.js +246 -111
- package/dist/src/bitgo/pendingApproval/pendingApprovals.js +23 -9
- package/dist/src/bitgo/proofs/WalletProofs.d.ts +19 -0
- package/dist/src/bitgo/proofs/WalletProofs.d.ts.map +1 -0
- package/dist/src/bitgo/proofs/WalletProofs.js +37 -0
- package/dist/src/bitgo/proofs/index.d.ts +2 -0
- package/dist/src/bitgo/proofs/index.d.ts.map +1 -0
- package/dist/src/bitgo/proofs/index.js +6 -0
- package/dist/src/bitgo/proofs/types.d.ts +80 -0
- package/dist/src/bitgo/proofs/types.d.ts.map +1 -0
- package/dist/src/bitgo/proofs/types.js +80 -0
- package/dist/src/bitgo/recovery/index.js +6 -2
- package/dist/src/bitgo/recovery/initiate.d.ts +13 -3
- package/dist/src/bitgo/recovery/initiate.d.ts.map +1 -1
- package/dist/src/bitgo/recovery/initiate.js +49 -41
- package/dist/src/bitgo/safe/iSafe.d.ts +87 -0
- package/dist/src/bitgo/safe/iSafe.d.ts.map +1 -0
- package/dist/src/bitgo/safe/iSafe.js +3 -0
- package/dist/src/bitgo/safe/iSafes.d.ts +94 -0
- package/dist/src/bitgo/safe/iSafes.d.ts.map +1 -0
- package/dist/src/bitgo/safe/iSafes.js +3 -0
- package/dist/src/bitgo/safe/index.d.ts +6 -0
- package/dist/src/bitgo/safe/index.d.ts.map +1 -0
- package/dist/src/bitgo/safe/index.js +22 -0
- package/dist/src/bitgo/safe/safe.d.ts +61 -0
- package/dist/src/bitgo/safe/safe.d.ts.map +1 -0
- package/dist/src/bitgo/safe/safe.js +230 -0
- package/dist/src/bitgo/safe/safeDerivation.d.ts +30 -0
- package/dist/src/bitgo/safe/safeDerivation.d.ts.map +1 -0
- package/dist/src/bitgo/safe/safeDerivation.js +122 -0
- package/dist/src/bitgo/safe/safes.d.ts +107 -0
- package/dist/src/bitgo/safe/safes.d.ts.map +1 -0
- package/dist/src/bitgo/safe/safes.js +306 -0
- package/dist/src/bitgo/staking/goStakingInterfaces.d.ts +136 -0
- package/dist/src/bitgo/staking/goStakingInterfaces.d.ts.map +1 -0
- package/dist/src/bitgo/staking/goStakingInterfaces.js +3 -0
- package/dist/src/bitgo/staking/goStakingWallet.d.ts +62 -0
- package/dist/src/bitgo/staking/goStakingWallet.d.ts.map +1 -0
- package/dist/src/bitgo/staking/goStakingWallet.js +141 -0
- package/dist/src/bitgo/staking/iGoStakingWallet.d.ts +17 -0
- package/dist/src/bitgo/staking/iGoStakingWallet.d.ts.map +1 -0
- package/dist/src/bitgo/staking/iGoStakingWallet.js +3 -0
- package/dist/src/bitgo/staking/iStakingWallet.d.ts +157 -8
- package/dist/src/bitgo/staking/iStakingWallet.d.ts.map +1 -1
- package/dist/src/bitgo/staking/iStakingWallet.js +2 -2
- package/dist/src/bitgo/staking/index.d.ts +3 -0
- package/dist/src/bitgo/staking/index.d.ts.map +1 -1
- package/dist/src/bitgo/staking/index.js +9 -2
- package/dist/src/bitgo/staking/stakingWallet.d.ts +21 -8
- package/dist/src/bitgo/staking/stakingWallet.d.ts.map +1 -1
- package/dist/src/bitgo/staking/stakingWallet.js +140 -7
- package/dist/src/bitgo/trading/iTradingAccount.d.ts +13 -1
- package/dist/src/bitgo/trading/iTradingAccount.d.ts.map +1 -1
- package/dist/src/bitgo/trading/iTradingAccount.js +1 -1
- package/dist/src/bitgo/trading/index.d.ts +1 -0
- package/dist/src/bitgo/trading/index.d.ts.map +1 -1
- package/dist/src/bitgo/trading/index.js +7 -2
- package/dist/src/bitgo/trading/network/decrypt-aes-gcm.d.ts +8 -0
- package/dist/src/bitgo/trading/network/decrypt-aes-gcm.d.ts.map +1 -0
- package/dist/src/bitgo/trading/network/decrypt-aes-gcm.js +31 -0
- package/dist/src/bitgo/trading/network/decrypt-rsa.d.ts +8 -0
- package/dist/src/bitgo/trading/network/decrypt-rsa.d.ts.map +1 -0
- package/dist/src/bitgo/trading/network/decrypt-rsa.js +23 -0
- package/dist/src/bitgo/trading/network/decrypt.d.ts +14 -0
- package/dist/src/bitgo/trading/network/decrypt.d.ts.map +1 -0
- package/dist/src/bitgo/trading/network/decrypt.js +23 -0
- package/dist/src/bitgo/trading/network/encrypt-aes-gcm.d.ts +8 -0
- package/dist/src/bitgo/trading/network/encrypt-aes-gcm.d.ts.map +1 -0
- package/dist/src/bitgo/trading/network/encrypt-aes-gcm.js +25 -0
- package/dist/src/bitgo/trading/network/encrypt-rsa-browser.d.ts +8 -0
- package/dist/src/bitgo/trading/network/encrypt-rsa-browser.d.ts.map +1 -0
- package/dist/src/bitgo/trading/network/encrypt-rsa-browser.js +65 -0
- package/dist/src/bitgo/trading/network/encrypt-rsa.d.ts +8 -0
- package/dist/src/bitgo/trading/network/encrypt-rsa.d.ts.map +1 -0
- package/dist/src/bitgo/trading/network/encrypt-rsa.js +23 -0
- package/dist/src/bitgo/trading/network/encrypt.d.ts +37 -0
- package/dist/src/bitgo/trading/network/encrypt.d.ts.map +1 -0
- package/dist/src/bitgo/trading/network/encrypt.js +58 -0
- package/dist/src/bitgo/trading/network/index.d.ts +2 -0
- package/dist/src/bitgo/trading/network/index.d.ts.map +1 -1
- package/dist/src/bitgo/trading/network/index.js +8 -2
- package/dist/src/bitgo/trading/network/network.d.ts +4 -3
- package/dist/src/bitgo/trading/network/network.d.ts.map +1 -1
- package/dist/src/bitgo/trading/network/network.js +24 -27
- package/dist/src/bitgo/trading/network/types.d.ts +79 -46
- package/dist/src/bitgo/trading/network/types.d.ts.map +1 -1
- package/dist/src/bitgo/trading/network/types.js +1 -1
- package/dist/src/bitgo/trading/network/utils.d.ts +20 -0
- package/dist/src/bitgo/trading/network/utils.d.ts.map +1 -0
- package/dist/src/bitgo/trading/network/utils.js +54 -0
- package/dist/src/bitgo/trading/tradingAccount.d.ts +15 -1
- package/dist/src/bitgo/trading/tradingAccount.d.ts.map +1 -1
- package/dist/src/bitgo/trading/tradingAccount.js +55 -7
- package/dist/src/bitgo/tss/bitgoPubKeys.d.ts +38 -0
- package/dist/src/bitgo/tss/bitgoPubKeys.d.ts.map +1 -0
- package/dist/src/bitgo/tss/bitgoPubKeys.js +72 -0
- package/dist/src/bitgo/tss/common.d.ts +40 -6
- package/dist/src/bitgo/tss/common.d.ts.map +1 -1
- package/dist/src/bitgo/tss/common.js +124 -17
- package/dist/src/bitgo/tss/ecdsa/ecdsa.d.ts +6 -4
- package/dist/src/bitgo/tss/ecdsa/ecdsa.d.ts.map +1 -1
- package/dist/src/bitgo/tss/ecdsa/ecdsa.js +78 -66
- package/dist/src/bitgo/tss/ecdsa/ecdsaMPCv2.d.ts +15 -0
- package/dist/src/bitgo/tss/ecdsa/ecdsaMPCv2.d.ts.map +1 -0
- package/dist/src/bitgo/tss/ecdsa/ecdsaMPCv2.js +167 -0
- package/dist/src/bitgo/tss/ecdsa/index.d.ts +1 -0
- package/dist/src/bitgo/tss/ecdsa/index.d.ts.map +1 -1
- package/dist/src/bitgo/tss/ecdsa/index.js +25 -10
- package/dist/src/bitgo/tss/ecdsa/types.d.ts +27 -27
- package/dist/src/bitgo/tss/ecdsa/types.d.ts.map +1 -1
- package/dist/src/bitgo/tss/ecdsa/types.js +3 -3
- package/dist/src/bitgo/tss/eddsa/eddsa.d.ts +15 -6
- package/dist/src/bitgo/tss/eddsa/eddsa.d.ts.map +1 -1
- package/dist/src/bitgo/tss/eddsa/eddsa.js +47 -40
- package/dist/src/bitgo/tss/eddsa/eddsaMPCv2.d.ts +42 -0
- package/dist/src/bitgo/tss/eddsa/eddsaMPCv2.d.ts.map +1 -0
- package/dist/src/bitgo/tss/eddsa/eddsaMPCv2.js +104 -0
- package/dist/src/bitgo/tss/eddsa/index.js +23 -9
- package/dist/src/bitgo/tss/eddsa/types.d.ts +4 -4
- package/dist/src/bitgo/tss/eddsa/types.d.ts.map +1 -1
- package/dist/src/bitgo/tss/index.d.ts +3 -2
- package/dist/src/bitgo/tss/index.d.ts.map +1 -1
- package/dist/src/bitgo/tss/index.js +26 -10
- package/dist/src/bitgo/tss/types.d.ts +3 -3
- package/dist/src/bitgo/tss/types.d.ts.map +1 -1
- package/dist/src/bitgo/tss/types.js +2 -2
- package/dist/src/bitgo/types.d.ts +3 -3
- package/dist/src/bitgo/types.d.ts.map +1 -1
- package/dist/src/bitgo/utils/abstractUtxoCoinUtil.d.ts +10 -0
- package/dist/src/bitgo/utils/abstractUtxoCoinUtil.d.ts.map +1 -1
- package/dist/src/bitgo/utils/abstractUtxoCoinUtil.js +76 -14
- package/dist/src/bitgo/utils/codecProps.js +24 -11
- package/dist/src/bitgo/utils/codecs.d.ts +11 -0
- package/dist/src/bitgo/utils/codecs.d.ts.map +1 -0
- package/dist/src/bitgo/utils/codecs.js +59 -0
- package/dist/src/bitgo/utils/decode.d.ts.map +1 -1
- package/dist/src/bitgo/utils/decode.js +30 -16
- package/dist/src/bitgo/utils/index.d.ts +4 -2
- package/dist/src/bitgo/utils/index.d.ts.map +1 -1
- package/dist/src/bitgo/utils/index.js +27 -11
- package/dist/src/bitgo/utils/messageTypes.d.ts +40 -0
- package/dist/src/bitgo/utils/messageTypes.d.ts.map +1 -0
- package/dist/src/bitgo/utils/messageTypes.js +17 -0
- package/dist/src/bitgo/utils/mpcUtils.d.ts +4 -4
- package/dist/src/bitgo/utils/mpcUtils.d.ts.map +1 -1
- package/dist/src/bitgo/utils/mpcUtils.js +160 -14
- package/dist/src/bitgo/utils/notEmpty.d.ts +2 -0
- package/dist/src/bitgo/utils/notEmpty.d.ts.map +1 -0
- package/dist/src/bitgo/utils/notEmpty.js +7 -0
- package/dist/src/bitgo/utils/opengpgUtils.d.ts +10 -7
- package/dist/src/bitgo/utils/opengpgUtils.d.ts.map +1 -1
- package/dist/src/bitgo/utils/opengpgUtils.js +75 -62
- package/dist/src/bitgo/utils/postWithCodec.d.ts.map +1 -1
- package/dist/src/bitgo/utils/postWithCodec.js +4 -38
- package/dist/src/bitgo/utils/promise-utils.d.ts +1 -1
- package/dist/src/bitgo/utils/promise-utils.d.ts.map +1 -1
- package/dist/src/bitgo/utils/promise-utils.js +2 -3
- package/dist/src/bitgo/utils/transactionUtils.d.ts +9 -0
- package/dist/src/bitgo/utils/transactionUtils.d.ts.map +1 -0
- package/dist/src/bitgo/utils/transactionUtils.js +29 -0
- package/dist/src/bitgo/utils/triple.d.ts +1 -1
- package/dist/src/bitgo/utils/triple.d.ts.map +1 -1
- package/dist/src/bitgo/utils/triple.js +2 -3
- package/dist/src/bitgo/utils/tss/addressVerification.d.ts +62 -0
- package/dist/src/bitgo/utils/tss/addressVerification.d.ts.map +1 -0
- package/dist/src/bitgo/utils/tss/addressVerification.js +93 -0
- package/dist/src/bitgo/utils/tss/baseTSSUtils.d.ts +90 -17
- package/dist/src/bitgo/utils/tss/baseTSSUtils.d.ts.map +1 -1
- package/dist/src/bitgo/utils/tss/baseTSSUtils.js +280 -45
- package/dist/src/bitgo/utils/tss/baseTypes.d.ts +420 -55
- package/dist/src/bitgo/utils/tss/baseTypes.d.ts.map +1 -1
- package/dist/src/bitgo/utils/tss/baseTypes.js +47 -22
- package/dist/src/bitgo/utils/tss/ecdsa/SMC/utils.d.ts +23 -0
- package/dist/src/bitgo/utils/tss/ecdsa/SMC/utils.d.ts.map +1 -0
- package/dist/src/bitgo/utils/tss/ecdsa/SMC/utils.js +157 -0
- package/dist/src/bitgo/utils/tss/ecdsa/base.d.ts +28 -0
- package/dist/src/bitgo/utils/tss/ecdsa/base.d.ts.map +1 -0
- package/dist/src/bitgo/utils/tss/ecdsa/base.js +53 -0
- package/dist/src/bitgo/utils/tss/ecdsa/ecdsa.d.ts +25 -51
- package/dist/src/bitgo/utils/tss/ecdsa/ecdsa.d.ts.map +1 -1
- package/dist/src/bitgo/utils/tss/ecdsa/ecdsa.js +173 -246
- package/dist/src/bitgo/utils/tss/ecdsa/ecdsaMPCv2.d.ts +216 -0
- package/dist/src/bitgo/utils/tss/ecdsa/ecdsaMPCv2.d.ts.map +1 -0
- package/dist/src/bitgo/utils/tss/ecdsa/ecdsaMPCv2.js +1057 -0
- package/dist/src/bitgo/utils/tss/ecdsa/ecdsaMPCv2KeyGenSender.d.ts +8 -0
- package/dist/src/bitgo/utils/tss/ecdsa/ecdsaMPCv2KeyGenSender.d.ts.map +1 -0
- package/dist/src/bitgo/utils/tss/ecdsa/ecdsaMPCv2KeyGenSender.js +16 -0
- package/dist/src/bitgo/utils/tss/ecdsa/index.d.ts +4 -0
- package/dist/src/bitgo/utils/tss/ecdsa/index.d.ts.map +1 -1
- package/dist/src/bitgo/utils/tss/ecdsa/index.js +10 -2
- package/dist/src/bitgo/utils/tss/ecdsa/types.d.ts +7 -10
- package/dist/src/bitgo/utils/tss/ecdsa/types.d.ts.map +1 -1
- package/dist/src/bitgo/utils/tss/ecdsa/types.js +1 -1
- package/dist/src/bitgo/utils/tss/ecdsa/typesMPCv2.d.ts +107 -0
- package/dist/src/bitgo/utils/tss/ecdsa/typesMPCv2.d.ts.map +1 -0
- package/dist/src/bitgo/utils/tss/ecdsa/typesMPCv2.js +55 -0
- package/dist/src/bitgo/utils/tss/eddsa/SMC/utils.d.ts +21 -0
- package/dist/src/bitgo/utils/tss/eddsa/SMC/utils.d.ts.map +1 -0
- package/dist/src/bitgo/utils/tss/eddsa/SMC/utils.js +118 -0
- package/dist/src/bitgo/utils/tss/eddsa/base.d.ts +18 -0
- package/dist/src/bitgo/utils/tss/eddsa/base.d.ts.map +1 -0
- package/dist/src/bitgo/utils/tss/eddsa/base.js +64 -0
- package/dist/src/bitgo/utils/tss/eddsa/eddsa.d.ts +38 -11
- package/dist/src/bitgo/utils/tss/eddsa/eddsa.d.ts.map +1 -1
- package/dist/src/bitgo/utils/tss/eddsa/eddsa.js +254 -96
- package/dist/src/bitgo/utils/tss/eddsa/eddsaMPCv2.d.ts +193 -0
- package/dist/src/bitgo/utils/tss/eddsa/eddsaMPCv2.d.ts.map +1 -0
- package/dist/src/bitgo/utils/tss/eddsa/eddsaMPCv2.js +835 -0
- package/dist/src/bitgo/utils/tss/eddsa/eddsaMPCv2KeyGenSender.d.ts +6 -0
- package/dist/src/bitgo/utils/tss/eddsa/eddsaMPCv2KeyGenSender.d.ts.map +1 -0
- package/dist/src/bitgo/utils/tss/eddsa/eddsaMPCv2KeyGenSender.js +16 -0
- package/dist/src/bitgo/utils/tss/eddsa/index.d.ts +4 -0
- package/dist/src/bitgo/utils/tss/eddsa/index.d.ts.map +1 -1
- package/dist/src/bitgo/utils/tss/eddsa/index.js +29 -8
- package/dist/src/bitgo/utils/tss/eddsa/types.d.ts +12 -7
- package/dist/src/bitgo/utils/tss/eddsa/types.d.ts.map +1 -1
- package/dist/src/bitgo/utils/tss/eddsa/types.js +1 -1
- package/dist/src/bitgo/utils/tss/eddsa/typesEddsaMPCv2.d.ts +40 -0
- package/dist/src/bitgo/utils/tss/eddsa/typesEddsaMPCv2.d.ts.map +1 -0
- package/dist/src/bitgo/utils/tss/eddsa/typesEddsaMPCv2.js +44 -0
- package/dist/src/bitgo/utils/tss/index.d.ts +4 -0
- package/dist/src/bitgo/utils/tss/index.d.ts.map +1 -1
- package/dist/src/bitgo/utils/tss/index.js +27 -9
- package/dist/src/bitgo/utils/tss/preHashedSignable.d.ts +23 -0
- package/dist/src/bitgo/utils/tss/preHashedSignable.d.ts.map +1 -0
- package/dist/src/bitgo/utils/tss/preHashedSignable.js +26 -0
- package/dist/src/bitgo/utils/tss/recipientUtils.d.ts +41 -0
- package/dist/src/bitgo/utils/tss/recipientUtils.d.ts.map +1 -0
- package/dist/src/bitgo/utils/tss/recipientUtils.js +141 -0
- package/dist/src/bitgo/utils/tss/serializedTxHexVerify.d.ts +8 -0
- package/dist/src/bitgo/utils/tss/serializedTxHexVerify.d.ts.map +1 -0
- package/dist/src/bitgo/utils/tss/serializedTxHexVerify.js +13 -0
- package/dist/src/bitgo/utils/tss/signableConsistency.d.ts +12 -0
- package/dist/src/bitgo/utils/tss/signableConsistency.d.ts.map +1 -0
- package/dist/src/bitgo/utils/tss/signableConsistency.js +9 -0
- package/dist/src/bitgo/utils/txRequest.d.ts +10 -0
- package/dist/src/bitgo/utils/txRequest.d.ts.map +1 -0
- package/dist/src/bitgo/utils/txRequest.js +49 -0
- package/dist/src/bitgo/utils/util.js +24 -10
- package/dist/src/bitgo/utils/wallet.d.ts +7 -0
- package/dist/src/bitgo/utils/wallet.d.ts.map +1 -0
- package/dist/src/bitgo/utils/wallet.js +48 -0
- package/dist/src/bitgo/v1Wallets.d.ts +170 -0
- package/dist/src/bitgo/v1Wallets.d.ts.map +1 -0
- package/dist/src/bitgo/v1Wallets.js +3 -0
- package/dist/src/bitgo/wallet/BuildParams.d.ts +80 -1
- package/dist/src/bitgo/wallet/BuildParams.d.ts.map +1 -1
- package/dist/src/bitgo/wallet/BuildParams.js +83 -11
- package/dist/src/bitgo/wallet/iWallet.d.ts +538 -31
- package/dist/src/bitgo/wallet/iWallet.d.ts.map +1 -1
- package/dist/src/bitgo/wallet/iWallet.js +1 -1
- package/dist/src/bitgo/wallet/iWallets.d.ts +308 -16
- package/dist/src/bitgo/wallet/iWallets.d.ts.map +1 -1
- package/dist/src/bitgo/wallet/iWallets.js +83 -3
- package/dist/src/bitgo/wallet/index.d.ts +1 -0
- package/dist/src/bitgo/wallet/index.d.ts.map +1 -1
- package/dist/src/bitgo/wallet/index.js +7 -2
- package/dist/src/bitgo/wallet/safeKeychain.d.ts +52 -0
- package/dist/src/bitgo/wallet/safeKeychain.d.ts.map +1 -0
- package/dist/src/bitgo/wallet/safeKeychain.js +97 -0
- package/dist/src/bitgo/wallet/wallet.d.ts +356 -28
- package/dist/src/bitgo/wallet/wallet.d.ts.map +1 -1
- package/dist/src/bitgo/wallet/wallet.js +2158 -386
- package/dist/src/bitgo/wallet/wallets.d.ts +93 -4
- package/dist/src/bitgo/wallet/wallets.d.ts.map +1 -1
- package/dist/src/bitgo/wallet/wallets.js +1163 -155
- package/dist/src/bitgo/walletUtil/iMessageProvider.d.ts +12 -0
- package/dist/src/bitgo/walletUtil/iMessageProvider.d.ts.map +1 -0
- package/dist/src/bitgo/walletUtil/iMessageProvider.js +3 -0
- package/dist/src/bitgo/walletUtil/index.d.ts +3 -0
- package/dist/src/bitgo/walletUtil/index.d.ts.map +1 -0
- package/dist/src/bitgo/walletUtil/index.js +19 -0
- package/dist/src/bitgo/walletUtil/midnightMessageProvider.d.ts +22 -0
- package/dist/src/bitgo/walletUtil/midnightMessageProvider.d.ts.map +1 -0
- package/dist/src/bitgo/walletUtil/midnightMessageProvider.js +95 -0
- package/dist/src/bitgo/walletUtil/signAccountBasedMidnightClaimMessages.d.ts +9 -0
- package/dist/src/bitgo/walletUtil/signAccountBasedMidnightClaimMessages.d.ts.map +1 -0
- package/dist/src/bitgo/walletUtil/signAccountBasedMidnightClaimMessages.js +72 -0
- package/dist/src/bitgo/walletUtil/utxoMessageProof.d.ts +15 -0
- package/dist/src/bitgo/walletUtil/utxoMessageProof.d.ts.map +1 -0
- package/dist/src/bitgo/walletUtil/utxoMessageProof.js +40 -0
- package/dist/src/bitgo/webhook/index.js +6 -2
- package/dist/src/bitgo/webhook/webhooks.js +23 -9
- package/dist/src/coins/fiat.d.ts +45 -0
- package/dist/src/coins/fiat.d.ts.map +1 -0
- package/dist/src/coins/fiat.js +94 -0
- package/dist/src/coins/index.d.ts +1 -6
- package/dist/src/coins/index.d.ts.map +1 -1
- package/dist/src/coins/index.js +7 -8
- package/dist/src/coins/ofc.d.ts +21 -2
- package/dist/src/coins/ofc.d.ts.map +1 -1
- package/dist/src/coins/ofc.js +29 -3
- package/dist/src/coins/ofcToken.d.ts +15 -4
- package/dist/src/coins/ofcToken.d.ts.map +1 -1
- package/dist/src/coins/ofcToken.js +43 -5
- package/dist/src/coins/susd.d.ts +3 -2
- package/dist/src/coins/susd.d.ts.map +1 -1
- package/dist/src/coins/susd.js +5 -1
- package/dist/src/common.js +27 -13
- package/dist/src/index.d.ts +9 -1
- package/dist/src/index.d.ts.map +1 -1
- package/dist/src/index.js +39 -11
- package/dist/src/lightning.d.ts +20 -0
- package/dist/src/lightning.d.ts.map +1 -0
- package/dist/src/lightning.js +13 -0
- package/dist/src/units.js +5 -6
- package/dist/test/unit/account-lib/baseCoin/messages/baseMessage.d.ts +2 -0
- package/dist/test/unit/account-lib/baseCoin/messages/baseMessage.d.ts.map +1 -0
- package/dist/test/unit/account-lib/baseCoin/messages/baseMessage.js +207 -0
- package/dist/test/unit/account-lib/baseCoin/messages/baseMessageBuilder.d.ts +2 -0
- package/dist/test/unit/account-lib/baseCoin/messages/baseMessageBuilder.d.ts.map +1 -0
- package/dist/test/unit/account-lib/baseCoin/messages/baseMessageBuilder.js +174 -0
- package/dist/test/unit/account-lib/baseCoin/messages/baseMessageBuilderFactory.d.ts +2 -0
- package/dist/test/unit/account-lib/baseCoin/messages/baseMessageBuilderFactory.d.ts.map +1 -0
- package/dist/test/unit/account-lib/baseCoin/messages/baseMessageBuilderFactory.js +108 -0
- package/dist/test/unit/account-lib/baseCoin/messages/fixtures.d.ts +46 -0
- package/dist/test/unit/account-lib/baseCoin/messages/fixtures.d.ts.map +1 -0
- package/dist/test/unit/account-lib/baseCoin/messages/fixtures.js +69 -0
- package/dist/test/unit/account-lib/mpc/tss/ecdsa/ecdsa.js +91 -29
- package/dist/test/unit/account-lib/mpc/util.d.ts +2 -0
- package/dist/test/unit/account-lib/mpc/util.d.ts.map +1 -0
- package/dist/test/unit/account-lib/mpc/util.js +53 -0
- package/dist/test/unit/bitgo/address-book/address-book.d.ts +2 -0
- package/dist/test/unit/bitgo/address-book/address-book.d.ts.map +1 -0
- package/dist/test/unit/bitgo/address-book/address-book.js +159 -0
- package/dist/test/unit/bitgo/defi/defiVault.d.ts +2 -0
- package/dist/test/unit/bitgo/defi/defiVault.d.ts.map +1 -0
- package/dist/test/unit/bitgo/defi/defiVault.js +600 -0
- package/dist/test/unit/bitgo/environment.d.ts +2 -0
- package/dist/test/unit/bitgo/environment.d.ts.map +1 -0
- package/dist/test/unit/bitgo/environment.js +38 -0
- package/dist/test/unit/bitgo/errors.d.ts +2 -0
- package/dist/test/unit/bitgo/errors.d.ts.map +1 -0
- package/dist/test/unit/bitgo/errors.js +262 -0
- package/dist/test/unit/bitgo/recovery/initiate.d.ts +2 -0
- package/dist/test/unit/bitgo/recovery/initiate.d.ts.map +1 -0
- package/dist/test/unit/bitgo/recovery/initiate.js +159 -0
- package/dist/test/unit/bitgo/safe/safe.d.ts +2 -0
- package/dist/test/unit/bitgo/safe/safe.d.ts.map +1 -0
- package/dist/test/unit/bitgo/safe/safe.js +277 -0
- package/dist/test/unit/bitgo/safe/safes.d.ts +2 -0
- package/dist/test/unit/bitgo/safe/safes.d.ts.map +1 -0
- package/dist/test/unit/bitgo/safe/safes.js +338 -0
- package/dist/test/unit/bitgo/trading/network/encrypt.d.ts +2 -0
- package/dist/test/unit/bitgo/trading/network/encrypt.d.ts.map +1 -0
- package/dist/test/unit/bitgo/trading/network/encrypt.js +71 -0
- package/dist/test/unit/bitgo/trading/network/network.test.d.ts +2 -0
- package/dist/test/unit/bitgo/trading/network/network.test.d.ts.map +1 -0
- package/dist/test/unit/bitgo/trading/network/network.test.js +136 -0
- package/dist/test/unit/bitgo/trading/tradingAccount.d.ts +2 -0
- package/dist/test/unit/bitgo/trading/tradingAccount.d.ts.map +1 -0
- package/dist/test/unit/bitgo/trading/tradingAccount.js +192 -0
- package/dist/test/unit/bitgo/utils/abstractUtxoCoinUtil.js +45 -4
- package/dist/test/unit/bitgo/utils/messageTypes.d.ts +2 -0
- package/dist/test/unit/bitgo/utils/messageTypes.d.ts.map +1 -0
- package/dist/test/unit/bitgo/utils/messageTypes.js +64 -0
- package/dist/test/unit/bitgo/utils/notEmpty.d.ts +2 -0
- package/dist/test/unit/bitgo/utils/notEmpty.d.ts.map +1 -0
- package/dist/test/unit/bitgo/utils/notEmpty.js +15 -0
- package/dist/test/unit/bitgo/utils/postWithCodec.js +32 -38
- package/dist/test/unit/bitgo/utils/tss/addressVerification.d.ts +2 -0
- package/dist/test/unit/bitgo/utils/tss/addressVerification.d.ts.map +1 -0
- package/dist/test/unit/bitgo/utils/tss/addressVerification.js +251 -0
- package/dist/test/unit/bitgo/utils/tss/baseTSSUtils.d.ts +2 -0
- package/dist/test/unit/bitgo/utils/tss/baseTSSUtils.d.ts.map +1 -0
- package/dist/test/unit/bitgo/utils/tss/baseTSSUtils.js +348 -0
- package/dist/test/unit/bitgo/utils/tss/ecdsa/ecdsaEncryptionVersion.d.ts +2 -0
- package/dist/test/unit/bitgo/utils/tss/ecdsa/ecdsaEncryptionVersion.d.ts.map +1 -0
- package/dist/test/unit/bitgo/utils/tss/ecdsa/ecdsaEncryptionVersion.js +94 -0
- package/dist/test/unit/bitgo/utils/tss/ecdsa/ecdsaMPCv2.d.ts +2 -0
- package/dist/test/unit/bitgo/utils/tss/ecdsa/ecdsaMPCv2.d.ts.map +1 -0
- package/dist/test/unit/bitgo/utils/tss/ecdsa/ecdsaMPCv2.js +999 -0
- package/dist/test/unit/bitgo/utils/tss/ecdsa/gpgKeys.d.ts +5 -0
- package/dist/test/unit/bitgo/utils/tss/ecdsa/gpgKeys.d.ts.map +1 -0
- package/dist/test/unit/bitgo/utils/tss/ecdsa/gpgKeys.js +36 -0
- package/dist/test/unit/bitgo/utils/tss/eddsa/eddsaExternalSigner.d.ts +2 -0
- package/dist/test/unit/bitgo/utils/tss/eddsa/eddsaExternalSigner.d.ts.map +1 -0
- package/dist/test/unit/bitgo/utils/tss/eddsa/eddsaExternalSigner.js +158 -0
- package/dist/test/unit/bitgo/utils/tss/eddsa/eddsaMPCv2.d.ts +2 -0
- package/dist/test/unit/bitgo/utils/tss/eddsa/eddsaMPCv2.d.ts.map +1 -0
- package/dist/test/unit/bitgo/utils/tss/eddsa/eddsaMPCv2.js +1881 -0
- package/dist/test/unit/bitgo/utils/tss/eddsa/smcUtil.d.ts +2 -0
- package/dist/test/unit/bitgo/utils/tss/eddsa/smcUtil.d.ts.map +1 -0
- package/dist/test/unit/bitgo/utils/tss/eddsa/smcUtil.js +311 -0
- package/dist/test/unit/bitgo/utils/tss/preHashedSignable.d.ts +2 -0
- package/dist/test/unit/bitgo/utils/tss/preHashedSignable.d.ts.map +1 -0
- package/dist/test/unit/bitgo/utils/tss/preHashedSignable.js +55 -0
- package/dist/test/unit/bitgo/utils/tss/recipientUtils.d.ts +2 -0
- package/dist/test/unit/bitgo/utils/tss/recipientUtils.d.ts.map +1 -0
- package/dist/test/unit/bitgo/utils/tss/recipientUtils.js +361 -0
- package/dist/test/unit/bitgo/utils/txRequest.d.ts +2 -0
- package/dist/test/unit/bitgo/utils/txRequest.d.ts.map +1 -0
- package/dist/test/unit/bitgo/utils/txRequest.js +179 -0
- package/dist/test/unit/bitgo/utils/wallet.d.ts +2 -0
- package/dist/test/unit/bitgo/utils/wallet.d.ts.map +1 -0
- package/dist/test/unit/bitgo/utils/wallet.js +55 -0
- package/dist/test/unit/bitgo/wallet/BuildParams.d.ts +2 -0
- package/dist/test/unit/bitgo/wallet/BuildParams.d.ts.map +1 -0
- package/dist/test/unit/bitgo/wallet/BuildParams.js +129 -0
- package/dist/test/unit/bitgo/wallet/SendTransactionRequest.js +79 -9
- package/dist/test/unit/bitgo/wallet/getAccountResources.d.ts +2 -0
- package/dist/test/unit/bitgo/wallet/getAccountResources.d.ts.map +1 -0
- package/dist/test/unit/bitgo/wallet/getAccountResources.js +133 -0
- package/dist/test/unit/bitgo/wallet/getResourceDelegations.d.ts +2 -0
- package/dist/test/unit/bitgo/wallet/getResourceDelegations.d.ts.map +1 -0
- package/dist/test/unit/bitgo/wallet/getResourceDelegations.js +118 -0
- package/dist/test/unit/bitgo/wallet/ofcWalletAddressCreation.d.ts +2 -0
- package/dist/test/unit/bitgo/wallet/ofcWalletAddressCreation.d.ts.map +1 -0
- package/dist/test/unit/bitgo/wallet/ofcWalletAddressCreation.js +141 -0
- package/dist/test/unit/bitgo/wallet/ofcWalletSignTransaction.d.ts +2 -0
- package/dist/test/unit/bitgo/wallet/ofcWalletSignTransaction.d.ts.map +1 -0
- package/dist/test/unit/bitgo/wallet/ofcWalletSignTransaction.js +185 -0
- package/dist/test/unit/bitgo/wallet/prebuildTransactionTypes.d.ts +2 -0
- package/dist/test/unit/bitgo/wallet/prebuildTransactionTypes.d.ts.map +1 -0
- package/dist/test/unit/bitgo/wallet/prebuildTransactionTypes.js +20 -0
- package/dist/test/unit/bitgo/wallet/resourceManagement.d.ts +3 -0
- package/dist/test/unit/bitgo/wallet/resourceManagement.d.ts.map +1 -0
- package/dist/test/unit/bitgo/wallet/resourceManagement.js +441 -0
- package/dist/test/unit/bitgo/wallet/safeGetUserPrv.d.ts +5 -0
- package/dist/test/unit/bitgo/wallet/safeGetUserPrv.d.ts.map +1 -0
- package/dist/test/unit/bitgo/wallet/safeGetUserPrv.js +671 -0
- package/dist/test/unit/bitgo/wallet/tokenApproval.d.ts +2 -0
- package/dist/test/unit/bitgo/wallet/tokenApproval.d.ts.map +1 -0
- package/dist/test/unit/bitgo/wallet/tokenApproval.js +201 -0
- package/dist/test/unit/bitgo/wallet/walletEvmAddressCreation.d.ts +2 -0
- package/dist/test/unit/bitgo/wallet/walletEvmAddressCreation.d.ts.map +1 -0
- package/dist/test/unit/bitgo/wallet/walletEvmAddressCreation.js +181 -0
- package/dist/test/unit/bitgo/wallet/walletOptionsCodecs.d.ts +2 -0
- package/dist/test/unit/bitgo/wallet/walletOptionsCodecs.d.ts.map +1 -0
- package/dist/test/unit/bitgo/wallet/walletOptionsCodecs.js +66 -0
- package/dist/test/unit/bitgo/wallet/walletTssAddressVerification.d.ts +2 -0
- package/dist/test/unit/bitgo/wallet/walletTssAddressVerification.d.ts.map +1 -0
- package/dist/test/unit/bitgo/wallet/walletTssAddressVerification.js +320 -0
- package/dist/test/unit/bitgo/wallet/walletsEncryptionVersion.d.ts +2 -0
- package/dist/test/unit/bitgo/wallet/walletsEncryptionVersion.d.ts.map +1 -0
- package/dist/test/unit/bitgo/wallet/walletsEncryptionVersion.js +273 -0
- package/dist/test/unit/bitgo/wallet/walletsEvmKeyring.d.ts +2 -0
- package/dist/test/unit/bitgo/wallet/walletsEvmKeyring.d.ts.map +1 -0
- package/dist/test/unit/bitgo/wallet/walletsEvmKeyring.js +216 -0
- package/dist/test/unit/bitgo/wallet/walletsExternalSigner.d.ts +2 -0
- package/dist/test/unit/bitgo/wallet/walletsExternalSigner.d.ts.map +1 -0
- package/dist/test/unit/bitgo/wallet/walletsExternalSigner.js +670 -0
- package/dist/test/unit/bitgo/wallet/walletsGoAccount.d.ts +2 -0
- package/dist/test/unit/bitgo/wallet/walletsGoAccount.d.ts.map +1 -0
- package/dist/test/unit/bitgo/wallet/walletsGoAccount.js +150 -0
- package/dist/test/unit/bitgo/wallet/walletsWebauthn.d.ts +2 -0
- package/dist/test/unit/bitgo/wallet/walletsWebauthn.d.ts.map +1 -0
- package/dist/test/unit/bitgo/wallet/walletsWebauthn.js +201 -0
- package/dist/test/unit/coins/ofc.d.ts +2 -0
- package/dist/test/unit/coins/ofc.d.ts.map +1 -0
- package/dist/test/unit/coins/ofc.js +124 -0
- package/dist/test/unit/lightning.d.ts +2 -0
- package/dist/test/unit/lightning.d.ts.map +1 -0
- package/dist/test/unit/lightning.js +23 -0
- package/dist/test/unit/units.d.ts.map +1 -1
- package/dist/test/unit/units.js +64 -64
- package/dist/tsconfig.tsbuildinfo +1 -1
- package/package.json +23 -21
- package/.eslintignore +0 -5
- package/CHANGELOG.md +0 -1712
- package/dist/src/account-lib/baseCoin/blsKeyPair.d.ts +0 -77
- package/dist/src/account-lib/baseCoin/blsKeyPair.d.ts.map +0 -1
- package/dist/src/account-lib/baseCoin/blsKeyPair.js +0 -209
- package/dist/src/bitgo/lightning/iLightning.d.ts +0 -186
- package/dist/src/bitgo/lightning/iLightning.d.ts.map +0 -1
- package/dist/src/bitgo/lightning/iLightning.js +0 -106
- package/dist/src/bitgo/lightning/index.d.ts +0 -5
- package/dist/src/bitgo/lightning/index.d.ts.map +0 -1
- package/dist/src/bitgo/lightning/index.js +0 -17
- package/dist/src/bitgo/lightning/lightning.d.ts +0 -25
- package/dist/src/bitgo/lightning/lightning.d.ts.map +0 -1
- package/dist/src/bitgo/lightning/lightning.js +0 -111
- package/dist/src/bitgo/lightning/lightningUtils.d.ts +0 -46
- package/dist/src/bitgo/lightning/lightningUtils.d.ts.map +0 -1
- package/dist/src/bitgo/lightning/lightningUtils.js +0 -133
- package/dist/src/bitgo/lightning/lnurlCodec.d.ts +0 -3
- package/dist/src/bitgo/lightning/lnurlCodec.d.ts.map +0 -1
- package/dist/src/bitgo/lightning/lnurlCodec.js +0 -28
- package/dist/src/bitgo/utils/blsUtils.d.ts +0 -52
- package/dist/src/bitgo/utils/blsUtils.d.ts.map +0 -1
- package/dist/src/bitgo/utils/blsUtils.js +0 -237
- package/dist/src/bitgo/utils/iBlsUtils.d.ts +0 -14
- package/dist/src/bitgo/utils/iBlsUtils.d.ts.map +0 -1
- package/dist/src/bitgo/utils/iBlsUtils.js +0 -3
- package/dist/src/coins/fiateur.d.ts +0 -31
- package/dist/src/coins/fiateur.d.ts.map +0 -1
- package/dist/src/coins/fiateur.js +0 -57
- package/dist/src/coins/fiatgbp.d.ts +0 -31
- package/dist/src/coins/fiatgbp.d.ts.map +0 -1
- package/dist/src/coins/fiatgbp.js +0 -57
- package/dist/src/coins/fiatusd.d.ts +0 -31
- package/dist/src/coins/fiatusd.d.ts.map +0 -1
- package/dist/src/coins/fiatusd.js +0 -57
- package/dist/src/coins/tfiateur.d.ts +0 -11
- package/dist/src/coins/tfiateur.d.ts.map +0 -1
- package/dist/src/coins/tfiateur.js +0 -17
- package/dist/src/coins/tfiatgbp.d.ts +0 -11
- package/dist/src/coins/tfiatgbp.d.ts.map +0 -1
- package/dist/src/coins/tfiatgbp.js +0 -17
- package/dist/src/coins/tfiatusd.d.ts +0 -11
- package/dist/src/coins/tfiatusd.d.ts.map +0 -1
- package/dist/src/coins/tfiatusd.js +0 -17
- package/dist/src/openssl/index.d.ts +0 -5
- package/dist/src/openssl/index.d.ts.map +0 -1
- package/dist/src/openssl/index.js +0 -9
- package/dist/test/unit/openssl.d.ts +0 -2
- package/dist/test/unit/openssl.d.ts.map +0 -1
- package/dist/test/unit/openssl.js +0 -39
|
@@ -0,0 +1,835 @@
|
|
|
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
|
+
exports.EddsaMPCv2RecoveryFunctions = exports.EddsaMPCv2Utils = void 0;
|
|
40
|
+
exports.isEddsaMpcV1SigningMaterial = isEddsaMpcV1SigningMaterial;
|
|
41
|
+
exports.getEddsaMpcV2RecoveryKeySharesFromReducedKey = getEddsaMpcV2RecoveryKeySharesFromReducedKey;
|
|
42
|
+
exports.signRecoveryEddsaMPCv2 = signRecoveryEddsaMPCv2;
|
|
43
|
+
exports.getEddsaSigningMaterial = getEddsaSigningMaterial;
|
|
44
|
+
exports.signEddsaMpcV2RecoveryTx = signEddsaMpcV2RecoveryTx;
|
|
45
|
+
const assert_1 = __importDefault(require("assert"));
|
|
46
|
+
const sjcl = __importStar(require("@bitgo-beta/sjcl"));
|
|
47
|
+
const pgp = __importStar(require("openpgp"));
|
|
48
|
+
const io_ts_types_1 = require("io-ts-types");
|
|
49
|
+
const public_types_1 = require("@bitgo/public-types");
|
|
50
|
+
const ed25519_1 = require("@noble/curves/ed25519");
|
|
51
|
+
const sdk_lib_mpc_1 = require("@bitgo-beta/sdk-lib-mpc");
|
|
52
|
+
const bitgoPubKeys_1 = require("../../../tss/bitgoPubKeys");
|
|
53
|
+
const common_1 = require("../../../tss/common");
|
|
54
|
+
const codecs_1 = require("../../codecs");
|
|
55
|
+
const eddsaMPCv2_1 = require("../../../tss/eddsa/eddsaMPCv2");
|
|
56
|
+
const eddsa_1 = require("../../../tss/eddsa/eddsa");
|
|
57
|
+
const opengpgUtils_1 = require("../../opengpgUtils");
|
|
58
|
+
const typesMPCv2_1 = require("../ecdsa/typesMPCv2");
|
|
59
|
+
const baseTypes_1 = require("../baseTypes");
|
|
60
|
+
const base_1 = require("./base");
|
|
61
|
+
const recipientUtils_1 = require("../recipientUtils");
|
|
62
|
+
const eddsaMPCv2KeyGenSender_1 = require("./eddsaMPCv2KeyGenSender");
|
|
63
|
+
class EddsaMPCv2Utils extends base_1.BaseEddsaUtils {
|
|
64
|
+
/** @inheritdoc */
|
|
65
|
+
async createKeychains(params) {
|
|
66
|
+
const userKeyPair = await (0, opengpgUtils_1.generateGPGKeyPair)('ed25519');
|
|
67
|
+
const userGpgKey = await pgp.readPrivateKey({ armoredKey: userKeyPair.privateKey });
|
|
68
|
+
const userGpgPublicKey = userKeyPair.publicKey;
|
|
69
|
+
const [userPk, userSk] = await sdk_lib_mpc_1.MPSComms.extractEd25519KeyPair(userGpgKey);
|
|
70
|
+
const backupKeyPair = await (0, opengpgUtils_1.generateGPGKeyPair)('ed25519');
|
|
71
|
+
const backupGpgKey = await pgp.readPrivateKey({ armoredKey: backupKeyPair.privateKey });
|
|
72
|
+
const backupGpgPublicKey = backupKeyPair.publicKey;
|
|
73
|
+
const [backupPk, backupSk] = await sdk_lib_mpc_1.MPSComms.extractEd25519KeyPair(backupGpgKey);
|
|
74
|
+
// Get the BitGo EdDSA MPCv2 public key (ed25519). Using the default mpcv2PublicKey (secp256k1)
|
|
75
|
+
// here would cause a WASM "Invalid Input" error, so we require the dedicated eddsaMpcv2PublicKey.
|
|
76
|
+
const { eddsaMpcv2PublicKey } = await this.getBitgoGpgPubkeyBasedOnFeatureFlags(params.enterprise, true);
|
|
77
|
+
const bitgoPublicGpgKey = eddsaMpcv2PublicKey ?? this.bitgoEddsaMpcv2PublicGpgKey;
|
|
78
|
+
(0, assert_1.default)(bitgoPublicGpgKey, 'Failed to get BitGo EdDSA MPCv2 GPG public key');
|
|
79
|
+
const bitgoPublicGpgKeyArmored = bitgoPublicGpgKey.armor();
|
|
80
|
+
if ((0, bitgoPubKeys_1.envRequiresBitgoPubGpgKeyConfig)(this.bitgo.getEnv())) {
|
|
81
|
+
(0, assert_1.default)((0, bitgoPubKeys_1.isBitgoEddsaMpcv2PubKey)(bitgoPublicGpgKeyArmored), 'Invalid BitGo GPG public key');
|
|
82
|
+
}
|
|
83
|
+
const bitgoKeyObj = await pgp.readKey({ armoredKey: bitgoPublicGpgKeyArmored });
|
|
84
|
+
const bitgoPk = await sdk_lib_mpc_1.MPSComms.extractEd25519PublicKey(bitgoKeyObj);
|
|
85
|
+
// Create DKG sessions for user (party 0) and backup (party 1)
|
|
86
|
+
const { userDkg, backupDkg } = await this.getUserAndBackupSession(params.retrofit);
|
|
87
|
+
// #region round 1
|
|
88
|
+
await userDkg.initDkg(userSk, [backupPk, bitgoPk]);
|
|
89
|
+
await backupDkg.initDkg(backupSk, [userPk, bitgoPk]);
|
|
90
|
+
const userMsg1 = userDkg.getFirstMessage();
|
|
91
|
+
const backupMsg1 = backupDkg.getFirstMessage();
|
|
92
|
+
const userSignedMsg1 = await sdk_lib_mpc_1.MPSComms.detachSignMpsMessage(Buffer.from(userMsg1.payload), userGpgKey);
|
|
93
|
+
const backupSignedMsg1 = await sdk_lib_mpc_1.MPSComms.detachSignMpsMessage(Buffer.from(backupMsg1.payload), backupGpgKey);
|
|
94
|
+
(0, assert_1.default)(io_ts_types_1.NonEmptyString.is(userGpgPublicKey), 'User GPG public key is required');
|
|
95
|
+
(0, assert_1.default)(io_ts_types_1.NonEmptyString.is(backupGpgPublicKey), 'Backup GPG public key is required');
|
|
96
|
+
const { sessionId, bitgoMsg1 } = await this.sendKeyGenerationRound1(params.enterprise, {
|
|
97
|
+
userGpgPublicKey,
|
|
98
|
+
backupGpgPublicKey,
|
|
99
|
+
userMsg1: userSignedMsg1,
|
|
100
|
+
backupMsg1: backupSignedMsg1,
|
|
101
|
+
...(params.retrofit?.walletId ? { walletId: params.retrofit.walletId } : {}),
|
|
102
|
+
}, params.safeId);
|
|
103
|
+
// #endregion
|
|
104
|
+
// #region round 2
|
|
105
|
+
const bitgoRawMsg1Bytes = await sdk_lib_mpc_1.MPSComms.verifyMpsMessage(bitgoMsg1, bitgoKeyObj);
|
|
106
|
+
const bitgoDeserializedMsg1 = {
|
|
107
|
+
from: typesMPCv2_1.MPCv2PartiesEnum.BITGO,
|
|
108
|
+
payload: new Uint8Array(bitgoRawMsg1Bytes),
|
|
109
|
+
};
|
|
110
|
+
const round1Messages = [userMsg1, backupMsg1, bitgoDeserializedMsg1];
|
|
111
|
+
const userRound2Msgs = userDkg.handleIncomingMessages(round1Messages);
|
|
112
|
+
const backupRound2Msgs = backupDkg.handleIncomingMessages(round1Messages);
|
|
113
|
+
(0, assert_1.default)(userRound2Msgs.length === 1, 'User round 1 should produce exactly one round 2 message');
|
|
114
|
+
(0, assert_1.default)(backupRound2Msgs.length === 1, 'Backup round 1 should produce exactly one round 2 message');
|
|
115
|
+
const userMsg2 = userRound2Msgs[0];
|
|
116
|
+
const backupMsg2 = backupRound2Msgs[0];
|
|
117
|
+
const userSignedMsg2 = await sdk_lib_mpc_1.MPSComms.detachSignMpsMessage(Buffer.from(userMsg2.payload), userGpgKey);
|
|
118
|
+
const backupSignedMsg2 = await sdk_lib_mpc_1.MPSComms.detachSignMpsMessage(Buffer.from(backupMsg2.payload), backupGpgKey);
|
|
119
|
+
const { sessionId: sessionIdRound2, commonPublicKeychain, bitgoMsg2, } = await this.sendKeyGenerationRound2(params.enterprise, {
|
|
120
|
+
sessionId,
|
|
121
|
+
userMsg2: userSignedMsg2,
|
|
122
|
+
backupMsg2: backupSignedMsg2,
|
|
123
|
+
});
|
|
124
|
+
// #endregion
|
|
125
|
+
// #region keychain creation
|
|
126
|
+
assert_1.default.equal(sessionId, sessionIdRound2, 'Round 1 and round 2 session IDs do not match');
|
|
127
|
+
const bitgoRawMsg2Bytes = await sdk_lib_mpc_1.MPSComms.verifyMpsMessage(bitgoMsg2, bitgoKeyObj);
|
|
128
|
+
const bitgoDeserializedMsg2 = {
|
|
129
|
+
from: typesMPCv2_1.MPCv2PartiesEnum.BITGO,
|
|
130
|
+
payload: new Uint8Array(bitgoRawMsg2Bytes),
|
|
131
|
+
};
|
|
132
|
+
const round2Messages = [userMsg2, backupMsg2, bitgoDeserializedMsg2];
|
|
133
|
+
const userFinalMsgs = userDkg.handleIncomingMessages(round2Messages);
|
|
134
|
+
const backupFinalMsgs = backupDkg.handleIncomingMessages(round2Messages);
|
|
135
|
+
(0, assert_1.default)(userFinalMsgs.length === 0, 'WASM round 2 should produce no output messages for user');
|
|
136
|
+
(0, assert_1.default)(backupFinalMsgs.length === 0, 'WASM round 2 should produce no output messages for backup');
|
|
137
|
+
const userCommonKeychain = userDkg.getCommonKeychain();
|
|
138
|
+
const backupCommonKeychain = backupDkg.getCommonKeychain();
|
|
139
|
+
assert_1.default.equal(userCommonKeychain, commonPublicKeychain, 'User computed keychain does not match BitGo common keychain');
|
|
140
|
+
assert_1.default.equal(backupCommonKeychain, commonPublicKeychain, 'Backup computed keychain does not match BitGo common keychain');
|
|
141
|
+
const userPrivateMaterial = userDkg.getKeyShare();
|
|
142
|
+
const backupPrivateMaterial = backupDkg.getKeyShare();
|
|
143
|
+
const userReducedPrivateMaterial = userDkg.getReducedKeyShare();
|
|
144
|
+
const backupReducedPrivateMaterial = backupDkg.getReducedKeyShare();
|
|
145
|
+
const userKeychainPromise = this.addUserKeychain(userCommonKeychain, userPrivateMaterial, userReducedPrivateMaterial, params.passphrase, params.originalPasscodeEncryptionCode, params.webauthnInfo, params.encryptionVersion, params.enterprise, params.safeId);
|
|
146
|
+
const backupKeychainPromise = this.addBackupKeychain(backupCommonKeychain, backupPrivateMaterial, backupReducedPrivateMaterial, params.passphrase, params.originalPasscodeEncryptionCode, params.encryptionVersion, params.safeId);
|
|
147
|
+
const bitgoKeychainPromise = this.addBitgoKeychain(userCommonKeychain, params.safeId);
|
|
148
|
+
const [userKeychain, backupKeychain, bitgoKeychain] = await Promise.all([
|
|
149
|
+
userKeychainPromise,
|
|
150
|
+
backupKeychainPromise,
|
|
151
|
+
bitgoKeychainPromise,
|
|
152
|
+
]);
|
|
153
|
+
// #endregion
|
|
154
|
+
return {
|
|
155
|
+
userKeychain,
|
|
156
|
+
backupKeychain,
|
|
157
|
+
bitgoKeychain,
|
|
158
|
+
};
|
|
159
|
+
}
|
|
160
|
+
async createKeychainsWithExternalSigner(params) {
|
|
161
|
+
const { enterprise, callbacks } = params;
|
|
162
|
+
const { eddsaMpcv2PublicKey } = await this.getBitgoGpgPubkeyBasedOnFeatureFlags(enterprise, true);
|
|
163
|
+
const bitgoPublicGpgKey = eddsaMpcv2PublicKey ?? this.bitgoEddsaMpcv2PublicGpgKey;
|
|
164
|
+
(0, assert_1.default)(bitgoPublicGpgKey, 'Failed to get BitGo EdDSA MPCv2 GPG public key');
|
|
165
|
+
const bitgoPublicGpgKeyArmored = bitgoPublicGpgKey.armor();
|
|
166
|
+
if ((0, bitgoPubKeys_1.envRequiresBitgoPubGpgKeyConfig)(this.bitgo.getEnv())) {
|
|
167
|
+
(0, assert_1.default)((0, bitgoPubKeys_1.isBitgoEddsaMpcv2PubKey)(bitgoPublicGpgKeyArmored), 'Invalid BitGo EdDSA MPCv2 GPG public key');
|
|
168
|
+
}
|
|
169
|
+
// Round 0: both parties generate GPG keys
|
|
170
|
+
const { userGpgPublicKey, backupGpgPublicKey, userState, backupState } = await callbacks.initializeCallback({
|
|
171
|
+
enterprise,
|
|
172
|
+
bitgoPublicGpgKey: bitgoPublicGpgKeyArmored,
|
|
173
|
+
});
|
|
174
|
+
(0, assert_1.default)(io_ts_types_1.NonEmptyString.is(userGpgPublicKey), 'User GPG public key is required');
|
|
175
|
+
(0, assert_1.default)(io_ts_types_1.NonEmptyString.is(backupGpgPublicKey), 'Backup GPG public key is required');
|
|
176
|
+
// Round 1: both parties run DKG round 1
|
|
177
|
+
const { userSignedMsg1, backupSignedMsg1, userState: userStateAfter1, backupState: backupStateAfter1, } = await callbacks.round1Callback({
|
|
178
|
+
bitgoPublicGpgKey: bitgoPublicGpgKeyArmored,
|
|
179
|
+
userGpgPublicKey,
|
|
180
|
+
backupGpgPublicKey,
|
|
181
|
+
userState,
|
|
182
|
+
backupState,
|
|
183
|
+
});
|
|
184
|
+
const { sessionId, bitgoMsg1 } = await this.sendKeyGenerationRound1(enterprise, {
|
|
185
|
+
userGpgPublicKey,
|
|
186
|
+
backupGpgPublicKey,
|
|
187
|
+
userMsg1: userSignedMsg1,
|
|
188
|
+
backupMsg1: backupSignedMsg1,
|
|
189
|
+
});
|
|
190
|
+
// Round 2: both parties run DKG round 2
|
|
191
|
+
const { userSignedMsg2, backupSignedMsg2, userState: userStateAfter2, backupState: backupStateAfter2, } = await callbacks.round2Callback({
|
|
192
|
+
bitgoMsg1,
|
|
193
|
+
userSignedMsg1,
|
|
194
|
+
backupSignedMsg1,
|
|
195
|
+
userState: userStateAfter1,
|
|
196
|
+
backupState: backupStateAfter1,
|
|
197
|
+
});
|
|
198
|
+
const { sessionId: sessionIdRound2, commonPublicKeychain: bitgoCommonKeychain, bitgoMsg2, } = await this.sendKeyGenerationRound2(enterprise, {
|
|
199
|
+
sessionId,
|
|
200
|
+
userMsg2: userSignedMsg2,
|
|
201
|
+
backupMsg2: backupSignedMsg2,
|
|
202
|
+
});
|
|
203
|
+
assert_1.default.strictEqual(sessionId, sessionIdRound2, 'Round 1 and round 2 session IDs do not match');
|
|
204
|
+
// Finalize: both parties verify and derive the common keychain
|
|
205
|
+
const { commonKeychain } = await callbacks.finalizeCallback({
|
|
206
|
+
bitgoMsg2,
|
|
207
|
+
bitgoCommonKeychain,
|
|
208
|
+
userState: userStateAfter2,
|
|
209
|
+
backupState: backupStateAfter2,
|
|
210
|
+
});
|
|
211
|
+
assert_1.default.strictEqual(commonKeychain, bitgoCommonKeychain, 'Common keychains do not match');
|
|
212
|
+
const keychains = this.baseCoin.keychains();
|
|
213
|
+
const [userKeychain, backupKeychain, bitgoKeychain] = await Promise.all([
|
|
214
|
+
keychains.add({ source: 'user', keyType: 'tss', commonKeychain, isMPCv2: true }),
|
|
215
|
+
keychains.add({ source: 'backup', keyType: 'tss', commonKeychain, isMPCv2: true }),
|
|
216
|
+
this.addBitgoKeychain(commonKeychain),
|
|
217
|
+
]);
|
|
218
|
+
return { userKeychain, backupKeychain, bitgoKeychain };
|
|
219
|
+
}
|
|
220
|
+
// #region keychain utils
|
|
221
|
+
async createParticipantKeychain(participantIndex, commonKeychain, privateMaterial, reducedPrivateMaterial, passphrase, originalPasscodeEncryptionCode, webauthnInfo, encryptionVersion, enterprise, safeId) {
|
|
222
|
+
let source;
|
|
223
|
+
let encryptedPrv = undefined;
|
|
224
|
+
let reducedEncryptedPrv = undefined;
|
|
225
|
+
let privateMaterialBase64 = undefined;
|
|
226
|
+
switch (participantIndex) {
|
|
227
|
+
case typesMPCv2_1.MPCv2PartiesEnum.USER:
|
|
228
|
+
case typesMPCv2_1.MPCv2PartiesEnum.BACKUP:
|
|
229
|
+
source = participantIndex === typesMPCv2_1.MPCv2PartiesEnum.USER ? 'user' : 'backup';
|
|
230
|
+
(0, assert_1.default)(privateMaterial, `Private material is required for ${source} keychain`);
|
|
231
|
+
(0, assert_1.default)(reducedPrivateMaterial, `Reduced private material is required for ${source} keychain`);
|
|
232
|
+
(0, assert_1.default)(passphrase, `Passphrase is required for ${source} keychain`);
|
|
233
|
+
privateMaterialBase64 = privateMaterial.toString('base64');
|
|
234
|
+
encryptedPrv = await this.bitgo.encrypt({
|
|
235
|
+
input: privateMaterialBase64,
|
|
236
|
+
password: passphrase,
|
|
237
|
+
encryptionVersion,
|
|
238
|
+
});
|
|
239
|
+
// Encrypts the CBOR-encoded ReducedKeyShare (which contains the party's public
|
|
240
|
+
// key) with the wallet passphrase. The result is stored as reducedEncryptedPrv
|
|
241
|
+
// on the key card QR code and represents a second copy of key material
|
|
242
|
+
// beyond the server-stored encryptedPrv.
|
|
243
|
+
reducedEncryptedPrv = await this.bitgo.encrypt({
|
|
244
|
+
// Buffer.toString('base64') can not be used here as it does not work on the browser.
|
|
245
|
+
// The browser deals with a Buffer as Uint8Array, therefore in the browser .toString('base64') just creates a comma separated string of the array values.
|
|
246
|
+
input: btoa(String.fromCharCode.apply(null, Array.from(new Uint8Array(reducedPrivateMaterial)))),
|
|
247
|
+
password: passphrase,
|
|
248
|
+
encryptionVersion,
|
|
249
|
+
});
|
|
250
|
+
break;
|
|
251
|
+
case typesMPCv2_1.MPCv2PartiesEnum.BITGO:
|
|
252
|
+
source = 'bitgo';
|
|
253
|
+
break;
|
|
254
|
+
default:
|
|
255
|
+
throw new Error('Invalid participant index');
|
|
256
|
+
}
|
|
257
|
+
const keychainParams = {
|
|
258
|
+
source,
|
|
259
|
+
keyType: 'tss',
|
|
260
|
+
commonKeychain,
|
|
261
|
+
encryptedPrv,
|
|
262
|
+
originalPasscodeEncryptionCode,
|
|
263
|
+
isMPCv2: true,
|
|
264
|
+
safeId,
|
|
265
|
+
};
|
|
266
|
+
if (webauthnInfo && participantIndex === typesMPCv2_1.MPCv2PartiesEnum.USER && privateMaterialBase64) {
|
|
267
|
+
// Send the passkey as `webauthnInfo`; the deprecated `webauthnDevices` array is ignored by POST /key.
|
|
268
|
+
(0, assert_1.default)(enterprise, 'enterprise is required to attach a webauthn device to the user keychain');
|
|
269
|
+
keychainParams.webauthnInfo = {
|
|
270
|
+
otpDeviceId: webauthnInfo.otpDeviceId,
|
|
271
|
+
prfSalt: webauthnInfo.prfSalt,
|
|
272
|
+
encryptedPrv: await this.bitgo.encrypt({
|
|
273
|
+
input: privateMaterialBase64,
|
|
274
|
+
password: webauthnInfo.passphrase,
|
|
275
|
+
encryptionVersion,
|
|
276
|
+
}),
|
|
277
|
+
enterpriseId: enterprise,
|
|
278
|
+
};
|
|
279
|
+
}
|
|
280
|
+
const keychains = this.baseCoin.keychains();
|
|
281
|
+
return { ...(await keychains.add(keychainParams)), reducedEncryptedPrv };
|
|
282
|
+
}
|
|
283
|
+
async addUserKeychain(commonKeychain, privateMaterial, reducedPrivateMaterial, passphrase, originalPasscodeEncryptionCode, webauthnInfo, encryptionVersion, enterprise, safeId) {
|
|
284
|
+
return this.createParticipantKeychain(typesMPCv2_1.MPCv2PartiesEnum.USER, commonKeychain, privateMaterial, reducedPrivateMaterial, passphrase, originalPasscodeEncryptionCode, webauthnInfo, encryptionVersion, enterprise, safeId);
|
|
285
|
+
}
|
|
286
|
+
async addBackupKeychain(commonKeychain, privateMaterial, reducedPrivateMaterial, passphrase, originalPasscodeEncryptionCode, encryptionVersion, safeId) {
|
|
287
|
+
return this.createParticipantKeychain(typesMPCv2_1.MPCv2PartiesEnum.BACKUP, commonKeychain, privateMaterial, reducedPrivateMaterial, passphrase, originalPasscodeEncryptionCode, undefined, encryptionVersion, undefined, safeId);
|
|
288
|
+
}
|
|
289
|
+
async addBitgoKeychain(commonKeychain, safeId) {
|
|
290
|
+
return this.createParticipantKeychain(typesMPCv2_1.MPCv2PartiesEnum.BITGO, commonKeychain, undefined, undefined, undefined, undefined, undefined, undefined, undefined, safeId);
|
|
291
|
+
}
|
|
292
|
+
// #endregion
|
|
293
|
+
async sendKeyGenerationRound1(enterprise, payload, safeId) {
|
|
294
|
+
return this.sendKeyGenerationRound1BySender((0, eddsaMPCv2KeyGenSender_1.KeyGenSenderForEnterprise)(this.bitgo, enterprise, safeId), payload);
|
|
295
|
+
}
|
|
296
|
+
async sendKeyGenerationRound1BySender(senderFn, payload) {
|
|
297
|
+
return senderFn(public_types_1.MPCv2KeyGenStateEnum['MPCv2-R1'], payload);
|
|
298
|
+
}
|
|
299
|
+
async sendKeyGenerationRound2(enterprise, payload) {
|
|
300
|
+
return this.sendKeyGenerationRound2BySender((0, eddsaMPCv2KeyGenSender_1.KeyGenSenderForEnterprise)(this.bitgo, enterprise), payload);
|
|
301
|
+
}
|
|
302
|
+
async sendKeyGenerationRound2BySender(senderFn, payload) {
|
|
303
|
+
return senderFn(public_types_1.MPCv2KeyGenStateEnum['MPCv2-R2'], payload);
|
|
304
|
+
}
|
|
305
|
+
// #endregion
|
|
306
|
+
// #region sign tx request
|
|
307
|
+
/**
|
|
308
|
+
* Signs the transaction associated with the transaction request.
|
|
309
|
+
* @param {string | TxRequest} params.txRequest - transaction request object or id
|
|
310
|
+
* @param {string} params.prv - decrypted private key
|
|
311
|
+
* @param {string} params.reqId - request id
|
|
312
|
+
* @returns {Promise<TxRequest>} fully signed TxRequest
|
|
313
|
+
*/
|
|
314
|
+
async signTxRequest(params) {
|
|
315
|
+
this.bitgo.setRequestTracer(params.reqId);
|
|
316
|
+
return this.signRequestBase(params, baseTypes_1.RequestType.tx);
|
|
317
|
+
}
|
|
318
|
+
/**
|
|
319
|
+
* Signs the message associated with the transaction request.
|
|
320
|
+
* @param {string | TxRequest} params.txRequest - transaction request object or id
|
|
321
|
+
* @param {string} params.prv - decrypted private key
|
|
322
|
+
* @param {string} params.reqId - request id
|
|
323
|
+
* @returns {Promise<TxRequest>} fully signed TxRequest
|
|
324
|
+
*/
|
|
325
|
+
async signTxRequestForMessage(params) {
|
|
326
|
+
this.bitgo.setRequestTracer(params.reqId);
|
|
327
|
+
return this.signRequestBase(params, baseTypes_1.RequestType.message);
|
|
328
|
+
}
|
|
329
|
+
/**
|
|
330
|
+
* Full 3-round EdDSA MPCv2 (MPS) online signing orchestration.
|
|
331
|
+
*
|
|
332
|
+
* Protocol overview:
|
|
333
|
+
* WASM Round 0 → getFirstMessage() (produces userMsg1)
|
|
334
|
+
* API Round 1 → send userMsg1 / recv bitgoMsg1
|
|
335
|
+
* WASM Round 1 → handleIncomingMessages([userMsg1, bitgoMsg1]) (produces userMsg2)
|
|
336
|
+
* API Round 2 → send userMsg2 / recv bitgoMsg2
|
|
337
|
+
* WASM Round 2 → handleIncomingMessages([userMsg2, bitgoMsg2]) (produces userMsg3)
|
|
338
|
+
* API Round 3 → send userMsg3 (WP finalises; no BitGo msg returned to client)
|
|
339
|
+
*/
|
|
340
|
+
async signRequestBase(params, requestType) {
|
|
341
|
+
const userKeyShare = Buffer.from(params.prv, 'base64');
|
|
342
|
+
const txRequest = typeof params.txRequest === 'string'
|
|
343
|
+
? await (0, common_1.getTxRequest)(this.bitgo, this.wallet.id(), params.txRequest, params.reqId)
|
|
344
|
+
: params.txRequest;
|
|
345
|
+
let txOrMessageToSign;
|
|
346
|
+
let derivationPath;
|
|
347
|
+
let bufferContent;
|
|
348
|
+
// One fresh ed25519 GPG key pair per signing session, reused across all signing rounds.
|
|
349
|
+
const userGpgKey = await (0, opengpgUtils_1.generateGPGKeyPair)('ed25519');
|
|
350
|
+
const userGpgPrvKey = await pgp.readPrivateKey({ armoredKey: userGpgKey.privateKey });
|
|
351
|
+
const bitgoGpgPubKey = await this.pickBitgoPubGpgKeyForSigning(true, params.reqId, txRequest.enterpriseId, true);
|
|
352
|
+
(0, assert_1.default)(bitgoGpgPubKey, 'Missing BitGo GPG key for MPCv2');
|
|
353
|
+
if (requestType === baseTypes_1.RequestType.tx) {
|
|
354
|
+
(0, assert_1.default)(txRequest.transactions || txRequest.unsignedTxs, 'Unable to find transactions in txRequest');
|
|
355
|
+
const unsignedTx = txRequest.apiVersion === 'full' ? txRequest.transactions[0].unsignedTx : txRequest.unsignedTxs[0];
|
|
356
|
+
txOrMessageToSign = unsignedTx.signableHex;
|
|
357
|
+
(0, assert_1.default)(txOrMessageToSign, 'Missing signableHex in unsignedTx');
|
|
358
|
+
derivationPath = unsignedTx.derivationPath;
|
|
359
|
+
bufferContent = Buffer.from(txOrMessageToSign, 'hex');
|
|
360
|
+
await this.baseCoin.verifyTransaction({
|
|
361
|
+
txPrebuild: { txHex: unsignedTx.serializedTxHex ?? txOrMessageToSign },
|
|
362
|
+
txParams: (0, recipientUtils_1.resolveEffectiveTxParams)(txRequest, params.txParams, this.baseCoin.getChain()),
|
|
363
|
+
wallet: this.wallet,
|
|
364
|
+
walletType: this.wallet.multisigType(),
|
|
365
|
+
});
|
|
366
|
+
}
|
|
367
|
+
else if (requestType === baseTypes_1.RequestType.message) {
|
|
368
|
+
(0, assert_1.default)(txRequest.messages && txRequest.messages.length > 0, 'Unable to find messages in txRequest');
|
|
369
|
+
txOrMessageToSign = txRequest.messages[0].messageEncoded;
|
|
370
|
+
(0, assert_1.default)(txOrMessageToSign, 'Missing messageEncoded in messages[0]');
|
|
371
|
+
derivationPath = txRequest.messages[0].derivationPath || 'm/0';
|
|
372
|
+
bufferContent = Buffer.from(txOrMessageToSign, 'hex');
|
|
373
|
+
}
|
|
374
|
+
else {
|
|
375
|
+
throw new Error('Invalid request type');
|
|
376
|
+
}
|
|
377
|
+
// ── WASM Round 0 ──────────────────────────────────────────────────────────
|
|
378
|
+
const partyId = params.mpcv2PartyId ?? typesMPCv2_1.MPCv2PartiesEnum.USER;
|
|
379
|
+
const signerShareType = partyId === typesMPCv2_1.MPCv2PartiesEnum.USER ? baseTypes_1.SignatureShareType.USER : baseTypes_1.SignatureShareType.BACKUP;
|
|
380
|
+
const userDsg = new sdk_lib_mpc_1.EddsaMPSDsg.DSG(partyId);
|
|
381
|
+
await userDsg.initDsg(userKeyShare, bufferContent, derivationPath, typesMPCv2_1.MPCv2PartiesEnum.BITGO);
|
|
382
|
+
const userMsg1 = userDsg.getFirstMessage();
|
|
383
|
+
// ── API Round 1 ───────────────────────────────────────────────────────────
|
|
384
|
+
const signatureShareRound1 = await (0, eddsaMPCv2_1.getSignatureShareRoundOne)(userMsg1, userGpgPrvKey, partyId);
|
|
385
|
+
let latestTxRequest = await (0, common_1.sendSignatureShareV2)(this.bitgo, txRequest.walletId, txRequest.txRequestId, [signatureShareRound1], requestType, this.baseCoin.getMPCAlgorithm(), userGpgKey.publicKey, undefined, this.wallet.multisigTypeVersion(), params.reqId);
|
|
386
|
+
(0, assert_1.default)(latestTxRequest.transactions || latestTxRequest.messages, 'Invalid txRequest object after round 1');
|
|
387
|
+
const signatureShares1 = requestType === baseTypes_1.RequestType.tx
|
|
388
|
+
? latestTxRequest.transactions[0].signatureShares
|
|
389
|
+
: latestTxRequest.messages[0].signatureShares;
|
|
390
|
+
const bitgoShareRoundOne = (0, common_1.getBitgoSignatureShare)(signatureShares1, signerShareType, 'round1Output');
|
|
391
|
+
const parsedBitGoToUserSigShareRoundOne = (0, codecs_1.decodeWithCodec)(public_types_1.EddsaMPCv2SignatureShareRound1Output, JSON.parse(bitgoShareRoundOne.share), 'Unexpected signature share response. Unable to parse data.');
|
|
392
|
+
if (parsedBitGoToUserSigShareRoundOne.type !== 'round1Output') {
|
|
393
|
+
throw new Error('Unexpected signature share response. Unable to parse data.');
|
|
394
|
+
}
|
|
395
|
+
const bitgoDeserializedMsg1 = await (0, eddsaMPCv2_1.verifyPeerMessageRoundOne)(parsedBitGoToUserSigShareRoundOne, bitgoGpgPubKey);
|
|
396
|
+
// ── WASM Round 1 ──────────────────────────────────────────────────────────
|
|
397
|
+
const [userMsg2] = userDsg.handleIncomingMessages([userMsg1, bitgoDeserializedMsg1]);
|
|
398
|
+
(0, assert_1.default)(userMsg2, 'WASM round 1 produced no message');
|
|
399
|
+
// ── API Round 2 ───────────────────────────────────────────────────────────
|
|
400
|
+
const signatureShareRoundTwo = await (0, eddsaMPCv2_1.getSignatureShareRoundTwo)(userMsg2, userGpgPrvKey, partyId);
|
|
401
|
+
latestTxRequest = await (0, common_1.sendSignatureShareV2)(this.bitgo, txRequest.walletId, txRequest.txRequestId, [signatureShareRoundTwo], requestType, this.baseCoin.getMPCAlgorithm(), userGpgKey.publicKey, undefined, this.wallet.multisigTypeVersion(), params.reqId);
|
|
402
|
+
(0, assert_1.default)(latestTxRequest.transactions || latestTxRequest.messages, 'Invalid txRequest object after round 2');
|
|
403
|
+
const txRequestSignatureShares = requestType === baseTypes_1.RequestType.tx
|
|
404
|
+
? latestTxRequest.transactions[0].signatureShares
|
|
405
|
+
: latestTxRequest.messages[0].signatureShares;
|
|
406
|
+
const bitgoShareRoundTwo = (0, common_1.getBitgoSignatureShare)(txRequestSignatureShares, signerShareType, 'round2Output');
|
|
407
|
+
const parsedBitGoToUserSigShareRoundTwo = (0, codecs_1.decodeWithCodec)(public_types_1.EddsaMPCv2SignatureShareRound2Output, JSON.parse(bitgoShareRoundTwo.share), 'Unexpected signature share response. Unable to parse data.');
|
|
408
|
+
if (parsedBitGoToUserSigShareRoundTwo.type !== 'round2Output') {
|
|
409
|
+
throw new Error('Unexpected signature share response. Unable to parse data.');
|
|
410
|
+
}
|
|
411
|
+
const bitgoDeserializedMsg2 = await (0, eddsaMPCv2_1.verifyPeerMessageRoundTwo)(parsedBitGoToUserSigShareRoundTwo, bitgoGpgPubKey);
|
|
412
|
+
// ── WASM Round 2 ──────────────────────────────────────────────────────────
|
|
413
|
+
const [userMsg3] = userDsg.handleIncomingMessages([userMsg2, bitgoDeserializedMsg2]);
|
|
414
|
+
(0, assert_1.default)(userMsg3, 'WASM round 2 produced no message');
|
|
415
|
+
// ── API Round 3 ───────────────────────────────────────────────────────────
|
|
416
|
+
// No BitGo response to verify; WP finalises the signing server-side
|
|
417
|
+
const signatureShareRound3 = await (0, eddsaMPCv2_1.getSignatureShareRoundThree)(userMsg3, userGpgPrvKey, partyId);
|
|
418
|
+
const round3TxRequest = await (0, common_1.sendSignatureShareV2)(this.bitgo, txRequest.walletId, txRequest.txRequestId, [signatureShareRound3], requestType, this.baseCoin.getMPCAlgorithm(), userGpgKey.publicKey, undefined, this.wallet.multisigTypeVersion(), params.reqId);
|
|
419
|
+
(0, assert_1.default)(round3TxRequest?.txRequestId === txRequest.txRequestId, 'Invalid txRequest object after round 3');
|
|
420
|
+
return (0, common_1.sendTxRequest)(this.bitgo, txRequest.walletId, txRequest.txRequestId, requestType, params.reqId);
|
|
421
|
+
}
|
|
422
|
+
// #endregion
|
|
423
|
+
// #region external signer
|
|
424
|
+
// #region KeyGenRound1Share
|
|
425
|
+
async createOfflineKeyGenRound1Share(params) {
|
|
426
|
+
const { walletPassphrase, encryptedUserGpgPrvKey, bitgoGpgPubKey, counterPartyGpgPubKey } = params;
|
|
427
|
+
const partyId = params.partyId ?? typesMPCv2_1.MPCv2PartiesEnum.USER;
|
|
428
|
+
const decryptedGpgPrvKey = await this.bitgo.decrypt({ input: encryptedUserGpgPrvKey, password: walletPassphrase });
|
|
429
|
+
const gpgPrvKey = await pgp.readPrivateKey({ armoredKey: decryptedGpgPrvKey });
|
|
430
|
+
const [, ownSk] = await sdk_lib_mpc_1.MPSComms.extractEd25519KeyPair(gpgPrvKey);
|
|
431
|
+
if ((0, bitgoPubKeys_1.envRequiresBitgoPubGpgKeyConfig)(this.bitgo.getEnv())) {
|
|
432
|
+
(0, assert_1.default)((0, bitgoPubKeys_1.isBitgoEddsaMpcv2PubKey)(bitgoGpgPubKey), 'Invalid BitGo GPG public key');
|
|
433
|
+
}
|
|
434
|
+
const bitgoKeyObj = await pgp.readKey({ armoredKey: bitgoGpgPubKey });
|
|
435
|
+
const bitgoPk = await sdk_lib_mpc_1.MPSComms.extractEd25519PublicKey(bitgoKeyObj);
|
|
436
|
+
const counterPartyKeyObj = await pgp.readKey({ armoredKey: counterPartyGpgPubKey });
|
|
437
|
+
const counterPartyPk = await sdk_lib_mpc_1.MPSComms.extractEd25519PublicKey(counterPartyKeyObj);
|
|
438
|
+
const dkg = new sdk_lib_mpc_1.EddsaMPSDkg.DKG(3, 2, partyId);
|
|
439
|
+
await dkg.initDkg(ownSk, [counterPartyPk, bitgoPk]);
|
|
440
|
+
const msg1 = dkg.getFirstMessage();
|
|
441
|
+
const signedMsg1 = await sdk_lib_mpc_1.MPSComms.detachSignMpsMessage(Buffer.from(msg1.payload), gpgPrvKey);
|
|
442
|
+
const sessionPayload = JSON.stringify({
|
|
443
|
+
dkgSession: dkg.getSession(),
|
|
444
|
+
ownMsgPayload: Buffer.from(msg1.payload).toString('base64'),
|
|
445
|
+
ownMsgFrom: msg1.from,
|
|
446
|
+
});
|
|
447
|
+
const encryptedRound1Session = await this.bitgo.encrypt({
|
|
448
|
+
input: sessionPayload,
|
|
449
|
+
password: walletPassphrase,
|
|
450
|
+
adata: `${EddsaMPCv2Utils.MPS_DKG_KEYGEN_ROUND1_STATE}:${partyId}`,
|
|
451
|
+
encryptionVersion: 1,
|
|
452
|
+
});
|
|
453
|
+
return { signedMsg1, encryptedRound1Session };
|
|
454
|
+
}
|
|
455
|
+
// #endregion
|
|
456
|
+
// #region Round1Share
|
|
457
|
+
async createOfflineRound1Share(params) {
|
|
458
|
+
const { prv, walletPassphrase, txRequest, encryptedPrv } = params;
|
|
459
|
+
const { signableHex, derivationPath } = this.getSignableHexAndDerivationPath(txRequest, 'Unable to find transactions in txRequest');
|
|
460
|
+
const adata = `${signableHex}:${derivationPath}`;
|
|
461
|
+
const userKeyShare = Buffer.from(prv, 'base64');
|
|
462
|
+
const userGpgKey = await (0, opengpgUtils_1.generateGPGKeyPair)('ed25519');
|
|
463
|
+
const userGpgPrvKey = await pgp.readPrivateKey({ armoredKey: userGpgKey.privateKey });
|
|
464
|
+
const userDsg = new sdk_lib_mpc_1.EddsaMPSDsg.DSG(typesMPCv2_1.MPCv2PartiesEnum.USER);
|
|
465
|
+
await userDsg.initDsg(userKeyShare, Buffer.from(signableHex, 'hex'), derivationPath, typesMPCv2_1.MPCv2PartiesEnum.BITGO);
|
|
466
|
+
const userMsg1 = userDsg.getFirstMessage();
|
|
467
|
+
const signatureShareRound1 = await (0, eddsaMPCv2_1.getSignatureShareRoundOne)(userMsg1, userGpgPrvKey);
|
|
468
|
+
const sessionPayload = JSON.stringify({
|
|
469
|
+
dsgSession: userDsg.getSession(),
|
|
470
|
+
userMsgPayload: Buffer.from(userMsg1.payload).toString('base64'),
|
|
471
|
+
});
|
|
472
|
+
const userGpgPubKey = userGpgKey.publicKey;
|
|
473
|
+
const useV2 = encryptedPrv !== undefined && (0, baseTypes_1.isV2Envelope)(encryptedPrv);
|
|
474
|
+
if (useV2) {
|
|
475
|
+
const session = await this.bitgo.createEncryptionSession(walletPassphrase);
|
|
476
|
+
try {
|
|
477
|
+
const encryptedRound1Session = await session.encrypt(sessionPayload, `${EddsaMPCv2Utils.MPS_DSG_SIGNING_ROUND1_STATE}:${adata}`);
|
|
478
|
+
const encryptedUserGpgPrvKey = await session.encrypt(userGpgKey.privateKey, `${EddsaMPCv2Utils.MPS_DSG_SIGNING_USER_GPG_KEY}:${adata}`);
|
|
479
|
+
return { signatureShareRound1, userGpgPubKey, encryptedRound1Session, encryptedUserGpgPrvKey };
|
|
480
|
+
}
|
|
481
|
+
finally {
|
|
482
|
+
session.destroy();
|
|
483
|
+
}
|
|
484
|
+
}
|
|
485
|
+
const encryptedRound1Session = await this.bitgo.encrypt({
|
|
486
|
+
input: sessionPayload,
|
|
487
|
+
password: walletPassphrase,
|
|
488
|
+
adata: `${EddsaMPCv2Utils.MPS_DSG_SIGNING_ROUND1_STATE}:${adata}`,
|
|
489
|
+
encryptionVersion: 1,
|
|
490
|
+
});
|
|
491
|
+
const encryptedUserGpgPrvKey = await this.bitgo.encrypt({
|
|
492
|
+
input: userGpgKey.privateKey,
|
|
493
|
+
password: walletPassphrase,
|
|
494
|
+
adata: `${EddsaMPCv2Utils.MPS_DSG_SIGNING_USER_GPG_KEY}:${adata}`,
|
|
495
|
+
encryptionVersion: 1,
|
|
496
|
+
});
|
|
497
|
+
return { signatureShareRound1, userGpgPubKey, encryptedRound1Session, encryptedUserGpgPrvKey };
|
|
498
|
+
}
|
|
499
|
+
// #endregion
|
|
500
|
+
// #region Round2Share
|
|
501
|
+
async createOfflineRound2Share(params) {
|
|
502
|
+
const { walletPassphrase, encryptedUserGpgPrvKey, encryptedRound1Session, bitgoPublicGpgKey, txRequest } = params;
|
|
503
|
+
const { signableHex, derivationPath } = this.getSignableHexAndDerivationPath(txRequest, 'Unable to find transactions in txRequest');
|
|
504
|
+
const adata = `${signableHex}:${derivationPath}`;
|
|
505
|
+
const useV2 = (0, baseTypes_1.isV2Envelope)(encryptedRound1Session);
|
|
506
|
+
const { bitgoGpgKey, userGpgPrvKey } = await this.getBitgoAndUserGpgKeys(bitgoPublicGpgKey, encryptedUserGpgPrvKey, walletPassphrase, adata, EddsaMPCv2Utils.MPS_DSG_SIGNING_USER_GPG_KEY);
|
|
507
|
+
const transactions = txRequest.transactions;
|
|
508
|
+
(0, assert_1.default)(Array.isArray(transactions) && transactions.length === 1, 'txRequest must have exactly one transaction');
|
|
509
|
+
const signatureShares = transactions[0].signatureShares;
|
|
510
|
+
(0, assert_1.default)(signatureShares, 'Missing signature shares in round 1 txRequest');
|
|
511
|
+
const bitgoShareRoundOne = (0, common_1.getBitgoSignatureShare)(signatureShares, baseTypes_1.SignatureShareType.USER, 'round1Output');
|
|
512
|
+
const parsedBitGoToUserSigShareRoundOne = (0, codecs_1.decodeWithCodec)(public_types_1.EddsaMPCv2SignatureShareRound1Output, JSON.parse(bitgoShareRoundOne.share), 'Unexpected signature share response. Unable to parse data.');
|
|
513
|
+
if (parsedBitGoToUserSigShareRoundOne.type !== 'round1Output') {
|
|
514
|
+
throw new Error('Unexpected signature share response. Unable to parse data.');
|
|
515
|
+
}
|
|
516
|
+
const bitgoDeserializedMsg1 = await (0, eddsaMPCv2_1.verifyPeerMessageRoundOne)(parsedBitGoToUserSigShareRoundOne, bitgoGpgKey);
|
|
517
|
+
this.validateAdata(adata, encryptedRound1Session, EddsaMPCv2Utils.MPS_DSG_SIGNING_ROUND1_STATE);
|
|
518
|
+
const decryptedRound1Session = await this.bitgo.decrypt({
|
|
519
|
+
input: encryptedRound1Session,
|
|
520
|
+
password: walletPassphrase,
|
|
521
|
+
});
|
|
522
|
+
const { dsgSession, userMsgPayload } = JSON.parse(decryptedRound1Session);
|
|
523
|
+
const userDsg = new sdk_lib_mpc_1.EddsaMPSDsg.DSG(typesMPCv2_1.MPCv2PartiesEnum.USER);
|
|
524
|
+
await userDsg.restoreSession(dsgSession);
|
|
525
|
+
const userMsg1 = {
|
|
526
|
+
from: typesMPCv2_1.MPCv2PartiesEnum.USER,
|
|
527
|
+
payload: new Uint8Array(Buffer.from(userMsgPayload, 'base64')),
|
|
528
|
+
};
|
|
529
|
+
const [userMsg2] = userDsg.handleIncomingMessages([userMsg1, bitgoDeserializedMsg1]);
|
|
530
|
+
(0, assert_1.default)(userMsg2, 'DSG handleIncomingMessages produced no round-2 output');
|
|
531
|
+
const signatureShareRound2 = await (0, eddsaMPCv2_1.getSignatureShareRoundTwo)(userMsg2, userGpgPrvKey);
|
|
532
|
+
const sessionPayload = JSON.stringify({
|
|
533
|
+
dsgSession: userDsg.getSession(),
|
|
534
|
+
userMsgPayload: Buffer.from(userMsg2.payload).toString('base64'),
|
|
535
|
+
});
|
|
536
|
+
if (useV2) {
|
|
537
|
+
const session = await this.bitgo.createEncryptionSession(walletPassphrase);
|
|
538
|
+
try {
|
|
539
|
+
const encryptedRound2Session = await session.encrypt(sessionPayload, `${EddsaMPCv2Utils.MPS_DSG_SIGNING_ROUND2_STATE}:${adata}`);
|
|
540
|
+
return { signatureShareRound2, encryptedRound2Session };
|
|
541
|
+
}
|
|
542
|
+
finally {
|
|
543
|
+
session.destroy();
|
|
544
|
+
}
|
|
545
|
+
}
|
|
546
|
+
const encryptedRound2Session = await this.bitgo.encrypt({
|
|
547
|
+
input: sessionPayload,
|
|
548
|
+
password: walletPassphrase,
|
|
549
|
+
adata: `${EddsaMPCv2Utils.MPS_DSG_SIGNING_ROUND2_STATE}:${adata}`,
|
|
550
|
+
encryptionVersion: 1,
|
|
551
|
+
});
|
|
552
|
+
return { signatureShareRound2, encryptedRound2Session };
|
|
553
|
+
}
|
|
554
|
+
// #endregion
|
|
555
|
+
// #region Round3Share
|
|
556
|
+
async createOfflineRound3Share(params) {
|
|
557
|
+
const { walletPassphrase, encryptedUserGpgPrvKey, encryptedRound2Session, bitgoPublicGpgKey, txRequest } = params;
|
|
558
|
+
const { signableHex, derivationPath } = this.getSignableHexAndDerivationPath(txRequest, 'Unable to find transactions in txRequest');
|
|
559
|
+
const adata = `${signableHex}:${derivationPath}`;
|
|
560
|
+
const { bitgoGpgKey, userGpgPrvKey } = await this.getBitgoAndUserGpgKeys(bitgoPublicGpgKey, encryptedUserGpgPrvKey, walletPassphrase, adata, EddsaMPCv2Utils.MPS_DSG_SIGNING_USER_GPG_KEY);
|
|
561
|
+
const transactions = txRequest.transactions;
|
|
562
|
+
(0, assert_1.default)(Array.isArray(transactions) && transactions.length === 1, 'txRequest must have exactly one transaction');
|
|
563
|
+
const signatureShares = transactions[0].signatureShares;
|
|
564
|
+
(0, assert_1.default)(signatureShares, 'Missing signature shares in round 2 txRequest');
|
|
565
|
+
const bitgoShareRoundTwo = (0, common_1.getBitgoSignatureShare)(signatureShares, baseTypes_1.SignatureShareType.USER, 'round2Output');
|
|
566
|
+
const parsedBitGoToUserSigShareRoundTwo = (0, codecs_1.decodeWithCodec)(public_types_1.EddsaMPCv2SignatureShareRound2Output, JSON.parse(bitgoShareRoundTwo.share), 'Unexpected signature share response. Unable to parse data.');
|
|
567
|
+
if (parsedBitGoToUserSigShareRoundTwo.type !== 'round2Output') {
|
|
568
|
+
throw new Error('Unexpected signature share response. Unable to parse data.');
|
|
569
|
+
}
|
|
570
|
+
const bitgoDeserializedMsg2 = await (0, eddsaMPCv2_1.verifyPeerMessageRoundTwo)(parsedBitGoToUserSigShareRoundTwo, bitgoGpgKey);
|
|
571
|
+
this.validateAdata(adata, encryptedRound2Session, EddsaMPCv2Utils.MPS_DSG_SIGNING_ROUND2_STATE);
|
|
572
|
+
const decryptedRound2Session = await this.bitgo.decrypt({
|
|
573
|
+
input: encryptedRound2Session,
|
|
574
|
+
password: walletPassphrase,
|
|
575
|
+
});
|
|
576
|
+
const { dsgSession, userMsgPayload } = JSON.parse(decryptedRound2Session);
|
|
577
|
+
const userDsg = new sdk_lib_mpc_1.EddsaMPSDsg.DSG(typesMPCv2_1.MPCv2PartiesEnum.USER);
|
|
578
|
+
await userDsg.restoreSession(dsgSession);
|
|
579
|
+
const userMsg2 = {
|
|
580
|
+
from: typesMPCv2_1.MPCv2PartiesEnum.USER,
|
|
581
|
+
payload: new Uint8Array(Buffer.from(userMsgPayload, 'base64')),
|
|
582
|
+
};
|
|
583
|
+
const [userMsg3] = userDsg.handleIncomingMessages([userMsg2, bitgoDeserializedMsg2]);
|
|
584
|
+
(0, assert_1.default)(userMsg3, 'DSG handleIncomingMessages produced no round-3 output');
|
|
585
|
+
const signatureShareRound3 = await (0, eddsaMPCv2_1.getSignatureShareRoundThree)(userMsg3, userGpgPrvKey);
|
|
586
|
+
return { signatureShareRound3 };
|
|
587
|
+
}
|
|
588
|
+
// #endregion
|
|
589
|
+
/** @inheritdoc */
|
|
590
|
+
async signEddsaMPCv2TssUsingExternalSigner(params, externalSignerEddsaMPCv2SigningRound1Generator, externalSignerEddsaMPCv2SigningRound2Generator, externalSignerEddsaMPCv2SigningRound3Generator, requestType = baseTypes_1.RequestType.tx) {
|
|
591
|
+
const { txRequest, reqId } = params;
|
|
592
|
+
// TODO(WP-2176): Add support for message signing
|
|
593
|
+
(0, assert_1.default)(requestType === baseTypes_1.RequestType.tx, 'Only transaction signing is supported for external signer, got: ' + requestType);
|
|
594
|
+
let txRequestResolved;
|
|
595
|
+
if (typeof txRequest === 'string') {
|
|
596
|
+
txRequestResolved = await (0, common_1.getTxRequest)(this.bitgo, this.wallet.id(), txRequest, reqId);
|
|
597
|
+
}
|
|
598
|
+
else {
|
|
599
|
+
txRequestResolved = txRequest;
|
|
600
|
+
}
|
|
601
|
+
const bitgoPublicGpgKey = await this.pickBitgoPubGpgKeyForSigning(true, reqId, txRequestResolved.enterpriseId, true);
|
|
602
|
+
if (!bitgoPublicGpgKey) {
|
|
603
|
+
throw new Error('Missing BitGo GPG key for MPCv2');
|
|
604
|
+
}
|
|
605
|
+
// round 1
|
|
606
|
+
const { signatureShareRound1, userGpgPubKey, encryptedRound1Session, encryptedUserGpgPrvKey } = await externalSignerEddsaMPCv2SigningRound1Generator({ txRequest: txRequestResolved });
|
|
607
|
+
const round1TxRequest = await (0, common_1.sendSignatureShareV2)(this.bitgo, txRequestResolved.walletId, txRequestResolved.txRequestId, [signatureShareRound1], requestType, this.baseCoin.getMPCAlgorithm(), userGpgPubKey, undefined, this.wallet.multisigTypeVersion(), reqId);
|
|
608
|
+
// round 2
|
|
609
|
+
const { signatureShareRound2, encryptedRound2Session } = await externalSignerEddsaMPCv2SigningRound2Generator({
|
|
610
|
+
txRequest: round1TxRequest,
|
|
611
|
+
encryptedRound1Session,
|
|
612
|
+
encryptedUserGpgPrvKey,
|
|
613
|
+
bitgoPublicGpgKey: bitgoPublicGpgKey.armor(),
|
|
614
|
+
});
|
|
615
|
+
const round2TxRequest = await (0, common_1.sendSignatureShareV2)(this.bitgo, txRequestResolved.walletId, txRequestResolved.txRequestId, [signatureShareRound2], requestType, this.baseCoin.getMPCAlgorithm(), userGpgPubKey, undefined, this.wallet.multisigTypeVersion(), reqId);
|
|
616
|
+
(0, assert_1.default)(round2TxRequest.transactions && round2TxRequest.transactions[0].signatureShares, 'Missing signature shares in round 2 txRequest');
|
|
617
|
+
// round 3
|
|
618
|
+
const { signatureShareRound3 } = await externalSignerEddsaMPCv2SigningRound3Generator({
|
|
619
|
+
txRequest: round2TxRequest,
|
|
620
|
+
encryptedRound2Session,
|
|
621
|
+
encryptedUserGpgPrvKey,
|
|
622
|
+
bitgoPublicGpgKey: bitgoPublicGpgKey.armor(),
|
|
623
|
+
});
|
|
624
|
+
await (0, common_1.sendSignatureShareV2)(this.bitgo, txRequestResolved.walletId, txRequestResolved.txRequestId, [signatureShareRound3], requestType, this.baseCoin.getMPCAlgorithm(), userGpgPubKey, undefined, this.wallet.multisigTypeVersion(), reqId);
|
|
625
|
+
return (0, common_1.sendTxRequest)(this.bitgo, txRequestResolved.walletId, txRequestResolved.txRequestId, requestType, reqId);
|
|
626
|
+
}
|
|
627
|
+
// #endregion
|
|
628
|
+
// #region retrofit
|
|
629
|
+
async getUserAndBackupSession(retrofit) {
|
|
630
|
+
if (retrofit) {
|
|
631
|
+
const { userRetrofitData, backupRetrofitData } = await this.getMpcV2RetrofitDataFromMpcV1Keys({
|
|
632
|
+
mpcv1UserKeyShare: retrofit.decryptedUserKey,
|
|
633
|
+
mpcv1BackupKeyShare: retrofit.decryptedBackupKey,
|
|
634
|
+
});
|
|
635
|
+
return {
|
|
636
|
+
userDkg: new sdk_lib_mpc_1.EddsaMPSDkg.DKG(3, 2, typesMPCv2_1.MPCv2PartiesEnum.USER, userRetrofitData),
|
|
637
|
+
backupDkg: new sdk_lib_mpc_1.EddsaMPSDkg.DKG(3, 2, typesMPCv2_1.MPCv2PartiesEnum.BACKUP, backupRetrofitData),
|
|
638
|
+
};
|
|
639
|
+
}
|
|
640
|
+
return {
|
|
641
|
+
userDkg: new sdk_lib_mpc_1.EddsaMPSDkg.DKG(3, 2, typesMPCv2_1.MPCv2PartiesEnum.USER),
|
|
642
|
+
backupDkg: new sdk_lib_mpc_1.EddsaMPSDkg.DKG(3, 2, typesMPCv2_1.MPCv2PartiesEnum.BACKUP),
|
|
643
|
+
};
|
|
644
|
+
}
|
|
645
|
+
async getMpcV2RetrofitDataFromMpcV1Keys(params) {
|
|
646
|
+
const MPC = await (0, eddsa_1.getInitializedMpcInstance)();
|
|
647
|
+
const userRetrofitData = EddsaMPCv2Utils.getMpcV2RetrofitDataFromMpcV1Key(params.mpcv1UserKeyShare, typesMPCv2_1.MPCv2PartiesEnum.USER, MPC);
|
|
648
|
+
const backupRetrofitData = EddsaMPCv2Utils.getMpcV2RetrofitDataFromMpcV1Key(params.mpcv1BackupKeyShare, typesMPCv2_1.MPCv2PartiesEnum.BACKUP, MPC);
|
|
649
|
+
(0, assert_1.default)(userRetrofitData.expectedPk === backupRetrofitData.expectedPk, 'MPCv1 user and backup keys combine to different aggregate public keys');
|
|
650
|
+
(0, assert_1.default)(userRetrofitData.chainCode === backupRetrofitData.chainCode, 'MPCv1 user and backup keys combine to different chain codes');
|
|
651
|
+
return { userRetrofitData, backupRetrofitData };
|
|
652
|
+
}
|
|
653
|
+
static getMpcV2RetrofitDataFromMpcV1Key(mpcv1PartyKeyShare, mpcv1PartyIndex, mpc) {
|
|
654
|
+
const signingMaterial = JSON.parse(mpcv1PartyKeyShare);
|
|
655
|
+
(0, assert_1.default)(signingMaterial.uShare, 'MPCv1 key material missing uShare');
|
|
656
|
+
(0, assert_1.default)(signingMaterial.bitgoYShare, 'MPCv1 key material missing bitgoYShare');
|
|
657
|
+
let pShare;
|
|
658
|
+
switch (mpcv1PartyIndex) {
|
|
659
|
+
case typesMPCv2_1.MPCv2PartiesEnum.USER:
|
|
660
|
+
(0, assert_1.default)(signingMaterial.backupYShare, 'User MPCv1 key material missing backupYShare');
|
|
661
|
+
pShare = mpc.keyCombine(signingMaterial.uShare, [
|
|
662
|
+
signingMaterial.bitgoYShare,
|
|
663
|
+
signingMaterial.backupYShare,
|
|
664
|
+
]).pShare;
|
|
665
|
+
break;
|
|
666
|
+
case typesMPCv2_1.MPCv2PartiesEnum.BACKUP:
|
|
667
|
+
(0, assert_1.default)(signingMaterial.userYShare, 'Backup MPCv1 key material missing userYShare');
|
|
668
|
+
pShare = mpc.keyCombine(signingMaterial.uShare, [
|
|
669
|
+
signingMaterial.bitgoYShare,
|
|
670
|
+
signingMaterial.userYShare,
|
|
671
|
+
]).pShare;
|
|
672
|
+
break;
|
|
673
|
+
default:
|
|
674
|
+
throw new Error('Invalid participant index');
|
|
675
|
+
}
|
|
676
|
+
return {
|
|
677
|
+
s_i_0: pShare.u,
|
|
678
|
+
expectedPk: pShare.y,
|
|
679
|
+
chainCode: pShare.chaincode,
|
|
680
|
+
};
|
|
681
|
+
}
|
|
682
|
+
}
|
|
683
|
+
exports.EddsaMPCv2Utils = EddsaMPCv2Utils;
|
|
684
|
+
EddsaMPCv2Utils.MPS_DSG_SIGNING_USER_GPG_KEY = 'MPS_DSG_SIGNING_USER_GPG_KEY';
|
|
685
|
+
EddsaMPCv2Utils.MPS_DSG_SIGNING_ROUND1_STATE = 'MPS_DSG_SIGNING_ROUND1_STATE';
|
|
686
|
+
EddsaMPCv2Utils.MPS_DSG_SIGNING_ROUND2_STATE = 'MPS_DSG_SIGNING_ROUND2_STATE';
|
|
687
|
+
EddsaMPCv2Utils.MPS_DKG_KEYGEN_ROUND1_STATE = 'MPS_DKG_KEYGEN_ROUND1_STATE';
|
|
688
|
+
/**
|
|
689
|
+
* Detect whether an encrypted keycard contains MPCv1 signing material.
|
|
690
|
+
*
|
|
691
|
+
* Decrypts the keycard and checks for the JSON shape produced by the MPCv1 TSS
|
|
692
|
+
* key-generation flow (uShare.seed + bitgoYShare.u + backupYShare.u / userYShare.u).
|
|
693
|
+
* Returns false for MPCv2 CBOR keycards, wrong passwords, or any decryption error.
|
|
694
|
+
*
|
|
695
|
+
* @param encryptedKeyShare encrypted user or backup keycard
|
|
696
|
+
* @param walletPassphrase passphrase used to encrypt the keycard
|
|
697
|
+
* @param bitgo optional BitGoBase instance; when provided, decrypts via
|
|
698
|
+
* bitgo.decrypt (supports both v1 SJCL and v2 Argon2id envelopes);
|
|
699
|
+
* when absent, falls back to sjcl.decrypt (v1 only)
|
|
700
|
+
*/
|
|
701
|
+
function parseEddsaMpcV1Material(decrypted) {
|
|
702
|
+
try {
|
|
703
|
+
const m = JSON.parse(decrypted);
|
|
704
|
+
if (typeof m?.uShare?.seed === 'string' &&
|
|
705
|
+
typeof m?.bitgoYShare?.u === 'string' &&
|
|
706
|
+
(typeof m?.backupYShare?.u === 'string' || typeof m?.userYShare?.u === 'string')) {
|
|
707
|
+
return decrypted;
|
|
708
|
+
}
|
|
709
|
+
}
|
|
710
|
+
catch {
|
|
711
|
+
// Not JSON → MPCv2 CBOR
|
|
712
|
+
}
|
|
713
|
+
return null;
|
|
714
|
+
}
|
|
715
|
+
async function isEddsaMpcV1SigningMaterial(encryptedKeyShare, walletPassphrase, bitgo) {
|
|
716
|
+
const decrypted = bitgo
|
|
717
|
+
? await bitgo.decrypt({ input: encryptedKeyShare, password: walletPassphrase })
|
|
718
|
+
: sjcl.decrypt(walletPassphrase, encryptedKeyShare);
|
|
719
|
+
return parseEddsaMpcV1Material(decrypted) !== null;
|
|
720
|
+
}
|
|
721
|
+
/**
|
|
722
|
+
* Get EdDSA MPCv2 recovery key shares from encrypted reduced user and backup keys.
|
|
723
|
+
*
|
|
724
|
+
* The encrypted inputs are the `reducedEncryptedPrv` values stored on EdDSA MPCv2
|
|
725
|
+
* key cards. They decrypt to CBOR-encoded reduced shares that contain the opaque
|
|
726
|
+
* MPS signing key-share bytes plus the common public keychain material.
|
|
727
|
+
*
|
|
728
|
+
* @param encryptedUserKey encrypted EdDSA MPCv2 reduced user key
|
|
729
|
+
* @param encryptedBackupKey encrypted EdDSA MPCv2 reduced backup key
|
|
730
|
+
* @param walletPassphrase password for user and backup keys
|
|
731
|
+
* @returns EdDSA MPCv2 recovery key shares and common keychain
|
|
732
|
+
*/
|
|
733
|
+
async function getEddsaMpcV2RecoveryKeySharesFromReducedKey(encryptedUserKey, encryptedBackupKey, walletPassphrase, bitgo) {
|
|
734
|
+
const decodeKey = async (encryptedKey) => {
|
|
735
|
+
const decrypted = bitgo
|
|
736
|
+
? await bitgo.decrypt({ input: encryptedKey, password: walletPassphrase })
|
|
737
|
+
: sjcl.decrypt(walletPassphrase, encryptedKey);
|
|
738
|
+
let reduced;
|
|
739
|
+
try {
|
|
740
|
+
reduced = sdk_lib_mpc_1.MPSTypes.getDecodedReducedKeyShare(Buffer.from(decrypted, 'base64'));
|
|
741
|
+
}
|
|
742
|
+
catch {
|
|
743
|
+
throw new Error('EdDSA MPCv2 recovery: unable to decode reduced key share from keycard material. The encrypted key may be corrupted, malformed, or not an EdDSA MPCv2 reduced key.');
|
|
744
|
+
}
|
|
745
|
+
if (!reduced.keyShare?.length || !reduced.pub?.length || !reduced.rootChainCode?.length) {
|
|
746
|
+
throw new Error('EdDSA MPCv2 recovery: reduced key share is missing keyShare, pub, or rootChainCode. This keycard may be public-only and cannot be used for recovery.');
|
|
747
|
+
}
|
|
748
|
+
return reduced;
|
|
749
|
+
};
|
|
750
|
+
const [userReduced, backupReduced] = await Promise.all([decodeKey(encryptedUserKey), decodeKey(encryptedBackupKey)]);
|
|
751
|
+
const userPub = Buffer.from(userReduced.pub).toString('hex');
|
|
752
|
+
const backupPub = Buffer.from(backupReduced.pub).toString('hex');
|
|
753
|
+
if (userPub !== backupPub) {
|
|
754
|
+
throw new Error('EdDSA MPCv2 recovery: user and backup pub keys do not match');
|
|
755
|
+
}
|
|
756
|
+
const userChainCode = Buffer.from(userReduced.rootChainCode).toString('hex');
|
|
757
|
+
const backupChainCode = Buffer.from(backupReduced.rootChainCode).toString('hex');
|
|
758
|
+
if (userChainCode !== backupChainCode) {
|
|
759
|
+
throw new Error('EdDSA MPCv2 recovery: user and backup rootChainCodes do not match');
|
|
760
|
+
}
|
|
761
|
+
return {
|
|
762
|
+
userKeyShare: Buffer.from(userReduced.keyShare),
|
|
763
|
+
backupKeyShare: Buffer.from(backupReduced.keyShare),
|
|
764
|
+
commonKeyChain: userPub + userChainCode,
|
|
765
|
+
};
|
|
766
|
+
}
|
|
767
|
+
/**
|
|
768
|
+
* Sign a message for recovery using EdDSA MPCv2 (MPS) with user and backup key shares.
|
|
769
|
+
*
|
|
770
|
+
* Runs the MPS DSG protocol locally to round 3, then verifies the resulting
|
|
771
|
+
* Ed25519 signature against the public key derived from the common keychain.
|
|
772
|
+
*
|
|
773
|
+
* @param message raw bytes to sign
|
|
774
|
+
* @param derivationPath BIP-32-style derivation path, e.g. `"m/0"`
|
|
775
|
+
* @param userKeyShare opaque MPS signing key-share bytes for the user party
|
|
776
|
+
* @param backupKeyShare opaque MPS signing key-share bytes for the backup party
|
|
777
|
+
* @param commonKeyChain 128-hex-char string: 32-byte pub + 32-byte rootChainCode
|
|
778
|
+
* @returns 64-byte Ed25519 signature Buffer
|
|
779
|
+
*/
|
|
780
|
+
async function signRecoveryEddsaMPCv2(message, derivationPath, userKeyShare, backupKeyShare, commonKeyChain) {
|
|
781
|
+
const userDsg = new sdk_lib_mpc_1.EddsaMPSDsg.DSG(typesMPCv2_1.MPCv2PartiesEnum.USER);
|
|
782
|
+
const backupDsg = new sdk_lib_mpc_1.EddsaMPSDsg.DSG(typesMPCv2_1.MPCv2PartiesEnum.BACKUP);
|
|
783
|
+
const signature = (await sdk_lib_mpc_1.MPSUtil.executeTillRound(3, userDsg, backupDsg, userKeyShare, backupKeyShare, message, derivationPath));
|
|
784
|
+
// Use Eddsa.deriveUnhardened (BIP32-Ed25519), which matches what DSG uses
|
|
785
|
+
// internally for path derivation since wasm-mps 1.9.0.
|
|
786
|
+
const mpc = await (0, eddsa_1.getInitializedMpcInstance)();
|
|
787
|
+
const derivedKeychain = mpc.deriveUnhardened(commonKeyChain, derivationPath);
|
|
788
|
+
const publicKeyBytes = Buffer.from(derivedKeychain.slice(0, 64), 'hex');
|
|
789
|
+
const verified = ed25519_1.ed25519.verify(new Uint8Array(signature), new Uint8Array(message), new Uint8Array(publicKeyBytes));
|
|
790
|
+
if (!verified) {
|
|
791
|
+
throw new Error('EdDSA MPCv2 recovery signature verification failed');
|
|
792
|
+
}
|
|
793
|
+
return signature;
|
|
794
|
+
}
|
|
795
|
+
/**
|
|
796
|
+
* Detects MPCv1 vs MPCv2 keycard format and returns typed signing material.
|
|
797
|
+
* For v1: decrypts once and returns the plaintext as userPrv.
|
|
798
|
+
* For v2: returns the encrypted key as-is for use with signEddsaMpcV2RecoveryTx.
|
|
799
|
+
* When bitgo is omitted, falls back to sjcl (v1 only).
|
|
800
|
+
*/
|
|
801
|
+
async function getEddsaSigningMaterial(userKey, walletPassphrase, bitgo) {
|
|
802
|
+
const normalized = userKey.replace(/\s/g, '');
|
|
803
|
+
let decrypted;
|
|
804
|
+
try {
|
|
805
|
+
decrypted = bitgo
|
|
806
|
+
? await bitgo.decrypt({ input: normalized, password: walletPassphrase })
|
|
807
|
+
: sjcl.decrypt(walletPassphrase, normalized);
|
|
808
|
+
}
|
|
809
|
+
catch (e) {
|
|
810
|
+
throw new Error(`Error decrypting user keychain: ${e instanceof Error ? e.message : String(e)}`);
|
|
811
|
+
}
|
|
812
|
+
const userPrv = parseEddsaMpcV1Material(decrypted);
|
|
813
|
+
return userPrv !== null ? { version: 'v1', userPrv } : { version: 'v2', encryptedUserKey: normalized };
|
|
814
|
+
}
|
|
815
|
+
/**
|
|
816
|
+
* Full MPCv2 recovery signing flow: decrypt key shares → validate commonKeyChain → MPS DSG.
|
|
817
|
+
* Returns raw 64-byte Ed25519 signature Buffer.
|
|
818
|
+
* Caller is responsible for any coin-specific envelope
|
|
819
|
+
* (e.g. 0x00 Substrate prefix, SUI flag+pubkey wrapper, or raw for NEAR/ADA/TON).
|
|
820
|
+
*/
|
|
821
|
+
async function signEddsaMpcV2RecoveryTx(params) {
|
|
822
|
+
const { userKeyShare, backupKeyShare, commonKeyChain } = await getEddsaMpcV2RecoveryKeySharesFromReducedKey(params.userKey, params.backupKey, params.walletPassphrase, params.bitgo);
|
|
823
|
+
if (commonKeyChain.toLowerCase() !== params.bitgoKey.toLowerCase()) {
|
|
824
|
+
throw new Error('EdDSA MPCv2 recovery: commonKeyChain from keycard does not match bitgoKey');
|
|
825
|
+
}
|
|
826
|
+
return signRecoveryEddsaMPCv2(params.message, params.derivationPath, userKeyShare, backupKeyShare, commonKeyChain);
|
|
827
|
+
}
|
|
828
|
+
exports.EddsaMPCv2RecoveryFunctions = {
|
|
829
|
+
isEddsaMpcV1SigningMaterial,
|
|
830
|
+
getEddsaMpcV2RecoveryKeySharesFromReducedKey,
|
|
831
|
+
signRecoveryEddsaMPCv2,
|
|
832
|
+
getEddsaSigningMaterial,
|
|
833
|
+
signEddsaMpcV2RecoveryTx,
|
|
834
|
+
};
|
|
835
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiZWRkc2FNUEN2Mi5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uLy4uLy4uLy4uL3NyYy9iaXRnby91dGlscy90c3MvZWRkc2EvZWRkc2FNUEN2Mi50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiOzs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7QUEycUNBLGtFQVNDO0FBY0Qsb0dBNkNDO0FBZUQsd0RBZ0NDO0FBZUQsMERBZ0JDO0FBUUQsNERBbUJDO0FBeDFDRCxvREFBNEI7QUFDNUIsdURBQXlDO0FBQ3pDLDZDQUErQjtBQUMvQiw2Q0FBNkM7QUFDN0Msc0RBUzZCO0FBRTdCLG1EQUFnRDtBQUNoRCx5REFBZ0c7QUFTaEcsNERBQXFHO0FBQ3JHLGdEQUFnSDtBQUNoSCx5Q0FBK0M7QUFDL0MsOERBTXVDO0FBQ3ZDLG9EQUFxRTtBQUNyRSxxREFBd0Q7QUFDeEQsb0RBQXVEO0FBQ3ZELDRDQWFzQjtBQUd0QixpQ0FBd0M7QUFDeEMsc0RBQTZEO0FBQzdELHFFQUE2RjtBQUk3RixNQUFhLGVBQWdCLFNBQVEscUJBQWM7SUFNakQsa0JBQWtCO0lBQ2xCLEtBQUssQ0FBQyxlQUFlLENBQUMsTUFTckI7UUFDQyxNQUFNLFdBQVcsR0FBRyxNQUFNLElBQUEsaUNBQWtCLEVBQUMsU0FBUyxDQUFDLENBQUM7UUFDeEQsTUFBTSxVQUFVLEdBQUcsTUFBTSxHQUFHLENBQUMsY0FBYyxDQUFDLEVBQUUsVUFBVSxFQUFFLFdBQVcsQ0FBQyxVQUFVLEVBQUUsQ0FBQyxDQUFDO1FBQ3BGLE1BQU0sZ0JBQWdCLEdBQUcsV0FBVyxDQUFDLFNBQVMsQ0FBQztRQUMvQyxNQUFNLENBQUMsTUFBTSxFQUFFLE1BQU0sQ0FBQyxHQUFHLE1BQU0sc0JBQVEsQ0FBQyxxQkFBcUIsQ0FBQyxVQUFVLENBQUMsQ0FBQztRQUUxRSxNQUFNLGFBQWEsR0FBRyxNQUFNLElBQUEsaUNBQWtCLEVBQUMsU0FBUyxDQUFDLENBQUM7UUFDMUQsTUFBTSxZ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QVksRUFBRSxjQUFjLEVBQUUsY0FBYyxFQUFFLEdBQUcsTUFBTSw0Q0FBNEMsQ0FDekcsTUFBTSxDQUFDLE9BQU8sRUFDZCxNQUFNLENBQUMsU0FBUyxFQUNoQixNQUFNLENBQUMsZ0JBQWdCLEVBQ3ZCLE1BQU0sQ0FBQyxLQUFLLENBQ2IsQ0FBQztJQUNGLElBQUksY0FBYyxDQUFDLFdBQVcsRUFBRSxLQUFLLE1BQU0sQ0FBQyxRQUFRLENBQUMsV0FBVyxFQUFFLEVBQUUsQ0FBQztRQUNuRSxNQUFNLElBQUksS0FBSyxDQUFDLDJFQUEyRSxDQUFDLENBQUM7SUFDL0YsQ0FBQztJQUNELE9BQU8sc0JBQXNCLENBQUMsTUFBTSxDQUFDLE9BQU8sRUFBRSxNQUFNLENBQUMsY0FBYyxFQUFFLFlBQVksRUFBRSxjQUFjLEVBQUUsY0FBYyxDQUFDLENBQUM7QUFDckgsQ0FBQztBQUVZLFFBQUEsMkJBQTJCLEdBQUc7SUFDekMsMkJBQTJCO0lBQzNCLDRDQUE0QztJQUM1QyxzQkFBc0I7SUFDdEIsdUJBQXVCO0lBQ3ZCLHdCQUF3QjtDQUN6QixDQUFDIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IGFzc2VydCBmcm9tICdhc3NlcnQnO1xuaW1wb3J0ICogYXMgc2pjbCBmcm9tICdAYml0Z28tYmV0YS9zamNsJztcbmltcG9ydCAqIGFzIHBncCBmcm9tICdvcGVucGdwJztcbmltcG9ydCB7IE5vbkVtcHR5U3RyaW5nIH0gZnJvbSAnaW8tdHMtdHlwZXMnO1xuaW1wb3J0IHtcbiAgRWRkc2FNUEN2MktleUdlblJvdW5kMVJlcXVlc3QsXG4gIEVkZHNhTVBDdjJLZXlHZW5Sb3VuZDFSZXNwb25zZSxcbiAgRWRkc2FNUEN2MktleUdlblJvdW5kMlJlcXVlc3QsXG4gIEVkZHNhTVBDdjJLZXlHZW5Sb3VuZDJSZXNwb25zZSxcbiAgRWRkc2FNUEN2MlNpZ25hdHVyZVNoYXJlUm91bmQxT3V0cHV0LFxuICBFZGRzYU1QQ3YyU2lnbmF0dXJlU2hhcmVSb3VuZDJPdXRwdXQsXG4gIE1QQ3YyS2V5R2VuU3RhdGVFbnVtLFxuICBNUEN2MlBhcnR5RnJvbVN0cmluZ09yTnVtYmVyLFxufSBmcm9tICdAYml0Z28vcHVibGljLXR5cGVzJztcbmltcG9ydCB7IEVkZHNhTVBDdjJLZXlHZW5DYWxsYmFja3MgfSBmcm9tICcuLi8uLi8uLi93YWxsZXQvaVdhbGxldHMnO1xuaW1wb3J0IHsgZWQyNTUxOSB9IGZyb20gJ0Bub2JsZS9jdXJ2ZXMvZWQyNTUxOSc7XG5pbXBvcnQgeyBFZGRzYU1QU0RrZywgRWRkc2FNUFNEc2csIE1QU0NvbW1zLCBNUFNUeXBlcywgTVBTVXRpbCB9IGZyb20gJ0BiaXRnby1iZXRhL3Nkay1saWItbXBjJztcbmltcG9ydCB7IEtleWNoYWluc1RyaXBsZXQgfSBmcm9tICcuLi8uLi8uLi9iYXNlQ29pbic7XG5pbXBvcnQge1xuICBBZGRLZXljaGFpbk9wdGlvbnMsXG4gIERlY3J5cHRlZFJldHJvZml0UGF5bG9hZCxcbiAgS2V5Y2hhaW4sXG4gIEtleVR5cGUsXG4gIFdlYmF1dGhuS2V5RW5jcnlwdGlvbkluZm8sXG59IGZyb20gJy4uLy4uLy4uL2tleWNoYWluJztcbmltcG9ydCB7IGVudlJlcXVpcmVzQml0Z29QdWJHcGdLZXlDb25maWcsIGlzQml0Z29FZGRzYU1wY3YyUHViS2V5IH0gZnJvbSAnLi4vLi4vLi4vdHNzL2JpdGdvUHViS2V5cyc7XG5pbXBvcnQgeyBnZXRCaXRnb1NpZ25hdHVyZVNoYXJlLCBnZXRUeFJlcXVlc3QsIHNlbmRTaWduYXR1cmVTaGFyZVYyLCBzZW5kVHhSZXF1ZXN0IH0gZnJvbSAnLi4vLi4vLi4vdHNzL2NvbW1vbic7XG5pbXBvcnQgeyBkZWNvZGVXaXRoQ29kZWMgfSBmcm9tICcuLi8uLi9jb2RlY3MnO1xuaW1wb3J0IHtcbiAgZ2V0U2lnbmF0dXJlU2hhcmVSb3VuZE9uZSxcbiAgZ2V0U2lnbmF0dXJlU2hhcmVSb3VuZFR3byxcbiAgZ2V0U2lnbmF0dXJlU2hhcmVSb3VuZFRocmVlLFxuICB2ZXJpZnlQZWVyTWVzc2FnZVJvdW5kT25lLFxuICB2ZXJpZnlQZWVyTWVzc2FnZVJvdW5kVHdvLFxufSBmcm9tICcuLi8uLi8uLi90c3MvZWRkc2EvZWRkc2FNUEN2Mic7XG5pbXBvcnQgeyBnZXRJbml0aWFsaXplZE1wY0luc3RhbmNlIH0gZnJvbSAnLi4vLi4vLi4vdHNzL2VkZHNhL2VkZHNhJztcbmltcG9ydCB7IGdlbmVyYXRlR1BHS2V5UGFpciB9IGZyb20gJy4uLy4uL29wZW5ncGdVdGlscyc7XG5pbXBvcnQgeyBNUEN2MlBhcnRpZXNFbnVtIH0gZnJvbSAnLi4vZWNkc2EvdHlwZXNNUEN2Mic7XG5pbXBvcnQge1xuICBDdXN0b21FZGRzYU1QQ3YyU2lnbmluZ1JvdW5kMUdlbmVyYXRpbmdGdW5jdGlvbixcbiAgQ3VzdG9tRWRkc2FNUEN2MlNpZ25pbmdSb3VuZDJHZW5lcmF0aW5nRnVuY3Rpb24sXG4gIEN1c3RvbUVkZHNhTVBDdjJTaWduaW5nUm91bmQzR2VuZXJhdGluZ0Z1bmN0aW9uLFxuICBSZXF1ZXN0VHlwZSxcbiAgU2lnbmF0dXJlU2hhcmVSZWNvcmQsXG4gIFNpZ25hdHVyZVNoYXJlVHlwZSxcbiAgVFNTUGFyYW1zLFxuICBUU1NQYXJhbXNGb3JNZXNzYWdlLFxuICBUU1NQYXJhbXNGb3JNZXNzYWdlV2l0aFBydixcbiAgVFNTUGFyYW1zV2l0aFBydixcbiAgVHhSZXF1ZXN0LFxuICBpc1YyRW52ZWxvcGUsXG59IGZyb20gJy4uL2Jhc2VUeXBlcyc7XG5pbXBvcnQgeyBFbmNyeXB0aW9uVmVyc2lvbiB9IGZyb20gJy4uLy4uLy4uLy4uL2FwaSc7XG5pbXBvcnQgeyBCaXRHb0Jhc2UgfSBmcm9tICcuLi8uLi8uLi9iaXRnb0Jhc2UnO1xuaW1wb3J0IHsgQmFzZUVkZHNhVXRpbHMgfSBmcm9tICcuL2Jhc2UnO1xuaW1wb3J0IHsgcmVzb2x2ZUVmZmVjdGl2ZVR4UGFyYW1zIH0gZnJvbSAnLi4vcmVjaXBpZW50VXRpbHMnO1xuaW1wb3J0IHsgRWRkc2FNUEN2MktleUdlblNlbmRGbiwgS2V5R2VuU2VuZGVyRm9yRW50ZXJwcmlzZSB9IGZyb20gJy4vZWRkc2FNUEN2MktleUdlblNlbmRlcic7XG5pbXBvcnQgeyBFZGRzYU1QQ3YyUmVjb3ZlcnlLZXlTaGFyZXMgfSBmcm9tICcuL3R5cGVzJztcbmltcG9ydCB7IFNpZ25pbmdNYXRlcmlhbCB9IGZyb20gJy4uLy4uLy4uL3Rzcyc7XG5cbmV4cG9ydCBjbGFzcyBFZGRzYU1QQ3YyVXRpbHMgZXh0ZW5kcyBCYXNlRWRkc2FVdGlscyB7XG4gIHByaXZhdGUgc3RhdGljIHJlYWRvbmx5IE1QU19EU0dfU0lHTklOR19VU0VSX0dQR19LRVkgPSAnTVBTX0RTR19TSUdOSU5HX1VTRVJfR1BHX0tFWSc7XG4gIHByaXZhdGUgc3RhdGljIHJlYWRvbmx5IE1QU19EU0dfU0lHTklOR19ST1VORDFfU1RBVEUgPSAnTVBTX0RTR19TSUdOSU5HX1JPVU5EMV9TVEFURSc7XG4gIHByaXZhdGUgc3RhdGljIHJlYWRvbmx5IE1QU19EU0dfU0lHTklOR19ST1VORDJfU1RBVEUgPSAnTVBTX0RTR19TSUdOSU5HX1JPVU5EMl9TVEFURSc7XG4gIHByaXZhdGUgc3RhdGljIHJlYWRvbmx5IE1QU19ES0dfS0VZR0VOX1JPVU5EMV9TVEFURSA9ICdNUFNfREtHX0tFWUdFTl9ST1VORDFfU1RBVEUnO1xuXG4gIC8qKiBAaW5oZXJpdGRvYyAqL1xuICBhc3luYyBjcmVhdGVLZXljaGFpbnMocGFyYW1zOiB7XG4gICAgcGFzc3BocmFzZTogc3RyaW5nO1xuICAgIGVudGVycHJpc2U6IHN0cmluZztcbiAgICBvcmlnaW5hbFBhc3Njb2RlRW5jcnlwdGlvbkNvZGU/OiBzdHJpbmc7XG4gICAgcmV0cm9maXQ/OiBEZWNyeXB0ZWRSZXRyb2ZpdFBheWxvYWQ7XG4gICAgd2ViYXV0aG5JbmZvPzogV2ViYXV0aG5LZXlFbmNyeXB0aW9uSW5mbztcbiAgICBlbmNyeXB0aW9uVmVyc2lvbj86IEVuY3J5cHRpb25WZXJzaW9uO1xuICAgIC8vIFdhbGxldCBTYWZlcyB2MSAoQGV4cGVyaW1lbnRhbCk6IHRhZ3MgdGhlIHJlc3VsdGluZyB1c2VyL2JhY2t1cC9iaXRnbyByb290IGtleXMgd2l0aCB0aGlzIHNhZmUuXG4gICAgc2FmZUlkPzogc3RyaW5nO1xuICB9KTogUHJvbWlzZTxLZXljaGFpbnNUcmlwbGV0PiB7XG4gICAgY29uc3QgdXNlcktleVBhaXIgPSBhd2FpdCBnZW5lcmF0ZUdQR0tleVBhaXIoJ2VkMjU1MTknKTtcbiAgICBjb25zdCB1c2VyR3BnS2V5ID0gYXdhaXQgcGdwLnJlYWRQcml2YXRlS2V5KHsgYXJtb3JlZEtleTogdXNlcktleVBhaXIucHJpdmF0ZUtleSB9KTtcbiAgICBjb25zdCB1c2VyR3BnUHVibGljS2V5ID0gdXNlcktleVBhaXIucHVibGljS2V5O1xuICAgIGNvbnN0IFt1c2VyUGssIHVzZXJTa10gPSBhd2FpdCBNUFNDb21tcy5leHRyYWN0RWQyNTUxOUtleVBhaXIodXNlckdwZ0tleSk7XG5cbiAgICBjb25zdCBiYWNrdXBLZXlQYWlyID0gYXdhaXQgZ2VuZXJhdGVHUEdLZXlQYWlyKCdlZDI1NTE5Jyk7XG4gICAgY29uc3QgYmFja3VwR3BnS2V5ID0gYXdhaXQgcGdwLnJlYWRQcml2YXRlS2V5KHsgYXJtb3JlZEtleTogYmFja3VwS2V5UGFpci5wcml2YXRlS2V5IH0pO1xuICAgIGNvbnN0IGJhY2t1cEdwZ1B1YmxpY0tleSA9IGJhY2t1cEtleVBhaXIucHVibGljS2V5O1xuICAgIGNvbnN0IFtiYWNrdXBQaywgYmFja3VwU2tdID0gYXdhaXQgTVBTQ29tbXMuZXh0cmFjdEVkMjU1MTlLZXlQYWlyKGJhY2t1cEdwZ0tleSk7XG5cbiAgICAvLyBHZXQgdGhlIEJpdEdvIEVkRFNBIE1QQ3YyIHB1YmxpYyBrZXkgKGVkMjU1MTkpLiBVc2luZyB0aGUgZGVmYXVsdCBtcGN2MlB1YmxpY0tleSAoc2VjcDI1NmsxKVxuICAgIC8vIGhlcmUgd291bGQgY2F1c2UgYSBXQVNNIFwiSW52YWxpZCBJbnB1dFwiIGVycm9yLCBzbyB3ZSByZXF1aXJlIHRoZSBkZWRpY2F0ZWQgZWRkc2FNcGN2MlB1YmxpY0tleS5cbiAgICBjb25zdCB7IGVkZHNhTXBjdjJQdWJsaWNLZXkgfSA9IGF3YWl0IHRoaXMuZ2V0Qml0Z29HcGdQdWJrZXlCYXNlZE9uRmVhdHVyZUZsYWdzKHBhcmFtcy5lbnRlcnByaXNlLCB0cnVlKTtcbiAgICBjb25zdCBiaXRnb1B1YmxpY0dwZ0tleSA9IGVkZHNhTXBjdjJQdWJsaWNLZXkgPz8gdGhpcy5iaXRnb0VkZHNhTXBjdjJQdWJsaWNHcGdLZXk7XG4gICAgYXNzZXJ0KGJpdGdvUHVibGljR3BnS2V5LCAnRmFpbGVkIHRvIGdldCBCaXRHbyBFZERTQSBNUEN2MiBHUEcgcHVibGljIGtleScpO1xuICAgIGNvbnN0IGJpdGdvUHVibGljR3BnS2V5QXJtb3JlZCA9IGJpdGdvUHVibGljR3BnS2V5LmFybW9yKCk7XG5cbiAgICBpZiAoZW52UmVxdWlyZXNCaXRnb1B1YkdwZ0tleUNvbmZpZyh0aGlzLmJpdGdvLmdldEVudigpKSkge1xuICAgICAgYXNzZXJ0KGlzQml0Z29FZGRzYU1wY3YyUHViS2V5KGJpdGdvUHVibGljR3BnS2V5QXJtb3JlZCksICdJbnZhbGlkIEJpdEdvIEdQRyBwdWJsaWMga2V5Jyk7XG4gICAgfVxuXG4gICAgY29uc3QgYml0Z29LZXlPYmogPSBhd2FpdCBwZ3AucmVhZEtleSh7IGFybW9yZWRLZXk6IGJpdGdvUHVibGljR3BnS2V5QXJtb3JlZCB9KTtcbiAgICBjb25zdCBiaXRnb1BrID0gYXdhaXQgTVBTQ29tbXMuZXh0cmFjdEVkMjU1MTlQdWJsaWNLZXkoYml0Z29LZXlPYmopO1xuXG4gICAgLy8gQ3JlYXRlIERLRyBzZXNzaW9ucyBmb3IgdXNlciAocGFydHkgMCkgYW5kIGJhY2t1cCAocGFydHkgMSlcbiAgICBjb25zdCB7IHVzZXJEa2csIGJhY2t1cERrZyB9ID0gYXdhaXQgdGhpcy5nZXRVc2VyQW5kQmFja3VwU2Vzc2lvbihwYXJhbXMucmV0cm9maXQpO1xuXG4gICAgLy8gI3JlZ2lvbiByb3VuZCAxXG4gICAgYXdhaXQgdXNlckRrZy5pbml0RGtnKHVzZXJTaywgW2JhY2t1cFBrLCBiaXRnb1BrXSk7XG4gICAgYXdhaXQgYmFja3VwRGtnLmluaXREa2coYmFja3VwU2ssIFt1c2VyUGssIGJpdGdvUGtdKTtcblxuICAgIGNvbnN0IHVzZXJNc2cxID0gdXNlckRrZy5nZXRGaXJzdE1lc3NhZ2UoKTtcbiAgICBjb25zdCBiYWNrdXBNc2cxID0gYmFja3VwRGtnLmdldEZpcnN0TWVzc2FnZSgpO1xuXG4gICAgY29uc3QgdXNlclNpZ25lZE1zZzEgPSBhd2FpdCBNUFNDb21tcy5kZXRhY2hTaWduTXBzTWVzc2FnZShCdWZmZXIuZnJvbSh1c2VyTXNnMS5wYXlsb2FkKSwgdXNlckdwZ0tleSk7XG4gICAgY29uc3QgYmFja3VwU2lnbmVkTXNnMSA9IGF3YWl0IE1QU0NvbW1zLmRldGFjaFNpZ25NcHNNZXNzYWdlKEJ1ZmZlci5mcm9tKGJhY2t1cE1zZzEucGF5bG9hZCksIGJhY2t1cEdwZ0tleSk7XG5cbiAgICBhc3NlcnQoTm9uRW1wdHlTdHJpbmcuaXModXNlckdwZ1B1YmxpY0tleSksICdVc2VyIEdQRyBwdWJsaWMga2V5IGlzIHJlcXVpcmVkJyk7XG4gICAgYXNzZXJ0KE5vbkVtcHR5U3RyaW5nLmlzKGJhY2t1cEdwZ1B1YmxpY0tleSksICdCYWNrdXAgR1BHIHB1YmxpYyBrZXkgaXMgcmVxdWlyZWQnKTtcblxuICAgIGNvbnN0IHsgc2Vzc2lvbklkLCBiaXRnb01zZzEgfSA9IGF3YWl0IHRoaXMuc2VuZEtleUdlbmVyYXRpb25Sb3VuZDEoXG4gICAgICBwYXJhbXMuZW50ZXJwcmlzZSxcbiAgICAgIHtcbiAgICAgICAgdXNlckdwZ1B1YmxpY0tleSxcbiAgICAgICAgYmFja3VwR3BnUHVibGljS2V5LFxuICAgICAgICB1c2VyTXNnMTogdXNlclNpZ25lZE1zZzEsXG4gICAgICAgIGJhY2t1cE1zZzE6IGJhY2t1cFNpZ25lZE1zZzEsXG4gICAgICAgIC4uLihwYXJhbXMucmV0cm9maXQ/LndhbGxldElkID8geyB3YWxsZXRJZDogcGFyYW1zLnJldHJvZml0LndhbGxldElkIH0gOiB7fSksXG4gICAgICB9LFxuICAgICAgcGFyYW1zLnNhZmVJZFxuICAgICk7XG4gICAgLy8gI2VuZHJlZ2lvblxuXG4gICAgLy8gI3JlZ2lvbiByb3VuZCAyXG4gICAgY29uc3QgYml0Z29SYXdNc2cxQnl0ZXMgPSBhd2FpdCBNUFNDb21tcy52ZXJpZnlNcHNNZXNzYWdlKGJpdGdvTXNnMSwgYml0Z29LZXlPYmopO1xuICAgIGNvbnN0IGJpdGdvRGVzZXJpYWxpemVkTXNnMTogTVBTVHlwZXMuRGVzZXJpYWxpemVkTWVzc2FnZSA9IHtcbiAgICAgIGZyb206IE1QQ3YyUGFydGllc0VudW0uQklUR08sXG4gICAgICBwYXlsb2FkOiBuZXcgVWludDhBcnJheShiaXRnb1Jhd01zZzFCeXRlcyksXG4gICAgfTtcblxuICAgIGNvbnN0IHJvdW5kMU1lc3NhZ2VzOiBNUFNUeXBlcy5EZXNlcmlhbGl6ZWRNZXNzYWdlcyA9IFt1c2VyTXNnMSwgYmFja3VwTXNnMSwgYml0Z29EZXNlcmlhbGl6ZWRNc2cxXTtcblxuICAgIGNvbnN0IHVzZXJSb3VuZDJNc2dzID0gdXNlckRrZy5oYW5kbGVJbmNvbWluZ01lc3NhZ2VzKHJvdW5kMU1lc3NhZ2VzKTtcbiAgICBjb25zdCBiYWNrdXBSb3VuZDJNc2dzID0gYmFja3VwRGtnLmhhbmRsZUluY29taW5nTWVzc2FnZXMocm91bmQxTWVzc2FnZXMpO1xuXG4gICAgYXNzZXJ0KHVzZXJSb3VuZDJNc2dzLmxlbmd0aCA9PT0gMSwgJ1VzZXIgcm91bmQgMSBzaG91bGQgcHJvZHVjZSBleGFjdGx5IG9uZSByb3VuZCAyIG1lc3NhZ2UnKTtcbiAgICBhc3NlcnQoYmFja3VwUm91bmQyTXNncy5sZW5ndGggPT09IDEsICdCYWNrdXAgcm91bmQgMSBzaG91bGQgcHJvZHVjZSBleGFjdGx5IG9uZSByb3VuZCAyIG1lc3NhZ2UnKTtcblxuICAgIGNvbnN0IHVzZXJNc2cyID0gdXNlclJvdW5kMk1zZ3NbMF07XG4gICAgY29uc3QgYmFja3VwTXNnMiA9IGJhY2t1cFJvdW5kMk1zZ3NbMF07XG5cbiAgICBjb25zdCB1c2VyU2lnbmVkTXNnMiA9IGF3YWl0IE1QU0NvbW1zLmRldGFjaFNpZ25NcHNNZXNzYWdlKEJ1ZmZlci5mcm9tKHVzZXJNc2cyLnBheWxvYWQpLCB1c2VyR3BnS2V5KTtcbiAgICBjb25zdCBiYWNrdXBTaWduZWRNc2cyID0gYXdhaXQgTVBTQ29tbXMuZGV0YWNoU2lnbk1wc01lc3NhZ2UoQnVmZmVyLmZyb20oYmFja3VwTXNnMi5wYXlsb2FkKSwgYmFja3VwR3BnS2V5KTtcblxuICAgIGNvbnN0IHtcbiAgICAgIHNlc3Npb25JZDogc2Vzc2lvbklkUm91bmQyLFxuICAgICAgY29tbW9uUHVibGljS2V5Y2hhaW4sXG4gICAgICBiaXRnb01zZzIsXG4gICAgfSA9IGF3YWl0IHRoaXMuc2VuZEtleUdlbmVyYXRpb25Sb3VuZDIocGFyYW1zLmVudGVycHJpc2UsIHtcbiAgICAgIHNlc3Npb25JZCxcbiAgICAgIHVzZXJNc2cyOiB1c2VyU2lnbmVkTXNnMixcbiAgICAgIGJhY2t1cE1zZzI6IGJhY2t1cFNpZ25lZE1zZzIsXG4gICAgfSk7XG4gICAgLy8gI2VuZHJlZ2lvblxuXG4gICAgLy8gI3JlZ2lvbiBrZXljaGFpbiBjcmVhdGlvblxuICAgIGFzc2VydC5lcXVhbChzZXNzaW9uSWQsIHNlc3Npb25JZFJvdW5kMiwgJ1JvdW5kIDEgYW5kIHJvdW5kIDIgc2Vzc2lvbiBJRHMgZG8gbm90IG1hdGNoJyk7XG5cbiAgICBjb25zdCBiaXRnb1Jhd01zZzJCeXRlcyA9IGF3YWl0IE1QU0NvbW1zLnZlcmlmeU1wc01lc3NhZ2UoYml0Z29Nc2cyLCBiaXRnb0tleU9iaik7XG4gICAgY29uc3QgYml0Z29EZXNlcmlhbGl6ZWRNc2cyOiBNUFNUeXBlcy5EZXNlcmlhbGl6ZWRNZXNzYWdlID0ge1xuICAgICAgZnJvbTogTVBDdjJQYXJ0aWVzRW51bS5CSVRHTyxcbiAgICAgIHBheWxvYWQ6IG5ldyBVaW50OEFycmF5KGJpdGdvUmF3TXNnMkJ5dGVzKSxcbiAgICB9O1xuXG4gICAgY29uc3Qgcm91bmQyTWVzc2FnZXM6IE1QU1R5cGVzLkRlc2VyaWFsaXplZE1lc3NhZ2VzID0gW3VzZXJNc2cyLCBiYWNrdXBNc2cyLCBiaXRnb0Rlc2VyaWFsaXplZE1zZzJdO1xuXG4gICAgY29uc3QgdXNlckZpbmFsTXNncyA9IHVzZXJEa2cuaGFuZGxlSW5jb21pbmdNZXNzYWdlcyhyb3VuZDJNZXNzYWdlcyk7XG4gICAgY29uc3QgYmFja3VwRmluYWxNc2dzID0gYmFja3VwRGtnLmhhbmRsZUluY29taW5nTWVzc2FnZXMocm91bmQyTWVzc2FnZXMpO1xuXG4gICAgYXNzZXJ0KHVzZXJGaW5hbE1zZ3MubGVuZ3RoID09PSAwLCAnV0FTTSByb3VuZCAyIHNob3VsZCBwcm9kdWNlIG5vIG91dHB1dCBtZXNzYWdlcyBmb3IgdXNlcicpO1xuICAgIGFzc2VydChiYWNrdXBGaW5hbE1zZ3MubGVuZ3RoID09PSAwLCAnV0FTTSByb3VuZCAyIHNob3VsZCBwcm9kdWNlIG5vIG91dHB1dCBtZXNzYWdlcyBmb3IgYmFja3VwJyk7XG5cbiAgICBjb25zdCB1c2VyQ29tbW9uS2V5Y2hhaW4gPSB1c2VyRGtnLmdldENvbW1vbktleWNoYWluKCk7XG4gICAgY29uc3QgYmFja3VwQ29tbW9uS2V5Y2hhaW4gPSBiYWNrdXBEa2cuZ2V0Q29tbW9uS2V5Y2hhaW4oKTtcblxuICAgIGFzc2VydC5lcXVhbChcbiAgICAgIHVzZXJDb21tb25LZXljaGFpbixcbiAgICAgIGNvbW1vblB1YmxpY0tleWNoYWluLFxuICAgICAgJ1VzZXIgY29tcHV0ZWQga2V5Y2hhaW4gZG9lcyBub3QgbWF0Y2ggQml0R28gY29tbW9uIGtleWNoYWluJ1xuICAgICk7XG4gICAgYXNzZXJ0LmVxdWFsKFxuICAgICAgYmFja3VwQ29tbW9uS2V5Y2hhaW4sXG4gICAgICBjb21tb25QdWJsaWNLZXljaGFpbixcbiAgICAgICdCYWNrdXAgY29tcHV0ZWQga2V5Y2hhaW4gZG9lcyBub3QgbWF0Y2ggQml0R28gY29tbW9uIGtleWNoYWluJ1xuICAgICk7XG5cbiAgICBjb25zdCB1c2VyUHJpdmF0ZU1hdGVyaWFsID0gdXNlckRrZy5nZXRLZXlTaGFyZSgpO1xuICAgIGNvbnN0IGJhY2t1cFByaXZhdGVNYXRlcmlhbCA9IGJhY2t1cERrZy5nZXRLZXlTaGFyZSgpO1xuICAgIGNvbnN0IHVzZXJSZWR1Y2VkUHJpdmF0ZU1hdGVyaWFsID0gdXNlckRrZy5nZXRSZWR1Y2VkS2V5U2hhcmUoKTtcbiAgICBjb25zdCBiYWNrdXBSZWR1Y2VkUHJpdmF0ZU1hdGVyaWFsID0gYmFja3VwRGtnLmdldFJlZHVjZWRLZXlTaGFyZSgpO1xuXG4gICAgY29uc3QgdXNlcktleWNoYWluUHJvbWlzZSA9IHRoaXMuYWRkVXNlcktleWNoYWluKFxuICAgICAgdXNlckNvbW1vbktleWNoYWluLFxuICAgICAgdXNlclByaXZhdGVNYXRlcmlhbCxcbiAgICAgIHVzZXJSZWR1Y2VkUHJpdmF0ZU1hdGVyaWFsLFxuICAgICAgcGFyYW1zLnBhc3NwaHJhc2UsXG4gICAgICBwYXJhbXMub3JpZ2luYWxQYXNzY29kZUVuY3J5cHRpb25Db2RlLFxuICAgICAgcGFyYW1zLndlYmF1dGhuSW5mbyxcbiAgICAgIHBhcmFtcy5lbmNyeXB0aW9uVmVyc2lvbixcbiAgICAgIHBhcmFtcy5lbnRlcnByaXNlLFxuICAgICAgcGFyYW1zLnNhZmVJZFxuICAgICk7XG4gICAgY29uc3QgYmFja3VwS2V5Y2hhaW5Qcm9taXNlID0gdGhpcy5hZGRCYWNrdXBLZXljaGFpbihcbiAgICAgIGJhY2t1cENvbW1vbktleWNoYWluLFxuICAgICAgYmFja3VwUHJpdmF0ZU1hdGVyaWFsLFxuICAgICAgYmFja3VwUmVkdWNlZFByaXZhdGVNYXRlcmlhbCxcbiAgICAgIHBhcmFtcy5wYXNzcGhyYXNlLFxuICAgICAgcGFyYW1zLm9yaWdpbmFsUGFzc2NvZGVFbmNyeXB0aW9uQ29kZSxcbiAgICAgIHBhcmFtcy5lbmNyeXB0aW9uVmVyc2lvbixcbiAgICAgIHBhcmFtcy5zYWZlSWRcbiAgICApO1xuICAgIGNvbnN0IGJpdGdvS2V5Y2hhaW5Qcm9taXNlID0gdGhpcy5hZGRCaXRnb0tleWNoYWluKHVzZXJDb21tb25LZXljaGFpbiwgcGFyYW1zLnNhZmVJZCk7XG5cbiAgICBjb25zdCBbdXNlcktleWNoYWluLCBiYWNrdXBLZXljaGFpbiwgYml0Z29LZXljaGFpbl0gPSBhd2FpdCBQcm9taXNlLmFsbChbXG4gICAgICB1c2VyS2V5Y2hhaW5Qcm9taXNlLFxuICAgICAgYmFja3VwS2V5Y2hhaW5Qcm9taXNlLFxuICAgICAgYml0Z29LZXljaGFpblByb21pc2UsXG4gICAgXSk7XG4gICAgLy8gI2VuZHJlZ2lvblxuXG4gICAgcmV0dXJuIHtcbiAgICAgIHVzZXJLZXljaGFpbixcbiAgICAgIGJhY2t1cEtleWNoYWluLFxuICAgICAgYml0Z29LZXljaGFpbixcbiAgICB9O1xuICB9XG5cbiAgYXN5bmMgY3JlYXRlS2V5Y2hhaW5zV2l0aEV4dGVybmFsU2lnbmVyKHBhcmFtczoge1xuICAgIGVudGVycHJpc2U6IHN0cmluZztcbiAgICBjYWxsYmFja3M6IEVkZHNhTVBDdjJLZXlHZW5DYWxsYmFja3M7XG4gIH0pOiBQcm9taXNlPEtleWNoYWluc1RyaXBsZXQ+IHtcbiAgICBjb25zdCB7IGVudGVycHJpc2UsIGNhbGxiYWNrcyB9ID0gcGFyYW1zO1xuXG4gICAgY29uc3QgeyBlZGRzYU1wY3YyUHVibGljS2V5IH0gPSBhd2FpdCB0aGlzLmdldEJpdGdvR3BnUHVia2V5QmFzZWRPbkZlYXR1cmVGbGFncyhlbnRlcnByaXNlLCB0cnVlKTtcbiAgICBjb25zdCBiaXRnb1B1YmxpY0dwZ0tleSA9IGVkZHNhTXBjdjJQdWJsaWNLZXkgPz8gdGhpcy5iaXRnb0VkZHNhTXBjdjJQdWJsaWNHcGdLZXk7XG4gICAgYXNzZXJ0KGJpdGdvUHVibGljR3BnS2V5LCAnRmFpbGVkIHRvIGdldCBCaXRHbyBFZERTQSBNUEN2MiBHUEcgcHVibGljIGtleScpO1xuICAgIGNvbnN0IGJpdGdvUHVibGljR3BnS2V5QXJtb3JlZCA9IGJpdGdvUHVibGljR3BnS2V5LmFybW9yKCk7XG5cbiAgICBpZiAoZW52UmVxdWlyZXNCaXRnb1B1YkdwZ0tleUNvbmZpZyh0aGlzLmJpdGdvLmdldEVudigpKSkge1xuICAgICAgYXNzZXJ0KGlzQml0Z29FZGRzYU1wY3YyUHViS2V5KGJpdGdvUHVibGljR3BnS2V5QXJtb3JlZCksICdJbnZhbGlkIEJpdEdvIEVkRFNBIE1QQ3YyIEdQRyBwdWJsaWMga2V5Jyk7XG4gICAgfVxuXG4gICAgLy8gUm91bmQgMDogYm90aCBwYXJ0aWVzIGdlbmVyYXRlIEdQRyBrZXlzXG4gICAgY29uc3QgeyB1c2VyR3BnUHVibGljS2V5LCBiYWNrdXBHcGdQdWJsaWNLZXksIHVzZXJTdGF0ZSwgYmFja3VwU3RhdGUgfSA9IGF3YWl0IGNhbGxiYWNrcy5pbml0aWFsaXplQ2FsbGJhY2soe1xuICAgICAgZW50ZXJwcmlzZSxcbiAgICAgIGJpdGdvUHVibGljR3BnS2V5OiBiaXRnb1B1YmxpY0dwZ0tleUFybW9yZWQsXG4gICAgfSk7XG5cbiAgICBhc3NlcnQoTm9uRW1wdHlTdHJpbmcuaXModXNlckdwZ1B1YmxpY0tleSksICdVc2VyIEdQRyBwdWJsaWMga2V5IGlzIHJlcXVpcmVkJyk7XG4gICAgYXNzZXJ0KE5vbkVtcHR5U3RyaW5nLmlzKGJhY2t1cEdwZ1B1YmxpY0tleSksICdCYWNrdXAgR1BHIHB1YmxpYyBrZXkgaXMgcmVxdWlyZWQnKTtcblxuICAgIC8vIFJvdW5kIDE6IGJvdGggcGFydGllcyBydW4gREtHIHJvdW5kIDFcbiAgICBjb25zdCB7XG4gICAgICB1c2VyU2lnbmVkTXNnMSxcbiAgICAgIGJhY2t1cFNpZ25lZE1zZzEsXG4gICAgICB1c2VyU3RhdGU6IHVzZXJTdGF0ZUFmdGVyMSxcbiAgICAgIGJhY2t1cFN0YXRlOiBiYWNrdXBTdGF0ZUFmdGVyMSxcbiAgICB9ID0gYXdhaXQgY2FsbGJhY2tzLnJvdW5kMUNhbGxiYWNrKHtcbiAgICAgIGJpdGdvUHVibGljR3BnS2V5OiBiaXRnb1B1YmxpY0dwZ0tleUFybW9yZWQsXG4gICAgICB1c2VyR3BnUHVibGljS2V5LFxuICAgICAgYmFja3VwR3BnUHVibGljS2V5LFxuICAgICAgdXNlclN0YXRlLFxuICAgICAgYmFja3VwU3RhdGUsXG4gICAgfSk7XG5cbiAgICBjb25zdCB7IHNlc3Npb25JZCwgYml0Z29Nc2cxIH0gPSBhd2FpdCB0aGlzLnNlbmRLZXlHZW5lcmF0aW9uUm91bmQxKGVudGVycHJpc2UsIHtcbiAgICAgIHVzZXJHcGdQdWJsaWNLZXksXG4gICAgICBiYWNrdXBHcGdQdWJsaWNLZXksXG4gICAgICB1c2VyTXNnMTogdXNlclNpZ25lZE1zZzEsXG4gICAgICBiYWNrdXBNc2cxOiBiYWNrdXBTaWduZWRNc2cxLFxuICAgIH0pO1xuXG4gICAgLy8gUm91bmQgMjogYm90aCBwYXJ0aWVzIHJ1biBES0cgcm91bmQgMlxuICAgIGNvbnN0IHtcbiAgICAgIHVzZXJTaWduZWRNc2cyLFxuICAgICAgYmFja3VwU2lnbmVkTXNnMixcbiAgICAgIHVzZXJTdGF0ZTogdXNlclN0YXRlQWZ0ZXIyLFxuICAgICAgYmFja3VwU3RhdGU6IGJhY2t1cFN0YXRlQWZ0ZXIyLFxuICAgIH0gPSBhd2FpdCBjYWxsYmFja3Mucm91bmQyQ2FsbGJhY2soe1xuICAgICAgYml0Z29Nc2cxLFxuICAgICAgdXNlclNpZ25lZE1zZzEsXG4gICAgICBiYWNrdXBTaWduZWRNc2cxLFxuICAgICAgdXNlclN0YXRlOiB1c2VyU3RhdGVBZnRlcjEsXG4gICAgICBiYWNrdXBTdGF0ZTogYmFja3VwU3RhdGVBZnRlcjEsXG4gICAgfSk7XG5cbiAgICBjb25zdCB7XG4gICAgICBzZXNzaW9uSWQ6IHNlc3Npb25JZFJvdW5kMixcbiAgICAgIGNvbW1vblB1YmxpY0tleWNoYWluOiBiaXRnb0NvbW1vbktleWNoYWluLFxuICAgICAgYml0Z29Nc2cyLFxuICAgIH0gPSBhd2FpdCB0aGlzLnNlbmRLZXlHZW5lcmF0aW9uUm91bmQyKGVudGVycHJpc2UsIHtcbiAgICAgIHNlc3Npb25JZCxcbiAgICAgIHVzZXJNc2cyOiB1c2VyU2lnbmVkTXNnMixcbiAgICAgIGJhY2t1cE1zZzI6IGJhY2t1cFNpZ25lZE1zZzIsXG4gICAgfSk7XG4gICAgYXNzZXJ0LnN0cmljdEVxdWFsKHNlc3Npb25JZCwgc2Vzc2lvbklkUm91bmQyLCAnUm91bmQgMSBhbmQgcm91bmQgMiBzZXNzaW9uIElEcyBkbyBub3QgbWF0Y2gnKTtcblxuICAgIC8vIEZpbmFsaXplOiBib3RoIHBhcnRpZXMgdmVyaWZ5IGFuZCBkZXJpdmUgdGhlIGNvbW1vbiBrZXljaGFpblxuICAgIGNvbnN0IHsgY29tbW9uS2V5Y2hhaW4gfSA9IGF3YWl0IGNhbGxiYWNrcy5maW5hbGl6ZUNhbGxiYWNrKHtcbiAgICAgIGJpdGdvTXNnMixcbiAgICAgIGJpdGdvQ29tbW9uS2V5Y2hhaW4sXG4gICAgICB1c2VyU3RhdGU6IHVzZXJTdGF0ZUFmdGVyMixcbiAgICAgIGJhY2t1cFN0YXRlOiBiYWNrdXBTdGF0ZUFmdGVyMixcbiAgICB9KTtcbiAgICBhc3NlcnQuc3RyaWN0RXF1YWwoY29tbW9uS2V5Y2hhaW4sIGJpdGdvQ29tbW9uS2V5Y2hhaW4sICdDb21tb24ga2V5Y2hhaW5zIGRvIG5vdCBtYXRjaCcpO1xuXG4gICAgY29uc3Qga2V5Y2hhaW5zID0gdGhpcy5iYXNlQ29pbi5rZXljaGFpbnMoKTtcbiAgICBjb25zdCBbdXNlcktleWNoYWluLCBiYWNrdXBLZXljaGFpbiwgYml0Z29LZXljaGFpbl0gPSBhd2FpdCBQcm9taXNlLmFsbChbXG4gICAgICBrZXljaGFpbnMuYWRkKHsgc291cmNlOiAndXNlcicsIGtleVR5cGU6ICd0c3MnIGFzIEtleVR5cGUsIGNvbW1vbktleWNoYWluLCBpc01QQ3YyOiB0cnVlIH0pLFxuICAgICAga2V5Y2hhaW5zLmFkZCh7IHNvdXJjZTogJ2JhY2t1cCcsIGtleVR5cGU6ICd0c3MnIGFzIEtleVR5cGUsIGNvbW1vbktleWNoYWluLCBpc01QQ3YyOiB0cnVlIH0pLFxuICAgICAgdGhpcy5hZGRCaXRnb0tleWNoYWluKGNvbW1vbktleWNoYWluKSxcbiAgICBdKTtcblxuICAgIHJldHVybiB7IHVzZXJLZXljaGFpbiwgYmFja3VwS2V5Y2hhaW4sIGJpdGdvS2V5Y2hhaW4gfTtcbiAgfVxuXG4gIC8vICNyZWdpb24ga2V5Y2hhaW4gdXRpbHNcbiAgYXN5bmMgY3JlYXRlUGFydGljaXBhbnRLZXljaGFpbihcbiAgICBwYXJ0aWNpcGFudEluZGV4OiBNUEN2MlBhcnR5RnJvbVN0cmluZ09yTnVtYmVyLFxuICAgIGNvbW1vbktleWNoYWluOiBzdHJpbmcsXG4gICAgcHJpdmF0ZU1hdGVyaWFsPzogQnVmZmVyLFxuICAgIHJlZHVjZWRQcml2YXRlTWF0ZXJpYWw/OiBCdWZmZXIsXG4gICAgcGFzc3BocmFzZT86IHN0cmluZyxcbiAgICBvcmlnaW5hbFBhc3Njb2RlRW5jcnlwdGlvbkNvZGU/OiBzdHJpbmcsXG4gICAgd2ViYXV0aG5JbmZvPzogV2ViYXV0aG5LZXlFbmNyeXB0aW9uSW5mbyxcbiAgICBlbmNyeXB0aW9uVmVyc2lvbj86IEVuY3J5cHRpb25WZXJzaW9uLFxuICAgIGVudGVycHJpc2U/OiBzdHJpbmcsXG4gICAgc2FmZUlkPzogc3RyaW5nXG4gICk6IFByb21pc2U8S2V5Y2hhaW4+IHtcbiAgICBsZXQgc291cmNlOiBzdHJpbmc7XG4gICAgbGV0IGVuY3J5cHRlZFBydjogc3RyaW5nIHwgdW5kZWZpbmVkID0gdW5kZWZpbmVkO1xuICAgIGxldCByZWR1Y2VkRW5jcnlwdGVkUHJ2OiBzdHJpbmcgfCB1bmRlZmluZWQgPSB1bmRlZmluZWQ7XG4gICAgbGV0IHByaXZhdGVNYXRlcmlhbEJhc2U2NDogc3RyaW5nIHwgdW5kZWZpbmVkID0gdW5kZWZpbmVkO1xuXG4gICAgc3dpdGNoIChwYXJ0aWNpcGFudEluZGV4KSB7XG4gICAgICBjYXNlIE1QQ3YyUGFydGllc0VudW0uVVNFUjpcbiAgICAgIGNhc2UgTVBDdjJQYXJ0aWVzRW51bS5CQUNLVVA6XG4gICAgICAgIHNvdXJjZSA9IHBhcnRpY2lwYW50SW5kZXggPT09IE1QQ3YyUGFydGllc0VudW0uVVNFUiA/ICd1c2VyJyA6ICdiYWNrdXAnO1xuICAgICAgICBhc3NlcnQocHJpdmF0ZU1hdGVyaWFsLCBgUHJpdmF0ZSBtYXRlcmlhbCBpcyByZXF1aXJlZCBmb3IgJHtzb3VyY2V9IGtleWNoYWluYCk7XG4gICAgICAgIGFzc2VydChyZWR1Y2VkUHJpdmF0ZU1hdGVyaWFsLCBgUmVkdWNlZCBwcml2YXRlIG1hdGVyaWFsIGlzIHJlcXVpcmVkIGZvciAke3NvdXJjZX0ga2V5Y2hhaW5gKTtcbiAgICAgICAgYXNzZXJ0KHBhc3NwaHJhc2UsIGBQYXNzcGhyYXNlIGlzIHJlcXVpcmVkIGZvciAke3NvdXJjZX0ga2V5Y2hhaW5gKTtcbiAgICAgICAgcHJpdmF0ZU1hdGVyaWFsQmFzZTY0ID0gcHJpdmF0ZU1hdGVyaWFsLnRvU3RyaW5nKCdiYXNlNjQnKTtcbiAgICAgICAgZW5jcnlwdGVkUHJ2ID0gYXdhaXQgdGhpcy5iaXRnby5lbmNyeXB0KHtcbiAgICAgICAgICBpbnB1dDogcHJpdmF0ZU1hdGVyaWFsQmFzZTY0LFxuICAgICAgICAgIHBhc3N3b3JkOiBwYXNzcGhyYXNlLFxuICAgICAgICAgIGVuY3J5cHRpb25WZXJzaW9uLFxuICAgICAgICB9KTtcbiAgICAgICAgLy8gRW5jcnlwdHMgdGhlIENCT1ItZW5jb2RlZCBSZWR1Y2VkS2V5U2hhcmUgKHdoaWNoIGNvbnRhaW5zIHRoZSBwYXJ0eSdzIHB1YmxpY1xuICAgICAgICAvLyBrZXkpIHdpdGggdGhlIHdhbGxldCBwYXNzcGhyYXNlLiBUaGUgcmVzdWx0IGlzIHN0b3JlZCBhcyByZWR1Y2VkRW5jcnlwdGVkUHJ2XG4gICAgICAgIC8vIG9uIHRoZSBrZXkgY2FyZCBRUiBjb2RlIGFuZCByZXByZXNlbnRzIGEgc2Vjb25kIGNvcHkgb2Yga2V5IG1hdGVyaWFsXG4gICAgICAgIC8vIGJleW9uZCB0aGUgc2VydmVyLXN0b3JlZCBlbmNyeXB0ZWRQcnYuXG4gICAgICAgIHJlZHVjZWRFbmNyeXB0ZWRQcnYgPSBhd2FpdCB0aGlzLmJpdGdvLmVuY3J5cHQoe1xuICAgICAgICAgIC8vIEJ1ZmZlci50b1N0cmluZygnYmFzZTY0JykgY2FuIG5vdCBiZSB1c2VkIGhlcmUgYXMgaXQgZG9lcyBub3Qgd29yayBvbiB0aGUgYnJvd3Nlci5cbiAgICAgICAgICAvLyBUaGUgYnJvd3NlciBkZWFscyB3aXRoIGEgQnVmZmVyIGFzIFVpbnQ4QXJyYXksIHRoZXJlZm9yZSBpbiB0aGUgYnJvd3NlciAudG9TdHJpbmcoJ2Jhc2U2NCcpIGp1c3QgY3JlYXRlcyBhIGNvbW1hIHNlcGFyYXRlZCBzdHJpbmcgb2YgdGhlIGFycmF5IHZhbHVlcy5cbiAgICAgICAgICBpbnB1dDogYnRvYShTdHJpbmcuZnJvbUNoYXJDb2RlLmFwcGx5KG51bGwsIEFycmF5LmZyb20obmV3IFVpbnQ4QXJyYXkocmVkdWNlZFByaXZhdGVNYXRlcmlhbCkpKSksXG4gICAgICAgICAgcGFzc3dvcmQ6IHBhc3NwaHJhc2UsXG4gICAgICAgICAgZW5jcnlwdGlvblZlcnNpb24sXG4gICAgICAgIH0pO1xuICAgICAgICBicmVhaztcbiAgICAgIGNhc2UgTVBDdjJQYXJ0aWVzRW51bS5CSVRHTzpcbiAgICAgICAgc291cmNlID0gJ2JpdGdvJztcbiAgICAgICAgYnJlYWs7XG4gICAgICBkZWZhdWx0OlxuICAgICAgICB0aHJvdyBuZXcgRXJyb3IoJ0ludmFsaWQgcGFydGljaXBhbnQgaW5kZXgnKTtcbiAgICB9XG5cbiAgICBjb25zdCBrZXljaGFpblBhcmFtczogQWRkS2V5Y2hhaW5PcHRpb25zID0ge1xuICAgICAgc291cmNlLFxuICAgICAga2V5VHlwZTogJ3RzcycgYXMgS2V5VHlwZSxcbiAgICAgIGNvbW1vbktleWNoYWluLFxuICAgICAgZW5jcnlwdGVkUHJ2LFxuICAgICAgb3JpZ2luYWxQYXNzY29kZUVuY3J5cHRpb25Db2RlLFxuICAgICAgaXNNUEN2MjogdHJ1ZSxcbiAgICAgIHNhZmVJZCxcbiAgICB9O1xuXG4gICAgaWYgKHdlYmF1dGhuSW5mbyAmJiBwYXJ0aWNpcGFudEluZGV4ID09PSBNUEN2MlBhcnRpZXNFbnVtLlVTRVIgJiYgcHJpdmF0ZU1hdGVyaWFsQmFzZTY0KSB7XG4gICAgICAvLyBTZW5kIHRoZSBwYXNza2V5IGFzIGB3ZWJhdXRobkluZm9gOyB0aGUgZGVwcmVjYXRlZCBgd2ViYXV0aG5EZXZpY2VzYCBhcnJheSBpcyBpZ25vcmVkIGJ5IFBPU1QgL2tleS5cbiAgICAgIGFzc2VydChlbnRlcnByaXNlLCAnZW50ZXJwcmlzZSBpcyByZXF1aXJlZCB0byBhdHRhY2ggYSB3ZWJhdXRobiBkZXZpY2UgdG8gdGhlIHVzZXIga2V5Y2hhaW4nKTtcbiAgICAgIGtleWNoYWluUGFyYW1zLndlYmF1dGhuSW5mbyA9IHtcbiAgICAgICAgb3RwRGV2aWNlSWQ6IHdlYmF1dGhuSW5mby5vdHBEZXZpY2VJZCxcbiAgICAgICAgcHJmU2FsdDogd2ViYXV0aG5JbmZvLnByZlNhbHQsXG4gICAgICAgIGVuY3J5cHRlZFBydjogYXdhaXQgdGhpcy5iaXRnby5lbmNyeXB0KHtcbiAgICAgICAgICBpbnB1dDogcHJpdmF0ZU1hdGVyaWFsQmFzZTY0LFxuICAgICAgICAgIHBhc3N3b3JkOiB3ZWJhdXRobkluZm8ucGFzc3BocmFzZSxcbiAgICAgICAgICBlbmNyeXB0aW9uVmVyc2lvbixcbiAgICAgICAgfSksXG4gICAgICAgIGVudGVycHJpc2VJZDogZW50ZXJwcmlzZSxcbiAgICAgIH07XG4gICAgfVxuXG4gICAgY29uc3Qga2V5Y2hhaW5zID0gdGhpcy5iYXNlQ29pbi5rZXljaGFpbnMoKTtcbiAgICByZXR1cm4geyAuLi4oYXdhaXQga2V5Y2hhaW5zLmFkZChrZXljaGFpblBhcmFtcykpLCByZWR1Y2VkRW5jcnlwdGVkUHJ2IH07XG4gIH1cblxuICBwcml2YXRlIGFzeW5jIGFkZFVzZXJLZXljaGFpbihcbiAgICBjb21tb25LZXljaGFpbjogc3RyaW5nLFxuICAgIHByaXZhdGVNYXRlcmlhbDogQnVmZmVyLFxuICAgIHJlZHVjZWRQcml2YXRlTWF0ZXJpYWw6IEJ1ZmZlcixcbiAgICBwYXNzcGhyYXNlOiBzdHJpbmcsXG4gICAgb3JpZ2luYWxQYXNzY29kZUVuY3J5cHRpb25Db2RlPzogc3RyaW5nLFxuICAgIHdlYmF1dGhuSW5mbz86IFdlYmF1dGhuS2V5RW5jcnlwdGlvbkluZm8sXG4gICAgZW5jcnlwdGlvblZlcnNpb24/OiBFbmNyeXB0aW9uVmVyc2lvbixcbiAgICBlbnRlcnByaXNlPzogc3RyaW5nLFxuICAgIHNhZmVJZD86IHN0cmluZ1xuICApOiBQcm9taXNlPEtleWNoYWluPiB7XG4gICAgcmV0dXJuIHRoaXMuY3JlYXRlUGFydGljaXBhbnRLZXljaGFpbihcbiAgICAgIE1QQ3YyUGFydGllc0VudW0uVVNFUixcbiAgICAgIGNvbW1vbktleWNoYWluLFxuICAgICAgcHJpdmF0ZU1hdGVyaWFsLFxuICAgICAgcmVkdWNlZFByaXZhdGVNYXRlcmlhbCxcbiAgICAgIHBhc3NwaHJhc2UsXG4gICAgICBvcmlnaW5hbFBhc3Njb2RlRW5jcnlwdGlvbkNvZGUsXG4gICAgICB3ZWJhdXRobkluZm8sXG4gICAgICBlbmNyeXB0aW9uVmVyc2lvbixcbiAgICAgIGVudGVycHJpc2UsXG4gICAgICBzYWZlSWRcbiAgICApO1xuICB9XG5cbiAgcHJpdmF0ZSBhc3luYyBhZGRCYWNrdXBLZXljaGFpbihcbiAgICBjb21tb25LZXljaGFpbjogc3RyaW5nLFxuICAgIHByaXZhdGVNYXRlcmlhbDogQnVmZmVyLFxuICAgIHJlZHVjZWRQcml2YXRlTWF0ZXJpYWw6IEJ1ZmZlcixcbiAgICBwYXNzcGhyYXNlOiBzdHJpbmcsXG4gICAgb3JpZ2luYWxQYXNzY29kZUVuY3J5cHRpb25Db2RlPzogc3RyaW5nLFxuICAgIGVuY3J5cHRpb25WZXJzaW9uPzogRW5jcnlwdGlvblZlcnNpb24sXG4gICAgc2FmZUlkPzogc3RyaW5nXG4gICk6IFByb21pc2U8S2V5Y2hhaW4+IHtcbiAgICByZXR1cm4gdGhpcy5jcmVhdGVQYXJ0aWNpcGFudEtleWNoYWluKFxuICAgICAgTVBDdjJQYXJ0aWVzRW51bS5CQUNLVVAsXG4gICAgICBjb21tb25LZXljaGFpbixcbiAgICAgIHByaXZhdGVNYXRlcmlhbCxcbiAgICAgIHJlZHVjZWRQcml2YXRlTWF0ZXJpYWwsXG4gICAgICBwYXNzcGhyYXNlLFxuICAgICAgb3JpZ2luYWxQYXNzY29kZUVuY3J5cHRpb25Db2RlLFxuICAgICAgdW5kZWZpbmVkLFxuICAgICAgZW5jcnlwdGlvblZlcnNpb24sXG4gICAgICB1bmRlZmluZWQsXG4gICAgICBzYWZlSWRcbiAgICApO1xuICB9XG5cbiAgcHJpdmF0ZSBhc3luYyBhZGRCaXRnb0tleWNoYWluKGNvbW1vbktleWNoYWluOiBzdHJpbmcsIHNhZmVJZD86IHN0cmluZyk6IFByb21pc2U8S2V5Y2hhaW4+IHtcbiAgICByZXR1cm4gdGhpcy5jcmVhdGVQYXJ0aWNpcGFudEtleWNoYWluKFxuICAgICAgTVBDdjJQYXJ0aWVzRW51bS5CSVRHTyxcbiAgICAgIGNvbW1vbktleWNoYWluLFxuICAgICAgdW5kZWZpbmVkLFxuICAgICAgdW5kZWZpbmVkLFxuICAgICAgdW5kZWZpbmVkLFxuICAgICAgdW5kZWZpbmVkLFxuICAgICAgdW5kZWZpbmVkLFxuICAgICAgdW5kZWZpbmVkLFxuICAgICAgdW5kZWZpbmVkLFxuICAgICAgc2FmZUlkXG4gICAgKTtcbiAgfVxuICAvLyAjZW5kcmVnaW9uXG5cbiAgYXN5bmMgc2VuZEtleUdlbmVyYXRpb25Sb3VuZDEoXG4gICAgZW50ZXJwcmlzZTogc3RyaW5nLFxuICAgIHBheWxvYWQ6IEVkZHNhTVBDdjJLZXlHZW5Sb3VuZDFSZXF1ZXN0ICYgeyB3YWxsZXRJZD86IHN0cmluZyB9LFxuICAgIHNhZmVJZD86IHN0cmluZ1xuICApOiBQcm9taXNlPEVkZHNhTVBDdjJLZXlHZW5Sb3VuZDFSZXNwb25zZT4ge1xuICAgIHJldHVybiB0aGlzLnNlbmRLZXlHZW5lcmF0aW9uUm91bmQxQnlTZW5kZXIoS2V5R2VuU2VuZGVyRm9yRW50ZXJwcmlzZSh0aGlzLmJpdGdvLCBlbnRlcnByaXNlLCBzYWZlSWQpLCBwYXlsb2FkKTtcbiAgfVxuXG4gIGFzeW5jIHNlbmRLZXlHZW5lcmF0aW9uUm91bmQxQnlTZW5kZXIoXG4gICAgc2VuZGVyRm46IEVkZHNhTVBDdjJLZXlHZW5TZW5kRm48RWRkc2FNUEN2MktleUdlblJvdW5kMVJlc3BvbnNlPixcbiAgICBwYXlsb2FkOiBFZGRzYU1QQ3YyS2V5R2VuUm91bmQxUmVxdWVzdCAmIHsgd2FsbGV0SWQ/OiBzdHJpbmcgfVxuICApOiBQcm9taXNlPEVkZHNhTVBDdjJLZXlHZW5Sb3VuZDFSZXNwb25zZT4ge1xuICAgIHJldHVybiBzZW5kZXJGbihNUEN2MktleUdlblN0YXRlRW51bVsnTVBDdjItUjEnXSwgcGF5bG9hZCk7XG4gIH1cblxuICBhc3luYyBzZW5kS2V5R2VuZXJhdGlvblJvdW5kMihcbiAgICBlbnRlcnByaXNlOiBzdHJpbmcsXG4gICAgcGF5bG9hZDogRWRkc2FNUEN2MktleUdlblJvdW5kMlJlcXVlc3RcbiAgKTogUHJvbWlzZTxFZGRzYU1QQ3YyS2V5R2VuUm91bmQyUmVzcG9uc2U+IHtcbiAgICByZXR1cm4gdGhpcy5zZW5kS2V5R2VuZXJhdGlvblJvdW5kMkJ5U2VuZGVyKEtleUdlblNlbmRlckZvckVudGVycHJpc2UodGhpcy5iaXRnbywgZW50ZXJwcmlzZSksIHBheWxvYWQpO1xuICB9XG5cbiAgYXN5bmMgc2VuZEtleUdlbmVyYXRpb25Sb3VuZDJCeVNlbmRlcihcbiAgICBzZW5kZXJGbjogRWRkc2FNUEN2MktleUdlblNlbmRGbjxFZGRzYU1QQ3YyS2V5R2VuUm91bmQyUmVzcG9uc2U+LFxuICAgIHBheWxvYWQ6IEVkZHNhTVBDdjJLZXlHZW5Sb3VuZDJSZXF1ZXN0XG4gICk6IFByb21pc2U8RWRkc2FNUEN2MktleUdlblJvdW5kMlJlc3BvbnNlPiB7XG4gICAgcmV0dXJuIHNlbmRlckZuKE1QQ3YyS2V5R2VuU3RhdGVFbnVtWydNUEN2Mi1SMiddLCBwYXlsb2FkKTtcbiAgfVxuXG4gIC8vICNlbmRyZWdpb25cblxuICAvLyAjcmVnaW9uIHNpZ24gdHggcmVxdWVzdFxuXG4gIC8qKlxuICAgKiBTaWducyB0aGUgdHJhbnNhY3Rpb24gYXNzb2NpYXRlZCB3aXRoIHRoZSB0cmFuc2FjdGlvbiByZXF1ZXN0LlxuICAgKiBAcGFyYW0ge3N0cmluZyB8IFR4UmVxdWVzdH0gcGFyYW1zLnR4UmVxdWVzdCAtIHRyYW5zYWN0aW9uIHJlcXVlc3Qgb2JqZWN0IG9yIGlkXG4gICAqIEBwYXJhbSB7c3RyaW5nfSBwYXJhbXMucHJ2IC0gZGVjcnlwdGVkIHByaXZhdGUga2V5XG4gICAqIEBwYXJhbSB7c3RyaW5nfSBwYXJhbXMucmVxSWQgLSByZXF1ZXN0IGlkXG4gICAqIEByZXR1cm5zIHtQcm9taXNlPFR4UmVxdWVzdD59IGZ1bGx5IHNpZ25lZCBUeFJlcXVlc3RcbiAgICovXG4gIGFzeW5jIHNpZ25UeFJlcXVlc3QocGFyYW1zOiBUU1NQYXJhbXNXaXRoUHJ2KTogUHJvbWlzZTxUeFJlcXVlc3Q+IHtcbiAgICB0aGlzLmJpdGdvLnNldFJlcXVlc3RUcmFjZXIocGFyYW1zLnJlcUlkKTtcbiAgICByZXR1cm4gdGhpcy5zaWduUmVxdWVzdEJhc2UocGFyYW1zLCBSZXF1ZXN0VHlwZS50eCk7XG4gIH1cblxuICAvKipcbiAgICogU2lnbnMgdGhlIG1lc3NhZ2UgYXNzb2NpYXRlZCB3aXRoIHRoZSB0cmFuc2FjdGlvbiByZXF1ZXN0LlxuICAgKiBAcGFyYW0ge3N0cmluZyB8IFR4UmVxdWVzdH0gcGFyYW1zLnR4UmVxdWVzdCAtIHRyYW5zYWN0aW9uIHJlcXVlc3Qgb2JqZWN0IG9yIGlkXG4gICAqIEBwYXJhbSB7c3RyaW5nfSBwYXJhbXMucHJ2IC0gZGVjcnlwdGVkIHByaXZhdGUga2V5XG4gICAqIEBwYXJhbSB7c3RyaW5nfSBwYXJhbXMucmVxSWQgLSByZXF1ZXN0IGlkXG4gICAqIEByZXR1cm5zIHtQcm9taXNlPFR4UmVxdWVzdD59IGZ1bGx5IHNpZ25lZCBUeFJlcXVlc3RcbiAgICovXG4gIGFzeW5jIHNpZ25UeFJlcXVlc3RGb3JNZXNzYWdlKHBhcmFtczogVFNTUGFyYW1zRm9yTWVzc2FnZVdpdGhQcnYpOiBQcm9taXNlPFR4UmVxdWVzdD4ge1xuICAgIHRoaXMuYml0Z28uc2V0UmVxdWVzdFRyYWNlcihwYXJhbXMucmVxSWQpO1xuICAgIHJldHVybiB0aGlzLnNpZ25SZXF1ZXN0QmFzZShwYXJhbXMsIFJlcXVlc3RUeXBlLm1lc3NhZ2UpO1xuICB9XG5cbiAgLyoqXG4gICAqIEZ1bGwgMy1yb3VuZCBFZERTQSBNUEN2MiAoTVBTKSBvbmxpbmUgc2lnbmluZyBvcmNoZXN0cmF0aW9uLlxuICAgKlxuICAgKiBQcm90b2NvbCBvdmVydmlldzpcbiAgICogICBXQVNNIFJvdW5kIDAgIOKGkiBnZXRGaXJzdE1lc3NhZ2UoKSAgICAgIChwcm9kdWNlcyB1c2VyTXNnMSlcbiAgICogICBBUEkgIFJvdW5kIDEgIOKGkiBzZW5kIHVzZXJNc2cxIC8gcmVjdiBiaXRnb01zZzFcbiAgICogICBXQVNNIFJvdW5kIDEgIOKGkiBoYW5kbGVJbmNvbWluZ01lc3NhZ2VzKFt1c2VyTXNnMSwgYml0Z29Nc2cxXSkgIChwcm9kdWNlcyB1c2VyTXNnMilcbiAgICogICBBUEkgIFJvdW5kIDIgIOKGkiBzZW5kIHVzZXJNc2cyIC8gcmVjdiBiaXRnb01zZzJcbiAgICogICBXQVNNIFJvdW5kIDIgIOKGkiBoYW5kbGVJbmNvbWluZ01lc3NhZ2VzKFt1c2VyTXNnMiwgYml0Z29Nc2cyXSkgIChwcm9kdWNlcyB1c2VyTXNnMylcbiAgICogICBBUEkgIFJvdW5kIDMgIOKGkiBzZW5kIHVzZXJNc2czIChXUCBmaW5hbGlzZXM7IG5vIEJpdEdvIG1zZyByZXR1cm5lZCB0byBjbGllbnQpXG4gICAqL1xuICBwcml2YXRlIGFzeW5jIHNpZ25SZXF1ZXN0QmFzZShcbiAgICBwYXJhbXM6IFRTU1BhcmFtc1dpdGhQcnYgfCBUU1NQYXJhbXNGb3JNZXNzYWdlV2l0aFBydixcbiAgICByZXF1ZXN0VHlwZTogUmVxdWVzdFR5cGVcbiAgKTogUHJvbWlzZTxUeFJlcXVlc3Q+IHtcbiAgICBjb25zdCB1c2VyS2V5U2hhcmUgPSBCdWZmZXIuZnJvbShwYXJhbXMucHJ2LCAnYmFzZTY0Jyk7XG5cbiAgICBjb25zdCB0eFJlcXVlc3Q6IFR4UmVxdWVzdCA9XG4gICAgICB0eXBlb2YgcGFyYW1zLnR4UmVxdWVzdCA9PT0gJ3N0cmluZydcbiAgICAgICAgPyBhd2FpdCBnZXRUeFJlcXVlc3QodGhpcy5iaXRnbywgdGhpcy53YWxsZXQuaWQoKSwgcGFyYW1zLnR4UmVxdWVzdCwgcGFyYW1zLnJlcUlkKVxuICAgICAgICA6IHBhcmFtcy50eFJlcXVlc3Q7XG5cbiAgICBsZXQgdHhPck1lc3NhZ2VUb1NpZ247XG4gICAgbGV0IGRlcml2YXRpb25QYXRoO1xuICAgIGxldCBidWZmZXJDb250ZW50O1xuICAgIC8vIE9uZSBmcmVzaCBlZDI1NTE5IEdQRyBrZXkgcGFpciBwZXIgc2lnbmluZyBzZXNzaW9uLCByZXVzZWQgYWNyb3NzIGFsbCBzaWduaW5nIHJvdW5kcy5cbiAgICBjb25zdCB1c2VyR3BnS2V5ID0gYXdhaXQgZ2VuZXJhdGVHUEdLZXlQYWlyKCdlZDI1NTE5Jyk7XG4gICAgY29uc3QgdXNlckdwZ1BydktleSA9IGF3YWl0IHBncC5yZWFkUHJpdmF0ZUtleSh7IGFybW9yZWRLZXk6IHVzZXJHcGdLZXkucHJpdmF0ZUtleSB9KTtcbiAgICBjb25zdCBiaXRnb0dwZ1B1YktleSA9IGF3YWl0IHRoaXMucGlja0JpdGdvUHViR3BnS2V5Rm9yU2lnbmluZyh0cnVlLCBwYXJhbXMucmVxSWQsIHR4UmVxdWVzdC5lbnRlcnByaXNlSWQsIHRydWUpO1xuICAgIGFzc2VydChiaXRnb0dwZ1B1YktleSwgJ01pc3NpbmcgQml0R28gR1BHIGtleSBmb3IgTVBDdjInKTtcblxuICAgIGlmIChyZXF1ZXN0VHlwZSA9PT0gUmVxdWVzdFR5cGUudHgpIHtcbiAgICAgIGFzc2VydCh0eFJlcXVlc3QudHJhbnNhY3Rpb25zIHx8IHR4UmVxdWVzdC51bnNpZ25lZFR4cywgJ1VuYWJsZSB0byBmaW5kIHRyYW5zYWN0aW9ucyBpbiB0eFJlcXVlc3QnKTtcbiAgICAgIGNvbnN0IHVuc2lnbmVkVHggPVxuICAgICAgICB0eFJlcXVlc3QuYXBpVmVyc2lvbiA9PT0gJ2Z1bGwnID8gdHhSZXF1ZXN0LnRyYW5zYWN0aW9ucyFbMF0udW5zaWduZWRUeCA6IHR4UmVxdWVzdC51bnNpZ25lZFR4cyFbMF07XG4gICAgICB0eE9yTWVzc2FnZVRvU2lnbiA9IHVuc2lnbmVkVHguc2lnbmFibGVIZXg7XG4gICAgICBhc3NlcnQodHhPck1lc3NhZ2VUb1NpZ24sICdNaXNzaW5nIHNpZ25hYmxlSGV4IGluIHVuc2lnbmVkVHgnKTtcbiAgICAgIGRlcml2YXRpb25QYXRoID0gdW5zaWduZWRUeC5kZXJpdmF0aW9uUGF0aDtcbiAgICAgIGJ1ZmZlckNvbnRlbnQgPSBCdWZmZXIuZnJvbSh0eE9yTWVzc2FnZVRvU2lnbiwgJ2hleCcpO1xuICAgICAgYXdhaXQgdGhpcy5iYXNlQ29pbi52ZXJpZnlUcmFuc2FjdGlvbih7XG4gICAgICAgIHR4UHJlYnVpbGQ6IHsgdHhIZXg6IHVuc2lnbmVkVHguc2VyaWFsaXplZFR4SGV4ID8/IHR4T3JNZXNzYWdlVG9TaWduIH0sXG4gICAgICAgIHR4UGFyYW1zOiByZXNvbHZlRWZmZWN0aXZlVHhQYXJhbXModHhSZXF1ZXN0LCBwYXJhbXMudHhQYXJhbXMsIHRoaXMuYmFzZUNvaW4uZ2V0Q2hhaW4oKSksXG4gICAgICAgIHdhbGxldDogdGhpcy53YWxsZXQsXG4gICAgICAgIHdhbGxldFR5cGU6IHRoaXMud2FsbGV0Lm11bHRpc2lnVHlwZSgpLFxuICAgICAgfSk7XG4gICAgfSBlbHNlIGlmIChyZXF1ZXN0VHlwZSA9PT0gUmVxdWVzdFR5cGUubWVzc2FnZSkge1xuICAgICAgYXNzZXJ0KHR4UmVxdWVzdC5tZXNzYWdlcyAmJiB0eFJlcXVlc3QubWVzc2FnZXMubGVuZ3RoID4gMCwgJ1VuYWJsZSB0byBmaW5kIG1lc3NhZ2VzIGluIHR4UmVxdWVzdCcpO1xuICAgICAgdHhPck1lc3NhZ2VUb1NpZ24gPSB0eFJlcXVlc3QubWVzc2FnZXNbMF0ubWVzc2FnZUVuY29kZWQ7XG4gICAgICBhc3NlcnQodHhPck1lc3NhZ2VUb1NpZ24sICdNaXNzaW5nIG1lc3NhZ2VFbmNvZGVkIGluIG1lc3NhZ2VzWzBdJyk7XG4gICAgICBkZXJpdmF0aW9uUGF0aCA9IHR4UmVxdWVzdC5tZXNzYWdlc1swXS5kZXJpdmF0aW9uUGF0aCB8fCAnbS8wJztcbiAgICAgIGJ1ZmZlckNvbnRlbnQgPSBCdWZmZXIuZnJvbSh0eE9yTWVzc2FnZVRvU2lnbiwgJ2hleCcpO1xuICAgIH0gZWxzZSB7XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoJ0ludmFsaWQgcmVxdWVzdCB0eXBlJyk7XG4gICAgfVxuXG4gICAgLy8g4pSA4pSAIFdBU00gUm91bmQgMCDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIBcbiAgICBjb25zdCBwYXJ0eUlkID0gcGFyYW1zLm1wY3YyUGFydHlJZCA/PyBNUEN2MlBhcnRpZXNFbnVtLlVTRVI7XG4gICAgY29uc3Qgc2lnbmVyU2hhcmVUeXBlID0gcGFydHlJZCA9PT0gTVBDdjJQYXJ0aWVzRW51bS5VU0VSID8gU2lnbmF0dXJlU2hhcmVUeXBlLlVTRVIgOiBTaWduYXR1cmVTaGFyZVR5cGUuQkFDS1VQO1xuICAgIGNvbnN0IHVzZXJEc2cgPSBuZXcgRWRkc2FNUFNEc2cuRFNHKHBhcnR5SWQpO1xuICAgIGF3YWl0IHVzZXJEc2cuaW5pdERzZyh1c2VyS2V5U2hhcmUsIGJ1ZmZlckNvbnRlbnQsIGRlcml2YXRpb25QYXRoLCBNUEN2MlBhcnRpZXNFbnVtLkJJVEdPKTtcbiAgICBjb25zdCB1c2VyTXNnMSA9IHVzZXJEc2cuZ2V0Rmlyc3RNZXNzYWdlKCk7XG5cbiAgICAvLyDilIDilIAgQVBJIFJvdW5kIDEg4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSAXG4gICAgY29uc3Qgc2lnbmF0dXJlU2hhcmVSb3VuZDEgPSBhd2FpdCBnZXRTaWduYXR1cmVTaGFyZVJvdW5kT25lKHVzZXJNc2cxLCB1c2VyR3BnUHJ2S2V5LCBwYXJ0eUlkKTtcbiAgICBsZXQgbGF0ZXN0VHhSZXF1ZXN0ID0gYXdhaXQgc2VuZFNpZ25hdHVyZVNoYXJlVjIoXG4gICAgICB0aGlzLmJpdGdvLFxuICAgICAgdHhSZXF1ZXN0LndhbGxldElkLFxuICAgICAgdHhSZXF1ZXN0LnR4UmVxdWVzdElkLFxuICAgICAgW3NpZ25hdHVyZVNoYXJlUm91bmQxXSxcbiAgICAgIHJlcXVlc3RUeXBlLFxuICAgICAgdGhpcy5iYXNlQ29pbi5nZXRNUENBbGdvcml0aG0oKSxcbiAgICAgIHVzZXJHcGdLZXkucHVibGljS2V5LFxuICAgICAgdW5kZWZpbmVkLFxuICAgICAgdGhpcy53YWxsZXQubXVsdGlzaWdUeXBlVmVyc2lvbigpLFxuICAgICAgcGFyYW1zLnJlcUlkXG4gICAgKTtcblxuICAgIGFzc2VydChsYXRlc3RUeFJlcXVlc3QudHJhbnNhY3Rpb25zIHx8IGxhdGVzdFR4UmVxdWVzdC5tZXNzYWdlcywgJ0ludmFsaWQgdHhSZXF1ZXN0IG9iamVjdCBhZnRlciByb3VuZCAxJyk7XG5cbiAgICBjb25zdCBzaWduYXR1cmVTaGFyZXMxID1cbiAgICAgIHJlcXVlc3RUeXBlID09PSBSZXF1ZXN0VHlwZS50eFxuICAgICAgICA/IGxhdGVzdFR4UmVxdWVzdC50cmFuc2FjdGlvbnMhWzBdLnNpZ25hdHVyZVNoYXJlc1xuICAgICAgICA6IGxhdGVzdFR4UmVxdWVzdC5tZXNzYWdlcyFbMF0uc2lnbmF0dXJlU2hhcmVzO1xuXG4gICAgY29uc3QgYml0Z29TaGFyZVJvdW5kT25lID0gZ2V0Qml0Z29TaWduYXR1cmVTaGFyZShzaWduYXR1cmVTaGFyZXMxLCBzaWduZXJTaGFyZVR5cGUsICdyb3VuZDFPdXRwdXQnKTtcbiAgICBjb25zdCBwYXJzZWRCaXRHb1RvVXNlclNpZ1NoYXJlUm91bmRPbmUgPSBkZWNvZGVXaXRoQ29kZWMoXG4gICAgICBFZGRzYU1QQ3YyU2lnbmF0dXJlU2hhcmVSb3VuZDFPdXRwdXQsXG4gICAgICBKU09OLnBhcnNlKGJpdGdvU2hhcmVSb3VuZE9uZS5zaGFyZSksXG4gICAgICAnVW5leHBlY3RlZCBzaWduYXR1cmUgc2hhcmUgcmVzcG9uc2UuIFVuYWJsZSB0byBwYXJzZSBkYXRhLidcbiAgICApO1xuXG4gICAgaWYgKHBhcnNlZEJpdEdvVG9Vc2VyU2lnU2hhcmVSb3VuZE9uZS50eXBlICE9PSAncm91bmQxT3V0cHV0Jykge1xuICAgICAgdGhyb3cgbmV3IEVycm9yKCdVbmV4cGVjdGVkIHNpZ25hdHVyZSBzaGFyZSByZXNwb25zZS4gVW5hYmxlIHRvIHBhcnNlIGRhdGEuJyk7XG4gICAgfVxuXG4gICAgY29uc3QgYml0Z29EZXNlcmlhbGl6ZWRNc2cxID0gYXdhaXQgdmVyaWZ5UGVlck1lc3NhZ2VSb3VuZE9uZShwYXJzZWRCaXRHb1RvVXNlclNpZ1NoYXJlUm91bmRPbmUsIGJpdGdvR3BnUHViS2V5KTtcblxuICAgIC8vIOKUgOKUgCBXQVNNIFJvdW5kIDEg4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSAXG4gICAgY29uc3QgW3VzZXJNc2cyXSA9IHVzZXJEc2cuaGFuZGxlSW5jb21pbmdNZXNzYWdlcyhbdXNlck1zZzEsIGJpdGdvRGVzZXJpYWxpemVkTXNnMV0pO1xuICAgIGFzc2VydCh1c2VyTXNnMiwgJ1dBU00gcm91bmQgMSBwcm9kdWNlZCBubyBtZXNzYWdlJyk7XG5cbiAgICAvLyDilIDilIAgQVBJIFJvdW5kIDIg4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSAXG4gICAgY29uc3Qgc2lnbmF0dXJlU2hhcmVSb3VuZFR3byA9IGF3YWl0IGdldFNpZ25hdHVyZVNoYXJlUm91bmRUd28odXNlck1zZzIsIHVzZXJHcGdQcnZLZXksIHBhcnR5SWQpO1xuICAgIGxhdGVzdFR4UmVxdWVzdCA9IGF3YWl0IHNlbmRTaWduYXR1cmVTaGFyZVYyKFxuICAgICAgdGhpcy5iaXRnbyxcbiAgICAgIHR4UmVxdWVzdC53YWxsZXRJZCxcbiAgICAgIHR4UmVxdWVzdC50eFJlcXVlc3RJZCxcbiAgICAgIFtzaWduYXR1cmVTaGFyZVJvdW5kVHdvXSxcbiAgICAgIHJlcXVlc3RUeXBlLFxuICAgICAgdGhpcy5iYXNlQ29pbi5nZXRNUENBbGdvcml0aG0oKSxcbiAgICAgIHVzZXJHcGdLZXkucHVibGljS2V5LFxuICAgICAgdW5kZWZpbmVkLFxuICAgICAgdGhpcy53YWxsZXQubXVsdGlzaWdUeXBlVmVyc2lvbigpLFxuICAgICAgcGFyYW1zLnJlcUlkXG4gICAgKTtcblxuICAgIGFzc2VydChsYXRlc3RUeFJlcXVlc3QudHJhbnNhY3Rpb25zIHx8IGxhdGVzdFR4UmVxdWVzdC5tZXNzYWdlcywgJ0ludmFsaWQgdHhSZXF1ZXN0IG9iamVjdCBhZnRlciByb3VuZCAyJyk7XG5cbiAgICBjb25zdCB0eFJlcXVlc3RTaWduYXR1cmVTaGFyZXMgPVxuICAgICAgcmVxdWVzdFR5cGUgPT09IFJlcXVlc3RUeXBlLnR4XG4gICAgICAgID8gbGF0ZXN0VHhSZXF1ZXN0LnRyYW5zYWN0aW9ucyFbMF0uc2lnbmF0dXJlU2hhcmVzXG4gICAgICAgIDogbGF0ZXN0VHhSZXF1ZXN0Lm1lc3NhZ2VzIVswXS5zaWduYXR1cmVTaGFyZXM7XG5cbiAgICBjb25zdCBiaXRnb1NoYXJlUm91bmRUd28gPSBnZXRCaXRnb1NpZ25hdHVyZVNoYXJlKHR4UmVxdWVzdFNpZ25hdHVyZVNoYXJlcywgc2lnbmVyU2hhcmVUeXBlLCAncm91bmQyT3V0cHV0Jyk7XG4gICAgY29uc3QgcGFyc2VkQml0R29Ub1VzZXJTaWdTaGFyZVJvdW5kVHdvID0gZGVjb2RlV2l0aENvZGVjKFxuICAgICAgRWRkc2FNUEN2MlNpZ25hdHVyZVNoYXJlUm91bmQyT3V0cHV0LFxuICAgICAgSlNPTi5wYXJzZShiaXRnb1NoYXJlUm91bmRUd28uc2hhcmUpLFxuICAgICAgJ1VuZXhwZWN0ZWQgc2lnbmF0dXJlIHNoYXJlIHJlc3BvbnNlLiBVbmFibGUgdG8gcGFyc2UgZGF0YS4nXG4gICAgKTtcblxuICAgIGlmIChwYXJzZWRCaXRHb1RvVXNlclNpZ1NoYXJlUm91bmRUd28udHlwZSAhPT0gJ3JvdW5kMk91dHB1dCcpIHtcbiAgICAgIHRocm93IG5ldyBFcnJvcignVW5leHBlY3RlZCBzaWduYXR1cmUgc2hhcmUgcmVzcG9uc2UuIFVuYWJsZSB0byBwYXJzZSBkYXRhLicpO1xuICAgIH1cblxuICAgIGNvbnN0IGJpdGdvRGVzZXJpYWxpemVkTXNnMiA9IGF3YWl0IHZlcmlmeVBlZXJNZXNzYWdlUm91bmRUd28ocGFyc2VkQml0R29Ub1VzZXJTaWdTaGFyZVJvdW5kVHdvLCBiaXRnb0dwZ1B1YktleSk7XG5cbiAgICAvLyDilIDilIAgV0FTTSBSb3VuZCAyIOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgFxuICAgIGNvbnN0IFt1c2VyTXNnM10gPSB1c2VyRHNnLmhhbmRsZUluY29taW5nTWVzc2FnZXMoW3VzZXJNc2cyLCBiaXRnb0Rlc2VyaWFsaXplZE1zZzJdKTtcbiAgICBhc3NlcnQodXNlck1zZzMsICdXQVNNIHJvdW5kIDIgcHJvZHVjZWQgbm8gbWVzc2FnZScpO1xuXG4gICAgLy8g4pSA4pSAIEFQSSBSb3VuZCAzIOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgFxuICAgIC8vIE5vIEJpdEdvIHJlc3BvbnNlIHRvIHZlcmlmeTsgV1AgZmluYWxpc2VzIHRoZSBzaWduaW5nIHNlcnZlci1zaWRlXG4gICAgY29uc3Qgc2lnbmF0dXJlU2hhcmVSb3VuZDMgPSBhd2FpdCBnZXRTaWduYXR1cmVTaGFyZVJvdW5kVGhyZWUodXNlck1zZzMsIHVzZXJHcGdQcnZLZXksIHBhcnR5SWQpO1xuICAgIGNvbnN0IHJvdW5kM1R4UmVxdWVzdCA9IGF3YWl0IHNlbmRTaWduYXR1cmVTaGFyZVYyKFxuICAgICAgdGhpcy5iaXRnbyxcbiAgICAgIHR4UmVxdWVzdC53YWxsZXRJZCxcbiAgICAgIHR4UmVxdWVzdC50eFJlcXVlc3RJZCxcbiAgICAgIFtzaWduYXR1cmVTaGFyZVJvdW5kM10sXG4gICAgICByZXF1ZXN0VHlwZSxcbiAgICAgIHRoaXMuYmFzZUNvaW4uZ2V0TVBDQWxnb3JpdGhtKCksXG4gICAgICB1c2VyR3BnS2V5LnB1YmxpY0tleSxcbiAgICAgIHVuZGVmaW5lZCxcbiAgICAgIHRoaXMud2FsbGV0Lm11bHRpc2lnVHlwZVZlcnNpb24oKSxcbiAgICAgIHBhcmFtcy5yZXFJZFxuICAgICk7XG4gICAgYXNzZXJ0KHJvdW5kM1R4UmVxdWVzdD8udHhSZXF1ZXN0SWQgPT09IHR4UmVxdWVzdC50eFJlcXVlc3RJZCwgJ0ludmFsaWQgdHhSZXF1ZXN0IG9iamVjdCBhZnRlciByb3VuZCAzJyk7XG5cbiAgICByZXR1cm4gc2VuZFR4UmVxdWVzdCh0aGlzLmJpdGdvLCB0eFJlcXVlc3Qud2FsbGV0SWQsIHR4UmVxdWVzdC50eFJlcXVlc3RJZCwgcmVxdWVzdFR5cGUsIHBhcmFtcy5yZXFJZCk7XG4gIH1cblxuICAvLyAjZW5kcmVnaW9uXG5cbiAgLy8gI3JlZ2lvbiBleHRlcm5hbCBzaWduZXJcblxuICAvLyAjcmVnaW9uIEtleUdlblJvdW5kMVNoYXJlXG4gIGFzeW5jIGNyZWF0ZU9mZmxpbmVLZXlHZW5Sb3VuZDFTaGFyZShwYXJhbXM6IHtcbiAgICB3YWxsZXRQYXNzcGhyYXNlOiBzdHJpbmc7XG4gICAgZW5jcnlwdGVkVXNlckdwZ1BydktleTogc3RyaW5nO1xuICAgIGJpdGdvR3BnUHViS2V5OiBzdHJpbmc7XG4gICAgY291bnRlclBhcnR5R3BnUHViS2V5OiBzdHJpbmc7XG4gICAgcGFydHlJZD86IE1QQ3YyUGFydGllc0VudW0uVVNFUiB8IE1QQ3YyUGFydGllc0VudW0uQkFDS1VQO1xuICB9KTogUHJvbWlzZTx7XG4gICAgc2lnbmVkTXNnMTogTVBTVHlwZXMuTVBTU2lnbmVkTWVzc2FnZTtcbiAgICBlbmNyeXB0ZWRSb3VuZDFTZXNzaW9uOiBzdHJpbmc7XG4gIH0+IHtcbiAgICBjb25zdCB7IHdhbGxldFBhc3NwaHJhc2UsIGVuY3J5cHRlZFVzZXJHcGdQcnZLZXksIGJpdGdvR3BnUHViS2V5LCBjb3VudGVyUGFydHlHcGdQdWJLZXkgfSA9IHBhcmFtcztcbiAgICBjb25zdCBwYXJ0eUlkID0gcGFyYW1zLnBhcnR5SWQgPz8gTVBDdjJQYXJ0aWVzRW51bS5VU0VSO1xuXG4gICAgY29uc3QgZGVjcnlwdGVkR3BnUHJ2S2V5ID0gYXdhaXQgdGhpcy5iaXRnby5kZWNyeXB0KHsgaW5wdXQ6IGVuY3J5cHRlZFVzZXJHcGdQcnZLZXksIHBhc3N3b3JkOiB3YWxsZXRQYXNzcGhyYXNlIH0pO1xuICAgIGNvbnN0IGdwZ1BydktleSA9IGF3YWl0IHBncC5yZWFkUHJpdmF0ZUtleSh7IGFybW9yZWRLZXk6IGRlY3J5cHRlZEdwZ1BydktleSB9KTtcblxuICAgIGNvbnN0IFssIG93blNrXSA9IGF3YWl0IE1QU0NvbW1zLmV4dHJhY3RFZDI1NTE5S2V5UGFpcihncGdQcnZLZXkpO1xuXG4gICAgaWYgKGVudlJlcXVpcmVzQml0Z29QdWJHcGdLZXlDb25maWcodGhpcy5iaXRnby5nZXRFbnYoKSkpIHtcbiAgICAgIGFzc2VydChpc0JpdGdvRWRkc2FNcGN2MlB1YktleShiaXRnb0dwZ1B1YktleSksICdJbnZhbGlkIEJpdEdvIEdQRyBwdWJsaWMga2V5Jyk7XG4gICAgfVxuXG4gICAgY29uc3QgYml0Z29LZXlPYmogPSBhd2FpdCBwZ3AucmVhZEtleSh7IGFybW9yZWRLZXk6IGJpdGdvR3BnUHViS2V5IH0pO1xuICAgIGNvbnN0IGJpdGdvUGsgPSBhd2FpdCBNUFNDb21tcy5leHRyYWN0RWQyNTUxOVB1YmxpY0tleShiaXRnb0tleU9iaik7XG5cbiAgICBjb25zdCBjb3VudGVyUGFydHlLZXlPYmogPSBhd2FpdCBwZ3AucmVhZEtleSh7IGFybW9yZWRLZXk6IGNvdW50ZXJQYXJ0eUdwZ1B1YktleSB9KTtcbiAgICBjb25zdCBjb3VudGVyUGFydHlQayA9IGF3YWl0IE1QU0NvbW1zLmV4dHJhY3RFZDI1NTE5UHVibGljS2V5KGNvdW50ZXJQYXJ0eUtleU9iaik7XG5cbiAgICBjb25zdCBka2cgPSBuZXcgRWRkc2FNUFNEa2cuREtHKDMsIDIsIHBhcnR5SWQpO1xuICAgIGF3YWl0IGRrZy5pbml0RGtnKG93blNrLCBbY291bnRlclBhcnR5UGssIGJpdGdvUGtdKTtcblxuICAgIGNvbnN0IG1zZzEgPSBka2cuZ2V0Rmlyc3RNZXNzYWdlKCk7XG4gICAgY29uc3Qgc2lnbmVkTXNnMSA9IGF3YWl0IE1QU0NvbW1zLmRldGFjaFNpZ25NcHNNZXNzYWdlKEJ1ZmZlci5mcm9tKG1zZzEucGF5bG9hZCksIGdwZ1BydktleSk7XG5cbiAgICBjb25zdCBzZXNzaW9uUGF5bG9hZCA9IEpTT04uc3RyaW5naWZ5KHtcbiAgICAgIGRrZ1Nlc3Npb246IGRrZy5nZXRTZXNzaW9uKCksXG4gICAgICBvd25Nc2dQYXlsb2FkOiBCdWZmZXIuZnJvbShtc2cxLnBheWxvYWQpLnRvU3RyaW5nKCdiYXNlNjQnKSxcbiAgICAgIG93bk1zZ0Zyb206IG1zZzEuZnJvbSxcbiAgICB9KTtcblxuICAgIGNvbnN0IGVuY3J5cHRlZFJvdW5kMVNlc3Npb24gPSBhd2FpdCB0aGlzLmJpdGdvLmVuY3J5cHQoe1xuICAgICAgaW5wdXQ6IHNlc3Npb25QYXlsb2FkLFxuICAgICAgcGFzc3dvcmQ6IHdhbGxldFBhc3NwaHJhc2UsXG4gICAgICBhZGF0YTogYCR7RWRkc2FNUEN2MlV0aWxzLk1QU19ES0dfS0VZR0VOX1JPVU5EMV9TVEFURX06JHtwYXJ0eUlkfWAsXG4gICAgICBlbmNyeXB0aW9uVmVyc2lvbjogMSxcbiAgICB9KTtcblxuICAgIHJldHVybiB7IHNpZ25lZE1zZzEsIGVuY3J5cHRlZFJvdW5kMVNlc3Npb24gfTtcbiAgfVxuICAvLyAjZW5kcmVnaW9uXG5cbiAgLy8gI3JlZ2lvbiBSb3VuZDFTaGFyZVxuICBhc3luYyBjcmVhdGVPZmZsaW5lUm91bmQxU2hhcmUocGFyYW1zOiB7XG4gICAgdHhSZXF1ZXN0OiBUeFJlcXVlc3Q7XG4gICAgcHJ2OiBzdHJpbmc7XG4gICAgd2FsbGV0UGFzc3BocmFzZTogc3RyaW5nO1xuICAgIGVuY3J5cHRlZFBydj86IHN0cmluZztcbiAgfSk6IFByb21pc2U8e1xuICAgIHNpZ25hdHVyZVNoYXJlUm91bmQxOiBTaWduYXR1cmVTaGFyZVJlY29yZDtcbiAgICB1c2VyR3BnUHViS2V5OiBzdHJpbmc7XG4gICAgZW5jcnlwdGVkUm91bmQxU2Vzc2lvbjogc3RyaW5nO1xuICAgIGVuY3J5cHRlZFVzZXJHcGdQcnZLZXk6IHN0cmluZztcbiAgfT4ge1xuICAgIGNvbnN0IHsgcHJ2LCB3YWxsZXRQYXNzcGhyYXNlLCB0eFJlcXVlc3QsIGVuY3J5cHRlZFBydiB9ID0gcGFyYW1zO1xuICAgIGNvbnN0IHsgc2lnbmFibGVIZXgsIGRlcml2YXRpb25QYXRoIH0gPSB0aGlzLmdldFNpZ25hYmxlSGV4QW5kRGVyaXZhdGlvblBhdGgoXG4gICAgICB0eFJlcXVlc3QsXG4gICAgICAnVW5hYmxlIHRvIGZpbmQgdHJhbnNhY3Rpb25zIGluIHR4UmVxdWVzdCdcbiAgICApO1xuICAgIGNvbnN0IGFkYXRhID0gYCR7c2lnbmFibGVIZXh9OiR7ZGVyaXZhdGlvblBhdGh9YDtcblxuICAgIGNvbnN0IHVzZXJLZXlTaGFyZSA9IEJ1ZmZlci5mcm9tKHBydiwgJ2Jhc2U2NCcpO1xuICAgIGNvbnN0IHVzZXJHcGdLZXkgPSBhd2FpdCBnZW5lcmF0ZUdQR0tleVBhaXIoJ2VkMjU1MTknKTtcbiAgICBjb25zdCB1c2VyR3BnUHJ2S2V5ID0gYXdhaXQgcGdwLnJlYWRQcml2YXRlS2V5KHsgYXJtb3JlZEtleTogdXNlckdwZ0tleS5wcml2YXRlS2V5IH0pO1xuXG4gICAgY29uc3QgdXNlckRzZyA9IG5ldyBFZGRzYU1QU0RzZy5EU0coTVBDdjJQYXJ0aWVzRW51bS5VU0VSKTtcbiAgICBhd2FpdCB1c2VyRHNnLmluaXREc2codXNlcktleVNoYXJlLCBCdWZmZXIuZnJvbShzaWduYWJsZUhleCwgJ2hleCcpLCBkZXJpdmF0aW9uUGF0aCwgTVBDdjJQYXJ0aWVzRW51bS5CSVRHTyk7XG4gICAgY29uc3QgdXNlck1zZzEgPSB1c2VyRHNnLmdldEZpcnN0TWVzc2FnZSgpO1xuICAgIGNvbnN0IHNpZ25hdHVyZVNoYXJlUm91bmQxID0gYXdhaXQgZ2V0U2lnbmF0dXJlU2hhcmVSb3VuZE9uZSh1c2VyTXNnMSwgdXNlckdwZ1BydktleSk7XG4gICAgY29uc3Qgc2Vzc2lvblBheWxvYWQgPSBKU09OLnN0cmluZ2lmeSh7XG4gICAgICBkc2dTZXNzaW9uOiB1c2VyRHNnLmdldFNlc3Npb24oKSxcbiAgICAgIHVzZXJNc2dQYXlsb2FkOiBCdWZmZXIuZnJvbSh1c2VyTXNnMS5wYXlsb2FkKS50b1N0cmluZygnYmFzZTY0JyksXG4gICAgfSk7XG4gICAgY29uc3QgdXNlckdwZ1B1YktleSA9IHVzZXJHcGdLZXkucHVibGljS2V5O1xuXG4gICAgY29uc3QgdXNlVjIgPSBlbmNyeXB0ZWRQcnYgIT09IHVuZGVmaW5lZCAmJiBpc1YyRW52ZWxvcGUoZW5jcnlwdGVkUHJ2KTtcbiAgICBpZiAodXNlVjIpIHtcbiAgICAgIGNvbnN0IHNlc3Npb24gPSBhd2FpdCB0aGlzLmJpdGdvLmNyZWF0ZUVuY3J5cHRpb25TZXNzaW9uKHdhbGxldFBhc3NwaHJhc2UpO1xuICAgICAgdHJ5IHtcbiAgICAgICAgY29uc3QgZW5jcnlwdGVkUm91bmQxU2Vzc2lvbiA9IGF3YWl0IHNlc3Npb24uZW5jcnlwdChcbiAgICAgICAgICBzZXNzaW9uUGF5bG9hZCxcbiAgICAgICAgICBgJHtFZGRzYU1QQ3YyVXRpbHMuTVBTX0RTR19TSUdOSU5HX1JPVU5EMV9TVEFURX06JHthZGF0YX1gXG4gICAgICAgICk7XG4gICAgICAgIGNvbnN0IGVuY3J5cHRlZFVzZXJHcGdQcnZLZXkgPSBhd2FpdCBzZXNzaW9uLmVuY3J5cHQoXG4gICAgICAgICAgdXNlckdwZ0tleS5wcml2YXRlS2V5LFxuICAgICAgICAgIGAke0VkZHNhTVBDdjJVdGlscy5NUFNfRFNHX1NJR05JTkdfVVNFUl9HUEdfS0VZfToke2FkYXRhfWBcbiAgICAgICAgKTtcbiAgICAgICAgcmV0dXJuIHsgc2lnbmF0dXJlU2hhcmVSb3VuZDEsIHVzZXJHcGdQdWJLZXksIGVuY3J5cHRlZFJvdW5kMVNlc3Npb24sIGVuY3J5cHRlZFVzZXJHcGdQcnZLZXkgfTtcbiAgICAgIH0gZmluYWxseSB7XG4gICAgICAgIHNlc3Npb24uZGVzdHJveSgpO1xuICAgICAgfVxuICAgIH1cblxuICAgIGNvbnN0IGVuY3J5cHRlZFJvdW5kMVNlc3Npb24gPSBhd2FpdCB0aGlzLmJpdGdvLmVuY3J5cHQoe1xuICAgICAgaW5wdXQ6IHNlc3Npb25QYXlsb2FkLFxuICAgICAgcGFzc3dvcmQ6IHdhbGxldFBhc3NwaHJhc2UsXG4gICAgICBhZGF0YTogYCR7RWRkc2FNUEN2MlV0aWxzLk1QU19EU0dfU0lHTklOR19ST1VORDFfU1RBVEV9OiR7YWRhdGF9YCxcbiAgICAgIGVuY3J5cHRpb25WZXJzaW9uOiAxLFxuICAgIH0pO1xuICAgIGNvbnN0IGVuY3J5cHRlZFVzZXJHcGdQcnZLZXkgPSBhd2FpdCB0aGlzLmJpdGdvLmVuY3J5cHQoe1xuICAgICAgaW5wdXQ6IHVzZXJHcGdLZXkucHJpdmF0ZUtleSxcbiAgICAgIHBhc3N3b3JkOiB3YWxsZXRQYXNzcGhyYXNlLFxuICAgICAgYWRhdGE6IGAke0VkZHNhTVBDdjJVdGlscy5NUFNfRFNHX1NJR05JTkdfVVNFUl9HUEdfS0VZfToke2FkYXRhfWAsXG4gICAgICBlbmNyeXB0aW9uVmVyc2lvbjogMSxcbiAgICB9KTtcblxuICAgIHJldHVybiB7IHNpZ25hdHVyZVNoYXJlUm91bmQxLCB1c2VyR3BnUHViS2V5LCBlbmNyeXB0ZWRSb3VuZDFTZXNzaW9uLCBlbmNyeXB0ZWRVc2VyR3BnUHJ2S2V5IH07XG4gIH1cbiAgLy8gI2VuZHJlZ2lvblxuXG4gIC8vICNyZWdpb24gUm91bmQyU2hhcmVcbiAgYXN5bmMgY3JlYXRlT2ZmbGluZVJvdW5kMlNoYXJlKHBhcmFtczoge1xuICAgIHR4UmVxdWVzdDogVHhSZXF1ZXN0O1xuICAgIHdhbGxldFBhc3NwaHJhc2U6IHN0cmluZztcbiAgICBiaXRnb1B1YmxpY0dwZ0tleTogc3RyaW5nO1xuICAgIGVuY3J5cHRlZFVzZXJHcGdQcnZLZXk6IHN0cmluZztcbiAgICBlbmNyeXB0ZWRSb3VuZDFTZXNzaW9uOiBzdHJpbmc7XG4gIH0pOiBQcm9taXNlPHtcbiAgICBzaWduYXR1cmVTaGFyZVJvdW5kMjogU2lnbmF0dXJlU2hhcmVSZWNvcmQ7XG4gICAgZW5jcnlwdGVkUm91bmQyU2Vzc2lvbjogc3RyaW5nO1xuICB9PiB7XG4gICAgY29uc3QgeyB3YWxsZXRQYXNzcGhyYXNlLCBlbmNyeXB0ZWRVc2VyR3BnUHJ2S2V5LCBlbmNyeXB0ZWRSb3VuZDFTZXNzaW9uLCBiaXRnb1B1YmxpY0dwZ0tleSwgdHhSZXF1ZXN0IH0gPSBwYXJhbXM7XG5cbiAgICBjb25zdCB7IHNpZ25hYmxlSGV4LCBkZXJpdmF0aW9uUGF0aCB9ID0gdGhpcy5nZXRTaWduYWJsZUhleEFuZERlcml2YXRpb25QYXRoKFxuICAgICAgdHhSZXF1ZXN0LFxuICAgICAgJ1VuYWJsZSB0byBmaW5kIHRyYW5zYWN0aW9ucyBpbiB0eFJlcXVlc3QnXG4gICAgKTtcbiAgICBjb25zdCBhZGF0YSA9IGAke3NpZ25hYmxlSGV4fToke2Rlcml2YXRpb25QYXRofWA7XG5cbiAgICBjb25zdCB1c2VWMiA9IGlzVjJFbnZlbG9wZShlbmNyeXB0ZWRSb3VuZDFTZXNzaW9uKTtcblxuICAgIGNvbnN0IHsgYml0Z29HcGdLZXksIHVzZXJHcGdQcnZLZXkgfSA9IGF3YWl0IHRoaXMuZ2V0Qml0Z29BbmRVc2VyR3BnS2V5cyhcbiAgICAgIGJpdGdvUHVibGljR3BnS2V5LFxuICAgICAgZW5jcnlwdGVkVXNlckdwZ1BydktleSxcbiAgICAgIHdhbGxldFBhc3NwaHJhc2UsXG4gICAgICBhZGF0YSxcbiAgICAgIEVkZHNhTVBDdjJVdGlscy5NUFNfRFNHX1NJR05JTkdfVVNFUl9HUEdfS0VZXG4gICAgKTtcblxuICAgIGNvbnN0IHRyYW5zYWN0aW9ucyA9IHR4UmVxdWVzdC50cmFuc2FjdGlvbnM7XG4gICAgYXNzZXJ0KEFycmF5LmlzQXJyYXkodHJhbnNhY3Rpb25zKSAmJiB0cmFuc2FjdGlvbnMubGVuZ3RoID09PSAxLCAndHhSZXF1ZXN0IG11c3QgaGF2ZSBleGFjdGx5IG9uZSB0cmFuc2FjdGlvbicpO1xuICAgIGNvbnN0IHNpZ25hdHVyZVNoYXJlcyA9IHRyYW5zYWN0aW9uc1swXS5zaWduYXR1cmVTaGFyZXM7XG4gICAgYXNzZXJ0KHNpZ25hdHVyZVNoYXJlcywgJ01pc3Npbmcgc2lnbmF0dXJlIHNoYXJlcyBpbiByb3VuZCAxIHR4UmVxdWVzdCcpO1xuXG4gICAgY29uc3QgYml0Z29TaGFyZVJvdW5kT25lID0gZ2V0Qml0Z29TaWduYXR1cmVTaGFyZShzaWduYXR1cmVTaGFyZXMsIFNpZ25hdHVyZVNoYXJlVHlwZS5VU0VSLCAncm91bmQxT3V0cHV0Jyk7XG4gICAgY29uc3QgcGFyc2VkQml0R29Ub1VzZXJTaWdTaGFyZVJvdW5kT25lID0gZGVjb2RlV2l0aENvZGVjKFxuICAgICAgRWRkc2FNUEN2MlNpZ25hdHVyZVNoYXJlUm91bmQxT3V0cHV0LFxuICAgICAgSlNPTi5wYXJzZShiaXRnb1NoYXJlUm91bmRPbmUuc2hhcmUpLFxuICAgICAgJ1VuZXhwZWN0ZWQgc2lnbmF0dXJlIHNoYXJlIHJlc3BvbnNlLiBVbmFibGUgdG8gcGFyc2UgZGF0YS4nXG4gICAgKTtcblxuICAgIGlmIChwYXJzZWRCaXRHb1RvVXNlclNpZ1NoYXJlUm91bmRPbmUudHlwZSAhPT0gJ3JvdW5kMU91dHB1dCcpIHtcbiAgICAgIHRocm93IG5ldyBFcnJvcignVW5leHBlY3RlZCBzaWduYXR1cmUgc2hhcmUgcmVzcG9uc2UuIFVuYWJsZSB0byBwYXJzZSBkYXRhLicpO1xuICAgIH1cblxuICAgIGNvbnN0IGJpdGdvRGVzZXJpYWxpemVkTXNnMSA9IGF3YWl0IHZlcmlmeVBlZXJNZXNzYWdlUm91bmRPbmUocGFyc2VkQml0R29Ub1VzZXJTaWdTaGFyZVJvdW5kT25lLCBiaXRnb0dwZ0tleSk7XG5cbiAgICB0aGlzLnZhbGlkYXRlQWRhdGEoYWRhdGEsIGVuY3J5cHRlZFJvdW5kMVNlc3Npb24sIEVkZHNhTVBDdjJVdGlscy5NUFNfRFNHX1NJR05JTkdfUk9VTkQxX1NUQVRFKTtcblxuICAgIGNvbnN0IGRlY3J5cHRlZFJvdW5kMVNlc3Npb24gPSBhd2FpdCB0aGlzLmJpdGdvLmRlY3J5cHQoe1xuICAgICAgaW5wdXQ6IGVuY3J5cHRlZFJvdW5kMVNlc3Npb24sXG4gICAgICBwYXNzd29yZDogd2FsbGV0UGFzc3BocmFzZSxcbiAgICB9KTtcblxuICAgIGNvbnN0IHsgZHNnU2Vzc2lvbiwgdXNlck1zZ1BheWxvYWQgfSA9IEpTT04ucGFyc2UoZGVjcnlwdGVkUm91bmQxU2Vzc2lvbikgYXMge1xuICAgICAgZHNnU2Vzc2lvbjogc3RyaW5nO1xuICAgICAgdXNlck1zZ1BheWxvYWQ6IHN0cmluZztcbiAgICB9O1xuXG4gICAgY29uc3QgdXNlckRzZyA9IG5ldyBFZGRzYU1QU0RzZy5EU0coTVBDdjJQYXJ0aWVzRW51bS5VU0VSKTtcbiAgICBhd2FpdCB1c2VyRHNnLnJlc3RvcmVTZXNzaW9uKGRzZ1Nlc3Npb24pO1xuICAgIGNvbnN0IHVzZXJNc2cxOiBNUFNUeXBlcy5EZXNlcmlhbGl6ZWRNZXNzYWdlID0ge1xuICAgICAgZnJvbTogTVBDdjJQYXJ0aWVzRW51bS5VU0VSLFxuICAgICAgcGF5bG9hZDogbmV3IFVpbnQ4QXJyYXkoQnVmZmVyLmZyb20odXNlck1zZ1BheWxvYWQsICdiYXNlNjQnKSksXG4gICAgfTtcblxuICAgIGNvbnN0IFt1c2VyTXNnMl0gPSB1c2VyRHNnLmhhbmRsZUluY29taW5nTWVzc2FnZXMoW3VzZXJNc2cxLCBiaXRnb0Rlc2VyaWFsaXplZE1zZzFdKTtcbiAgICBhc3NlcnQodXNlck1zZzIsICdEU0cgaGFuZGxlSW5jb21pbmdNZXNzYWdlcyBwcm9kdWNlZCBubyByb3VuZC0yIG91dHB1dCcpO1xuXG4gICAgY29uc3Qgc2lnbmF0dXJlU2hhcmVSb3VuZDIgPSBhd2FpdCBnZXRTaWduYXR1cmVTaGFyZVJvdW5kVHdvKHVzZXJNc2cyLCB1c2VyR3BnUHJ2S2V5KTtcbiAgICBjb25zdCBzZXNzaW9uUGF5bG9hZCA9IEpTT04uc3RyaW5naWZ5KHtcbiAgICAgIGRzZ1Nlc3Npb246IHVzZXJEc2cuZ2V0U2Vzc2lvbigpLFxuICAgICAgdXNlck1zZ1BheWxvYWQ6IEJ1ZmZlci5mcm9tKHVzZXJNc2cyLnBheWxvYWQpLnRvU3RyaW5nKCdiYXNlNjQnKSxcbiAgICB9KTtcblxuICAgIGlmICh1c2VWMikge1xuICAgICAgY29uc3Qgc2Vzc2lvbiA9IGF3YWl0IHRoaXMuYml0Z28uY3JlYXRlRW5jcnlwdGlvblNlc3Npb24od2FsbGV0UGFzc3BocmFzZSk7XG4gICAgICB0cnkge1xuICAgICAgICBjb25zdCBlbmNyeXB0ZWRSb3VuZDJTZXNzaW9uID0gYXdhaXQgc2Vzc2lvbi5lbmNyeXB0KFxuICAgICAgICAgIHNlc3Npb25QYXlsb2FkLFxuICAgICAgICAgIGAke0VkZHNhTVBDdjJVdGlscy5NUFNfRFNHX1NJR05JTkdfUk9VTkQyX1NUQVRFfToke2FkYXRhfWBcbiAgICAgICAgKTtcbiAgICAgICAgcmV0dXJuIHsgc2lnbmF0dXJlU2hhcmVSb3VuZDIsIGVuY3J5cHRlZFJvdW5kMlNlc3Npb24gfTtcbiAgICAgIH0gZmluYWxseSB7XG4gICAgICAgIHNlc3Npb24uZGVzdHJveSgpO1xuICAgICAgfVxuICAgIH1cblxuICAgIGNvbnN0IGVuY3J5cHRlZFJvdW5kMlNlc3Npb24gPSBhd2FpdCB0aGlzLmJpdGdvLmVuY3J5cHQoe1xuICAgICAgaW5wdXQ6IHNlc3Npb25QYXlsb2FkLFxuICAgICAgcGFzc3dvcmQ6IHdhbGxldFBhc3NwaHJhc2UsXG4gICAgICBhZGF0YTogYCR7RWRkc2FNUEN2MlV0aWxzLk1QU19EU0dfU0lHTklOR19ST1VORDJfU1RBVEV9OiR7YWRhdGF9YCxcbiAgICAgIGVuY3J5cHRpb25WZXJzaW9uOiAxLFxuICAgIH0pO1xuXG4gICAgcmV0dXJuIHsgc2lnbmF0dXJlU2hhcmVSb3VuZDIsIGVuY3J5cHRlZFJvdW5kMlNlc3Npb24gfTtcbiAgfVxuICAvLyAjZW5kcmVnaW9uXG5cbiAgLy8gI3JlZ2lvbiBSb3VuZDNTaGFyZVxuICBhc3luYyBjcmVhdGVPZmZsaW5lUm91bmQzU2hhcmUocGFyYW1zOiB7XG4gICAgdHhSZXF1ZXN0OiBUeFJlcXVlc3Q7XG4gICAgd2FsbGV0UGFzc3BocmFzZTogc3RyaW5nO1xuICAgIGJpdGdvUHVibGljR3BnS2V5OiBzdHJpbmc7XG4gICAgZW5jcnlwdGVkVXNlckdwZ1BydktleTogc3RyaW5nO1xuICAgIGVuY3J5cHRlZFJvdW5kMlNlc3Npb246IHN0cmluZztcbiAgfSk6IFByb21pc2U8e1xuICAgIHNpZ25hdHVyZVNoYXJlUm91bmQzOiBTaWduYXR1cmVTaGFyZVJlY29yZDtcbiAgfT4ge1xuICAgIGNvbnN0IHsgd2FsbGV0UGFzc3BocmFzZSwgZW5jcnlwdGVkVXNlckdwZ1BydktleSwgZW5jcnlwdGVkUm91bmQyU2Vzc2lvbiwgYml0Z29QdWJsaWNHcGdLZXksIHR4UmVxdWVzdCB9ID0gcGFyYW1zO1xuXG4gICAgY29uc3QgeyBzaWduYWJsZUhleCwgZGVyaXZhdGlvblBhdGggfSA9IHRoaXMuZ2V0U2lnbmFibGVIZXhBbmREZXJpdmF0aW9uUGF0aChcbiAgICAgIHR4UmVxdWVzdCxcbiAgICAgICdVbmFibGUgdG8gZmluZCB0cmFuc2FjdGlvbnMgaW4gdHhSZXF1ZXN0J1xuICAgICk7XG4gICAgY29uc3QgYWRhdGEgPSBgJHtzaWduYWJsZUhleH06JHtkZXJpdmF0aW9uUGF0aH1gO1xuXG4gICAgY29uc3QgeyBiaXRnb0dwZ0tleSwgdXNlckdwZ1BydktleSB9ID0gYXdhaXQgdGhpcy5nZXRCaXRnb0FuZFVzZXJHcGdLZXlzKFxuICAgICAgYml0Z29QdWJsaWNHcGdLZXksXG4gICAgICBlbmNyeXB0ZWRVc2VyR3BnUHJ2S2V5LFxuICAgICAgd2FsbGV0UGFzc3BocmFzZSxcbiAgICAgIGFkYXRhLFxuICAgICAgRWRkc2FNUEN2MlV0aWxzLk1QU19EU0dfU0lHTklOR19VU0VSX0dQR19LRVlcbiAgICApO1xuXG4gICAgY29uc3QgdHJhbnNhY3Rpb25zID0gdHhSZXF1ZXN0LnRyYW5zYWN0aW9ucztcbiAgICBhc3NlcnQoQXJyYXkuaXNBcnJheSh0cmFuc2FjdGlvbnMpICYmIHRyYW5zYWN0aW9ucy5sZW5ndGggPT09IDEsICd0eFJlcXVlc3QgbXVzdCBoYXZlIGV4YWN0bHkgb25lIHRyYW5zYWN0aW9uJyk7XG4gICAgY29uc3Qgc2lnbmF0dXJlU2hhcmVzID0gdHJhbnNhY3Rpb25zWzBdLnNpZ25hdHVyZVNoYXJlcztcbiAgICBhc3NlcnQoc2lnbmF0dXJlU2hhcmVzLCAnTWlzc2luZyBzaWduYXR1cmUgc2hhcmVzIGluIHJvdW5kIDIgdHhSZXF1ZXN0Jyk7XG5cbiAgICBjb25zdCBiaXRnb1NoYXJlUm91bmRUd28gPSBnZXRCaXRnb1NpZ25hdHVyZVNoYXJlKHNpZ25hdHVyZVNoYXJlcywgU2lnbmF0dXJlU2hhcmVUeXBlLlVTRVIsICdyb3VuZDJPdXRwdXQnKTtcblxuICAgIGNvbnN0IHBhcnNlZEJpdEdvVG9Vc2VyU2lnU2hhcmVSb3VuZFR3byA9IGRlY29kZVdpdGhDb2RlYyhcbiAgICAgIEVkZHNhTVBDdjJTaWduYXR1cmVTaGFyZVJvdW5kMk91dHB1dCxcbiAgICAgIEpTT04ucGFyc2UoYml0Z29TaGFyZVJvdW5kVHdvLnNoYXJlKSxcbiAgICAgICdVbmV4cGVjdGVkIHNpZ25hdHVyZSBzaGFyZSByZXNwb25zZS4gVW5hYmxlIHRvIHBhcnNlIGRhdGEuJ1xuICAgICk7XG5cbiAgICBpZiAocGFyc2VkQml0R29Ub1VzZXJTaWdTaGFyZVJvdW5kVHdvLnR5cGUgIT09ICdyb3VuZDJPdXRwdXQnKSB7XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoJ1VuZXhwZWN0ZWQgc2lnbmF0dXJlIHNoYXJlIHJlc3BvbnNlLiBVbmFibGUgdG8gcGFyc2UgZGF0YS4nKTtcbiAgICB9XG5cbiAgICBjb25zdCBiaXRnb0Rlc2VyaWFsaXplZE1zZzIgPSBhd2FpdCB2ZXJpZnlQZWVyTWVzc2FnZVJvdW5kVHdvKHBhcnNlZEJpdEdvVG9Vc2VyU2lnU2hhcmVSb3VuZFR3bywgYml0Z29HcGdLZXkpO1xuXG4gICAgdGhpcy52YWxpZGF0ZUFkYXRhKGFkYXRhLCBlbmNyeXB0ZWRSb3VuZDJTZXNzaW9uLCBFZGRzYU1QQ3YyVXRpbHMuTVBTX0RTR19TSUdOSU5HX1JPVU5EMl9TVEFURSk7XG5cbiAgICBjb25zdCBkZWNyeXB0ZWRSb3VuZDJTZXNzaW9uID0gYXdhaXQgdGhpcy5iaXRnby5kZWNyeXB0KHtcbiAgICAgIGlucHV0OiBlbmNyeXB0ZWRSb3VuZDJTZXNzaW9uLFxuICAgICAgcGFzc3dvcmQ6IHdhbGxldFBhc3NwaHJhc2UsXG4gICAgfSk7XG5cbiAgICBjb25zdCB7IGRzZ1Nlc3Npb24sIHVzZXJNc2dQYXlsb2FkIH0gPSBKU09OLnBhcnNlKGRlY3J5cHRlZFJvdW5kMlNlc3Npb24pIGFzIHtcbiAgICAgIGRzZ1Nlc3Npb246IHN0cmluZztcbiAgICAgIHVzZXJNc2dQYXlsb2FkOiBzdHJpbmc7XG4gICAgfTtcblxuICAgIGNvbnN0IHVzZXJEc2cgPSBuZXcgRWRkc2FNUFNEc2cuRFNHKE1QQ3YyUGFydGllc0VudW0uVVNFUik7XG4gICAgYXdhaXQgdXNlckRzZy5yZXN0b3JlU2Vzc2lvbihkc2dTZXNzaW9uKTtcbiAgICBjb25zdCB1c2VyTXNnMjogTVBTVHlwZXMuRGVzZXJpYWxpemVkTWVzc2FnZSA9IHtcbiAgICAgIGZyb206IE1QQ3YyUGFydGllc0VudW0uVVNFUixcbiAgICAgIHBheWxvYWQ6IG5ldyBVaW50OEFycmF5KEJ1ZmZlci5mcm9tKHVzZXJNc2dQYXlsb2FkLCAnYmFzZTY0JykpLFxuICAgIH07XG5cbiAgICBjb25zdCBbdXNlck1zZzNdID0gdXNlckRzZy5oYW5kbGVJbmNvbWluZ01lc3NhZ2VzKFt1c2VyTXNnMiwgYml0Z29EZXNlcmlhbGl6ZWRNc2cyXSk7XG4gICAgYXNzZXJ0KHVzZXJNc2czLCAnRFNHIGhhbmRsZUluY29taW5nTWVzc2FnZXMgcHJvZHVjZWQgbm8gcm91bmQtMyBvdXRwdXQnKTtcblxuICAgIGNvbnN0IHNpZ25hdHVyZVNoYXJlUm91bmQzID0gYXdhaXQgZ2V0U2lnbmF0dXJlU2hhcmVSb3VuZFRocmVlKHVzZXJNc2czLCB1c2VyR3BnUHJ2S2V5KTtcblxuICAgIHJldHVybiB7IHNpZ25hdHVyZVNoYXJlUm91bmQzIH07XG4gIH1cbiAgLy8gI2VuZHJlZ2lvblxuXG4gIC8qKiBAaW5oZXJpdGRvYyAqL1xuICBhc3luYyBzaWduRWRkc2FNUEN2MlRzc1VzaW5nRXh0ZXJuYWxTaWduZXIoXG4gICAgcGFyYW1zOiBUU1NQYXJhbXMgfCBUU1NQYXJhbXNGb3JNZXNzYWdlLFxuICAgIGV4dGVybmFsU2lnbmVyRWRkc2FNUEN2MlNpZ25pbmdSb3VuZDFHZW5lcmF0b3I6IEN1c3RvbUVkZHNhTVBDdjJTaWduaW5nUm91bmQxR2VuZXJhdGluZ0Z1bmN0aW9uLFxuICAgIGV4dGVybmFsU2lnbmVyRWRkc2FNUEN2MlNpZ25pbmdSb3VuZDJHZW5lcmF0b3I6IEN1c3RvbUVkZHNhTVBDdjJTaWduaW5nUm91bmQyR2VuZXJhdGluZ0Z1bmN0aW9uLFxuICAgIGV4dGVybmFsU2lnbmVyRWRkc2FNUEN2MlNpZ25pbmdSb3VuZDNHZW5lcmF0b3I6IEN1c3RvbUVkZHNhTVBDdjJTaWduaW5nUm91bmQzR2VuZXJhdGluZ0Z1bmN0aW9uLFxuICAgIHJlcXVlc3RUeXBlOiBSZXF1ZXN0VHlwZSA9IFJlcXVlc3RUeXBlLnR4XG4gICk6IFByb21pc2U8VHhSZXF1ZXN0PiB7XG4gICAgY29uc3QgeyB0eFJlcXVlc3QsIHJlcUlkIH0gPSBwYXJhbXM7XG5cbiAgICAvLyBUT0RPKFdQLTIxNzYpOiBBZGQgc3VwcG9ydCBmb3IgbWVzc2FnZSBzaWduaW5nXG4gICAgYXNzZXJ0KFxuICAgICAgcmVxdWVzdFR5cGUgPT09IFJlcXVlc3RUeXBlLnR4LFxuICAgICAgJ09ubHkgdHJhbnNhY3Rpb24gc2lnbmluZyBpcyBzdXBwb3J0ZWQgZm9yIGV4dGVybmFsIHNpZ25lciwgZ290OiAnICsgcmVxdWVzdFR5cGVcbiAgICApO1xuXG4gICAgbGV0IHR4UmVxdWVzdFJlc29sdmVkOiBUeFJlcXVlc3Q7XG4gICAgaWYgKHR5cGVvZiB0eFJlcXVlc3QgPT09ICdzdHJpbmcnKSB7XG4gICAgICB0eFJlcXVlc3RSZXNvbHZlZCA9IGF3YWl0IGdldFR4UmVxdWVzdCh0aGlzLmJpdGdvLCB0aGlzLndhbGxldC5pZCgpLCB0eFJlcXVlc3QsIHJlcUlkKTtcbiAgICB9IGVsc2Uge1xuICAgICAgdHhSZXF1ZXN0UmVzb2x2ZWQgPSB0eFJlcXVlc3Q7XG4gICAgfVxuXG4gICAgY29uc3QgYml0Z29QdWJsaWNHcGdLZXkgPSBhd2FpdCB0aGlzLnBpY2tCaXRnb1B1YkdwZ0tleUZvclNpZ25pbmcoXG4gICAgICB0cnVlLFxuICAgICAgcmVxSWQsXG4gICAgICB0eFJlcXVlc3RSZXNvbHZlZC5lbnRlcnByaXNlSWQsXG4gICAgICB0cnVlXG4gICAgKTtcblxuICAgIGlmICghYml0Z29QdWJsaWNHcGdLZXkpIHtcbiAgICAgIHRocm93IG5ldyBFcnJvcignTWlzc2luZyBCaXRHbyBHUEcga2V5IGZvciBNUEN2MicpO1xuICAgIH1cblxuICAgIC8vIHJvdW5kIDFcbiAgICBjb25zdCB7IHNpZ25hdHVyZVNoYXJlUm91bmQxLCB1c2VyR3BnUHViS2V5LCBlbmNyeXB0ZWRSb3VuZDFTZXNzaW9uLCBlbmNyeXB0ZWRVc2VyR3BnUHJ2S2V5IH0gPVxuICAgICAgYXdhaXQgZXh0ZXJuYWxTaWduZXJFZGRzYU1QQ3YyU2lnbmluZ1JvdW5kMUdlbmVyYXRvcih7IHR4UmVxdWVzdDogdHhSZXF1ZXN0UmVzb2x2ZWQgfSk7XG4gICAgY29uc3Qgcm91bmQxVHhSZXF1ZXN0ID0gYXdhaXQgc2VuZFNpZ25hdHVyZVNoYXJlVjIoXG4gICAgICB0aGlzLmJpdGdvLFxuICAgICAgdHhSZXF1ZXN0UmVzb2x2ZWQud2FsbGV0SWQsXG4gICAgICB0eFJlcXVlc3RSZXNvbHZlZC50eFJlcXVlc3RJZCxcbiAgICAgIFtzaWduYXR1cmVTaGFyZVJvdW5kMV0sXG4gICAgICByZXF1ZXN0VHlwZSxcbiAgICAgIHRoaXMuYmFzZUNvaW4uZ2V0TVBDQWxnb3JpdGhtKCksXG4gICAgICB1c2VyR3BnUHViS2V5LFxuICAgICAgdW5kZWZpbmVkLFxuICAgICAgdGhpcy53YWxsZXQubXVsdGlzaWdUeXBlVmVyc2lvbigpLFxuICAgICAgcmVxSWRcbiAgICApO1xuXG4gICAgLy8gcm91bmQgMlxuICAgIGNvbnN0IHsgc2lnbmF0dXJlU2hhcmVSb3VuZDIsIGVuY3J5cHRlZFJvdW5kMlNlc3Npb24gfSA9IGF3YWl0IGV4dGVybmFsU2lnbmVyRWRkc2FNUEN2MlNpZ25pbmdSb3VuZDJHZW5lcmF0b3Ioe1xuICAgICAgdHhSZXF1ZXN0OiByb3VuZDFUeFJlcXVlc3QsXG4gICAgICBlbmNyeXB0ZWRSb3VuZDFTZXNzaW9uLFxuICAgICAgZW5jcnlwdGVkVXNlckdwZ1BydktleSxcbiAgICAgIGJpdGdvUHVibGljR3BnS2V5OiBiaXRnb1B1YmxpY0dwZ0tleS5hcm1vcigpLFxuICAgIH0pO1xuICAgIGNvbnN0IHJvdW5kMlR4UmVxdWVzdCA9IGF3YWl0IHNlbmRTaWduYXR1cmVTaGFyZVYyKFxuICAgICAgdGhpcy5iaXRnbyxcbiAgICAgIHR4UmVxdWVzdFJlc29sdmVkLndhbGxldElkLFxuICAgICAgdHhSZXF1ZXN0UmVzb2x2ZWQudHhSZXF1ZXN0SWQsXG4gICAgICBbc2lnbmF0dXJlU2hhcmVSb3VuZDJdLFxuICAgICAgcmVxdWVzdFR5cGUsXG4gICAgICB0aGlzLmJhc2VDb2luLmdldE1QQ0FsZ29yaXRobSgpLFxuICAgICAgdXNlckdwZ1B1YktleSxcbiAgICAgIHVuZGVmaW5lZCxcbiAgICAgIHRoaXMud2FsbGV0Lm11bHRpc2lnVHlwZVZlcnNpb24oKSxcbiAgICAgIHJlcUlkXG4gICAgKTtcbiAgICBhc3NlcnQoXG4gICAgICByb3VuZDJUeFJlcXVlc3QudHJhbnNhY3Rpb25zICYmIHJvdW5kMlR4UmVxdWVzdC50cmFuc2FjdGlvbnNbMF0uc2lnbmF0dXJlU2hhcmVzLFxuICAgICAgJ01pc3Npbmcgc2lnbmF0dXJlIHNoYXJlcyBpbiByb3VuZCAyIHR4UmVxdWVzdCdcbiAgICApO1xuXG4gICAgLy8gcm91bmQgM1xuICAgIGNvbnN0IHsgc2lnbmF0dXJlU2hhcmVSb3VuZDMgfSA9IGF3YWl0IGV4dGVybmFsU2lnbmVyRWRkc2FNUEN2MlNpZ25pbmdSb3VuZDNHZW5lcmF0b3Ioe1xuICAgICAgdHhSZXF1ZXN0OiByb3VuZDJUeFJlcXVlc3QsXG4gICAgICBlbmNyeXB0ZWRSb3VuZDJTZXNzaW9uLFxuICAgICAgZW5jcnlwdGVkVXNlckdwZ1BydktleSxcbiAgICAgIGJpdGdvUHVibGljR3BnS2V5OiBiaXRnb1B1YmxpY0dwZ0tleS5hcm1vcigpLFxuICAgIH0pO1xuICAgIGF3YWl0IHNlbmRTaWduYXR1cmVTaGFyZVYyKFxuICAgICAgdGhpcy5iaXRnbyxcbiAgICAgIHR4UmVxdWVzdFJlc29sdmVkLndhbGxldElkLFxuICAgICAgdHhSZXF1ZXN0UmVzb2x2ZWQudHhSZXF1ZXN0SWQsXG4gICAgICBbc2lnbmF0dXJlU2hhcmVSb3VuZDNdLFxuICAgICAgcmVxdWVzdFR5cGUsXG4gICAgICB0aGlzLmJhc2VDb2luLmdldE1QQ0FsZ29yaXRobSgpLFxuICAgICAgdXNlckdwZ1B1YktleSxcbiAgICAgIHVuZGVmaW5lZCxcbiAgICAgIHRoaXMud2FsbGV0Lm11bHRpc2lnVHlwZVZlcnNpb24oKSxcbiAgICAgIHJlcUlkXG4gICAgKTtcblxuICAgIHJldHVybiBzZW5kVHhSZXF1ZXN0KHRoaXMuYml0Z28sIHR4UmVxdWVzdFJlc29sdmVkLndhbGxldElkLCB0eFJlcXVlc3RSZXNvbHZlZC50eFJlcXVlc3RJZCwgcmVxdWVzdFR5cGUsIHJlcUlkKTtcbiAgfVxuICAvLyAjZW5kcmVnaW9uXG5cbiAgLy8gI3JlZ2lvbiByZXRyb2ZpdFxuXG4gIHByaXZhdGUgYXN5bmMgZ2V0VXNlckFuZEJhY2t1cFNlc3Npb24ocmV0cm9maXQ/OiBEZWNyeXB0ZWRSZXRyb2ZpdFBheWxvYWQpOiBQcm9taXNlPHtcbiAgICB1c2VyRGtnOiBFZGRzYU1QU0RrZy5ES0c7XG4gICAgYmFja3VwRGtnOiBFZGRzYU1QU0RrZy5ES0c7XG4gIH0+IHtcbiAgICBpZiAocmV0cm9maXQpIHtcbiAgICAgIGNvbnN0IHsgdXNlclJldHJvZml0RGF0YSwgYmFja3VwUmV0cm9maXREYXRhIH0gPSBhd2FpdCB0aGlzLmdldE1wY1YyUmV0cm9maXREYXRhRnJvbU1wY1YxS2V5cyh7XG4gICAgICAgIG1wY3YxVXNlcktleVNoYXJlOiByZXRyb2ZpdC5kZWNyeXB0ZWRVc2VyS2V5LFxuICAgICAgICBtcGN2MUJhY2t1cEtleVNoYXJlOiByZXRyb2ZpdC5kZWNyeXB0ZWRCYWNrdXBLZXksXG4gICAgICB9KTtcbiAgICAgIHJldHVybiB7XG4gICAgICAgIHVzZXJEa2c6IG5ldyBFZGRzYU1QU0RrZy5ES0coMywgMiwgTVBDdjJQYXJ0aWVzRW51bS5VU0VSLCB1c2VyUmV0cm9maXREYXRhKSxcbiAgICAgICAgYmFja3VwRGtnOiBuZXcgRWRkc2FNUFNEa2cuREtHKDMsIDIsIE1QQ3YyUGFydGllc0VudW0uQkFDS1VQLCBiYWNrdXBSZXRyb2ZpdERhdGEpLFxuICAgICAgfTtcbiAgICB9XG4gICAgcmV0dXJuIHtcbiAgICAgIHVzZXJEa2c6IG5ldyBFZGRzYU1QU0RrZy5ES0coMywgMiwgTVBDdjJQYXJ0aWVzRW51bS5VU0VSKSxcbiAgICAgIGJhY2t1cERrZzogbmV3IEVkZHNhTVBTRGtnLkRLRygzLCAyLCBNUEN2MlBhcnRpZXNFbnVtLkJBQ0tVUCksXG4gICAgfTtcbiAgfVxuXG4gIGFzeW5jIGdldE1wY1YyUmV0cm9maXREYXRhRnJvbU1wY1YxS2V5cyhwYXJhbXM6IHsgbXBjdjFVc2VyS2V5U2hhcmU6IHN0cmluZzsgbXBjdjFCYWNrdXBLZXlTaGFyZTogc3RyaW5nIH0pOiBQcm9taXNlPHtcbiAgICB1c2VyUmV0cm9maXREYXRhOiBNUFNUeXBlcy5FZGRzYVJldHJvZml0RGF0YTtcbiAgICBiYWNrdXBSZXRyb2ZpdERhdGE6IE1QU1R5cGVzLkVkZHNhUmV0cm9maXREYXRhO1xuICB9PiB7XG4gICAgY29uc3QgTVBDID0gYXdhaXQgZ2V0SW5pdGlhbGl6ZWRNcGNJbnN0YW5jZSgpO1xuICAgIGNvbnN0IHVzZXJSZXRyb2ZpdERhdGEgPSBFZGRzYU1QQ3YyVXRpbHMuZ2V0TXBjVjJSZXRyb2ZpdERhdGFGcm9tTXBjVjFLZXkoXG4gICAgICBwYXJhbXMubXBjdjFVc2VyS2V5U2hhcmUsXG4gICAgICBNUEN2MlBhcnRpZXNFbnVtLlVTRVIsXG4gICAgICBNUENcbiAgICApO1xuICAgIGNvbnN0IGJhY2t1cFJldHJvZml0RGF0YSA9IEVkZHNhTVBDdjJVdGlscy5nZXRNcGNWMlJldHJvZml0RGF0YUZyb21NcGNWMUtleShcbiAgICAgIHBhcmFtcy5tcGN2MUJhY2t1cEtleVNoYXJlLFxuICAgICAgTVBDdjJQYXJ0aWVzRW51bS5CQUNLVVAsXG4gICAgICBNUENcbiAgICApO1xuXG4gICAgYXNzZXJ0KFxuICAgICAgdXNlclJldHJvZml0RGF0YS5leHBlY3RlZFBrID09PSBiYWNrdXBSZXRyb2ZpdERhdGEuZXhwZWN0ZWRQayxcbiAgICAgICdNUEN2MSB1c2VyIGFuZCBiYWNrdXAga2V5cyBjb21iaW5lIHRvIGRpZmZlcmVudCBhZ2dyZWdhdGUgcHVibGljIGtleXMnXG4gICAgKTtcbiAgICBhc3NlcnQoXG4gICAgICB1c2VyUmV0cm9maXREYXRhLmNoYWluQ29kZSA9PT0gYmFja3VwUmV0cm9maXREYXRhLmNoYWluQ29kZSxcbiAgICAgICdNUEN2MSB1c2VyIGFuZCBiYWNrdXAga2V5cyBjb21iaW5lIHRvIGRpZmZlcmVudCBjaGFpbiBjb2RlcydcbiAgICApO1xuXG4gICAgcmV0dXJuIHsgdXNlclJldHJvZml0RGF0YSwgYmFja3VwUmV0cm9maXREYXRhIH07XG4gIH1cblxuICBwcml2YXRlIHN0YXRpYyBnZXRNcGNWMlJldHJvZml0RGF0YUZyb21NcGNWMUtleShcbiAgICBtcGN2MVBhcnR5S2V5U2hhcmU6IHN0cmluZyxcbiAgICBtcGN2MVBhcnR5SW5kZXg6IE1QQ3YyUGFydGllc0VudW0uVVNFUiB8IE1QQ3YyUGFydGllc0VudW0uQkFDS1VQLFxuICAgIG1wYzogQXdhaXRlZDxSZXR1cm5UeXBlPHR5cGVvZiBnZXRJbml0aWFsaXplZE1wY0luc3RhbmNlPj5cbiAgKTogTVBTVHlwZXMuRWRkc2FSZXRyb2ZpdERhdGEge1xuICAgIGNvbnN0IHNpZ25pbmdNYXRlcmlhbDogU2lnbmluZ01hdGVyaWFsID0gSlNPTi5wYXJzZShtcGN2MVBhcnR5S2V5U2hhcmUpO1xuICAgIGFzc2VydChzaWduaW5nTWF0ZXJpYWwudVNoYXJlLCAnTVBDdjEga2V5IG1hdGVyaWFsIG1pc3NpbmcgdVNoYXJlJyk7XG4gICAgYXNzZXJ0KHNpZ25pbmdNYXRlcmlhbC5iaXRnb1lTaGFyZSwgJ01QQ3YxIGtleSBtYXRlcmlhbCBtaXNzaW5nIGJpdGdvWVNoYXJlJyk7XG5cbiAgICBsZXQgcFNoYXJlO1xuICAgIHN3aXRjaCAobXBjdjFQYXJ0eUluZGV4KSB7XG4gICAgICBjYXNlIE1QQ3YyUGFydGllc0VudW0uVVNFUjpcbiAgICAgICAgYXNzZXJ0KHNpZ25pbmdNYXRlcmlhbC5iYWNrdXBZU2hhcmUsICdVc2VyIE1QQ3YxIGtleSBtYXRlcmlhbCBtaXNzaW5nIGJhY2t1cFlTaGFyZScpO1xuICAgICAgICBwU2hhcmUgPSBtcGMua2V5Q29tYmluZShzaWduaW5nTWF0ZXJpYWwudVNoYXJlLCBbXG4gICAgICAgICAgc2lnbmluZ01hdGVyaWFsLmJpdGdvWVNoYXJlLFxuICAgICAgICAgIHNpZ25pbmdNYXRlcmlhbC5iYWNrdXBZU2hhcmUsXG4gICAgICAgIF0pLnBTaGFyZTtcbiAgICAgICAgYnJlYWs7XG4gICAgICBjYXNlIE1QQ3YyUGFydGllc0VudW0uQkFDS1VQOlxuICAgICAgICBhc3NlcnQoc2lnbmluZ01hdGVyaWFsLnVzZXJZU2hhcmUsICdCYWNrdXAgTVBDdjEga2V5IG1hdGVyaWFsIG1pc3NpbmcgdXNlcllTaGFyZScpO1xuICAgICAgICBwU2hhcmUgPSBtcGMua2V5Q29tYmluZShzaWduaW5nTWF0ZXJpYWwudVNoYXJlLCBbXG4gICAgICAgICAgc2lnbmluZ01hdGVyaWFsLmJpdGdvWVNoYXJlLFxuICAgICAgICAgIHNpZ25pbmdNYXRlcmlhbC51c2VyWVNoYXJlLFxuICAgICAgICBdKS5wU2hhcmU7XG4gICAgICAgIGJyZWFrO1xuICAgICAgZGVmYXVsdDpcbiAgICAgICAgdGhyb3cgbmV3IEVycm9yKCdJbnZhbGlkIHBhcnRpY2lwYW50IGluZGV4Jyk7XG4gICAgfVxuXG4gICAgcmV0dXJuIHtcbiAgICAgIHNfaV8wOiBwU2hhcmUudSxcbiAgICAgIGV4cGVjdGVkUGs6IHBTaGFyZS55LFxuICAgICAgY2hhaW5Db2RlOiBwU2hhcmUuY2hhaW5jb2RlLFxuICAgIH07XG4gIH1cblxuICAvLyAjZW5kcmVnaW9uXG59XG5cbi8qKlxuICogRGV0ZWN0IHdoZXRoZXIgYW4gZW5jcnlwdGVkIGtleWNhcmQgY29udGFpbnMgTVBDdjEgc2lnbmluZyBtYXRlcmlhbC5cbiAqXG4gKiBEZWNyeXB0cyB0aGUga2V5Y2FyZCBhbmQgY2hlY2tzIGZvciB0aGUgSlNPTiBzaGFwZSBwcm9kdWNlZCBieSB0aGUgTVBDdjEgVFNTXG4gKiBrZXktZ2VuZXJhdGlvbiBmbG93ICh1U2hhcmUuc2VlZCArIGJpdGdvWVNoYXJlLnUgKyBiYWNrdXBZU2hhcmUudSAvIHVzZXJZU2hhcmUudSkuXG4gKiBSZXR1cm5zIGZhbHNlIGZvciBNUEN2MiBDQk9SIGtleWNhcmRzLCB3cm9uZyBwYXNzd29yZHMsIG9yIGFueSBkZWNyeXB0aW9uIGVycm9yLlxuICpcbiAqIEBwYXJhbSBlbmNyeXB0ZWRLZXlTaGFyZSBlbmNyeXB0ZWQgdXNlciBvciBiYWNrdXAga2V5Y2FyZFxuICogQHBhcmFtIHdhbGxldFBhc3NwaHJhc2UgcGFzc3BocmFzZSB1c2VkIHRvIGVuY3J5cHQgdGhlIGtleWNhcmRcbiAqIEBwYXJhbSBiaXRnbyBvcHRpb25hbCBCaXRHb0Jhc2UgaW5zdGFuY2U7IHdoZW4gcHJvdmlkZWQsIGRlY3J5cHRzIHZpYVxuICogICBiaXRnby5kZWNyeXB0IChzdXBwb3J0cyBib3RoIHYxIFNKQ0wgYW5kIHYyIEFyZ29uMmlkIGVudmVsb3Blcyk7XG4gKiAgIHdoZW4gYWJzZW50LCBmYWxscyBiYWNrIHRvIHNqY2wuZGVjcnlwdCAodjEgb25seSlcbiAqL1xuZnVuY3Rpb24gcGFyc2VFZGRzYU1wY1YxTWF0ZXJpYWwoZGVjcnlwdGVkOiBzdHJpbmcpOiBzdHJpbmcgfCBudWxsIHtcbiAgdHJ5IHtcbiAgICBjb25zdCBtID0gSlNPTi5wYXJzZShkZWNyeXB0ZWQpO1xuICAgIGlmIChcbiAgICAgIHR5cGVvZiBtPy51U2hhcmU/LnNlZWQgPT09ICdzdHJpbmcnICYmXG4gICAgICB0eXBlb2YgbT8uYml0Z29ZU2hhcmU/LnUgPT09ICdzdHJpbmcnICYmXG4gICAgICAodHlwZW9mIG0/LmJhY2t1cFlTaGFyZT8udSA9PT0gJ3N0cmluZycgfHwgdHlwZW9mIG0/LnVzZXJZU2hhcmU/LnUgPT09ICdzdHJpbmcnKVxuICAgICkge1xuICAgICAgcmV0dXJuIGRlY3J5cHRlZDtcbiAgICB9XG4gIH0gY2F0Y2gge1xuICAgIC8vIE5vdCBKU09OIOKGkiBNUEN2MiBDQk9SXG4gIH1cbiAgcmV0dXJuIG51bGw7XG59XG5cbmV4cG9ydCBhc3luYyBmdW5jdGlvbiBpc0VkZHNhTXBjVjFTaWduaW5nTWF0ZXJpYWwoXG4gIGVuY3J5cHRlZEtleVNoYXJlOiBzdHJpbmcsXG4gIHdhbGxldFBhc3NwaHJhc2U6IHN0cmluZyxcbiAgYml0Z28/OiBCaXRHb0Jhc2Vcbik6IFByb21pc2U8Ym9vbGVhbj4ge1xuICBjb25zdCBkZWNyeXB0ZWQgPSBiaXRnb1xuICAgID8gYXdhaXQgYml0Z28uZGVjcnlwdCh7IGlucHV0OiBlbmNyeXB0ZWRLZXlTaGFyZSwgcGFzc3dvcmQ6IHdhbGxldFBhc3NwaHJhc2UgfSlcbiAgICA6IHNqY2wuZGVjcnlwdCh3YWxsZXRQYXNzcGhyYXNlLCBlbmNyeXB0ZWRLZXlTaGFyZSk7XG4gIHJldHVybiBwYXJzZUVkZHNhTXBjVjFNYXRlcmlhbChkZWNyeXB0ZWQpICE9PSBudWxsO1xufVxuXG4vKipcbiAqIEdldCBFZERTQSBNUEN2MiByZWNvdmVyeSBrZXkgc2hhcmVzIGZyb20gZW5jcnlwdGVkIHJlZHVjZWQgdXNlciBhbmQgYmFja3VwIGtleXMuXG4gKlxuICogVGhlIGVuY3J5cHRlZCBpbnB1dHMgYXJlIHRoZSBgcmVkdWNlZEVuY3J5cHRlZFBydmAgdmFsdWVzIHN0b3JlZCBvbiBFZERTQSBNUEN2MlxuICoga2V5IGNhcmRzLiBUaGV5IGRlY3J5cHQgdG8gQ0JPUi1lbmNvZGVkIHJlZHVjZWQgc2hhcmVzIHRoYXQgY29udGFpbiB0aGUgb3BhcXVlXG4gKiBNUFMgc2lnbmluZyBrZXktc2hhcmUgYnl0ZXMgcGx1cyB0aGUgY29tbW9uIHB1YmxpYyBrZXljaGFpbiBtYXRlcmlhbC5cbiAqXG4gKiBAcGFyYW0gZW5jcnlwdGVkVXNlcktleSBlbmNyeXB0ZWQgRWREU0EgTVBDdjIgcmVkdWNlZCB1c2VyIGtleVxuICogQHBhcmFtIGVuY3J5cHRlZEJhY2t1cEtleSBlbmNyeXB0ZWQgRWREU0EgTVBDdjIgcmVkdWNlZCBiYWNrdXAga2V5XG4gKiBAcGFyYW0gd2FsbGV0UGFzc3BocmFzZSBwYXNzd29yZCBmb3IgdXNlciBhbmQgYmFja3VwIGtleXNcbiAqIEByZXR1cm5zIEVkRFNBIE1QQ3YyIHJlY292ZXJ5IGtleSBzaGFyZXMgYW5kIGNvbW1vbiBrZXljaGFpblxuICovXG5leHBvcnQgYXN5bmMgZnVuY3Rpb24gZ2V0RWRkc2FNcGNWMlJlY292ZXJ5S2V5U2hhcmVzRnJvbVJlZHVjZWRLZXkoXG4gIGVuY3J5cHRlZFVzZXJLZXk6IHN0cmluZyxcbiAgZW5jcnlwdGVkQmFja3VwS2V5OiBzdHJpbmcsXG4gIHdhbGxldFBhc3NwaHJhc2U/OiBzdHJpbmcsXG4gIGJpdGdvPzogQml0R29CYXNlXG4pOiBQcm9taXNlPEVkZHNhTVBDdjJSZWNvdmVyeUtleVNoYXJlcz4ge1xuICBjb25zdCBkZWNvZGVLZXkgPSBhc3luYyAoZW5jcnlwdGVkS2V5OiBzdHJpbmcpOiBQcm9taXNlPE1QU1R5cGVzLkVkZHNhUmVkdWNlZEtleVNoYXJlPiA9PiB7XG4gICAgY29uc3QgZGVjcnlwdGVkID0gYml0Z29cbiAgICAgID8gYXdhaXQgYml0Z28uZGVjcnlwdCh7IGlucHV0OiBlbmNyeXB0ZWRLZXksIHBhc3N3b3JkOiB3YWxsZXRQYXNzcGhyYXNlIH0pXG4gICAgICA6IHNqY2wuZGVjcnlwdCh3YWxsZXRQYXNzcGhyYXNlLCBlbmNyeXB0ZWRLZXkpO1xuICAgIGxldCByZWR1Y2VkOiBNUFNUeXBlcy5FZGRzYVJlZHVjZWRLZXlTaGFyZTtcbiAgICB0cnkge1xuICAgICAgcmVkdWNlZCA9IE1QU1R5cGVzLmdldERlY29kZWRSZWR1Y2VkS2V5U2hhcmUoQnVmZmVyLmZyb20oZGVjcnlwdGVkLCAnYmFzZTY0JykpO1xuICAgIH0gY2F0Y2gge1xuICAgICAgdGhyb3cgbmV3IEVycm9yKFxuICAgICAgICAnRWREU0EgTVBDdjIgcmVjb3Zlcnk6IHVuYWJsZSB0byBkZWNvZGUgcmVkdWNlZCBrZXkgc2hhcmUgZnJvbSBrZXljYXJkIG1hdGVyaWFsLiBUaGUgZW5jcnlwdGVkIGtleSBtYXkgYmUgY29ycnVwdGVkLCBtYWxmb3JtZWQsIG9yIG5vdCBhbiBFZERTQSBNUEN2MiByZWR1Y2VkIGtleS4nXG4gICAgICApO1xuICAgIH1cbiAgICBpZiAoIXJlZHVjZWQua2V5U2hhcmU/Lmxlbmd0aCB8fCAhcmVkdWNlZC5wdWI/Lmxlbmd0aCB8fCAhcmVkdWNlZC5yb290Q2hhaW5Db2RlPy5sZW5ndGgpIHtcbiAgICAgIHRocm93IG5ldyBFcnJvcihcbiAgICAgICAgJ0VkRFNBIE1QQ3YyIHJlY292ZXJ5OiByZWR1Y2VkIGtleSBzaGFyZSBpcyBtaXNzaW5nIGtleVNoYXJlLCBwdWIsIG9yIHJvb3RDaGFpbkNvZGUuIFRoaXMga2V5Y2FyZCBtYXkgYmUgcHVibGljLW9ubHkgYW5kIGNhbm5vdCBiZSB1c2VkIGZvciByZWNvdmVyeS4nXG4gICAgICApO1xuICAgIH1cbiAgICByZXR1cm4gcmVkdWNlZDtcbiAgfTtcblxuICBjb25zdCBbdXNlclJlZHVjZWQsIGJhY2t1cFJlZHVjZWRdID0gYXdhaXQgUHJvbWlzZS5hbGwoW2RlY29kZUtleShlbmNyeXB0ZWRVc2VyS2V5KSwgZGVjb2RlS2V5KGVuY3J5cHRlZEJhY2t1cEtleSldKTtcblxuICBjb25zdCB1c2VyUHViID0gQnVmZmVyLmZyb20odXNlclJlZHVjZWQucHViKS50b1N0cmluZygnaGV4Jyk7XG4gIGNvbnN0IGJhY2t1cFB1YiA9IEJ1ZmZlci5mcm9tKGJhY2t1cFJlZHVjZWQucHViKS50b1N0cmluZygnaGV4Jyk7XG4gIGlmICh1c2VyUHViICE9PSBiYWNrdXBQdWIpIHtcbiAgICB0aHJvdyBuZXcgRXJyb3IoJ0VkRFNBIE1QQ3YyIHJlY292ZXJ5OiB1c2VyIGFuZCBiYWNrdXAgcHViIGtleXMgZG8gbm90IG1hdGNoJyk7XG4gIH1cblxuICBjb25zdCB1c2VyQ2hhaW5Db2RlID0gQnVmZmVyLmZyb20odXNlclJlZHVjZWQucm9vdENoYWluQ29kZSkudG9TdHJpbmcoJ2hleCcpO1xuICBjb25zdCBiYWNrdXBDaGFpbkNvZGUgPSBCdWZmZXIuZnJvbShiYWNrdXBSZWR1Y2VkLnJvb3RDaGFpbkNvZGUpLnRvU3RyaW5nKCdoZXgnKTtcbiAgaWYgKHVzZXJDaGFpbkNvZGUgIT09IGJhY2t1cENoYWluQ29kZSkge1xuICAgIHRocm93IG5ldyBFcnJvcignRWREU0EgTVBDdjIgcmVjb3Zlcnk6IHVzZXIgYW5kIGJhY2t1cCByb290Q2hhaW5Db2RlcyBkbyBub3QgbWF0Y2gnKTtcbiAgfVxuXG4gIHJldHVybiB7XG4gICAgdXNlcktleVNoYXJlOiBCdWZmZXIuZnJvbSh1c2VyUmVkdWNlZC5rZXlTaGFyZSksXG4gICAgYmFja3VwS2V5U2hhcmU6IEJ1ZmZlci5mcm9tKGJhY2t1cFJlZHVjZWQua2V5U2hhcmUpLFxuICAgIGNvbW1vbktleUNoYWluOiB1c2VyUHViICsgdXNlckNoYWluQ29kZSxcbiAgfTtcbn1cblxuLyoqXG4gKiBTaWduIGEgbWVzc2FnZSBmb3IgcmVjb3ZlcnkgdXNpbmcgRWREU0EgTVBDdjIgKE1QUykgd2l0aCB1c2VyIGFuZCBiYWNrdXAga2V5IHNoYXJlcy5cbiAqXG4gKiBSdW5zIHRoZSBNUFMgRFNHIHByb3RvY29sIGxvY2FsbHkgdG8gcm91bmQgMywgdGhlbiB2ZXJpZmllcyB0aGUgcmVzdWx0aW5nXG4gKiBFZDI1NTE5IHNpZ25hdHVyZSBhZ2FpbnN0IHRoZSBwdWJsaWMga2V5IGRlcml2ZWQgZnJvbSB0aGUgY29tbW9uIGtleWNoYWluLlxuICpcbiAqIEBwYXJhbSBtZXNzYWdlIHJhdyBieXRlcyB0byBzaWduXG4gKiBAcGFyYW0gZGVyaXZhdGlvblBhdGggQklQLTMyLXN0eWxlIGRlcml2YXRpb24gcGF0aCwgZS5nLiBgXCJtLzBcImBcbiAqIEBwYXJhbSB1c2VyS2V5U2hhcmUgb3BhcXVlIE1QUyBzaWduaW5nIGtleS1zaGFyZSBieXRlcyBmb3IgdGhlIHVzZXIgcGFydHlcbiAqIEBwYXJhbSBiYWNrdXBLZXlTaGFyZSBvcGFxdWUgTVBTIHNpZ25pbmcga2V5LXNoYXJlIGJ5dGVzIGZvciB0aGUgYmFja3VwIHBhcnR5XG4gKiBAcGFyYW0gY29tbW9uS2V5Q2hhaW4gMTI4LWhleC1jaGFyIHN0cmluZzogMzItYnl0ZSBwdWIgKyAzMi1ieXRlIHJvb3RDaGFpbkNvZGVcbiAqIEByZXR1cm5zIDY0LWJ5dGUgRWQyNTUxOSBzaWduYXR1cmUgQnVmZmVyXG4gKi9cbmV4cG9ydCBhc3luYyBmdW5jdGlvbiBzaWduUmVjb3ZlcnlFZGRzYU1QQ3YyKFxuICBtZXNzYWdlOiBCdWZmZXIsXG4gIGRlcml2YXRpb25QYXRoOiBzdHJpbmcsXG4gIHVzZXJLZXlTaGFyZTogQnVmZmVyLFxuICBiYWNrdXBLZXlTaGFyZTogQnVmZmVyLFxuICBjb21tb25LZXlDaGFpbjogc3RyaW5nXG4pOiBQcm9taXNlPEJ1ZmZlcj4ge1xuICBjb25zdCB1c2VyRHNnID0gbmV3IEVkZHNhTVBTRHNnLkRTRyhNUEN2MlBhcnRpZXNFbnVtLlVTRVIpO1xuICBjb25zdCBiYWNrdXBEc2cgPSBuZXcgRWRkc2FNUFNEc2cuRFNHKE1QQ3YyUGFydGllc0VudW0uQkFDS1VQKTtcblxuICBjb25zdCBzaWduYXR1cmUgPSAoYXdhaXQgTVBTVXRpbC5leGVjdXRlVGlsbFJvdW5kKFxuICAgIDMsXG4gICAgdXNlckRzZyxcbiAgICBiYWNrdXBEc2csXG4gICAgdXNlcktleVNoYXJlLFxuICAgIGJhY2t1cEtleVNoYXJlLFxuICAgIG1lc3NhZ2UsXG4gICAgZGVyaXZhdGlvblBhdGhcbiAgKSkgYXMgQnVmZmVyO1xuXG4gIC8vIFVzZSBFZGRzYS5kZXJpdmVVbmhhcmRlbmVkIChCSVAzMi1FZDI1NTE5KSwgd2hpY2ggbWF0Y2hlcyB3aGF0IERTRyB1c2VzXG4gIC8vIGludGVybmFsbHkgZm9yIHBhdGggZGVyaXZhdGlvbiBzaW5jZSB3YXNtLW1wcyAxLjkuMC5cbiAgY29uc3QgbXBjID0gYXdhaXQgZ2V0SW5pdGlhbGl6ZWRNcGNJbnN0YW5jZSgpO1xuICBjb25zdCBkZXJpdmVkS2V5Y2hhaW4gPSBtcGMuZGVyaXZlVW5oYXJkZW5lZChjb21tb25LZXlDaGFpbiwgZGVyaXZhdGlvblBhdGgpO1xuICBjb25zdCBwdWJsaWNLZXlCeXRlcyA9IEJ1ZmZlci5mcm9tKGRlcml2ZWRLZXljaGFpbi5zbGljZSgwLCA2NCksICdoZXgnKTtcblxuICBjb25zdCB2ZXJpZmllZCA9IGVkMjU1MTkudmVyaWZ5KG5ldyBVaW50OEFycmF5KHNpZ25hdHVyZSksIG5ldyBVaW50OEFycmF5KG1lc3NhZ2UpLCBuZXcgVWludDhBcnJheShwdWJsaWNLZXlCeXRlcykpO1xuICBpZiAoIXZlcmlmaWVkKSB7XG4gICAgdGhyb3cgbmV3IEVycm9yKCdFZERTQSBNUEN2MiByZWNvdmVyeSBzaWduYXR1cmUgdmVyaWZpY2F0aW9uIGZhaWxlZCcpO1xuICB9XG5cbiAgcmV0dXJuIHNpZ25hdHVyZTtcbn1cblxuLyoqXG4gKiBEaXNjcmltaW5hdGVkIHVuaW9uIHJlcHJlc2VudGluZyBFZERTQSBzaWduaW5nIG1hdGVyaWFsIGRldGVjdGVkIGZyb20gYSBrZXljYXJkLlxuICogdjE6IE1QQ3YxIEpTT04ga2V5Y2FyZCDigJQgdXNlclBydiBpcyB0aGUgZGVjcnlwdGVkIHBsYWludGV4dC5cbiAqIHYyOiBNUEN2MiBDQk9SIGtleWNhcmQg4oCUIGVuY3J5cHRlZFVzZXJLZXkgaXMgcmV0dXJuZWQgYXMtaXMgZm9yIE1QUyBEU0cuXG4gKi9cbmV4cG9ydCB0eXBlIEVkZHNhU2lnbmluZ01hdGVyaWFsID0geyB2ZXJzaW9uOiAndjEnOyB1c2VyUHJ2OiBzdHJpbmcgfSB8IHsgdmVyc2lvbjogJ3YyJzsgZW5jcnlwdGVkVXNlcktleTogc3RyaW5nIH07XG5cbi8qKlxuICogRGV0ZWN0cyBNUEN2MSB2cyBNUEN2MiBrZXljYXJkIGZvcm1hdCBhbmQgcmV0dXJucyB0eXBlZCBzaWduaW5nIG1hdGVyaWFsLlxuICogRm9yIHYxOiBkZWNyeXB0cyBvbmNlIGFuZCByZXR1cm5zIHRoZSBwbGFpbnRleHQgYXMgdXNlclBydi5cbiAqIEZvciB2MjogcmV0dXJucyB0aGUgZW5jcnlwdGVkIGtleSBhcy1pcyBmb3IgdXNlIHdpdGggc2lnbkVkZHNhTXBjVjJSZWNvdmVyeVR4LlxuICogV2hlbiBiaXRnbyBpcyBvbWl0dGVkLCBmYWxscyBiYWNrIHRvIHNqY2wgKHYxIG9ubHkpLlxuICovXG5leHBvcnQgYXN5bmMgZnVuY3Rpb24gZ2V0RWRkc2FTaWduaW5nTWF0ZXJpYWwoXG4gIHVzZXJLZXk6IHN0cmluZyxcbiAgd2FsbGV0UGFzc3BocmFzZTogc3RyaW5nLFxuICBiaXRnbz86IEJpdEdvQmFzZVxuKTogUHJvbWlzZTxFZGRzYVNpZ25pbmdNYXRlcmlhbD4ge1xuICBjb25zdCBub3JtYWxpemVkID0gdXNlcktleS5yZXBsYWNlKC9cXHMvZywgJycpO1xuICBsZXQgZGVjcnlwdGVkOiBzdHJpbmc7XG4gIHRyeSB7XG4gICAgZGVjcnlwdGVkID0gYml0Z29cbiAgICAgID8gYXdhaXQgYml0Z28uZGVjcnlwdCh7IGlucHV0OiBub3JtYWxpemVkLCBwYXNzd29yZDogd2FsbGV0UGFzc3BocmFzZSB9KVxuICAgICAgOiBzamNsLmRlY3J5cHQod2FsbGV0UGFzc3BocmFzZSwgbm9ybWFsaXplZCk7XG4gIH0gY2F0Y2ggKGUpIHtcbiAgICB0aHJvdyBuZXcgRXJyb3IoYEVycm9yIGRlY3J5cHRpbmcgdXNlciBrZXljaGFpbjogJHtlIGluc3RhbmNlb2YgRXJyb3IgPyBlLm1lc3NhZ2UgOiBTdHJpbmcoZSl9YCk7XG4gIH1cbiAgY29uc3QgdXNlclBydiA9IHBhcnNlRWRkc2FNcGNWMU1hdGVyaWFsKGRlY3J5cHRlZCk7XG4gIHJldHVybiB1c2VyUHJ2ICE9PSBudWxsID8geyB2ZXJzaW9uOiAndjEnLCB1c2VyUHJ2IH0gOiB7IHZlcnNpb246ICd2MicsIGVuY3J5cHRlZFVzZXJLZXk6IG5vcm1hbGl6ZWQgfTtcbn1cblxuLyoqXG4gKiBGdWxsIE1QQ3YyIHJlY292ZXJ5IHNpZ25pbmcgZmxvdzogZGVjcnlwdCBrZXkgc2hhcmVzIOKGkiB2YWxpZGF0ZSBjb21tb25LZXlDaGFpbiDihpIgTVBTIERTRy5cbiAqIFJldHVybnMgcmF3IDY0LWJ5dGUgRWQyNTUxOSBzaWduYXR1cmUgQnVmZmVyLlxuICogQ2FsbGVyIGlzIHJlc3BvbnNpYmxlIGZvciBhbnkgY29pbi1zcGVjaWZpYyBlbnZlbG9wZVxuICogKGUuZy4gMHgwMCBTdWJzdHJhdGUgcHJlZml4LCBTVUkgZmxhZytwdWJrZXkgd3JhcHBlciwgb3IgcmF3IGZvciBORUFSL0FEQS9UT04pLlxuICovXG5leHBvcnQgYXN5bmMgZnVuY3Rpb24gc2lnbkVkZHNhTXBjVjJSZWNvdmVyeVR4KHBhcmFtczoge1xuICBtZXNzYWdlOiBCdWZmZXI7XG4gIHVzZXJLZXk6IHN0cmluZztcbiAgYmFja3VwS2V5OiBzdHJpbmc7XG4gIHdhbGxldFBhc3NwaHJhc2U6IHN0cmluZztcbiAgYml0Z29LZXk6IHN0cmluZztcbiAgZGVyaXZhdGlvblBhdGg6IHN0cmluZztcbiAgYml0Z28/OiBCaXRHb0Jhc2U7XG59KTogUHJvbWlzZTxCdWZmZXI+IHtcbiAgY29uc3QgeyB1c2VyS2V5U2hhcmUsIGJhY2t1cEtleVNoYXJlLCBjb21tb25LZXlDaGFpbiB9ID0gYXdhaXQgZ2V0RWRkc2FNcGNWMlJlY292ZXJ5S2V5U2hhcmVzRnJvbVJlZHVjZWRLZXkoXG4gICAgcGFyYW1zLnVzZXJLZXksXG4gICAgcGFyYW1zLmJhY2t1cEtleSxcbiAgICBwYXJhbXMud2FsbGV0UGFzc3BocmFzZSxcbiAgICBwYXJhbXMuYml0Z29cbiAgKTtcbiAgaWYgKGNvbW1vbktleUNoYWluLnRvTG93ZXJDYXNlKCkgIT09IHBhcmFtcy5iaXRnb0tleS50b0xvd2VyQ2FzZSgpKSB7XG4gICAgdGhyb3cgbmV3IEVycm9yKCdFZERTQSBNUEN2MiByZWNvdmVyeTogY29tbW9uS2V5Q2hhaW4gZnJvbSBrZXljYXJkIGRvZXMgbm90IG1hdGNoIGJpdGdvS2V5Jyk7XG4gIH1cbiAgcmV0dXJuIHNpZ25SZWNvdmVyeUVkZHNhTVBDdjIocGFyYW1zLm1lc3NhZ2UsIHBhcmFtcy5kZXJpdmF0aW9uUGF0aCwgdXNlcktleVNoYXJlLCBiYWNrdXBLZXlTaGFyZSwgY29tbW9uS2V5Q2hhaW4pO1xufVxuXG5leHBvcnQgY29uc3QgRWRkc2FNUEN2MlJlY292ZXJ5RnVuY3Rpb25zID0ge1xuICBpc0VkZHNhTXBjVjFTaWduaW5nTWF0ZXJpYWwsXG4gIGdldEVkZHNhTXBjVjJSZWNvdmVyeUtleVNoYXJlc0Zyb21SZWR1Y2VkS2V5LFxuICBzaWduUmVjb3ZlcnlFZGRzYU1QQ3YyLFxuICBnZXRFZGRzYVNpZ25pbmdNYXRlcmlhbCxcbiAgc2lnbkVkZHNhTXBjVjJSZWNvdmVyeVR4LFxufTtcbiJdfQ==
|