@qntx/spark 0.0.0-stage → 0.1.1
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/LICENSE +201 -0
- package/NOTICE +6 -0
- package/README.md +59 -2
- package/dist/bolt11-DsNTTS_O.d.mts +52 -0
- package/dist/crypto.d.mts +3 -0
- package/dist/crypto.mjs +9 -0
- package/dist/errors-5xLkExNL.mjs +67 -0
- package/dist/index-B_g3vHnT.d.mts +820 -0
- package/dist/index-D1fBaHTa.d.mts +55 -0
- package/dist/index-DUSx3L3J.d.mts +69 -0
- package/dist/index.d.mts +115 -0
- package/dist/index.mjs +7322 -0
- package/dist/lightning-address-CRULmi9v.d.mts +106 -0
- package/dist/lightning-address-CZrb8x4p.mjs +92 -0
- package/dist/lnurl-kcdXU75g.mjs +729 -0
- package/dist/lnurl.d.mts +258 -0
- package/dist/lnurl.mjs +1 -0
- package/dist/server.d.mts +158 -0
- package/dist/server.mjs +373 -0
- package/dist/signer.d.mts +72 -0
- package/dist/signer.mjs +1024 -0
- package/dist/text-DC_Vptn6.mjs +303 -0
- package/dist/token-DmojVTWi.mjs +2122 -0
- package/dist/types-jBCznYd6.d.mts +322 -0
- package/package.json +98 -4
|
@@ -0,0 +1,2122 @@
|
|
|
1
|
+
import { n as SparkError, r as SparkInputError } from "./errors-5xLkExNL.mjs";
|
|
2
|
+
import { bytesToHex, concatBytes, hexToBytes, utf8ToBytes } from "@noble/hashes/utils.js";
|
|
3
|
+
import { fileDesc, messageDesc, serviceDesc } from "@bufbuild/protobuf/codegenv2";
|
|
4
|
+
import { TimestampSchema, file_google_protobuf_descriptor, file_google_protobuf_duration, file_google_protobuf_empty, file_google_protobuf_timestamp } from "@bufbuild/protobuf/wkt";
|
|
5
|
+
import { ScalarType, fromBinary, toBinary } from "@bufbuild/protobuf";
|
|
6
|
+
import { BinaryWriter } from "@bufbuild/protobuf/wire";
|
|
7
|
+
import { schnorr, secp256k1 } from "@noble/curves/secp256k1.js";
|
|
8
|
+
import { base64urlnopad } from "@scure/base";
|
|
9
|
+
import { sha256 } from "@noble/hashes/sha2.js";
|
|
10
|
+
import { Address, NETWORK, OutScript, Script, ScriptNum, SigHash, TEST_NETWORK, TaprootControlBlock, Transaction, p2tr, taprootListToTree } from "@scure/btc-signer";
|
|
11
|
+
import { isReflectList, isReflectMap, isReflectMessage, reflect } from "@bufbuild/protobuf/reflect";
|
|
12
|
+
//#region src/proto/gen/validate/validate_pb.ts
|
|
13
|
+
/**
|
|
14
|
+
* Describes the file validate/validate.proto.
|
|
15
|
+
*/
|
|
16
|
+
const file_validate_validate = /*@__PURE__*/ fileDesc("Chd2YWxpZGF0ZS92YWxpZGF0ZS5wcm90bxIIdmFsaWRhdGUimAcKCkZpZWxkUnVsZXMSJwoHbWVzc2FnZRgRIAEoCzIWLnZhbGlkYXRlLk1lc3NhZ2VSdWxlcxIlCgVmbG9hdBgBIAEoCzIULnZhbGlkYXRlLkZsb2F0UnVsZXNIABInCgZkb3VibGUYAiABKAsyFS52YWxpZGF0ZS5Eb3VibGVSdWxlc0gAEiUKBWludDMyGAMgASgLMhQudmFsaWRhdGUuSW50MzJSdWxlc0gAEiUKBWludDY0GAQgASgLMhQudmFsaWRhdGUuSW50NjRSdWxlc0gAEicKBnVpbnQzMhgFIAEoCzIVLnZhbGlkYXRlLlVJbnQzMlJ1bGVzSAASJwoGdWludDY0GAYgASgLMhUudmFsaWRhdGUuVUludDY0UnVsZXNIABInCgZzaW50MzIYByABKAsyFS52YWxpZGF0ZS5TSW50MzJSdWxlc0gAEicKBnNpbnQ2NBgIIAEoCzIVLnZhbGlkYXRlLlNJbnQ2NFJ1bGVzSAASKQoHZml4ZWQzMhgJIAEoCzIWLnZhbGlkYXRlLkZpeGVkMzJSdWxlc0gAEikKB2ZpeGVkNjQYCiABKAsyFi52YWxpZGF0ZS5GaXhlZDY0UnVsZXNIABIrCghzZml4ZWQzMhgLIAEoCzIXLnZhbGlkYXRlLlNGaXhlZDMyUnVsZXNIABIrCghzZml4ZWQ2NBgMIAEoCzIXLnZhbGlkYXRlLlNGaXhlZDY0UnVsZXNIABIjCgRib29sGA0gASgLMhMudmFsaWRhdGUuQm9vbFJ1bGVzSAASJwoGc3RyaW5nGA4gASgLMhUudmFsaWRhdGUuU3RyaW5nUnVsZXNIABIlCgVieXRlcxgPIAEoCzIULnZhbGlkYXRlLkJ5dGVzUnVsZXNIABIjCgRlbnVtGBAgASgLMhMudmFsaWRhdGUuRW51bVJ1bGVzSAASKwoIcmVwZWF0ZWQYEiABKAsyFy52YWxpZGF0ZS5SZXBlYXRlZFJ1bGVzSAASIQoDbWFwGBMgASgLMhIudmFsaWRhdGUuTWFwUnVsZXNIABIhCgNhbnkYFCABKAsyEi52YWxpZGF0ZS5BbnlSdWxlc0gAEisKCGR1cmF0aW9uGBUgASgLMhcudmFsaWRhdGUuRHVyYXRpb25SdWxlc0gAEi0KCXRpbWVzdGFtcBgWIAEoCzIYLnZhbGlkYXRlLlRpbWVzdGFtcFJ1bGVzSABCBgoEdHlwZSJ/CgpGbG9hdFJ1bGVzEg0KBWNvbnN0GAEgASgCEgoKAmx0GAIgASgCEgsKA2x0ZRgDIAEoAhIKCgJndBgEIAEoAhILCgNndGUYBSABKAISCgoCaW4YBiADKAISDgoGbm90X2luGAcgAygCEhQKDGlnbm9yZV9lbXB0eRgIIAEoCCKAAQoLRG91YmxlUnVsZXMSDQoFY29uc3QYASABKAESCgoCbHQYAiABKAESCwoDbHRlGAMgASgBEgoKAmd0GAQgASgBEgsKA2d0ZRgFIAEoARIKCgJpbhgGIAMoARIOCgZub3RfaW4YByADKAESFAoMaWdub3JlX2VtcHR5GAggASgIIn8KCkludDMyUnVsZXMSDQoFY29uc3QYASABKAUSCgoCbHQYAiABKAUSCwoDbHRlGAMgASgFEgoKAmd0GAQgASgFEgsKA2d0ZRgFIAEoBRIKCgJpbhgGIAMoBRIOCgZub3RfaW4YByADKAUSFAoMaWdub3JlX2VtcHR5GAggASgIIn8KCkludDY0UnVsZXMSDQoFY29uc3QYASABKAMSCgoCbHQYAiABKAMSCwoDbHRlGAMgASgDEgoKAmd0GAQgASgDEgsKA2d0ZRgFIAEoAxIKCgJpbhgGIAMoAxIOCgZub3RfaW4YByADKAMSFAoMaWdub3JlX2VtcHR5GAggASgIIoABCgtVSW50MzJSdWxlcxINCgVjb25zdBgBIAEoDRIKCgJsdBgCIAEoDRILCgNsdGUYAyABKA0SCgoCZ3QYBCABKA0SCwoDZ3RlGAUgASgNEgoKAmluGAYgAygNEg4KBm5vdF9pbhgHIAMoDRIUCgxpZ25vcmVfZW1wdHkYCCABKAgigAEKC1VJbnQ2NFJ1bGVzEg0KBWNvbnN0GAEgASgEEgoKAmx0GAIgASgEEgsKA2x0ZRgDIAEoBBIKCgJndBgEIAEoBBILCgNndGUYBSABKAQSCgoCaW4YBiADKAQSDgoGbm90X2luGAcgAygEEhQKDGlnbm9yZV9lbXB0eRgIIAEoCCKAAQoLU0ludDMyUnVsZXMSDQoFY29uc3QYASABKBESCgoCbHQYAiABKBESCwoDbHRlGAMgASgREgoKAmd0GAQgASgREgsKA2d0ZRgFIAEoERIKCgJpbhgGIAMoERIOCgZub3RfaW4YByADKBESFAoMaWdub3JlX2VtcHR5GAggASgIIoABCgtTSW50NjRSdWxlcxINCgVjb25zdBgBIAEoEhIKCgJsdBgCIAEoEhILCgNsdGUYAyABKBISCgoCZ3QYBCABKBISCwoDZ3RlGAUgASgSEgoKAmluGAYgAygSEg4KBm5vdF9pbhgHIAMoEhIUCgxpZ25vcmVfZW1wdHkYCCABKAgigQEKDEZpeGVkMzJSdWxlcxINCgVjb25zdBgBIAEoBxIKCgJsdBgCIAEoBxILCgNsdGUYAyABKAcSCgoCZ3QYBCABKAcSCwoDZ3RlGAUgASgHEgoKAmluGAYgAygHEg4KBm5vdF9pbhgHIAMoBxIUCgxpZ25vcmVfZW1wdHkYCCABKAgigQEKDEZpeGVkNjRSdWxlcxINCgVjb25zdBgBIAEoBhIKCgJsdBgCIAEoBhILCgNsdGUYAyABKAYSCgoCZ3QYBCABKAYSCwoDZ3RlGAUgASgGEgoKAmluGAYgAygGEg4KBm5vdF9pbhgHIAMoBhIUCgxpZ25vcmVfZW1wdHkYCCABKAgiggEKDVNGaXhlZDMyUnVsZXMSDQoFY29uc3QYASABKA8SCgoCbHQYAiABKA8SCwoDbHRlGAMgASgPEgoKAmd0GAQgASgPEgsKA2d0ZRgFIAEoDxIKCgJpbhgGIAMoDxIOCgZub3RfaW4YByADKA8SFAoMaWdub3JlX2VtcHR5GAggASgIIoIBCg1TRml4ZWQ2NFJ1bGVzEg0KBWNvbnN0GAEgASgQEgoKAmx0GAIgASgQEgsKA2x0ZRgDIAEoEBIKCgJndBgEIAEoEBILCgNndGUYBSABKBASCgoCaW4YBiADKBASDgoGbm90X2luGAcgAygQEhQKDGlnbm9yZV9lbXB0eRgIIAEoCCIaCglCb29sUnVsZXMSDQoFY29uc3QYASABKAgi/QMKC1N0cmluZ1J1bGVzEg0KBWNvbnN0GAEgASgJEgsKA2xlbhgTIAEoBBIPCgdtaW5fbGVuGAIgASgEEg8KB21heF9sZW4YAyABKAQSEQoJbGVuX2J5dGVzGBQgASgEEhEKCW1pbl9ieXRlcxgEIAEoBBIRCgltYXhfYnl0ZXMYBSABKAQSDwoHcGF0dGVybhgGIAEoCRIOCgZwcmVmaXgYByABKAkSDgoGc3VmZml4GAggASgJEhAKCGNvbnRhaW5zGAkgASgJEhQKDG5vdF9jb250YWlucxgXIAEoCRIKCgJpbhgKIAMoCRIOCgZub3RfaW4YCyADKAkSDwoFZW1haWwYDCABKAhIABISCghob3N0bmFtZRgNIAEoCEgAEgwKAmlwGA4gASgISAASDgoEaXB2NBgPIAEoCEgAEg4KBGlwdjYYECABKAhIABINCgN1cmkYESABKAhIABIRCgd1cmlfcmVmGBIgASgISAASEQoHYWRkcmVzcxgVIAEoCEgAEg4KBHV1aWQYFiABKAhIABIwChB3ZWxsX2tub3duX3JlZ2V4GBggASgOMhQudmFsaWRhdGUuS25vd25SZWdleEgAEhQKBnN0cmljdBgZIAEoCDoEdHJ1ZRIUCgxpZ25vcmVfZW1wdHkYGiABKAhCDAoKd2VsbF9rbm93biL7AQoKQnl0ZXNSdWxlcxINCgVjb25zdBgBIAEoDBILCgNsZW4YDSABKAQSDwoHbWluX2xlbhgCIAEoBBIPCgdtYXhfbGVuGAMgASgEEg8KB3BhdHRlcm4YBCABKAkSDgoGcHJlZml4GAUgASgMEg4KBnN1ZmZpeBgGIAEoDBIQCghjb250YWlucxgHIAEoDBIKCgJpbhgIIAMoDBIOCgZub3RfaW4YCSADKAwSDAoCaXAYCiABKAhIABIOCgRpcHY0GAsgASgISAASDgoEaXB2NhgMIAEoCEgAEhQKDGlnbm9yZV9lbXB0eRgOIAEoCEIMCgp3ZWxsX2tub3duIkwKCUVudW1SdWxlcxINCgVjb25zdBgBIAEoBRIUCgxkZWZpbmVkX29ubHkYAiABKAgSCgoCaW4YAyADKAUSDgoGbm90X2luGAQgAygFIi4KDE1lc3NhZ2VSdWxlcxIMCgRza2lwGAEgASgIEhAKCHJlcXVpcmVkGAIgASgIIoABCg1SZXBlYXRlZFJ1bGVzEhEKCW1pbl9pdGVtcxgBIAEoBBIRCgltYXhfaXRlbXMYAiABKAQSDgoGdW5pcXVlGAMgASgIEiMKBWl0ZW1zGAQgASgLMhQudmFsaWRhdGUuRmllbGRSdWxlcxIUCgxpZ25vcmVfZW1wdHkYBSABKAgiowEKCE1hcFJ1bGVzEhEKCW1pbl9wYWlycxgBIAEoBBIRCgltYXhfcGFpcnMYAiABKAQSEQoJbm9fc3BhcnNlGAMgASgIEiIKBGtleXMYBCABKAsyFC52YWxpZGF0ZS5GaWVsZFJ1bGVzEiQKBnZhbHVlcxgFIAEoCzIULnZhbGlkYXRlLkZpZWxkUnVsZXMSFAoMaWdub3JlX2VtcHR5GAYgASgIIjgKCEFueVJ1bGVzEhAKCHJlcXVpcmVkGAEgASgIEgoKAmluGAIgAygJEg4KBm5vdF9pbhgDIAMoCSK7AgoNRHVyYXRpb25SdWxlcxIQCghyZXF1aXJlZBgBIAEoCBIoCgVjb25zdBgCIAEoCzIZLmdvb2dsZS5wcm90b2J1Zi5EdXJhdGlvbhIlCgJsdBgDIAEoCzIZLmdvb2dsZS5wcm90b2J1Zi5EdXJhdGlvbhImCgNsdGUYBCABKAsyGS5nb29nbGUucHJvdG9idWYuRHVyYXRpb24SJQoCZ3QYBSABKAsyGS5nb29nbGUucHJvdG9idWYuRHVyYXRpb24SJgoDZ3RlGAYgASgLMhkuZ29vZ2xlLnByb3RvYnVmLkR1cmF0aW9uEiUKAmluGAcgAygLMhkuZ29vZ2xlLnByb3RvYnVmLkR1cmF0aW9uEikKBm5vdF9pbhgIIAMoCzIZLmdvb2dsZS5wcm90b2J1Zi5EdXJhdGlvbiK6AgoOVGltZXN0YW1wUnVsZXMSEAoIcmVxdWlyZWQYASABKAgSKQoFY29uc3QYAiABKAsyGi5nb29nbGUucHJvdG9idWYuVGltZXN0YW1wEiYKAmx0GAMgASgLMhouZ29vZ2xlLnByb3RvYnVmLlRpbWVzdGFtcBInCgNsdGUYBCABKAsyGi5nb29nbGUucHJvdG9idWYuVGltZXN0YW1wEiYKAmd0GAUgASgLMhouZ29vZ2xlLnByb3RvYnVmLlRpbWVzdGFtcBInCgNndGUYBiABKAsyGi5nb29nbGUucHJvdG9idWYuVGltZXN0YW1wEg4KBmx0X25vdxgHIAEoCBIOCgZndF9ub3cYCCABKAgSKQoGd2l0aGluGAkgASgLMhkuZ29vZ2xlLnByb3RvYnVmLkR1cmF0aW9uKkYKCktub3duUmVnZXgSCwoHVU5LTk9XThAAEhQKEEhUVFBfSEVBREVSX05BTUUQARIVChFIVFRQX0hFQURFUl9WQUxVRRACOjwKCGRpc2FibGVkEh8uZ29vZ2xlLnByb3RvYnVmLk1lc3NhZ2VPcHRpb25zGK8IIAEoCFIIZGlzYWJsZWQ6OgoHaWdub3JlZBIfLmdvb2dsZS5wcm90b2J1Zi5NZXNzYWdlT3B0aW9ucxiwCCABKAhSB2lnbm9yZWQ6OgoIcmVxdWlyZWQSHS5nb29nbGUucHJvdG9idWYuT25lb2ZPcHRpb25zGK8IIAEoCFIIcmVxdWlyZWQ6SgoFcnVsZXMSHS5nb29nbGUucHJvdG9idWYuRmllbGRPcHRpb25zGK8IIAEoCzIULnZhbGlkYXRlLkZpZWxkUnVsZXNSBXJ1bGVzQlAKGmlvLmVudm95cHJveHkucGd2LnZhbGlkYXRlWjJnaXRodWIuY29tL2Vudm95cHJveHkvcHJvdG9jLWdlbi12YWxpZGF0ZS92YWxpZGF0ZQ", [
|
|
17
|
+
file_google_protobuf_descriptor,
|
|
18
|
+
file_google_protobuf_duration,
|
|
19
|
+
file_google_protobuf_timestamp
|
|
20
|
+
]);
|
|
21
|
+
//#endregion
|
|
22
|
+
//#region src/proto/gen/common_pb.ts
|
|
23
|
+
/**
|
|
24
|
+
* Describes the file common.proto.
|
|
25
|
+
*/
|
|
26
|
+
const file_common = /*@__PURE__*/ fileDesc("Cgxjb21tb24ucHJvdG8SBmNvbW1vbiJxCgpQYWNrYWdlTWFwEjIKCHBhY2thZ2VzGAEgAygLMiAuY29tbW9uLlBhY2thZ2VNYXAuUGFja2FnZXNFbnRyeRovCg1QYWNrYWdlc0VudHJ5EgsKA2tleRgBIAEoCRINCgV2YWx1ZRgCIAEoDDoCOAEiNAoRU2lnbmluZ0NvbW1pdG1lbnQSDgoGaGlkaW5nGAEgASgMEg8KB2JpbmRpbmcYAiABKAwiKAoNU2lnbmluZ1Jlc3VsdBIXCg9zaWduYXR1cmVfc2hhcmUYASABKAwiXAoJU2lnbmF0dXJlEjMKBnNjaGVtZRgBIAEoDjIXLmNvbW1vbi5TaWduYXR1cmVTY2hlbWVCCvpCB4IBBBABIAASGgoJc2lnbmF0dXJlGAIgASgMQgf6QgR6AhABKl0KD1NpZ25hdHVyZUludGVudBIMCghDUkVBVElPThAAEgwKCFRSQU5TRkVSEAESDQoJQUdHUkVHQVRFEAISDwoHUkVGUkVTSBADGgIIARIOCgZFWFRFTkQQBBoCCAEqbQoPU2lnbmF0dXJlU2NoZW1lEiAKHFNJR05BVFVSRV9TQ0hFTUVfVU5TUEVDSUZJRUQQABIaChZTSUdOQVRVUkVfU0NIRU1FX0VDRFNBEAESHAoYU0lHTkFUVVJFX1NDSEVNRV9TQ0hOT1JSEAJCLVorZ2l0aHViLmNvbS9saWdodHNwYXJrZGV2L3NwYXJrL3Byb3RvL2NvbW1vbmIGcHJvdG8z", [file_validate_validate]);
|
|
27
|
+
/**
|
|
28
|
+
* The scheme used to produce a Signature.
|
|
29
|
+
*
|
|
30
|
+
* @generated from enum common.SignatureScheme
|
|
31
|
+
*/
|
|
32
|
+
const SignatureScheme = {
|
|
33
|
+
/**
|
|
34
|
+
* @generated from enum value: SIGNATURE_SCHEME_UNSPECIFIED = 0;
|
|
35
|
+
*/
|
|
36
|
+
UNSPECIFIED: 0,
|
|
37
|
+
/**
|
|
38
|
+
* secp256k1 ECDSA, strict DER encoding (variable length).
|
|
39
|
+
*
|
|
40
|
+
* @generated from enum value: SIGNATURE_SCHEME_ECDSA = 1;
|
|
41
|
+
*/
|
|
42
|
+
ECDSA: 1,
|
|
43
|
+
/**
|
|
44
|
+
* BIP-340 Schnorr over secp256k1, 64 bytes.
|
|
45
|
+
*
|
|
46
|
+
* @generated from enum value: SIGNATURE_SCHEME_SCHNORR = 2;
|
|
47
|
+
*/
|
|
48
|
+
SCHNORR: 2
|
|
49
|
+
};
|
|
50
|
+
//#endregion
|
|
51
|
+
//#region src/proto/gen/spark_pb.ts
|
|
52
|
+
/**
|
|
53
|
+
* Describes the file spark.proto.
|
|
54
|
+
*/
|
|
55
|
+
const file_spark = /*@__PURE__*/ fileDesc("CgtzcGFyay5wcm90bxIFc3BhcmsiNwoYU3Vic2NyaWJlVG9FdmVudHNSZXF1ZXN0EhsKE2lkZW50aXR5X3B1YmxpY19rZXkYCiABKAwizQIKGVN1YnNjcmliZVRvRXZlbnRzUmVzcG9uc2USOwoRcmVjZWl2ZXJfdHJhbnNmZXIYASABKAsyFC5zcGFyay5UcmFuc2ZlckV2ZW50SABSCHRyYW5zZmVyEiYKB2RlcG9zaXQYAiABKAsyEy5zcGFyay5EZXBvc2l0RXZlbnRIABIqCgljb25uZWN0ZWQYAyABKAsyFS5zcGFyay5Db25uZWN0ZWRFdmVudEgAEi8KD3NlbmRlcl90cmFuc2ZlchgEIAEoCzIULnNwYXJrLlRyYW5zZmVyRXZlbnRIABIqCgloZWFydGJlYXQYBSABKAsyFS5zcGFyay5IZWFydGJlYXRFdmVudEgAEjkKEXRva2VuX3RyYW5zYWN0aW9uGAYgASgLMhwuc3BhcmsuVG9rZW5UcmFuc2FjdGlvbkV2ZW50SABCBwoFZXZlbnQiagoVVG9rZW5UcmFuc2FjdGlvbkV2ZW50Eh4KFnRva2VuX3RyYW5zYWN0aW9uX2hhc2gYASABKAwSGQoRdG9rZW5faWRlbnRpZmllcnMYAiADKAwSFgoOc3BhcmtfaW52b2ljZXMYAyADKAkiEAoOQ29ubmVjdGVkRXZlbnQiEAoOSGVhcnRiZWF0RXZlbnQiRAoNVHJhbnNmZXJFdmVudBIhCgh0cmFuc2ZlchgKIAEoCzIPLnNwYXJrLlRyYW5zZmVyEhAKCHRyYWNlX2lkGAsgASgJIkIKDERlcG9zaXRFdmVudBIgCgdkZXBvc2l0GAogASgLMg8uc3BhcmsuVHJlZU5vZGUSEAoIdHJhY2VfaWQYCyABKAkihwEKC1BhZ2VSZXF1ZXN0EiQKEHVuc2FmZV9wYWdlX3NpemUYASABKAVCCvpCBxoFGOgHKAASHQoJcGFnZV9zaXplGAQgASgNQgr6QgcqBRjoBygAEg4KBmN1cnNvchgCIAEoCRIjCglkaXJlY3Rpb24YAyABKA4yEC5zcGFyay5EaXJlY3Rpb24ibgoMUGFnZVJlc3BvbnNlEhUKDWhhc19uZXh0X3BhZ2UYASABKAgSGQoRaGFzX3ByZXZpb3VzX3BhZ2UYAiABKAgSEwoLbmV4dF9jdXJzb3IYAyABKAkSFwoPcHJldmlvdXNfY3Vyc29yGAQgASgJIsUBChNEZXBvc2l0QWRkcmVzc1Byb29mEk0KEmFkZHJlc3Nfc2lnbmF0dXJlcxgBIAMoCzIxLnNwYXJrLkRlcG9zaXRBZGRyZXNzUHJvb2YuQWRkcmVzc1NpZ25hdHVyZXNFbnRyeRIlCh1wcm9vZl9vZl9wb3NzZXNzaW9uX3NpZ25hdHVyZRgCIAEoDBo4ChZBZGRyZXNzU2lnbmF0dXJlc0VudHJ5EgsKA2tleRgBIAEoCRINCgV2YWx1ZRgCIAEoDDoCOAEi/wEKHUdlbmVyYXRlRGVwb3NpdEFkZHJlc3NSZXF1ZXN0EhoKEnNpZ25pbmdfcHVibGljX2tleRgBIAEoDBIbChNpZGVudGl0eV9wdWJsaWNfa2V5GAIgASgMEikKB25ldHdvcmsYAyABKA4yDi5zcGFyay5OZXR3b3JrQgj6QgWCAQIgABIeCgdsZWFmX2lkGAQgASgJQgj6QgVyA7ABAUgAiAEBEhYKCWlzX3N0YXRpYxgFIAEoCEgBiAEBEigKDGhhc2hfdmFyaWFudBgGIAEoDjISLnNwYXJrLkhhc2hWYXJpYW50QgoKCF9sZWFmX2lkQgwKCl9pc19zdGF0aWMifwoHQWRkcmVzcxIPCgdhZGRyZXNzGAEgASgJEhUKDXZlcmlmeWluZ19rZXkYAiABKAwSOQoVZGVwb3NpdF9hZGRyZXNzX3Byb29mGAMgASgLMhouc3BhcmsuRGVwb3NpdEFkZHJlc3NQcm9vZhIRCglpc19zdGF0aWMYBSABKAgiSQoeR2VuZXJhdGVEZXBvc2l0QWRkcmVzc1Jlc3BvbnNlEicKD2RlcG9zaXRfYWRkcmVzcxgBIAEoCzIOLnNwYXJrLkFkZHJlc3MixQEKI0dlbmVyYXRlU3RhdGljRGVwb3NpdEFkZHJlc3NSZXF1ZXN0EiMKEnNpZ25pbmdfcHVibGljX2tleRgBIAEoDEIH+kIEegJoIRIkChNpZGVudGl0eV9wdWJsaWNfa2V5GAIgASgMQgf6QgR6AmghEikKB25ldHdvcmsYAyABKA4yDi5zcGFyay5OZXR3b3JrQgj6QgWCAQIgABIoCgxoYXNoX3ZhcmlhbnQYBCABKA4yEi5zcGFyay5IYXNoVmFyaWFudCJPCiRHZW5lcmF0ZVN0YXRpY0RlcG9zaXRBZGRyZXNzUmVzcG9uc2USJwoPZGVwb3NpdF9hZGRyZXNzGAEgASgLMg4uc3BhcmsuQWRkcmVzcyKdAQohUm90YXRlU3RhdGljRGVwb3NpdEFkZHJlc3NSZXF1ZXN0EiMKEnNpZ25pbmdfcHVibGljX2tleRgBIAEoDEIH+kIEegJoIRIpCgduZXR3b3JrGAIgASgOMg4uc3BhcmsuTmV0d29ya0II+kIFggECIAASKAoMaGFzaF92YXJpYW50GAMgASgOMhIuc3BhcmsuSGFzaFZhcmlhbnQigwEKIlJvdGF0ZVN0YXRpY0RlcG9zaXRBZGRyZXNzUmVzcG9uc2USKwoTbmV3X2RlcG9zaXRfYWRkcmVzcxgBIAEoCzIOLnNwYXJrLkFkZHJlc3MSMAoYYXJjaGl2ZWRfZGVwb3NpdF9hZGRyZXNzGAIgASgLMg4uc3BhcmsuQWRkcmVzcyJdCgRVVFhPEg4KBnJhd190eBgBIAEoDBIMCgR2b3V0GAIgASgNEikKB25ldHdvcmsYAyABKA4yDi5zcGFyay5OZXR3b3JrQgj6QgWCAQIgABIMCgR0eGlkGAQgASgMIlEKDUFkZHJlc3NlZFV0eG8SDwoHYWRkcmVzcxgBIAEoCRIZCgR1dHhvGAIgASgLMgsuc3BhcmsuVVRYTxIUCgxpc19jb25maXJtZWQYAyABKAgiKwoKTm9kZU91dHB1dBIPCgdub2RlX2lkGAEgASgJEgwKBHZvdXQYAiABKA0idQoKU2lnbmluZ0pvYhIaChJzaWduaW5nX3B1YmxpY19rZXkYASABKAwSDgoGcmF3X3R4GAIgASgMEjsKGHNpZ25pbmdfbm9uY2VfY29tbWl0bWVudBgDIAEoCzIZLmNvbW1vbi5TaWduaW5nQ29tbWl0bWVudCL7AQoPU2lnbmluZ0tleXNoYXJlEhkKEW93bmVyX2lkZW50aWZpZXJzGAEgAygJEhEKCXRocmVzaG9sZBgCIAEoDRISCgpwdWJsaWNfa2V5GAMgASgMEj8KDXB1YmxpY19zaGFyZXMYBCADKAsyKC5zcGFyay5TaWduaW5nS2V5c2hhcmUuUHVibGljU2hhcmVzRW50cnkSMAoMdXBkYXRlZF90aW1lGAUgASgLMhouZ29vZ2xlLnByb3RvYnVmLlRpbWVzdGFtcBozChFQdWJsaWNTaGFyZXNFbnRyeRILCgNrZXkYASABKAkSDQoFdmFsdWUYAiABKAw6AjgBIt0DCg1TaWduaW5nUmVzdWx0EjkKC3B1YmxpY19rZXlzGAEgAygLMiQuc3BhcmsuU2lnbmluZ1Jlc3VsdC5QdWJsaWNLZXlzRW50cnkSVAoZc2lnbmluZ19ub25jZV9jb21taXRtZW50cxgCIAMoCzIxLnNwYXJrLlNpZ25pbmdSZXN1bHQuU2lnbmluZ05vbmNlQ29tbWl0bWVudHNFbnRyeRJDChBzaWduYXR1cmVfc2hhcmVzGAMgAygLMikuc3BhcmsuU2lnbmluZ1Jlc3VsdC5TaWduYXR1cmVTaGFyZXNFbnRyeRIwChBzaWduaW5nX2tleXNoYXJlGAQgASgLMhYuc3BhcmsuU2lnbmluZ0tleXNoYXJlGjEKD1B1YmxpY0tleXNFbnRyeRILCgNrZXkYASABKAkSDQoFdmFsdWUYAiABKAw6AjgBGlkKHFNpZ25pbmdOb25jZUNvbW1pdG1lbnRzRW50cnkSCwoDa2V5GAEgASgJEigKBXZhbHVlGAIgASgLMhkuY29tbW9uLlNpZ25pbmdDb21taXRtZW50OgI4ARo2ChRTaWduYXR1cmVTaGFyZXNFbnRyeRILCgNrZXkYASABKAkSDQoFdmFsdWUYAiABKAw6AjgBIv4CChBSZW5ld0xlYWZSZXF1ZXN0Eg8KB2xlYWZfaWQYASABKAkSTQofcmVuZXdfbm9kZV90aW1lbG9ja19zaWduaW5nX2pvYhgCIAEoCzIiLnNwYXJrLlJlbmV3Tm9kZVRpbWVsb2NrU2lnbmluZ0pvYkgAElEKIXJlbmV3X3JlZnVuZF90aW1lbG9ja19zaWduaW5nX2pvYhgDIAEoCzIkLnNwYXJrLlJlbmV3UmVmdW5kVGltZWxvY2tTaWduaW5nSm9iSAASVgokcmVuZXdfbm9kZV96ZXJvX3RpbWVsb2NrX3NpZ25pbmdfam9iGAQgASgLMiYuc3BhcmsuUmVuZXdOb2RlWmVyb1RpbWVsb2NrU2lnbmluZ0pvYkgAEjsKD2RlbGVnYXRpb25fcGF0aBgFIAEoCzIdLnNwYXJrLkRlbGVnYXRpb25QYXRoU2VsZWN0b3JIAYgBAUIOCgxzaWduaW5nX2pvYnNCEgoQX2RlbGVnYXRpb25fcGF0aCI0ChZEZWxlZ2F0aW9uUGF0aFNlbGVjdG9yEhoKCGdyYW50X2lkGAEgASgJQgj6QgVyA7ABASL5AwobUmVuZXdOb2RlVGltZWxvY2tTaWduaW5nSm9iEkAKGXNwbGl0X25vZGVfdHhfc2lnbmluZ19qb2IYASABKAsyHS5zcGFyay5Vc2VyU2lnbmVkVHhTaWduaW5nSm9iEkcKIHNwbGl0X25vZGVfZGlyZWN0X3R4X3NpZ25pbmdfam9iGAIgASgLMh0uc3BhcmsuVXNlclNpZ25lZFR4U2lnbmluZ0pvYhI6ChNub2RlX3R4X3NpZ25pbmdfam9iGAMgASgLMh0uc3BhcmsuVXNlclNpZ25lZFR4U2lnbmluZ0pvYhI8ChVyZWZ1bmRfdHhfc2lnbmluZ19qb2IYBCABKAsyHS5zcGFyay5Vc2VyU2lnbmVkVHhTaWduaW5nSm9iEkEKGmRpcmVjdF9ub2RlX3R4X3NpZ25pbmdfam9iGAUgASgLMh0uc3BhcmsuVXNlclNpZ25lZFR4U2lnbmluZ0pvYhJDChxkaXJlY3RfcmVmdW5kX3R4X3NpZ25pbmdfam9iGAYgASgLMh0uc3BhcmsuVXNlclNpZ25lZFR4U2lnbmluZ0pvYhJNCiZkaXJlY3RfZnJvbV9jcGZwX3JlZnVuZF90eF9zaWduaW5nX2pvYhgHIAEoCzIdLnNwYXJrLlVzZXJTaWduZWRUeFNpZ25pbmdKb2Ii8AIKHVJlbmV3UmVmdW5kVGltZWxvY2tTaWduaW5nSm9iEjoKE25vZGVfdHhfc2lnbmluZ19qb2IYASABKAsyHS5zcGFyay5Vc2VyU2lnbmVkVHhTaWduaW5nSm9iEjwKFXJlZnVuZF90eF9zaWduaW5nX2pvYhgCIAEoCzIdLnNwYXJrLlVzZXJTaWduZWRUeFNpZ25pbmdKb2ISQQoaZGlyZWN0X25vZGVfdHhfc2lnbmluZ19qb2IYAyABKAsyHS5zcGFyay5Vc2VyU2lnbmVkVHhTaWduaW5nSm9iEkMKHGRpcmVjdF9yZWZ1bmRfdHhfc2lnbmluZ19qb2IYBCABKAsyHS5zcGFyay5Vc2VyU2lnbmVkVHhTaWduaW5nSm9iEk0KJmRpcmVjdF9mcm9tX2NwZnBfcmVmdW5kX3R4X3NpZ25pbmdfam9iGAUgASgLMh0uc3BhcmsuVXNlclNpZ25lZFR4U2lnbmluZ0pvYiKzAgofUmVuZXdOb2RlWmVyb1RpbWVsb2NrU2lnbmluZ0pvYhI6ChNub2RlX3R4X3NpZ25pbmdfam9iGAEgASgLMh0uc3BhcmsuVXNlclNpZ25lZFR4U2lnbmluZ0pvYhI8ChVyZWZ1bmRfdHhfc2lnbmluZ19qb2IYAiABKAsyHS5zcGFyay5Vc2VyU2lnbmVkVHhTaWduaW5nSm9iEkEKGmRpcmVjdF9ub2RlX3R4X3NpZ25pbmdfam9iGAMgASgLMh0uc3BhcmsuVXNlclNpZ25lZFR4U2lnbmluZ0pvYhJNCiZkaXJlY3RfZnJvbV9jcGZwX3JlZnVuZF90eF9zaWduaW5nX2pvYhgFIAEoCzIdLnNwYXJrLlVzZXJTaWduZWRUeFNpZ25pbmdKb2JKBAgEEAUiggIKEVJlbmV3TGVhZlJlc3BvbnNlEkQKGnJlbmV3X25vZGVfdGltZWxvY2tfcmVzdWx0GAEgASgLMh4uc3BhcmsuUmVuZXdOb2RlVGltZWxvY2tSZXN1bHRIABJIChxyZW5ld19yZWZ1bmRfdGltZWxvY2tfcmVzdWx0GAIgASgLMiAuc3BhcmsuUmVuZXdSZWZ1bmRUaW1lbG9ja1Jlc3VsdEgAEk0KH3JlbmV3X25vZGVfemVyb190aW1lbG9ja19yZXN1bHQYAyABKAsyIi5zcGFyay5SZW5ld05vZGVaZXJvVGltZWxvY2tSZXN1bHRIAEIOCgxyZW5ld19yZXN1bHQiXQoXUmVuZXdOb2RlVGltZWxvY2tSZXN1bHQSIwoKc3BsaXRfbm9kZRgBIAEoCzIPLnNwYXJrLlRyZWVOb2RlEh0KBG5vZGUYAiABKAsyDy5zcGFyay5UcmVlTm9kZSI6ChlSZW5ld1JlZnVuZFRpbWVsb2NrUmVzdWx0Eh0KBG5vZGUYASABKAsyDy5zcGFyay5UcmVlTm9kZSJhChtSZW5ld05vZGVaZXJvVGltZWxvY2tSZXN1bHQSIwoKc3BsaXRfbm9kZRgBIAEoCzIPLnNwYXJrLlRyZWVOb2RlEh0KBG5vZGUYAiABKAsyDy5zcGFyay5UcmVlTm9kZSL4AgoTTm9kZVNpZ25hdHVyZVNoYXJlcxIPCgdub2RlX2lkGAEgASgJEjQKFm5vZGVfdHhfc2lnbmluZ19yZXN1bHQYAiABKAsyFC5zcGFyay5TaWduaW5nUmVzdWx0EjYKGHJlZnVuZF90eF9zaWduaW5nX3Jlc3VsdBgDIAEoCzIULnNwYXJrLlNpZ25pbmdSZXN1bHQSFQoNdmVyaWZ5aW5nX2tleRgEIAEoDBI/Ch1kaXJlY3Rfbm9kZV90eF9zaWduaW5nX3Jlc3VsdBgFIAEoCzIULnNwYXJrLlNpZ25pbmdSZXN1bHRCAhgBEkEKH2RpcmVjdF9yZWZ1bmRfdHhfc2lnbmluZ19yZXN1bHQYBiABKAsyFC5zcGFyay5TaWduaW5nUmVzdWx0QgIYARJHCilkaXJlY3RfZnJvbV9jcGZwX3JlZnVuZF90eF9zaWduaW5nX3Jlc3VsdBgHIAEoCzIULnNwYXJrLlNpZ25pbmdSZXN1bHQizQEKDk5vZGVTaWduYXR1cmVzEg8KB25vZGVfaWQYASABKAkSGQoRbm9kZV90eF9zaWduYXR1cmUYAiABKAwSGwoTcmVmdW5kX3R4X3NpZ25hdHVyZRgDIAEoDBIgChhkaXJlY3Rfbm9kZV90eF9zaWduYXR1cmUYBCABKAwSIgoaZGlyZWN0X3JlZnVuZF90eF9zaWduYXR1cmUYBSABKAwSLAokZGlyZWN0X2Zyb21fY3BmcF9yZWZ1bmRfdHhfc2lnbmF0dXJlGAYgASgMIvACChhTdGFydFRyZWVDcmVhdGlvblJlcXVlc3QSGwoTaWRlbnRpdHlfcHVibGljX2tleRgBIAEoDBIiCg1vbl9jaGFpbl91dHhvGAIgASgLMgsuc3BhcmsuVVRYTxIuChNyb290X3R4X3NpZ25pbmdfam9iGAMgASgLMhEuc3BhcmsuU2lnbmluZ0pvYhIwChVyZWZ1bmRfdHhfc2lnbmluZ19qb2IYBCABKAsyES5zcGFyay5TaWduaW5nSm9iEjUKGmRpcmVjdF9yb290X3R4X3NpZ25pbmdfam9iGAUgASgLMhEuc3BhcmsuU2lnbmluZ0pvYhI3ChxkaXJlY3RfcmVmdW5kX3R4X3NpZ25pbmdfam9iGAYgASgLMhEuc3BhcmsuU2lnbmluZ0pvYhJBCiZkaXJlY3RfZnJvbV9jcGZwX3JlZnVuZF90eF9zaWduaW5nX2pvYhgHIAEoCzIRLnNwYXJrLlNpZ25pbmdKb2IibAoZU3RhcnRUcmVlQ3JlYXRpb25SZXNwb25zZRIPCgd0cmVlX2lkGAEgASgJEj4KGnJvb3Rfbm9kZV9zaWduYXR1cmVfc2hhcmVzGAIgASgLMhouc3BhcmsuTm9kZVNpZ25hdHVyZVNoYXJlcyL/AgofU3RhcnREZXBvc2l0VHJlZUNyZWF0aW9uUmVxdWVzdBIbChNpZGVudGl0eV9wdWJsaWNfa2V5GAEgASgMEiIKDW9uX2NoYWluX3V0eG8YAiABKAsyCy5zcGFyay5VVFhPEi4KE3Jvb3RfdHhfc2lnbmluZ19qb2IYAyABKAsyES5zcGFyay5TaWduaW5nSm9iEjAKFXJlZnVuZF90eF9zaWduaW5nX2pvYhgEIAEoCzIRLnNwYXJrLlNpZ25pbmdKb2ISOQoaZGlyZWN0X3Jvb3RfdHhfc2lnbmluZ19qb2IYBSABKAsyES5zcGFyay5TaWduaW5nSm9iQgIYARI7ChxkaXJlY3RfcmVmdW5kX3R4X3NpZ25pbmdfam9iGAYgASgLMhEuc3BhcmsuU2lnbmluZ0pvYkICGAESQQomZGlyZWN0X2Zyb21fY3BmcF9yZWZ1bmRfdHhfc2lnbmluZ19qb2IYByABKAsyES5zcGFyay5TaWduaW5nSm9iInMKIFN0YXJ0RGVwb3NpdFRyZWVDcmVhdGlvblJlc3BvbnNlEg8KB3RyZWVfaWQYASABKAkSPgoacm9vdF9ub2RlX3NpZ25hdHVyZV9zaGFyZXMYAiABKAsyGi5zcGFyay5Ob2RlU2lnbmF0dXJlU2hhcmVzIucCCiJGaW5hbGl6ZURlcG9zaXRUcmVlQ3JlYXRpb25SZXF1ZXN0EiQKE2lkZW50aXR5X3B1YmxpY19rZXkYASABKAxCB/pCBHoCaCESIgoNb25fY2hhaW5fdXR4bxgCIAEoCzILLnNwYXJrLlVUWE8SOgoTcm9vdF90eF9zaWduaW5nX2pvYhgDIAEoCzIdLnNwYXJrLlVzZXJTaWduZWRUeFNpZ25pbmdKb2ISPAoVcmVmdW5kX3R4X3NpZ25pbmdfam9iGAQgASgLMh0uc3BhcmsuVXNlclNpZ25lZFR4U2lnbmluZ0pvYhJNCiZkaXJlY3RfZnJvbV9jcGZwX3JlZnVuZF90eF9zaWduaW5nX2pvYhgFIAEoCzIdLnNwYXJrLlVzZXJTaWduZWRUeFNpZ25pbmdKb2ISLgoZYWRkaXRpb25hbF9vbl9jaGFpbl91dHhvcxgGIAMoCzILLnNwYXJrLlVUWE8iSQojRmluYWxpemVEZXBvc2l0VHJlZUNyZWF0aW9uUmVzcG9uc2USIgoJcm9vdF9ub2RlGAEgASgLMg8uc3BhcmsuVHJlZU5vZGUiwwQKCFRyZWVOb2RlEgoKAmlkGAEgASgJEg8KB3RyZWVfaWQYAiABKAkSDQoFdmFsdWUYAyABKAQSGwoOcGFyZW50X25vZGVfaWQYBCABKAlIAIgBARIPCgdub2RlX3R4GAUgASgMEhEKCXJlZnVuZF90eBgGIAEoDBIMCgR2b3V0GAcgASgNEhwKFHZlcmlmeWluZ19wdWJsaWNfa2V5GAggASgMEiEKGW93bmVyX2lkZW50aXR5X3B1YmxpY19rZXkYCSABKAwSMAoQc2lnbmluZ19rZXlzaGFyZRgKIAEoCzIWLnNwYXJrLlNpZ25pbmdLZXlzaGFyZRIOCgZzdGF0dXMYCyABKAkSHwoHbmV0d29yaxgMIAEoDjIOLnNwYXJrLk5ldHdvcmsSMAoMY3JlYXRlZF90aW1lGA0gASgLMhouZ29vZ2xlLnByb3RvYnVmLlRpbWVzdGFtcBIwCgx1cGRhdGVkX3RpbWUYDiABKAsyGi5nb29nbGUucHJvdG9idWYuVGltZXN0YW1wEiAKGG93bmVyX3NpZ25pbmdfcHVibGljX2tleRgPIAEoDBIRCglkaXJlY3RfdHgYECABKAwSGAoQZGlyZWN0X3JlZnVuZF90eBgRIAEoDBIiChpkaXJlY3RfZnJvbV9jcGZwX3JlZnVuZF90eBgSIAEoDBIuCg90cmVlbm9kZV9zdGF0dXMYEyABKA4yFS5zcGFyay5UcmVlTm9kZVN0YXR1c0IRCg9fcGFyZW50X25vZGVfaWQieAodRmluYWxpemVOb2RlU2lnbmF0dXJlc1JlcXVlc3QSJwoGaW50ZW50GAEgASgOMhcuY29tbW9uLlNpZ25hdHVyZUludGVudBIuCg9ub2RlX3NpZ25hdHVyZXMYAiADKAsyFS5zcGFyay5Ob2RlU2lnbmF0dXJlcyJACh5GaW5hbGl6ZU5vZGVTaWduYXR1cmVzUmVzcG9uc2USHgoFbm9kZXMYASADKAsyDy5zcGFyay5UcmVlTm9kZSIzCgtTZWNyZXRTaGFyZRIUCgxzZWNyZXRfc2hhcmUYASABKAwSDgoGcHJvb2ZzGAIgAygMIh0KC1NlY3JldFByb29mEg4KBnByb29mcxgBIAMoDCLXAQoWTGVhZlJlZnVuZFR4U2lnbmluZ0pvYhIPCgdsZWFmX2lkGAEgASgJEjAKFXJlZnVuZF90eF9zaWduaW5nX2pvYhgCIAEoCzIRLnNwYXJrLlNpZ25pbmdKb2ISNwocZGlyZWN0X3JlZnVuZF90eF9zaWduaW5nX2pvYhgDIAEoCzIRLnNwYXJrLlNpZ25pbmdKb2ISQQomZGlyZWN0X2Zyb21fY3BmcF9yZWZ1bmRfdHhfc2lnbmluZ19qb2IYBCABKAsyES5zcGFyay5TaWduaW5nSm9iItgCChZVc2VyU2lnbmVkVHhTaWduaW5nSm9iEg8KB2xlYWZfaWQYASABKAkSGgoSc2lnbmluZ19wdWJsaWNfa2V5GAIgASgMEg4KBnJhd190eBgDIAEoDBI7ChhzaWduaW5nX25vbmNlX2NvbW1pdG1lbnQYBCABKAsyGS5jb21tb24uU2lnbmluZ0NvbW1pdG1lbnQSFgoOdXNlcl9zaWduYXR1cmUYBSABKAwSNgoTc2lnbmluZ19jb21taXRtZW50cxgGIAEoCzIZLnNwYXJrLlNpZ25pbmdDb21taXRtZW50cxIyChFhZGRpdGlvbmFsX2lucHV0cxgHIAMoCzIXLnNwYXJrLklucHV0U2lnbmluZ0RhdGESQAoVc3VidXNlcl9jb250cmlidXRpb25zGAggAygLMiEuc3BhcmsuU3ViVXNlclNpZ25pbmdDb250cmlidXRpb24inwEKEElucHV0U2lnbmluZ0RhdGESOwoYc2lnbmluZ19ub25jZV9jb21taXRtZW50GAEgASgLMhkuY29tbW9uLlNpZ25pbmdDb21taXRtZW50EhYKDnVzZXJfc2lnbmF0dXJlGAIgASgMEjYKE3NpZ25pbmdfY29tbWl0bWVudHMYAyABKAsyGS5zcGFyay5TaWduaW5nQ29tbWl0bWVudHMigwIKGUxlYWZSZWZ1bmRUeFNpZ25pbmdSZXN1bHQSDwoHbGVhZl9pZBgBIAEoCRI2ChhyZWZ1bmRfdHhfc2lnbmluZ19yZXN1bHQYAiABKAsyFC5zcGFyay5TaWduaW5nUmVzdWx0EhUKDXZlcmlmeWluZ19rZXkYAyABKAwSPQofZGlyZWN0X3JlZnVuZF90eF9zaWduaW5nX3Jlc3VsdBgEIAEoCzIULnNwYXJrLlNpZ25pbmdSZXN1bHQSRwopZGlyZWN0X2Zyb21fY3BmcF9yZWZ1bmRfdHhfc2lnbmluZ19yZXN1bHQYBSABKAsyFC5zcGFyay5TaWduaW5nUmVzdWx0IrECChRTdGFydFRyYW5zZmVyUmVxdWVzdBITCgt0cmFuc2Zlcl9pZBgBIAEoCRIhChlvd25lcl9pZGVudGl0eV9wdWJsaWNfa2V5GAIgASgMEjUKDmxlYXZlc190b19zZW5kGAMgAygLMh0uc3BhcmsuTGVhZlJlZnVuZFR4U2lnbmluZ0pvYhIkChxyZWNlaXZlcl9pZGVudGl0eV9wdWJsaWNfa2V5GAQgASgMEi8KC2V4cGlyeV90aW1lGAUgASgLMhouZ29vZ2xlLnByb3RvYnVmLlRpbWVzdGFtcBIwChB0cmFuc2Zlcl9wYWNrYWdlGAcgASgLMhYuc3BhcmsuVHJhbnNmZXJQYWNrYWdlEhUKDXNwYXJrX2ludm9pY2UYCiABKAlKBAgGEAdKBAgJEAoidQoVU3RhcnRUcmFuc2ZlclJlc3BvbnNlEiEKCHRyYW5zZmVyGAEgASgLMg8uc3BhcmsuVHJhbnNmZXISOQoPc2lnbmluZ19yZXN1bHRzGAIgAygLMiAuc3BhcmsuTGVhZlJlZnVuZFR4U2lnbmluZ1Jlc3VsdCK1AgoVU2VuZGVyVHJhbnNmZXJQYWNrYWdlEiEKGW93bmVyX2lkZW50aXR5X3B1YmxpY19rZXkYASABKAwSMAoQdHJhbnNmZXJfcGFja2FnZRgCIAEoCzIWLnNwYXJrLlRyYW5zZmVyUGFja2FnZRJjCh1yZWNlaXZlcl9pZGVudGl0eV9wdWJsaWNfa2V5cxgDIAMoCzI8LnNwYXJrLlNlbmRlclRyYW5zZmVyUGFja2FnZS5SZWNlaXZlcklkZW50aXR5UHVibGljS2V5c0VudHJ5Eh8KF21hbmlmZXN0X2hhc2hfc2lnbmF0dXJlGAQgASgMGkEKH1JlY2VpdmVySWRlbnRpdHlQdWJsaWNLZXlzRW50cnkSCwoDa2V5GAEgASgJEg0KBXZhbHVlGAIgASgMOgI4ASLJAQoWU3RhcnRUcmFuc2ZlclYzUmVxdWVzdBITCgt0cmFuc2Zlcl9pZBgBIAEoCRI1Cg9zZW5kZXJfcGFja2FnZXMYAiADKAsyHC5zcGFyay5TZW5kZXJUcmFuc2ZlclBhY2thZ2USLwoLZXhwaXJ5X3RpbWUYAyABKAsyGi5nb29nbGUucHJvdG9idWYuVGltZXN0YW1wEjIKEXRyYW5zZmVyX21hbmlmZXN0GAQgASgLMhcuc3BhcmsuVHJhbnNmZXJNYW5pZmVzdCLEAwoPVHJhbnNmZXJQYWNrYWdlEjUKDmxlYXZlc190b19zZW5kGAEgAygLMh0uc3BhcmsuVXNlclNpZ25lZFR4U2lnbmluZ0pvYhJGChFrZXlfdHdlYWtfcGFja2FnZRgCIAMoCzIrLnNwYXJrLlRyYW5zZmVyUGFja2FnZS5LZXlUd2Vha1BhY2thZ2VFbnRyeRIWCg51c2VyX3NpZ25hdHVyZRgDIAEoDBI8ChVkaXJlY3RfbGVhdmVzX3RvX3NlbmQYBCADKAsyHS5zcGFyay5Vc2VyU2lnbmVkVHhTaWduaW5nSm9iEkYKH2RpcmVjdF9mcm9tX2NwZnBfbGVhdmVzX3RvX3NlbmQYBSADKAsyHS5zcGFyay5Vc2VyU2lnbmVkVHhTaWduaW5nSm9iEigKDGhhc2hfdmFyaWFudBgGIAEoDjISLnNwYXJrLkhhc2hWYXJpYW50EjIKEWRlbGVnYXRpb25faW50ZW50GAcgASgLMhcuc3BhcmsuRGVsZWdhdGlvbkludGVudBo2ChRLZXlUd2Vha1BhY2thZ2VFbnRyeRILCgNrZXkYASABKAkSDQoFdmFsdWUYAiABKAw6AjgBIoQCChBEZWxlZ2F0aW9uSW50ZW50EhoKCGdyYW50X2lkGAEgASgJQgj6QgVyA7ABARIsChtzcGVuZGVyX2lkZW50aXR5X3B1YmxpY19rZXkYAiABKAxCB/pCBHoCaCESGQoRdG90YWxfYW1vdW50X3NhdHMYAyABKAQSTwoVcmVjZWl2ZXJfYW1vdW50c19zYXRzGAQgAygLMjAuc3BhcmsuRGVsZWdhdGlvbkludGVudC5SZWNlaXZlckFtb3VudHNTYXRzRW50cnkaOgoYUmVjZWl2ZXJBbW91bnRzU2F0c0VudHJ5EgsKA2tleRgBIAEoCRINCgV2YWx1ZRgCIAEoBDoCOAEiRAoRU2VuZExlYWZLZXlUd2Vha3MSLwoObGVhdmVzX3RvX3NlbmQYASADKAsyFy5zcGFyay5TZW5kTGVhZktleVR3ZWFrIqEDChBTZW5kTGVhZktleVR3ZWFrEg8KB2xlYWZfaWQYASABKAkSLgoSc2VjcmV0X3NoYXJlX3R3ZWFrGAIgASgLMhIuc3BhcmsuU2VjcmV0U2hhcmUSSwoTcHVia2V5X3NoYXJlc190d2VhaxgDIAMoCzIuLnNwYXJrLlNlbmRMZWFmS2V5VHdlYWsuUHVia2V5U2hhcmVzVHdlYWtFbnRyeRIVCg1zZWNyZXRfY2lwaGVyGAQgASgMEhMKCXNpZ25hdHVyZRgFIAEoDEgAEiwKD3R5cGVkX3NpZ25hdHVyZRgJIAEoCzIRLmNvbW1vbi5TaWduYXR1cmVIABIYChByZWZ1bmRfc2lnbmF0dXJlGAYgASgMEh8KF2RpcmVjdF9yZWZ1bmRfc2lnbmF0dXJlGAcgASgMEikKIWRpcmVjdF9mcm9tX2NwZnBfcmVmdW5kX3NpZ25hdHVyZRgIIAEoDBo4ChZQdWJrZXlTaGFyZXNUd2Vha0VudHJ5EgsKA2tleRgBIAEoCRINCgV2YWx1ZRgCIAEoDDoCOAFCBQoDc2lnIooBChdTdGFydFRyYW5zZmVyTXBjUmVxdWVzdBITCgt0cmFuc2Zlcl9pZBgBIAEoCRIhChlvd25lcl9pZGVudGl0eV9wdWJsaWNfa2V5GAIgASgMEjcKFG1wY190cmFuc2Zlcl9wYWNrYWdlGAMgASgLMhkuc3BhcmsuTXBjVHJhbnNmZXJQYWNrYWdlIscDChJNcGNUcmFuc2ZlclBhY2thZ2USIgoGbGVhdmVzGAEgAygLMhIuc3BhcmsuTXBjU2VuZExlYWYSPAoKa2V5X3R3ZWFrcxgCIAMoCzIoLnNwYXJrLk1wY1RyYW5zZmVyUGFja2FnZS5LZXlUd2Vha3NFbnRyeRI1Cg5sZWF2ZXNfdG9fc2VuZBgDIAMoCzIdLnNwYXJrLlVzZXJTaWduZWRUeFNpZ25pbmdKb2ISPAoVZGlyZWN0X2xlYXZlc190b19zZW5kGAQgAygLMh0uc3BhcmsuVXNlclNpZ25lZFR4U2lnbmluZ0pvYhJGCh9kaXJlY3RfZnJvbV9jcGZwX2xlYXZlc190b19zZW5kGAUgAygLMh0uc3BhcmsuVXNlclNpZ25lZFR4U2lnbmluZ0pvYhIzCg1hdXRob3JpemF0aW9uGAYgASgLMhwuc3BhcmsuVHJhbnNmZXJBdXRob3JpemF0aW9uEhEKCXBvc2l0aW9ucxgHIAMoDRpKCg5LZXlUd2Vha3NFbnRyeRILCgNrZXkYASABKAkSJwoFdmFsdWUYAiABKAsyGC5zcGFyay5NcGNPcGVyYXRvclNoYXJlczoCOAEikgEKC01wY1NlbmRMZWFmEg8KB2xlYWZfaWQYASABKAkSNQoTc3VidXNlcl9jb21taXRtZW50cxgCIAMoCzIYLnNwYXJrLlN1YlVzZXJDb21taXRtZW50EhUKDXNlY3JldF9jaXBoZXIYAyABKAwSJAoJc2lnbmF0dXJlGAQgASgLMhEuY29tbW9uLlNpZ25hdHVyZSIjChFTdWJVc2VyQ29tbWl0bWVudBIOCgZwcm9vZnMYASADKAwiOgoRTXBjT3BlcmF0b3JTaGFyZXMSJQoGc2hhcmVzGAEgAygLMhUuc3BhcmsuTXBjU2VhbGVkU2hhcmUiHwoOTXBjU2VhbGVkU2hhcmUSDQoFZWNpZXMYASABKAwiWQoVTXBjU2VhbGVkU2hhcmVQYXlsb2FkEhMKC3RyYW5zZmVyX2lkGAEgASgJEisKC2xlYWZfc2hhcmVzGAIgAygLMhYuc3BhcmsuTXBjTGVhZlN1YlNoYXJlIjgKD01wY0xlYWZTdWJTaGFyZRIPCgdsZWFmX2lkGAEgASgJEhQKDHNlY3JldF9zaGFyZRgCIAEoDCLOAQoVVHJhbnNmZXJBdXRob3JpemF0aW9uEhMKC3RyYW5zZmVyX2lkGAEgASgJEigKBmxlYXZlcxgCIAMoCzIYLnNwYXJrLkxlYWZBdXRob3JpemF0aW9uEh8KF3JlZnVuZF9zaWdoYXNoZXNfZGlnZXN0GAMgASgMEi8KC2V4cGlyeV90aW1lGAQgASgLMhouZ29vZ2xlLnByb3RvYnVmLlRpbWVzdGFtcBIkCglzaWduYXR1cmUYBSABKAsyES5jb21tb24uU2lnbmF0dXJlIpoBChFMZWFmQXV0aG9yaXphdGlvbhIPCgdsZWFmX2lkGAEgASgJEhMKC2Ftb3VudF9zYXRzGAIgASgEEiAKGG93bmVyX3NpZ25pbmdfcHVibGljX2tleRgDIAEoDBIXCg9tYXNrX2NvbW1pdG1lbnQYBCABKAwSJAoccmVjZWl2ZXJfaWRlbnRpdHlfcHVibGljX2tleRgFIAEoDCJsChpTdWJVc2VyU2lnbmluZ0NvbnRyaWJ1dGlvbhIzChBub25jZV9jb21taXRtZW50GAEgASgLMhkuY29tbW9uLlNpZ25pbmdDb21taXRtZW50EhkKEXBhcnRpYWxfc2lnbmF0dXJlGAIgASgMIqABChdGaW5hbGl6ZVRyYW5zZmVyUmVxdWVzdBITCgt0cmFuc2Zlcl9pZBgBIAEoCRIhChlvd25lcl9pZGVudGl0eV9wdWJsaWNfa2V5GAIgASgMEi8KDmxlYXZlc190b19zZW5kGAMgAygLMhcuc3BhcmsuU2VuZExlYWZLZXlUd2VhaxIcChRzcGFya19wYXltZW50X2ludGVudBgEIAEoCSKWAQoqRmluYWxpemVUcmFuc2ZlcldpdGhUcmFuc2ZlclBhY2thZ2VSZXF1ZXN0EhMKC3RyYW5zZmVyX2lkGAEgASgJEiEKGW93bmVyX2lkZW50aXR5X3B1YmxpY19rZXkYAiABKAwSMAoQdHJhbnNmZXJfcGFja2FnZRgDIAEoCzIWLnNwYXJrLlRyYW5zZmVyUGFja2FnZSI9ChhGaW5hbGl6ZVRyYW5zZmVyUmVzcG9uc2USIQoIdHJhbnNmZXIYASABKAsyDy5zcGFyay5UcmFuc2ZlciK0AQoQVHJhbnNmZXJSZWNlaXZlchIbChNpZGVudGl0eV9wdWJsaWNfa2V5GAEgASgMEhMKC2Ftb3VudF9zYXRzGAIgASgEEi0KBnN0YXR1cxgDIAEoDjIdLnNwYXJrLlRyYW5zZmVyUmVjZWl2ZXJTdGF0dXMSCgoCaWQYBCABKAkSMwoPY29tcGxldGlvbl90aW1lGAUgASgLMhouZ29vZ2xlLnByb3RvYnVmLlRpbWVzdGFtcCI5Cg5UcmFuc2ZlclNlbmRlchIKCgJpZBgBIAEoCRIbChNpZGVudGl0eV9wdWJsaWNfa2V5GAIgASgMIoUECghUcmFuc2ZlchIKCgJpZBgBIAEoCRIiChpzZW5kZXJfaWRlbnRpdHlfcHVibGljX2tleRgCIAEoDBIkChxyZWNlaXZlcl9pZGVudGl0eV9wdWJsaWNfa2V5GAMgASgMEiUKBnN0YXR1cxgEIAEoDjIVLnNwYXJrLlRyYW5zZmVyU3RhdHVzEhMKC3RvdGFsX3ZhbHVlGAUgASgEEi8KC2V4cGlyeV90aW1lGAYgASgLMhouZ29vZ2xlLnByb3RvYnVmLlRpbWVzdGFtcBIjCgZsZWF2ZXMYByADKAsyEy5zcGFyay5UcmFuc2ZlckxlYWYSMAoMY3JlYXRlZF90aW1lGAggASgLMhouZ29vZ2xlLnByb3RvYnVmLlRpbWVzdGFtcBIwCgx1cGRhdGVkX3RpbWUYCSABKAsyGi5nb29nbGUucHJvdG9idWYuVGltZXN0YW1wEiEKBHR5cGUYCiABKA4yEy5zcGFyay5UcmFuc2ZlclR5cGUSFQoNc3BhcmtfaW52b2ljZRgLIAEoCRIfCgduZXR3b3JrGAwgASgOMg4uc3BhcmsuTmV0d29yaxIqCglyZWNlaXZlcnMYDSADKAsyFy5zcGFyay5UcmFuc2ZlclJlY2VpdmVyEiYKB3NlbmRlcnMYDiADKAsyFS5zcGFyay5UcmFuc2ZlclNlbmRlciLmAgoMVHJhbnNmZXJMZWFmEh0KBGxlYWYYASABKAsyDy5zcGFyay5UcmVlTm9kZRIVCg1zZWNyZXRfY2lwaGVyGAIgASgMEhMKCXNpZ25hdHVyZRgDIAEoDEgAEiwKD3R5cGVkX3NpZ25hdHVyZRgKIAEoCzIRLmNvbW1vbi5TaWduYXR1cmVIABIeChZpbnRlcm1lZGlhdGVfcmVmdW5kX3R4GAQgASgMEiUKHWludGVybWVkaWF0ZV9kaXJlY3RfcmVmdW5kX3R4GAUgASgMEi8KJ2ludGVybWVkaWF0ZV9kaXJlY3RfZnJvbV9jcGZwX3JlZnVuZF90eBgGIAEoDBIkChxwZW5kaW5nX2tleV90d2Vha19wdWJsaWNfa2V5GAcgASgMEhwKFHRyYW5zZmVyX3JlY2VpdmVyX2lkGAggASgJEhoKEnRyYW5zZmVyX3NlbmRlcl9pZBgJIAEoCUIFCgNzaWciuAIKEFRyYW5zZmVyTWFuaWZlc3QSGAoHdmVyc2lvbhgBIAEoDUIH+kIEKgIgABIdCgt0cmFuc2Zlcl9pZBgCIAEoCUII+kIFcgOwAQESKQoHbmV0d29yaxgDIAEoDjIOLnNwYXJrLk5ldHdvcmtCCPpCBYIBAiAAEjgKFHRyYW5zZmVyX2V4cGlyeV90aW1lGAQgASgLMhouZ29vZ2xlLnByb3RvYnVmLlRpbWVzdGFtcBIsCgVlZGdlcxgFIAMoCzITLnNwYXJrLk1hbmlmZXN0RWRnZUII+kIFkgECCAESIQoEZmVlcxgGIAMoCzITLnNwYXJrLkZlZUNvbXBvbmVudBI1ChFxdW90ZV9leHBpcnlfdGltZRgHIAEoCzIaLmdvb2dsZS5wcm90b2J1Zi5UaW1lc3RhbXAiOQoOTWFuaWZlc3RBbW91bnQSDgoEc2F0cxgBIAEoBEgAEg0KA2JwcxgCIAEoDUgAQggKBmFtb3VudCKRAQoMTWFuaWZlc3RFZGdlEisKGnNlbmRlcl9pZGVudGl0eV9wdWJsaWNfa2V5GAEgASgMQgf6QgR6AmghEi0KHHJlY2VpdmVyX2lkZW50aXR5X3B1YmxpY19rZXkYAiABKAxCB/pCBHoCaCESJQoGYW1vdW50GAMgASgLMhUuc3BhcmsuTWFuaWZlc3RBbW91bnQipAEKDEZlZUNvbXBvbmVudBIgCgZzb3VyY2UYASABKA4yEC5zcGFyay5GZWVTb3VyY2USHAoEcm9sZRgCIAEoDjIOLnNwYXJrLkZlZVJvbGUSJQoGYW1vdW50GAMgASgLMhUuc3BhcmsuTWFuaWZlc3RBbW91bnQSLQoccmVjZWl2ZXJfaWRlbnRpdHlfcHVibGljX2tleRgEIAEoDEIH+kIEegJoISLZAwoOVHJhbnNmZXJGaWx0ZXISJgoccmVjZWl2ZXJfaWRlbnRpdHlfcHVibGljX2tleRgBIAEoDEgAEiQKGnNlbmRlcl9pZGVudGl0eV9wdWJsaWNfa2V5GAIgASgMSAASMAomc2VuZGVyX29yX3JlY2VpdmVyX2lkZW50aXR5X3B1YmxpY19rZXkYPCABKAxIABIUCgx0cmFuc2Zlcl9pZHMYAyADKAkSDQoFbGltaXQYKCABKAMSDgoGb2Zmc2V0GDIgASgDEiIKBXR5cGVzGEYgAygOMhMuc3BhcmsuVHJhbnNmZXJUeXBlEh8KB25ldHdvcmsYBCABKA4yDi5zcGFyay5OZXR3b3JrEicKCHN0YXR1c2VzGFAgAygOMhUuc3BhcmsuVHJhbnNmZXJTdGF0dXMSGwoFb3JkZXIYBSABKA4yDC5zcGFyay5PcmRlchIzCg1jcmVhdGVkX2FmdGVyGAYgASgLMhouZ29vZ2xlLnByb3RvYnVmLlRpbWVzdGFtcEgBEjQKDmNyZWF0ZWRfYmVmb3JlGAcgASgLMhouZ29vZ2xlLnByb3RvYnVmLlRpbWVzdGFtcEgBQg0KC3BhcnRpY2lwYW50Qg0KC3RpbWVfZmlsdGVyIkwKFlF1ZXJ5VHJhbnNmZXJzUmVzcG9uc2USIgoJdHJhbnNmZXJzGAEgAygLMg8uc3BhcmsuVHJhbnNmZXISDgoGb2Zmc2V0GAIgASgDInIKGVF1ZXJ5VHJhbnNmZXJzQnlJZFJlcXVlc3QSKAoMdHJhbnNmZXJfaWRzGAEgAygJQhL6Qg+SAQwIARDoByIFcgOwAQESKwoHbmV0d29yaxgCIAEoDjIOLnNwYXJrLk5ldHdvcmtCCvpCB4IBBBABIAAi3AEKEUNsYWltTGVhZktleVR3ZWFrEg8KB2xlYWZfaWQYASABKAkSLgoSc2VjcmV0X3NoYXJlX3R3ZWFrGAIgASgLMhIuc3BhcmsuU2VjcmV0U2hhcmUSTAoTcHVia2V5X3NoYXJlc190d2VhaxgDIAMoCzIvLnNwYXJrLkNsYWltTGVhZktleVR3ZWFrLlB1YmtleVNoYXJlc1R3ZWFrRW50cnkaOAoWUHVia2V5U2hhcmVzVHdlYWtFbnRyeRILCgNrZXkYASABKAkSDQoFdmFsdWUYAiABKAw6AjgBIkkKEkNsYWltTGVhZktleVR3ZWFrcxIzChFsZWF2ZXNfdG9fcmVjZWl2ZRgBIAMoCzIYLnNwYXJrLkNsYWltTGVhZktleVR3ZWFrIo0DCgxDbGFpbVBhY2thZ2USNgoPbGVhdmVzX3RvX2NsYWltGAEgAygLMh0uc3BhcmsuVXNlclNpZ25lZFR4U2lnbmluZ0pvYhJDChFrZXlfdHdlYWtfcGFja2FnZRgCIAMoCzIoLnNwYXJrLkNsYWltUGFja2FnZS5LZXlUd2Vha1BhY2thZ2VFbnRyeRIWCg51c2VyX3NpZ25hdHVyZRgDIAEoDBI9ChZkaXJlY3RfbGVhdmVzX3RvX2NsYWltGAQgAygLMh0uc3BhcmsuVXNlclNpZ25lZFR4U2lnbmluZ0pvYhJHCiBkaXJlY3RfZnJvbV9jcGZwX2xlYXZlc190b19jbGFpbRgFIAMoCzIdLnNwYXJrLlVzZXJTaWduZWRUeFNpZ25pbmdKb2ISKAoMaGFzaF92YXJpYW50GAYgASgOMhIuc3BhcmsuSGFzaFZhcmlhbnQaNgoUS2V5VHdlYWtQYWNrYWdlRW50cnkSCwoDa2V5GAEgASgJEg0KBXZhbHVlGAIgASgMOgI4ASJ6ChRDbGFpbVRyYW5zZmVyUmVxdWVzdBITCgt0cmFuc2Zlcl9pZBgBIAEoCRIhChlvd25lcl9pZGVudGl0eV9wdWJsaWNfa2V5GAIgASgMEioKDWNsYWltX3BhY2thZ2UYAyABKAsyEy5zcGFyay5DbGFpbVBhY2thZ2UiOgoVQ2xhaW1UcmFuc2ZlclJlc3BvbnNlEiEKCHRyYW5zZmVyGAEgASgLMg8uc3BhcmsuVHJhbnNmZXIijAEKHUNsYWltVHJhbnNmZXJUd2Vha0tleXNSZXF1ZXN0EhMKC3RyYW5zZmVyX2lkGAEgASgJEiEKGW93bmVyX2lkZW50aXR5X3B1YmxpY19rZXkYAiABKAwSMwoRbGVhdmVzX3RvX3JlY2VpdmUYAyADKAsyGC5zcGFyay5DbGFpbUxlYWZLZXlUd2VhayKUAQofQ2xhaW1UcmFuc2ZlclNpZ25SZWZ1bmRzUmVxdWVzdBITCgt0cmFuc2Zlcl9pZBgBIAEoCRIhChlvd25lcl9pZGVudGl0eV9wdWJsaWNfa2V5GAIgASgMEjMKDHNpZ25pbmdfam9icxgDIAMoCzIdLnNwYXJrLkxlYWZSZWZ1bmRUeFNpZ25pbmdKb2JKBAgEEAUiXQogQ2xhaW1UcmFuc2ZlclNpZ25SZWZ1bmRzUmVzcG9uc2USOQoPc2lnbmluZ19yZXN1bHRzGAEgAygLMiAuc3BhcmsuTGVhZlJlZnVuZFR4U2lnbmluZ1Jlc3VsdCKqAQoZU3RvcmVQcmVpbWFnZVNoYXJlUmVxdWVzdBIUCgxwYXltZW50X2hhc2gYASABKAwSKgoOcHJlaW1hZ2Vfc2hhcmUYAiABKAsyEi5zcGFyay5TZWNyZXRTaGFyZRIRCgl0aHJlc2hvbGQYAyABKA0SFgoOaW52b2ljZV9zdHJpbmcYBCABKAkSIAoYdXNlcl9pZGVudGl0eV9wdWJsaWNfa2V5GAUgASgMIroCChtTdG9yZVByZWltYWdlU2hhcmVWMlJlcXVlc3QSFAoMcGF5bWVudF9oYXNoGAEgASgMEmIKGWVuY3J5cHRlZF9wcmVpbWFnZV9zaGFyZXMYAiADKAsyPy5zcGFyay5TdG9yZVByZWltYWdlU2hhcmVWMlJlcXVlc3QuRW5jcnlwdGVkUHJlaW1hZ2VTaGFyZXNFbnRyeRIRCgl0aHJlc2hvbGQYAyABKA0SFgoOaW52b2ljZV9zdHJpbmcYBCABKAkSIAoYdXNlcl9pZGVudGl0eV9wdWJsaWNfa2V5GAUgASgMGj4KHEVuY3J5cHRlZFByZWltYWdlU2hhcmVzRW50cnkSCwoDa2V5GAEgASgJEg0KBXZhbHVlGAIgASgMOgI4AUoECAYQB1IOdXNlcl9zaWduYXR1cmUi3AEKG1JlcXVlc3RlZFNpZ25pbmdDb21taXRtZW50cxJiChlzaWduaW5nX25vbmNlX2NvbW1pdG1lbnRzGAEgAygLMj8uc3BhcmsuUmVxdWVzdGVkU2lnbmluZ0NvbW1pdG1lbnRzLlNpZ25pbmdOb25jZUNvbW1pdG1lbnRzRW50cnkaWQocU2lnbmluZ05vbmNlQ29tbWl0bWVudHNFbnRyeRILCgNrZXkYASABKAkSKAoFdmFsdWUYAiABKAsyGS5jb21tb24uU2lnbmluZ0NvbW1pdG1lbnQ6AjgBIlYKHEdldFNpZ25pbmdDb21taXRtZW50c1JlcXVlc3QSEAoIbm9kZV9pZHMYASADKAkSDQoFY291bnQYAiABKA0SFQoNbm9kZV9pZF9jb3VudBgDIAEoDSJgCh1HZXRTaWduaW5nQ29tbWl0bWVudHNSZXNwb25zZRI/ChNzaWduaW5nX2NvbW1pdG1lbnRzGAEgAygLMiIuc3BhcmsuUmVxdWVzdGVkU2lnbmluZ0NvbW1pdG1lbnRzIroBChJTaWduaW5nQ29tbWl0bWVudHMSTgoTc2lnbmluZ19jb21taXRtZW50cxgBIAMoCzIxLnNwYXJrLlNpZ25pbmdDb21taXRtZW50cy5TaWduaW5nQ29tbWl0bWVudHNFbnRyeRpUChdTaWduaW5nQ29tbWl0bWVudHNFbnRyeRILCgNrZXkYASABKAkSKAoFdmFsdWUYAiABKAsyGS5jb21tb24uU2lnbmluZ0NvbW1pdG1lbnQ6AjgBIiwKEkludm9pY2VBbW91bnRQcm9vZhIWCg5ib2x0MTFfaW52b2ljZRgBIAEoCSJcCg1JbnZvaWNlQW1vdW50EhIKCnZhbHVlX3NhdHMYASABKAQSNwoUaW52b2ljZV9hbW91bnRfcHJvb2YYAiABKAsyGS5zcGFyay5JbnZvaWNlQW1vdW50UHJvb2YiygIKG0luaXRpYXRlUHJlaW1hZ2VTd2FwUmVxdWVzdBIUCgxwYXltZW50X2hhc2gYASABKAwSLAoOaW52b2ljZV9hbW91bnQYAiABKAsyFC5zcGFyay5JbnZvaWNlQW1vdW50EjkKBnJlYXNvbhgDIAEoDjIpLnNwYXJrLkluaXRpYXRlUHJlaW1hZ2VTd2FwUmVxdWVzdC5SZWFzb24SJAoccmVjZWl2ZXJfaWRlbnRpdHlfcHVibGljX2tleRgFIAEoDBIQCghmZWVfc2F0cxgGIAEoBBI1ChB0cmFuc2Zlcl9yZXF1ZXN0GAcgASgLMhsuc3BhcmsuU3RhcnRUcmFuc2ZlclJlcXVlc3QiLQoGUmVhc29uEg8KC1JFQVNPTl9TRU5EEAASEgoOUkVBU09OX1JFQ0VJVkUQAUoECAQQBVIIdHJhbnNmZXIiuAIKHUluaXRpYXRlUHJlaW1hZ2VTd2FwVjRSZXF1ZXN0Eh0KDHBheW1lbnRfaGFzaBgBIAEoDEIH+kIEegJoIBIsCg5pbnZvaWNlX2Ftb3VudBgCIAEoCzIULnNwYXJrLkludm9pY2VBbW91bnQSOQoGcmVhc29uGAMgASgOMikuc3BhcmsuSW5pdGlhdGVQcmVpbWFnZVN3YXBSZXF1ZXN0LlJlYXNvbhItChxhdHRlc3Rvcl9pZGVudGl0eV9wdWJsaWNfa2V5GAQgASgMQgf6QgR6AmghEhoKEmF0dGVzdG9yX3NpZ25hdHVyZRgFIAEoDBJEChN0cmFuc2Zlcl92M19yZXF1ZXN0GAYgASgLMh0uc3BhcmsuU3RhcnRUcmFuc2ZlclYzUmVxdWVzdEII+kIFigECEAEiUwocSW5pdGlhdGVQcmVpbWFnZVN3YXBSZXNwb25zZRIQCghwcmVpbWFnZRgBIAEoDBIhCgh0cmFuc2ZlchgCIAEoCzIPLnNwYXJrLlRyYW5zZmVyIiYKCE91dFBvaW50EgwKBHR4aWQYASABKAwSDAoEdm91dBgCIAEoDSKBAQoWQ29vcGVyYXRpdmVFeGl0UmVxdWVzdBItCgh0cmFuc2ZlchgBIAEoCzIbLnNwYXJrLlN0YXJ0VHJhbnNmZXJSZXF1ZXN0Eg8KB2V4aXRfaWQYAiABKAkSEQoJZXhpdF90eGlkGAMgASgMEhQKDGNvbm5lY3Rvcl90eBgEIAEoDCJ3ChdDb29wZXJhdGl2ZUV4aXRSZXNwb25zZRIhCgh0cmFuc2ZlchgBIAEoCzIPLnNwYXJrLlRyYW5zZmVyEjkKD3NpZ25pbmdfcmVzdWx0cxgCIAMoCzIgLnNwYXJrLkxlYWZSZWZ1bmRUeFNpZ25pbmdSZXN1bHQixAEKFkNvdW50ZXJMZWFmU3dhcFJlcXVlc3QSLQoIdHJhbnNmZXIYASABKAsyGy5zcGFyay5TdGFydFRyYW5zZmVyUmVxdWVzdBIPCgdzd2FwX2lkGAIgASgJEhoKEmFkYXB0b3JfcHVibGljX2tleRgDIAEoDBIhChlkaXJlY3RfYWRhcHRvcl9wdWJsaWNfa2V5GAQgASgMEisKI2RpcmVjdF9mcm9tX2NwZnBfYWRhcHRvcl9wdWJsaWNfa2V5GAUgASgMIncKF0NvdW50ZXJMZWFmU3dhcFJlc3BvbnNlEiEKCHRyYW5zZmVyGAEgASgLMg8uc3BhcmsuVHJhbnNmZXISOQoPc2lnbmluZ19yZXN1bHRzGAIgAygLMiAuc3BhcmsuTGVhZlJlZnVuZFR4U2lnbmluZ1Jlc3VsdCJ1ChZSZWZyZXNoVGltZWxvY2tSZXF1ZXN0Eg8KB2xlYWZfaWQYASABKAkSIQoZb3duZXJfaWRlbnRpdHlfcHVibGljX2tleRgCIAEoDBInCgxzaWduaW5nX2pvYnMYAyADKAsyES5zcGFyay5TaWduaW5nSm9iImMKHFJlZnJlc2hUaW1lbG9ja1NpZ25pbmdSZXN1bHQSLAoOc2lnbmluZ19yZXN1bHQYASABKAsyFC5zcGFyay5TaWduaW5nUmVzdWx0EhUKDXZlcmlmeWluZ19rZXkYAiABKAwiVwoXUmVmcmVzaFRpbWVsb2NrUmVzcG9uc2USPAoPc2lnbmluZ19yZXN1bHRzGAEgAygLMiMuc3BhcmsuUmVmcmVzaFRpbWVsb2NrU2lnbmluZ1Jlc3VsdCLcAgoRRXh0ZW5kTGVhZlJlcXVlc3QSDwoHbGVhZl9pZBgBIAEoCRIhChlvd25lcl9pZGVudGl0eV9wdWJsaWNfa2V5GAIgASgMEi4KE25vZGVfdHhfc2lnbmluZ19qb2IYAyABKAsyES5zcGFyay5TaWduaW5nSm9iEjAKFXJlZnVuZF90eF9zaWduaW5nX2pvYhgEIAEoCzIRLnNwYXJrLlNpZ25pbmdKb2ISNQoaZGlyZWN0X25vZGVfdHhfc2lnbmluZ19qb2IYBSABKAsyES5zcGFyay5TaWduaW5nSm9iEjcKHGRpcmVjdF9yZWZ1bmRfdHhfc2lnbmluZ19qb2IYBiABKAsyES5zcGFyay5TaWduaW5nSm9iEkEKJmRpcmVjdF9mcm9tX2NwZnBfcmVmdW5kX3R4X3NpZ25pbmdfam9iGAcgASgLMhEuc3BhcmsuU2lnbmluZ0pvYiJeChdFeHRlbmRMZWFmU2lnbmluZ1Jlc3VsdBIsCg5zaWduaW5nX3Jlc3VsdBgBIAEoCzIULnNwYXJrLlNpZ25pbmdSZXN1bHQSFQoNdmVyaWZ5aW5nX2tleRgCIAEoDCKKAwoSRXh0ZW5kTGVhZlJlc3BvbnNlEg8KB2xlYWZfaWQYASABKAkSPgoWbm9kZV90eF9zaWduaW5nX3Jlc3VsdBgCIAEoCzIeLnNwYXJrLkV4dGVuZExlYWZTaWduaW5nUmVzdWx0EkAKGHJlZnVuZF90eF9zaWduaW5nX3Jlc3VsdBgDIAEoCzIeLnNwYXJrLkV4dGVuZExlYWZTaWduaW5nUmVzdWx0EkUKHWRpcmVjdF9ub2RlX3R4X3NpZ25pbmdfcmVzdWx0GAQgASgLMh4uc3BhcmsuRXh0ZW5kTGVhZlNpZ25pbmdSZXN1bHQSRwofZGlyZWN0X3JlZnVuZF90eF9zaWduaW5nX3Jlc3VsdBgFIAEoCzIeLnNwYXJrLkV4dGVuZExlYWZTaWduaW5nUmVzdWx0ElEKKWRpcmVjdF9mcm9tX2NwZnBfcmVmdW5kX3R4X3NpZ25pbmdfcmVzdWx0GAYgASgLMh4uc3BhcmsuRXh0ZW5kTGVhZlNpZ25pbmdSZXN1bHQiWgoSQWRkcmVzc1JlcXVlc3ROb2RlEhcKD3VzZXJfcHVibGljX2tleRgBIAEoDBIrCghjaGlsZHJlbhgCIAMoCzIZLnNwYXJrLkFkZHJlc3NSZXF1ZXN0Tm9kZSLHAQoZUHJlcGFyZVRyZWVBZGRyZXNzUmVxdWVzdBIvChJwYXJlbnRfbm9kZV9vdXRwdXQYASABKAsyES5zcGFyay5Ob2RlT3V0cHV0SAASJAoNb25fY2hhaW5fdXR4bxgCIAEoCzILLnNwYXJrLlVUWE9IABInCgRub2RlGAMgASgLMhkuc3BhcmsuQWRkcmVzc1JlcXVlc3ROb2RlEiAKGHVzZXJfaWRlbnRpdHlfcHVibGljX2tleRgEIAEoDEIICgZzb3VyY2UiVAoLQWRkcmVzc05vZGUSHwoHYWRkcmVzcxgBIAEoCzIOLnNwYXJrLkFkZHJlc3MSJAoIY2hpbGRyZW4YAiADKAsyEi5zcGFyay5BZGRyZXNzTm9kZSI+ChpQcmVwYXJlVHJlZUFkZHJlc3NSZXNwb25zZRIgCgRub2RlGAEgASgLMhIuc3BhcmsuQWRkcmVzc05vZGUiygIKDENyZWF0aW9uTm9kZRIuChNub2RlX3R4X3NpZ25pbmdfam9iGAEgASgLMhEuc3BhcmsuU2lnbmluZ0pvYhIwChVyZWZ1bmRfdHhfc2lnbmluZ19qb2IYAiABKAsyES5zcGFyay5TaWduaW5nSm9iEiUKCGNoaWxkcmVuGAMgAygLMhMuc3BhcmsuQ3JlYXRpb25Ob2RlEjUKGmRpcmVjdF9ub2RlX3R4X3NpZ25pbmdfam9iGAQgASgLMhEuc3BhcmsuU2lnbmluZ0pvYhI3ChxkaXJlY3RfcmVmdW5kX3R4X3NpZ25pbmdfam9iGAUgASgLMhEuc3BhcmsuU2lnbmluZ0pvYhJBCiZkaXJlY3RfZnJvbV9jcGZwX3JlZnVuZF90eF9zaWduaW5nX2pvYhgGIAEoCzIRLnNwYXJrLlNpZ25pbmdKb2IiuQEKEUNyZWF0ZVRyZWVSZXF1ZXN0Ei8KEnBhcmVudF9ub2RlX291dHB1dBgBIAEoCzIRLnNwYXJrLk5vZGVPdXRwdXRIABIkCg1vbl9jaGFpbl91dHhvGAIgASgLMgsuc3BhcmsuVVRYT0gAEiEKBG5vZGUYAyABKAsyEy5zcGFyay5DcmVhdGlvbk5vZGUSIAoYdXNlcl9pZGVudGl0eV9wdWJsaWNfa2V5GAQgASgMQggKBnNvdXJjZSKJAwoUQ3JlYXRpb25SZXNwb25zZU5vZGUSDwoHbm9kZV9pZBgBIAEoCRI0ChZub2RlX3R4X3NpZ25pbmdfcmVzdWx0GAIgASgLMhQuc3BhcmsuU2lnbmluZ1Jlc3VsdBI2ChhyZWZ1bmRfdHhfc2lnbmluZ19yZXN1bHQYAyABKAsyFC5zcGFyay5TaWduaW5nUmVzdWx0Ei0KCGNoaWxkcmVuGAQgAygLMhsuc3BhcmsuQ3JlYXRpb25SZXNwb25zZU5vZGUSOwodZGlyZWN0X25vZGVfdHhfc2lnbmluZ19yZXN1bHQYBSABKAsyFC5zcGFyay5TaWduaW5nUmVzdWx0Ej0KH2RpcmVjdF9yZWZ1bmRfdHhfc2lnbmluZ19yZXN1bHQYBiABKAsyFC5zcGFyay5TaWduaW5nUmVzdWx0EkcKKWRpcmVjdF9mcm9tX2NwZnBfcmVmdW5kX3R4X3NpZ25pbmdfcmVzdWx0GAcgASgLMhQuc3BhcmsuU2lnbmluZ1Jlc3VsdCI/ChJDcmVhdGVUcmVlUmVzcG9uc2USKQoEbm9kZRgBIAEoCzIbLnNwYXJrLkNyZWF0aW9uUmVzcG9uc2VOb2RlIl0KE1NpZ25pbmdPcGVyYXRvckluZm8SDQoFaW5kZXgYASABKAQSEgoKaWRlbnRpZmllchgCIAEoCRISCgpwdWJsaWNfa2V5GAMgASgMEg8KB2FkZHJlc3MYBCABKAkizQEKHkdldFNpZ25pbmdPcGVyYXRvckxpc3RSZXNwb25zZRJWChFzaWduaW5nX29wZXJhdG9ycxgBIAMoCzI7LnNwYXJrLkdldFNpZ25pbmdPcGVyYXRvckxpc3RSZXNwb25zZS5TaWduaW5nT3BlcmF0b3JzRW50cnkaUwoVU2lnbmluZ09wZXJhdG9yc0VudHJ5EgsKA2tleRgBIAEoCRIpCgV2YWx1ZRgCIAEoCzIaLnNwYXJrLlNpZ25pbmdPcGVyYXRvckluZm86AjgBIsACChtQcmVpbWFnZVJlcXVlc3RXaXRoVHJhbnNmZXISHQoMcGF5bWVudF9oYXNoGAEgASgMQgf6QgR6AmggEikKGHJlY2VpdmVyX2lkZW50aXR5X3B1YmtleRgCIAEoDEIH+kIEegJoIRIsCgZzdGF0dXMYAyABKA4yHC5zcGFyay5QcmVpbWFnZVJlcXVlc3RTdGF0dXMSMAoMY3JlYXRlZF90aW1lGAQgASgLMhouZ29vZ2xlLnByb3RvYnVmLlRpbWVzdGFtcBImCgh0cmFuc2ZlchgFIAEoCzIPLnNwYXJrLlRyYW5zZmVySACIAQESFQoIcHJlaW1hZ2UYBiABKAxIAYgBARIeChZzZW5kZXJfaWRlbnRpdHlfcHVia2V5GAcgASgMQgsKCV90cmFuc2ZlckILCglfcHJlaW1hZ2Ui8wEKEFF1ZXJ5SHRsY1JlcXVlc3QSFgoOcGF5bWVudF9oYXNoZXMYASADKAwSJAoTaWRlbnRpdHlfcHVibGljX2tleRgCIAEoDEIH+kIEegJoIRIxCgZzdGF0dXMYAyABKA4yHC5zcGFyay5QcmVpbWFnZVJlcXVlc3RTdGF0dXNIAIgBARINCgVsaW1pdBgEIAEoAxIOCgZvZmZzZXQYBSABKAMSFAoMdHJhbnNmZXJfaWRzGAYgAygJEi4KCm1hdGNoX3JvbGUYByABKA4yGi5zcGFyay5QcmVpbWFnZVJlcXVlc3RSb2xlQgkKB19zdGF0dXMiYgoRUXVlcnlIdGxjUmVzcG9uc2USPQoRcHJlaW1hZ2VfcmVxdWVzdHMYASADKAsyIi5zcGFyay5QcmVpbWFnZVJlcXVlc3RXaXRoVHJhbnNmZXISDgoGb2Zmc2V0GAIgASgDIl0KFlByb3ZpZGVQcmVpbWFnZVJlcXVlc3QSFAoMcGF5bWVudF9oYXNoGAEgASgMEhAKCHByZWltYWdlGAIgASgMEhsKE2lkZW50aXR5X3B1YmxpY19rZXkYAyABKAwiPAoXUHJvdmlkZVByZWltYWdlUmVzcG9uc2USIQoIdHJhbnNmZXIYASABKAsyDy5zcGFyay5UcmFuc2ZlciJgChRRdWVyeVByZWltYWdlUmVxdWVzdBIdCgxwYXltZW50X2hhc2gYASABKAxCB/pCBHoCaCASKQoYcmVjZWl2ZXJfaWRlbnRpdHlfcHVia2V5GAIgASgMQgf6QgR6AmghIjsKFVF1ZXJ5UHJlaW1hZ2VSZXNwb25zZRIVCghwcmVpbWFnZRgBIAEoDEgAiAEBQgsKCV9wcmVpbWFnZSIfCgtUcmVlTm9kZUlkcxIQCghub2RlX2lkcxgBIAMoCSLoAQoRUXVlcnlOb2Rlc1JlcXVlc3QSHwoVb3duZXJfaWRlbnRpdHlfcHVia2V5GAEgASgMSAASJgoIbm9kZV9pZHMYAiABKAsyEi5zcGFyay5UcmVlTm9kZUlkc0gAEhcKD2luY2x1ZGVfcGFyZW50cxgDIAEoCBINCgVsaW1pdBgEIAEoAxIOCgZvZmZzZXQYBSABKAMSHwoHbmV0d29yaxgGIAEoDjIOLnNwYXJrLk5ldHdvcmsSJwoIc3RhdHVzZXMYByADKA4yFS5zcGFyay5UcmVlTm9kZVN0YXR1c0IICgZzb3VyY2UimAEKElF1ZXJ5Tm9kZXNSZXNwb25zZRIzCgVub2RlcxgBIAMoCzIkLnNwYXJrLlF1ZXJ5Tm9kZXNSZXNwb25zZS5Ob2Rlc0VudHJ5Eg4KBm9mZnNldBgCIAEoAxo9CgpOb2Rlc0VudHJ5EgsKA2tleRgBIAEoCRIeCgV2YWx1ZRgCIAEoCzIPLnNwYXJrLlRyZWVOb2RlOgI4ASJQChVDYW5jZWxUcmFuc2ZlclJlcXVlc3QSEwoLdHJhbnNmZXJfaWQYASABKAkSIgoac2VuZGVyX2lkZW50aXR5X3B1YmxpY19rZXkYAiABKAwiOwoWQ2FuY2VsVHJhbnNmZXJSZXNwb25zZRIhCgh0cmFuc2ZlchgBIAEoCzIPLnNwYXJrLlRyYW5zZmVyIoEBCiJRdWVyeVVudXNlZERlcG9zaXRBZGRyZXNzZXNSZXF1ZXN0EhsKE2lkZW50aXR5X3B1YmxpY19rZXkYASABKAwSHwoHbmV0d29yaxgCIAEoDjIOLnNwYXJrLk5ldHdvcmsSDQoFbGltaXQYAyABKAMSDgoGb2Zmc2V0GAQgASgDIt0BCiJRdWVyeVN0YXRpY0RlcG9zaXRBZGRyZXNzZXNSZXF1ZXN0EhsKE2lkZW50aXR5X3B1YmxpY19rZXkYASABKAwSHwoHbmV0d29yaxgCIAEoDjIOLnNwYXJrLk5ldHdvcmsSDQoFbGltaXQYBCABKAMSDgoGb2Zmc2V0GAUgASgDEhwKD2RlcG9zaXRfYWRkcmVzcxgGIAEoCUgAiAEBEigKDGhhc2hfdmFyaWFudBgHIAEoDjISLnNwYXJrLkhhc2hWYXJpYW50QhIKEF9kZXBvc2l0X2FkZHJlc3Mi9QEKGURlcG9zaXRBZGRyZXNzUXVlcnlSZXN1bHQSFwoPZGVwb3NpdF9hZGRyZXNzGAEgASgJEh8KF3VzZXJfc2lnbmluZ19wdWJsaWNfa2V5GAIgASgMEhwKFHZlcmlmeWluZ19wdWJsaWNfa2V5GAMgASgMEh4KB2xlYWZfaWQYBCABKAlCCPpCBXIDsAEBSACIAQESPAoTcHJvb2Zfb2ZfcG9zc2Vzc2lvbhgFIAEoCzIaLnNwYXJrLkRlcG9zaXRBZGRyZXNzUHJvb2ZIAYgBAUIKCghfbGVhZl9pZEIWChRfcHJvb2Zfb2ZfcG9zc2Vzc2lvbiJyCiNRdWVyeVVudXNlZERlcG9zaXRBZGRyZXNzZXNSZXNwb25zZRI7ChFkZXBvc2l0X2FkZHJlc3NlcxgBIAMoCzIgLnNwYXJrLkRlcG9zaXRBZGRyZXNzUXVlcnlSZXN1bHQSDgoGb2Zmc2V0GAIgASgDImIKI1F1ZXJ5U3RhdGljRGVwb3NpdEFkZHJlc3Nlc1Jlc3BvbnNlEjsKEWRlcG9zaXRfYWRkcmVzc2VzGAEgAygLMiAuc3BhcmsuRGVwb3NpdEFkZHJlc3NRdWVyeVJlc3VsdCJTChNRdWVyeUJhbGFuY2VSZXF1ZXN0EhsKE2lkZW50aXR5X3B1YmxpY19rZXkYASABKAwSHwoHbmV0d29yaxgCIAEoDjIOLnNwYXJrLk5ldHdvcmsiogEKFFF1ZXJ5QmFsYW5jZVJlc3BvbnNlEg8KB2JhbGFuY2UYASABKAQSRAoNbm9kZV9iYWxhbmNlcxgCIAMoCzItLnNwYXJrLlF1ZXJ5QmFsYW5jZVJlc3BvbnNlLk5vZGVCYWxhbmNlc0VudHJ5GjMKEU5vZGVCYWxhbmNlc0VudHJ5EgsKA2tleRgBIAEoCRINCgV2YWx1ZRgCIAEoBDoCOAEikwEKDFNwYXJrQWRkcmVzcxIbChNpZGVudGl0eV9wdWJsaWNfa2V5GAEgASgMEjcKFHNwYXJrX2ludm9pY2VfZmllbGRzGAIgASgLMhkuc3BhcmsuU3BhcmtJbnZvaWNlRmllbGRzEh8KCXNpZ25hdHVyZRgDIAEoDEIH+kIEegJoQEgAiAEBQgwKCl9zaWduYXR1cmUi0AIKElNwYXJrSW52b2ljZUZpZWxkcxIPCgd2ZXJzaW9uGAEgASgNEhMKAmlkGAIgASgMQgf6QgR6AmgQEi4KDnRva2Vuc19wYXltZW50GAMgASgLMhQuc3BhcmsuVG9rZW5zUGF5bWVudEgAEioKDHNhdHNfcGF5bWVudBgEIAEoCzISLnNwYXJrLlNhdHNQYXltZW50SAASGgoEbWVtbxgFIAEoCUIH+kIEcgIoeEgBiAEBEicKEXNlbmRlcl9wdWJsaWNfa2V5GAYgASgMQgf6QgR6AmghSAKIAQESNAoLZXhwaXJ5X3RpbWUYByABKAsyGi5nb29nbGUucHJvdG9idWYuVGltZXN0YW1wSAOIAQFCDgoMcGF5bWVudF90eXBlQgcKBV9tZW1vQhQKEl9zZW5kZXJfcHVibGljX2tleUIOCgxfZXhwaXJ5X3RpbWUiLQoLU2F0c1BheW1lbnQSEwoGYW1vdW50GAEgASgESACIAQFCCQoHX2Ftb3VudCJ1Cg1Ub2tlbnNQYXltZW50EiYKEHRva2VuX2lkZW50aWZpZXIYASABKAxCB/pCBHoCaCBIAIgBARIcCgZhbW91bnQYAiABKAxCB/pCBHoCGBBIAYgBAUITChFfdG9rZW5faWRlbnRpZmllckIJCgdfYW1vdW50IsABCiZJbml0aWF0ZVN0YXRpY0RlcG9zaXRVdHhvUmVmdW5kUmVxdWVzdBIiCg1vbl9jaGFpbl91dHhvGAEgASgLMgsuc3BhcmsuVVRYTxIwChVyZWZ1bmRfdHhfc2lnbmluZ19qb2IYAyABKAsyES5zcGFyay5TaWduaW5nSm9iEhYKDnVzZXJfc2lnbmF0dXJlGAQgASgMEigKDGhhc2hfdmFyaWFudBgFIAEoDjISLnNwYXJrLkhhc2hWYXJpYW50IpwBCidJbml0aWF0ZVN0YXRpY0RlcG9zaXRVdHhvUmVmdW5kUmVzcG9uc2USNgoYcmVmdW5kX3R4X3NpZ25pbmdfcmVzdWx0GAEgASgLMhQuc3BhcmsuU2lnbmluZ1Jlc3VsdBI5Cg9kZXBvc2l0X2FkZHJlc3MYAiABKAsyIC5zcGFyay5EZXBvc2l0QWRkcmVzc1F1ZXJ5UmVzdWx0Ir4CChdJbml0aWF0ZVV0eG9Td2FwUmVxdWVzdBIiCg1vbl9jaGFpbl91dHhvGAEgASgLMgsuc3BhcmsuVVRYTxIwCgxyZXF1ZXN0X3R5cGUYAiABKA4yGi5zcGFyay5VdHhvU3dhcFJlcXVlc3RUeXBlEhwKEmNyZWRpdF9hbW91bnRfc2F0cxgDIAEoBEgAEhYKDG1heF9mZWVfc2F0cxgEIAEoBEgAEhUKDXNzcF9zaWduYXR1cmUYBSABKAwSFgoOdXNlcl9zaWduYXR1cmUYBiABKAwSLQoIdHJhbnNmZXIYByABKAsyGy5zcGFyay5TdGFydFRyYW5zZmVyUmVxdWVzdBIvChRzcGVuZF90eF9zaWduaW5nX2pvYhgIIAEoCzIRLnNwYXJrLlNpZ25pbmdKb2JCCAoGYW1vdW50Iq8BChhJbml0aWF0ZVV0eG9Td2FwUmVzcG9uc2USNQoXc3BlbmRfdHhfc2lnbmluZ19yZXN1bHQYASABKAsyFC5zcGFyay5TaWduaW5nUmVzdWx0EiEKCHRyYW5zZmVyGAIgASgLMg8uc3BhcmsuVHJhbnNmZXISOQoPZGVwb3NpdF9hZGRyZXNzGAMgASgLMiAuc3BhcmsuRGVwb3NpdEFkZHJlc3NRdWVyeVJlc3VsdCJnCgtFeGl0aW5nVHJlZRIPCgd0cmVlX2lkGAEgASgJEjoKF3VzZXJfc2lnbmluZ19jb21taXRtZW50GAIgASgLMhkuY29tbW9uLlNpZ25pbmdDb21taXRtZW50EgsKA3ZpbhgDIAEoDSJ3Ch9FeGl0U2luZ2xlTm9kZVRyZWVTaWduaW5nUmVzdWx0Eg8KB3RyZWVfaWQYASABKAkSLAoOc2lnbmluZ19yZXN1bHQYAiABKAsyFC5zcGFyay5TaWduaW5nUmVzdWx0EhUKDXZlcmlmeWluZ19rZXkYAyABKAwiPAoYQml0Y29pblRyYW5zYWN0aW9uT3V0cHV0Eg0KBXZhbHVlGAEgASgDEhEKCXBrX3NjcmlwdBgCIAEoDCK1AQoaRXhpdFNpbmdsZU5vZGVUcmVlc1JlcXVlc3QSIQoZb3duZXJfaWRlbnRpdHlfcHVibGljX2tleRgBIAEoDBIpCg1leGl0aW5nX3RyZWVzGAIgAygLMhIuc3BhcmsuRXhpdGluZ1RyZWUSDgoGcmF3X3R4GAMgASgMEjkKEHByZXZpb3VzX291dHB1dHMYBCADKAsyHy5zcGFyay5CaXRjb2luVHJhbnNhY3Rpb25PdXRwdXQiXgobRXhpdFNpbmdsZU5vZGVUcmVlc1Jlc3BvbnNlEj8KD3NpZ25pbmdfcmVzdWx0cxgBIAMoCzImLnNwYXJrLkV4aXRTaW5nbGVOb2RlVHJlZVNpZ25pbmdSZXN1bHQigQEKIlJlY292ZXJXYXRjaHRvd2VyRXhpdGVkTGVhZlJlcXVlc3QSDwoHbGVhZl9pZBgBIAEoCRIyChdyZWNvdmVyeV90eF9zaWduaW5nX2pvYhgCIAEoCzIRLnNwYXJrLlNpZ25pbmdKb2ISFgoOdXNlcl9zaWduYXR1cmUYAyABKAwidgojUmVjb3ZlcldhdGNodG93ZXJFeGl0ZWRMZWFmUmVzcG9uc2USOAoacmVjb3ZlcnlfdHhfc2lnbmluZ19yZXN1bHQYASABKAsyFC5zcGFyay5TaWduaW5nUmVzdWx0EhUKDXZlcmlmeWluZ19rZXkYAiABKAwiQgodUXVlcnlOb2Rlc0Rpc3RyaWJ1dGlvblJlcXVlc3QSIQoZb3duZXJfaWRlbnRpdHlfcHVibGljX2tleRgBIAEoDCKxAQoeUXVlcnlOb2Rlc0Rpc3RyaWJ1dGlvblJlc3BvbnNlElYKEW5vZGVfZGlzdHJpYnV0aW9uGAEgAygLMjsuc3BhcmsuUXVlcnlOb2Rlc0Rpc3RyaWJ1dGlvblJlc3BvbnNlLk5vZGVEaXN0cmlidXRpb25FbnRyeRo3ChVOb2RlRGlzdHJpYnV0aW9uRW50cnkSCwoDa2V5GAEgASgEEg0KBXZhbHVlGAIgASgEOgI4ASJrChhRdWVyeU5vZGVzQnlWYWx1ZVJlcXVlc3QSIQoZb3duZXJfaWRlbnRpdHlfcHVibGljX2tleRgBIAEoDBINCgV2YWx1ZRgCIAEoAxIOCgZvZmZzZXQYAyABKAMSDQoFbGltaXQYBCABKAMipgEKGVF1ZXJ5Tm9kZXNCeVZhbHVlUmVzcG9uc2USOgoFbm9kZXMYASADKAsyKy5zcGFyay5RdWVyeU5vZGVzQnlWYWx1ZVJlc3BvbnNlLk5vZGVzRW50cnkSDgoGb2Zmc2V0GAIgASgDGj0KCk5vZGVzRW50cnkSCwoDa2V5GAEgASgJEh4KBXZhbHVlGAIgASgLMg8uc3BhcmsuVHJlZU5vZGU6AjgBIoUBChlHZXRVdHhvc0ZvckFkZHJlc3NSZXF1ZXN0Eg8KB2FkZHJlc3MYASABKAkSDgoGb2Zmc2V0GAIgASgEEg0KBWxpbWl0GAMgASgEEh8KB25ldHdvcmsYBCABKA4yDi5zcGFyay5OZXR3b3JrEhcKD2V4Y2x1ZGVfY2xhaW1lZBgFIAEoCCJIChpHZXRVdHhvc0ZvckFkZHJlc3NSZXNwb25zZRIaCgV1dHhvcxgBIAMoCzILLnNwYXJrLlVUWE8SDgoGb2Zmc2V0GAIgASgEIsEBChpHZXRVdHhvc0ZvcklkZW50aXR5UmVxdWVzdBIkChNpZGVudGl0eV9wdWJsaWNfa2V5GAEgASgMQgf6QgR6AmghEikKB25ldHdvcmsYAiABKA4yDi5zcGFyay5OZXR3b3JrQgj6QgWCAQIgABIXCg9leGNsdWRlX2NsYWltZWQYAyABKAgSIAoEcGFnZRgEIAEoCzISLnNwYXJrLlBhZ2VSZXF1ZXN0EhcKD2luY2x1ZGVfcGVuZGluZxgFIAEoCCJlChtHZXRVdHhvc0ZvcklkZW50aXR5UmVzcG9uc2USIwoFdXR4b3MYASADKAsyFC5zcGFyay5BZGRyZXNzZWRVdHhvEiEKBHBhZ2UYAiABKAsyEy5zcGFyay5QYWdlUmVzcG9uc2UiSwoZUXVlcnlTcGFya0ludm9pY2VzUmVxdWVzdBINCgVsaW1pdBgBIAEoAxIOCgZvZmZzZXQYAiABKAMSDwoHaW52b2ljZRgDIAMoCSJeChpRdWVyeVNwYXJrSW52b2ljZXNSZXNwb25zZRIOCgZvZmZzZXQYASABKAMSMAoQaW52b2ljZV9zdGF0dXNlcxgCIAMoCzIWLnNwYXJrLkludm9pY2VSZXNwb25zZSK3AQoPSW52b2ljZVJlc3BvbnNlEg8KB2ludm9pY2UYASABKAkSJAoGc3RhdHVzGAIgASgOMhQuc3BhcmsuSW52b2ljZVN0YXR1cxIsCg1zYXRzX3RyYW5zZmVyGAMgASgLMhMuc3BhcmsuU2F0c1RyYW5zZmVySAASLgoOdG9rZW5fdHJhbnNmZXIYBCABKAsyFC5zcGFyay5Ub2tlblRyYW5zZmVySABCDwoNdHJhbnNmZXJfdHlwZSIsCgxTYXRzVHJhbnNmZXISHAoLdHJhbnNmZXJfaWQYASABKAxCB/pCBHoCaBAiPgoNVG9rZW5UcmFuc2ZlchItChxmaW5hbF90b2tlbl90cmFuc2FjdGlvbl9oYXNoGAEgASgMQgf6QgR6AmggIpABCiJJbml0aWF0ZVN3YXBQcmltYXJ5VHJhbnNmZXJSZXF1ZXN0Ei0KCHRyYW5zZmVyGAEgASgLMhsuc3BhcmsuU3RhcnRUcmFuc2ZlclJlcXVlc3QSOwoTYWRhcHRvcl9wdWJsaWNfa2V5cxgCIAEoCzIeLnNwYXJrLkFkYXB0b3JQdWJsaWNLZXlQYWNrYWdlIoMBCiNJbml0aWF0ZVN3YXBQcmltYXJ5VHJhbnNmZXJSZXNwb25zZRIhCgh0cmFuc2ZlchgBIAEoCzIPLnNwYXJrLlRyYW5zZmVyEjkKD3NpZ25pbmdfcmVzdWx0cxgCIAMoCzIgLnNwYXJrLkxlYWZSZWZ1bmRUeFNpZ25pbmdSZXN1bHQihQEKF0FkYXB0b3JQdWJsaWNLZXlQYWNrYWdlEhoKEmFkYXB0b3JfcHVibGljX2tleRgBIAEoDBIhChlkaXJlY3RfYWRhcHRvcl9wdWJsaWNfa2V5GAIgASgMEisKI2RpcmVjdF9mcm9tX2NwZnBfYWRhcHRvcl9wdWJsaWNfa2V5GAMgASgMIqUBCg1XYWxsZXRTZXR0aW5nEioKGW93bmVyX2lkZW50aXR5X3B1YmxpY19rZXkYASABKAxCB/pCBHoCaCESFwoPcHJpdmF0ZV9lbmFibGVkGAIgASgIEjAKGm1hc3Rlcl9pZGVudGl0eV9wdWJsaWNfa2V5GAMgASgMQgf6QgR6AmghSACIAQFCHQobX21hc3Rlcl9pZGVudGl0eV9wdWJsaWNfa2V5IsIBChpVcGRhdGVXYWxsZXRTZXR0aW5nUmVxdWVzdBIcCg9wcml2YXRlX2VuYWJsZWQYASABKAhIAYgBARIoCh5zZXRfbWFzdGVyX2lkZW50aXR5X3B1YmxpY19rZXkYAiABKAxIABIqCiBjbGVhcl9tYXN0ZXJfaWRlbnRpdHlfcHVibGljX2tleRgDIAEoCEgAQhwKGm1hc3Rlcl9pZGVudGl0eV9wdWJsaWNfa2V5QhIKEF9wcml2YXRlX2VuYWJsZWQiSwobVXBkYXRlV2FsbGV0U2V0dGluZ1Jlc3BvbnNlEiwKDndhbGxldF9zZXR0aW5nGAEgASgLMhQuc3BhcmsuV2FsbGV0U2V0dGluZyIbChlRdWVyeVdhbGxldFNldHRpbmdSZXF1ZXN0IkoKGlF1ZXJ5V2FsbGV0U2V0dGluZ1Jlc3BvbnNlEiwKDndhbGxldF9zZXR0aW5nGAEgASgLMhQuc3BhcmsuV2FsbGV0U2V0dGluZyKVBAoPRGVsZWdhdGlvbkdyYW50EhoKCGdyYW50X2lkGAEgASgJQgj6QgVyA7ABARIqChlvd25lcl9pZGVudGl0eV9wdWJsaWNfa2V5GAIgASgMQgf6QgR6AmghEjUKCHNwZW5kZXJzGAMgAygLMhguc3BhcmsuRGVsZWdhdGlvblNwZW5kZXJCCfpCBpIBAxCAAhI5CgtleHBpcnlfdGltZRgEIAEoCzIaLmdvb2dsZS5wcm90b2J1Zi5UaW1lc3RhbXBCCPpCBbIBAggBEhYKDnNjb3BlX3RyYW5zZmVyGAUgASgIEhMKC3Njb3BlX3JlbmV3GAYgASgIEhMKC3Njb3BlX2NsYWltGAcgASgIEhUKDWZlZV9mbGF0X3NhdHMYCCABKAQSNwohZmVlX2NvbGxlY3Rvcl9pZGVudGl0eV9wdWJsaWNfa2V5GAkgASgMQgf6QgR6AmghSACIAQESGAoHdmVyc2lvbhgKIAEoBEIH+kIEMgIoARIiCg9vd25lcl9zaWduYXR1cmUYCyABKAxCCfpCBnoEEEAYSRInCgZzdGF0dXMYDCABKA4yFy5zcGFyay5EZWxlZ2F0aW9uU3RhdHVzEikKB25ldHdvcmsYDSABKA4yDi5zcGFyay5OZXR3b3JrQgj6QgWCAQIgAEIkCiJfZmVlX2NvbGxlY3Rvcl9pZGVudGl0eV9wdWJsaWNfa2V5IvQBChFEZWxlZ2F0aW9uU3BlbmRlchIsChtzcGVuZGVyX2lkZW50aXR5X3B1YmxpY19rZXkYASABKAxCB/pCBHoCaCESFwoPcGVyX3R4X2NhcF9zYXRzGAIgASgEEhoKEnJvbGxpbmdfbGltaXRfc2F0cxgDIAEoBBIeChZyb2xsaW5nX3dpbmRvd19zZWNvbmRzGAQgASgEEicKBnN0YXR1cxgFIAEoDjIXLnNwYXJrLkRlbGVnYXRpb25TdGF0dXMSGAoQcGVyX3R4X3VubGltaXRlZBgGIAEoCBIZChFyb2xsaW5nX3VubGltaXRlZBgHIAEoCCJPChxDcmVhdGVEZWxlZ2F0aW9uR3JhbnRSZXF1ZXN0Ei8KBWdyYW50GAEgASgLMhYuc3BhcmsuRGVsZWdhdGlvbkdyYW50Qgj6QgWKAQIQASJGCh1DcmVhdGVEZWxlZ2F0aW9uR3JhbnRSZXNwb25zZRIlCgVncmFudBgBIAEoCzIWLnNwYXJrLkRlbGVnYXRpb25HcmFudCKkAQocUmV2b2tlRGVsZWdhdGlvbkdyYW50UmVxdWVzdBIaCghncmFudF9pZBgBIAEoCUII+kIFcgOwAQESKgoZb3duZXJfaWRlbnRpdHlfcHVibGljX2tleRgCIAEoDEIH+kIEegJoIRIYCgd2ZXJzaW9uGAMgASgEQgf6QgQyAigBEiIKD293bmVyX3NpZ25hdHVyZRgEIAEoDEIJ+kIGegQQQBhJIkYKHVJldm9rZURlbGVnYXRpb25HcmFudFJlc3BvbnNlEiUKBWdyYW50GAEgASgLMhYuc3BhcmsuRGVsZWdhdGlvbkdyYW50IqwBChtBZGREZWxlZ2F0aW9uU3BlbmRlclJlcXVlc3QSGgoIZ3JhbnRfaWQYASABKAlCCPpCBXIDsAEBEjMKB3NwZW5kZXIYAiABKAsyGC5zcGFyay5EZWxlZ2F0aW9uU3BlbmRlckII+kIFigECEAESGAoHdmVyc2lvbhgDIAEoBEIH+kIEMgIoARIiCg9vd25lcl9zaWduYXR1cmUYBCABKAxCCfpCBnoEEEAYSSJFChxBZGREZWxlZ2F0aW9uU3BlbmRlclJlc3BvbnNlEiUKBWdyYW50GAEgASgLMhYuc3BhcmsuRGVsZWdhdGlvbkdyYW50IqgBCh5SZXZva2VEZWxlZ2F0aW9uU3BlbmRlclJlcXVlc3QSGgoIZ3JhbnRfaWQYASABKAlCCPpCBXIDsAEBEiwKG3NwZW5kZXJfaWRlbnRpdHlfcHVibGljX2tleRgCIAEoDEIH+kIEegJoIRIYCgd2ZXJzaW9uGAMgASgEQgf6QgQyAigBEiIKD293bmVyX3NpZ25hdHVyZRgEIAEoDEIJ+kIGegQQQBhJIkgKH1Jldm9rZURlbGVnYXRpb25TcGVuZGVyUmVzcG9uc2USJQoFZ3JhbnQYASABKAsyFi5zcGFyay5EZWxlZ2F0aW9uR3JhbnQihwEKHFF1ZXJ5RGVsZWdhdGlvbkdyYW50c1JlcXVlc3QSLAoZb3duZXJfaWRlbnRpdHlfcHVibGljX2tleRgBIAEoDEIH+kIEegJoIUgAEi8KHGRlbGVnYXRlX2lkZW50aXR5X3B1YmxpY19rZXkYAiABKAxCB/pCBHoCaCFIAEIICgZmaWx0ZXIiygEKE0RlbGVnYXRpb25HcmFudEluZm8SJQoFZ3JhbnQYASABKAsyFi5zcGFyay5EZWxlZ2F0aW9uR3JhbnQSUQoVc3BlbnRfc2F0c19ieV9zcGVuZGVyGAIgAygLMjIuc3BhcmsuRGVsZWdhdGlvbkdyYW50SW5mby5TcGVudFNhdHNCeVNwZW5kZXJFbnRyeRo5ChdTcGVudFNhdHNCeVNwZW5kZXJFbnRyeRILCgNrZXkYASABKAkSDQoFdmFsdWUYAiABKAQ6AjgBIksKHVF1ZXJ5RGVsZWdhdGlvbkdyYW50c1Jlc3BvbnNlEioKBmdyYW50cxgBIAMoCzIaLnNwYXJrLkRlbGVnYXRpb25HcmFudEluZm8iYwoYTGVhZkRlY29tcG9zaXRpb25JbnN0YWxsEhkKB2xlYWZfaWQYASABKAlCCPpCBXIDsAEBEiwKG2RlbGVnYXRlX3NpZ25pbmdfcHVibGljX2tleRgCIAEoDEIH+kIEegJoISLcAgogSW5zdGFsbExlYWZEZWNvbXBvc2l0aW9uc1JlcXVlc3QSGgoIZ3JhbnRfaWQYASABKAlCCPpCBXIDsAEBEioKGW93bmVyX2lkZW50aXR5X3B1YmxpY19rZXkYAiABKAxCB/pCBHoCaCESOwoIaW5zdGFsbHMYAyADKAsyHy5zcGFyay5MZWFmRGVjb21wb3NpdGlvbkluc3RhbGxCCPpCBZIBAggBElcKEWtleV90d2Vha19wYWNrYWdlGAQgAygLMjwuc3BhcmsuSW5zdGFsbExlYWZEZWNvbXBvc2l0aW9uc1JlcXVlc3QuS2V5VHdlYWtQYWNrYWdlRW50cnkSIgoPb3duZXJfc2lnbmF0dXJlGAUgASgMQgn6QgZ6BBBAGEkaNgoUS2V5VHdlYWtQYWNrYWdlRW50cnkSCwoDa2V5GAEgASgJEg0KBXZhbHVlGAIgASgMOgI4ASJSCiBJbnN0YWxsTGVhZkRlY29tcG9zaXRpb25Qcm9ncmVzcxIbChNvcGVyYXRvcl9pZGVudGlmaWVyGAEgASgJEhEKCWluc3RhbGxlZBgCIAEoCCJeCiFJbnN0YWxsTGVhZkRlY29tcG9zaXRpb25zUmVzcG9uc2USOQoIcHJvZ3Jlc3MYASADKAsyJy5zcGFyay5JbnN0YWxsTGVhZkRlY29tcG9zaXRpb25Qcm9ncmVzcypNCgdOZXR3b3JrEg8KC1VOU1BFQ0lGSUVEEAASCwoHTUFJTk5FVBABEgsKB1JFR1RFU1QQAhILCgdURVNUTkVUEAMSCgoGU0lHTkVUEAQqIwoJRGlyZWN0aW9uEggKBE5FWFQQABIMCghQUkVWSU9VUxABKvwDCg5UcmFuc2ZlclN0YXR1cxIkCiBUUkFOU0ZFUl9TVEFUVVNfU0VOREVSX0lOSVRJQVRFRBAAEiwKKFRSQU5TRkVSX1NUQVRVU19TRU5ERVJfS0VZX1RXRUFLX1BFTkRJTkcQARImCiJUUkFOU0ZFUl9TVEFUVVNfU0VOREVSX0tFWV9UV0VBS0VEEAISKAokVFJBTlNGRVJfU1RBVFVTX1JFQ0VJVkVSX0tFWV9UV0VBS0VEEAMSKgomVFJBTlNGRVJfU1RBVFVTX1JFQ0VJVkVSX1JFRlVORF9TSUdORUQQBBIdChlUUkFOU0ZFUl9TVEFUVVNfQ09NUExFVEVEEAUSGwoXVFJBTlNGRVJfU1RBVFVTX0VYUElSRUQQBhIcChhUUkFOU0ZFUl9TVEFUVVNfUkVUVVJORUQQBxIwCixUUkFOU0ZFUl9TVEFUVVNfU0VOREVSX0lOSVRJQVRFRF9DT09SRElOQVRPUhAIEi0KKVRSQU5TRkVSX1NUQVRVU19SRUNFSVZFUl9LRVlfVFdFQUtfTE9DS0VEEAkSLgoqVFJBTlNGRVJfU1RBVFVTX1JFQ0VJVkVSX0tFWV9UV0VBS19BUFBMSUVEEAoSLQopVFJBTlNGRVJfU1RBVFVTX0FQUExZSU5HX1NFTkRFUl9LRVlfVFdFQUsQCyrxAgoWVHJhbnNmZXJSZWNlaXZlclN0YXR1cxImCiJUUkFOU0ZFUl9SRUNFSVZFUl9TVEFUVVNfSU5JVElBVEVEEAASKgomVFJBTlNGRVJfUkVDRUlWRVJfU1RBVFVTX0NMQUlNX1BFTkRJTkcQARIoCiRUUkFOU0ZFUl9SRUNFSVZFUl9TVEFUVVNfS0VZX1RXRUFLRUQQAhItCilUUkFOU0ZFUl9SRUNFSVZFUl9TVEFUVVNfS0VZX1RXRUFLX0xPQ0tFRBADEi4KKlRSQU5TRkVSX1JFQ0VJVkVSX1NUQVRVU19LRVlfVFdFQUtfQVBQTElFRBAEEioKJlRSQU5TRkVSX1JFQ0VJVkVSX1NUQVRVU19SRUZVTkRfU0lHTkVEEAUSJgoiVFJBTlNGRVJfUkVDRUlWRVJfU1RBVFVTX0NPTVBMRVRFRBAGEiYKIlRSQU5TRkVSX1JFQ0VJVkVSX1NUQVRVU19DQU5DRUxMRUQQByqaAQoMVHJhbnNmZXJUeXBlEhEKDVBSRUlNQUdFX1NXQVAQABIUChBDT09QRVJBVElWRV9FWElUEAESDAoIVFJBTlNGRVIQAhINCglVVFhPX1NXQVAQAxIICgRTV0FQEB4SEAoMQ09VTlRFUl9TV0FQECgSEwoPUFJJTUFSWV9TV0FQX1YzEAQSEwoPQ09VTlRFUl9TV0FQX1YzEAUqJgoFT3JkZXISDgoKREVTQ0VORElORxAAEg0KCUFTQ0VORElORxABKnMKCUZlZVNvdXJjZRIaChZGRUVfU09VUkNFX1VOU1BFQ0lGSUVEEAASHQoZRkVFX1NPVVJDRV9QQVJUTkVSX01BUktVUBABEhMKD0ZFRV9TT1VSQ0VfQkFTRRACEhYKEkZFRV9TT1VSQ0VfTkVUV09SSxADKmIKB0ZlZVJvbGUSGAoURkVFX1JPTEVfVU5TUEVDSUZJRUQQABIWChJGRUVfUk9MRV9BRkZJTElBVEUQARIUChBGRUVfUk9MRV9QQVJUTkVSEAISDwoLRkVFX1JPTEVfTFMQAyqcAQoVUHJlaW1hZ2VSZXF1ZXN0U3RhdHVzEjAKLFBSRUlNQUdFX1JFUVVFU1RfU1RBVFVTX1dBSVRJTkdfRk9SX1BSRUlNQUdFEAASKwonUFJFSU1BR0VfUkVRVUVTVF9TVEFUVVNfUFJFSU1BR0VfU0hBUkVEEAESJAogUFJFSU1BR0VfUkVRVUVTVF9TVEFUVVNfUkVUVVJORUQQAiqKAQoTUHJlaW1hZ2VSZXF1ZXN0Um9sZRIiCh5QUkVJTUFHRV9SRVFVRVNUX1JPTEVfUkVDRUlWRVIQABIgChxQUkVJTUFHRV9SRVFVRVNUX1JPTEVfU0VOREVSEAESLQopUFJFSU1BR0VfUkVRVUVTVF9ST0xFX1JFQ0VJVkVSX0FORF9TRU5ERVIQAipFChNVdHhvU3dhcFJlcXVlc3RUeXBlEgkKBUZpeGVkEAASCgoGTWF4RmVlEAESCgoGUmVmdW5kEAISCwoHSW5zdGFudBADKpABCg5VdHhvU3dhcFN0YXR1cxIgChxVVFhPX1NXQVBfU1RBVFVTX1VOU1BFQ0lGSUVEEAASHAoYVVRYT19TV0FQX1NUQVRVU19DUkVBVEVEEAESHgoaVVRYT19TV0FQX1NUQVRVU19DT01QTEVURUQQAhIeChpVVFhPX1NXQVBfU1RBVFVTX0NBTkNFTExFRBADKkAKC0hhc2hWYXJpYW50EhwKGEhBU0hfVkFSSUFOVF9VTlNQRUNJRklFRBAAEhMKD0hBU0hfVkFSSUFOVF9WMhABKrEBCg1JbnZvaWNlU3RhdHVzEg0KCU5PVF9GT1VORBAAEgsKB1BFTkRJTkcQARINCglGSU5BTElaRUQQAhIMCghSRVRVUk5FRBAEEiAKHE1JU01BVENIRURfSU5WT0lDRV9GSU5BTElaRUQQBRIeChpNSVNNQVRDSEVEX0lOVk9JQ0VfUEVORElORxAGEh8KG01JU01BVENIRURfSU5WT0lDRV9SRVRVUk5FRBAHIgQIAxADKsQECg5UcmVlTm9kZVN0YXR1cxIdChlUUkVFX05PREVfU1RBVFVTX0NSRUFUSU5HEAASHgoaVFJFRV9OT0RFX1NUQVRVU19BVkFJTEFCTEUQARIlCiFUUkVFX05PREVfU1RBVFVTX0ZST1pFTl9CWV9JU1NVRVIQAhIkCiBUUkVFX05PREVfU1RBVFVTX1RSQU5TRkVSX0xPQ0tFRBADEiEKHVRSRUVfTk9ERV9TVEFUVVNfU1BMSVRfTE9DS0VEEAQSHQoZVFJFRV9OT0RFX1NUQVRVU19TUExJVFRFRBAFEh8KG1RSRUVfTk9ERV9TVEFUVVNfQUdHUkVHQVRFRBAGEh0KGVRSRUVfTk9ERV9TVEFUVVNfT05fQ0hBSU4QBxIjCh9UUkVFX05PREVfU1RBVFVTX0FHR1JFR0FURV9MT0NLEAgSGwoXVFJFRV9OT0RFX1NUQVRVU19FWElURUQQCRIhCh1UUkVFX05PREVfU1RBVFVTX1JFTkVXX0xPQ0tFRBAKEiAKHFRSRUVfTk9ERV9TVEFUVVNfVU5BVkFJTEFCTEUQCxIiCh5UUkVFX05PREVfU1RBVFVTX1BBUkVOVF9FWElURUQQDBIhCh1UUkVFX05PREVfU1RBVFVTX0NPTlNPTElEQVRFRBANEiYKIlRSRUVfTk9ERV9TVEFUVVNfV0FUQ0hUT1dFUl9FWElURUQQDhIuCipUUkVFX05PREVfU1RBVFVTX1dBVENIVE9XRVJfRVhJVF9SRUNPVkVSRUQQDypyChBEZWxlZ2F0aW9uU3RhdHVzEiEKHURFTEVHQVRJT05fU1RBVFVTX1VOU1BFQ0lGSUVEEAASHAoYREVMRUdBVElPTl9TVEFUVVNfQUNUSVZFEAESHQoZREVMRUdBVElPTl9TVEFUVVNfUkVWT0tFRBACMr8lCgxTcGFya1NlcnZpY2USaQoYZ2VuZXJhdGVfZGVwb3NpdF9hZGRyZXNzEiQuc3BhcmsuR2VuZXJhdGVEZXBvc2l0QWRkcmVzc1JlcXVlc3QaJS5zcGFyay5HZW5lcmF0ZURlcG9zaXRBZGRyZXNzUmVzcG9uc2UiABJ8Ch9nZW5lcmF0ZV9zdGF0aWNfZGVwb3NpdF9hZGRyZXNzEiouc3BhcmsuR2VuZXJhdGVTdGF0aWNEZXBvc2l0QWRkcmVzc1JlcXVlc3QaKy5zcGFyay5HZW5lcmF0ZVN0YXRpY0RlcG9zaXRBZGRyZXNzUmVzcG9uc2UiABJ2Ch1yb3RhdGVfc3RhdGljX2RlcG9zaXRfYWRkcmVzcxIoLnNwYXJrLlJvdGF0ZVN0YXRpY0RlcG9zaXRBZGRyZXNzUmVxdWVzdBopLnNwYXJrLlJvdGF0ZVN0YXRpY0RlcG9zaXRBZGRyZXNzUmVzcG9uc2UiABJwChtzdGFydF9kZXBvc2l0X3RyZWVfY3JlYXRpb24SJi5zcGFyay5TdGFydERlcG9zaXRUcmVlQ3JlYXRpb25SZXF1ZXN0Gicuc3BhcmsuU3RhcnREZXBvc2l0VHJlZUNyZWF0aW9uUmVzcG9uc2UiABJ5Ch5maW5hbGl6ZV9kZXBvc2l0X3RyZWVfY3JlYXRpb24SKS5zcGFyay5GaW5hbGl6ZURlcG9zaXRUcmVlQ3JlYXRpb25SZXF1ZXN0Giouc3BhcmsuRmluYWxpemVEZXBvc2l0VHJlZUNyZWF0aW9uUmVzcG9uc2UiABJ/CidmaW5hbGl6ZV90cmFuc2Zlcl93aXRoX3RyYW5zZmVyX3BhY2thZ2USMS5zcGFyay5GaW5hbGl6ZVRyYW5zZmVyV2l0aFRyYW5zZmVyUGFja2FnZVJlcXVlc3QaHy5zcGFyay5GaW5hbGl6ZVRyYW5zZmVyUmVzcG9uc2UiABJRChdxdWVyeV9wZW5kaW5nX3RyYW5zZmVycxIVLnNwYXJrLlRyYW5zZmVyRmlsdGVyGh0uc3BhcmsuUXVlcnlUcmFuc2ZlcnNSZXNwb25zZSIAEk0KE3F1ZXJ5X2FsbF90cmFuc2ZlcnMSFS5zcGFyay5UcmFuc2ZlckZpbHRlchodLnNwYXJrLlF1ZXJ5VHJhbnNmZXJzUmVzcG9uc2UiABJaChVxdWVyeV90cmFuc2ZlcnNfYnlfaWQSIC5zcGFyay5RdWVyeVRyYW5zZmVyc0J5SWRSZXF1ZXN0Gh0uc3BhcmsuUXVlcnlUcmFuc2ZlcnNSZXNwb25zZSIAElsKGWNsYWltX3RyYW5zZmVyX3R3ZWFrX2tleXMSJC5zcGFyay5DbGFpbVRyYW5zZmVyVHdlYWtLZXlzUmVxdWVzdBoWLmdvb2dsZS5wcm90b2J1Zi5FbXB0eSIAElIKFHN0b3JlX3ByZWltYWdlX3NoYXJlEiAuc3BhcmsuU3RvcmVQcmVpbWFnZVNoYXJlUmVxdWVzdBoWLmdvb2dsZS5wcm90b2J1Zi5FbXB0eSIAElcKF3N0b3JlX3ByZWltYWdlX3NoYXJlX3YyEiIuc3BhcmsuU3RvcmVQcmVpbWFnZVNoYXJlVjJSZXF1ZXN0GhYuZ29vZ2xlLnByb3RvYnVmLkVtcHR5IgASZgoXZ2V0X3NpZ25pbmdfY29tbWl0bWVudHMSIy5zcGFyay5HZXRTaWduaW5nQ29tbWl0bWVudHNSZXF1ZXN0GiQuc3BhcmsuR2V0U2lnbmluZ0NvbW1pdG1lbnRzUmVzcG9uc2UiABJTChBwcm92aWRlX3ByZWltYWdlEh0uc3BhcmsuUHJvdmlkZVByZWltYWdlUmVxdWVzdBoeLnNwYXJrLlByb3ZpZGVQcmVpbWFnZVJlc3BvbnNlIgASTQoOcXVlcnlfcHJlaW1hZ2USGy5zcGFyay5RdWVyeVByZWltYWdlUmVxdWVzdBocLnNwYXJrLlF1ZXJ5UHJlaW1hZ2VSZXNwb25zZSIAEkEKCnF1ZXJ5X2h0bGMSFy5zcGFyay5RdWVyeUh0bGNSZXF1ZXN0Ghguc3BhcmsuUXVlcnlIdGxjUmVzcG9uc2UiABJBCgpyZW5ld19sZWFmEhcuc3BhcmsuUmVuZXdMZWFmUmVxdWVzdBoYLnNwYXJrLlJlbmV3TGVhZlJlc3BvbnNlIgASXAoZZ2V0X3NpZ25pbmdfb3BlcmF0b3JfbGlzdBIWLmdvb2dsZS5wcm90b2J1Zi5FbXB0eRolLnNwYXJrLkdldFNpZ25pbmdPcGVyYXRvckxpc3RSZXNwb25zZSIAEkQKC3F1ZXJ5X25vZGVzEhguc3BhcmsuUXVlcnlOb2Rlc1JlcXVlc3QaGS5zcGFyay5RdWVyeU5vZGVzUmVzcG9uc2UiABJKCg1xdWVyeV9iYWxhbmNlEhouc3BhcmsuUXVlcnlCYWxhbmNlUmVxdWVzdBobLnNwYXJrLlF1ZXJ5QmFsYW5jZVJlc3BvbnNlIgASeQoecXVlcnlfdW51c2VkX2RlcG9zaXRfYWRkcmVzc2VzEikuc3BhcmsuUXVlcnlVbnVzZWREZXBvc2l0QWRkcmVzc2VzUmVxdWVzdBoqLnNwYXJrLlF1ZXJ5VW51c2VkRGVwb3NpdEFkZHJlc3Nlc1Jlc3BvbnNlIgASeQoecXVlcnlfc3RhdGljX2RlcG9zaXRfYWRkcmVzc2VzEikuc3BhcmsuUXVlcnlTdGF0aWNEZXBvc2l0QWRkcmVzc2VzUmVxdWVzdBoqLnNwYXJrLlF1ZXJ5U3RhdGljRGVwb3NpdEFkZHJlc3Nlc1Jlc3BvbnNlIgASXAoTc3Vic2NyaWJlX3RvX2V2ZW50cxIfLnNwYXJrLlN1YnNjcmliZVRvRXZlbnRzUmVxdWVzdBogLnNwYXJrLlN1YnNjcmliZVRvRXZlbnRzUmVzcG9uc2UiADABEoYBCiNpbml0aWF0ZV9zdGF0aWNfZGVwb3NpdF91dHhvX3JlZnVuZBItLnNwYXJrLkluaXRpYXRlU3RhdGljRGVwb3NpdFV0eG9SZWZ1bmRSZXF1ZXN0Gi4uc3BhcmsuSW5pdGlhdGVTdGF0aWNEZXBvc2l0VXR4b1JlZnVuZFJlc3BvbnNlIgASYQoWZXhpdF9zaW5nbGVfbm9kZV90cmVlcxIhLnNwYXJrLkV4aXRTaW5nbGVOb2RlVHJlZXNSZXF1ZXN0GiIuc3BhcmsuRXhpdFNpbmdsZU5vZGVUcmVlc1Jlc3BvbnNlIgASeQoecmVjb3Zlcl93YXRjaHRvd2VyX2V4aXRlZF9sZWFmEikuc3BhcmsuUmVjb3ZlcldhdGNodG93ZXJFeGl0ZWRMZWFmUmVxdWVzdBoqLnNwYXJrLlJlY292ZXJXYXRjaHRvd2VyRXhpdGVkTGVhZlJlc3BvbnNlIgASVgoTY29vcGVyYXRpdmVfZXhpdF92MhIdLnNwYXJrLkNvb3BlcmF0aXZlRXhpdFJlcXVlc3QaHi5zcGFyay5Db29wZXJhdGl2ZUV4aXRSZXNwb25zZSIAEnMKHmNsYWltX3RyYW5zZmVyX3NpZ25fcmVmdW5kc192MhImLnNwYXJrLkNsYWltVHJhbnNmZXJTaWduUmVmdW5kc1JlcXVlc3QaJy5zcGFyay5DbGFpbVRyYW5zZmVyU2lnblJlZnVuZHNSZXNwb25zZSIAEmwKG2ZpbmFsaXplX25vZGVfc2lnbmF0dXJlc192MhIkLnNwYXJrLkZpbmFsaXplTm9kZVNpZ25hdHVyZXNSZXF1ZXN0GiUuc3BhcmsuRmluYWxpemVOb2RlU2lnbmF0dXJlc1Jlc3BvbnNlIgASZgoZaW5pdGlhdGVfcHJlaW1hZ2Vfc3dhcF92MhIiLnNwYXJrLkluaXRpYXRlUHJlaW1hZ2VTd2FwUmVxdWVzdBojLnNwYXJrLkluaXRpYXRlUHJlaW1hZ2VTd2FwUmVzcG9uc2UiABJmChlpbml0aWF0ZV9wcmVpbWFnZV9zd2FwX3YzEiIuc3BhcmsuSW5pdGlhdGVQcmVpbWFnZVN3YXBSZXF1ZXN0GiMuc3BhcmsuSW5pdGlhdGVQcmVpbWFnZVN3YXBSZXNwb25zZSIAEmgKGWluaXRpYXRlX3ByZWltYWdlX3N3YXBfdjQSJC5zcGFyay5Jbml0aWF0ZVByZWltYWdlU3dhcFY0UmVxdWVzdBojLnNwYXJrLkluaXRpYXRlUHJlaW1hZ2VTd2FwUmVzcG9uc2UiABJQChFzdGFydF90cmFuc2Zlcl92MhIbLnNwYXJrLlN0YXJ0VHJhbnNmZXJSZXF1ZXN0Ghwuc3BhcmsuU3RhcnRUcmFuc2ZlclJlc3BvbnNlIgASUgoRc3RhcnRfdHJhbnNmZXJfdjMSHS5zcGFyay5TdGFydFRyYW5zZmVyVjNSZXF1ZXN0Ghwuc3BhcmsuU3RhcnRUcmFuc2ZlclJlc3BvbnNlIgASVAoSc3RhcnRfdHJhbnNmZXJfbXBjEh4uc3BhcmsuU3RhcnRUcmFuc2Zlck1wY1JlcXVlc3QaHC5zcGFyay5TdGFydFRyYW5zZmVyUmVzcG9uc2UiABJNCg5jbGFpbV90cmFuc2ZlchIbLnNwYXJrLkNsYWltVHJhbnNmZXJSZXF1ZXN0Ghwuc3BhcmsuQ2xhaW1UcmFuc2ZlclJlc3BvbnNlIgASXgoVZ2V0X3V0eG9zX2Zvcl9hZGRyZXNzEiAuc3BhcmsuR2V0VXR4b3NGb3JBZGRyZXNzUmVxdWVzdBohLnNwYXJrLkdldFV0eG9zRm9yQWRkcmVzc1Jlc3BvbnNlIgASYQoWZ2V0X3V0eG9zX2Zvcl9pZGVudGl0eRIhLnNwYXJrLkdldFV0eG9zRm9ySWRlbnRpdHlSZXF1ZXN0GiIuc3BhcmsuR2V0VXR4b3NGb3JJZGVudGl0eVJlc3BvbnNlIgASXQoUcXVlcnlfc3BhcmtfaW52b2ljZXMSIC5zcGFyay5RdWVyeVNwYXJrSW52b2ljZXNSZXF1ZXN0GiEuc3BhcmsuUXVlcnlTcGFya0ludm9pY2VzUmVzcG9uc2UiABJ5Ch5pbml0aWF0ZV9zd2FwX3ByaW1hcnlfdHJhbnNmZXISKS5zcGFyay5Jbml0aWF0ZVN3YXBQcmltYXJ5VHJhbnNmZXJSZXF1ZXN0Giouc3BhcmsuSW5pdGlhdGVTd2FwUHJpbWFyeVRyYW5zZmVyUmVzcG9uc2UiABJgChV1cGRhdGVfd2FsbGV0X3NldHRpbmcSIS5zcGFyay5VcGRhdGVXYWxsZXRTZXR0aW5nUmVxdWVzdBoiLnNwYXJrLlVwZGF0ZVdhbGxldFNldHRpbmdSZXNwb25zZSIAEl0KFHF1ZXJ5X3dhbGxldF9zZXR0aW5nEiAuc3BhcmsuUXVlcnlXYWxsZXRTZXR0aW5nUmVxdWVzdBohLnNwYXJrLlF1ZXJ5V2FsbGV0U2V0dGluZ1Jlc3BvbnNlIgASZgoXY3JlYXRlX2RlbGVnYXRpb25fZ3JhbnQSIy5zcGFyay5DcmVhdGVEZWxlZ2F0aW9uR3JhbnRSZXF1ZXN0GiQuc3BhcmsuQ3JlYXRlRGVsZWdhdGlvbkdyYW50UmVzcG9uc2UiABJmChdyZXZva2VfZGVsZWdhdGlvbl9ncmFudBIjLnNwYXJrLlJldm9rZURlbGVnYXRpb25HcmFudFJlcXVlc3QaJC5zcGFyay5SZXZva2VEZWxlZ2F0aW9uR3JhbnRSZXNwb25zZSIAEmYKF3F1ZXJ5X2RlbGVnYXRpb25fZ3JhbnRzEiMuc3BhcmsuUXVlcnlEZWxlZ2F0aW9uR3JhbnRzUmVxdWVzdBokLnNwYXJrLlF1ZXJ5RGVsZWdhdGlvbkdyYW50c1Jlc3BvbnNlIgAScgobaW5zdGFsbF9sZWFmX2RlY29tcG9zaXRpb25zEicuc3BhcmsuSW5zdGFsbExlYWZEZWNvbXBvc2l0aW9uc1JlcXVlc3QaKC5zcGFyay5JbnN0YWxsTGVhZkRlY29tcG9zaXRpb25zUmVzcG9uc2UiABJjChZhZGRfZGVsZWdhdGlvbl9zcGVuZGVyEiIuc3BhcmsuQWRkRGVsZWdhdGlvblNwZW5kZXJSZXF1ZXN0GiMuc3BhcmsuQWRkRGVsZWdhdGlvblNwZW5kZXJSZXNwb25zZSIAEmwKGXJldm9rZV9kZWxlZ2F0aW9uX3NwZW5kZXISJS5zcGFyay5SZXZva2VEZWxlZ2F0aW9uU3BlbmRlclJlcXVlc3QaJi5zcGFyay5SZXZva2VEZWxlZ2F0aW9uU3BlbmRlclJlc3BvbnNlIgBCLFoqZ2l0aHViLmNvbS9saWdodHNwYXJrZGV2L3NwYXJrL3Byb3RvL3NwYXJrYgZwcm90bzM", [
|
|
56
|
+
file_google_protobuf_timestamp,
|
|
57
|
+
file_google_protobuf_empty,
|
|
58
|
+
file_validate_validate,
|
|
59
|
+
file_common
|
|
60
|
+
]);
|
|
61
|
+
/**
|
|
62
|
+
* Describes the message spark.SigningJob.
|
|
63
|
+
* Use `create(SigningJobSchema)` to create a new message.
|
|
64
|
+
*/
|
|
65
|
+
const SigningJobSchema = /*@__PURE__*/ messageDesc(file_spark, 20);
|
|
66
|
+
/**
|
|
67
|
+
* Describes the message spark.RenewNodeTimelockSigningJob.
|
|
68
|
+
* Use `create(RenewNodeTimelockSigningJobSchema)` to create a new message.
|
|
69
|
+
*/
|
|
70
|
+
const RenewNodeTimelockSigningJobSchema = /*@__PURE__*/ messageDesc(file_spark, 25);
|
|
71
|
+
/**
|
|
72
|
+
* Describes the message spark.RenewRefundTimelockSigningJob.
|
|
73
|
+
* Use `create(RenewRefundTimelockSigningJobSchema)` to create a new message.
|
|
74
|
+
*/
|
|
75
|
+
const RenewRefundTimelockSigningJobSchema = /*@__PURE__*/ messageDesc(file_spark, 26);
|
|
76
|
+
/**
|
|
77
|
+
* Describes the message spark.RenewNodeZeroTimelockSigningJob.
|
|
78
|
+
* Use `create(RenewNodeZeroTimelockSigningJobSchema)` to create a new message.
|
|
79
|
+
*/
|
|
80
|
+
const RenewNodeZeroTimelockSigningJobSchema = /*@__PURE__*/ messageDesc(file_spark, 27);
|
|
81
|
+
/**
|
|
82
|
+
* Describes the message spark.SecretShare.
|
|
83
|
+
* Use `create(SecretShareSchema)` to create a new message.
|
|
84
|
+
*/
|
|
85
|
+
const SecretShareSchema = /*@__PURE__*/ messageDesc(file_spark, 43);
|
|
86
|
+
/**
|
|
87
|
+
* Describes the message spark.UserSignedTxSigningJob.
|
|
88
|
+
* Use `create(UserSignedTxSigningJobSchema)` to create a new message.
|
|
89
|
+
*/
|
|
90
|
+
const UserSignedTxSigningJobSchema = /*@__PURE__*/ messageDesc(file_spark, 46);
|
|
91
|
+
/**
|
|
92
|
+
* Describes the message spark.InputSigningData.
|
|
93
|
+
* Use `create(InputSigningDataSchema)` to create a new message.
|
|
94
|
+
*/
|
|
95
|
+
const InputSigningDataSchema = /*@__PURE__*/ messageDesc(file_spark, 47);
|
|
96
|
+
/**
|
|
97
|
+
* Describes the message spark.StartTransferRequest.
|
|
98
|
+
* Use `create(StartTransferRequestSchema)` to create a new message.
|
|
99
|
+
*/
|
|
100
|
+
const StartTransferRequestSchema = /*@__PURE__*/ messageDesc(file_spark, 49);
|
|
101
|
+
/**
|
|
102
|
+
* Describes the message spark.SenderTransferPackage.
|
|
103
|
+
* Use `create(SenderTransferPackageSchema)` to create a new message.
|
|
104
|
+
*/
|
|
105
|
+
const SenderTransferPackageSchema = /*@__PURE__*/ messageDesc(file_spark, 51);
|
|
106
|
+
/**
|
|
107
|
+
* Describes the message spark.TransferPackage.
|
|
108
|
+
* Use `create(TransferPackageSchema)` to create a new message.
|
|
109
|
+
*/
|
|
110
|
+
const TransferPackageSchema = /*@__PURE__*/ messageDesc(file_spark, 53);
|
|
111
|
+
/**
|
|
112
|
+
* Describes the message spark.SendLeafKeyTweaks.
|
|
113
|
+
* Use `create(SendLeafKeyTweaksSchema)` to create a new message.
|
|
114
|
+
*/
|
|
115
|
+
const SendLeafKeyTweaksSchema = /*@__PURE__*/ messageDesc(file_spark, 55);
|
|
116
|
+
/**
|
|
117
|
+
* Describes the message spark.SendLeafKeyTweak.
|
|
118
|
+
* Use `create(SendLeafKeyTweakSchema)` to create a new message.
|
|
119
|
+
*/
|
|
120
|
+
const SendLeafKeyTweakSchema = /*@__PURE__*/ messageDesc(file_spark, 56);
|
|
121
|
+
/**
|
|
122
|
+
* Describes the message spark.ClaimLeafKeyTweak.
|
|
123
|
+
* Use `create(ClaimLeafKeyTweakSchema)` to create a new message.
|
|
124
|
+
*/
|
|
125
|
+
const ClaimLeafKeyTweakSchema = /*@__PURE__*/ messageDesc(file_spark, 82);
|
|
126
|
+
/**
|
|
127
|
+
* Describes the message spark.ClaimLeafKeyTweaks.
|
|
128
|
+
* Use `create(ClaimLeafKeyTweaksSchema)` to create a new message.
|
|
129
|
+
*/
|
|
130
|
+
const ClaimLeafKeyTweaksSchema = /*@__PURE__*/ messageDesc(file_spark, 83);
|
|
131
|
+
/**
|
|
132
|
+
* Describes the message spark.ClaimPackage.
|
|
133
|
+
* Use `create(ClaimPackageSchema)` to create a new message.
|
|
134
|
+
*/
|
|
135
|
+
const ClaimPackageSchema = /*@__PURE__*/ messageDesc(file_spark, 84);
|
|
136
|
+
/**
|
|
137
|
+
* @generated from enum spark.InitiatePreimageSwapRequest.Reason
|
|
138
|
+
*/
|
|
139
|
+
const InitiatePreimageSwapRequest_Reason = {
|
|
140
|
+
/**
|
|
141
|
+
* The associated lightning service is sending the payment.
|
|
142
|
+
*
|
|
143
|
+
* @generated from enum value: REASON_SEND = 0;
|
|
144
|
+
*/
|
|
145
|
+
SEND: 0,
|
|
146
|
+
/**
|
|
147
|
+
* The associated lightning service is receiving the payment.
|
|
148
|
+
*
|
|
149
|
+
* @generated from enum value: REASON_RECEIVE = 1;
|
|
150
|
+
*/
|
|
151
|
+
RECEIVE: 1
|
|
152
|
+
};
|
|
153
|
+
/**
|
|
154
|
+
* Describes the message spark.SparkAddress.
|
|
155
|
+
* Use `create(SparkAddressSchema)` to create a new message.
|
|
156
|
+
*/
|
|
157
|
+
const SparkAddressSchema = /*@__PURE__*/ messageDesc(file_spark, 141);
|
|
158
|
+
/**
|
|
159
|
+
* Describes the message spark.SparkInvoiceFields.
|
|
160
|
+
* Use `create(SparkInvoiceFieldsSchema)` to create a new message.
|
|
161
|
+
*/
|
|
162
|
+
const SparkInvoiceFieldsSchema = /*@__PURE__*/ messageDesc(file_spark, 142);
|
|
163
|
+
/**
|
|
164
|
+
* Describes the message spark.SatsPayment.
|
|
165
|
+
* Use `create(SatsPaymentSchema)` to create a new message.
|
|
166
|
+
*/
|
|
167
|
+
const SatsPaymentSchema = /*@__PURE__*/ messageDesc(file_spark, 143);
|
|
168
|
+
/**
|
|
169
|
+
* Describes the message spark.TokensPayment.
|
|
170
|
+
* Use `create(TokensPaymentSchema)` to create a new message.
|
|
171
|
+
*/
|
|
172
|
+
const TokensPaymentSchema = /*@__PURE__*/ messageDesc(file_spark, 144);
|
|
173
|
+
/**
|
|
174
|
+
* Describes the message spark.AdaptorPublicKeyPackage.
|
|
175
|
+
* Use `create(AdaptorPublicKeyPackageSchema)` to create a new message.
|
|
176
|
+
*/
|
|
177
|
+
const AdaptorPublicKeyPackageSchema = /*@__PURE__*/ messageDesc(file_spark, 171);
|
|
178
|
+
/**
|
|
179
|
+
* *
|
|
180
|
+
* Network is the network type of the bitcoin network.
|
|
181
|
+
*
|
|
182
|
+
* @generated from enum spark.Network
|
|
183
|
+
*/
|
|
184
|
+
const Network = {
|
|
185
|
+
/**
|
|
186
|
+
* @generated from enum value: UNSPECIFIED = 0;
|
|
187
|
+
*/
|
|
188
|
+
UNSPECIFIED: 0,
|
|
189
|
+
/**
|
|
190
|
+
* @generated from enum value: MAINNET = 1;
|
|
191
|
+
*/
|
|
192
|
+
MAINNET: 1,
|
|
193
|
+
/**
|
|
194
|
+
* @generated from enum value: REGTEST = 2;
|
|
195
|
+
*/
|
|
196
|
+
REGTEST: 2,
|
|
197
|
+
/**
|
|
198
|
+
* @generated from enum value: TESTNET = 3;
|
|
199
|
+
*/
|
|
200
|
+
TESTNET: 3,
|
|
201
|
+
/**
|
|
202
|
+
* @generated from enum value: SIGNET = 4;
|
|
203
|
+
*/
|
|
204
|
+
SIGNET: 4
|
|
205
|
+
};
|
|
206
|
+
/**
|
|
207
|
+
* @generated from enum spark.Direction
|
|
208
|
+
*/
|
|
209
|
+
const Direction = {
|
|
210
|
+
/**
|
|
211
|
+
* @generated from enum value: NEXT = 0;
|
|
212
|
+
*/
|
|
213
|
+
NEXT: 0,
|
|
214
|
+
/**
|
|
215
|
+
* @generated from enum value: PREVIOUS = 1;
|
|
216
|
+
*/
|
|
217
|
+
PREVIOUS: 1
|
|
218
|
+
};
|
|
219
|
+
/**
|
|
220
|
+
* @generated from enum spark.TransferStatus
|
|
221
|
+
*/
|
|
222
|
+
const TransferStatus = {
|
|
223
|
+
/**
|
|
224
|
+
* @generated from enum value: TRANSFER_STATUS_SENDER_INITIATED = 0;
|
|
225
|
+
*/
|
|
226
|
+
SENDER_INITIATED: 0,
|
|
227
|
+
/**
|
|
228
|
+
* @generated from enum value: TRANSFER_STATUS_SENDER_KEY_TWEAK_PENDING = 1;
|
|
229
|
+
*/
|
|
230
|
+
SENDER_KEY_TWEAK_PENDING: 1,
|
|
231
|
+
/**
|
|
232
|
+
* @generated from enum value: TRANSFER_STATUS_SENDER_KEY_TWEAKED = 2;
|
|
233
|
+
*/
|
|
234
|
+
SENDER_KEY_TWEAKED: 2,
|
|
235
|
+
/**
|
|
236
|
+
* @generated from enum value: TRANSFER_STATUS_RECEIVER_KEY_TWEAKED = 3;
|
|
237
|
+
*/
|
|
238
|
+
RECEIVER_KEY_TWEAKED: 3,
|
|
239
|
+
/**
|
|
240
|
+
* @generated from enum value: TRANSFER_STATUS_RECEIVER_REFUND_SIGNED = 4;
|
|
241
|
+
*/
|
|
242
|
+
RECEIVER_REFUND_SIGNED: 4,
|
|
243
|
+
/**
|
|
244
|
+
* @generated from enum value: TRANSFER_STATUS_COMPLETED = 5;
|
|
245
|
+
*/
|
|
246
|
+
COMPLETED: 5,
|
|
247
|
+
/**
|
|
248
|
+
* @generated from enum value: TRANSFER_STATUS_EXPIRED = 6;
|
|
249
|
+
*/
|
|
250
|
+
EXPIRED: 6,
|
|
251
|
+
/**
|
|
252
|
+
* @generated from enum value: TRANSFER_STATUS_RETURNED = 7;
|
|
253
|
+
*/
|
|
254
|
+
RETURNED: 7,
|
|
255
|
+
/**
|
|
256
|
+
* @generated from enum value: TRANSFER_STATUS_SENDER_INITIATED_COORDINATOR = 8;
|
|
257
|
+
*/
|
|
258
|
+
SENDER_INITIATED_COORDINATOR: 8,
|
|
259
|
+
/**
|
|
260
|
+
* @generated from enum value: TRANSFER_STATUS_RECEIVER_KEY_TWEAK_LOCKED = 9;
|
|
261
|
+
*/
|
|
262
|
+
RECEIVER_KEY_TWEAK_LOCKED: 9,
|
|
263
|
+
/**
|
|
264
|
+
* @generated from enum value: TRANSFER_STATUS_RECEIVER_KEY_TWEAK_APPLIED = 10;
|
|
265
|
+
*/
|
|
266
|
+
RECEIVER_KEY_TWEAK_APPLIED: 10,
|
|
267
|
+
/**
|
|
268
|
+
* @generated from enum value: TRANSFER_STATUS_APPLYING_SENDER_KEY_TWEAK = 11;
|
|
269
|
+
*/
|
|
270
|
+
APPLYING_SENDER_KEY_TWEAK: 11
|
|
271
|
+
};
|
|
272
|
+
/**
|
|
273
|
+
* Per-receiver status on the receiver edge of a Transfer. For single-receiver
|
|
274
|
+
* (V2) transfers this is always lock-step with Transfer.status. For
|
|
275
|
+
* multi-receiver (V3) transfers each receiver advances independently.
|
|
276
|
+
* This is the authoritative per-receiver state.
|
|
277
|
+
*
|
|
278
|
+
* @generated from enum spark.TransferReceiverStatus
|
|
279
|
+
*/
|
|
280
|
+
const TransferReceiverStatus = {
|
|
281
|
+
/**
|
|
282
|
+
* @generated from enum value: TRANSFER_RECEIVER_STATUS_INITIATED = 0;
|
|
283
|
+
*/
|
|
284
|
+
INITIATED: 0,
|
|
285
|
+
/**
|
|
286
|
+
* @generated from enum value: TRANSFER_RECEIVER_STATUS_CLAIM_PENDING = 1;
|
|
287
|
+
*/
|
|
288
|
+
CLAIM_PENDING: 1,
|
|
289
|
+
/**
|
|
290
|
+
* @generated from enum value: TRANSFER_RECEIVER_STATUS_KEY_TWEAKED = 2;
|
|
291
|
+
*/
|
|
292
|
+
KEY_TWEAKED: 2,
|
|
293
|
+
/**
|
|
294
|
+
* @generated from enum value: TRANSFER_RECEIVER_STATUS_KEY_TWEAK_LOCKED = 3;
|
|
295
|
+
*/
|
|
296
|
+
KEY_TWEAK_LOCKED: 3,
|
|
297
|
+
/**
|
|
298
|
+
* @generated from enum value: TRANSFER_RECEIVER_STATUS_KEY_TWEAK_APPLIED = 4;
|
|
299
|
+
*/
|
|
300
|
+
KEY_TWEAK_APPLIED: 4,
|
|
301
|
+
/**
|
|
302
|
+
* @generated from enum value: TRANSFER_RECEIVER_STATUS_REFUND_SIGNED = 5;
|
|
303
|
+
*/
|
|
304
|
+
REFUND_SIGNED: 5,
|
|
305
|
+
/**
|
|
306
|
+
* @generated from enum value: TRANSFER_RECEIVER_STATUS_COMPLETED = 6;
|
|
307
|
+
*/
|
|
308
|
+
COMPLETED: 6,
|
|
309
|
+
/**
|
|
310
|
+
* @generated from enum value: TRANSFER_RECEIVER_STATUS_CANCELLED = 7;
|
|
311
|
+
*/
|
|
312
|
+
CANCELLED: 7
|
|
313
|
+
};
|
|
314
|
+
/**
|
|
315
|
+
* @generated from enum spark.TransferType
|
|
316
|
+
*/
|
|
317
|
+
const TransferType = {
|
|
318
|
+
/**
|
|
319
|
+
* @generated from enum value: PREIMAGE_SWAP = 0;
|
|
320
|
+
*/
|
|
321
|
+
PREIMAGE_SWAP: 0,
|
|
322
|
+
/**
|
|
323
|
+
* @generated from enum value: COOPERATIVE_EXIT = 1;
|
|
324
|
+
*/
|
|
325
|
+
COOPERATIVE_EXIT: 1,
|
|
326
|
+
/**
|
|
327
|
+
* @generated from enum value: TRANSFER = 2;
|
|
328
|
+
*/
|
|
329
|
+
TRANSFER: 2,
|
|
330
|
+
/**
|
|
331
|
+
* @generated from enum value: UTXO_SWAP = 3;
|
|
332
|
+
*/
|
|
333
|
+
UTXO_SWAP: 3,
|
|
334
|
+
/**
|
|
335
|
+
* @generated from enum value: SWAP = 30;
|
|
336
|
+
*/
|
|
337
|
+
SWAP: 30,
|
|
338
|
+
/**
|
|
339
|
+
* @generated from enum value: COUNTER_SWAP = 40;
|
|
340
|
+
*/
|
|
341
|
+
COUNTER_SWAP: 40,
|
|
342
|
+
/**
|
|
343
|
+
* @generated from enum value: PRIMARY_SWAP_V3 = 4;
|
|
344
|
+
*/
|
|
345
|
+
PRIMARY_SWAP_V3: 4,
|
|
346
|
+
/**
|
|
347
|
+
* @generated from enum value: COUNTER_SWAP_V3 = 5;
|
|
348
|
+
*/
|
|
349
|
+
COUNTER_SWAP_V3: 5
|
|
350
|
+
};
|
|
351
|
+
/**
|
|
352
|
+
* @generated from enum spark.Order
|
|
353
|
+
*/
|
|
354
|
+
const Order = {
|
|
355
|
+
/**
|
|
356
|
+
* @generated from enum value: DESCENDING = 0;
|
|
357
|
+
*/
|
|
358
|
+
DESCENDING: 0,
|
|
359
|
+
/**
|
|
360
|
+
* @generated from enum value: ASCENDING = 1;
|
|
361
|
+
*/
|
|
362
|
+
ASCENDING: 1
|
|
363
|
+
};
|
|
364
|
+
/**
|
|
365
|
+
* Which hash variant to use in cryptographic operations.
|
|
366
|
+
*
|
|
367
|
+
* @generated from enum spark.HashVariant
|
|
368
|
+
*/
|
|
369
|
+
const HashVariant = {
|
|
370
|
+
/**
|
|
371
|
+
* Legacy
|
|
372
|
+
*
|
|
373
|
+
* @generated from enum value: HASH_VARIANT_UNSPECIFIED = 0;
|
|
374
|
+
*/
|
|
375
|
+
UNSPECIFIED: 0,
|
|
376
|
+
/**
|
|
377
|
+
* Structured hashing. Binds the delegation intent (Spark Pull) too when the
|
|
378
|
+
* transfer package carries one; a package without an intent hashes exactly as
|
|
379
|
+
* it did before delegation existed, so already-released SDKs keep verifying.
|
|
380
|
+
*
|
|
381
|
+
* @generated from enum value: HASH_VARIANT_V2 = 1;
|
|
382
|
+
*/
|
|
383
|
+
V2: 1
|
|
384
|
+
};
|
|
385
|
+
/**
|
|
386
|
+
* @generated from enum spark.InvoiceStatus
|
|
387
|
+
*/
|
|
388
|
+
const InvoiceStatus = {
|
|
389
|
+
/**
|
|
390
|
+
* @generated from enum value: NOT_FOUND = 0;
|
|
391
|
+
*/
|
|
392
|
+
NOT_FOUND: 0,
|
|
393
|
+
/**
|
|
394
|
+
* @generated from enum value: PENDING = 1;
|
|
395
|
+
*/
|
|
396
|
+
PENDING: 1,
|
|
397
|
+
/**
|
|
398
|
+
* Payment for this id is complete and the stored invoice's money fields
|
|
399
|
+
* (receiver, payment kind, amount, token identifier) match the invoice
|
|
400
|
+
* you queried.
|
|
401
|
+
*
|
|
402
|
+
* @generated from enum value: FINALIZED = 2;
|
|
403
|
+
*/
|
|
404
|
+
FINALIZED: 2,
|
|
405
|
+
/**
|
|
406
|
+
* @generated from enum value: RETURNED = 4;
|
|
407
|
+
*/
|
|
408
|
+
RETURNED: 4,
|
|
409
|
+
/**
|
|
410
|
+
* A payment exists for this invoice id, but the money fields (receiver,
|
|
411
|
+
* payment kind, amount, token identifier) of the stored invoice may differ
|
|
412
|
+
* from the invoice you queried. Compare response.invoice to the invoice
|
|
413
|
+
* you queried and confirm it matches what you expect before relying on
|
|
414
|
+
* this result.
|
|
415
|
+
*
|
|
416
|
+
* @generated from enum value: MISMATCHED_INVOICE_FINALIZED = 5;
|
|
417
|
+
*/
|
|
418
|
+
MISMATCHED_INVOICE_FINALIZED: 5,
|
|
419
|
+
/**
|
|
420
|
+
* @generated from enum value: MISMATCHED_INVOICE_PENDING = 6;
|
|
421
|
+
*/
|
|
422
|
+
MISMATCHED_INVOICE_PENDING: 6,
|
|
423
|
+
/**
|
|
424
|
+
* @generated from enum value: MISMATCHED_INVOICE_RETURNED = 7;
|
|
425
|
+
*/
|
|
426
|
+
MISMATCHED_INVOICE_RETURNED: 7
|
|
427
|
+
};
|
|
428
|
+
/**
|
|
429
|
+
* @generated from enum spark.TreeNodeStatus
|
|
430
|
+
*/
|
|
431
|
+
const TreeNodeStatus = {
|
|
432
|
+
/**
|
|
433
|
+
* @generated from enum value: TREE_NODE_STATUS_CREATING = 0;
|
|
434
|
+
*/
|
|
435
|
+
CREATING: 0,
|
|
436
|
+
/**
|
|
437
|
+
* @generated from enum value: TREE_NODE_STATUS_AVAILABLE = 1;
|
|
438
|
+
*/
|
|
439
|
+
AVAILABLE: 1,
|
|
440
|
+
/**
|
|
441
|
+
* @generated from enum value: TREE_NODE_STATUS_FROZEN_BY_ISSUER = 2;
|
|
442
|
+
*/
|
|
443
|
+
FROZEN_BY_ISSUER: 2,
|
|
444
|
+
/**
|
|
445
|
+
* @generated from enum value: TREE_NODE_STATUS_TRANSFER_LOCKED = 3;
|
|
446
|
+
*/
|
|
447
|
+
TRANSFER_LOCKED: 3,
|
|
448
|
+
/**
|
|
449
|
+
* @generated from enum value: TREE_NODE_STATUS_SPLIT_LOCKED = 4;
|
|
450
|
+
*/
|
|
451
|
+
SPLIT_LOCKED: 4,
|
|
452
|
+
/**
|
|
453
|
+
* @generated from enum value: TREE_NODE_STATUS_SPLITTED = 5;
|
|
454
|
+
*/
|
|
455
|
+
SPLITTED: 5,
|
|
456
|
+
/**
|
|
457
|
+
* @generated from enum value: TREE_NODE_STATUS_AGGREGATED = 6;
|
|
458
|
+
*/
|
|
459
|
+
AGGREGATED: 6,
|
|
460
|
+
/**
|
|
461
|
+
* @generated from enum value: TREE_NODE_STATUS_ON_CHAIN = 7;
|
|
462
|
+
*/
|
|
463
|
+
ON_CHAIN: 7,
|
|
464
|
+
/**
|
|
465
|
+
* @generated from enum value: TREE_NODE_STATUS_AGGREGATE_LOCK = 8;
|
|
466
|
+
*/
|
|
467
|
+
AGGREGATE_LOCK: 8,
|
|
468
|
+
/**
|
|
469
|
+
* @generated from enum value: TREE_NODE_STATUS_EXITED = 9;
|
|
470
|
+
*/
|
|
471
|
+
EXITED: 9,
|
|
472
|
+
/**
|
|
473
|
+
* @generated from enum value: TREE_NODE_STATUS_RENEW_LOCKED = 10;
|
|
474
|
+
*/
|
|
475
|
+
RENEW_LOCKED: 10,
|
|
476
|
+
/**
|
|
477
|
+
* @generated from enum value: TREE_NODE_STATUS_UNAVAILABLE = 11;
|
|
478
|
+
*/
|
|
479
|
+
UNAVAILABLE: 11,
|
|
480
|
+
/**
|
|
481
|
+
* @generated from enum value: TREE_NODE_STATUS_PARENT_EXITED = 12;
|
|
482
|
+
*/
|
|
483
|
+
PARENT_EXITED: 12,
|
|
484
|
+
/**
|
|
485
|
+
* The node's subtree was aggregated back into it (AggregateLeaves): it
|
|
486
|
+
* carries live exit transactions signed under the aggregated leaf key and
|
|
487
|
+
* is exit-only — not transferable, renewable, or splittable. It may be
|
|
488
|
+
* aggregated further up the tree.
|
|
489
|
+
*
|
|
490
|
+
* @generated from enum value: TREE_NODE_STATUS_CONSOLIDATED = 13;
|
|
491
|
+
*/
|
|
492
|
+
CONSOLIDATED: 13,
|
|
493
|
+
/**
|
|
494
|
+
* A node below one whose watchtower transaction confirmed, which spends the
|
|
495
|
+
* output this node's own transaction claims. Terminal; recovery moves to L1.
|
|
496
|
+
*
|
|
497
|
+
* @generated from enum value: TREE_NODE_STATUS_WATCHTOWER_EXITED = 14;
|
|
498
|
+
*/
|
|
499
|
+
WATCHTOWER_EXITED: 14,
|
|
500
|
+
/**
|
|
501
|
+
* A watchtower-exited node whose owner has co-signed a transaction spending
|
|
502
|
+
* the swept output with the SE. Written when that signature is issued, not
|
|
503
|
+
* when it confirms — the SE never observes the broadcast. Terminal: the leaf
|
|
504
|
+
* can no longer be used off-chain, and recovery is on L1.
|
|
505
|
+
*
|
|
506
|
+
* @generated from enum value: TREE_NODE_STATUS_WATCHTOWER_EXIT_RECOVERED = 15;
|
|
507
|
+
*/
|
|
508
|
+
WATCHTOWER_EXIT_RECOVERED: 15
|
|
509
|
+
};
|
|
510
|
+
/**
|
|
511
|
+
* @generated from service spark.SparkService
|
|
512
|
+
*/
|
|
513
|
+
const SparkService = /*@__PURE__*/ serviceDesc(file_spark, 0);
|
|
514
|
+
//#endregion
|
|
515
|
+
//#region src/core/network.ts
|
|
516
|
+
const SSP_GRAPHQL_PATH = "graphql/spark/2025-03-19";
|
|
517
|
+
const COORDINATOR = "0000000000000000000000000000000000000000000000000000000000000001";
|
|
518
|
+
const OPERATORS = [
|
|
519
|
+
{
|
|
520
|
+
id: 0,
|
|
521
|
+
identifier: "0000000000000000000000000000000000000000000000000000000000000001",
|
|
522
|
+
address: "https://0.spark.lightspark.com",
|
|
523
|
+
identityPublicKey: "03dfbdff4b6332c220f8fa2ba8ed496c698ceada563fa01b67d9983bfc5c95e763"
|
|
524
|
+
},
|
|
525
|
+
{
|
|
526
|
+
id: 1,
|
|
527
|
+
identifier: "0000000000000000000000000000000000000000000000000000000000000002",
|
|
528
|
+
address: "https://spark-operator.breez.technology",
|
|
529
|
+
identityPublicKey: "03e625e9768651c9be268e287245cc33f96a68ce9141b0b4769205db027ee8ed77"
|
|
530
|
+
},
|
|
531
|
+
{
|
|
532
|
+
id: 2,
|
|
533
|
+
identifier: "0000000000000000000000000000000000000000000000000000000000000003",
|
|
534
|
+
address: "https://2.spark.flashnet.xyz",
|
|
535
|
+
identityPublicKey: "022eda13465a59205413086130a65dc0ed1b8f8e51937043161f8be0c369b1a410"
|
|
536
|
+
}
|
|
537
|
+
];
|
|
538
|
+
const SSP_IDENTITY_KEY = {
|
|
539
|
+
mainnet: "023e33e2920326f64ea31058d44777442d97d7d5cbfcf54e3060bc1695e5261c93",
|
|
540
|
+
regtest: "022bf283544b16c0622daecb79422007d167eca6ce9f0c98c0c49833b1f7170bfe"
|
|
541
|
+
};
|
|
542
|
+
/**
|
|
543
|
+
* Static network parameters for `network`. Each call builds a fresh config — fresh `Uint8Array`
|
|
544
|
+
* keys — so callers can never corrupt shared module state. Throws {@link SparkInputError} on an
|
|
545
|
+
* unknown name.
|
|
546
|
+
*/
|
|
547
|
+
function sparkNetworkConfig(network) {
|
|
548
|
+
const sspKey = SSP_IDENTITY_KEY[network];
|
|
549
|
+
if (sspKey === void 0) throw new SparkInputError("network: must be 'mainnet' or 'regtest'");
|
|
550
|
+
return {
|
|
551
|
+
network,
|
|
552
|
+
operators: OPERATORS.map((operator) => ({
|
|
553
|
+
id: operator.id,
|
|
554
|
+
identifier: operator.identifier,
|
|
555
|
+
address: operator.address,
|
|
556
|
+
identityPublicKey: hexToBytes(operator.identityPublicKey)
|
|
557
|
+
})),
|
|
558
|
+
threshold: 2,
|
|
559
|
+
coordinator: COORDINATOR,
|
|
560
|
+
ssp: {
|
|
561
|
+
baseUrl: "https://api.lightspark.com",
|
|
562
|
+
identityPublicKey: hexToBytes(sspKey),
|
|
563
|
+
graphqlPath: SSP_GRAPHQL_PATH
|
|
564
|
+
},
|
|
565
|
+
tokens: {
|
|
566
|
+
withdrawBondSats: 1e4,
|
|
567
|
+
withdrawRelativeBlockLocktime: 1e3,
|
|
568
|
+
validityDurationSeconds: 180
|
|
569
|
+
}
|
|
570
|
+
};
|
|
571
|
+
}
|
|
572
|
+
const PROTO_NETWORK = {
|
|
573
|
+
mainnet: Network.MAINNET,
|
|
574
|
+
regtest: Network.REGTEST
|
|
575
|
+
};
|
|
576
|
+
/** Maps a {@link SparkNetwork} onto the protobuf `spark.Network` enum. */
|
|
577
|
+
function sparkNetworkProto(network) {
|
|
578
|
+
return PROTO_NETWORK[network];
|
|
579
|
+
}
|
|
580
|
+
/** Maps a protobuf `spark.Network` enum value back onto {@link SparkNetwork}. */
|
|
581
|
+
function sparkNetworkFromProto(network) {
|
|
582
|
+
switch (network) {
|
|
583
|
+
case Network.MAINNET: return "mainnet";
|
|
584
|
+
case Network.REGTEST: return "regtest";
|
|
585
|
+
default: throw new SparkInputError("unknown proto network");
|
|
586
|
+
}
|
|
587
|
+
}
|
|
588
|
+
//#endregion
|
|
589
|
+
//#region src/core/assert.ts
|
|
590
|
+
/** Maximum satoshi amount accepted anywhere in the protocol (21e6 BTC). */
|
|
591
|
+
const MAX_SATS = 0x775f05a074000;
|
|
592
|
+
function assertU32(value, field) {
|
|
593
|
+
if (!Number.isSafeInteger(value) || value < 0 || value > 4294967295) throw new SparkInputError(`${field}: must be a uint32`);
|
|
594
|
+
}
|
|
595
|
+
function assertSats(value, field) {
|
|
596
|
+
if (!Number.isSafeInteger(value) || value < 0 || value > 0x775f05a074000) throw new SparkInputError(`${field}: must be a non-negative satoshi amount (<= ${MAX_SATS})`);
|
|
597
|
+
}
|
|
598
|
+
function requireLength(value, length, field) {
|
|
599
|
+
if (value.length !== length) throw new SparkInputError(`${field}: must be exactly ${length} bytes`);
|
|
600
|
+
}
|
|
601
|
+
/** Narrows a protobuf `uint64`/`int64` satoshi value; rejects anything outside 0..MAX_SATS. */
|
|
602
|
+
function u64ToSats(value, field) {
|
|
603
|
+
if (value < 0n || value > BigInt(0x775f05a074000)) throw new SparkInputError(`${field}: must be a non-negative satoshi amount (<= ${MAX_SATS})`);
|
|
604
|
+
return Number(value);
|
|
605
|
+
}
|
|
606
|
+
/** Length-checks plus a real point-on-curve check for a compressed secp256k1 key. */
|
|
607
|
+
function assertCompressedKey(key, field) {
|
|
608
|
+
if (key.length !== 33) throw new SparkInputError(`${field}: must be a 33-byte compressed public key`);
|
|
609
|
+
try {
|
|
610
|
+
secp256k1.Point.fromBytes(key);
|
|
611
|
+
} catch (error) {
|
|
612
|
+
throw new SparkInputError(`${field}: not a valid secp256k1 point`, { cause: error });
|
|
613
|
+
}
|
|
614
|
+
}
|
|
615
|
+
//#endregion
|
|
616
|
+
//#region src/core/bytes.ts
|
|
617
|
+
/** Byte-level helpers shared across core. */
|
|
618
|
+
/** Lexicographic byte comparison; equal prefixes order by length (shorter first). */
|
|
619
|
+
function compareBytes(a, b) {
|
|
620
|
+
const minLength = Math.min(a.length, b.length);
|
|
621
|
+
for (let i = 0; i < minLength; i++) {
|
|
622
|
+
const av = a[i];
|
|
623
|
+
const bv = b[i];
|
|
624
|
+
if (av !== void 0 && bv !== void 0 && av !== bv) return av - bv;
|
|
625
|
+
}
|
|
626
|
+
return a.length - b.length;
|
|
627
|
+
}
|
|
628
|
+
/** Big-endian u32 serialization. */
|
|
629
|
+
function uint32be(value) {
|
|
630
|
+
const bytes = /* @__PURE__ */ new Uint8Array(4);
|
|
631
|
+
new DataView(bytes.buffer).setUint32(0, value >>> 0, false);
|
|
632
|
+
return bytes;
|
|
633
|
+
}
|
|
634
|
+
/** Big-endian u64 serialization. */
|
|
635
|
+
function uint64be(value) {
|
|
636
|
+
const bytes = /* @__PURE__ */ new Uint8Array(8);
|
|
637
|
+
new DataView(bytes.buffer).setBigUint64(0, value, false);
|
|
638
|
+
return bytes;
|
|
639
|
+
}
|
|
640
|
+
//#endregion
|
|
641
|
+
//#region src/core/uuid.ts
|
|
642
|
+
/**
|
|
643
|
+
* UUIDv7 (RFC 9562 §5.7): 48-bit millisecond timestamp, then 74 random bits with the version (0111)
|
|
644
|
+
* and variant (10) fields applied. Randomness and the clock are injected so the function stays
|
|
645
|
+
* platform-neutral and deterministic under test.
|
|
646
|
+
*/
|
|
647
|
+
function uuidv7(random, now = () => Date.now()) {
|
|
648
|
+
const timestamp = now();
|
|
649
|
+
if (!Number.isSafeInteger(timestamp) || timestamp < 0 || timestamp > 0xffffffffffff) throw new SparkInputError("timestamp: must be a non-negative 48-bit millisecond value");
|
|
650
|
+
const rand = random(10);
|
|
651
|
+
if (rand.length < 10) throw new SparkInputError("random: must return at least 10 bytes");
|
|
652
|
+
const bytes = /* @__PURE__ */ new Uint8Array(16);
|
|
653
|
+
bytes[0] = timestamp / 1099511627776;
|
|
654
|
+
bytes[1] = timestamp / 4294967296;
|
|
655
|
+
bytes[2] = timestamp / 16777216;
|
|
656
|
+
bytes[3] = timestamp / 65536;
|
|
657
|
+
bytes[4] = timestamp / 256;
|
|
658
|
+
bytes[5] = timestamp;
|
|
659
|
+
const [r0 = 0, r1 = 0, r2 = 0] = rand;
|
|
660
|
+
bytes[6] = 112 | r0 & 15;
|
|
661
|
+
bytes[7] = r1;
|
|
662
|
+
bytes[8] = 128 | r2 & 63;
|
|
663
|
+
bytes.set(rand.subarray(3, 10), 9);
|
|
664
|
+
return uuidFromBytes(bytes);
|
|
665
|
+
}
|
|
666
|
+
const HEX = "0123456789abcdef";
|
|
667
|
+
/** Formats 16 bytes as a canonical lowercase UUID string. */
|
|
668
|
+
function uuidFromBytes(bytes) {
|
|
669
|
+
if (bytes.length !== 16) throw new SparkInputError("uuid: must be 16 bytes");
|
|
670
|
+
let out = "";
|
|
671
|
+
let i = 0;
|
|
672
|
+
for (const b of bytes) {
|
|
673
|
+
if (i === 4 || i === 6 || i === 8 || i === 10) out += "-";
|
|
674
|
+
out += HEX.charAt(b >> 4) + HEX.charAt(b & 15);
|
|
675
|
+
i += 1;
|
|
676
|
+
}
|
|
677
|
+
return out;
|
|
678
|
+
}
|
|
679
|
+
/**
|
|
680
|
+
* Parses a UUID string to its 16 bytes. Accepts upper- and lowercase hex; braces and the
|
|
681
|
+
* `urn:uuid:` prefix are rejected — only the canonical `xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx` shape
|
|
682
|
+
* is valid here.
|
|
683
|
+
*/
|
|
684
|
+
function uuidToBytes(id) {
|
|
685
|
+
if (!/^[0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{12}$/.test(id)) throw new SparkInputError("id: must be a UUID in canonical form");
|
|
686
|
+
const hex = id.replaceAll("-", "");
|
|
687
|
+
const bytes = /* @__PURE__ */ new Uint8Array(16);
|
|
688
|
+
for (let i = 0; i < 16; i++) bytes[i] = Number.parseInt(hex.slice(i * 2, i * 2 + 2), 16);
|
|
689
|
+
return bytes;
|
|
690
|
+
}
|
|
691
|
+
const MEMO_MAX_BYTES = 120;
|
|
692
|
+
const TOKEN_IDENTIFIER_LENGTH$1 = 32;
|
|
693
|
+
const MAX_TOKEN_AMOUNT_BYTES$1 = 16;
|
|
694
|
+
/**
|
|
695
|
+
* Validates every field of an invoice: `id` must be a UUID, `memo` at most 120 UTF-8 bytes,
|
|
696
|
+
* `senderPublicKey` a valid compressed secp256k1 point, `expiresAt` a non-negative safe integer,
|
|
697
|
+
* sats amounts bounded by {@link MAX_SATS} and token fields uint128-sized. With
|
|
698
|
+
* `requireCurrentVersion` the version must equal {@link INVOICE_VERSION} — used for locally built
|
|
699
|
+
* invoices; decoded peer invoices may carry newer versions and still parse.
|
|
700
|
+
*/
|
|
701
|
+
function validateInvoiceFields(invoice, options) {
|
|
702
|
+
if (options.requireCurrentVersion && invoice.version !== 1) throw new SparkInputError(`invoice.version: must be 1`);
|
|
703
|
+
uuidToBytes(invoice.id);
|
|
704
|
+
if (invoice.memo !== void 0 && utf8ToBytes(invoice.memo).length > MEMO_MAX_BYTES) throw new SparkInputError(`invoice.memo: exceeds ${MEMO_MAX_BYTES} UTF-8 bytes`);
|
|
705
|
+
if (invoice.senderPublicKey !== void 0) assertCompressedKey(invoice.senderPublicKey, "invoice.senderPublicKey");
|
|
706
|
+
if (invoice.expiresAt !== void 0 && (!Number.isSafeInteger(invoice.expiresAt) || invoice.expiresAt < 0)) throw new SparkInputError("invoice.expiresAt: must be a non-negative safe-integer unix-ms timestamp");
|
|
707
|
+
const { payment } = invoice;
|
|
708
|
+
if (payment === void 0) return;
|
|
709
|
+
switch (payment.type) {
|
|
710
|
+
case "sats":
|
|
711
|
+
if (payment.amount !== void 0) assertSats(payment.amount, "invoice.payment.amount");
|
|
712
|
+
return;
|
|
713
|
+
case "tokens":
|
|
714
|
+
if (payment.tokenIdentifier !== void 0) requireLength(payment.tokenIdentifier, TOKEN_IDENTIFIER_LENGTH$1, "invoice.payment.tokenIdentifier");
|
|
715
|
+
if (payment.amount !== void 0 && payment.amount.length > MAX_TOKEN_AMOUNT_BYTES$1) throw new SparkInputError(`invoice.payment.amount: exceeds ${MAX_TOKEN_AMOUNT_BYTES$1} bytes (uint128)`);
|
|
716
|
+
}
|
|
717
|
+
}
|
|
718
|
+
/**
|
|
719
|
+
* Converts a decoded `SparkInvoiceFields` message into the plain model, normalizing empty fields
|
|
720
|
+
* (zero-length bytes, absent scalars) to `undefined`.
|
|
721
|
+
*/
|
|
722
|
+
function protoInvoiceToPlain(fields) {
|
|
723
|
+
const { paymentType } = fields;
|
|
724
|
+
let payment;
|
|
725
|
+
if (paymentType.case === "tokensPayment") payment = {
|
|
726
|
+
type: "tokens",
|
|
727
|
+
tokenIdentifier: paymentType.value.tokenIdentifier !== void 0 && paymentType.value.tokenIdentifier.length > 0 ? paymentType.value.tokenIdentifier : void 0,
|
|
728
|
+
amount: paymentType.value.amount !== void 0 && paymentType.value.amount.length > 0 ? paymentType.value.amount : void 0
|
|
729
|
+
};
|
|
730
|
+
else if (paymentType.case === "satsPayment") {
|
|
731
|
+
const { amount } = paymentType.value;
|
|
732
|
+
payment = {
|
|
733
|
+
type: "sats",
|
|
734
|
+
amount: amount === void 0 ? void 0 : bigintToSafeInt(amount)
|
|
735
|
+
};
|
|
736
|
+
}
|
|
737
|
+
return {
|
|
738
|
+
version: fields.version,
|
|
739
|
+
id: uuidFromBytes(fields.id),
|
|
740
|
+
payment,
|
|
741
|
+
memo: fields.memo,
|
|
742
|
+
senderPublicKey: fields.senderPublicKey !== void 0 && fields.senderPublicKey.length > 0 ? fields.senderPublicKey : void 0,
|
|
743
|
+
expiresAt: fields.expiryTime === void 0 ? void 0 : Number(fields.expiryTime.seconds) * 1e3 + Math.floor(fields.expiryTime.nanos / 1e6)
|
|
744
|
+
};
|
|
745
|
+
}
|
|
746
|
+
function encodeInvoiceFields(invoice) {
|
|
747
|
+
const w = new BinaryWriter();
|
|
748
|
+
if (invoice.version !== 0) w.uint32(8).uint32(invoice.version);
|
|
749
|
+
const id = uuidToBytes(invoice.id);
|
|
750
|
+
w.uint32(18).bytes(id);
|
|
751
|
+
if (invoice.memo !== void 0) w.uint32(42).string(invoice.memo);
|
|
752
|
+
if (invoice.senderPublicKey !== void 0) w.uint32(50).bytes(invoice.senderPublicKey);
|
|
753
|
+
if (invoice.expiresAt !== void 0) {
|
|
754
|
+
const seconds = Math.floor(invoice.expiresAt / 1e3);
|
|
755
|
+
const timestamp = toBinary(TimestampSchema, {
|
|
756
|
+
$typeName: "google.protobuf.Timestamp",
|
|
757
|
+
seconds: BigInt(seconds),
|
|
758
|
+
nanos: (invoice.expiresAt - seconds * 1e3) * 1e6
|
|
759
|
+
});
|
|
760
|
+
w.uint32(58).bytes(timestamp);
|
|
761
|
+
}
|
|
762
|
+
const { payment } = invoice;
|
|
763
|
+
if (payment?.type === "tokens") {
|
|
764
|
+
const tokens = toBinary(TokensPaymentSchema, {
|
|
765
|
+
$typeName: "spark.TokensPayment",
|
|
766
|
+
tokenIdentifier: payment.tokenIdentifier,
|
|
767
|
+
amount: payment.amount
|
|
768
|
+
});
|
|
769
|
+
w.uint32(26).bytes(tokens);
|
|
770
|
+
} else if (payment?.type === "sats") {
|
|
771
|
+
const sats = toBinary(SatsPaymentSchema, {
|
|
772
|
+
$typeName: "spark.SatsPayment",
|
|
773
|
+
amount: payment.amount === void 0 ? void 0 : BigInt(payment.amount)
|
|
774
|
+
});
|
|
775
|
+
w.uint32(34).bytes(sats);
|
|
776
|
+
}
|
|
777
|
+
return w.finish();
|
|
778
|
+
}
|
|
779
|
+
function bigintToSafeInt(amount) {
|
|
780
|
+
if (amount < 0n || amount > BigInt(Number.MAX_SAFE_INTEGER)) throw new SparkInputError("invoice.payment.amount: does not fit a safe integer");
|
|
781
|
+
return Number(amount);
|
|
782
|
+
}
|
|
783
|
+
//#endregion
|
|
784
|
+
//#region src/core/hashing/invoice.ts
|
|
785
|
+
const PUBLIC_KEY_LENGTH = 33;
|
|
786
|
+
const TOKEN_IDENTIFIER_LENGTH = 32;
|
|
787
|
+
const MAX_TOKEN_AMOUNT_BYTES = 16;
|
|
788
|
+
function networkMagic(network) {
|
|
789
|
+
if (network === "mainnet") return 3652501241;
|
|
790
|
+
if (network === "regtest") return 3669344250;
|
|
791
|
+
throw new SparkInputError("invoice network: must be 'mainnet' or 'regtest'");
|
|
792
|
+
}
|
|
793
|
+
function hashNetworkMagic(network) {
|
|
794
|
+
return sha256(sha256(uint32be(networkMagic(network))));
|
|
795
|
+
}
|
|
796
|
+
/**
|
|
797
|
+
* The deterministic digest a Spark invoice signature covers: SHA-256 over the per-field hashes of
|
|
798
|
+
* version, id, network magic, receiver public key, the payment discriminator and contents, memo,
|
|
799
|
+
* sender public key and expiry seconds. Fields are optional at the protobuf level but have fixed
|
|
800
|
+
* defaults here (zero-filled keys, zero amounts, empty memo).
|
|
801
|
+
*/
|
|
802
|
+
function hashSparkInvoice(invoice, receiverPublicKey, network) {
|
|
803
|
+
if (invoice.version !== 1) throw new SparkInputError(`invoice.version: must be 1`);
|
|
804
|
+
requireLength(receiverPublicKey, PUBLIC_KEY_LENGTH, "receiver public key");
|
|
805
|
+
const allHashes = [
|
|
806
|
+
sha256(uint32be(invoice.version)),
|
|
807
|
+
sha256(uuidToBytes(invoice.id)),
|
|
808
|
+
hashNetworkMagic(network),
|
|
809
|
+
sha256(receiverPublicKey)
|
|
810
|
+
];
|
|
811
|
+
const { payment } = invoice;
|
|
812
|
+
if (payment === void 0) throw new SparkInputError("invoice.payment: missing payment type");
|
|
813
|
+
switch (payment.type) {
|
|
814
|
+
case "tokens": {
|
|
815
|
+
allHashes.push(sha256(new Uint8Array([1])));
|
|
816
|
+
const { tokenIdentifier } = payment;
|
|
817
|
+
if (tokenIdentifier === void 0 || tokenIdentifier.length === 0) allHashes.push(sha256(new Uint8Array(TOKEN_IDENTIFIER_LENGTH)));
|
|
818
|
+
else {
|
|
819
|
+
if (tokenIdentifier.length !== TOKEN_IDENTIFIER_LENGTH) throw new SparkInputError("invoice token identifier must be exactly 32 bytes");
|
|
820
|
+
allHashes.push(sha256(tokenIdentifier));
|
|
821
|
+
}
|
|
822
|
+
const { amount } = payment;
|
|
823
|
+
if (amount !== void 0 && amount.length > MAX_TOKEN_AMOUNT_BYTES) throw new SparkInputError("invoice token amount exceeds 16 bytes");
|
|
824
|
+
allHashes.push(sha256(amount ?? /* @__PURE__ */ new Uint8Array()));
|
|
825
|
+
break;
|
|
826
|
+
}
|
|
827
|
+
case "sats": {
|
|
828
|
+
allHashes.push(sha256(new Uint8Array([2])));
|
|
829
|
+
const sats = payment.amount;
|
|
830
|
+
if (sats !== void 0 && (!Number.isSafeInteger(sats) || sats < 0)) throw new SparkInputError("invoice sats amount must be a non-negative safe integer");
|
|
831
|
+
allHashes.push(sha256(uint64be(BigInt(sats ?? 0))));
|
|
832
|
+
break;
|
|
833
|
+
}
|
|
834
|
+
}
|
|
835
|
+
allHashes.push(sha256(invoice.memo === void 0 ? /* @__PURE__ */ new Uint8Array() : utf8ToBytes(invoice.memo)));
|
|
836
|
+
const { senderPublicKey } = invoice;
|
|
837
|
+
if (senderPublicKey === void 0 || senderPublicKey.length === 0) allHashes.push(sha256(new Uint8Array(PUBLIC_KEY_LENGTH)));
|
|
838
|
+
else {
|
|
839
|
+
if (senderPublicKey.length !== PUBLIC_KEY_LENGTH) throw new SparkInputError("invoice sender public key must be exactly 33 bytes");
|
|
840
|
+
allHashes.push(sha256(senderPublicKey));
|
|
841
|
+
}
|
|
842
|
+
let expirySeconds = 0n;
|
|
843
|
+
if (invoice.expiresAt !== void 0) {
|
|
844
|
+
const seconds = Math.floor(invoice.expiresAt / 1e3);
|
|
845
|
+
if (seconds > 0) expirySeconds = BigInt(seconds);
|
|
846
|
+
}
|
|
847
|
+
allHashes.push(sha256(uint64be(expirySeconds)));
|
|
848
|
+
const finalHasher = sha256.create();
|
|
849
|
+
for (const hash of allHashes) finalHasher.update(hash);
|
|
850
|
+
return finalHasher.digest();
|
|
851
|
+
}
|
|
852
|
+
//#endregion
|
|
853
|
+
//#region src/proto/gen/spark_authn_pb.ts
|
|
854
|
+
/**
|
|
855
|
+
* Describes the file spark_authn.proto.
|
|
856
|
+
*/
|
|
857
|
+
const file_spark_authn = /*@__PURE__*/ fileDesc("ChFzcGFya19hdXRobi5wcm90bxILc3BhcmtfYXV0aG4iUgoJQ2hhbGxlbmdlEg8KB3ZlcnNpb24YASABKAUSEQoJdGltZXN0YW1wGAIgASgDEg0KBW5vbmNlGAMgASgMEhIKCnB1YmxpY19rZXkYBCABKAwiZQoSUHJvdGVjdGVkQ2hhbGxlbmdlEg8KB3ZlcnNpb24YASABKAUSKQoJY2hhbGxlbmdlGAIgASgLMhYuc3BhcmtfYXV0aG4uQ2hhbGxlbmdlEhMKC3NlcnZlcl9obWFjGAMgASgMIikKE0dldENoYWxsZW5nZVJlcXVlc3QSEgoKcHVibGljX2tleRgBIAEoDCJUChRHZXRDaGFsbGVuZ2VSZXNwb25zZRI8ChNwcm90ZWN0ZWRfY2hhbGxlbmdlGAEgASgLMh8uc3BhcmtfYXV0aG4uUHJvdGVjdGVkQ2hhbGxlbmdlIn0KFlZlcmlmeUNoYWxsZW5nZVJlcXVlc3QSPAoTcHJvdGVjdGVkX2NoYWxsZW5nZRgBIAEoCzIfLnNwYXJrX2F1dGhuLlByb3RlY3RlZENoYWxsZW5nZRIRCglzaWduYXR1cmUYAiABKAwSEgoKcHVibGljX2tleRgDIAEoDCJOChdWZXJpZnlDaGFsbGVuZ2VSZXNwb25zZRIVCg1zZXNzaW9uX3Rva2VuGAEgASgJEhwKFGV4cGlyYXRpb25fdGltZXN0YW1wGAIgASgDMswBChFTcGFya0F1dGhuU2VydmljZRJWCg1nZXRfY2hhbGxlbmdlEiAuc3BhcmtfYXV0aG4uR2V0Q2hhbGxlbmdlUmVxdWVzdBohLnNwYXJrX2F1dGhuLkdldENoYWxsZW5nZVJlc3BvbnNlIgASXwoQdmVyaWZ5X2NoYWxsZW5nZRIjLnNwYXJrX2F1dGhuLlZlcmlmeUNoYWxsZW5nZVJlcXVlc3QaJC5zcGFya19hdXRobi5WZXJpZnlDaGFsbGVuZ2VSZXNwb25zZSIAQjJaMGdpdGh1Yi5jb20vbGlnaHRzcGFya2Rldi9zcGFyay9wcm90by9zcGFya19hdXRobmIGcHJvdG8z");
|
|
858
|
+
/**
|
|
859
|
+
* Describes the message spark_authn.Challenge.
|
|
860
|
+
* Use `create(ChallengeSchema)` to create a new message.
|
|
861
|
+
*/
|
|
862
|
+
const ChallengeSchema = /*@__PURE__*/ messageDesc(file_spark_authn, 0);
|
|
863
|
+
/**
|
|
864
|
+
* @generated from service spark_authn.SparkAuthnService
|
|
865
|
+
*/
|
|
866
|
+
const SparkAuthnService = /*@__PURE__*/ serviceDesc(file_spark_authn, 0);
|
|
867
|
+
//#endregion
|
|
868
|
+
//#region src/proto/gen/spark_token_pb.ts
|
|
869
|
+
/**
|
|
870
|
+
* Describes the file spark_token.proto.
|
|
871
|
+
*/
|
|
872
|
+
const file_spark_token = /*@__PURE__*/ fileDesc("ChFzcGFya190b2tlbi5wcm90bxILc3BhcmtfdG9rZW4iZwoSVG9rZW5PdXRwdXRUb1NwZW5kEiwKG3ByZXZfdG9rZW5fdHJhbnNhY3Rpb25faGFzaBgBIAEoDEIH+kIEegJoIBIjChtwcmV2X3Rva2VuX3RyYW5zYWN0aW9uX3ZvdXQYAiABKA0iTwoSVG9rZW5UcmFuc2ZlcklucHV0EjkKEG91dHB1dHNfdG9fc3BlbmQYASADKAsyHy5zcGFya190b2tlbi5Ub2tlbk91dHB1dFRvU3BlbmQicQoOVG9rZW5NaW50SW5wdXQSIgoRaXNzdWVyX3B1YmxpY19rZXkYASABKAxCB/pCBHoCaCESJgoQdG9rZW5faWRlbnRpZmllchgCIAEoDEIH+kIEegJoIEgAiAEBQhMKEV90b2tlbl9pZGVudGlmaWVyIswCChBUb2tlbkNyZWF0ZUlucHV0EiIKEWlzc3Vlcl9wdWJsaWNfa2V5GAEgASgMQgf6QgR6AmghEhsKCnRva2VuX25hbWUYAiABKAlCB/pCBHICGBQSHQoMdG9rZW5fdGlja2VyGAMgASgJQgf6QgRyAhgGEhoKCGRlY2ltYWxzGAQgASgNQgj6QgUqAxj/ARIbCgptYXhfc3VwcGx5GAUgASgMQgf6QgR6AmgQEhQKDGlzX2ZyZWV6YWJsZRgGIAEoCBIwChpjcmVhdGlvbl9lbnRpdHlfcHVibGljX2tleRgHIAEoDEIH+kIEegJoIUgAiAEBEiUKDmV4dHJhX21ldGFkYXRhGAggASgMQgj6QgV6AxiACEgBiAEBQh0KG19jcmVhdGlvbl9lbnRpdHlfcHVibGljX2tleUIRCg9fZXh0cmFfbWV0YWRhdGEiwAQKC1Rva2VuT3V0cHV0EhkKAmlkGAEgASgJQgj6QgVyA7ABAUgAiAEBEiEKEG93bmVyX3B1YmxpY19rZXkYAiABKAxCB/pCBHoCaCESKwoVcmV2b2NhdGlvbl9jb21taXRtZW50GAMgASgMQgf6QgR6AmghSAGIAQESHwoSd2l0aGRyYXdfYm9uZF9zYXRzGAQgASgESAKIAQESLQogd2l0aGRyYXdfcmVsYXRpdmVfYmxvY2tfbG9ja3RpbWUYBSABKARIA4gBARImChB0b2tlbl9wdWJsaWNfa2V5GAYgASgMQgf6QgR6AmghSASIAQESJgoQdG9rZW5faWRlbnRpZmllchgIIAEoDEIH+kIEegJoIEgFiAEBEh0KDHRva2VuX2Ftb3VudBgHIAEoDEIH+kIEegJoEBIkChdzZV93aXRoZHJhd2FsX3NpZ25hdHVyZRgJIAEoDEgGiAEBEjMKBnN0YXR1cxgKIAEoDjIeLnNwYXJrX3Rva2VuLlRva2VuT3V0cHV0U3RhdHVzSAeIAQFCBQoDX2lkQhgKFl9yZXZvY2F0aW9uX2NvbW1pdG1lbnRCFQoTX3dpdGhkcmF3X2JvbmRfc2F0c0IjCiFfd2l0aGRyYXdfcmVsYXRpdmVfYmxvY2tfbG9ja3RpbWVCEwoRX3Rva2VuX3B1YmxpY19rZXlCEwoRX3Rva2VuX2lkZW50aWZpZXJCGgoYX3NlX3dpdGhkcmF3YWxfc2lnbmF0dXJlQgkKB19zdGF0dXMivwEKElBhcnRpYWxUb2tlbk91dHB1dBIhChBvd25lcl9wdWJsaWNfa2V5GAEgASgMQgf6QgR6AmghEhoKEndpdGhkcmF3X2JvbmRfc2F0cxgCIAEoBBIoCiB3aXRoZHJhd19yZWxhdGl2ZV9ibG9ja19sb2NrdGltZRgDIAEoBBIhChB0b2tlbl9pZGVudGlmaWVyGAQgASgMQgf6QgR6AmggEh0KDHRva2VuX2Ftb3VudBgFIAEoDEIH+kIEegJoECJ5ChBGaW5hbFRva2VuT3V0cHV0Ej0KFHBhcnRpYWxfdG9rZW5fb3V0cHV0GAEgASgLMh8uc3BhcmtfdG9rZW4uUGFydGlhbFRva2VuT3V0cHV0EiYKFXJldm9jYXRpb25fY29tbWl0bWVudBgCIAEoDEIH+kIEegJoISKtBQoQVG9rZW5UcmFuc2FjdGlvbhIPCgd2ZXJzaW9uGAEgASgNEjEKCm1pbnRfaW5wdXQYAiABKAsyGy5zcGFya190b2tlbi5Ub2tlbk1pbnRJbnB1dEgAEjkKDnRyYW5zZmVyX2lucHV0GAMgASgLMh8uc3BhcmtfdG9rZW4uVG9rZW5UcmFuc2ZlcklucHV0SAASNQoMY3JlYXRlX2lucHV0GAggASgLMh0uc3BhcmtfdG9rZW4uVG9rZW5DcmVhdGVJbnB1dEgAEi8KDXRva2VuX291dHB1dHMYBCADKAsyGC5zcGFya190b2tlbi5Ub2tlbk91dHB1dBI5CiNzcGFya19vcGVyYXRvcl9pZGVudGl0eV9wdWJsaWNfa2V5cxgFIAMoDEIM+kIJkgEGIgR6AmghEi8KC2V4cGlyeV90aW1lGAYgASgLMhouZ29vZ2xlLnByb3RvYnVmLlRpbWVzdGFtcBIpCgduZXR3b3JrGAcgASgOMg4uc3BhcmsuTmV0d29ya0II+kIFggECIAASPAoYY2xpZW50X2NyZWF0ZWRfdGltZXN0YW1wGAkgASgLMhouZ29vZ2xlLnByb3RvYnVmLlRpbWVzdGFtcBI7ChNpbnZvaWNlX2F0dGFjaG1lbnRzGAogAygLMh4uc3BhcmtfdG9rZW4uSW52b2ljZUF0dGFjaG1lbnQSJgoZdmFsaWRpdHlfZHVyYXRpb25fc2Vjb25kcxgLIAEoBEgBiAEBEjcKDmV4ZWN1dGVfYmVmb3JlGAwgASgLMhouZ29vZ2xlLnByb3RvYnVmLlRpbWVzdGFtcEgCiAEBQg4KDHRva2VuX2lucHV0c0IcChpfdmFsaWRpdHlfZHVyYXRpb25fc2Vjb25kc0IRCg9fZXhlY3V0ZV9iZWZvcmUiqgIKGFRva2VuVHJhbnNhY3Rpb25NZXRhZGF0YRI5CiNzcGFya19vcGVyYXRvcl9pZGVudGl0eV9wdWJsaWNfa2V5cxgCIAMoDEIM+kIJkgEGIgR6AmghEikKB25ldHdvcmsYAyABKA4yDi5zcGFyay5OZXR3b3JrQgj6QgWCAQIgABI8ChhjbGllbnRfY3JlYXRlZF90aW1lc3RhbXAYBCABKAsyGi5nb29nbGUucHJvdG9idWYuVGltZXN0YW1wEi0KGXZhbGlkaXR5X2R1cmF0aW9uX3NlY29uZHMYBSABKARCCvpCBzIFGKwCKAESOwoTaW52b2ljZV9hdHRhY2htZW50cxgGIAMoCzIeLnNwYXJrX3Rva2VuLkludm9pY2VBdHRhY2htZW50IrYDChdQYXJ0aWFsVG9rZW5UcmFuc2FjdGlvbhIPCgd2ZXJzaW9uGAEgASgNEkkKGnRva2VuX3RyYW5zYWN0aW9uX21ldGFkYXRhGAIgASgLMiUuc3BhcmtfdG9rZW4uVG9rZW5UcmFuc2FjdGlvbk1ldGFkYXRhEjEKCm1pbnRfaW5wdXQYAyABKAsyGy5zcGFya190b2tlbi5Ub2tlbk1pbnRJbnB1dEgAEjkKDnRyYW5zZmVyX2lucHV0GAQgASgLMh8uc3BhcmtfdG9rZW4uVG9rZW5UcmFuc2ZlcklucHV0SAASNQoMY3JlYXRlX2lucHV0GAUgASgLMh0uc3BhcmtfdG9rZW4uVG9rZW5DcmVhdGVJbnB1dEgAEj4KFXBhcnRpYWxfdG9rZW5fb3V0cHV0cxgGIAMoCzIfLnNwYXJrX3Rva2VuLlBhcnRpYWxUb2tlbk91dHB1dBI3Cg5leGVjdXRlX2JlZm9yZRgHIAEoCzIaLmdvb2dsZS5wcm90b2J1Zi5UaW1lc3RhbXBIAYgBAUIOCgx0b2tlbl9pbnB1dHNCEQoPX2V4ZWN1dGVfYmVmb3JlIrADChVGaW5hbFRva2VuVHJhbnNhY3Rpb24SDwoHdmVyc2lvbhgBIAEoDRJJChp0b2tlbl90cmFuc2FjdGlvbl9tZXRhZGF0YRgCIAEoCzIlLnNwYXJrX3Rva2VuLlRva2VuVHJhbnNhY3Rpb25NZXRhZGF0YRIxCgptaW50X2lucHV0GAMgASgLMhsuc3BhcmtfdG9rZW4uVG9rZW5NaW50SW5wdXRIABI5Cg50cmFuc2Zlcl9pbnB1dBgEIAEoCzIfLnNwYXJrX3Rva2VuLlRva2VuVHJhbnNmZXJJbnB1dEgAEjUKDGNyZWF0ZV9pbnB1dBgFIAEoCzIdLnNwYXJrX3Rva2VuLlRva2VuQ3JlYXRlSW5wdXRIABI6ChNmaW5hbF90b2tlbl9vdXRwdXRzGAYgAygLMh0uc3BhcmtfdG9rZW4uRmluYWxUb2tlbk91dHB1dBI3Cg5leGVjdXRlX2JlZm9yZRgHIAEoCzIaLmdvb2dsZS5wcm90b2J1Zi5UaW1lc3RhbXBIAYgBAUIOCgx0b2tlbl9pbnB1dHNCEQoPX2V4ZWN1dGVfYmVmb3JlIioKEUludm9pY2VBdHRhY2htZW50EhUKDXNwYXJrX2ludm9pY2UYASABKAkicgoSQWxsb3dhbmNlU2lnbmF0dXJlEh0KDGFsbG93YW5jZV9pZBgBIAEoDEIH+kIEegJoEBI9ChFzcGVuZGVyX3NpZ25hdHVyZRgCIAEoCzIYLm11bHRpc2lnLktleWVkU2lnbmF0dXJlQgj6QgWKAQIQASKpAgoSU2lnbmF0dXJlV2l0aEluZGV4EiMKCXNpZ25hdHVyZRgBIAEoDEIL+kIIegYQQBhJcAFIAYgBARITCgtpbnB1dF9pbmRleBgCIAEoDRI0ChBzaW5nbGVfc2lnbmF0dXJlGAMgASgLMhgubXVsdGlzaWcuS2V5ZWRTaWduYXR1cmVIABI9ChNtdWx0aXNpZ19zaWduYXR1cmVzGAQgASgLMh4ubXVsdGlzaWcuTXVsdGlzaWdTaWduYXR1cmVTZXRIABI+ChNhbGxvd2FuY2Vfc2lnbmF0dXJlGAUgASgLMh8uc3BhcmtfdG9rZW4uQWxsb3dhbmNlU2lnbmF0dXJlSABCFgoUYXV0aG9yaXR5X3NpZ25hdHVyZXNCDAoKX3NpZ25hdHVyZSKJAQoeSW5wdXRUdHhvU2lnbmF0dXJlc1Blck9wZXJhdG9yEjgKD3R0eG9fc2lnbmF0dXJlcxgBIAMoCzIfLnNwYXJrX3Rva2VuLlNpZ25hdHVyZVdpdGhJbmRleBItChxvcGVyYXRvcl9pZGVudGl0eV9wdWJsaWNfa2V5GAIgASgMQgf6QgR6AmghIoUCChdTdGFydFRyYW5zYWN0aW9uUmVxdWVzdBIkChNpZGVudGl0eV9wdWJsaWNfa2V5GAEgASgMQgf6QgR6AmghEkAKGXBhcnRpYWxfdG9rZW5fdHJhbnNhY3Rpb24YAiABKAsyHS5zcGFya190b2tlbi5Ub2tlblRyYW5zYWN0aW9uElMKKnBhcnRpYWxfdG9rZW5fdHJhbnNhY3Rpb25fb3duZXJfc2lnbmF0dXJlcxgDIAMoCzIfLnNwYXJrX3Rva2VuLlNpZ25hdHVyZVdpdGhJbmRleBItChl2YWxpZGl0eV9kdXJhdGlvbl9zZWNvbmRzGAQgASgEQgr6QgcyBRisAigBIokBChhTdGFydFRyYW5zYWN0aW9uUmVzcG9uc2USPgoXZmluYWxfdG9rZW5fdHJhbnNhY3Rpb24YASABKAsyHS5zcGFya190b2tlbi5Ub2tlblRyYW5zYWN0aW9uEi0KDWtleXNoYXJlX2luZm8YAiABKAsyFi5zcGFyay5TaWduaW5nS2V5c2hhcmUijgIKGENvbW1pdFRyYW5zYWN0aW9uUmVxdWVzdBI+ChdmaW5hbF90b2tlbl90cmFuc2FjdGlvbhgBIAEoCzIdLnNwYXJrX3Rva2VuLlRva2VuVHJhbnNhY3Rpb24SLQocZmluYWxfdG9rZW5fdHJhbnNhY3Rpb25faGFzaBgCIAEoDEIH+kIEegJoIBJXCiJpbnB1dF90dHhvX3NpZ25hdHVyZXNfcGVyX29wZXJhdG9yGAMgAygLMisuc3BhcmtfdG9rZW4uSW5wdXRUdHhvU2lnbmF0dXJlc1Blck9wZXJhdG9yEioKGW93bmVyX2lkZW50aXR5X3B1YmxpY19rZXkYBCABKAxCB/pCBHoCaCEifgoOQ29tbWl0UHJvZ3Jlc3MSNAoeY29tbWl0dGVkX29wZXJhdG9yX3B1YmxpY19rZXlzGAEgAygMQgz6QgmSAQYiBHoCaCESNgogdW5jb21taXR0ZWRfb3BlcmF0b3JfcHVibGljX2tleXMYAiADKAxCDPpCCZIBBiIEegJoISLAAQoZQ29tbWl0VHJhbnNhY3Rpb25SZXNwb25zZRIwCg1jb21taXRfc3RhdHVzGAEgASgOMhkuc3BhcmtfdG9rZW4uQ29tbWl0U3RhdHVzEjQKD2NvbW1pdF9wcm9ncmVzcxgCIAEoCzIbLnNwYXJrX3Rva2VuLkNvbW1pdFByb2dyZXNzEiYKEHRva2VuX2lkZW50aWZpZXIYAyABKAxCB/pCBHoCaCBIAIgBAUITChFfdG9rZW5faWRlbnRpZmllciLZAQobQnJvYWRjYXN0VHJhbnNhY3Rpb25SZXF1ZXN0EiQKE2lkZW50aXR5X3B1YmxpY19rZXkYASABKAxCB/pCBHoCaCESRwoZcGFydGlhbF90b2tlbl90cmFuc2FjdGlvbhgCIAEoCzIkLnNwYXJrX3Rva2VuLlBhcnRpYWxUb2tlblRyYW5zYWN0aW9uEksKInRva2VuX3RyYW5zYWN0aW9uX293bmVyX3NpZ25hdHVyZXMYAyADKAsyHy5zcGFya190b2tlbi5TaWduYXR1cmVXaXRoSW5kZXgiiAIKHEJyb2FkY2FzdFRyYW5zYWN0aW9uUmVzcG9uc2USQwoXZmluYWxfdG9rZW5fdHJhbnNhY3Rpb24YASABKAsyIi5zcGFya190b2tlbi5GaW5hbFRva2VuVHJhbnNhY3Rpb24SMAoNY29tbWl0X3N0YXR1cxgCIAEoDjIZLnNwYXJrX3Rva2VuLkNvbW1pdFN0YXR1cxI0Cg9jb21taXRfcHJvZ3Jlc3MYAyABKAsyGy5zcGFya190b2tlbi5Db21taXRQcm9ncmVzcxImChB0b2tlbl9pZGVudGlmaWVyGAQgASgMQgf6QgR6AmggSACIAQFCEwoRX3Rva2VuX2lkZW50aWZpZXIibgoZUXVlcnlUb2tlbk1ldGFkYXRhUmVxdWVzdBInChF0b2tlbl9pZGVudGlmaWVycxgBIAMoDEIM+kIJkgEGIgR6AmggEigKEmlzc3Vlcl9wdWJsaWNfa2V5cxgCIAMoDEIM+kIJkgEGIgR6AmghIuwCCg1Ub2tlbk1ldGFkYXRhEiIKEWlzc3Vlcl9wdWJsaWNfa2V5GAEgASgMQgf6QgR6AmghEhsKCnRva2VuX25hbWUYAiABKAlCB/pCBHICGBQSHQoMdG9rZW5fdGlja2VyGAMgASgJQgf6QgRyAhgGEhoKCGRlY2ltYWxzGAQgASgNQgj6QgUqAxj/ARIbCgptYXhfc3VwcGx5GAUgASgMQgf6QgR6AmgQEhQKDGlzX2ZyZWV6YWJsZRgGIAEoCBIwChpjcmVhdGlvbl9lbnRpdHlfcHVibGljX2tleRgHIAEoDEIH+kIEegJoIUgAiAEBEiEKEHRva2VuX2lkZW50aWZpZXIYCCABKAxCB/pCBHoCaCASJQoOZXh0cmFfbWV0YWRhdGEYCSABKAxCCPpCBXoDGIAISAGIAQFCHQobX2NyZWF0aW9uX2VudGl0eV9wdWJsaWNfa2V5QhEKD19leHRyYV9tZXRhZGF0YSJQChpRdWVyeVRva2VuTWV0YWRhdGFSZXNwb25zZRIyCg50b2tlbl9tZXRhZGF0YRgBIAMoCzIaLnNwYXJrX3Rva2VuLlRva2VuTWV0YWRhdGEi4QEKGFF1ZXJ5VG9rZW5PdXRwdXRzUmVxdWVzdBInChFvd25lcl9wdWJsaWNfa2V5cxgBIAMoDEIM+kIJkgEGIgR6AmghEigKEmlzc3Vlcl9wdWJsaWNfa2V5cxgCIAMoDEIM+kIJkgEGIgR6AmghEicKEXRva2VuX2lkZW50aWZpZXJzGAQgAygMQgz6QgmSAQYiBHoCaCASHwoHbmV0d29yaxgDIAEoDjIOLnNwYXJrLk5ldHdvcmsSKAoMcGFnZV9yZXF1ZXN0GAUgASgLMhIuc3BhcmsuUGFnZVJlcXVlc3Qi1AMKHVF1ZXJ5VG9rZW5UcmFuc2FjdGlvbnNSZXF1ZXN0EkEKCmJ5X3R4X2hhc2gYCSABKAsyKy5zcGFya190b2tlbi5RdWVyeVRva2VuVHJhbnNhY3Rpb25zQnlUeEhhc2hIABJCCgpieV9maWx0ZXJzGAogASgLMiwuc3BhcmtfdG9rZW4uUXVlcnlUb2tlblRyYW5zYWN0aW9uc0J5RmlsdGVyc0gAEiEKCm91dHB1dF9pZHMYASADKAlCDfpCCpIBByIFcgOwAQESJwoRb3duZXJfcHVibGljX2tleXMYAiADKAxCDPpCCZIBBiIEegJoIRIoChJpc3N1ZXJfcHVibGljX2tleXMYAyADKAxCDPpCCZIBBiIEegJoIRInChF0b2tlbl9pZGVudGlmaWVycxgHIAMoDEIM+kIJkgEGIgR6AmggEi4KGHRva2VuX3RyYW5zYWN0aW9uX2hhc2hlcxgEIAMoDEIM+kIJkgEGIgR6AmggEhsKBW9yZGVyGAggASgOMgwuc3BhcmsuT3JkZXISGQoFbGltaXQYBSABKANCCvpCByIFGOgHKAASFwoGb2Zmc2V0GAYgASgDQgf6QgQiAigAQgwKCnF1ZXJ5X3R5cGUiUgoeUXVlcnlUb2tlblRyYW5zYWN0aW9uc0J5VHhIYXNoEjAKGHRva2VuX3RyYW5zYWN0aW9uX2hhc2hlcxgBIAMoDEIO+kILkgEICAEiBHoCaCAi6gEKH1F1ZXJ5VG9rZW5UcmFuc2FjdGlvbnNCeUZpbHRlcnMSIQoKb3V0cHV0X2lkcxgBIAMoCUIN+kIKkgEHIgVyA7ABARInChFvd25lcl9wdWJsaWNfa2V5cxgCIAMoDEIM+kIJkgEGIgR6AmghEigKEmlzc3Vlcl9wdWJsaWNfa2V5cxgDIAMoDEIM+kIJkgEGIgR6AmghEicKEXRva2VuX2lkZW50aWZpZXJzGAQgAygMQgz6QgmSAQYiBHoCaCASKAoMcGFnZV9yZXF1ZXN0GAUgASgLMhIuc3BhcmsuUGFnZVJlcXVlc3QirQEKHlF1ZXJ5VG9rZW5UcmFuc2FjdGlvbnNSZXNwb25zZRJPCh50b2tlbl90cmFuc2FjdGlvbnNfd2l0aF9zdGF0dXMYASADKAsyJy5zcGFya190b2tlbi5Ub2tlblRyYW5zYWN0aW9uV2l0aFN0YXR1cxIOCgZvZmZzZXQYAiABKAMSKgoNcGFnZV9yZXNwb25zZRgDIAEoCzITLnNwYXJrLlBhZ2VSZXNwb25zZSKcAQohT3V0cHV0V2l0aFByZXZpb3VzVHJhbnNhY3Rpb25EYXRhEigKBm91dHB1dBgBIAEoCzIYLnNwYXJrX3Rva2VuLlRva2VuT3V0cHV0EioKGXByZXZpb3VzX3RyYW5zYWN0aW9uX2hhc2gYAiABKAxCB/pCBHoCaCASIQoZcHJldmlvdXNfdHJhbnNhY3Rpb25fdm91dBgDIAEoDSKnAQoZUXVlcnlUb2tlbk91dHB1dHNSZXNwb25zZRJeCiZvdXRwdXRzX3dpdGhfcHJldmlvdXNfdHJhbnNhY3Rpb25fZGF0YRgBIAMoCzIuLnNwYXJrX3Rva2VuLk91dHB1dFdpdGhQcmV2aW91c1RyYW5zYWN0aW9uRGF0YRIqCg1wYWdlX3Jlc3BvbnNlGAIgASgLMhMuc3BhcmsuUGFnZVJlc3BvbnNlIkgKGFNwZW50VG9rZW5PdXRwdXRNZXRhZGF0YRIRCglvdXRwdXRfaWQYASABKAkSGQoRcmV2b2NhdGlvbl9zZWNyZXQYAiABKAwicwokVG9rZW5UcmFuc2FjdGlvbkNvbmZpcm1hdGlvbk1ldGFkYXRhEksKHHNwZW50X3Rva2VuX291dHB1dHNfbWV0YWRhdGEYASADKAsyJS5zcGFya190b2tlbi5TcGVudFRva2VuT3V0cHV0TWV0YWRhdGEihgIKGlRva2VuVHJhbnNhY3Rpb25XaXRoU3RhdHVzEjgKEXRva2VuX3RyYW5zYWN0aW9uGAEgASgLMh0uc3BhcmtfdG9rZW4uVG9rZW5UcmFuc2FjdGlvbhIzCgZzdGF0dXMYAiABKA4yIy5zcGFya190b2tlbi5Ub2tlblRyYW5zYWN0aW9uU3RhdHVzElAKFWNvbmZpcm1hdGlvbl9tZXRhZGF0YRgDIAEoCzIxLnNwYXJrX3Rva2VuLlRva2VuVHJhbnNhY3Rpb25Db25maXJtYXRpb25NZXRhZGF0YRInChZ0b2tlbl90cmFuc2FjdGlvbl9oYXNoGAQgASgMQgf6QgR6AmggIsgCChNGcmVlemVUb2tlbnNQYXlsb2FkEg8KB3ZlcnNpb24YASABKA0SJgoQb3duZXJfcHVibGljX2tleRgCIAEoDEIH+kIEegJoIUgAiAEBEiYKEHRva2VuX3B1YmxpY19rZXkYAyABKAxCB/pCBHoCaCFIAYgBARImChB0b2tlbl9pZGVudGlmaWVyGAQgASgMQgf6QgR6AmggSAKIAQESIQoZaXNzdWVyX3Byb3ZpZGVkX3RpbWVzdGFtcBgFIAEoBBItChxvcGVyYXRvcl9pZGVudGl0eV9wdWJsaWNfa2V5GAYgASgMQgf6QgR6AmghEhcKD3Nob3VsZF91bmZyZWV6ZRgHIAEoCEITChFfb3duZXJfcHVibGljX2tleUITChFfdG9rZW5fcHVibGljX2tleUITChFfdG9rZW5faWRlbnRpZmllciJ7ChNGcmVlemVUb2tlbnNSZXF1ZXN0Ej8KFWZyZWV6ZV90b2tlbnNfcGF5bG9hZBgBIAEoCzIgLnNwYXJrX3Rva2VuLkZyZWV6ZVRva2Vuc1BheWxvYWQSIwoQaXNzdWVyX3NpZ25hdHVyZRgCIAEoDEIJ+kIGegQQQBhJIkEKDlRva2VuT3V0cHV0UmVmEiEKEHRyYW5zYWN0aW9uX2hhc2gYASABKAxCB/pCBHoCaCASDAoEdm91dBgCIAEoDSJECg5GcmVlemVQcm9ncmVzcxIyChxhcHBsaWVkX29wZXJhdG9yX3B1YmxpY19rZXlzGAEgAygMQgz6QgmSAQYiBHoCaCEi1gEKFEZyZWV6ZVRva2Vuc1Jlc3BvbnNlEiwKE2ltcGFjdGVkX291dHB1dF9pZHMYASADKAlCDxgB+kIKkgEHIgVyA7ABARIdChVpbXBhY3RlZF90b2tlbl9hbW91bnQYAiABKAwSOwoWaW1wYWN0ZWRfdG9rZW5fb3V0cHV0cxgDIAMoCzIbLnNwYXJrX3Rva2VuLlRva2VuT3V0cHV0UmVmEjQKD2ZyZWV6ZV9wcm9ncmVzcxgEIAEoCzIbLnNwYXJrX3Rva2VuLkZyZWV6ZVByb2dyZXNzIt4DChVUb2tlbkFsbG93YW5jZVBheWxvYWQSDwoHdmVyc2lvbhgBIAEoDRIdCgxhbGxvd2FuY2VfaWQYAiABKAxCB/pCBHoCaBASIQoQb3duZXJfcHVibGljX2tleRgDIAEoDEIH+kIEegJoIRIjChJzcGVuZGVyX3B1YmxpY19rZXkYBCABKAxCB/pCBHoCaCESIQoQdG9rZW5faWRlbnRpZmllchgFIAEoDEIH+kIEegJoIBIkChNwZXJfdHJhbnNhY3Rpb25fY2FwGAYgASgMQgf6QgR6AmgQEhwKC3RvdGFsX2xpbWl0GAcgASgMQgf6QgR6AmgQEiwKE3JlY2lwaWVudF9hbGxvd2xpc3QYCCADKAxCD/pCDJIBCRCAAiIEegJoIRIvCgtleHBpcnlfdGltZRgJIAEoCzIaLmdvb2dsZS5wcm90b2J1Zi5UaW1lc3RhbXASKQoHbmV0d29yaxgNIAEoDjIOLnNwYXJrLk5ldHdvcmtCCPpCBYIBAiAAEiAKGG93bmVyX3Byb3ZpZGVkX3RpbWVzdGFtcBgOIAEoBBIhChlwZXJfdHJhbnNhY3Rpb25fdW5saW1pdGVkGA8gASgIEhcKD3RvdGFsX3VubGltaXRlZBgQIAEoCCKAAQobQ3JlYXRlVG9rZW5BbGxvd2FuY2VSZXF1ZXN0Ej0KEWFsbG93YW5jZV9wYXlsb2FkGAEgASgLMiIuc3BhcmtfdG9rZW4uVG9rZW5BbGxvd2FuY2VQYXlsb2FkEiIKD293bmVyX3NpZ25hdHVyZRgCIAEoDEIJ+kIGegQQQBhJIkcKEUFsbG93YW5jZVByb2dyZXNzEjIKHGFwcGxpZWRfb3BlcmF0b3JfcHVibGljX2tleXMYASADKAxCDPpCCZIBBiIEegJoISJSChxDcmVhdGVUb2tlbkFsbG93YW5jZVJlc3BvbnNlEjIKCWFsbG93YW5jZRgBIAEoCzIfLnNwYXJrX3Rva2VuLlRva2VuQWxsb3dhbmNlSW5mbyKSAQobUmV2b2tlVG9rZW5BbGxvd2FuY2VQYXlsb2FkEg8KB3ZlcnNpb24YASABKA0SHQoMYWxsb3dhbmNlX2lkGAIgASgMQgf6QgR6AmgQEiEKEG93bmVyX3B1YmxpY19rZXkYAyABKAxCB/pCBHoCaCESIAoYb3duZXJfcHJvdmlkZWRfdGltZXN0YW1wGAQgASgEIo0BChtSZXZva2VUb2tlbkFsbG93YW5jZVJlcXVlc3QSSgoYcmV2b2tlX2FsbG93YW5jZV9wYXlsb2FkGAEgASgLMiguc3BhcmtfdG9rZW4uUmV2b2tlVG9rZW5BbGxvd2FuY2VQYXlsb2FkEiIKD293bmVyX3NpZ25hdHVyZRgCIAEoDEIJ+kIGegQQQBhJIloKHFJldm9rZVRva2VuQWxsb3dhbmNlUmVzcG9uc2USOgoSYWxsb3dhbmNlX3Byb2dyZXNzGAEgASgLMh4uc3BhcmtfdG9rZW4uQWxsb3dhbmNlUHJvZ3Jlc3MikAIKElRva2VuQWxsb3dhbmNlSW5mbxI9ChFhbGxvd2FuY2VfcGF5bG9hZBgBIAEoCzIiLnNwYXJrX3Rva2VuLlRva2VuQWxsb3dhbmNlUGF5bG9hZBIUCgxzcGVudF9hbW91bnQYAiABKAwSMQoGc3RhdHVzGAMgASgOMiEuc3BhcmtfdG9rZW4uVG9rZW5BbGxvd2FuY2VTdGF0dXMSFwoPb3duZXJfc2lnbmF0dXJlGAQgASgMEhgKEHJldm9rZV9zaWduYXR1cmUYBSABKAwSJwofb3duZXJfcHJvdmlkZWRfcmV2b2tlX3RpbWVzdGFtcBgGIAEoBBIWCg5yZXZva2VfdmVyc2lvbhgHIAEoDSKRAgobUXVlcnlUb2tlbkFsbG93YW5jZXNSZXF1ZXN0EiYKEG93bmVyX3B1YmxpY19rZXkYASABKAxCB/pCBHoCaCFIAIgBARIoChJzcGVuZGVyX3B1YmxpY19rZXkYAiABKAxCB/pCBHoCaCFIAYgBARImChB0b2tlbl9pZGVudGlmaWVyGAMgASgMQgf6QgR6AmggSAKIAQESGAoQaW5jbHVkZV9pbmFjdGl2ZRgEIAEoCBINCgVsaW1pdBgFIAEoAxIOCgZvZmZzZXQYBiABKANCEwoRX293bmVyX3B1YmxpY19rZXlCFQoTX3NwZW5kZXJfcHVibGljX2tleUITChFfdG9rZW5faWRlbnRpZmllciJjChxRdWVyeVRva2VuQWxsb3dhbmNlc1Jlc3BvbnNlEjMKCmFsbG93YW5jZXMYASADKAsyHy5zcGFya190b2tlbi5Ub2tlbkFsbG93YW5jZUluZm8SDgoGb2Zmc2V0GAIgASgDKoUBChFUb2tlbk91dHB1dFN0YXR1cxIjCh9UT0tFTl9PVVRQVVRfU1RBVFVTX1VOU1BFQ0lGSUVEEAASIQodVE9LRU5fT1VUUFVUX1NUQVRVU19BVkFJTEFCTEUQARIoCiRUT0tFTl9PVVRQVVRfU1RBVFVTX1BFTkRJTkdfT1VUQk9VTkQQAiqnAQoUVG9rZW5UcmFuc2FjdGlvblR5cGUSJgoiVE9LRU5fVFJBTlNBQ1RJT05fVFlQRV9VTlNQRUNJRklFRBAAEiEKHVRPS0VOX1RSQU5TQUNUSU9OX1RZUEVfQ1JFQVRFEAESHwobVE9LRU5fVFJBTlNBQ1RJT05fVFlQRV9NSU5UEAISIwofVE9LRU5fVFJBTlNBQ1RJT05fVFlQRV9UUkFOU0ZFUhADKlMKDENvbW1pdFN0YXR1cxIWChJDT01NSVRfVU5TUEVDSUZJRUQQABIVChFDT01NSVRfUFJPQ0VTU0lORxABEhQKEENPTU1JVF9GSU5BTElaRUQQAiqGAgoWVG9rZW5UcmFuc2FjdGlvblN0YXR1cxIdChlUT0tFTl9UUkFOU0FDVElPTl9TVEFSVEVEEAASHAoYVE9LRU5fVFJBTlNBQ1RJT05fU0lHTkVEEAESHgoaVE9LRU5fVFJBTlNBQ1RJT05fUkVWRUFMRUQQBRIfChtUT0tFTl9UUkFOU0FDVElPTl9GSU5BTElaRUQQAhInCiNUT0tFTl9UUkFOU0FDVElPTl9TVEFSVEVEX0NBTkNFTExFRBADEiYKIlRPS0VOX1RSQU5TQUNUSU9OX1NJR05FRF9DQU5DRUxMRUQQBBIdChlUT0tFTl9UUkFOU0FDVElPTl9VTktOT1dOEAoqzwEKFFRva2VuQWxsb3dhbmNlU3RhdHVzEiYKIlRPS0VOX0FMTE9XQU5DRV9TVEFUVVNfVU5TUEVDSUZJRUQQABIhCh1UT0tFTl9BTExPV0FOQ0VfU1RBVFVTX0FDVElWRRABEiIKHlRPS0VOX0FMTE9XQU5DRV9TVEFUVVNfUkVWT0tFRBACEiQKIFRPS0VOX0FMTE9XQU5DRV9TVEFUVVNfRVhIQVVTVEVEEAMSIgoeVE9LRU5fQUxMT1dBTkNFX1NUQVRVU19FWFBJUkVEEAQywwgKEVNwYXJrVG9rZW5TZXJ2aWNlEmIKEXN0YXJ0X3RyYW5zYWN0aW9uEiQuc3BhcmtfdG9rZW4uU3RhcnRUcmFuc2FjdGlvblJlcXVlc3QaJS5zcGFya190b2tlbi5TdGFydFRyYW5zYWN0aW9uUmVzcG9uc2UiABJlChJjb21taXRfdHJhbnNhY3Rpb24SJS5zcGFya190b2tlbi5Db21taXRUcmFuc2FjdGlvblJlcXVlc3QaJi5zcGFya190b2tlbi5Db21taXRUcmFuc2FjdGlvblJlc3BvbnNlIgASaQoUcXVlcnlfdG9rZW5fbWV0YWRhdGESJi5zcGFya190b2tlbi5RdWVyeVRva2VuTWV0YWRhdGFSZXF1ZXN0Gicuc3BhcmtfdG9rZW4uUXVlcnlUb2tlbk1ldGFkYXRhUmVzcG9uc2UiABJ1ChhxdWVyeV90b2tlbl90cmFuc2FjdGlvbnMSKi5zcGFya190b2tlbi5RdWVyeVRva2VuVHJhbnNhY3Rpb25zUmVxdWVzdBorLnNwYXJrX3Rva2VuLlF1ZXJ5VG9rZW5UcmFuc2FjdGlvbnNSZXNwb25zZSIAEmYKE3F1ZXJ5X3Rva2VuX291dHB1dHMSJS5zcGFya190b2tlbi5RdWVyeVRva2VuT3V0cHV0c1JlcXVlc3QaJi5zcGFya190b2tlbi5RdWVyeVRva2VuT3V0cHV0c1Jlc3BvbnNlIgASVgoNZnJlZXplX3Rva2VucxIgLnNwYXJrX3Rva2VuLkZyZWV6ZVRva2Vuc1JlcXVlc3QaIS5zcGFya190b2tlbi5GcmVlemVUb2tlbnNSZXNwb25zZSIAEm4KFWJyb2FkY2FzdF90cmFuc2FjdGlvbhIoLnNwYXJrX3Rva2VuLkJyb2FkY2FzdFRyYW5zYWN0aW9uUmVxdWVzdBopLnNwYXJrX3Rva2VuLkJyb2FkY2FzdFRyYW5zYWN0aW9uUmVzcG9uc2UiABJvChZjcmVhdGVfdG9rZW5fYWxsb3dhbmNlEiguc3BhcmtfdG9rZW4uQ3JlYXRlVG9rZW5BbGxvd2FuY2VSZXF1ZXN0Gikuc3BhcmtfdG9rZW4uQ3JlYXRlVG9rZW5BbGxvd2FuY2VSZXNwb25zZSIAEm8KFnJldm9rZV90b2tlbl9hbGxvd2FuY2USKC5zcGFya190b2tlbi5SZXZva2VUb2tlbkFsbG93YW5jZVJlcXVlc3QaKS5zcGFya190b2tlbi5SZXZva2VUb2tlbkFsbG93YW5jZVJlc3BvbnNlIgASbwoWcXVlcnlfdG9rZW5fYWxsb3dhbmNlcxIoLnNwYXJrX3Rva2VuLlF1ZXJ5VG9rZW5BbGxvd2FuY2VzUmVxdWVzdBopLnNwYXJrX3Rva2VuLlF1ZXJ5VG9rZW5BbGxvd2FuY2VzUmVzcG9uc2UiAEIyWjBnaXRodWIuY29tL2xpZ2h0c3BhcmtkZXYvc3BhcmsvcHJvdG8vc3BhcmtfdG9rZW5iBnByb3RvMw", [
|
|
873
|
+
file_google_protobuf_timestamp,
|
|
874
|
+
/* @__PURE__ */ fileDesc("Cg5tdWx0aXNpZy5wcm90bxIIbXVsdGlzaWciYgoOTXVsdGlzaWdDb25maWcSDwoHdmVyc2lvbhgBIAEoDRIaCgl0aHJlc2hvbGQYAiABKA1CB/pCBCoCKAESIwoLcHVibGljX2tleXMYAyADKAxCDvpCC5IBCAgCIgR6AmghIksKDktleWVkU2lnbmF0dXJlEhsKCnB1YmxpY19rZXkYASABKAxCB/pCBHoCaCESHAoJc2lnbmF0dXJlGAIgASgMQgn6QgZ6BBBAGEkigQEKFE11bHRpc2lnU2lnbmF0dXJlU2V0EjsKD211bHRpc2lnX2NvbmZpZxgBIAEoCzIYLm11bHRpc2lnLk11bHRpc2lnQ29uZmlnQgj6QgWKAQIQARIsCgpzaWduYXR1cmVzGAIgAygLMhgubXVsdGlzaWcuS2V5ZWRTaWduYXR1cmUibAoQU2lnbmluZ0F1dGhvcml0eRIdCgpwdWJsaWNfa2V5GAEgASgMQgf6QgR6AmghSAASLAoIbXVsdGlzaWcYAiABKAsyGC5tdWx0aXNpZy5NdWx0aXNpZ0NvbmZpZ0gAQgsKCWF1dGhvcml0eUIvWi1naXRodWIuY29tL2xpZ2h0c3BhcmtkZXYvc3BhcmsvcHJvdG8vbXVsdGlzaWdiBnByb3RvMw", [file_validate_validate]),
|
|
875
|
+
file_spark,
|
|
876
|
+
file_validate_validate
|
|
877
|
+
]);
|
|
878
|
+
/**
|
|
879
|
+
* Describes the message spark_token.PartialTokenOutput.
|
|
880
|
+
* Use `create(PartialTokenOutputSchema)` to create a new message.
|
|
881
|
+
*/
|
|
882
|
+
const PartialTokenOutputSchema = /*@__PURE__*/ messageDesc(file_spark_token, 5);
|
|
883
|
+
/**
|
|
884
|
+
* Describes the message spark_token.TokenTransactionMetadata.
|
|
885
|
+
* Use `create(TokenTransactionMetadataSchema)` to create a new message.
|
|
886
|
+
*/
|
|
887
|
+
const TokenTransactionMetadataSchema = /*@__PURE__*/ messageDesc(file_spark_token, 8);
|
|
888
|
+
/**
|
|
889
|
+
* Describes the message spark_token.PartialTokenTransaction.
|
|
890
|
+
* Use `create(PartialTokenTransactionSchema)` to create a new message.
|
|
891
|
+
*/
|
|
892
|
+
const PartialTokenTransactionSchema = /*@__PURE__*/ messageDesc(file_spark_token, 9);
|
|
893
|
+
/**
|
|
894
|
+
* Describes the message spark_token.FinalTokenTransaction.
|
|
895
|
+
* Use `create(FinalTokenTransactionSchema)` to create a new message.
|
|
896
|
+
*/
|
|
897
|
+
const FinalTokenTransactionSchema = /*@__PURE__*/ messageDesc(file_spark_token, 10);
|
|
898
|
+
/**
|
|
899
|
+
* Describes the message spark_token.InvoiceAttachment.
|
|
900
|
+
* Use `create(InvoiceAttachmentSchema)` to create a new message.
|
|
901
|
+
*/
|
|
902
|
+
const InvoiceAttachmentSchema = /*@__PURE__*/ messageDesc(file_spark_token, 11);
|
|
903
|
+
/**
|
|
904
|
+
* Describes the message spark_token.SignatureWithIndex.
|
|
905
|
+
* Use `create(SignatureWithIndexSchema)` to create a new message.
|
|
906
|
+
*/
|
|
907
|
+
const SignatureWithIndexSchema = /*@__PURE__*/ messageDesc(file_spark_token, 13);
|
|
908
|
+
/**
|
|
909
|
+
* @generated from enum spark_token.TokenOutputStatus
|
|
910
|
+
*/
|
|
911
|
+
const TokenOutputStatus = {
|
|
912
|
+
/**
|
|
913
|
+
* @generated from enum value: TOKEN_OUTPUT_STATUS_UNSPECIFIED = 0;
|
|
914
|
+
*/
|
|
915
|
+
UNSPECIFIED: 0,
|
|
916
|
+
/**
|
|
917
|
+
* @generated from enum value: TOKEN_OUTPUT_STATUS_AVAILABLE = 1;
|
|
918
|
+
*/
|
|
919
|
+
AVAILABLE: 1,
|
|
920
|
+
/**
|
|
921
|
+
* @generated from enum value: TOKEN_OUTPUT_STATUS_PENDING_OUTBOUND = 2;
|
|
922
|
+
*/
|
|
923
|
+
PENDING_OUTBOUND: 2
|
|
924
|
+
};
|
|
925
|
+
/**
|
|
926
|
+
* @generated from enum spark_token.CommitStatus
|
|
927
|
+
*/
|
|
928
|
+
const CommitStatus = {
|
|
929
|
+
/**
|
|
930
|
+
* @generated from enum value: COMMIT_UNSPECIFIED = 0;
|
|
931
|
+
*/
|
|
932
|
+
COMMIT_UNSPECIFIED: 0,
|
|
933
|
+
/**
|
|
934
|
+
* @generated from enum value: COMMIT_PROCESSING = 1;
|
|
935
|
+
*/
|
|
936
|
+
COMMIT_PROCESSING: 1,
|
|
937
|
+
/**
|
|
938
|
+
* @generated from enum value: COMMIT_FINALIZED = 2;
|
|
939
|
+
*/
|
|
940
|
+
COMMIT_FINALIZED: 2
|
|
941
|
+
};
|
|
942
|
+
/**
|
|
943
|
+
* @generated from enum spark_token.TokenTransactionStatus
|
|
944
|
+
*/
|
|
945
|
+
const TokenTransactionStatus = {
|
|
946
|
+
/**
|
|
947
|
+
* @generated from enum value: TOKEN_TRANSACTION_STARTED = 0;
|
|
948
|
+
*/
|
|
949
|
+
TOKEN_TRANSACTION_STARTED: 0,
|
|
950
|
+
/**
|
|
951
|
+
* @generated from enum value: TOKEN_TRANSACTION_SIGNED = 1;
|
|
952
|
+
*/
|
|
953
|
+
TOKEN_TRANSACTION_SIGNED: 1,
|
|
954
|
+
/**
|
|
955
|
+
* @generated from enum value: TOKEN_TRANSACTION_REVEALED = 5;
|
|
956
|
+
*/
|
|
957
|
+
TOKEN_TRANSACTION_REVEALED: 5,
|
|
958
|
+
/**
|
|
959
|
+
* @generated from enum value: TOKEN_TRANSACTION_FINALIZED = 2;
|
|
960
|
+
*/
|
|
961
|
+
TOKEN_TRANSACTION_FINALIZED: 2,
|
|
962
|
+
/**
|
|
963
|
+
* @generated from enum value: TOKEN_TRANSACTION_STARTED_CANCELLED = 3;
|
|
964
|
+
*/
|
|
965
|
+
TOKEN_TRANSACTION_STARTED_CANCELLED: 3,
|
|
966
|
+
/**
|
|
967
|
+
* @generated from enum value: TOKEN_TRANSACTION_SIGNED_CANCELLED = 4;
|
|
968
|
+
*/
|
|
969
|
+
TOKEN_TRANSACTION_SIGNED_CANCELLED: 4,
|
|
970
|
+
/**
|
|
971
|
+
* @generated from enum value: TOKEN_TRANSACTION_UNKNOWN = 10;
|
|
972
|
+
*/
|
|
973
|
+
TOKEN_TRANSACTION_UNKNOWN: 10
|
|
974
|
+
};
|
|
975
|
+
/**
|
|
976
|
+
* @generated from service spark_token.SparkTokenService
|
|
977
|
+
*/
|
|
978
|
+
const SparkTokenService = /*@__PURE__*/ serviceDesc(file_spark_token, 0);
|
|
979
|
+
//#endregion
|
|
980
|
+
//#region src/core/bitcoin/sighash.ts
|
|
981
|
+
/** Parses raw transaction bytes, tolerating nonstandard outputs (P2A anchors). */
|
|
982
|
+
function parseTransaction(bytes) {
|
|
983
|
+
try {
|
|
984
|
+
return Transaction.fromRaw(bytes, { allowUnknownOutputs: true });
|
|
985
|
+
} catch (error) {
|
|
986
|
+
throw new SparkInputError("transaction: failed to parse raw transaction", { cause: error });
|
|
987
|
+
}
|
|
988
|
+
}
|
|
989
|
+
/** Internal: BIP-341 sighash over an already-parsed transaction. */
|
|
990
|
+
function keySpendSighash(tx, inputIndex, prevouts) {
|
|
991
|
+
if (!Number.isSafeInteger(inputIndex) || inputIndex < 0 || inputIndex >= tx.inputsLength) throw new SparkInputError("inputIndex: out of range for the transaction's inputs");
|
|
992
|
+
if (prevouts.length !== tx.inputsLength) throw new SparkInputError("prevouts: must contain one entry per transaction input");
|
|
993
|
+
const scripts = [];
|
|
994
|
+
const amounts = [];
|
|
995
|
+
for (const prevout of prevouts) {
|
|
996
|
+
if (prevout.script.length === 0) throw new SparkInputError("prevouts.script: must not be empty");
|
|
997
|
+
assertSats(prevout.amount, "prevouts.amount");
|
|
998
|
+
scripts.push(prevout.script);
|
|
999
|
+
amounts.push(BigInt(prevout.amount));
|
|
1000
|
+
}
|
|
1001
|
+
try {
|
|
1002
|
+
return tx.preimageWitnessV1(inputIndex, scripts, SigHash.DEFAULT, amounts);
|
|
1003
|
+
} catch (error) {
|
|
1004
|
+
throw new SparkInputError("sighash: taproot key-spend preimage failed", { cause: error });
|
|
1005
|
+
}
|
|
1006
|
+
}
|
|
1007
|
+
/**
|
|
1008
|
+
* BIP-341 key-spend sighash (SIGHASH_DEFAULT) for `inputIndex`, committing to all inputs' prevouts.
|
|
1009
|
+
* The single-input case is the same function with a one-element `prevouts` array.
|
|
1010
|
+
*/
|
|
1011
|
+
function taprootKeySpendSighash(target) {
|
|
1012
|
+
return keySpendSighash(parseTransaction(target.transaction), target.inputIndex, target.prevouts);
|
|
1013
|
+
}
|
|
1014
|
+
/**
|
|
1015
|
+
* BIP-342 script-path sighash for `inputIndex` spending via `leafScript` (tapscript leaf version
|
|
1016
|
+
* 0xc0). Used by the HTLC sender/receiver spends.
|
|
1017
|
+
*/
|
|
1018
|
+
function taprootScriptSpendSighash(target, leafScript) {
|
|
1019
|
+
const tx = parseTransaction(target.transaction);
|
|
1020
|
+
const scripts = [];
|
|
1021
|
+
const amounts = [];
|
|
1022
|
+
for (const prevout of target.prevouts) {
|
|
1023
|
+
assertSats(prevout.amount, "prevouts.amount");
|
|
1024
|
+
scripts.push(prevout.script);
|
|
1025
|
+
amounts.push(BigInt(prevout.amount));
|
|
1026
|
+
}
|
|
1027
|
+
if (!Number.isSafeInteger(target.inputIndex) || target.inputIndex < 0) throw new SparkInputError("inputIndex: must be a non-negative integer");
|
|
1028
|
+
try {
|
|
1029
|
+
return tx.preimageWitnessV1(target.inputIndex, scripts, SigHash.DEFAULT, amounts, -1, leafScript, 192);
|
|
1030
|
+
} catch (error) {
|
|
1031
|
+
throw new SparkInputError("sighash: taproot script-spend preimage failed", { cause: error });
|
|
1032
|
+
}
|
|
1033
|
+
}
|
|
1034
|
+
//#endregion
|
|
1035
|
+
//#region src/core/bitcoin/sequence.ts
|
|
1036
|
+
const SEQUENCE_LOCK_TIME_DISABLED = 2147483648;
|
|
1037
|
+
const SEQUENCE_LOCK_TIME_IS_SECONDS = 4194304;
|
|
1038
|
+
/** Lower 16 bits carry the block-based timelock value. */
|
|
1039
|
+
const SEQUENCE_LOCK_TIME_MASK = 65535;
|
|
1040
|
+
const BIT_30 = 1 << 30;
|
|
1041
|
+
const INITIAL_SEQUENCE = 2e3;
|
|
1042
|
+
/** Extracts the block-based timelock (lower 16 bits) from a sequence number. */
|
|
1043
|
+
function getTimelockFromSequence(sequence) {
|
|
1044
|
+
assertU32(sequence, "sequence");
|
|
1045
|
+
return sequence & SEQUENCE_LOCK_TIME_MASK;
|
|
1046
|
+
}
|
|
1047
|
+
/**
|
|
1048
|
+
* Rejects sequences with bit 31 (timelock disabled) or bit 22 (time-based timelock) set — Spark
|
|
1049
|
+
* only uses block-based relative timelocks.
|
|
1050
|
+
*/
|
|
1051
|
+
function checkIfValidSequence(sequence) {
|
|
1052
|
+
assertU32(sequence, "sequence");
|
|
1053
|
+
if ((sequence & SEQUENCE_LOCK_TIME_DISABLED) !== 0) throw new SparkInputError("sequence: bit 31 set disables the relative timelock");
|
|
1054
|
+
if ((sequence & SEQUENCE_LOCK_TIME_IS_SECONDS) !== 0) throw new SparkInputError("sequence: bit 22 selects a time-based timelock");
|
|
1055
|
+
}
|
|
1056
|
+
/** True when the sequence's timelock value is zero (upper bits ignored). */
|
|
1057
|
+
function isZeroTimelock(sequence) {
|
|
1058
|
+
return getTimelockFromSequence(sequence) === 0;
|
|
1059
|
+
}
|
|
1060
|
+
/** Rounds `timelock` down to the nearest multiple of `timeLockInterval` (0 disables rounding). */
|
|
1061
|
+
function roundDownToTimelockInterval(timelock, timeLockInterval) {
|
|
1062
|
+
assertU32(timelock, "timelock");
|
|
1063
|
+
assertU32(timeLockInterval, "timeLockInterval");
|
|
1064
|
+
if (timeLockInterval === 0) return timelock;
|
|
1065
|
+
return timelock - timelock % timeLockInterval;
|
|
1066
|
+
}
|
|
1067
|
+
/**
|
|
1068
|
+
* Next node/refund sequence: decrements the timelock by `TIME_LOCK_INTERVAL`. Mirrors the upstream
|
|
1069
|
+
* TS helper: node transactions may decrement to zero, other transactions must stay above zero; only
|
|
1070
|
+
* bit 30 is preserved.
|
|
1071
|
+
*/
|
|
1072
|
+
function getNextTransactionSequence(currSequence, isNodeTx) {
|
|
1073
|
+
const nextTimelock = getTimelockFromSequence(currSequence) - 100;
|
|
1074
|
+
const upper = currSequence & BIT_30;
|
|
1075
|
+
if (isNodeTx === true && nextTimelock < 0) throw new SparkInputError("sequence: next timelock is below zero");
|
|
1076
|
+
if (isNodeTx !== true && nextTimelock <= 0) throw new SparkInputError("sequence: next timelock must stay above zero");
|
|
1077
|
+
return {
|
|
1078
|
+
nextSequence: upper | nextTimelock,
|
|
1079
|
+
nextDirectSequence: upper | nextTimelock + 50
|
|
1080
|
+
};
|
|
1081
|
+
}
|
|
1082
|
+
/** Same decrement for HTLC transactions, offset by the HTLC timelock deltas. */
|
|
1083
|
+
function getNextHTLCTransactionSequence(currSequence, isNodeTx) {
|
|
1084
|
+
const nextTimelock = getTimelockFromSequence(currSequence) - 100;
|
|
1085
|
+
const upper = currSequence & BIT_30;
|
|
1086
|
+
if (isNodeTx === true && nextTimelock < 0) throw new SparkInputError("sequence: next timelock is below zero");
|
|
1087
|
+
if (isNodeTx !== true && nextTimelock <= 0) throw new SparkInputError("sequence: next timelock must stay above zero");
|
|
1088
|
+
return {
|
|
1089
|
+
nextSequence: upper | nextTimelock + 70,
|
|
1090
|
+
nextDirectSequence: upper | nextTimelock + 85
|
|
1091
|
+
};
|
|
1092
|
+
}
|
|
1093
|
+
/**
|
|
1094
|
+
* Whether the transaction should be renewed: refresh before the timelock drops below 200 blocks so
|
|
1095
|
+
* it cannot fall under 100 after a transfer or renewal, which would risk interfering with
|
|
1096
|
+
* watchtowers.
|
|
1097
|
+
*/
|
|
1098
|
+
function doesTxnNeedRenewed(currSequence) {
|
|
1099
|
+
return getTimelockFromSequence(currSequence) < 200;
|
|
1100
|
+
}
|
|
1101
|
+
//#endregion
|
|
1102
|
+
//#region src/core/bitcoin/script.ts
|
|
1103
|
+
/** Ephemeral anchor (P2A): OP_TRUE, push 2 bytes, 0x4e73 — value 0 sats. */
|
|
1104
|
+
const EPHEMERAL_ANCHOR_SCRIPT = new Uint8Array([
|
|
1105
|
+
81,
|
|
1106
|
+
2,
|
|
1107
|
+
78,
|
|
1108
|
+
115
|
|
1109
|
+
]);
|
|
1110
|
+
/** Maps a {@link SparkNetwork} onto btc-signer network parameters (`bc` / `bcrt`). */
|
|
1111
|
+
function btcNetwork(network) {
|
|
1112
|
+
return network === "mainnet" ? NETWORK : {
|
|
1113
|
+
...TEST_NETWORK,
|
|
1114
|
+
bech32: "bcrt"
|
|
1115
|
+
};
|
|
1116
|
+
}
|
|
1117
|
+
function assertCompressedPublicKey(publicKey, field) {
|
|
1118
|
+
if (publicKey.length !== 33) throw new SparkInputError(`${field}: must be a 33-byte compressed public key`);
|
|
1119
|
+
try {
|
|
1120
|
+
secp256k1.Point.fromBytes(publicKey);
|
|
1121
|
+
} catch (error) {
|
|
1122
|
+
throw new SparkInputError(`${field}: not a valid secp256k1 point`, { cause: error });
|
|
1123
|
+
}
|
|
1124
|
+
}
|
|
1125
|
+
/** The x-only (32-byte) form of a compressed public key, validated on-curve. */
|
|
1126
|
+
function xOnlyPublicKey(publicKey) {
|
|
1127
|
+
assertCompressedPublicKey(publicKey, "publicKey");
|
|
1128
|
+
return secp256k1.Point.fromBytes(publicKey).toBytes(true).subarray(1);
|
|
1129
|
+
}
|
|
1130
|
+
/**
|
|
1131
|
+
* BIP-341 key tweak with no script tree: `Q = lift_x(P) + tagged_hash("TapTweak", P) * G`. Returns
|
|
1132
|
+
* the tweaked key as 33-byte compressed bytes.
|
|
1133
|
+
*/
|
|
1134
|
+
function computeTaprootKeyNoScript(xOnlyKey) {
|
|
1135
|
+
if (xOnlyKey.length !== 32) throw new SparkInputError("xOnlyKey: must be a 32-byte x-only public key");
|
|
1136
|
+
const tweakHash = schnorr.utils.taggedHash("TapTweak", xOnlyKey);
|
|
1137
|
+
const tweak = BigInt(`0x${bytesToHex(tweakHash)}`);
|
|
1138
|
+
try {
|
|
1139
|
+
return schnorr.utils.lift_x(BigInt(`0x${bytesToHex(xOnlyKey)}`)).add(secp256k1.Point.BASE.multiply(tweak)).toBytes(true);
|
|
1140
|
+
} catch (error) {
|
|
1141
|
+
throw new SparkInputError("xOnlyKey: cannot derive a taproot key", { cause: error });
|
|
1142
|
+
}
|
|
1143
|
+
}
|
|
1144
|
+
/** P2TR scriptPubKey for a 33-byte compressed public key (key-path only). */
|
|
1145
|
+
function p2trScriptFromPublicKey(publicKey, network) {
|
|
1146
|
+
const { script } = p2tr(xOnlyPublicKey(publicKey), void 0, btcNetwork(network));
|
|
1147
|
+
if (script === void 0) throw new SparkInputError("publicKey: cannot derive a P2TR script");
|
|
1148
|
+
return script;
|
|
1149
|
+
}
|
|
1150
|
+
/** Re-encodes a P2TR scriptPubKey (34 bytes, `5120…`) as a bech32m address. */
|
|
1151
|
+
function p2trAddressFromScript(pkScript, network) {
|
|
1152
|
+
if (pkScript.length !== 34 || pkScript[0] !== 81 || pkScript[1] !== 32) throw new SparkInputError("pkScript: must be a 34-byte P2TR script (0x5120…)");
|
|
1153
|
+
try {
|
|
1154
|
+
return Address(btcNetwork(network)).encode(OutScript.decode(pkScript));
|
|
1155
|
+
} catch (error) {
|
|
1156
|
+
throw new SparkInputError("pkScript: not a decodable output script", { cause: error });
|
|
1157
|
+
}
|
|
1158
|
+
}
|
|
1159
|
+
//#endregion
|
|
1160
|
+
//#region src/core/bitcoin/transactions.ts
|
|
1161
|
+
/**
|
|
1162
|
+
* Display-order txid (the usual block-explorer hex form). The txid never covers witness data —
|
|
1163
|
+
* hashing the raw serialization of a segwit transaction would yield its wtxid instead.
|
|
1164
|
+
*/
|
|
1165
|
+
function txId(txBytes) {
|
|
1166
|
+
return parseTransaction(txBytes).id;
|
|
1167
|
+
}
|
|
1168
|
+
/**
|
|
1169
|
+
* Display-order txid bytes — the form btc-signer's `TransactionInput.txid` expects (it reverses
|
|
1170
|
+
* internally when serializing the outpoint).
|
|
1171
|
+
*/
|
|
1172
|
+
function txIdInputBytes(txBytes) {
|
|
1173
|
+
return hexToBytes(parseTransaction(txBytes).id);
|
|
1174
|
+
}
|
|
1175
|
+
/**
|
|
1176
|
+
* Verifies the aggregated Schnorr key-path signature an operator attaches to a finalized
|
|
1177
|
+
* transaction (e.g. the root node and refund returned by `finalize_deposit_tree_creation`): input
|
|
1178
|
+
* `inputIndex`'s first witness element must be a 64-byte BIP-340 signature over `sighash` under the
|
|
1179
|
+
* BIP-341 taproot output key of `verifyingPublicKey` with an empty script tree. Fails closed — any
|
|
1180
|
+
* malformed input returns `false` rather than throwing, matching breez-spark-sdk
|
|
1181
|
+
* `verify_finalized_taproot_signature` (bitcoin/service.rs @956ff90).
|
|
1182
|
+
*/
|
|
1183
|
+
function verifyFinalizedTaprootSignature(signedTxBytes, sighash, verifyingPublicKey, inputIndex) {
|
|
1184
|
+
try {
|
|
1185
|
+
const tx = parseTransaction(signedTxBytes);
|
|
1186
|
+
const signature = (inputIndex >= 0 && inputIndex < tx.inputsLength ? tx.getInput(inputIndex).finalScriptWitness : void 0)?.[0];
|
|
1187
|
+
if (signature === void 0 || signature.length !== 64 || sighash.length !== 32) return false;
|
|
1188
|
+
const taprootKey = computeTaprootKeyNoScript(xOnlyPublicKey(verifyingPublicKey)).subarray(1);
|
|
1189
|
+
return schnorr.verify(signature, sighash, taprootKey);
|
|
1190
|
+
} catch {
|
|
1191
|
+
return false;
|
|
1192
|
+
}
|
|
1193
|
+
}
|
|
1194
|
+
/** Subtracts `feeSats` when the amount can cover it; otherwise returns the amount unchanged. */
|
|
1195
|
+
function maybeApplyFee(amountSats, feeSats) {
|
|
1196
|
+
assertSats(amountSats, "amount");
|
|
1197
|
+
assertSats(feeSats, "feeSats");
|
|
1198
|
+
return amountSats > feeSats ? amountSats - feeSats : amountSats;
|
|
1199
|
+
}
|
|
1200
|
+
function prevOutAt(tx, vout) {
|
|
1201
|
+
if (!Number.isSafeInteger(vout) || vout < 0 || vout >= tx.outputsLength) throw new SparkInputError("vout: out of range for the transaction's outputs");
|
|
1202
|
+
const { script, amount } = tx.getOutput(vout);
|
|
1203
|
+
if (script === void 0 || amount === void 0) throw new SparkInputError("vout: output is missing its script or amount");
|
|
1204
|
+
if (amount > BigInt(0x775f05a074000)) throw new SparkInputError(`vout: amount exceeds ${MAX_SATS} sats`);
|
|
1205
|
+
return {
|
|
1206
|
+
script,
|
|
1207
|
+
amountSats: Number(amount)
|
|
1208
|
+
};
|
|
1209
|
+
}
|
|
1210
|
+
/**
|
|
1211
|
+
* Decodes a Bitcoin address to its output script under any network — matching upstream
|
|
1212
|
+
* `Address::from_str(..).assume_checked()`, which never checks that the address's network matches
|
|
1213
|
+
* the operating network.
|
|
1214
|
+
*/
|
|
1215
|
+
function addressToScript(address) {
|
|
1216
|
+
for (const net of [btcNetwork("mainnet"), btcNetwork("regtest")]) try {
|
|
1217
|
+
return OutScript.encode(Address(net).decode(address));
|
|
1218
|
+
} catch {}
|
|
1219
|
+
throw new SparkInputError("address: not a decodable Bitcoin address");
|
|
1220
|
+
}
|
|
1221
|
+
/**
|
|
1222
|
+
* Shared builder for node/refund transactions: one input spending `parentTxBytes`'s `vout`, one
|
|
1223
|
+
* destination output, and optionally the ephemeral anchor output. Version 3, locktime 0.
|
|
1224
|
+
*/
|
|
1225
|
+
function buildSingleOutputTx(parentTxBytes, vout, outputScript, sequence, applyFee, feeSats, includeAnchor) {
|
|
1226
|
+
const prevOut = prevOutAt(parseTransaction(parentTxBytes), vout);
|
|
1227
|
+
const outAmount = applyFee ? maybeApplyFee(prevOut.amountSats, feeSats) : prevOut.amountSats;
|
|
1228
|
+
const tx = new Transaction({
|
|
1229
|
+
version: 3,
|
|
1230
|
+
allowUnknownOutputs: true
|
|
1231
|
+
});
|
|
1232
|
+
tx.addInput({
|
|
1233
|
+
txid: txIdInputBytes(parentTxBytes),
|
|
1234
|
+
index: vout,
|
|
1235
|
+
sequence
|
|
1236
|
+
});
|
|
1237
|
+
tx.addOutput({
|
|
1238
|
+
script: outputScript,
|
|
1239
|
+
amount: BigInt(outAmount)
|
|
1240
|
+
});
|
|
1241
|
+
if (includeAnchor) tx.addOutput({
|
|
1242
|
+
script: EPHEMERAL_ANCHOR_SCRIPT,
|
|
1243
|
+
amount: 0n
|
|
1244
|
+
});
|
|
1245
|
+
return {
|
|
1246
|
+
txBytes: tx.toBytes(true),
|
|
1247
|
+
sighash: keySpendSighash(tx, 0, [{
|
|
1248
|
+
script: prevOut.script,
|
|
1249
|
+
amount: prevOut.amountSats
|
|
1250
|
+
}])
|
|
1251
|
+
};
|
|
1252
|
+
}
|
|
1253
|
+
/**
|
|
1254
|
+
* Both node transactions over a parent output. The CPFP variant carries the full amount plus the
|
|
1255
|
+
* anchor output at `sequence`; the direct variant deducts the fee, has no anchor, and uses
|
|
1256
|
+
* `directSequence`.
|
|
1257
|
+
*/
|
|
1258
|
+
function constructNodeTxPair(parentTx, vout, address, sequence, directSequence, feeSats) {
|
|
1259
|
+
checkIfValidSequence(sequence);
|
|
1260
|
+
checkIfValidSequence(directSequence);
|
|
1261
|
+
const outputScript = addressToScript(address);
|
|
1262
|
+
return {
|
|
1263
|
+
cpfp: buildSingleOutputTx(parentTx, vout, outputScript, sequence, false, feeSats, true),
|
|
1264
|
+
direct: buildSingleOutputTx(parentTx, vout, outputScript, directSequence, true, feeSats, false)
|
|
1265
|
+
};
|
|
1266
|
+
}
|
|
1267
|
+
/**
|
|
1268
|
+
* The three refund variants spending a node transaction's `vout` to the P2TR script of
|
|
1269
|
+
* `receivingPublicKey`: CPFP (no fee, with anchor), direct (fee, no anchor, only when a direct node
|
|
1270
|
+
* tx exists), and direct-from-CPFP (fee, no anchor, spending the CPFP node tx at
|
|
1271
|
+
* `directSequence`).
|
|
1272
|
+
*/
|
|
1273
|
+
function constructRefundTxTrio(cpfpNodeTx, directNodeTx, vout, receivingPublicKey, network, sequence, directSequence, feeSats) {
|
|
1274
|
+
checkIfValidSequence(sequence);
|
|
1275
|
+
checkIfValidSequence(directSequence);
|
|
1276
|
+
const outputScript = p2trScriptFromPublicKey(receivingPublicKey, network);
|
|
1277
|
+
return {
|
|
1278
|
+
cpfpRefund: buildSingleOutputTx(cpfpNodeTx, vout, outputScript, sequence, false, feeSats, true),
|
|
1279
|
+
directRefund: directNodeTx === void 0 ? void 0 : buildSingleOutputTx(directNodeTx, vout, outputScript, directSequence, true, feeSats, false),
|
|
1280
|
+
directFromCpfpRefund: buildSingleOutputTx(cpfpNodeTx, vout, outputScript, directSequence, true, feeSats, false)
|
|
1281
|
+
};
|
|
1282
|
+
}
|
|
1283
|
+
/** Node tx pair whose destination is the parent output's own P2TR address. */
|
|
1284
|
+
function createNodeTxs(params) {
|
|
1285
|
+
const address = p2trAddressFromScript(prevOutAt(parseTransaction(params.parentTx), params.vout).script, params.network);
|
|
1286
|
+
const directSequence = params.directSequence ?? params.sequence + 50;
|
|
1287
|
+
return constructNodeTxPair(params.parentTx, params.vout, address, params.sequence, directSequence, 955);
|
|
1288
|
+
}
|
|
1289
|
+
/** Zero-timelock node transactions over output 0 (root variant of `createNodeTxs`). */
|
|
1290
|
+
function createZeroTimelockNodeTx(parentTx, network) {
|
|
1291
|
+
return createNodeTxs({
|
|
1292
|
+
parentTx,
|
|
1293
|
+
sequence: 0,
|
|
1294
|
+
directSequence: 50,
|
|
1295
|
+
vout: 0,
|
|
1296
|
+
network
|
|
1297
|
+
});
|
|
1298
|
+
}
|
|
1299
|
+
/** Node transactions at `INITIAL_SEQUENCE` (2000 blocks). */
|
|
1300
|
+
function createInitialTimelockNodeTx(parentTx, network) {
|
|
1301
|
+
return createNodeTxs({
|
|
1302
|
+
parentTx,
|
|
1303
|
+
sequence: INITIAL_SEQUENCE,
|
|
1304
|
+
vout: 0,
|
|
1305
|
+
network
|
|
1306
|
+
});
|
|
1307
|
+
}
|
|
1308
|
+
/** Node transactions one `TIME_LOCK_INTERVAL` below `currentTx`'s input sequence. */
|
|
1309
|
+
function createDecrementedTimelockNodeTx(parentTx, currentTx, network) {
|
|
1310
|
+
const { sequence } = parseTransaction(currentTx).getInput(0);
|
|
1311
|
+
if (sequence === void 0) throw new SparkInputError("currentTx: input 0 has no sequence");
|
|
1312
|
+
return createNodeTxs({
|
|
1313
|
+
parentTx,
|
|
1314
|
+
sequence: getNextTransactionSequence(sequence).nextSequence,
|
|
1315
|
+
vout: 0,
|
|
1316
|
+
network
|
|
1317
|
+
});
|
|
1318
|
+
}
|
|
1319
|
+
/**
|
|
1320
|
+
* The refund trio for a node transaction. With `enforceTimelocks`, the sequence's timelock is first
|
|
1321
|
+
* rounded down to the interval grid (upstream behaviour when renewing); a zero-timelock node tx
|
|
1322
|
+
* never produces a direct refund.
|
|
1323
|
+
*/
|
|
1324
|
+
function createRefundTxs(params) {
|
|
1325
|
+
let { sequence } = params;
|
|
1326
|
+
if (params.enforceTimelocks === true) sequence = roundDownToTimelockInterval(getTimelockFromSequence(sequence), 100) | sequence & 1 << 30;
|
|
1327
|
+
const directSequence = sequence + 50;
|
|
1328
|
+
const nodeSequence = parseTransaction(params.nodeTx).getInput(0).sequence;
|
|
1329
|
+
if (nodeSequence === void 0) throw new SparkInputError("nodeTx: input 0 has no sequence");
|
|
1330
|
+
const directNodeTx = isZeroTimelock(nodeSequence) ? void 0 : params.directNodeTx;
|
|
1331
|
+
return constructRefundTxTrio(params.nodeTx, directNodeTx, 0, params.receivingPublicKey, params.network, sequence, directSequence, 955);
|
|
1332
|
+
}
|
|
1333
|
+
/** Refund trio at `INITIAL_SEQUENCE`. */
|
|
1334
|
+
function createInitialTimelockRefundTxs(params) {
|
|
1335
|
+
return createRefundTxs({
|
|
1336
|
+
...params,
|
|
1337
|
+
sequence: INITIAL_SEQUENCE
|
|
1338
|
+
});
|
|
1339
|
+
}
|
|
1340
|
+
/** Refund trio one interval below `sequence`, rounded to the interval grid. */
|
|
1341
|
+
function createDecrementedTimelockRefundTxs(params) {
|
|
1342
|
+
const { nextSequence } = getNextTransactionSequence(params.sequence);
|
|
1343
|
+
return createRefundTxs({
|
|
1344
|
+
...params,
|
|
1345
|
+
sequence: nextSequence,
|
|
1346
|
+
enforceTimelocks: true
|
|
1347
|
+
});
|
|
1348
|
+
}
|
|
1349
|
+
/** Refund trio at the current timelock, rounded down to the interval grid. */
|
|
1350
|
+
function createCurrentTimelockRefundTxs(params) {
|
|
1351
|
+
return createRefundTxs({
|
|
1352
|
+
...params,
|
|
1353
|
+
enforceTimelocks: true
|
|
1354
|
+
});
|
|
1355
|
+
}
|
|
1356
|
+
/**
|
|
1357
|
+
* The decremented refund trio plus the connector input appended to each transaction. The connector
|
|
1358
|
+
* changes every input commitment, so the returned transactions must be re-signed via
|
|
1359
|
+
* `taprootKeySpendSighash` with both prevouts — the sibling `sighash` fields describe the one-input
|
|
1360
|
+
* forms.
|
|
1361
|
+
*/
|
|
1362
|
+
function createConnectorRefundTxs(params) {
|
|
1363
|
+
const { connectorInput, ...base } = params;
|
|
1364
|
+
assertU32(connectorInput.index, "connectorInput.index");
|
|
1365
|
+
if (connectorInput.txid.length !== 32) throw new SparkInputError("connectorInput.txid: must be 32 bytes");
|
|
1366
|
+
const trio = createDecrementedTimelockRefundTxs(base);
|
|
1367
|
+
const splice = (txBytes) => {
|
|
1368
|
+
const tx = parseTransaction(txBytes);
|
|
1369
|
+
tx.addInput({
|
|
1370
|
+
txid: connectorInput.txid,
|
|
1371
|
+
index: connectorInput.index,
|
|
1372
|
+
...connectorInput.sequence === void 0 ? {} : { sequence: connectorInput.sequence }
|
|
1373
|
+
});
|
|
1374
|
+
return tx.toBytes(true);
|
|
1375
|
+
};
|
|
1376
|
+
return {
|
|
1377
|
+
cpfpRefundTx: splice(trio.cpfpRefund.txBytes),
|
|
1378
|
+
directRefundTx: trio.directRefund === void 0 ? void 0 : splice(trio.directRefund.txBytes),
|
|
1379
|
+
directFromCpfpRefundTx: splice(trio.directFromCpfpRefund.txBytes)
|
|
1380
|
+
};
|
|
1381
|
+
}
|
|
1382
|
+
/**
|
|
1383
|
+
* Consolidates deposit UTXOs (all paying the same address) into one root output plus the ephemeral
|
|
1384
|
+
* anchor. Inputs keep the caller's order; the output reuses the first deposit output's script and
|
|
1385
|
+
* the summed amount.
|
|
1386
|
+
*/
|
|
1387
|
+
function createMultiInputRootTx(depositTxs) {
|
|
1388
|
+
if (depositTxs.length === 0) throw new SparkInputError("depositTxs: must not be empty");
|
|
1389
|
+
const tx = new Transaction({
|
|
1390
|
+
version: 3,
|
|
1391
|
+
allowUnknownOutputs: true
|
|
1392
|
+
});
|
|
1393
|
+
let total = 0;
|
|
1394
|
+
let firstScript;
|
|
1395
|
+
for (const { tx: txBytes, vout } of depositTxs) {
|
|
1396
|
+
const prevOut = prevOutAt(parseTransaction(txBytes), vout);
|
|
1397
|
+
tx.addInput({
|
|
1398
|
+
txid: txIdInputBytes(txBytes),
|
|
1399
|
+
index: vout,
|
|
1400
|
+
sequence: 0
|
|
1401
|
+
});
|
|
1402
|
+
firstScript ??= prevOut.script;
|
|
1403
|
+
total += prevOut.amountSats;
|
|
1404
|
+
assertSats(total, "totalAmount");
|
|
1405
|
+
}
|
|
1406
|
+
if (firstScript === void 0) throw new SparkInputError("depositTxs: must not be empty");
|
|
1407
|
+
tx.addOutput({
|
|
1408
|
+
script: firstScript,
|
|
1409
|
+
amount: BigInt(total)
|
|
1410
|
+
});
|
|
1411
|
+
tx.addOutput({
|
|
1412
|
+
script: EPHEMERAL_ANCHOR_SCRIPT,
|
|
1413
|
+
amount: 0n
|
|
1414
|
+
});
|
|
1415
|
+
return tx.toBytes(true);
|
|
1416
|
+
}
|
|
1417
|
+
/** Rough vbytes estimate used for fee planning: 10 + 150/input + 34/output. */
|
|
1418
|
+
function estimateVbytes(numInputs, numOutputs) {
|
|
1419
|
+
return 10 + numInputs * 150 + numOutputs * 34;
|
|
1420
|
+
}
|
|
1421
|
+
//#endregion
|
|
1422
|
+
//#region src/core/bitcoin/htlc.ts
|
|
1423
|
+
/** X-only taproot NUMS internal key — unspendable key-path for HTLC outputs. */
|
|
1424
|
+
const NUMS_INTERNAL_KEY = new Uint8Array([
|
|
1425
|
+
80,
|
|
1426
|
+
146,
|
|
1427
|
+
155,
|
|
1428
|
+
116,
|
|
1429
|
+
193,
|
|
1430
|
+
160,
|
|
1431
|
+
73,
|
|
1432
|
+
84,
|
|
1433
|
+
183,
|
|
1434
|
+
139,
|
|
1435
|
+
75,
|
|
1436
|
+
96,
|
|
1437
|
+
53,
|
|
1438
|
+
233,
|
|
1439
|
+
122,
|
|
1440
|
+
94,
|
|
1441
|
+
7,
|
|
1442
|
+
138,
|
|
1443
|
+
90,
|
|
1444
|
+
15,
|
|
1445
|
+
40,
|
|
1446
|
+
236,
|
|
1447
|
+
150,
|
|
1448
|
+
213,
|
|
1449
|
+
71,
|
|
1450
|
+
191,
|
|
1451
|
+
238,
|
|
1452
|
+
154,
|
|
1453
|
+
206,
|
|
1454
|
+
128,
|
|
1455
|
+
58,
|
|
1456
|
+
192
|
|
1457
|
+
]);
|
|
1458
|
+
const LIGHTNING_HTLC_SEQUENCE = 2160;
|
|
1459
|
+
/** `OP_SHA256 <32-byte hash> OP_EQUALVERIFY <x-only pubkey> OP_CHECKSIG`. */
|
|
1460
|
+
function createHashLockScript(paymentHash, publicKey) {
|
|
1461
|
+
if (paymentHash.length !== 32) throw new SparkInputError("paymentHash: must be 32 bytes");
|
|
1462
|
+
return Script.encode([
|
|
1463
|
+
"SHA256",
|
|
1464
|
+
paymentHash,
|
|
1465
|
+
"EQUALVERIFY",
|
|
1466
|
+
xOnlyPublicKey(publicKey),
|
|
1467
|
+
"CHECKSIG"
|
|
1468
|
+
]);
|
|
1469
|
+
}
|
|
1470
|
+
/** `<sequence> OP_CHECKSEQUENCEVERIFY OP_DROP <x-only pubkey> OP_CHECKSIG`. */
|
|
1471
|
+
function createSequenceLockScript(sequence, publicKey) {
|
|
1472
|
+
const elements = sequence <= 16 ? [
|
|
1473
|
+
sequence,
|
|
1474
|
+
"CHECKSEQUENCEVERIFY",
|
|
1475
|
+
"DROP",
|
|
1476
|
+
xOnlyPublicKey(publicKey),
|
|
1477
|
+
"CHECKSIG"
|
|
1478
|
+
] : [
|
|
1479
|
+
ScriptNum().encode(BigInt(sequence)),
|
|
1480
|
+
"CHECKSEQUENCEVERIFY",
|
|
1481
|
+
"DROP",
|
|
1482
|
+
xOnlyPublicKey(publicKey),
|
|
1483
|
+
"CHECKSIG"
|
|
1484
|
+
];
|
|
1485
|
+
return Script.encode(elements);
|
|
1486
|
+
}
|
|
1487
|
+
/**
|
|
1488
|
+
* Two-leaf taproot tree (hash-lock leaf first, sequence-lock leaf second) on the NUMS internal key
|
|
1489
|
+
* — the HTLC output structure. The output script does not depend on the network, so upstream's
|
|
1490
|
+
* `network` parameter is not needed here.
|
|
1491
|
+
*/
|
|
1492
|
+
function htlcP2tr(hashLockScript, sequenceLockScript) {
|
|
1493
|
+
const tree = taprootListToTree([{
|
|
1494
|
+
leafVersion: 192,
|
|
1495
|
+
script: hashLockScript
|
|
1496
|
+
}, {
|
|
1497
|
+
leafVersion: 192,
|
|
1498
|
+
script: sequenceLockScript
|
|
1499
|
+
}]);
|
|
1500
|
+
const p2 = p2tr(NUMS_INTERNAL_KEY, tree, void 0, true);
|
|
1501
|
+
const { script } = p2;
|
|
1502
|
+
const leafScripts = p2.tapLeafScript;
|
|
1503
|
+
if (script === void 0 || leafScripts === void 0 || leafScripts.length !== 2) throw new SparkInputError("htlc: failed to build the two-leaf taproot tree");
|
|
1504
|
+
return {
|
|
1505
|
+
script,
|
|
1506
|
+
leafScripts
|
|
1507
|
+
};
|
|
1508
|
+
}
|
|
1509
|
+
function findLeafScript(leafScripts, leafScript) {
|
|
1510
|
+
for (const entry of leafScripts) {
|
|
1511
|
+
const [, versionedScript] = entry;
|
|
1512
|
+
if (versionedScript.length === leafScript.length + 1) {
|
|
1513
|
+
let same = versionedScript.at(-1) === 192;
|
|
1514
|
+
for (let i = 0; i < leafScript.length && same; i += 1) same = versionedScript[i] === leafScript[i];
|
|
1515
|
+
if (same) return entry;
|
|
1516
|
+
}
|
|
1517
|
+
}
|
|
1518
|
+
throw new SparkInputError("htlc: leaf script not present in the taproot tree");
|
|
1519
|
+
}
|
|
1520
|
+
/**
|
|
1521
|
+
* The HTLC refund transaction's output 0 script — the two-leaf NUMS-keyed P2TR every
|
|
1522
|
+
* `createRefundTxsForLightning` variant carries, built exactly as `constructHtlcTransaction` builds
|
|
1523
|
+
* it (hash-lock leaf first, `LIGHTNING_HTLC_SEQUENCE` CSV leaf second). Comparing it against a
|
|
1524
|
+
* committed refund's output 0 binds the payment hash and both destination keys without rebuilding
|
|
1525
|
+
* the whole transaction: the input sequence, prevout and fee never enter the script.
|
|
1526
|
+
*/
|
|
1527
|
+
function lightningHtlcOutputScript(paymentHash, hashLockPublicKey, sequenceLockPublicKey) {
|
|
1528
|
+
return htlcP2tr(createHashLockScript(paymentHash, hashLockPublicKey), createSequenceLockScript(LIGHTNING_HTLC_SEQUENCE, sequenceLockPublicKey)).script;
|
|
1529
|
+
}
|
|
1530
|
+
/**
|
|
1531
|
+
* HTLC transaction spending `nodeTx`'s `vout` into the two-leaf NUMS-keyed P2TR output plus the
|
|
1532
|
+
* ephemeral anchor. `sequence` is the input's relative timelock; `htlcSequence` is the
|
|
1533
|
+
* sequence-lock leaf's CSV delay.
|
|
1534
|
+
*/
|
|
1535
|
+
function constructHtlcTransaction(nodeTx, vout, sequence, paymentHash, hashLockPublicKey, sequenceLockPublicKey, htlcSequence, applyFee, feeSats) {
|
|
1536
|
+
checkIfValidSequence(sequence);
|
|
1537
|
+
checkIfValidSequence(htlcSequence);
|
|
1538
|
+
const node = parseTransaction(nodeTx);
|
|
1539
|
+
if (!Number.isSafeInteger(vout) || vout < 0 || vout >= node.outputsLength) throw new SparkInputError("vout: out of range for the node transaction's outputs");
|
|
1540
|
+
const output = node.getOutput(vout);
|
|
1541
|
+
const prevAmount = output.amount;
|
|
1542
|
+
const prevScript = output.script;
|
|
1543
|
+
if (prevAmount === void 0 || prevScript === void 0) throw new SparkInputError("vout: node transaction output is missing script or amount");
|
|
1544
|
+
const outAmount = applyFee ? maybeApplyFee(Number(prevAmount), feeSats) : prevAmount;
|
|
1545
|
+
const { script } = htlcP2tr(createHashLockScript(paymentHash, hashLockPublicKey), createSequenceLockScript(htlcSequence, sequenceLockPublicKey));
|
|
1546
|
+
const tx = new Transaction({
|
|
1547
|
+
version: 3,
|
|
1548
|
+
allowUnknownOutputs: true
|
|
1549
|
+
});
|
|
1550
|
+
tx.addInput({
|
|
1551
|
+
txid: txIdInputBytes(nodeTx),
|
|
1552
|
+
index: vout,
|
|
1553
|
+
sequence
|
|
1554
|
+
});
|
|
1555
|
+
tx.addOutput({
|
|
1556
|
+
script,
|
|
1557
|
+
amount: BigInt(outAmount)
|
|
1558
|
+
});
|
|
1559
|
+
if (!applyFee) tx.addOutput({
|
|
1560
|
+
script: EPHEMERAL_ANCHOR_SCRIPT,
|
|
1561
|
+
amount: 0n
|
|
1562
|
+
});
|
|
1563
|
+
return {
|
|
1564
|
+
txBytes: tx.toBytes(true),
|
|
1565
|
+
sighash: tx.preimageWitnessV1(0, [prevScript], SigHash.DEFAULT, [prevAmount])
|
|
1566
|
+
};
|
|
1567
|
+
}
|
|
1568
|
+
function buildHtlcSpend(htlcTx, vout, destinationScript, paymentHash, hashLockPublicKey, sequenceLockPublicKey, htlcSequence, inputSequence, spendLeafScript, feeSats) {
|
|
1569
|
+
checkIfValidSequence(htlcSequence);
|
|
1570
|
+
if (destinationScript.length === 0) throw new SparkInputError("destinationScript: must not be empty");
|
|
1571
|
+
const node = parseTransaction(htlcTx);
|
|
1572
|
+
if (!Number.isSafeInteger(vout) || vout < 0 || vout >= node.outputsLength) throw new SparkInputError("vout: out of range for the HTLC transaction's outputs");
|
|
1573
|
+
const output = node.getOutput(vout);
|
|
1574
|
+
const prevAmount = output.amount;
|
|
1575
|
+
const prevScript = output.script;
|
|
1576
|
+
if (prevAmount === void 0 || prevScript === void 0) throw new SparkInputError("vout: HTLC output is missing script or amount");
|
|
1577
|
+
const outAmount = maybeApplyFee(Number(prevAmount), feeSats);
|
|
1578
|
+
const { leafScripts } = htlcP2tr(createHashLockScript(paymentHash, hashLockPublicKey), createSequenceLockScript(htlcSequence, sequenceLockPublicKey));
|
|
1579
|
+
const [controlBlockData] = findLeafScript(leafScripts, spendLeafScript);
|
|
1580
|
+
const tx = new Transaction({
|
|
1581
|
+
version: 3,
|
|
1582
|
+
allowUnknownOutputs: true
|
|
1583
|
+
});
|
|
1584
|
+
tx.addInput({
|
|
1585
|
+
txid: txIdInputBytes(htlcTx),
|
|
1586
|
+
index: vout,
|
|
1587
|
+
sequence: inputSequence
|
|
1588
|
+
});
|
|
1589
|
+
tx.addOutput({
|
|
1590
|
+
script: destinationScript,
|
|
1591
|
+
amount: BigInt(outAmount)
|
|
1592
|
+
});
|
|
1593
|
+
const txBytes = tx.toBytes(true);
|
|
1594
|
+
return {
|
|
1595
|
+
txBytes,
|
|
1596
|
+
sighash: taprootScriptSpendSighash({
|
|
1597
|
+
transaction: txBytes,
|
|
1598
|
+
inputIndex: 0,
|
|
1599
|
+
prevouts: [{
|
|
1600
|
+
script: prevScript,
|
|
1601
|
+
amount: Number(prevAmount)
|
|
1602
|
+
}]
|
|
1603
|
+
}, spendLeafScript),
|
|
1604
|
+
script: spendLeafScript,
|
|
1605
|
+
controlBlock: TaprootControlBlock.encode(controlBlockData)
|
|
1606
|
+
};
|
|
1607
|
+
}
|
|
1608
|
+
/**
|
|
1609
|
+
* Timeout path: spends `htlcTx`'s `vout` output through the sequence-lock leaf to
|
|
1610
|
+
* `destinationScript`. Input sequence equals `htlcSequence` so the leaf's CSV is satisfied.
|
|
1611
|
+
*/
|
|
1612
|
+
function constructHtlcSenderSpend(htlcTx, vout, destinationScript, paymentHash, hashLockPublicKey, sequenceLockPublicKey, htlcSequence, feeSats) {
|
|
1613
|
+
return buildHtlcSpend(htlcTx, vout, destinationScript, paymentHash, hashLockPublicKey, sequenceLockPublicKey, htlcSequence, htlcSequence, createSequenceLockScript(htlcSequence, sequenceLockPublicKey), feeSats);
|
|
1614
|
+
}
|
|
1615
|
+
/**
|
|
1616
|
+
* Attaches the 64-byte BIP-340 leaf signature plus the spend's leaf script and control block as
|
|
1617
|
+
* input 0's witness — `<sig> <script> <control block>` — and returns the network-serialized signed
|
|
1618
|
+
* spend.
|
|
1619
|
+
*/
|
|
1620
|
+
function finalizeHtlcSpend(spend, signature) {
|
|
1621
|
+
if (signature.length !== 64) throw new SparkInputError("signature: must be a 64-byte schnorr signature");
|
|
1622
|
+
const tx = parseTransaction(spend.txBytes);
|
|
1623
|
+
tx.updateInput(0, { finalScriptWitness: [
|
|
1624
|
+
signature,
|
|
1625
|
+
spend.script,
|
|
1626
|
+
spend.controlBlock
|
|
1627
|
+
] });
|
|
1628
|
+
return tx.toBytes(true, true);
|
|
1629
|
+
}
|
|
1630
|
+
/**
|
|
1631
|
+
* CPFP + direct HTLC refund transactions spending a node tx into the HTLC output (sender side of a
|
|
1632
|
+
* Lightning transfer). Mirrors the upstream TS `createRefundTxsForLightning` composition.
|
|
1633
|
+
*/
|
|
1634
|
+
function createRefundTxsForLightning(params) {
|
|
1635
|
+
const feeSats = params.feeSats ?? 955;
|
|
1636
|
+
const cpfpRefundTx = constructHtlcTransaction(params.nodeTx, params.vout, params.sequence, params.paymentHash, params.hashLockDestinationPublicKey, params.sequenceLockDestinationPublicKey, LIGHTNING_HTLC_SEQUENCE, false, feeSats);
|
|
1637
|
+
let directRefundTx;
|
|
1638
|
+
if (params.directSequence !== 0 && params.directNodeTx !== void 0) directRefundTx = constructHtlcTransaction(params.directNodeTx, params.vout, params.directSequence, params.paymentHash, params.hashLockDestinationPublicKey, params.sequenceLockDestinationPublicKey, LIGHTNING_HTLC_SEQUENCE, true, feeSats);
|
|
1639
|
+
const directFromCpfpRefundTx = constructHtlcTransaction(params.nodeTx, params.vout, params.directSequence, params.paymentHash, params.hashLockDestinationPublicKey, params.sequenceLockDestinationPublicKey, LIGHTNING_HTLC_SEQUENCE, true, feeSats);
|
|
1640
|
+
return {
|
|
1641
|
+
cpfpRefundTx,
|
|
1642
|
+
directRefundTx,
|
|
1643
|
+
directFromCpfpRefundTx
|
|
1644
|
+
};
|
|
1645
|
+
}
|
|
1646
|
+
/**
|
|
1647
|
+
* Describes the message ssp_authn.ProtectedChallenge.
|
|
1648
|
+
* Use `create(ProtectedChallengeSchema)` to create a new message.
|
|
1649
|
+
*/
|
|
1650
|
+
const ProtectedChallengeSchema = /*@__PURE__*/ messageDesc(/* @__PURE__ */ fileDesc("Cg9zc3BfYXV0aG4ucHJvdG8SCXNzcF9hdXRobiJSCglDaGFsbGVuZ2USDwoHdmVyc2lvbhgBIAEoBRIRCgl0aW1lc3RhbXAYCiABKAMSDQoFbm9uY2UYFCABKAwSEgoKcHVibGljX2tleRgeIAEoDCJjChJQcm90ZWN0ZWRDaGFsbGVuZ2USDwoHdmVyc2lvbhgBIAEoBRInCgljaGFsbGVuZ2UYCiABKAsyFC5zc3BfYXV0aG4uQ2hhbGxlbmdlEhMKC3NlcnZlcl9obWFjGBQgASgMYgZwcm90bzM"), 1);
|
|
1651
|
+
//#endregion
|
|
1652
|
+
//#region src/core/hashing/hashstructure.ts
|
|
1653
|
+
const MAX_UINT64$1 = 18446744073709551615n;
|
|
1654
|
+
function serializeTag(tag) {
|
|
1655
|
+
const parts = [];
|
|
1656
|
+
for (const component of tag) {
|
|
1657
|
+
const componentBytes = utf8ToBytes(component);
|
|
1658
|
+
const lengthBytes = uint64be(BigInt(componentBytes.length));
|
|
1659
|
+
parts.push(lengthBytes, componentBytes);
|
|
1660
|
+
}
|
|
1661
|
+
const totalLength = parts.reduce((sum, part) => sum + part.length, 0);
|
|
1662
|
+
const result = new Uint8Array(totalLength);
|
|
1663
|
+
let offset = 0;
|
|
1664
|
+
for (const part of parts) {
|
|
1665
|
+
result.set(part, offset);
|
|
1666
|
+
offset += part.length;
|
|
1667
|
+
}
|
|
1668
|
+
return result;
|
|
1669
|
+
}
|
|
1670
|
+
/**
|
|
1671
|
+
* BIP-340-style tagged hasher for Spark signing statements. Tag order matters and acts as the
|
|
1672
|
+
* statement version: a schema change must change the tag, not the encoding.
|
|
1673
|
+
*/
|
|
1674
|
+
var Hasher = class Hasher {
|
|
1675
|
+
hasher;
|
|
1676
|
+
constructor(tag) {
|
|
1677
|
+
const tagHash = sha256(serializeTag(tag));
|
|
1678
|
+
this.hasher = sha256.create();
|
|
1679
|
+
this.hasher.update(tagHash);
|
|
1680
|
+
this.hasher.update(tagHash);
|
|
1681
|
+
}
|
|
1682
|
+
static new(tag) {
|
|
1683
|
+
return new Hasher(tag);
|
|
1684
|
+
}
|
|
1685
|
+
addBytes(b) {
|
|
1686
|
+
this.addValue(b);
|
|
1687
|
+
return this;
|
|
1688
|
+
}
|
|
1689
|
+
addString(s) {
|
|
1690
|
+
this.addValue(utf8ToBytes(s));
|
|
1691
|
+
return this;
|
|
1692
|
+
}
|
|
1693
|
+
/** Numbers must be non-negative safe integers; bigints may cover the full uint64 range. */
|
|
1694
|
+
addUint64(v) {
|
|
1695
|
+
let value;
|
|
1696
|
+
if (typeof v === "number") {
|
|
1697
|
+
if (!Number.isSafeInteger(v) || v < 0) throw new SparkInputError("addUint64: number must be a non-negative safe integer");
|
|
1698
|
+
value = BigInt(v);
|
|
1699
|
+
} else {
|
|
1700
|
+
if (v < 0n || v > MAX_UINT64$1) throw new SparkInputError("addUint64: bigint must be within uint64 range");
|
|
1701
|
+
value = v;
|
|
1702
|
+
}
|
|
1703
|
+
const valueBytes = uint64be(value);
|
|
1704
|
+
this.addValue(valueBytes);
|
|
1705
|
+
return this;
|
|
1706
|
+
}
|
|
1707
|
+
addUint32(v) {
|
|
1708
|
+
if (!Number.isSafeInteger(v) || v < 0 || v > 4294967295) throw new SparkInputError("addUint32: value must be a valid uint32");
|
|
1709
|
+
return this.addUint64(BigInt(v));
|
|
1710
|
+
}
|
|
1711
|
+
addUint16(v) {
|
|
1712
|
+
if (!Number.isSafeInteger(v) || v < 0 || v > 65535) throw new SparkInputError("addUint16: value must be a valid uint16");
|
|
1713
|
+
return this.addUint64(BigInt(v));
|
|
1714
|
+
}
|
|
1715
|
+
addUint8(v) {
|
|
1716
|
+
if (!Number.isSafeInteger(v) || v < 0 || v > 255) throw new SparkInputError("addUint8: value must be a valid uint8");
|
|
1717
|
+
return this.addUint64(BigInt(v));
|
|
1718
|
+
}
|
|
1719
|
+
/** Count, then key/value pairs sorted by UTF-8 bytewise key order. */
|
|
1720
|
+
addMapStringToBytes(m) {
|
|
1721
|
+
this.addUint64(Object.keys(m).length);
|
|
1722
|
+
const pairs = Object.entries(m).map(([key, value]) => ({
|
|
1723
|
+
key,
|
|
1724
|
+
value,
|
|
1725
|
+
keyBytes: utf8ToBytes(key)
|
|
1726
|
+
}));
|
|
1727
|
+
pairs.sort((a, b) => compareBytes(a.keyBytes, b.keyBytes));
|
|
1728
|
+
for (const pair of pairs) {
|
|
1729
|
+
this.addString(pair.key);
|
|
1730
|
+
this.addBytes(pair.value);
|
|
1731
|
+
}
|
|
1732
|
+
return this;
|
|
1733
|
+
}
|
|
1734
|
+
/** Count, then key/value pairs sorted by UTF-8 bytewise key order. */
|
|
1735
|
+
addMapStringToUint64(m) {
|
|
1736
|
+
this.addUint64(Object.keys(m).length);
|
|
1737
|
+
const pairs = Object.entries(m).map(([key, value]) => ({
|
|
1738
|
+
key,
|
|
1739
|
+
value,
|
|
1740
|
+
keyBytes: utf8ToBytes(key)
|
|
1741
|
+
}));
|
|
1742
|
+
pairs.sort((a, b) => compareBytes(a.keyBytes, b.keyBytes));
|
|
1743
|
+
for (const pair of pairs) {
|
|
1744
|
+
this.addString(pair.key);
|
|
1745
|
+
this.addUint64(pair.value);
|
|
1746
|
+
}
|
|
1747
|
+
return this;
|
|
1748
|
+
}
|
|
1749
|
+
addValue(valueBytes) {
|
|
1750
|
+
const lengthBytes = uint64be(BigInt(valueBytes.length));
|
|
1751
|
+
this.hasher.update(lengthBytes);
|
|
1752
|
+
this.hasher.update(valueBytes);
|
|
1753
|
+
}
|
|
1754
|
+
hash() {
|
|
1755
|
+
return this.hasher.digest();
|
|
1756
|
+
}
|
|
1757
|
+
};
|
|
1758
|
+
function newHasher(tag) {
|
|
1759
|
+
return Hasher.new(tag);
|
|
1760
|
+
}
|
|
1761
|
+
//#endregion
|
|
1762
|
+
//#region src/core/hashing/statements.ts
|
|
1763
|
+
/**
|
|
1764
|
+
* The transfer-package digest the sender signs: the HASH_VARIANT_V2 tagged hashstructure digest
|
|
1765
|
+
* over the transfer id and the key-tweak map. The SDK only ever produces V2 packages, so any other
|
|
1766
|
+
* variant — and any package carrying a `delegationIntent` (Spark Pull) — is rejected.
|
|
1767
|
+
*/
|
|
1768
|
+
function transferPackageDigest(transferId, transferPackage) {
|
|
1769
|
+
if (transferPackage.hashVariant !== HashVariant.V2) throw new SparkInputError("transfer package: only hash variant HASH_VARIANT_V2 is supported");
|
|
1770
|
+
if (transferPackage.delegationIntent !== void 0) throw new SparkInputError("transfer package: delegation intent is not supported");
|
|
1771
|
+
return newHasher([
|
|
1772
|
+
"spark",
|
|
1773
|
+
"transfer",
|
|
1774
|
+
"signing payload"
|
|
1775
|
+
]).addBytes(uuidToBytes(transferId)).addMapStringToBytes(transferPackage.keyTweakPackage).hash();
|
|
1776
|
+
}
|
|
1777
|
+
/** The claim-package digest: tagged hasher over the transfer id and tweak map. */
|
|
1778
|
+
function claimPackageDigest(transferId, keyTweakPackage) {
|
|
1779
|
+
return newHasher([
|
|
1780
|
+
"spark",
|
|
1781
|
+
"claim",
|
|
1782
|
+
"signing payload"
|
|
1783
|
+
]).addBytes(uuidToBytes(transferId)).addMapStringToBytes(keyTweakPackage).hash();
|
|
1784
|
+
}
|
|
1785
|
+
/** Sha256(utf8(leafId) ‖ utf8(transferId) ‖ secretCipher) — the per-leaf send signature digest. */
|
|
1786
|
+
function sendLeafSigningDigest(leafId, transferId, secretCipher) {
|
|
1787
|
+
return sha256(concatBytes(utf8ToBytes(leafId), utf8ToBytes(transferId), secretCipher));
|
|
1788
|
+
}
|
|
1789
|
+
/** Deposit-address proof of possession, signed with the identity key at address generation. */
|
|
1790
|
+
function proofOfPossessionDigest(userPublicKey, operatorPublicKey, depositAddress) {
|
|
1791
|
+
return newHasher([
|
|
1792
|
+
"spark",
|
|
1793
|
+
"deposit",
|
|
1794
|
+
"proof_of_possession"
|
|
1795
|
+
]).addBytes(userPublicKey).addBytes(operatorPublicKey).addBytes(utf8ToBytes(depositAddress)).hash();
|
|
1796
|
+
}
|
|
1797
|
+
const STATIC_DEPOSIT_REQUEST_TYPE = {
|
|
1798
|
+
fixed: 0,
|
|
1799
|
+
maxFee: 1,
|
|
1800
|
+
refund: 2
|
|
1801
|
+
};
|
|
1802
|
+
/**
|
|
1803
|
+
* The static-deposit user statement digest: SHA-256 over the concatenation "claim_static_deposit" ‖
|
|
1804
|
+
* network ‖ txid(hex text) ‖ vout(u32 LE) ‖ requestType(u8) ‖ creditAmount(u64 LE) ‖ payload where
|
|
1805
|
+
* payload is the raw SSP signature bytes for claims/max-fee and the raw sighash of the refund spend
|
|
1806
|
+
* transaction for refunds. Network is the lowercase network name ("mainnet"/"regtest"). This is the
|
|
1807
|
+
* only form the SDK signs (spark-wallet.ts `getStaticDepositSigningPayload` + sha256).
|
|
1808
|
+
*/
|
|
1809
|
+
function staticDepositStatementDigest({ transactionId, outputIndex, network, requestType, creditAmountSats, payload }) {
|
|
1810
|
+
if (!Number.isSafeInteger(outputIndex) || outputIndex < 0 || outputIndex > 4294967295) throw new SparkInputError("static deposit statement: output index must be a uint32");
|
|
1811
|
+
if (!Number.isSafeInteger(creditAmountSats) || creditAmountSats < 0) throw new SparkInputError("static deposit statement: credit amount must be a safe integer");
|
|
1812
|
+
const requestTypeValue = STATIC_DEPOSIT_REQUEST_TYPE[requestType];
|
|
1813
|
+
const outputIndexBytes = /* @__PURE__ */ new Uint8Array(4);
|
|
1814
|
+
new DataView(outputIndexBytes.buffer).setUint32(0, outputIndex, true);
|
|
1815
|
+
const creditAmountBytes = /* @__PURE__ */ new Uint8Array(8);
|
|
1816
|
+
new DataView(creditAmountBytes.buffer).setBigUint64(0, BigInt(creditAmountSats), true);
|
|
1817
|
+
return sha256(concatBytes(utf8ToBytes("claim_static_deposit"), utf8ToBytes(network), utf8ToBytes(transactionId), outputIndexBytes, new Uint8Array([requestTypeValue]), creditAmountBytes, payload));
|
|
1818
|
+
}
|
|
1819
|
+
const NETWORK_STATEMENT_NAME = {
|
|
1820
|
+
mainnet: "MAINNET",
|
|
1821
|
+
regtest: "REGTEST"
|
|
1822
|
+
};
|
|
1823
|
+
/**
|
|
1824
|
+
* The watchtower recovery statement digest: sha256("recover_watchtower_exited_leaf" ‖ NETWORK ‖
|
|
1825
|
+
* leafId ‖ recoveryTxSighash) where NETWORK is the upper-case proto network name
|
|
1826
|
+
* ("MAINNET"/"REGTEST") — unlike the lowercase, Bitcoin-style names the static deposit statements
|
|
1827
|
+
* use.
|
|
1828
|
+
*/
|
|
1829
|
+
function watchtowerRecoveryStatementDigest(network, leafId, recoveryTxSighash) {
|
|
1830
|
+
return sha256(concatBytes(utf8ToBytes("recover_watchtower_exited_leaf"), utf8ToBytes(NETWORK_STATEMENT_NAME[network]), utf8ToBytes(uuidFromBytes(uuidToBytes(leafId))), recoveryTxSighash));
|
|
1831
|
+
}
|
|
1832
|
+
/**
|
|
1833
|
+
* Sha256 over the base64-decoded SSP protected challenge — the digest the SSP session signature
|
|
1834
|
+
* covers (upstream graphql/client.ts `authenticate`). The SSP emits unpadded base64url; like Node's
|
|
1835
|
+
* base64 decoder the standard-alphabet characters and padding are normalized away before decoding
|
|
1836
|
+
* with the URL-safe, unpadded variant.
|
|
1837
|
+
*
|
|
1838
|
+
* The decoded bytes are server-chosen input to the identity key — a signature over this digest
|
|
1839
|
+
* verifies anywhere a raw sha256 digest is signed — so they are accepted only as an
|
|
1840
|
+
* `ssp_authn.ProtectedChallenge` whose `challenge.public_key` is `identityPublicKey` (either key
|
|
1841
|
+
* encoding). Unknown fields are tolerated; the bytes are signed verbatim. Ported from
|
|
1842
|
+
* breez-spark-sdk `crates/spark/src/ssp/challenge.rs` @956ff90.
|
|
1843
|
+
*/
|
|
1844
|
+
function sspChallengeDigest(protectedChallenge, identityPublicKey) {
|
|
1845
|
+
let decoded;
|
|
1846
|
+
try {
|
|
1847
|
+
const normalized = protectedChallenge.replaceAll("+", "-").replaceAll("/", "_").replaceAll("=", "");
|
|
1848
|
+
decoded = base64urlnopad.decode(normalized);
|
|
1849
|
+
} catch {
|
|
1850
|
+
throw new SparkInputError("ssp challenge: protected challenge is not valid base64");
|
|
1851
|
+
}
|
|
1852
|
+
let protectedMsg;
|
|
1853
|
+
try {
|
|
1854
|
+
protectedMsg = fromBinary(ProtectedChallengeSchema, decoded);
|
|
1855
|
+
} catch {
|
|
1856
|
+
throw new SparkInputError("ssp challenge: not a ssp_authn.ProtectedChallenge");
|
|
1857
|
+
}
|
|
1858
|
+
const { challenge } = protectedMsg;
|
|
1859
|
+
if (challenge === void 0) throw new SparkInputError("ssp challenge: missing challenge");
|
|
1860
|
+
if (challenge.publicKey.length === 0) throw new SparkInputError("ssp challenge: missing public key");
|
|
1861
|
+
let issuedTo;
|
|
1862
|
+
let identity;
|
|
1863
|
+
try {
|
|
1864
|
+
issuedTo = secp256k1.Point.fromBytes(challenge.publicKey);
|
|
1865
|
+
identity = secp256k1.Point.fromBytes(identityPublicKey);
|
|
1866
|
+
} catch {
|
|
1867
|
+
throw new SparkInputError("ssp challenge: malformed public key");
|
|
1868
|
+
}
|
|
1869
|
+
if (!issuedTo.equals(identity)) throw new SparkInputError("ssp challenge: challenge is issued to a different public key");
|
|
1870
|
+
return sha256(decoded);
|
|
1871
|
+
}
|
|
1872
|
+
/** Sha256 over the serialized spark_authn.Challenge — the digest the session signature covers. */
|
|
1873
|
+
function authnChallengeDigest(challenge) {
|
|
1874
|
+
return sha256(toBinary(ChallengeSchema, challenge));
|
|
1875
|
+
}
|
|
1876
|
+
//#endregion
|
|
1877
|
+
//#region src/core/hashing/protohash.ts
|
|
1878
|
+
const BOOL_TAG = utf8ToBytes("b");
|
|
1879
|
+
const MAP_TAG = utf8ToBytes("d");
|
|
1880
|
+
const FLOAT_TAG = utf8ToBytes("f");
|
|
1881
|
+
const INT_TAG = utf8ToBytes("i");
|
|
1882
|
+
const LIST_TAG = utf8ToBytes("l");
|
|
1883
|
+
const BYTES_TAG = utf8ToBytes("r");
|
|
1884
|
+
const STRING_TAG = utf8ToBytes("u");
|
|
1885
|
+
const NAN_BITS = 9221120237041090561n;
|
|
1886
|
+
const MAX_UINT64 = 18446744073709551615n;
|
|
1887
|
+
const WKT_PREFIX = "google.protobuf.";
|
|
1888
|
+
function expectNumber(value, context) {
|
|
1889
|
+
if (typeof value !== "number") throw new SparkInputError(`protohash: ${context} expected a number`);
|
|
1890
|
+
return value;
|
|
1891
|
+
}
|
|
1892
|
+
function expectInteger(value, context) {
|
|
1893
|
+
if (typeof value === "bigint") return value;
|
|
1894
|
+
if (typeof value === "number" && Number.isInteger(value)) return BigInt(value);
|
|
1895
|
+
throw new SparkInputError(`protohash: ${context} expected an integer`);
|
|
1896
|
+
}
|
|
1897
|
+
function expectString(value, context) {
|
|
1898
|
+
if (typeof value !== "string") throw new SparkInputError(`protohash: ${context} expected a string`);
|
|
1899
|
+
return value;
|
|
1900
|
+
}
|
|
1901
|
+
function expectBytes(value, context) {
|
|
1902
|
+
if (!(value instanceof Uint8Array)) throw new SparkInputError(`protohash: ${context} expected bytes`);
|
|
1903
|
+
return value;
|
|
1904
|
+
}
|
|
1905
|
+
function expectReflectMessage(value, context) {
|
|
1906
|
+
if (!isReflectMessage(value)) throw new SparkInputError(`protohash: ${context} expected a message`);
|
|
1907
|
+
return value;
|
|
1908
|
+
}
|
|
1909
|
+
function expectReflectList(value, context) {
|
|
1910
|
+
if (!isReflectList(value)) throw new SparkInputError(`protohash: ${context} expected a list`);
|
|
1911
|
+
return value;
|
|
1912
|
+
}
|
|
1913
|
+
function expectReflectMap(value, context) {
|
|
1914
|
+
if (!isReflectMap(value)) throw new SparkInputError(`protohash: ${context} expected a map`);
|
|
1915
|
+
return value;
|
|
1916
|
+
}
|
|
1917
|
+
function tagged(tag, value) {
|
|
1918
|
+
const h = sha256.create();
|
|
1919
|
+
h.update(tag);
|
|
1920
|
+
h.update(value);
|
|
1921
|
+
return h.digest();
|
|
1922
|
+
}
|
|
1923
|
+
function hashBool(v) {
|
|
1924
|
+
return tagged(BOOL_TAG, v ? utf8ToBytes("1") : utf8ToBytes("0"));
|
|
1925
|
+
}
|
|
1926
|
+
function hashU64(v) {
|
|
1927
|
+
const bytes = uint64be(v & MAX_UINT64);
|
|
1928
|
+
return tagged(INT_TAG, bytes);
|
|
1929
|
+
}
|
|
1930
|
+
function hashF64(v) {
|
|
1931
|
+
const bytes = /* @__PURE__ */ new Uint8Array(8);
|
|
1932
|
+
const view = new DataView(bytes.buffer);
|
|
1933
|
+
if (Number.isNaN(v)) view.setBigUint64(0, NAN_BITS, false);
|
|
1934
|
+
else view.setFloat64(0, v === 0 ? 0 : v, false);
|
|
1935
|
+
return tagged(FLOAT_TAG, bytes);
|
|
1936
|
+
}
|
|
1937
|
+
function hashString(v) {
|
|
1938
|
+
return tagged(STRING_TAG, utf8ToBytes(v));
|
|
1939
|
+
}
|
|
1940
|
+
function hashBytes(v) {
|
|
1941
|
+
return tagged(BYTES_TAG, v);
|
|
1942
|
+
}
|
|
1943
|
+
function hashFieldKey(number) {
|
|
1944
|
+
return hashU64(BigInt(number));
|
|
1945
|
+
}
|
|
1946
|
+
const INTEGER_SCALAR_TYPES = /* @__PURE__ */ new Set([
|
|
1947
|
+
ScalarType.INT32,
|
|
1948
|
+
ScalarType.SINT32,
|
|
1949
|
+
ScalarType.SFIXED32,
|
|
1950
|
+
ScalarType.INT64,
|
|
1951
|
+
ScalarType.SINT64,
|
|
1952
|
+
ScalarType.SFIXED64,
|
|
1953
|
+
ScalarType.UINT32,
|
|
1954
|
+
ScalarType.FIXED32,
|
|
1955
|
+
ScalarType.UINT64,
|
|
1956
|
+
ScalarType.FIXED64
|
|
1957
|
+
]);
|
|
1958
|
+
function hashScalar(scalar, value) {
|
|
1959
|
+
if (scalar === ScalarType.BOOL) return hashBool(value === true);
|
|
1960
|
+
if (scalar === ScalarType.DOUBLE) return hashF64(expectNumber(value, "double"));
|
|
1961
|
+
if (scalar === ScalarType.FLOAT) return hashF64(Math.fround(expectNumber(value, "float")));
|
|
1962
|
+
if (INTEGER_SCALAR_TYPES.has(scalar)) return hashU64(expectInteger(value, "integer scalar"));
|
|
1963
|
+
if (scalar === ScalarType.STRING) return hashString(expectString(value, "string"));
|
|
1964
|
+
return hashBytes(expectBytes(value, "bytes"));
|
|
1965
|
+
}
|
|
1966
|
+
function hashEnum(value) {
|
|
1967
|
+
return hashU64(expectInteger(value, "enum"));
|
|
1968
|
+
}
|
|
1969
|
+
function isScalarDefault(scalar, value) {
|
|
1970
|
+
switch (scalar) {
|
|
1971
|
+
case ScalarType.BOOL: return value === false;
|
|
1972
|
+
case ScalarType.STRING: return value === "";
|
|
1973
|
+
case ScalarType.BYTES: return value instanceof Uint8Array && value.length === 0;
|
|
1974
|
+
case ScalarType.DOUBLE:
|
|
1975
|
+
case ScalarType.FLOAT: return value === 0;
|
|
1976
|
+
default: return value === 0 || value === 0n;
|
|
1977
|
+
}
|
|
1978
|
+
}
|
|
1979
|
+
function isEmptyMessage(message) {
|
|
1980
|
+
for (const field of message.desc.fields) if (message.isSet(field)) return false;
|
|
1981
|
+
return true;
|
|
1982
|
+
}
|
|
1983
|
+
function isDefaultValue(field, value) {
|
|
1984
|
+
switch (field.fieldKind) {
|
|
1985
|
+
case "scalar": return isScalarDefault(field.scalar, value);
|
|
1986
|
+
case "enum": return value === (field.getDefaultValue() ?? 0);
|
|
1987
|
+
case "message": return isReflectMessage(value) && isEmptyMessage(value);
|
|
1988
|
+
default: return false;
|
|
1989
|
+
}
|
|
1990
|
+
}
|
|
1991
|
+
function hashSingular(field, value) {
|
|
1992
|
+
switch (field.fieldKind) {
|
|
1993
|
+
case "scalar": return hashScalar(field.scalar, value);
|
|
1994
|
+
case "enum": return hashEnum(value);
|
|
1995
|
+
case "message": return hashMessage(expectReflectMessage(value, field.name));
|
|
1996
|
+
default: return;
|
|
1997
|
+
}
|
|
1998
|
+
}
|
|
1999
|
+
/** Hashes a repeated element or a map key/value against the element kind of `field`. */
|
|
2000
|
+
function hashElement(field, value) {
|
|
2001
|
+
if (field.fieldKind === "list") switch (field.listKind) {
|
|
2002
|
+
case "scalar": return hashScalar(field.scalar, value);
|
|
2003
|
+
case "enum": return hashEnum(value);
|
|
2004
|
+
case "message": return hashMessage(expectReflectMessage(value, field.name));
|
|
2005
|
+
}
|
|
2006
|
+
if (field.fieldKind === "map") switch (field.mapKind) {
|
|
2007
|
+
case "scalar": return hashScalar(field.scalar, value);
|
|
2008
|
+
case "enum": return hashEnum(value);
|
|
2009
|
+
case "message": return hashMessage(expectReflectMessage(value, field.name));
|
|
2010
|
+
}
|
|
2011
|
+
return hashSingular(field, value);
|
|
2012
|
+
}
|
|
2013
|
+
function hashList(field, value) {
|
|
2014
|
+
const list = expectReflectList(value, field.name);
|
|
2015
|
+
if (list.size === 0) return;
|
|
2016
|
+
const h = sha256.create();
|
|
2017
|
+
h.update(LIST_TAG);
|
|
2018
|
+
for (const item of list) {
|
|
2019
|
+
const itemHash = hashElement(field, item);
|
|
2020
|
+
if (itemHash !== void 0) h.update(itemHash);
|
|
2021
|
+
}
|
|
2022
|
+
return h.digest();
|
|
2023
|
+
}
|
|
2024
|
+
function hashMap(field, mapValue) {
|
|
2025
|
+
if (field.fieldKind !== "map") throw new SparkInputError(`protohash: ${field.name} is not a map field`);
|
|
2026
|
+
const map = expectReflectMap(mapValue, field.name);
|
|
2027
|
+
const entries = [];
|
|
2028
|
+
for (const [key, value] of map.entries()) {
|
|
2029
|
+
const kHash = hashScalar(field.mapKey, key);
|
|
2030
|
+
const vHash = hashElement(field, value);
|
|
2031
|
+
if (vHash === void 0) return;
|
|
2032
|
+
entries.push({
|
|
2033
|
+
k: kHash,
|
|
2034
|
+
v: vHash
|
|
2035
|
+
});
|
|
2036
|
+
}
|
|
2037
|
+
if (entries.length === 0) return;
|
|
2038
|
+
entries.sort((a, b) => compareBytes(a.k, b.k));
|
|
2039
|
+
const h = sha256.create();
|
|
2040
|
+
h.update(MAP_TAG);
|
|
2041
|
+
for (const entry of entries) {
|
|
2042
|
+
h.update(entry.k);
|
|
2043
|
+
h.update(entry.v);
|
|
2044
|
+
}
|
|
2045
|
+
return h.digest();
|
|
2046
|
+
}
|
|
2047
|
+
function hashFieldValue(field, value) {
|
|
2048
|
+
if (field.fieldKind === "list") return hashList(field, value);
|
|
2049
|
+
if (field.fieldKind === "map") return hashMap(field, value);
|
|
2050
|
+
return hashSingular(field, value);
|
|
2051
|
+
}
|
|
2052
|
+
function fieldByName(desc, name) {
|
|
2053
|
+
const field = desc.fields.find((f) => f.name === name);
|
|
2054
|
+
if (field === void 0) throw new SparkInputError(`protohash: missing field ${name} on ${desc.typeName}`);
|
|
2055
|
+
return field;
|
|
2056
|
+
}
|
|
2057
|
+
/** Listed fields hashed in the given order under "l", defaults included. */
|
|
2058
|
+
function hashFieldsByNames(message, names) {
|
|
2059
|
+
const h = sha256.create();
|
|
2060
|
+
h.update(LIST_TAG);
|
|
2061
|
+
for (const name of names) {
|
|
2062
|
+
const field = fieldByName(message.desc, name);
|
|
2063
|
+
const valueHash = hashSingular(field, message.get(field));
|
|
2064
|
+
if (valueHash !== void 0) h.update(valueHash);
|
|
2065
|
+
}
|
|
2066
|
+
return h.digest();
|
|
2067
|
+
}
|
|
2068
|
+
function hashMessage(message) {
|
|
2069
|
+
const { typeName } = message.desc;
|
|
2070
|
+
if (typeName.startsWith(WKT_PREFIX)) {
|
|
2071
|
+
if (typeName === "google.protobuf.Timestamp") return hashFieldsByNames(message, ["seconds", "nanos"]);
|
|
2072
|
+
if (typeName !== "google.protobuf.Empty") throw new SparkError(`protohash: unsupported well-known type ${typeName}`);
|
|
2073
|
+
}
|
|
2074
|
+
const fieldHashes = [];
|
|
2075
|
+
for (const field of message.desc.fields) {
|
|
2076
|
+
if (!message.isSet(field)) continue;
|
|
2077
|
+
const value = message.get(field);
|
|
2078
|
+
if (isDefaultValue(field, value)) continue;
|
|
2079
|
+
const vHash = hashFieldValue(field, value);
|
|
2080
|
+
if (vHash === void 0) continue;
|
|
2081
|
+
fieldHashes.push({
|
|
2082
|
+
number: field.number,
|
|
2083
|
+
k: hashFieldKey(field.number),
|
|
2084
|
+
v: vHash
|
|
2085
|
+
});
|
|
2086
|
+
}
|
|
2087
|
+
fieldHashes.sort((a, b) => a.number - b.number);
|
|
2088
|
+
const h = sha256.create();
|
|
2089
|
+
h.update(MAP_TAG);
|
|
2090
|
+
for (const entry of fieldHashes) {
|
|
2091
|
+
h.update(entry.k);
|
|
2092
|
+
h.update(entry.v);
|
|
2093
|
+
}
|
|
2094
|
+
return h.digest();
|
|
2095
|
+
}
|
|
2096
|
+
/**
|
|
2097
|
+
* Protoreflecthash over a protobuf-es message: the deterministic SHA-256 digest Go's
|
|
2098
|
+
* `protohash.Hash` and Rust `spark-token-primitives` produce identically. The well-known types
|
|
2099
|
+
* handled by our protos (Timestamp, Empty) follow upstream; any other `google.protobuf` type
|
|
2100
|
+
* throws. Unknown fields are ignored.
|
|
2101
|
+
*/
|
|
2102
|
+
function hashProto(schema, message) {
|
|
2103
|
+
const reflected = reflect(schema, message);
|
|
2104
|
+
const { typeName } = reflected.desc;
|
|
2105
|
+
const digest = hashMessage(reflected);
|
|
2106
|
+
if (digest === void 0) throw new SparkInputError(`protohash: nothing to hash in ${typeName}`);
|
|
2107
|
+
return digest;
|
|
2108
|
+
}
|
|
2109
|
+
//#endregion
|
|
2110
|
+
//#region src/core/hashing/token.ts
|
|
2111
|
+
/** Protoreflecthash of `spark_token.PartialTokenTransaction` — what owners sign V3 inputs over. */
|
|
2112
|
+
function hashPartialTokenTransaction(partialTokenTransaction) {
|
|
2113
|
+
if (partialTokenTransaction === void 0 || partialTokenTransaction === null) throw new SparkInputError("partial token transaction cannot be nil");
|
|
2114
|
+
return hashProto(PartialTokenTransactionSchema, partialTokenTransaction);
|
|
2115
|
+
}
|
|
2116
|
+
/** Protoreflecthash of `spark_token.FinalTokenTransaction`. */
|
|
2117
|
+
function hashFinalTokenTransaction(finalTokenTransaction) {
|
|
2118
|
+
if (finalTokenTransaction === void 0 || finalTokenTransaction === null) throw new SparkInputError("final token transaction cannot be nil");
|
|
2119
|
+
return hashProto(FinalTokenTransactionSchema, finalTokenTransaction);
|
|
2120
|
+
}
|
|
2121
|
+
//#endregion
|
|
2122
|
+
export { SparkAuthnService as $, EPHEMERAL_ANCHOR_SCRIPT as A, SecretShareSchema as At, parseTransaction as B, TransferReceiverStatus as Bt, createInitialTimelockRefundTxs as C, InitiatePreimageSwapRequest_Reason as Ct, txId as D, RenewNodeTimelockSigningJobSchema as Dt, estimateVbytes as E, Order as Et, checkIfValidSequence as F, SparkAddressSchema as Ft, PartialTokenOutputSchema as G, SignatureScheme as Gt, taprootScriptSpendSighash as H, TransferType as Ht, doesTxnNeedRenewed as I, SparkInvoiceFieldsSchema as It, SparkTokenService as J, PartialTokenTransactionSchema as K, getNextHTLCTransactionSequence as L, SparkService as Lt, computeTaprootKeyNoScript as M, SendLeafKeyTweaksSchema as Mt, p2trScriptFromPublicKey as N, SenderTransferPackageSchema as Nt, txIdInputBytes as O, RenewNodeZeroTimelockSigningJobSchema as Ot, xOnlyPublicKey as P, SigningJobSchema as Pt, ChallengeSchema as Q, getTimelockFromSequence as R, StartTransferRequestSchema as Rt, createInitialTimelockNodeTx as S, HashVariant as St, createZeroTimelockNodeTx as T, InvoiceStatus as Tt, CommitStatus as U, TreeNodeStatus as Ut, taprootKeySpendSighash as V, TransferStatus as Vt, InvoiceAttachmentSchema as W, UserSignedTxSigningJobSchema as Wt, TokenTransactionMetadataSchema as X, TokenOutputStatus as Y, TokenTransactionStatus as Z, addressToScript as _, AdaptorPublicKeyPackageSchema as _t, proofOfPossessionDigest as a, uuidToBytes as at, createDecrementedTimelockNodeTx as b, ClaimPackageSchema as bt, staticDepositStatementDigest as c, uint64be as ct, LIGHTNING_HTLC_SEQUENCE as d, assertU32 as dt, hashSparkInvoice as et, constructHtlcSenderSpend as f, requireLength as ft, lightningHtlcOutputScript as g, sparkNetworkProto as gt, finalizeHtlcSpend as h, sparkNetworkFromProto as ht, claimPackageDigest as i, uuidFromBytes as it, btcNetwork as j, SendLeafKeyTweakSchema as jt, verifyFinalizedTaprootSignature as k, RenewRefundTimelockSigningJobSchema as kt, transferPackageDigest as l, assertCompressedKey as lt, createSequenceLockScript as m, sparkNetworkConfig as mt, hashPartialTokenTransaction as n, protoInvoiceToPlain as nt, sendLeafSigningDigest as o, uuidv7 as ot, createRefundTxsForLightning as p, u64ToSats as pt, SignatureWithIndexSchema as q, authnChallengeDigest as r, validateInvoiceFields as rt, sspChallengeDigest as s, compareBytes as st, hashFinalTokenTransaction as t, encodeInvoiceFields as tt, watchtowerRecoveryStatementDigest as u, assertSats as ut, createConnectorRefundTxs as v, ClaimLeafKeyTweakSchema as vt, createMultiInputRootTx as w, InputSigningDataSchema as wt, createDecrementedTimelockRefundTxs as x, Direction as xt, createCurrentTimelockRefundTxs as y, ClaimLeafKeyTweaksSchema as yt, isZeroTimelock as z, TransferPackageSchema as zt };
|