@keetanetwork/keetanet-client 0.12.0 → 0.14.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (213) hide show
  1. package/api/index.d.ts +23 -2
  2. package/api/node.d.ts +7 -1
  3. package/api/p2p.d.ts +13 -0
  4. package/api/vote.d.ts +10 -0
  5. package/benchmarking/test.d.ts +4 -0
  6. package/client/builder.d.ts +6 -4
  7. package/client/client_common_tests.d.ts +18 -0
  8. package/client/index-browser.d.ts +42 -14
  9. package/client/index-browser.js +2577 -881
  10. package/client/index.d.ts +42 -14
  11. package/client/index.js +2318 -663
  12. package/config/index.d.ts +2 -0
  13. package/docs/assets/hierarchy.js +1 -1
  14. package/docs/assets/navigation.js +1 -1
  15. package/docs/assets/search.js +1 -1
  16. package/docs/classes/KeetaNetSDK.Client.html +14 -10
  17. package/docs/classes/KeetaNetSDK.Referenced.BaseSet.html +2 -2
  18. package/docs/classes/KeetaNetSDK.Referenced.BaseVoteBuilder.html +10 -0
  19. package/docs/classes/KeetaNetSDK.Referenced.Block.html +9 -5
  20. package/docs/classes/KeetaNetSDK.Referenced.BlockBuilder.html +3 -2
  21. package/docs/classes/KeetaNetSDK.Referenced.BlockHash.html +1 -1
  22. package/docs/classes/KeetaNetSDK.Referenced.BlockOperation.html +1 -1
  23. package/docs/classes/KeetaNetSDK.Referenced.BlockOperationCREATE_IDENTIFIER.html +4 -4
  24. package/docs/classes/KeetaNetSDK.Referenced.BlockOperationMANAGE_CERTIFICATE.html +2 -2
  25. package/docs/classes/KeetaNetSDK.Referenced.BlockOperationMODIFY_PERMISSIONS.html +1 -1
  26. package/docs/classes/KeetaNetSDK.Referenced.BlockOperationRECEIVE.html +1 -1
  27. package/docs/classes/KeetaNetSDK.Referenced.BlockOperationSEND.html +1 -1
  28. package/docs/classes/KeetaNetSDK.Referenced.BlockOperationSET_INFO.html +1 -1
  29. package/docs/classes/KeetaNetSDK.Referenced.BlockOperationSET_REP.html +1 -1
  30. package/docs/classes/KeetaNetSDK.Referenced.BlockOperationTOKEN_ADMIN_MODIFY_BALANCE.html +1 -1
  31. package/docs/classes/KeetaNetSDK.Referenced.BlockOperationTOKEN_ADMIN_SUPPLY.html +1 -1
  32. package/docs/classes/KeetaNetSDK.Referenced.Certificate.html +26 -8
  33. package/docs/classes/KeetaNetSDK.Referenced.CertificateBundle.html +1 -1
  34. package/docs/classes/KeetaNetSDK.Referenced.CertificateHash.html +1 -1
  35. package/docs/classes/KeetaNetSDK.Referenced.ECDSAKeyPair.html +1 -1
  36. package/docs/classes/KeetaNetSDK.Referenced.ECDSASECP256K1KeyPair.html +1 -1
  37. package/docs/classes/KeetaNetSDK.Referenced.ECDSASECP256K1PrivateKey.html +1 -1
  38. package/docs/classes/KeetaNetSDK.Referenced.ECDSASECP256K1PublicKey.html +1 -1
  39. package/docs/classes/KeetaNetSDK.Referenced.ECDSASECP256K1Signature.html +1 -1
  40. package/docs/classes/KeetaNetSDK.Referenced.ECDSASECP256R1KeyPair.html +1 -1
  41. package/docs/classes/KeetaNetSDK.Referenced.ECDSASECP256R1PrivateKey.html +1 -1
  42. package/docs/classes/KeetaNetSDK.Referenced.ECDSASECP256R1PublicKey.html +1 -1
  43. package/docs/classes/KeetaNetSDK.Referenced.ECDSASECP256R1Signature.html +1 -1
  44. package/docs/classes/KeetaNetSDK.Referenced.ED25519KeyPair.html +1 -1
  45. package/docs/classes/KeetaNetSDK.Referenced.ED25519PrivateKey.html +1 -1
  46. package/docs/classes/KeetaNetSDK.Referenced.ED25519PublicKey.html +1 -1
  47. package/docs/classes/KeetaNetSDK.Referenced.ED25519Signature.html +1 -1
  48. package/docs/classes/KeetaNetSDK.Referenced.ExternalKeyPair.html +1 -1
  49. package/docs/classes/KeetaNetSDK.Referenced.ExternalSet.html +1 -1
  50. package/docs/classes/KeetaNetSDK.Referenced.IdentifierKey.html +1 -1
  51. package/docs/classes/KeetaNetSDK.Referenced.IdentifierKeyPair.html +1 -1
  52. package/docs/classes/KeetaNetSDK.Referenced.KeetaNetError.html +1 -1
  53. package/docs/classes/KeetaNetSDK.Referenced.KeyInterface.html +1 -1
  54. package/docs/classes/KeetaNetSDK.Referenced.KeyStorage.html +1 -1
  55. package/docs/classes/KeetaNetSDK.Referenced.Ledger.html +5 -2
  56. package/docs/classes/KeetaNetSDK.Referenced.LedgerAtomicInterface.html +3 -1
  57. package/docs/classes/KeetaNetSDK.Referenced.P2PSwitch.html +6 -2
  58. package/docs/classes/KeetaNetSDK.Referenced.PermissionSetHolder.html +1 -1
  59. package/docs/classes/KeetaNetSDK.Referenced.PossiblyExpiredVote.html +31 -26
  60. package/docs/classes/KeetaNetSDK.Referenced.SignatureStorage.html +1 -1
  61. package/docs/classes/KeetaNetSDK.Referenced.UserClientBuilder.html +4 -3
  62. package/docs/classes/KeetaNetSDK.Referenced.Vote.html +8 -3
  63. package/docs/classes/KeetaNetSDK.Referenced.VoteBlockBundle.html +3 -3
  64. package/docs/classes/KeetaNetSDK.Referenced.VoteBlockHash.html +2 -2
  65. package/docs/classes/KeetaNetSDK.Referenced.VoteBuilder.html +10 -7
  66. package/docs/classes/KeetaNetSDK.Referenced.VoteHash.html +2 -2
  67. package/docs/classes/KeetaNetSDK.Referenced.VoteLikeBase.html +32 -0
  68. package/docs/classes/KeetaNetSDK.Referenced.VoteQuote.html +34 -0
  69. package/docs/classes/KeetaNetSDK.Referenced.VoteQuoteBuilder.html +11 -0
  70. package/docs/classes/KeetaNetSDK.Referenced.VoteStaple.html +3 -3
  71. package/docs/classes/KeetaNetSDK.Referenced.VoteStapleHash.html +2 -2
  72. package/docs/classes/KeetaNetSDK.Referenced.default.html +1 -1
  73. package/docs/classes/KeetaNetSDK.Referenced.src_lib_utils_asn1.ValidateASN1.html +2 -2
  74. package/docs/classes/KeetaNetSDK.Referenced.src_lib_utils_buffer.BufferStorage.html +1 -1
  75. package/docs/classes/KeetaNetSDK.UserClient.html +7 -2
  76. package/docs/enums/KeetaNetSDK.Referenced.BaseFlag.html +2 -1
  77. package/docs/enums/KeetaNetSDK.Referenced.BasePermissionGroup.html +3 -1
  78. package/docs/enums/KeetaNetSDK.Referenced.BlockPurpose.html +3 -0
  79. package/docs/functions/KeetaNetSDK.Referenced.src_lib_utils_asn1.isASN1Object.html +1 -0
  80. package/docs/functions/KeetaNetSDK.Referenced.src_lib_utils_buffer.ZlibDeflateAsync.html +1 -0
  81. package/docs/functions/KeetaNetSDK.Referenced.src_lib_utils_buffer.ZlibInflateAsync.html +1 -0
  82. package/docs/functions/KeetaNetSDK.Referenced.src_lib_utils_helper.bufferToBigInt.html +1 -0
  83. package/docs/hierarchy.html +1 -1
  84. package/docs/interfaces/KeetaNetSDK.PublishOptions.html +5 -0
  85. package/docs/interfaces/KeetaNetSDK.Referenced.ACLEntry.html +1 -1
  86. package/docs/interfaces/KeetaNetSDK.Referenced.ACLUpdate.html +1 -1
  87. package/docs/interfaces/KeetaNetSDK.Referenced.ASN1ExplicitContextTag.html +1 -1
  88. package/docs/interfaces/KeetaNetSDK.Referenced.ASN1ImplicitContextTag.html +1 -1
  89. package/docs/interfaces/KeetaNetSDK.Referenced.ASN1Object.html +1 -1
  90. package/docs/interfaces/KeetaNetSDK.Referenced.AccountInfo.html +4 -2
  91. package/docs/interfaces/KeetaNetSDK.Referenced.BaseExternalKeyPairFunctions.html +1 -1
  92. package/docs/interfaces/KeetaNetSDK.Referenced.BaseGenerationConfig.html +1 -1
  93. package/docs/interfaces/KeetaNetSDK.Referenced.BaseIdentifierCreateArguments.html +3 -0
  94. package/docs/interfaces/KeetaNetSDK.Referenced.BlockJSONOperation.html +1 -1
  95. package/docs/interfaces/KeetaNetSDK.Referenced.BlockJSONOperationCREATE_IDENTIFIER.html +3 -3
  96. package/docs/interfaces/KeetaNetSDK.Referenced.BlockJSONOperationMANAGE_CERTIFICATE.html +1 -1
  97. package/docs/interfaces/KeetaNetSDK.Referenced.BlockJSONOperationMANAGE_CERTIFICATESerializable.html +1 -1
  98. package/docs/interfaces/KeetaNetSDK.Referenced.BlockJSONOperationMODIFY_PERMISSIONS.html +1 -1
  99. package/docs/interfaces/KeetaNetSDK.Referenced.BlockJSONOperationRECEIVE.html +1 -1
  100. package/docs/interfaces/KeetaNetSDK.Referenced.BlockJSONOperationSEND.html +1 -1
  101. package/docs/interfaces/KeetaNetSDK.Referenced.BlockJSONOperationSET_INFO.html +1 -1
  102. package/docs/interfaces/KeetaNetSDK.Referenced.BlockJSONOperationSET_REP.html +1 -1
  103. package/docs/interfaces/KeetaNetSDK.Referenced.BlockJSONOperationTOKEN_ADMIN_MODIFY_BALANCE.html +1 -1
  104. package/docs/interfaces/KeetaNetSDK.Referenced.BlockJSONOperationTOKEN_ADMIN_SUPPLY.html +1 -1
  105. package/docs/interfaces/{KeetaNetSDK.Referenced.BlockCanonical.html → KeetaNetSDK.Referenced.BlockV1Canonical.html} +1 -1
  106. package/docs/interfaces/KeetaNetSDK.Referenced.BlockV1JSON.html +12 -0
  107. package/docs/interfaces/KeetaNetSDK.Referenced.BlockV1UnsignedCanonical.html +11 -0
  108. package/docs/interfaces/KeetaNetSDK.Referenced.BlockV2Canonical.html +11 -0
  109. package/docs/interfaces/KeetaNetSDK.Referenced.BlockV2JSON.html +12 -0
  110. package/docs/interfaces/KeetaNetSDK.Referenced.BlockV2UnsignedCanonical.html +11 -0
  111. package/docs/interfaces/KeetaNetSDK.Referenced.ComputedBlocksEffectFields.html +3 -2
  112. package/docs/interfaces/KeetaNetSDK.Referenced.Constructor.html +1 -1
  113. package/docs/interfaces/KeetaNetSDK.Referenced.CreateIdentifierRequest.html +4 -0
  114. package/docs/interfaces/KeetaNetSDK.Referenced.DisposableTimingHandle.html +1 -1
  115. package/docs/interfaces/KeetaNetSDK.Referenced.ExternalKeyPairFunctionsNoEncryption.html +1 -1
  116. package/docs/interfaces/KeetaNetSDK.Referenced.ExternalKeyPairFunctionsSupportsEncryption.html +1 -1
  117. package/docs/interfaces/KeetaNetSDK.Referenced.FeeAmountAndToken.html +5 -0
  118. package/docs/interfaces/KeetaNetSDK.Referenced.FeeAmountAndTokenJSON.html +4 -0
  119. package/docs/interfaces/KeetaNetSDK.Referenced.InitialConfigSupply.html +1 -1
  120. package/docs/interfaces/KeetaNetSDK.Referenced.InstanceSet.html +1 -1
  121. package/docs/interfaces/KeetaNetSDK.Referenced.KVGenericOptionsType.html +1 -1
  122. package/docs/interfaces/KeetaNetSDK.Referenced.KVSetOptionsType.html +1 -1
  123. package/docs/interfaces/KeetaNetSDK.Referenced.LedgerConfig.html +5 -3
  124. package/docs/interfaces/KeetaNetSDK.Referenced.LedgerStorageAPI.html +3 -3
  125. package/docs/interfaces/KeetaNetSDK.Referenced.ModifyTokenBalanceEntry.html +1 -1
  126. package/docs/interfaces/KeetaNetSDK.Referenced.MultiSigIdentifierCreateArguments.html +5 -0
  127. package/docs/interfaces/KeetaNetSDK.Referenced.MultisigConfig.html +3 -0
  128. package/docs/interfaces/KeetaNetSDK.Referenced.NumericValueEntry.html +1 -1
  129. package/docs/interfaces/KeetaNetSDK.Referenced.P2PConfig.html +4 -2
  130. package/docs/interfaces/KeetaNetSDK.Referenced.P2PPeerBase.html +1 -1
  131. package/docs/interfaces/KeetaNetSDK.Referenced.P2PPeerListener.html +1 -1
  132. package/docs/interfaces/KeetaNetSDK.Referenced.P2PPeerRepBase.html +4 -2
  133. package/docs/interfaces/KeetaNetSDK.Referenced.PrincipalACLWithInfoParsed.html +1 -0
  134. package/docs/interfaces/KeetaNetSDK.Referenced.PublicKeyStorage.html +1 -1
  135. package/docs/interfaces/KeetaNetSDK.Referenced.RequestTokenReceiveEntry.html +1 -1
  136. package/docs/interfaces/KeetaNetSDK.Referenced.TokenNumericEntry.html +1 -1
  137. package/docs/interfaces/KeetaNetSDK.Referenced.UserClientConfig.html +5 -3
  138. package/docs/interfaces/KeetaNetSDK.Referenced.UserClientOptions.html +4 -2
  139. package/docs/interfaces/KeetaNetSDK.Referenced.VoteJSON.html +4 -2
  140. package/docs/interfaces/KeetaNetSDK.Referenced.VoteStapleJSON.html +2 -2
  141. package/docs/interfaces/KeetaNetSDK.Referenced.WithIsInstance.html +1 -1
  142. package/docs/interfaces/KeetaNetSDK.Referenced.src_config.ValidationConfig.html +2 -2
  143. package/docs/interfaces/KeetaNetSDK.Referenced.src_lib_utils_asn1.ASN1BitString.html +1 -1
  144. package/docs/interfaces/KeetaNetSDK.Referenced.src_lib_utils_asn1.ASN1Date.html +1 -1
  145. package/docs/interfaces/KeetaNetSDK.Referenced.src_lib_utils_asn1.ASN1OID.html +1 -1
  146. package/docs/interfaces/KeetaNetSDK.Referenced.src_lib_utils_asn1.ASN1Set.html +1 -1
  147. package/docs/interfaces/KeetaNetSDK.Referenced.src_lib_utils_asn1.ASN1String.html +1 -1
  148. package/docs/interfaces/KeetaNetSDK.Referenced.src_lib_utils_helper.InstanceSetConstructor.html +2 -2
  149. package/docs/modules/KeetaNetSDK.Referenced.html +1 -1
  150. package/docs/modules/KeetaNetSDK.Referenced.src_lib_utils_asn1.html +1 -1
  151. package/docs/modules/KeetaNetSDK.Referenced.src_lib_utils_buffer.html +1 -1
  152. package/docs/modules/KeetaNetSDK.Referenced.src_lib_utils_helper.html +1 -1
  153. package/docs/modules/KeetaNetSDK.html +2 -2
  154. package/docs/types/KeetaNetSDK.Referenced.BlockASN1SchemaWithoutSignature.html +1 -0
  155. package/docs/types/KeetaNetSDK.Referenced.BlockJSON.html +1 -0
  156. package/docs/types/KeetaNetSDK.Referenced.BlockJSONIncomplete.html +1 -1
  157. package/docs/types/KeetaNetSDK.Referenced.BlockOperationASN1SchemaType.html +1 -0
  158. package/docs/types/KeetaNetSDK.Referenced.BlockOperationTypes.html +1 -0
  159. package/docs/types/KeetaNetSDK.Referenced.BlockSignature.html +2 -0
  160. package/docs/types/KeetaNetSDK.Referenced.BlockSignatureField.html +1 -0
  161. package/docs/types/KeetaNetSDK.Referenced.BlockSignerField.html +1 -0
  162. package/docs/types/KeetaNetSDK.Referenced.BlockSignerFieldJSON.html +1 -0
  163. package/docs/types/KeetaNetSDK.Referenced.BlockV1ASN1WithoutSignature.html +1 -0
  164. package/docs/types/KeetaNetSDK.Referenced.BlockV2ASN1WithoutSignature.html +1 -0
  165. package/docs/types/KeetaNetSDK.Referenced.CertificateBuilderParams.html +8 -3
  166. package/docs/types/KeetaNetSDK.Referenced.CertificateExtensionData.html +1 -0
  167. package/docs/types/KeetaNetSDK.Referenced.CertificateExtensions.html +2 -2
  168. package/docs/types/KeetaNetSDK.Referenced.ComputedEffectOfBlocks.html +2 -2
  169. package/docs/types/KeetaNetSDK.Referenced.GetAccountStateAPIResponseFormatted.html +1 -0
  170. package/docs/types/KeetaNetSDK.Referenced.HashNames.html +1 -0
  171. package/docs/types/KeetaNetSDK.Referenced.MultisigAddress.html +1 -0
  172. package/docs/types/KeetaNetSDK.Referenced.MultisigSignerField.html +1 -0
  173. package/docs/types/KeetaNetSDK.Referenced.MultisigSignerFieldJSON.html +1 -0
  174. package/docs/types/KeetaNetSDK.Referenced.OmitLastArrayValue.html +1 -0
  175. package/docs/types/KeetaNetSDK.Referenced.P2PUpdateOptions.html +1 -0
  176. package/docs/types/KeetaNetSDK.Referenced.StorageAddress.html +1 -0
  177. package/docs/types/KeetaNetSDK.Referenced.UserEditableAccountInfo.html +1 -0
  178. package/docs/types/KeetaNetSDK.Referenced.VoteBuilderOptions.html +4 -0
  179. package/docs/types/KeetaNetSDK.Referenced.src_config.NetworkConfig.html +1 -1
  180. package/docs/types/KeetaNetSDK.Referenced.src_lib_utils_asn1.ValidateASN1.Schema.html +1 -1
  181. package/docs/types/KeetaNetSDK.Referenced.src_lib_utils_asn1.ValidateASN1.SchemaMap.html +1 -1
  182. package/docs/variables/KeetaNetSDK.Referenced.BlockErrorCodes.html +1 -1
  183. package/docs/variables/KeetaNetSDK.Referenced.BlockOperationASN1Schema.html +2 -0
  184. package/docs/variables/KeetaNetSDK.Referenced.LedgerErrorCodes.html +1 -1
  185. package/docs/variables/KeetaNetSDK.Referenced.VoteErrorCodes.html +1 -1
  186. package/docs/variables/KeetaNetSDK.Referenced.src_lib_utils_helper.crypto.html +1 -0
  187. package/lib/block/index.d.ts +104 -36
  188. package/lib/block/operations.d.ts +31 -3
  189. package/lib/error/block.d.ts +1 -1
  190. package/lib/error/ledger.d.ts +1 -1
  191. package/lib/error/vote.d.ts +1 -1
  192. package/lib/ledger/common.d.ts +14 -1
  193. package/lib/ledger/db_dynamodb.d.ts +2 -2
  194. package/lib/ledger/db_postgres.d.ts +1 -1
  195. package/lib/ledger/db_spanner.d.ts +1 -1
  196. package/lib/ledger/db_spanner_helper.d.ts +28 -5
  197. package/lib/ledger/db_sqlite.d.ts +1 -1
  198. package/lib/ledger/effects.d.ts +10 -9
  199. package/lib/ledger/index.d.ts +17 -8
  200. package/lib/ledger/types.d.ts +10 -1
  201. package/lib/node/utils.d.ts +5 -0
  202. package/lib/p2p.d.ts +32 -0
  203. package/lib/permissions.d.ts +5 -2
  204. package/lib/utils/asn1.d.ts +5 -4
  205. package/lib/utils/buffer.d.ts +4 -0
  206. package/lib/utils/certificate.d.ts +82 -15
  207. package/lib/utils/helper.d.ts +9 -1
  208. package/lib/vote.d.ts +106 -30
  209. package/package.json +1 -1
  210. package/version.d.ts +1 -1
  211. package/docs/interfaces/KeetaNetSDK.Referenced.BlockJSON.html +0 -11
  212. package/docs/interfaces/KeetaNetSDK.Referenced.BlockUnsignedCanonical.html +0 -11
  213. package/docs/types/KeetaNetSDK.Referenced.CreateIdentifierRequest.html +0 -6
package/client/index.js CHANGED
@@ -57274,6 +57274,7 @@ exports.UserClientBuilder = exports.PendingAccount = void 0;
57274
57274
  const lib_1 = __importDefault(__webpack_require__(8568));
57275
57275
  const account_1 = __webpack_require__(9415);
57276
57276
  const block_1 = __webpack_require__(6158);
57277
+ const operations_1 = __webpack_require__(2778);
57277
57278
  const client_1 = __importDefault(__webpack_require__(3642));
57278
57279
  const permissions_1 = __webpack_require__(5860);
57279
57280
  const conversion_1 = __webpack_require__(2360);
@@ -57519,7 +57520,7 @@ class UserClientBuilder {
57519
57520
  });
57520
57521
  return (await _a.FromPendingJSON(__classPrivateFieldGet(this, _UserClientBuilder_defaultOptions, "f"), getPrivateKey, [this.pendingToJSON()]));
57521
57522
  }
57522
- async publish(client) {
57523
+ async publish(options, client) {
57523
57524
  if (client === undefined) {
57524
57525
  client = __classPrivateFieldGet(this, _UserClientBuilder_userClient, "f");
57525
57526
  }
@@ -57532,10 +57533,58 @@ class UserClientBuilder {
57532
57533
  }
57533
57534
  else {
57534
57535
  const blocks = await this.computeBlocks(client);
57535
- retval = await client.client.transmit(blocks.blocks);
57536
+ retval = await client.client.transmit(blocks.blocks, options);
57536
57537
  }
57537
57538
  return (retval);
57538
57539
  }
57540
+ async computeFeeBlock(staple, options = {}, renderOptions) {
57541
+ __classPrivateFieldGet(this, _UserClientBuilder_instances, "m", _UserClientBuilder_useOptions).call(this, options);
57542
+ if (renderOptions === undefined) {
57543
+ renderOptions = __classPrivateFieldGet(this, _UserClientBuilder_userClient, "f");
57544
+ }
57545
+ if (renderOptions === undefined) {
57546
+ throw (new client_1.default('CLIENT_BUILDER_USER_CLIENT_REQUIRED', 'UserClient is required to compute blocks'));
57547
+ }
57548
+ if (!('getPrevious' in renderOptions)) {
57549
+ renderOptions = __classPrivateFieldGet(this, _UserClientBuilder_instances, "m", _UserClientBuilder_getRenderOptionsFromClient).call(this, renderOptions);
57550
+ }
57551
+ const previousByKey = {};
57552
+ for (const existing of staple.blocks) {
57553
+ const previous = existing.previous.toString();
57554
+ const pubKey = existing.account.publicKeyString.get();
57555
+ if (!previousByKey[pubKey] || previousByKey[pubKey].toString() === previous) {
57556
+ previousByKey[pubKey] = existing.hash.toString();
57557
+ }
57558
+ }
57559
+ const { account, signer } = __classPrivateFieldGet(this, _UserClientBuilder_pendingOptions, "f");
57560
+ const accountPubKey = account.publicKeyString.get();
57561
+ let previous = previousByKey[accountPubKey];
57562
+ if (!previous) {
57563
+ previous = await renderOptions.getPrevious(account) ?? block_1.Block.NO_PREVIOUS;
57564
+ }
57565
+ const { baseToken } = lib_1.default.Account.generateBaseAddresses(renderOptions.network);
57566
+ const operations = [];
57567
+ for (const vote of staple.votes) {
57568
+ if (vote.fee !== undefined) {
57569
+ operations.push({
57570
+ type: operations_1.OperationType.SEND,
57571
+ amount: vote.fee.amount,
57572
+ to: vote.fee.payTo ?? vote.issuer,
57573
+ token: vote.fee.token ?? baseToken
57574
+ });
57575
+ }
57576
+ }
57577
+ const block = await new block_1.Block.Builder({
57578
+ version: 2,
57579
+ purpose: block_1.BlockPurpose.FEE,
57580
+ account: account,
57581
+ signer: signer,
57582
+ network: renderOptions.network,
57583
+ previous: previous,
57584
+ operations: operations
57585
+ }).seal();
57586
+ return (block);
57587
+ }
57539
57588
  async computeBlocks(renderOptions) {
57540
57589
  if (this.rendered) {
57541
57590
  return ({ blocks: this.blocks });
@@ -57973,7 +58022,7 @@ var __classPrivateFieldGet = (this && this.__classPrivateFieldGet) || function (
57973
58022
  var __importDefault = (this && this.__importDefault) || function (mod) {
57974
58023
  return (mod && mod.__esModule) ? mod : { "default": mod };
57975
58024
  };
57976
- var _Client_instances, _Client_reps, _Client_weightOrderedReps, _Client_intervals, _Client_updateRepsPromise, _Client_apiRaw, _Client_api, _Client_requestVotes, _Client_getVotes, _Client_getBuilderRenderOptions, _Client_urlSeparatedAccounts, _Client_formatAllBalances, _Client_parseResponsePermissions, _Client_formatAccountInfo, _Client_parseAccountInfo, _Client_parsePermissionEntries, _Client_mapCertificateWithBundleResult, _Client_parseRepInfo, _UserClient_instances, _UserClient_config, _UserClient_client, _UserClient_listeners, _UserClient_intervals, _UserClient_previousAccountChangeData, _UserClient_socketPromise, _UserClient_filteredWebSocket, _UserClient_changePromise, _UserClient_reconnectAttempts, _UserClient_RECONNECT_TIMEOUT, _UserClient_transientUserClients, _UserClient_getAccount, _UserClient_publishAidURL_get, _UserClient_publishWithPublishAid, _UserClient_reconnectWebSocket, _UserClient_setupFilteredWebSocket, _UserClient_emit, _UserClient_emitAccountInfoIfChanged;
58025
+ var _Client_instances, _Client_reps, _Client_weightOrderedReps, _Client_intervals, _Client_updateRepsPromise, _Client_apiRaw, _Client_api, _Client_requestVoteOrQuote, _Client_requestQuotes, _Client_requestVotes, _Client_getVotes, _Client_getBuilderRenderOptions, _Client_urlSeparatedAccounts, _Client_formatAllBalances, _Client_parseResponsePermissions, _Client_formatAccountInfo, _Client_parseAccountInfo, _Client_parsePermissionEntries, _Client_mapCertificateWithBundleResult, _Client_parseRepInfo, _UserClient_instances, _UserClient_config, _UserClient_client, _UserClient_listeners, _UserClient_intervals, _UserClient_previousAccountChangeData, _UserClient_socketPromise, _UserClient_filteredWebSocket, _UserClient_changePromise, _UserClient_reconnectAttempts, _UserClient_RECONNECT_TIMEOUT, _UserClient_transientUserClients, _UserClient_getAccount, _UserClient_publishAidURL_get, _UserClient_publishWithPublishAid, _UserClient_reconnectWebSocket, _UserClient_setupFilteredWebSocket, _UserClient_emit, _UserClient_emitAccountInfoIfChanged;
57977
58026
  Object.defineProperty(exports, "__esModule", ({ value: true }));
57978
58027
  exports.lib = exports.UserClient = exports.Client = void 0;
57979
58028
  exports.blockGenerator = blockGenerator;
@@ -58009,6 +58058,7 @@ const effects_1 = __webpack_require__(7346);
58009
58058
  const client_1 = __importDefault(__webpack_require__(3642));
58010
58059
  const certificate_1 = __webpack_require__(5661);
58011
58060
  const certificate_2 = __webpack_require__(5661);
58061
+ const vote_1 = __webpack_require__(1130);
58012
58062
  function isGetAccountStateAPIResponseFailure(object) {
58013
58063
  if (typeof object !== 'object' || object === null) {
58014
58064
  return (false);
@@ -58192,23 +58242,42 @@ class Client {
58192
58242
  * votes and permanent votes for the blocks and then publish them to
58193
58243
  * the network.
58194
58244
  *
58195
- * If `blocks` is a {@link UserClientBuilder} then the blocks will be
58196
- * computed and then transmitted. If `blocks` is an array of blocks
58197
- * then they will be transmitted as-is.
58245
+ * The `blocks` builder will be computed using {@link computeBuilderBlocks} and then transmitted.
58198
58246
  *
58199
- * @param blocks The blocks or UserClientBuilder to transmit
58247
+ * @param builder The UserClientBuilder to compute and transmit transmit
58200
58248
  * @param network The network to use for the builder (if using a builder)
58201
58249
  * @return The result of the publish operation
58202
58250
  */
58203
- async transmit(blocks, network) {
58204
- if (builder_1.UserClientBuilder.isInstance(blocks)) {
58205
- if (network === undefined) {
58206
- throw (new Error('Network must be defined when using transmit() with a builder'));
58251
+ async transmitBuilder(builder, network, options) {
58252
+ const blocks = await this.computeBuilderBlocks(network, builder);
58253
+ return (await this.transmit(blocks.blocks, options));
58254
+ }
58255
+ /**
58256
+ * Transmit a set of blocks to the network. This will request short
58257
+ * votes and permanent votes for the blocks and then publish them to
58258
+ * the network. Optionally it will generate a fee block from a user
58259
+ * provided function if fees are required.
58260
+ *
58261
+ * @param blocks The blocks to transmit
58262
+ * @param options User provided options {@link PublishOptions }
58263
+ * @return The result of the publish operation
58264
+ */
58265
+ async transmit(blocks, options) {
58266
+ const tempVotes = await __classPrivateFieldGet(this, _Client_instances, "m", _Client_requestVotes).call(this, blocks, undefined, undefined, options?.quotes);
58267
+ let requiresFee = false;
58268
+ for (const vote of tempVotes) {
58269
+ if (vote.fee !== undefined) {
58270
+ requiresFee = true;
58271
+ }
58272
+ }
58273
+ if (requiresFee) {
58274
+ if (options?.generateFeeBlock === undefined) {
58275
+ throw (new Error('Votes require fees but generateFeeBlock was not defined'));
58207
58276
  }
58208
- await this.computeBuilderBlocks(network, blocks);
58209
- blocks = blocks.blocks;
58277
+ const staple = vote_1.VoteStaple.fromVotesAndBlocks(tempVotes, blocks);
58278
+ const feeBlock = await options.generateFeeBlock(staple);
58279
+ blocks.push(feeBlock);
58210
58280
  }
58211
- const tempVotes = await __classPrivateFieldGet(this, _Client_instances, "m", _Client_requestVotes).call(this, blocks);
58212
58281
  const permVotes = await __classPrivateFieldGet(this, _Client_instances, "m", _Client_requestVotes).call(this, blocks, tempVotes);
58213
58282
  const votesAndBlocks = lib_1.default.Vote.Staple.fromVotesAndBlocks(permVotes, blocks);
58214
58283
  return (await this.transmitStaple(votesAndBlocks));
@@ -58658,7 +58727,7 @@ class Client {
58658
58727
  * that it will always return at least 1 vote staple if there are any
58659
58728
  * vote staples available.
58660
58729
  *
58661
- * @param account The account to get the history for
58730
+ * @param account The account to get the history for -- if null then the history for all accounts will be returned
58662
58731
  * @param options The options to use for the request
58663
58732
  * @param options.startBlocksHash The block hash to start from -- this is used to paginate the request
58664
58733
  * @param options.depth The maximum number of vote staples to return -- this is used to limit the number of vote staples returned
@@ -58682,20 +58751,19 @@ class Client {
58682
58751
  const query = {
58683
58752
  limit: String(limit)
58684
58753
  };
58754
+ if (startVoteStapleID !== undefined) {
58755
+ query.start = startVoteStapleID;
58756
+ }
58685
58757
  let history;
58686
- if (startVoteStapleID === undefined) {
58687
- history = await __classPrivateFieldGet(this, _Client_instances, "m", _Client_api).call(this, 'ANY', 'GET /node/ledger/account/:account/history', {
58688
- args: {
58689
- account
58690
- },
58758
+ if (account === null) {
58759
+ history = await __classPrivateFieldGet(this, _Client_instances, "m", _Client_api).call(this, 'ANY', 'GET /node/ledger/history', {
58691
58760
  queryParams: query
58692
58761
  });
58693
58762
  }
58694
58763
  else {
58695
- history = await __classPrivateFieldGet(this, _Client_instances, "m", _Client_api).call(this, 'ANY', 'GET /node/ledger/account/:account/history/start/:block', {
58764
+ history = await __classPrivateFieldGet(this, _Client_instances, "m", _Client_api).call(this, 'ANY', 'GET /node/ledger/account/:account/history', {
58696
58765
  args: {
58697
- account: account,
58698
- block: startVoteStapleID
58766
+ account
58699
58767
  },
58700
58768
  queryParams: query
58701
58769
  });
@@ -58705,7 +58773,7 @@ class Client {
58705
58773
  }
58706
58774
  for (const historyEntry of history.history) {
58707
58775
  const voteStapleInfo = historyEntry.voteStaple;
58708
- if (!voteStapleInfo['$binary']) {
58776
+ if (voteStapleInfo['$binary'] === undefined) {
58709
58777
  throw (new Error('Vote Staple is missing binary data'));
58710
58778
  }
58711
58779
  const voteStapleBinary = Buffer.from(voteStapleInfo['$binary'], 'base64');
@@ -59117,6 +59185,9 @@ class Client {
59117
59185
  }
59118
59186
  return (voteStaple);
59119
59187
  }
59188
+ async getVoteQuotes(blocks) {
59189
+ return (await __classPrivateFieldGet(this, _Client_instances, "m", _Client_requestQuotes).call(this, blocks));
59190
+ }
59120
59191
  /** Work in progress */
59121
59192
  async getLedgerChecksum(rep = 'ANY') {
59122
59193
  const checksumResponse = await __classPrivateFieldGet(this, _Client_instances, "m", _Client_api).call(this, rep, 'GET /node/ledger/checksum');
@@ -59285,54 +59356,27 @@ async function _Client_apiRaw(rep, api, method, options = {}) {
59285
59356
  }
59286
59357
  // eslint-disable-next-line @typescript-eslint/consistent-type-assertions
59287
59358
  return await __classPrivateFieldGet(this, _Client_instances, "m", _Client_apiRaw).call(this, rep, path, method, options);
59288
- }, _Client_requestVotes = async function _Client_requestVotes(blocks, otherVotes, reps = __classPrivateFieldGet(this, _Client_reps, "f")) {
59289
- // Wait for reps promise to ensure we have the right list of reps and their weight
59290
- await __classPrivateFieldGet(this, _Client_updateRepsPromise, "f");
59291
- const request = {
59292
- blocks: blocks.map(function (block) {
59293
- return (Buffer.from(block.toBytes()).toString('base64'));
59294
- })
59295
- };
59296
- if (otherVotes !== undefined) {
59297
- if (otherVotes.length === 0) {
59298
- throw (new Error('requestVotes() otherVotes must not have a length of 0'));
59299
- }
59300
- request.votes = otherVotes.map(function (vote) {
59301
- return (Buffer.from(vote.toBytes()).toString('base64'));
59302
- });
59303
- if (reps === __classPrivateFieldGet(this, _Client_reps, "f")) {
59304
- reps = otherVotes.map((vote) => {
59305
- const voteRepPubKey = vote.issuer.publicKeyString.get();
59306
- return (__classPrivateFieldGet(this, _Client_reps, "f").find(function (rep) {
59307
- const checkRepPubKey = rep.key.publicKeyString.get();
59308
- if (checkRepPubKey === voteRepPubKey) {
59309
- return (true);
59310
- }
59311
- return (false);
59312
- }));
59313
- }).filter(function (rep) {
59314
- if (rep === undefined) {
59315
- return (false);
59316
- }
59317
- return (true);
59318
- });
59319
- }
59320
- }
59359
+ }, _Client_requestVoteOrQuote = async function _Client_requestVoteOrQuote(api, request, reps = __classPrivateFieldGet(this, _Client_reps, "f"), quotes = []) {
59321
59360
  let recentVotingError;
59322
59361
  let recentVotingErrorWeight;
59362
+ const quoteMap = new Map();
59363
+ for (const quote of quotes) {
59364
+ quoteMap.set(quote.issuer.publicKeyAndTypeString, quote);
59365
+ }
59323
59366
  const votePromises = [];
59324
59367
  for (const rep of reps) {
59368
+ const quote = quoteMap.get(rep.key.publicKeyAndTypeString);
59369
+ if (quote !== undefined) {
59370
+ request.quote = Buffer.from(quote.toBytes()).toString('base64');
59371
+ }
59325
59372
  votePromises.push((async () => {
59326
59373
  try {
59327
- const apiResult = await __classPrivateFieldGet(this, _Client_instances, "m", _Client_api).call(this, rep, 'POST /vote/_root', {
59374
+ const apiResult = await __classPrivateFieldGet(this, _Client_instances, "m", _Client_api).call(this, rep, api, {
59328
59375
  body: request
59329
59376
  });
59330
59377
  return (apiResult);
59331
59378
  }
59332
59379
  catch (voteError) {
59333
- if (otherVotes !== undefined) {
59334
- throw (voteError);
59335
- }
59336
59380
  const weight = rep.weight ?? 0n;
59337
59381
  if (recentVotingErrorWeight === undefined || weight > recentVotingErrorWeight) {
59338
59382
  recentVotingError = voteError;
@@ -59354,9 +59398,21 @@ async function _Client_apiRaw(rep, api, method, options = {}) {
59354
59398
  if (voteObjectWrapper === undefined) {
59355
59399
  continue;
59356
59400
  }
59357
- const voteObject = voteObjectWrapper['vote'];
59358
- const voteBin = Buffer.from(voteObject['$binary'], 'base64');
59359
- retval.push(new lib_1.default.Vote(voteBin));
59401
+ if ('vote' in voteObjectWrapper) {
59402
+ const voteObject = voteObjectWrapper['vote'];
59403
+ const voteBin = Buffer.from(voteObject['$binary'], 'base64');
59404
+ const vote = new lib_1.default.Vote(voteBin);
59405
+ retval.push(vote);
59406
+ }
59407
+ else if ('quote' in voteObjectWrapper) {
59408
+ const voteObject = voteObjectWrapper['quote'];
59409
+ const quoteBin = Buffer.from(voteObject['$binary'], 'base64');
59410
+ const quote = new lib_1.default.Vote.Quote(quoteBin);
59411
+ retval.push(quote);
59412
+ }
59413
+ else {
59414
+ throw (new Error('Vote or Quote not in response'));
59415
+ }
59360
59416
  }
59361
59417
  if (retval.length === 0 && recentVotingError !== undefined) {
59362
59418
  if (recentVotingError !== undefined) {
@@ -59378,6 +59434,51 @@ async function _Client_apiRaw(rep, api, method, options = {}) {
59378
59434
  }
59379
59435
  }
59380
59436
  return (retval);
59437
+ }, _Client_requestQuotes = async function _Client_requestQuotes(blocks, reps = __classPrivateFieldGet(this, _Client_reps, "f")) {
59438
+ // Wait for reps promise to ensure we have the right list of reps and their weight
59439
+ await __classPrivateFieldGet(this, _Client_updateRepsPromise, "f");
59440
+ const request = {
59441
+ blocks: blocks.map(function (block) {
59442
+ return (Buffer.from(block.toBytes()).toString('base64'));
59443
+ })
59444
+ };
59445
+ const quotes = await __classPrivateFieldGet(this, _Client_instances, "m", _Client_requestVoteOrQuote).call(this, 'POST /vote/quote', request, reps);
59446
+ return (quotes);
59447
+ }, _Client_requestVotes = async function _Client_requestVotes(blocks, otherVotes, reps = __classPrivateFieldGet(this, _Client_reps, "f"), quotes) {
59448
+ // Wait for reps promise to ensure we have the right list of reps and their weight
59449
+ await __classPrivateFieldGet(this, _Client_updateRepsPromise, "f");
59450
+ const request = {
59451
+ blocks: blocks.map(function (block) {
59452
+ return (Buffer.from(block.toBytes()).toString('base64'));
59453
+ })
59454
+ };
59455
+ if (otherVotes !== undefined) {
59456
+ if (otherVotes.length === 0) {
59457
+ throw (new Error('requestVotes() otherVotes must not have a length of 0'));
59458
+ }
59459
+ request.votes = otherVotes.map(function (vote) {
59460
+ return (Buffer.from(vote.toBytes()).toString('base64'));
59461
+ });
59462
+ if (reps === __classPrivateFieldGet(this, _Client_reps, "f")) {
59463
+ reps = otherVotes.map((vote) => {
59464
+ const voteRepPubKey = vote.issuer.publicKeyString.get();
59465
+ return (__classPrivateFieldGet(this, _Client_reps, "f").find(function (rep) {
59466
+ const checkRepPubKey = rep.key.publicKeyString.get();
59467
+ if (checkRepPubKey === voteRepPubKey) {
59468
+ return (true);
59469
+ }
59470
+ return (false);
59471
+ }));
59472
+ }).filter(function (rep) {
59473
+ if (rep === undefined) {
59474
+ return (false);
59475
+ }
59476
+ return (true);
59477
+ });
59478
+ }
59479
+ }
59480
+ const votes = await __classPrivateFieldGet(this, _Client_instances, "m", _Client_requestVoteOrQuote).call(this, 'POST /vote/_root', request, reps, quotes);
59481
+ return (votes);
59381
59482
  }, _Client_getVotes = async function _Client_getVotes(blockhash, side = 'main', rep = 'ANY') {
59382
59483
  const query = {
59383
59484
  side: (0, common_1.assertLedgerStorage)(side)
@@ -59742,7 +59843,14 @@ class UserClient {
59742
59843
  const { networkAddress, baseToken } = lib_1.default.Account.generateBaseAddresses(config.network);
59743
59844
  this.networkAddress = networkAddress;
59744
59845
  this.baseToken = baseToken;
59745
- __classPrivateFieldSet(this, _UserClient_config, config, "f");
59846
+ __classPrivateFieldSet(this, _UserClient_config, {
59847
+ generateFeeBlock: async (staple) => {
59848
+ const builder = this.initBuilder();
59849
+ const block = await builder.computeFeeBlock(staple);
59850
+ return (block);
59851
+ },
59852
+ ...config
59853
+ }, "f");
59746
59854
  // For event listeners/polling
59747
59855
  __classPrivateFieldSet(this, _UserClient_listeners, {}, "f");
59748
59856
  __classPrivateFieldSet(this, _UserClient_intervals, {}, "f");
@@ -59864,11 +59972,12 @@ class UserClient {
59864
59972
  * instead of this one.
59865
59973
  *
59866
59974
  * @param builder The builder to publish
59975
+ * @param options options for publishing {@link PublishOptions }
59867
59976
  * @return The vote staple that was generated and whether it was able to be published
59868
59977
  */
59869
- async publishBuilder(builder) {
59978
+ async publishBuilder(builder, options = { generateFeeBlock: __classPrivateFieldGet(this, _UserClient_config, "f").generateFeeBlock }) {
59870
59979
  if (!__classPrivateFieldGet(this, _UserClient_config, "f").usePublishAid) {
59871
- return (await __classPrivateFieldGet(this, _UserClient_client, "f").transmit(builder, this.network));
59980
+ return (await __classPrivateFieldGet(this, _UserClient_client, "f").transmitBuilder(builder, this.network, options));
59872
59981
  }
59873
59982
  await __classPrivateFieldGet(this, _UserClient_client, "f").computeBuilderBlocks(this.network, builder);
59874
59983
  const retval = await __classPrivateFieldGet(this, _UserClient_instances, "m", _UserClient_publishWithPublishAid).call(this, builder.blocks);
@@ -59941,6 +60050,14 @@ class UserClient {
59941
60050
  }
59942
60051
  throw (new Error('Unreachable code reached in UserClient.send'));
59943
60052
  }
60053
+ /**
60054
+ * Gets a quote for the cost for a given set of blocks from each representative
60055
+ * @param blocks
60056
+ * @returns A list of quotes from representatives the client knows about
60057
+ */
60058
+ async getQuotes(blocks) {
60059
+ return (await __classPrivateFieldGet(this, _UserClient_client, "f").getVoteQuotes(blocks));
60060
+ }
59944
60061
  /**
59945
60062
  * Generate a new identifier for the given type and publish the blocks
59946
60063
  *
@@ -60543,7 +60660,9 @@ exports.baseValidationConfig = {
60543
60660
  },
60544
60661
  supply: {
60545
60662
  maxValue: (10n ** 200n) - 1n
60546
- }
60663
+ },
60664
+ blockSignerCount: { maxValue: 16n },
60665
+ blockSignerDepth: { maxValue: 3n }
60547
60666
  },
60548
60667
  permissions: {
60549
60668
  maxExternalOffset: 32
@@ -62308,25 +62427,25 @@ var __importStar = (this && this.__importStar) || function (mod) {
62308
62427
  __setModuleDefault(result, mod);
62309
62428
  return result;
62310
62429
  };
62430
+ var __classPrivateFieldGet = (this && this.__classPrivateFieldGet) || function (receiver, state, kind, f) {
62431
+ if (kind === "a" && !f) throw new TypeError("Private accessor was defined without a getter");
62432
+ if (typeof state === "function" ? receiver !== state || !f : !state.has(receiver)) throw new TypeError("Cannot read private member from an object whose class did not declare it");
62433
+ return kind === "m" ? f : kind === "a" ? f.call(receiver) : f ? f.value : state.get(receiver);
62434
+ };
62311
62435
  var __classPrivateFieldSet = (this && this.__classPrivateFieldSet) || function (receiver, state, value, kind, f) {
62312
62436
  if (kind === "m") throw new TypeError("Private method is not writable");
62313
62437
  if (kind === "a" && !f) throw new TypeError("Private accessor was defined without a setter");
62314
62438
  if (typeof state === "function" ? receiver !== state || !f : !state.has(receiver)) throw new TypeError("Cannot write private member to an object whose class did not declare it");
62315
62439
  return (kind === "a" ? f.call(receiver, value) : f ? f.value = value : state.set(receiver, value)), value;
62316
62440
  };
62317
- var __classPrivateFieldGet = (this && this.__classPrivateFieldGet) || function (receiver, state, kind, f) {
62318
- if (kind === "a" && !f) throw new TypeError("Private accessor was defined without a getter");
62319
- if (typeof state === "function" ? receiver !== state || !f : !state.has(receiver)) throw new TypeError("Cannot read private member from an object whose class did not declare it");
62320
- return kind === "m" ? f : kind === "a" ? f.call(receiver) : f ? f.value : state.get(receiver);
62321
- };
62322
62441
  var __importDefault = (this && this.__importDefault) || function (mod) {
62323
62442
  return (mod && mod.__esModule) ? mod : { "default": mod };
62324
62443
  };
62325
- var _Block_instances, _Block_valueBytes, _Block_valueHash, _Block_validateOperations, _Block_validateSignature, _BlockBuilder_block;
62444
+ var _Block_instances, _a, _Block_valueBytes, _Block_valueHash, _Block_getSortedRequiredSigners, _Block_validateOperationsPurpose, _Block_validateSignerField, _Block_validateSignatures, _BlockBuilder_block;
62326
62445
  Object.defineProperty(exports, "__esModule", ({ value: true }));
62327
- exports.BlockBuilder = exports.Block = exports.BlockHash = exports.AdjustMethod = void 0;
62328
- exports.assertAdjustMethod = assertAdjustMethod;
62329
- const account_1 = __importDefault(__webpack_require__(9415));
62446
+ exports.BlockBuilder = exports.Block = exports.BlockHash = exports.AdjustMethod = exports.BlockPurpose = void 0;
62447
+ exports.toAdjustMethod = toAdjustMethod;
62448
+ const account_1 = __importStar(__webpack_require__(9415));
62330
62449
  const buffer_1 = __webpack_require__(3310);
62331
62450
  const hash_1 = __webpack_require__(7908);
62332
62451
  const ASN1 = __importStar(__webpack_require__(6045));
@@ -62334,17 +62453,42 @@ const helper_1 = __webpack_require__(3208);
62334
62453
  const util_1 = __webpack_require__(9023);
62335
62454
  const Operations = __importStar(__webpack_require__(2778));
62336
62455
  const block_1 = __importDefault(__webpack_require__(7412));
62456
+ const common_1 = __webpack_require__(5663);
62337
62457
  const NO_PREVIOUS = '9bd05fa2-8e59-42a2-8153-26d8e8c10143:NO_PREVIOUS';
62458
+ var BlockPurpose;
62459
+ (function (BlockPurpose) {
62460
+ BlockPurpose[BlockPurpose["GENERIC"] = 0] = "GENERIC";
62461
+ BlockPurpose[BlockPurpose["FEE"] = 1] = "FEE";
62462
+ })(BlockPurpose || (exports.BlockPurpose = BlockPurpose = {}));
62463
+ function toBlockPurpose(value) {
62464
+ if (typeof value === 'bigint') {
62465
+ value = Number(value);
62466
+ }
62467
+ if (typeof value !== 'number') {
62468
+ throw (new Error(`Invalid BlockPurpose supplied: got ${value} -- ${typeof value}`));
62469
+ }
62470
+ // We add this type assertion to make sure the switch is exhaustive
62471
+ // eslint-disable-next-line @typescript-eslint/consistent-type-assertions
62472
+ switch (value) {
62473
+ case BlockPurpose.GENERIC:
62474
+ case BlockPurpose.FEE:
62475
+ return (value);
62476
+ }
62477
+ throw (new Error(`Invalid BlockPurpose supplied: got ${value} -- ${typeof value}`));
62478
+ }
62338
62479
  var AdjustMethod;
62339
62480
  (function (AdjustMethod) {
62340
62481
  AdjustMethod[AdjustMethod["ADD"] = 0] = "ADD";
62341
62482
  AdjustMethod[AdjustMethod["SUBTRACT"] = 1] = "SUBTRACT";
62342
62483
  AdjustMethod[AdjustMethod["SET"] = 2] = "SET";
62343
62484
  })(AdjustMethod || (exports.AdjustMethod = AdjustMethod = {}));
62344
- function assertAdjustMethod(value, bigintOkay) {
62345
- if (bigintOkay && typeof value === 'bigint') {
62485
+ function toAdjustMethod(value) {
62486
+ if (typeof value === 'bigint') {
62346
62487
  value = Number(value);
62347
62488
  }
62489
+ if (typeof value !== 'number') {
62490
+ throw (new Error(`Invalid AdjustMethod supplied: got ${value} -- ${typeof value}`));
62491
+ }
62348
62492
  // We add this type assertion to make sure the switch is exhaustive
62349
62493
  // eslint-disable-next-line @typescript-eslint/consistent-type-assertions
62350
62494
  switch (value) {
@@ -62388,7 +62532,7 @@ BlockHash.Set = (0, helper_1.setGenerator)(BlockHash, function (value) {
62388
62532
  return (new BlockHash(Buffer.from(value, 'hex')));
62389
62533
  });
62390
62534
  /** @internal */
62391
- const BlockASN1Schema = [
62535
+ const BlockV1ASN1Schema = [
62392
62536
  0n,
62393
62537
  ASN1.BufferStorageASN1.Validate.IsInteger,
62394
62538
  { choice: [ASN1.BufferStorageASN1.Validate.IsInteger, ASN1.BufferStorageASN1.Validate.IsNull] },
@@ -62399,28 +62543,154 @@ const BlockASN1Schema = [
62399
62543
  { sequenceOf: { choice: Object.values(Operations.BlockOperationASN1Schema) } },
62400
62544
  ASN1.BufferStorageASN1.Validate.IsOctetString
62401
62545
  ];
62546
+ const multisigSignerInfoASN1Schema = [
62547
+ ASN1.BufferStorageASN1.Validate.IsOctetString,
62548
+ {
62549
+ sequenceOf: {
62550
+ choice: [
62551
+ // XXX:TODO We need to use a type assertion here because the ASN1 schema does not support recursive types
62552
+ // eslint-disable-next-line @typescript-eslint/consistent-type-assertions
62553
+ (() => multisigSignerInfoASN1Schema),
62554
+ ASN1.BufferStorageASN1.Validate.IsOctetString
62555
+ ]
62556
+ }
62557
+ }
62558
+ ];
62559
+ function parseBlockSignerFieldContainer(input, state) {
62560
+ if (!state) {
62561
+ state = { depth: 0 };
62562
+ }
62563
+ else if (state.depth > 3) {
62564
+ throw (new block_1.default('BLOCK_INVALID_MULTISIG_SIGNER_DEPTH', 'Multisig signer depth exceeded maximum allowed depth'));
62565
+ }
62566
+ const multisigAccount = account_1.default.fromPublicKeyAndType(input[0]).assertKeyType(account_1.AccountKeyAlgorithm.MULTISIG);
62567
+ const signers = [];
62568
+ // XXX:TODO We need to use a type assertion here because the ASN1 schema does not support recursive types properly
62569
+ // eslint-disable-next-line @typescript-eslint/consistent-type-assertions
62570
+ for (const signer of input[1]) {
62571
+ let parsedSigner;
62572
+ if (Buffer.isBuffer(signer)) {
62573
+ parsedSigner = account_1.default.fromPublicKeyAndType(signer).assertAccount();
62574
+ }
62575
+ else if (signer && Array.isArray(signer)) {
62576
+ if (signer.length !== 2) {
62577
+ throw (new Error('Multisig signer must have two items'));
62578
+ }
62579
+ if (!Buffer.isBuffer(signer[0])) {
62580
+ throw (new Error('Multisig signer first item must be a buffer'));
62581
+ }
62582
+ if (!Array.isArray(signer[1])) {
62583
+ throw (new Error('Multisig signer second item must be an array'));
62584
+ }
62585
+ // XXX:TODO We need to use a type assertion here because we are not asserting the type recursively
62586
+ // eslint-disable-next-line @typescript-eslint/consistent-type-assertions
62587
+ const inner = parseBlockSignerFieldContainer(signer, { depth: state.depth + 1 });
62588
+ parsedSigner = inner.parsed;
62589
+ }
62590
+ else {
62591
+ throw (new Error('Multisig signer must be a buffer or an array'));
62592
+ }
62593
+ signers.push(parsedSigner);
62594
+ }
62595
+ return ({
62596
+ parsed: [multisigAccount, signers],
62597
+ depth: state.depth
62598
+ });
62599
+ }
62600
+ function getMultisigSignerContainer(input) {
62601
+ const out = [input[0].publicKeyAndType, []];
62602
+ for (const signer of input[1]) {
62603
+ let parsed;
62604
+ if (Array.isArray(signer)) {
62605
+ parsed = getMultisigSignerContainer(signer);
62606
+ }
62607
+ else {
62608
+ parsed = signer.publicKeyAndType;
62609
+ }
62610
+ out[1].push(parsed);
62611
+ }
62612
+ // XXX:TODO We need to use a type assertion here because the ASN1 schema does not support recursive types properly
62613
+ // eslint-disable-next-line @typescript-eslint/consistent-type-assertions
62614
+ return out;
62615
+ }
62616
+ /** @internal */
62617
+ const BlockV2ASN1Schema = {
62618
+ type: 'context',
62619
+ kind: 'explicit',
62620
+ value: 1,
62621
+ contains: [
62622
+ ASN1.BufferStorageASN1.Validate.IsInteger,
62623
+ { optional: ASN1.BufferStorageASN1.Validate.IsInteger },
62624
+ { type: 'date', kind: 'general' },
62625
+ ASN1.BufferStorageASN1.Validate.IsInteger,
62626
+ ASN1.BufferStorageASN1.Validate.IsOctetString,
62627
+ {
62628
+ choice: [
62629
+ ASN1.BufferStorageASN1.Validate.IsNull,
62630
+ // If principal has a private key, the signature of principal
62631
+ ASN1.BufferStorageASN1.Validate.IsOctetString,
62632
+ // If principal does not have private key, list of accounts signing on behalf of principal and their signatures
62633
+ multisigSignerInfoASN1Schema
62634
+ ]
62635
+ },
62636
+ ASN1.BufferStorageASN1.Validate.IsOctetString,
62637
+ { sequenceOf: { choice: Object.values(Operations.BlockOperationASN1Schema) } },
62638
+ {
62639
+ choice: [
62640
+ // If principal has a private key, the signature of principal
62641
+ ASN1.BufferStorageASN1.Validate.IsOctetString,
62642
+ // If principal does not have private key, list of accounts signing on behalf of principal and their signatures
62643
+ { sequenceOf: ASN1.BufferStorageASN1.Validate.IsOctetString }
62644
+ ]
62645
+ }
62646
+ ]
62647
+ };
62648
+ const BlockASN1Schema = {
62649
+ choice: [
62650
+ BlockV1ASN1Schema,
62651
+ BlockV2ASN1Schema
62652
+ ]
62653
+ };
62654
+ function parseBlockSignerFieldJSON(input) {
62655
+ if (!Array.isArray(input)) {
62656
+ return (account_1.default.toAccount(input).assertAccount());
62657
+ }
62658
+ if (input.length !== 2) {
62659
+ throw (new Error('Multisig signer field must have two items'));
62660
+ }
62661
+ const signer = account_1.default.toAccount(input[0]).assertKeyType(account_1.AccountKeyAlgorithm.MULTISIG);
62662
+ const innerSigners = [];
62663
+ for (const signer of input[1]) {
62664
+ innerSigners.push(parseBlockSignerFieldJSON(signer));
62665
+ }
62666
+ return ([signer, innerSigners]);
62667
+ }
62402
62668
  /**
62403
62669
  * Statically assert that the BlockASN1 type is compatible with BlockASN1Schema
62404
62670
  * @internal
62405
62671
  */
62406
62672
  // eslint-disable-next-line @typescript-eslint/no-unused-vars
62407
62673
  function _ignore_static_checks() {
62674
+ // V1 Checks
62408
62675
  // eslint-disable-next-line @typescript-eslint/no-unused-vars,@typescript-eslint/consistent-type-assertions
62409
- const _ignore_check_blockasn1_forward_1 = {};
62676
+ const _ignore_check_blockasn1v1_forward_1 = {};
62410
62677
  // eslint-disable-next-line @typescript-eslint/no-unused-vars
62411
- const _ignore_check_blockasn1_forward_2 = _ignore_check_blockasn1_forward_1;
62678
+ const _ignore_check_blockasn1v1_forward_2 = _ignore_check_blockasn1v1_forward_1;
62412
62679
  // eslint-disable-next-line @typescript-eslint/no-unused-vars,@typescript-eslint/consistent-type-assertions
62413
- const _ignore_check_blockasn1_reverse_1 = {};
62680
+ const _ignore_check_blockasn1v1_reverse_1 = {};
62414
62681
  // eslint-disable-next-line @typescript-eslint/no-unused-vars
62415
- const _ignore_check_blockasn1_reverse_2 = _ignore_check_blockasn1_reverse_1;
62416
- }
62417
- function assertBlockBlockCanonicalVersion(input) {
62418
- const expected = 1;
62419
- if (input !== expected) {
62420
- throw (new Error('Invalid block version'));
62421
- }
62682
+ const _ignore_check_blockasn1v1_reverse_2 = _ignore_check_blockasn1v1_reverse_1;
62683
+ // V2 Checks
62684
+ // eslint-disable-next-line @typescript-eslint/no-unused-vars,@typescript-eslint/consistent-type-assertions
62685
+ const _ignore_check_blockasn1v2_forward_1 = {};
62686
+ // eslint-disable-next-line @typescript-eslint/no-unused-vars
62687
+ const _ignore_check_blockasn1v2_forward_2 = _ignore_check_blockasn1v2_forward_1;
62688
+ // eslint-disable-next-line @typescript-eslint/no-unused-vars,@typescript-eslint/consistent-type-assertions
62689
+ const _ignore_check_blockasn1v2_reverse_1 = {};
62690
+ // eslint-disable-next-line @typescript-eslint/no-unused-vars
62691
+ const _ignore_check_blockasn1v2_reverse_2 = _ignore_check_blockasn1v2_reverse_1;
62422
62692
  }
62423
- function MapInputValues(input) {
62693
+ function MapV1InputValues(input) {
62424
62694
  const output = {};
62425
62695
  if (input.version !== 1) {
62426
62696
  throw (new Error('MapInputValues should not be called with version != 1'));
@@ -62433,6 +62703,9 @@ function MapInputValues(input) {
62433
62703
  * Import account
62434
62704
  */
62435
62705
  output.account = account_1.default.toAccount(input.account) ?? undefined;
62706
+ if (Array.isArray(input.signer)) {
62707
+ throw (new Error('V1 block signer must not be a multisig signer'));
62708
+ }
62436
62709
  output.signer = account_1.default.toAccount(input.signer);
62437
62710
  if (!output.signer && output.account?.isAccount()) {
62438
62711
  output.signer = output.account;
@@ -62485,37 +62758,129 @@ function MapInputValues(input) {
62485
62758
  // eslint-disable-next-line @typescript-eslint/consistent-type-assertions
62486
62759
  return output;
62487
62760
  }
62761
+ function MapV2InputValues(input) {
62762
+ const output = {};
62763
+ if (input.version !== 2) {
62764
+ throw (new Error('MapInputValues should not be called with version != 2'));
62765
+ }
62766
+ output.version = input.version;
62767
+ output.purpose = input.purpose;
62768
+ if (input.date !== undefined) {
62769
+ output.date = new Date(input.date);
62770
+ }
62771
+ /*
62772
+ * Import account
62773
+ */
62774
+ output.account = account_1.default.toAccount(input.account) ?? undefined;
62775
+ /*
62776
+ * Import previous block hash
62777
+ */
62778
+ if (input.previous !== undefined) {
62779
+ if (BlockHash.isInstance(input.previous)) {
62780
+ output.previous = input.previous;
62781
+ }
62782
+ else if (input.previous === NO_PREVIOUS) {
62783
+ if (output.account) {
62784
+ output.previous = BlockHash.getAccountOpeningHash(output.account);
62785
+ }
62786
+ }
62787
+ else {
62788
+ output.previous = new BlockHash(input.previous);
62789
+ }
62790
+ }
62791
+ /*
62792
+ * Import network
62793
+ */
62794
+ if (input.network !== undefined) {
62795
+ output.network = BigInt(input.network);
62796
+ }
62797
+ /*
62798
+ * Import Subnet
62799
+ */
62800
+ if (input.subnet !== undefined) {
62801
+ output.subnet = BigInt(input.subnet);
62802
+ }
62803
+ /*
62804
+ * Import operations from JSON
62805
+ */
62806
+ if (input.operations !== undefined) {
62807
+ output.operations = Operations.ImportOperationsJSON(input.operations);
62808
+ }
62809
+ if (input.signer !== undefined) {
62810
+ output.signer = parseBlockSignerFieldJSON(input.signer);
62811
+ }
62812
+ // This is valid, the compiler does not understand that we are adding all of the values in this function
62813
+ // eslint-disable-next-line @typescript-eslint/consistent-type-assertions
62814
+ return output;
62815
+ }
62816
+ function assertBlockSignatureField(input) {
62817
+ if (input.length < 1) {
62818
+ throw (new Error('Input must include 1+ signatures'));
62819
+ }
62820
+ }
62488
62821
  /**
62489
62822
  * Block: An item which contains a number of operations (transactions) which
62490
62823
  * originated from an account at a particular instant
62491
62824
  */
62492
62825
  class Block {
62493
- static async fromUnsignedJSON(input) {
62494
- const inputCheck = input;
62826
+ get principal() {
62827
+ if (Array.isArray(this.signer)) {
62828
+ return (this.signer[0]);
62829
+ }
62830
+ else {
62831
+ return (this.signer);
62832
+ }
62833
+ }
62834
+ static async fromUnsignedJSON(input) {
62835
+ const inputCheck = input;
62495
62836
  if (typeof inputCheck === 'object' && inputCheck !== null) {
62496
- if ('signature' in inputCheck) {
62497
- throw (new Error('fromUnsignedJSON() was called when a signature already exists'));
62837
+ if ('signature' in inputCheck || 'signatures' in inputCheck) {
62838
+ throw (new Error('fromUnsignedJSON() was called when a signature(s) already exists'));
62498
62839
  }
62499
62840
  }
62500
- const container = Block.getASN1ContainerWithoutSignature(input);
62841
+ const container = this.getASN1ContainerWithoutSignature(input);
62842
+ // We have to ignore the type here because the ASN1.JStoASN1 function does not handle recursive types well
62843
+ // @ts-ignore
62501
62844
  const bytes = ASN1.JStoASN1(container).toBER(false);
62502
62845
  const hash = new BlockHash((0, hash_1.Hash)(Buffer.from(bytes)));
62503
- const signature = await input.signer.sign(hash.getBuffer());
62504
- return (new Block({
62505
- version: input.version,
62506
- date: input.date,
62507
- previous: input.previous,
62508
- account: input.account,
62509
- signer: input.signer,
62510
- operations: input.operations,
62511
- network: input.network,
62512
- subnet: input.subnet,
62513
- signature: signature.getBuffer()
62846
+ const signers = __classPrivateFieldGet(this, _a, "m", _Block_getSortedRequiredSigners).call(this, input.signer);
62847
+ const signatures = await Promise.all(signers.map(async function (signer) {
62848
+ const signature = await signer.sign(hash.getBuffer());
62849
+ return (signature.getBuffer());
62514
62850
  }));
62851
+ let blockInput;
62852
+ if (input.version === 1) {
62853
+ blockInput = { ...input, signature: signatures[0] };
62854
+ }
62855
+ else {
62856
+ blockInput = { ...input, signatures };
62857
+ }
62858
+ return (new _a(blockInput));
62515
62859
  }
62516
- static isValidJSON(block) {
62517
- for (const checkField of ['version', 'date', 'previous', 'network', 'network', 'account', 'signer', 'signature', 'operations']) {
62518
- if (block[checkField] === undefined) {
62860
+ static isValidJSON(block, version) {
62861
+ if (!block || typeof block !== 'object' || Array.isArray(block)) {
62862
+ return (false);
62863
+ }
62864
+ if (!('version' in block)) {
62865
+ return (false);
62866
+ }
62867
+ if (version !== undefined && block.version !== version) {
62868
+ return (false);
62869
+ }
62870
+ const checkFields = ['date', 'previous', 'network', 'network', 'account', 'signer', 'operations'];
62871
+ if (block.version === 1) {
62872
+ checkFields.push('signature');
62873
+ }
62874
+ else if (block.version === 2) {
62875
+ checkFields.push('signatures');
62876
+ checkFields.push('purpose');
62877
+ }
62878
+ else {
62879
+ return (false);
62880
+ }
62881
+ for (const checkField of checkFields) {
62882
+ // eslint-disable-next-line @typescript-eslint/consistent-type-assertions
62883
+ if (!(checkField in block) || block[checkField] === undefined) {
62519
62884
  return (false);
62520
62885
  }
62521
62886
  }
@@ -62526,7 +62891,6 @@ class Block {
62526
62891
  _Block_valueBytes.set(this, void 0);
62527
62892
  _Block_valueHash.set(this, void 0);
62528
62893
  // Extra attributes
62529
- this.$signatureValid = true;
62530
62894
  this.$opening = false;
62531
62895
  if (typeof input === 'string') {
62532
62896
  input = Buffer.from(input, 'base64');
@@ -62535,75 +62899,159 @@ class Block {
62535
62899
  input = (0, helper_1.bufferToArrayBuffer)(input);
62536
62900
  }
62537
62901
  if (util_1.types.isArrayBuffer(input)) {
62538
- /*
62539
- * TypeScript cannot deal with this complex type, so we have to manually
62540
- * specify the type -- this might be fixed in TypeScript 5.7+
62541
- */
62542
- // @ts-ignore
62543
62902
  const data = new ASN1.BufferStorageASN1(input, BlockASN1Schema).getASN1();
62544
- if (data[0] !== 0n) {
62545
- throw (new block_1.default('BLOCK_INVALID_VERSION', 'Only version 1 is supported'));
62546
- }
62547
- const version = Number(data[0]) + 1;
62548
- assertBlockBlockCanonicalVersion(version);
62549
- this.version = version;
62550
- this.network = data[1];
62551
- this.subnet = data[2] ?? undefined;
62552
- this.date = data[3].date;
62553
- const signerPubKey = data[4];
62554
- this.signer = account_1.default.fromPublicKeyAndType(signerPubKey).assertAccount();
62555
- const acctItem = data[5];
62556
- if (acctItem === null) {
62557
- this.account = this.signer;
62903
+ if (Array.isArray(data)) {
62904
+ if (data[0] !== 0n) {
62905
+ throw (new Error('Invalid block version without context tag'));
62906
+ }
62907
+ this.version = 1;
62908
+ this.purpose = BlockPurpose.GENERIC;
62909
+ this.network = data[1];
62910
+ this.subnet = data[2] ?? undefined;
62911
+ this.date = data[3].date;
62912
+ const signerContainer = data[4];
62913
+ this.signer = account_1.default.fromPublicKeyAndType(signerContainer).assertAccount();
62914
+ const acctItem = data[5];
62915
+ if (acctItem === null) {
62916
+ this.account = this.signer;
62917
+ }
62918
+ else {
62919
+ this.account = account_1.default.fromPublicKeyAndType(acctItem);
62920
+ if (this.account.comparePublicKey(this.signer)) {
62921
+ throw (new Error('Account should not be in block when it is same as signer, we cannot use this block'));
62922
+ }
62923
+ }
62924
+ const prevHashBuf = data[6];
62925
+ this.previous = new BlockHash(prevHashBuf);
62926
+ this.operations = Operations.ImportOperationsASN1(data[7], this.network);
62927
+ this.signatures = [data[8]];
62928
+ }
62929
+ else if (data.value === 1) {
62930
+ this.version = 2;
62931
+ const container = data.contains;
62932
+ this.network = container[0];
62933
+ this.subnet = container[1] ?? undefined;
62934
+ this.date = container[2].date;
62935
+ this.purpose = toBlockPurpose(container[3]);
62936
+ this.account = account_1.default.fromPublicKeyAndType(container[4]);
62937
+ const signersContainer = container[5];
62938
+ if (signersContainer === null) {
62939
+ this.signer = this.account.assertAccount();
62940
+ }
62941
+ else if (Buffer.isBuffer(signersContainer)) {
62942
+ this.signer = account_1.default.fromPublicKeyAndType(signersContainer).assertAccount();
62943
+ if (this.account.comparePublicKey(this.signer)) {
62944
+ throw (new Error('Signer should not be in block when it is same as account, we cannot use this block'));
62945
+ }
62946
+ }
62947
+ else {
62948
+ this.signer = parseBlockSignerFieldContainer(signersContainer).parsed;
62949
+ }
62950
+ this.previous = new BlockHash(container[6]);
62951
+ this.operations = Operations.ImportOperationsASN1(container[7], this.network);
62952
+ const signatureContainer = container[8];
62953
+ if (Buffer.isBuffer(signatureContainer)) {
62954
+ this.signatures = [signatureContainer];
62955
+ }
62956
+ else {
62957
+ if (signatureContainer.length <= 1) {
62958
+ throw (new Error('Signature field invalid, must be greater than one when using sequence of'));
62959
+ }
62960
+ assertBlockSignatureField(signatureContainer);
62961
+ this.signatures = signatureContainer;
62962
+ }
62558
62963
  }
62559
62964
  else {
62560
- this.account = account_1.default.fromPublicKeyAndType(acctItem);
62561
- if (this.account.comparePublicKey(this.signer)) {
62562
- throw (new Error('Account should not be in block when it is same as signer, we cannot use this block'));
62563
- }
62965
+ throw (new Error('Unknown block version'));
62564
62966
  }
62565
- const prevHashBuf = data[6];
62566
- this.previous = new BlockHash(prevHashBuf);
62567
- this.operations = Operations.ImportOperationsASN1(data[7], this.network);
62568
- this.signature = data[8];
62569
62967
  __classPrivateFieldSet(this, _Block_valueBytes, input, "f");
62570
62968
  }
62571
62969
  else {
62572
- if (!Block.isValidJSON(input)) {
62573
- throw (new Error('Cannot construct block, it is not a valid Block JSON object'));
62574
- }
62575
- /* XXX:TODO: Verify that no extra keys were passed in */
62576
- /*
62577
- * Map input to our values
62578
- */
62579
- const { version, date, previous, network, subnet, account, operations, signer } = MapInputValues(input);
62580
- this.version = version;
62581
- this.date = date;
62582
- this.previous = previous;
62583
- this.network = network;
62584
- this.subnet = subnet;
62585
- this.account = account;
62586
- this.signer = signer;
62587
- this.operations = operations;
62588
- /*
62589
- * We must handle the signature last because we will
62590
- * sign the hash of the block based on what has been
62591
- * processed
62592
- */
62593
- if (input.signature === undefined) {
62594
- throw (new Error('Cannot construct block without a signature and explicit direction to sign'));
62970
+ if (_a.isInstance(input)) {
62971
+ this.version = input.version;
62972
+ this.purpose = input.purpose;
62973
+ this.date = input.date;
62974
+ this.previous = input.previous;
62975
+ this.network = input.network;
62976
+ this.subnet = input.subnet;
62977
+ this.account = input.account;
62978
+ this.operations = input.operations;
62979
+ this.signer = input.signer;
62980
+ this.signatures = input.signatures;
62981
+ }
62982
+ else if (_a.isValidJSON(input, 1)) {
62983
+ /*
62984
+ * Map input to our values
62985
+ */
62986
+ const { version, date, previous, network, subnet, account, operations, signer } = MapV1InputValues(input);
62987
+ this.version = version;
62988
+ this.purpose = BlockPurpose.GENERIC;
62989
+ this.date = date;
62990
+ this.previous = previous;
62991
+ this.network = network;
62992
+ this.subnet = subnet;
62993
+ this.account = account;
62994
+ this.operations = operations;
62995
+ this.signer = signer;
62996
+ /*
62997
+ * We must handle the signature last because we will
62998
+ * sign the hash of the block based on what has been
62999
+ * processed
63000
+ */
63001
+ if (input.signature === undefined) {
63002
+ throw (new Error('Cannot construct block without a signature and explicit direction to sign'));
63003
+ }
63004
+ let signature;
63005
+ if (typeof input.signature === 'string') {
63006
+ signature = Buffer.from(input.signature, 'hex');
63007
+ }
63008
+ else {
63009
+ signature = Buffer.from(input.signature);
63010
+ }
63011
+ this.signatures = [signature];
62595
63012
  }
62596
- if (typeof input.signature === 'string') {
62597
- this.signature = Buffer.from(input.signature, 'hex');
63013
+ else if (_a.isValidJSON(input, 2)) {
63014
+ /*
63015
+ * Map input to our values
63016
+ */
63017
+ const { version, date, previous, network, subnet, account, operations, signer, purpose } = MapV2InputValues(input);
63018
+ this.version = version;
63019
+ this.purpose = purpose;
63020
+ this.date = date;
63021
+ this.previous = previous;
63022
+ this.network = network;
63023
+ this.subnet = subnet;
63024
+ this.account = account;
63025
+ this.signer = signer;
63026
+ this.operations = operations;
63027
+ /*
63028
+ * We must handle the signature last because we will
63029
+ * sign the hash of the block based on what has been
63030
+ * processed
63031
+ */
63032
+ if (input.signatures === undefined) {
63033
+ throw (new Error('Cannot construct block without a signature and explicit direction to sign'));
63034
+ }
63035
+ const signatures = input.signatures.map(function (signature) {
63036
+ if (typeof signature === 'string') {
63037
+ return (Buffer.from(signature, 'hex'));
63038
+ }
63039
+ else {
63040
+ return (Buffer.from(signature));
63041
+ }
63042
+ });
63043
+ assertBlockSignatureField(signatures);
63044
+ this.signatures = signatures;
62598
63045
  }
62599
63046
  else {
62600
- this.signature = Buffer.from(input.signature);
63047
+ throw (new Error('Cannot construct block, it is not a valid Block JSON object'));
62601
63048
  }
63049
+ /* XXX:TODO: Verify that no extra keys were passed in */
62602
63050
  }
62603
63051
  if (this.previous.compareHexString(this.hash)) {
62604
63052
  throw (new block_1.default('BLOCK_PREVIOUS_SELF', 'internal error: Block references itself'));
62605
63053
  }
62606
- const checkAccountOpening = Block.getAccountOpeningHash(this.account);
63054
+ const checkAccountOpening = _a.getAccountOpeningHash(this.account);
62607
63055
  this.$opening = this.previous.compareHexString(checkAccountOpening);
62608
63056
  if (this.network < 0n) {
62609
63057
  throw (new Error('Network ID must be a positive number'));
@@ -62613,35 +63061,91 @@ class Block {
62613
63061
  throw (new Error('Subnet ID must be a positive number'));
62614
63062
  }
62615
63063
  }
62616
- if (this.version !== 1) {
62617
- throw (new Error('We only support Blocks with Version 1'));
63064
+ if (this.version !== 1 && this.version !== 2) {
63065
+ throw (new block_1.default('BLOCK_INVALID_VERSION', 'We only support Blocks Version 1-2'));
62618
63066
  }
62619
63067
  if (this.account.isMultisig()) {
62620
63068
  throw (new block_1.default('BLOCK_NO_MULTISIG_OP', 'Cannot create a block for a multisig account'));
62621
63069
  }
62622
- __classPrivateFieldGet(this, _Block_instances, "m", _Block_validateOperations).call(this);
62623
- __classPrivateFieldGet(this, _Block_instances, "m", _Block_validateSignature).call(this);
63070
+ if (this.account.isMultisig()) {
63071
+ throw (new block_1.default('BLOCK_NO_MULTISIG_OP', 'Cannot create a block for a multisig account'));
63072
+ }
63073
+ __classPrivateFieldGet(this, _Block_instances, "m", _Block_validateSignerField).call(this);
63074
+ __classPrivateFieldGet(this, _Block_instances, "m", _Block_validateOperationsPurpose).call(this);
63075
+ __classPrivateFieldGet(this, _Block_instances, "m", _Block_validateSignatures).call(this);
62624
63076
  }
62625
63077
  static getAccountOpeningHash(account) {
62626
63078
  return (BlockHash.getAccountOpeningHash(account));
62627
63079
  }
62628
- toBytes(includeSignature = true) {
62629
- if (__classPrivateFieldGet(this, _Block_valueBytes, "f") !== undefined) {
62630
- if (includeSignature) {
62631
- return (__classPrivateFieldGet(this, _Block_valueBytes, "f"));
63080
+ toBytes(includeSignatures = true) {
63081
+ if (__classPrivateFieldGet(this, _Block_valueBytes, "f") !== undefined && includeSignatures) {
63082
+ return (__classPrivateFieldGet(this, _Block_valueBytes, "f"));
63083
+ }
63084
+ const sharedBlockValues = {
63085
+ previous: this.previous,
63086
+ operations: this.operations,
63087
+ account: this.account,
63088
+ network: this.network,
63089
+ subnet: this.subnet,
63090
+ date: this.date
63091
+ };
63092
+ let container;
63093
+ if (this.version === 1) {
63094
+ if (Array.isArray(this.signer) || this.signatures.length !== 1) {
63095
+ throw (new Error('Block v1 only supports single signer'));
63096
+ }
63097
+ container = _a.getV1ASN1ContainerWithoutSignature({
63098
+ ...sharedBlockValues,
63099
+ version: 1,
63100
+ signer: this.signer
63101
+ });
63102
+ if (includeSignatures) {
63103
+ container.push(this.signatures[0]);
62632
63104
  }
62633
63105
  }
62634
- const container = Block.getASN1ContainerWithoutSignature(this);
62635
- if (includeSignature) {
62636
- container.push(this.signature);
63106
+ else {
63107
+ const versionTag = this.version - 1;
63108
+ if (versionTag !== 1) {
63109
+ // We only support version 2
63110
+ throw (new block_1.default('BLOCK_INVALID_VERSION', 'We only support version 1/2 blocks'));
63111
+ }
63112
+ const v2Container = _a.getV2ASN1ContainerWithoutSignature({
63113
+ ...sharedBlockValues,
63114
+ purpose: this.purpose,
63115
+ version: this.version,
63116
+ signer: this.signer
63117
+ });
63118
+ const baseContextTag = {
63119
+ type: 'context',
63120
+ kind: 'explicit',
63121
+ value: versionTag
63122
+ };
63123
+ if (includeSignatures) {
63124
+ let signatureContainer;
63125
+ if (this.signatures.length > 1) {
63126
+ signatureContainer = this.signatures;
63127
+ }
63128
+ else if (this.signatures.length === 1) {
63129
+ signatureContainer = this.signatures[0];
63130
+ }
63131
+ else {
63132
+ throw (new Error('Block has not been signed'));
63133
+ }
63134
+ container = { ...baseContextTag, contains: [...v2Container, signatureContainer] };
63135
+ }
63136
+ else {
63137
+ container = { ...baseContextTag, contains: v2Container };
63138
+ }
62637
63139
  }
63140
+ // We know the container is valid because of the container type, but the ASN1.JStoASN1 function does not handle recursive types well
63141
+ // @ts-ignore
62638
63142
  const retval = ASN1.JStoASN1(container).toBER(false);
62639
- if (includeSignature) {
63143
+ if (includeSignatures) {
62640
63144
  __classPrivateFieldSet(this, _Block_valueBytes, retval, "f");
62641
63145
  }
62642
63146
  return (retval);
62643
63147
  }
62644
- static getASN1ContainerWithoutSignature(input) {
63148
+ static getV1ASN1ContainerWithoutSignature(input) {
62645
63149
  let outputAccount;
62646
63150
  if (input.account.comparePublicKey(input.signer)) {
62647
63151
  outputAccount = null;
@@ -62652,7 +63156,7 @@ class Block {
62652
63156
  if (input.version !== 1) {
62653
63157
  throw (new Error('Cannot call getASN1ContainerWithoutSignature when version != 1'));
62654
63158
  }
62655
- const container = [
63159
+ return ([
62656
63160
  0n,
62657
63161
  input.network,
62658
63162
  input.subnet ?? null,
@@ -62661,21 +63165,72 @@ class Block {
62661
63165
  outputAccount,
62662
63166
  Buffer.from(input.previous.get()),
62663
63167
  Operations.ExportBlockOperations([...input.operations])
62664
- ];
62665
- return (container);
63168
+ ]);
63169
+ }
63170
+ static getV2ASN1ContainerWithoutSignature(input) {
63171
+ if (input.version !== 2) {
63172
+ throw (new Error('Only version 2 supported'));
63173
+ }
63174
+ let signerContainer;
63175
+ if (Array.isArray(input.signer)) {
63176
+ signerContainer = getMultisigSignerContainer(input.signer);
63177
+ }
63178
+ else if (input.signer.comparePublicKey(input.account)) {
63179
+ signerContainer = null;
63180
+ }
63181
+ else {
63182
+ signerContainer = input.signer.publicKeyAndType;
63183
+ }
63184
+ return ([
63185
+ input.network,
63186
+ input.subnet,
63187
+ { type: 'date', kind: 'general', date: input.date },
63188
+ BigInt(input.purpose),
63189
+ input.account.publicKeyAndType,
63190
+ signerContainer,
63191
+ Buffer.from(input.previous.get()),
63192
+ Operations.ExportBlockOperations([...input.operations])
63193
+ ]);
63194
+ }
63195
+ static getASN1ContainerWithoutSignature(input) {
63196
+ if (input.version === 1) {
63197
+ return (this.getV1ASN1ContainerWithoutSignature(input));
63198
+ }
63199
+ else if (input.version === 2) {
63200
+ return ({
63201
+ type: 'context',
63202
+ kind: 'explicit',
63203
+ value: 1,
63204
+ contains: this.getV2ASN1ContainerWithoutSignature(input)
63205
+ });
63206
+ }
63207
+ else {
63208
+ throw (new block_1.default('BLOCK_INVALID_VERSION', 'Invalid Version'));
63209
+ }
62666
63210
  }
62667
63211
  toJSON(options) {
62668
63212
  const additionalFields = {};
62669
63213
  if (options?.addBinary) {
62670
63214
  additionalFields['$binary'] = Buffer.from(this.toBytes()).toString('base64');
62671
63215
  }
63216
+ const signatures = this.signatures.map(function (signature) {
63217
+ return (signature.toString('hex').toUpperCase());
63218
+ });
63219
+ if (this.version === 1) {
63220
+ additionalFields.signature = signatures[0];
63221
+ }
63222
+ else {
63223
+ additionalFields.signatures = signatures;
63224
+ }
62672
63225
  return ({
62673
63226
  version: this.version,
62674
63227
  date: this.date,
62675
63228
  previous: this.previous,
62676
63229
  account: this.account,
63230
+ purpose: this.purpose,
63231
+ // XXX:TODO We need to use a type assertion here because toJSONSerializable does not support recursive types
63232
+ // eslint-disable-next-line @typescript-eslint/consistent-type-assertions
62677
63233
  signer: this.signer,
62678
- signature: this.signature.toString('hex').toUpperCase(),
62679
63234
  network: this.network,
62680
63235
  subnet: this.subnet,
62681
63236
  operations: Operations.ExportOperationsJSON(this.operations),
@@ -62702,7 +63257,27 @@ class Block {
62702
63257
  }
62703
63258
  }
62704
63259
  exports.Block = Block;
62705
- _Block_valueBytes = new WeakMap(), _Block_valueHash = new WeakMap(), _Block_instances = new WeakSet(), _Block_validateOperations = function _Block_validateOperations() {
63260
+ _a = Block, _Block_valueBytes = new WeakMap(), _Block_valueHash = new WeakMap(), _Block_instances = new WeakSet(), _Block_getSortedRequiredSigners = function _Block_getSortedRequiredSigners(input) {
63261
+ const queue = [input];
63262
+ const visited = new account_1.default.Set();
63263
+ const out = [];
63264
+ while (queue.length > 0) {
63265
+ // We can assume that the signerFieldQueue is not empty here since the loop condition checks it
63266
+ // eslint-disable-next-line @typescript-eslint/no-non-null-assertion
63267
+ const cur = queue.shift();
63268
+ if (account_1.default.isInstance(cur)) {
63269
+ if (visited.has(cur)) {
63270
+ continue;
63271
+ }
63272
+ visited.add(cur);
63273
+ out.push(cur);
63274
+ }
63275
+ else {
63276
+ queue.unshift(...cur[1]);
63277
+ }
63278
+ }
63279
+ return (out);
63280
+ }, _Block_validateOperationsPurpose = function _Block_validateOperationsPurpose() {
62706
63281
  /**
62707
63282
  * Do not allow blocks to contain invalid constructions
62708
63283
  */
@@ -62711,23 +63286,63 @@ _Block_valueBytes = new WeakMap(), _Block_valueHash = new WeakMap(), _Block_inst
62711
63286
  operationIndex: 0
62712
63287
  };
62713
63288
  for (const operation of this.operations) {
63289
+ if (this.purpose === BlockPurpose.FEE) {
63290
+ if (operation.type !== Operations.OperationType.SEND) {
63291
+ throw (new block_1.default('BLOCK_INVALID_PURPOSE_VALIDATION', `Block purpose is FEE, but operation at index ${context.operationIndex} is not a SEND operation`));
63292
+ }
63293
+ }
62714
63294
  operation.validate(context);
62715
63295
  context.operationIndex++;
62716
63296
  }
62717
- }, _Block_validateSignature = function _Block_validateSignature() {
62718
- /* XXX:TODO: 64 is the size of signatures right now but this shouldn't be hard-coded */
62719
- const signature = new buffer_1.BufferStorage(this.signature, 64);
62720
- const valid = this.signer.verify(this.hash.get(), signature.get());
62721
- if (valid !== true) {
62722
- throw (new Error(`Unable to validate signature of ${this.hash.toString()} against signature ${this.signature}`));
63297
+ }, _Block_validateSignerField = function _Block_validateSignerField() {
63298
+ if (!Array.isArray(this.signer)) {
63299
+ return;
63300
+ }
63301
+ const queue = [[1n, this.signer]];
63302
+ while (queue.length > 0) {
63303
+ // We can assume that the signerFieldQueue is not empty here since the loop condition checks it
63304
+ // eslint-disable-next-line @typescript-eslint/no-non-null-assertion
63305
+ const [depth, cur] = queue.shift();
63306
+ (0, common_1.validateBlockSignerDepth)(depth, this.network);
63307
+ if (Array.isArray(cur)) {
63308
+ (0, common_1.validateBlockSignerCount)(BigInt(cur[1].length), this.network);
63309
+ const seen = new account_1.default.Set();
63310
+ for (const innerSigner of cur[1]) {
63311
+ let signer;
63312
+ if (Array.isArray(innerSigner)) {
63313
+ signer = innerSigner[0];
63314
+ queue.push([depth + 1n, innerSigner]);
63315
+ }
63316
+ else {
63317
+ signer = innerSigner;
63318
+ }
63319
+ if (seen.has(signer)) {
63320
+ throw (new block_1.default('BLOCK_INVALID_MULTISIG_SIGNER_DUPLICATE', `Multisig signer at depth ${depth} has duplicate signer ${signer.publicKeyString.get()}`));
63321
+ }
63322
+ seen.add(signer);
63323
+ }
63324
+ }
63325
+ }
63326
+ }, _Block_validateSignatures = function _Block_validateSignatures() {
63327
+ const signers = __classPrivateFieldGet(_a, _a, "m", _Block_getSortedRequiredSigners).call(_a, this.signer);
63328
+ if (this.signatures.length !== signers.length) {
63329
+ throw (new block_1.default('BLOCK_INVALID_SIGNER', 'Signer count does not match signature count'));
63330
+ }
63331
+ for (let i = 0; i < signers.length; i++) {
63332
+ const signature = new buffer_1.BufferStorage(this.signatures[i], 64);
63333
+ const valid = signers[i].verify(this.hash.get(), signature.get());
63334
+ if (valid !== true) {
63335
+ throw (new Error(`Unable to validate signature of ${this.hash.toString()} against signature ${this.signatures[i]} for account ${signers[i].publicKeyString.get()}`));
63336
+ }
62723
63337
  }
62724
63338
  };
62725
- Block.isInstance = (0, helper_1.checkableGenerator)(Block);
63339
+ Block.isInstance = (0, helper_1.checkableGenerator)(_a);
62726
63340
  Block.Hash = BlockHash;
62727
63341
  Block.OperationType = Operations.OperationType;
62728
63342
  Block.Operation = Operations.Operation;
62729
63343
  Block.NO_PREVIOUS = NO_PREVIOUS;
62730
63344
  Block.AdjustMethod = AdjustMethod;
63345
+ Block.Purpose = BlockPurpose;
62731
63346
  class BlockBuilder {
62732
63347
  constructor(block) {
62733
63348
  _BlockBuilder_block.set(this, void 0);
@@ -62745,13 +63360,13 @@ class BlockBuilder {
62745
63360
  __classPrivateFieldSet(this, _BlockBuilder_block, new Block(block), "f");
62746
63361
  }
62747
63362
  else {
62748
- if (block !== undefined && Block.isValidJSON(block)) {
63363
+ if (block !== undefined && Block.isValidJSON(block, 2)) {
62749
63364
  __classPrivateFieldSet(this, _BlockBuilder_block, new Block(block), "f");
62750
63365
  }
62751
63366
  else {
62752
63367
  const incompleteBlockJSON = {
62753
- version: 1,
62754
63368
  date: (new Date()).toISOString(),
63369
+ version: 1,
62755
63370
  ...block
62756
63371
  };
62757
63372
  /*
@@ -62761,7 +63376,18 @@ class BlockBuilder {
62761
63376
  if (incompleteBlockJSON.previous === BlockBuilder.NO_PREVIOUS) {
62762
63377
  setPreviousNoBlock = true;
62763
63378
  }
62764
- const newBlockJSON = MapInputValues(incompleteBlockJSON);
63379
+ let newBlockJSON;
63380
+ if (incompleteBlockJSON.version === 1) {
63381
+ // We have to use a type assertion here because the MapV1InputValues function does not support recursive types
63382
+ // eslint-disable-next-line @typescript-eslint/consistent-type-assertions
63383
+ newBlockJSON = MapV1InputValues({ ...incompleteBlockJSON, version: 1 });
63384
+ }
63385
+ else if (incompleteBlockJSON.version === 2) {
63386
+ newBlockJSON = MapV2InputValues({ ...incompleteBlockJSON, version: 2 });
63387
+ }
63388
+ else {
63389
+ throw (new Error('Cannot construct block, it is not a valid Block JSON object'));
63390
+ }
62765
63391
  if (setPreviousNoBlock) {
62766
63392
  newBlockJSON.previous = BlockBuilder.NO_PREVIOUS;
62767
63393
  }
@@ -62801,20 +63427,42 @@ class BlockBuilder {
62801
63427
  network: this.network,
62802
63428
  subnet: this.subnet,
62803
63429
  operations: this.operations,
63430
+ purpose: this.purpose,
62804
63431
  ['$opening']: this.$opening
62805
63432
  });
62806
63433
  }
62807
63434
  async seal() {
62808
- const block = await Block.fromUnsignedJSON(MapInputValues(this));
63435
+ if (this.version === undefined) {
63436
+ throw (new Error('Cannot seal block without version'));
63437
+ }
63438
+ let input;
63439
+ // There is no clean way to tell the compiler which version `this` is, so we have to use a type assertion
63440
+ if (this.version === 1) {
63441
+ // eslint-disable-next-line @typescript-eslint/consistent-type-assertions
63442
+ input = MapV1InputValues(this);
63443
+ }
63444
+ else {
63445
+ // eslint-disable-next-line @typescript-eslint/consistent-type-assertions
63446
+ input = MapV2InputValues(this);
63447
+ }
63448
+ const block = await Block.fromUnsignedJSON(input);
62809
63449
  __classPrivateFieldSet(this, _BlockBuilder_block, block, "f");
62810
63450
  return (block);
62811
63451
  }
62812
63452
  unseal() {
62813
63453
  let retval;
62814
63454
  if (Block.isInstance(__classPrivateFieldGet(this, _BlockBuilder_block, "f"))) {
62815
- __classPrivateFieldSet(this, _BlockBuilder_block, { ...__classPrivateFieldGet(this, _BlockBuilder_block, "f") }, "f");
63455
+ __classPrivateFieldSet(this, _BlockBuilder_block, {
63456
+ version: __classPrivateFieldGet(this, _BlockBuilder_block, "f").version,
63457
+ date: __classPrivateFieldGet(this, _BlockBuilder_block, "f").date,
63458
+ previous: __classPrivateFieldGet(this, _BlockBuilder_block, "f").previous,
63459
+ account: __classPrivateFieldGet(this, _BlockBuilder_block, "f").account,
63460
+ signer: __classPrivateFieldGet(this, _BlockBuilder_block, "f").signer,
63461
+ network: __classPrivateFieldGet(this, _BlockBuilder_block, "f").network,
63462
+ subnet: __classPrivateFieldGet(this, _BlockBuilder_block, "f").subnet,
63463
+ operations: [...__classPrivateFieldGet(this, _BlockBuilder_block, "f").operations]
63464
+ }, "f");
62816
63465
  retval = __classPrivateFieldGet(this, _BlockBuilder_block, "f");
62817
- delete retval['signature'];
62818
63466
  }
62819
63467
  else {
62820
63468
  retval = __classPrivateFieldGet(this, _BlockBuilder_block, "f");
@@ -62839,12 +63487,36 @@ class BlockBuilder {
62839
63487
  }
62840
63488
  }
62841
63489
  set signer(signer) {
62842
- this.currentWIP.signer = account_1.default.toAccount(signer);
63490
+ if (signer) {
63491
+ this.currentWIP.signer = parseBlockSignerFieldJSON(signer);
63492
+ }
63493
+ else {
63494
+ this.currentWIP.signer = undefined;
63495
+ }
62843
63496
  }
62844
63497
  get signer() {
62845
63498
  const signer = __classPrivateFieldGet(this, _BlockBuilder_block, "f").signer;
62846
- if (signer !== undefined && !account_1.default.isInstance(signer)) {
62847
- throw (new Error('internal error: We only represent signer as Account'));
63499
+ if (signer === undefined) {
63500
+ if (this.account && this.account.isAccount() && this.account.hasPrivateKey) {
63501
+ return (this.account);
63502
+ }
63503
+ }
63504
+ else {
63505
+ const queue = [signer];
63506
+ while (queue.length > 0) {
63507
+ const cur = queue.shift();
63508
+ let signer;
63509
+ if (Array.isArray(cur)) {
63510
+ signer = cur[0];
63511
+ queue.push(...cur[1]);
63512
+ }
63513
+ else {
63514
+ signer = cur;
63515
+ }
63516
+ if (!account_1.default.isInstance(signer)) {
63517
+ throw (new Error('internal error: We only represent signer/multisig-info as their constructed values'));
63518
+ }
63519
+ }
62848
63520
  }
62849
63521
  return (signer);
62850
63522
  }
@@ -62856,7 +63528,16 @@ class BlockBuilder {
62856
63528
  if (account !== undefined && !account_1.default.isInstance(account)) {
62857
63529
  throw (new Error('internal error: We only represent account as an Account'));
62858
63530
  }
62859
- return (account ?? this.signer);
63531
+ if (account === undefined && this.version === 1 || this.version === undefined) {
63532
+ if (Array.isArray(this.signer)) {
63533
+ throw (new Error('Cannot create a v1 block with a multisig signer'));
63534
+ }
63535
+ if (typeof this.signer === 'string') {
63536
+ throw (new Error('We should only represent signer as an Account'));
63537
+ }
63538
+ return (this.signer);
63539
+ }
63540
+ return (account);
62860
63541
  }
62861
63542
  set previous(blockhash) {
62862
63543
  const wip = this.currentWIP;
@@ -62929,6 +63610,18 @@ class BlockBuilder {
62929
63610
  get version() {
62930
63611
  return (this.currentBlock.version);
62931
63612
  }
63613
+ set purpose(purpose) {
63614
+ if (purpose !== undefined && purpose !== BlockPurpose.GENERIC && this.version === 1) {
63615
+ throw (new Error('Cannot set purpose (other than generic) on a v1 block'));
63616
+ }
63617
+ this.currentWIP.purpose = purpose;
63618
+ }
63619
+ get purpose() {
63620
+ if (this.currentBlock.purpose !== undefined) {
63621
+ return (this.currentBlock.purpose);
63622
+ }
63623
+ return (BlockPurpose.GENERIC);
63624
+ }
62932
63625
  set network(network) {
62933
63626
  this.currentWIP.network = network;
62934
63627
  }
@@ -63025,7 +63718,7 @@ var __classPrivateFieldGet = (this && this.__classPrivateFieldGet) || function (
63025
63718
  var __importDefault = (this && this.__importDefault) || function (mod) {
63026
63719
  return (mod && mod.__esModule) ? mod : { "default": mod };
63027
63720
  };
63028
- var _BlockOperationSEND_instances, _BlockOperationSEND_to, _BlockOperationSEND_amount, _BlockOperationSEND_token, _BlockOperationSEND_computeToken, _BlockOperationRECEIVE_instances, _BlockOperationRECEIVE_amount, _BlockOperationRECEIVE_token, _BlockOperationRECEIVE_from, _BlockOperationRECEIVE_forward, _BlockOperationRECEIVE_exact, _BlockOperationRECEIVE_computeExact, _BlockOperationRECEIVE_computeForward, _BlockOperationRECEIVE_computeToken, _BlockOperationTOKEN_ADMIN_MODIFY_BALANCE_instances, _BlockOperationTOKEN_ADMIN_MODIFY_BALANCE_token, _BlockOperationTOKEN_ADMIN_MODIFY_BALANCE_method, _BlockOperationTOKEN_ADMIN_MODIFY_BALANCE_amount, _BlockOperationTOKEN_ADMIN_MODIFY_BALANCE_computeToken, _BlockOperationSET_REP_to, _BlockOperationCREATE_IDENTIFIER_instances, _BlockOperationCREATE_IDENTIFIER_identifier, _BlockOperationCREATE_IDENTIFIER_computeIdentifier, _BlockOperationSET_INFO_instances, _BlockOperationSET_INFO_name, _BlockOperationSET_INFO_description, _BlockOperationSET_INFO_metadata, _BlockOperationSET_INFO_defaultPermission, _BlockOperationSET_INFO_validateNameDesc, _BlockOperationMODIFY_PERMISSIONS_instances, _BlockOperationMODIFY_PERMISSIONS_principal, _BlockOperationMODIFY_PERMISSIONS_target, _BlockOperationMODIFY_PERMISSIONS_method, _BlockOperationMODIFY_PERMISSIONS_permissions, _BlockOperationMODIFY_PERMISSIONS_computePermissions, _BlockOperationTOKEN_ADMIN_SUPPLY_instances, _BlockOperationTOKEN_ADMIN_SUPPLY_amount, _BlockOperationTOKEN_ADMIN_SUPPLY_method, _BlockOperationTOKEN_ADMIN_SUPPLY_computeSupplyMethod, _BlockOperationMANAGE_CERTIFICATE_instances, _BlockOperationMANAGE_CERTIFICATE_certificateOrHash, _BlockOperationMANAGE_CERTIFICATE_intermediateCertificates, _BlockOperationMANAGE_CERTIFICATE_method, _BlockOperationMANAGE_CERTIFICATE_asCertificate, _BlockOperationMANAGE_CERTIFICATE_asIntermediateCertificates, _BlockOperationMANAGE_CERTIFICATE_computeCertificateMethod;
63721
+ var _BlockOperationSEND_instances, _BlockOperationSEND_to, _BlockOperationSEND_amount, _BlockOperationSEND_token, _BlockOperationSEND_computeToken, _BlockOperationRECEIVE_instances, _BlockOperationRECEIVE_amount, _BlockOperationRECEIVE_token, _BlockOperationRECEIVE_from, _BlockOperationRECEIVE_forward, _BlockOperationRECEIVE_exact, _BlockOperationRECEIVE_computeExact, _BlockOperationRECEIVE_computeForward, _BlockOperationRECEIVE_computeToken, _BlockOperationTOKEN_ADMIN_MODIFY_BALANCE_instances, _BlockOperationTOKEN_ADMIN_MODIFY_BALANCE_token, _BlockOperationTOKEN_ADMIN_MODIFY_BALANCE_method, _BlockOperationTOKEN_ADMIN_MODIFY_BALANCE_amount, _BlockOperationTOKEN_ADMIN_MODIFY_BALANCE_computeToken, _BlockOperationSET_REP_to, _BlockOperationCREATE_IDENTIFIER_instances, _BlockOperationCREATE_IDENTIFIER_identifier, _BlockOperationCREATE_IDENTIFIER_createArguments, _BlockOperationCREATE_IDENTIFIER_computeIdentifier, _BlockOperationCREATE_IDENTIFIER_computeCreateArguments, _BlockOperationSET_INFO_instances, _BlockOperationSET_INFO_name, _BlockOperationSET_INFO_description, _BlockOperationSET_INFO_metadata, _BlockOperationSET_INFO_defaultPermission, _BlockOperationSET_INFO_validateNameDesc, _BlockOperationMODIFY_PERMISSIONS_instances, _BlockOperationMODIFY_PERMISSIONS_principal, _BlockOperationMODIFY_PERMISSIONS_target, _BlockOperationMODIFY_PERMISSIONS_method, _BlockOperationMODIFY_PERMISSIONS_permissions, _BlockOperationMODIFY_PERMISSIONS_computePermissions, _BlockOperationTOKEN_ADMIN_SUPPLY_instances, _BlockOperationTOKEN_ADMIN_SUPPLY_amount, _BlockOperationTOKEN_ADMIN_SUPPLY_method, _BlockOperationTOKEN_ADMIN_SUPPLY_computeSupplyMethod, _BlockOperationMANAGE_CERTIFICATE_instances, _BlockOperationMANAGE_CERTIFICATE_certificateOrHash, _BlockOperationMANAGE_CERTIFICATE_intermediateCertificates, _BlockOperationMANAGE_CERTIFICATE_method, _BlockOperationMANAGE_CERTIFICATE_asCertificate, _BlockOperationMANAGE_CERTIFICATE_asIntermediateCertificates, _BlockOperationMANAGE_CERTIFICATE_computeCertificateMethod;
63029
63722
  Object.defineProperty(exports, "__esModule", ({ value: true }));
63030
63723
  exports.Operation = exports.BlockOperationASN1Schema = exports.OperationType = void 0;
63031
63724
  exports.createBlockOperation = createBlockOperation;
@@ -63121,7 +63814,25 @@ const BlockOperationASN1SchemaBase = {
63121
63814
  { name: 'target', schema: { optional: asn1_1.ValidateASN1.IsOctetString } }
63122
63815
  ],
63123
63816
  'CREATE_IDENTIFIER': [
63124
- { name: 'identifier', schema: asn1_1.ValidateASN1.IsOctetString }
63817
+ { name: 'identifier', schema: asn1_1.ValidateASN1.IsOctetString },
63818
+ {
63819
+ name: 'createArguments',
63820
+ schema: {
63821
+ optional: {
63822
+ choice: [
63823
+ {
63824
+ type: 'context',
63825
+ kind: 'explicit',
63826
+ value: 7,
63827
+ contains: [
63828
+ { sequenceOf: asn1_1.ValidateASN1.IsOctetString },
63829
+ asn1_1.ValidateASN1.IsInteger
63830
+ ]
63831
+ }
63832
+ ]
63833
+ }
63834
+ }
63835
+ }
63125
63836
  ],
63126
63837
  'TOKEN_ADMIN_SUPPLY': [
63127
63838
  { name: 'amount', schema: asn1_1.ValidateASN1.IsInteger },
@@ -63469,10 +64180,12 @@ class BlockOperationCREATE_IDENTIFIER extends BlockOperation {
63469
64180
  _BlockOperationCREATE_IDENTIFIER_instances.add(this);
63470
64181
  this.type = OperationType.CREATE_IDENTIFIER;
63471
64182
  _BlockOperationCREATE_IDENTIFIER_identifier.set(this, void 0);
64183
+ _BlockOperationCREATE_IDENTIFIER_createArguments.set(this, void 0);
63472
64184
  if (input.type !== OperationType.CREATE_IDENTIFIER) {
63473
64185
  throw (new block_1.default('BLOCK_INVALID_TYPE', 'Invalid construction of BlockOperationCREATE_IDENTIFIER'));
63474
64186
  }
63475
64187
  __classPrivateFieldSet(this, _BlockOperationCREATE_IDENTIFIER_identifier, __classPrivateFieldGet(this, _BlockOperationCREATE_IDENTIFIER_instances, "m", _BlockOperationCREATE_IDENTIFIER_computeIdentifier).call(this, input.identifier), "f");
64188
+ __classPrivateFieldSet(this, _BlockOperationCREATE_IDENTIFIER_createArguments, __classPrivateFieldGet(this, _BlockOperationCREATE_IDENTIFIER_instances, "m", _BlockOperationCREATE_IDENTIFIER_computeCreateArguments).call(this, input.createArguments), "f");
63476
64189
  }
63477
64190
  set identifier(identifier) {
63478
64191
  __classPrivateFieldSet(this, _BlockOperationCREATE_IDENTIFIER_identifier, __classPrivateFieldGet(this, _BlockOperationCREATE_IDENTIFIER_instances, "m", _BlockOperationCREATE_IDENTIFIER_computeIdentifier).call(this, identifier), "f");
@@ -63480,6 +64193,12 @@ class BlockOperationCREATE_IDENTIFIER extends BlockOperation {
63480
64193
  get identifier() {
63481
64194
  return (__classPrivateFieldGet(this, _BlockOperationCREATE_IDENTIFIER_identifier, "f"));
63482
64195
  }
64196
+ set createArguments(input) {
64197
+ __classPrivateFieldSet(this, _BlockOperationCREATE_IDENTIFIER_createArguments, __classPrivateFieldGet(this, _BlockOperationCREATE_IDENTIFIER_instances, "m", _BlockOperationCREATE_IDENTIFIER_computeCreateArguments).call(this, input), "f");
64198
+ }
64199
+ get createArguments() {
64200
+ return (__classPrivateFieldGet(this, _BlockOperationCREATE_IDENTIFIER_createArguments, "f"));
64201
+ }
63483
64202
  validate(context) {
63484
64203
  const { block, operationIndex } = context;
63485
64204
  if (block.account.isIdentifier()) {
@@ -63493,24 +64212,65 @@ class BlockOperationCREATE_IDENTIFIER extends BlockOperation {
63493
64212
  if (this.identifier.comparePublicKey(validIdentifier) === false) {
63494
64213
  throw (new block_1.default('BLOCK_IDENTIFIER_INVALID', 'Requested token identifier is not valid'));
63495
64214
  }
64215
+ const keyTypesArgumentsRequired = [account_1.AccountKeyAlgorithm.MULTISIG];
64216
+ const shouldHaveCreateArguments = keyTypesArgumentsRequired.includes(this.identifier.keyType);
64217
+ if ((this.createArguments !== undefined) !== shouldHaveCreateArguments) {
64218
+ throw (new block_1.default('BLOCK_INVALID_CREATE_IDENTIFIER_ARGS', `Create arguments set/unset when should not be for key type ${this.identifier.keyType}`));
64219
+ }
64220
+ if (__classPrivateFieldGet(this, _BlockOperationCREATE_IDENTIFIER_createArguments, "f")) {
64221
+ if (!__classPrivateFieldGet(this, _BlockOperationCREATE_IDENTIFIER_identifier, "f").isKeyType(__classPrivateFieldGet(this, _BlockOperationCREATE_IDENTIFIER_createArguments, "f").type)) {
64222
+ throw (new block_1.default('BLOCK_INVALID_CREATE_IDENTIFIER_ARGS', 'Invalid create arguments for key type'));
64223
+ }
64224
+ if (__classPrivateFieldGet(this, _BlockOperationCREATE_IDENTIFIER_createArguments, "f").type === account_1.AccountKeyAlgorithm.MULTISIG) {
64225
+ const { signers, quorum } = __classPrivateFieldGet(this, _BlockOperationCREATE_IDENTIFIER_createArguments, "f");
64226
+ (0, common_1.validateBlockSignerCount)(BigInt(signers.length), block.network);
64227
+ const signerSet = new account_1.default.Set(signers);
64228
+ if (signerSet.size !== signers.length) {
64229
+ throw (new block_1.default('BLOCK_INVALID_MULTISIG_SIGNER_DUPLICATE', `Duplicate signer found`));
64230
+ }
64231
+ if (quorum < 1n || quorum > signerSet.size) {
64232
+ throw (new block_1.default('BLOCK_INVALID_MULTISIG_QUORUM', `Quorum must be between [1, ${signerSet.size}], got ${quorum}`));
64233
+ }
64234
+ }
64235
+ else {
64236
+ throw (new Error('Unrecognized createArguments type'));
64237
+ }
64238
+ }
63496
64239
  }
63497
64240
  toJSON() {
63498
64241
  return ({
63499
64242
  type: this.type,
63500
- identifier: this.identifier
64243
+ identifier: this.identifier,
64244
+ createArguments: __classPrivateFieldGet(this, _BlockOperationCREATE_IDENTIFIER_createArguments, "f")
63501
64245
  });
63502
64246
  }
63503
64247
  }
63504
- _BlockOperationCREATE_IDENTIFIER_identifier = new WeakMap(), _BlockOperationCREATE_IDENTIFIER_instances = new WeakSet(), _BlockOperationCREATE_IDENTIFIER_computeIdentifier = function _BlockOperationCREATE_IDENTIFIER_computeIdentifier(identifierStr) {
64248
+ _BlockOperationCREATE_IDENTIFIER_identifier = new WeakMap(), _BlockOperationCREATE_IDENTIFIER_createArguments = new WeakMap(), _BlockOperationCREATE_IDENTIFIER_instances = new WeakSet(), _BlockOperationCREATE_IDENTIFIER_computeIdentifier = function _BlockOperationCREATE_IDENTIFIER_computeIdentifier(identifierStr) {
63505
64249
  const account = this.computeTo(identifierStr, true);
63506
64250
  if (account.keyType === account_1.AccountKeyAlgorithm.NETWORK) {
63507
64251
  throw (new Error('BlockOperationCREATE_IDENTIFIER must have a non-network identifier account'));
63508
64252
  }
63509
- // XXX:TODO Remove this once multisig account metadata is done
63510
- if (account.keyType === account_1.AccountKeyAlgorithm.MULTISIG) {
63511
- throw (new Error('Multisig accounts currently not supported'));
63512
- }
63513
64253
  return (account);
64254
+ }, _BlockOperationCREATE_IDENTIFIER_computeCreateArguments = function _BlockOperationCREATE_IDENTIFIER_computeCreateArguments(input) {
64255
+ if (input === undefined) {
64256
+ return (undefined);
64257
+ }
64258
+ if (input.type === account_1.AccountKeyAlgorithm.MULTISIG) {
64259
+ return ({
64260
+ type: account_1.AccountKeyAlgorithm.MULTISIG,
64261
+ quorum: BigInt(input.quorum),
64262
+ signers: input.signers.map(function (signerInput) {
64263
+ const signer = account_1.default.toAccount(signerInput);
64264
+ if (!signer.isMultisig() && !signer.isAccount()) {
64265
+ throw (new block_1.default('BLOCK_INVALID_CREATE_IDENTIFIER_ARGS', 'Unsupported key type for multisig signer'));
64266
+ }
64267
+ return (signer);
64268
+ })
64269
+ });
64270
+ }
64271
+ else {
64272
+ throw (new block_1.default('BLOCK_INVALID_CREATE_IDENTIFIER_ARGS', 'Unsupported key type for identifier creation args'));
64273
+ }
63514
64274
  };
63515
64275
  BlockOperationCREATE_IDENTIFIER.isInstance = (0, helper_1.checkableGenerator)(BlockOperationCREATE_IDENTIFIER);
63516
64276
  class BlockOperationSET_INFO extends BlockOperation {
@@ -63767,7 +64527,7 @@ class BlockOperationTOKEN_ADMIN_SUPPLY extends BlockOperation {
63767
64527
  }
63768
64528
  }
63769
64529
  _BlockOperationTOKEN_ADMIN_SUPPLY_amount = new WeakMap(), _BlockOperationTOKEN_ADMIN_SUPPLY_method = new WeakMap(), _BlockOperationTOKEN_ADMIN_SUPPLY_instances = new WeakSet(), _BlockOperationTOKEN_ADMIN_SUPPLY_computeSupplyMethod = function _BlockOperationTOKEN_ADMIN_SUPPLY_computeSupplyMethod(method) {
63770
- const numericMethod = (0, _1.assertAdjustMethod)(method, true);
64530
+ const numericMethod = (0, _1.toAdjustMethod)(method);
63771
64531
  if (numericMethod === _2.default.AdjustMethod.SET) {
63772
64532
  throw (new Error('Cannot use AdjustMethod.SET on a TOKEN_ADMIN_SUPPLY operation'));
63773
64533
  }
@@ -63925,7 +64685,7 @@ _BlockOperationMANAGE_CERTIFICATE_certificateOrHash = new WeakMap(), _BlockOpera
63925
64685
  }
63926
64686
  return (bundleObject);
63927
64687
  }, _BlockOperationMANAGE_CERTIFICATE_computeCertificateMethod = function _BlockOperationMANAGE_CERTIFICATE_computeCertificateMethod(method) {
63928
- const numericMethod = (0, _1.assertAdjustMethod)(method, true);
64688
+ const numericMethod = (0, _1.toAdjustMethod)(method);
63929
64689
  if (numericMethod === _2.default.AdjustMethod.SET) {
63930
64690
  throw (new Error('Cannot use AdjustMethod.SET on a MANAGE_CERTIFICATE operation.'));
63931
64691
  }
@@ -63993,11 +64753,30 @@ function ExportBlockOperations(operations) {
63993
64753
  }
63994
64754
  // We want to be able to read any key on the operation, so we need to cast it to any
63995
64755
  const unTypedEntry = entry;
63996
- for (const { name: key } of operationSchema) {
64756
+ for (const { name: key, schema } of operationSchema) {
63997
64757
  let valueToWrite = unTypedEntry[key];
63998
64758
  if (valueToWrite === undefined) {
64759
+ if (typeof schema === 'object' && schema && !('optional' in schema)) {
64760
+ throw (new Error(`Key ${key} for operation ${typeStr} is not optional but undefined value provided`));
64761
+ }
63999
64762
  continue;
64000
64763
  }
64764
+ else if (typeStr === 'CREATE_IDENTIFIER' && key === 'createArguments') {
64765
+ // We are checking this in other places, and if this argument changes there will be many other things that break beforehand
64766
+ // eslint-disable-next-line @typescript-eslint/consistent-type-assertions
64767
+ const typedValue = valueToWrite;
64768
+ valueToWrite = {
64769
+ type: 'context',
64770
+ kind: 'explicit',
64771
+ value: valueToWrite.type,
64772
+ contains: [
64773
+ typedValue.signers.map(function (signer) {
64774
+ return (signer.publicKeyAndType);
64775
+ }),
64776
+ typedValue.quorum
64777
+ ]
64778
+ };
64779
+ }
64001
64780
  else if (typeof valueToWrite === 'string') {
64002
64781
  valueToWrite = { type: 'string', kind: 'utf8', value: valueToWrite };
64003
64782
  }
@@ -64030,34 +64809,37 @@ function ExportBlockOperations(operations) {
64030
64809
  // eslint-disable-next-line @typescript-eslint/consistent-type-assertions
64031
64810
  return container;
64032
64811
  }
64812
+ function assertExplicitContextValueLike(input) {
64813
+ if (typeof input !== 'object' || input === null) {
64814
+ throw (new Error(`Found entry which is not a context ${String(input)}`));
64815
+ }
64816
+ if (!('type' in input) || input.type !== 'context') {
64817
+ throw (new Error(`Found entry which is not a context ${String(input)}`));
64818
+ }
64819
+ if (!('kind' in input) || input.kind !== 'explicit') {
64820
+ throw (new Error(`Found entry which is not an explicit context ${String(input)}`));
64821
+ }
64822
+ if (!('value' in input)) {
64823
+ throw (new Error(`Found entry which is not a numeric explicit context ${String(input)}`));
64824
+ }
64825
+ const typeInput = input.value;
64826
+ if (typeof typeInput !== 'number') {
64827
+ throw (new Error(`Found entry which is not a numeric explicit context ${String(input)}`));
64828
+ }
64829
+ if (!('contains' in input)) {
64830
+ throw (new Error(`Found entry which which lacks contains ${JSON.stringify(input)}`));
64831
+ }
64832
+ if (!Array.isArray(input.contains)) {
64833
+ throw (new Error(`Found entry which is not a Sequence ${input.contains}`));
64834
+ }
64835
+ }
64033
64836
  function ImportOperationsASN1(input, network) {
64034
64837
  const retval = [];
64035
64838
  for (const entryWrapper of input) {
64036
64839
  const operation = {};
64037
- if (typeof entryWrapper !== 'object' || entryWrapper === null) {
64038
- throw (new Error(`Found entry which is not a context ${String(entryWrapper)}`));
64039
- }
64040
- if (!('type' in entryWrapper) || entryWrapper.type !== 'context') {
64041
- throw (new Error(`Found entry which is not a context ${String(entryWrapper)}`));
64042
- }
64043
- if (!('kind' in entryWrapper) || entryWrapper.kind !== 'explicit') {
64044
- throw (new Error(`Found entry which is not an explicit context ${String(entryWrapper)}`));
64045
- }
64046
- if (!('value' in entryWrapper)) {
64047
- throw (new Error(`Found entry which is not a numeric explicit context ${String(entryWrapper)}`));
64048
- }
64049
- const typeInput = entryWrapper.value;
64050
- if (typeof typeInput !== 'number') {
64051
- throw (new Error(`Found entry which is not a numeric explicit context ${String(entryWrapper)}`));
64052
- }
64053
- const type = assertOperationType(typeInput);
64054
- if (!('contains' in entryWrapper)) {
64055
- throw (new Error(`Found entry which which lacks contains ${JSON.stringify(entryWrapper)}`));
64056
- }
64840
+ assertExplicitContextValueLike(entryWrapper);
64841
+ const type = assertOperationType(entryWrapper.value);
64057
64842
  const entry = entryWrapper.contains;
64058
- if (!Array.isArray(entry)) {
64059
- throw (new Error(`Found entry which is not a Sequence ${entry}`));
64060
- }
64061
64843
  const typeStr = operationTypeToString(type);
64062
64844
  const operationSchema = BlockOperationASN1SchemaBase[typeStr];
64063
64845
  if (!operationSchema) {
@@ -64088,6 +64870,22 @@ function ImportOperationsASN1(input, network) {
64088
64870
  newKeyValue.validate(network);
64089
64871
  keyValueOut = newKeyValue;
64090
64872
  }
64873
+ else if (key === 'createArguments' && typeStr === 'CREATE_IDENTIFIER') {
64874
+ assertExplicitContextValueLike(keyValueIn);
64875
+ if (keyValueIn.value !== account_1.AccountKeyAlgorithm.MULTISIG) {
64876
+ throw (new Error('unrecognized type for multisig create arguments'));
64877
+ }
64878
+ if (keyValueIn.contains.length !== 2 || !Array.isArray(keyValueIn.contains[0])) {
64879
+ throw (new Error('Invalid createArgs container'));
64880
+ }
64881
+ keyValueOut = {
64882
+ type: keyValueIn.value,
64883
+ signers: keyValueIn.contains[0].map(function (value) {
64884
+ return (account_1.default.fromPublicKeyAndType(value));
64885
+ }),
64886
+ quorum: keyValueIn.contains[1]
64887
+ };
64888
+ }
64091
64889
  else if (Array.isArray(keyValueIn) && key === 'intermediateCertificates') {
64092
64890
  keyValueOut = new certificate_1.CertificateBundle(keyValueIn.map(function (certificate) {
64093
64891
  return (new certificate_1.Certificate(certificate));
@@ -64095,7 +64893,7 @@ function ImportOperationsASN1(input, network) {
64095
64893
  }
64096
64894
  else if ((0, helper_1.isBuffer)(keyValueIn)) {
64097
64895
  if (type === OperationType.MANAGE_CERTIFICATE && key === 'certificateOrHash') {
64098
- const method = (0, _1.assertAdjustMethod)(operation['method'], true);
64896
+ const method = (0, _1.toAdjustMethod)(operation['method']);
64099
64897
  if (method === _2.AdjustMethod.SUBTRACT) {
64100
64898
  keyValueOut = new certificate_1.CertificateHash(keyValueIn);
64101
64899
  }
@@ -64187,6 +64985,13 @@ const BlockErrorCodes = [
64187
64985
  'ONLY_IDENTIFIER_OP',
64188
64986
  'NO_TOKEN_OP',
64189
64987
  'NO_IDENTIFIER_OP',
64988
+ 'INVALID_SIGNER',
64989
+ 'INVALID_PURPOSE_VALIDATION',
64990
+ 'INVALID_MULTISIG_QUORUM',
64991
+ 'INVALID_MULTISIG_SIGNER_DEPTH',
64992
+ 'INVALID_MULTISIG_SIGNER_COUNT',
64993
+ 'INVALID_MULTISIG_SIGNER_DUPLICATE',
64994
+ 'INVALID_CREATE_IDENTIFIER_ARGS',
64190
64995
  'NO_MULTISIG_OP',
64191
64996
  'IDENTIFIER_INVALID',
64192
64997
  'GENERAL_FIELD_INVALID',
@@ -64347,7 +65152,16 @@ const LedgerErrorCodes = [
64347
65152
  'BLOCKS_DIFFER_FROM_VOTED_ON',
64348
65153
  'NO_PERM_WITHOUT_SELF_TEMP',
64349
65154
  'DUPLICATE_VOTE_ISSUER_FOUND',
64350
- 'OTHER'
65155
+ 'OTHER',
65156
+ 'MISSING_BLOCKS',
65157
+ // Fee Errors
65158
+ 'FEE_AMOUNT_MISMATCH',
65159
+ 'FEE_TOKEN_MISMATCH',
65160
+ 'FEE_MISSING',
65161
+ 'MISSING_REQUIRED_FEE_BLOCK',
65162
+ 'PERM_VOTE_WITH_QUOTE',
65163
+ 'QUOTE_MISMATCH',
65164
+ 'REQUIRED_FEE_MISMATCH'
64351
65165
  ];
64352
65166
  class KeetaNetLedgerError extends _1.KeetaNetError {
64353
65167
  constructor(code, message, shouldRetry = false, retryDelay) {
@@ -64440,11 +65254,11 @@ const VoteErrorCodes = [
64440
65254
  'MALFORMED_VOTE_VALIDITY_INFORMATION',
64441
65255
  'MALFORMED_VOTE_SERIAL',
64442
65256
  'MALFORMED_VOTE_EXTENSIONS',
65257
+ 'MALFORMED_VOTE_EXTENSIONS_DATA',
64443
65258
  'MALFORMED_VOTE_EXTENSIONS_VALUE',
64444
65259
  'MALFORMED_VOTE_EXTENSIONS_VALUE_OID',
64445
65260
  'MALFORMED_VOTE_EXTENSIONS_VALUE_CRITICAL',
64446
65261
  'MALFORMED_VOTE_EXTENSIONS_VALUE_CRITICAL_TYPE',
64447
- 'MALFORMED_VOTE_EXTENSIONS_VALUE_HASH_DATA',
64448
65262
  'MALFORMED_VOTE_SIGNATURE_SCHEME_DOES_NOT_MATCH_ISSUER',
64449
65263
  'MALFORMED_VOTE_SIGNATURE_SCHEME_DOES_NOT_MATCH_WRAPPER',
64450
65264
  'MALFORMED_VOTE_SIGNATURE_SCHEME_ECDSA_INVALID_CURVE',
@@ -64473,7 +65287,19 @@ const VoteErrorCodes = [
64473
65287
  'MALFORMED_HASHES_FROM_VOTE_DATA_NOT_TWO_ITEMS',
64474
65288
  'MALFORMED_HASHES_FROM_VOTE_DATA_UNSUPPORTED_HASH_FUNC',
64475
65289
  'MALFORMED_HASHES_FROM_VOTE_DATA_UNSUPPORTED_HASH_TYPE',
64476
- 'MALFORMED_HASHES_FROM_VOTE_DATA_SECOND_MUST_BE_SEQUENCE'
65290
+ 'MALFORMED_HASHES_FROM_VOTE_DATA_SECOND_MUST_BE_SEQUENCE',
65291
+ // Errors from the feesFromVote function
65292
+ 'MALFORMED_FEES_AMOUNT',
65293
+ 'MALFORMED_FEES_FROM_VOTE_INVALID_INPUT',
65294
+ 'MALFORMED_FEES_IN_PERMANENT_VOTE',
65295
+ 'MALFORMED_FEES_PAY_TO_INVALID',
65296
+ 'MALFORMED_FEES_TOKEN_NOT_TOKEN',
65297
+ // Fee Quote Errors
65298
+ 'FEE_IS_QUOTE',
65299
+ 'FEE_QUOTE_MISSING_FEES',
65300
+ 'FEE_NOT_QUOTE',
65301
+ 'MALFORMED_FEES_KIND_MISSING',
65302
+ 'MALFORMED_FEES_QUOTE_INVALID'
64477
65303
  ];
64478
65304
  class KeetaNetVoteError extends _1.KeetaNetError {
64479
65305
  constructor(code, message) {
@@ -64829,6 +65655,8 @@ Object.defineProperty(exports, "__esModule", ({ value: true }));
64829
65655
  exports.LedgerStorageBase = void 0;
64830
65656
  exports.findPermissionMatch = findPermissionMatch;
64831
65657
  exports.validateSupply = validateSupply;
65658
+ exports.validateBlockSignerCount = validateBlockSignerCount;
65659
+ exports.validateBlockSignerDepth = validateBlockSignerDepth;
64832
65660
  exports.computeLedgerEffect = computeLedgerEffect;
64833
65661
  exports.addTimeStatistic = addTimeStatistic;
64834
65662
  exports.assertLedgerStorage = assertLedgerStorage;
@@ -64836,6 +65664,7 @@ const account_1 = __importStar(__webpack_require__(9415));
64836
65664
  const block_1 = __webpack_require__(6158);
64837
65665
  const permissions_1 = __webpack_require__(5860);
64838
65666
  const ledger_1 = __importDefault(__webpack_require__(452));
65667
+ const helper_1 = __webpack_require__(3208);
64839
65668
  const config_1 = __webpack_require__(1491);
64840
65669
  const block_2 = __importDefault(__webpack_require__(7412));
64841
65670
  function findPermissionMatch(lookingFor, entries) {
@@ -64867,6 +65696,18 @@ function validateSupply(amount, network) {
64867
65696
  throw (new block_2.default('BLOCK_SUPPLY_INVALID', `supply does not fit proper format -- GOT: '${amount}' MaxValue: ${maxValue}`));
64868
65697
  }
64869
65698
  }
65699
+ function validateBlockSignerCount(amount, network) {
65700
+ const { maxValue } = (0, config_1.getValidation)(network).accountInfoFieldRules['blockSignerCount'];
65701
+ if (amount > maxValue || amount < 1n) {
65702
+ throw (new block_2.default('BLOCK_INVALID_MULTISIG_SIGNER_COUNT', `signer count does not fit proper format -- GOT: '${amount}' MaxValue: ${maxValue}`));
65703
+ }
65704
+ }
65705
+ function validateBlockSignerDepth(depth, network) {
65706
+ const { maxValue } = (0, config_1.getValidation)(network).accountInfoFieldRules['blockSignerDepth'];
65707
+ if (depth > maxValue) {
65708
+ throw (new block_2.default('BLOCK_INVALID_MULTISIG_SIGNER_DEPTH', `signer depth does not fit proper format -- GOT: '${depth}' MaxValue: ${maxValue}`));
65709
+ }
65710
+ }
64870
65711
  /**
64871
65712
  * Compute effects on the ledger from block effects
64872
65713
  */
@@ -65329,18 +66170,24 @@ class LedgerStorageBase {
65329
66170
  }
65330
66171
  ret.defaultPermission = new permissions_1.Permissions(baseSet, externalSet);
65331
66172
  }
65332
- if (account.keyType === account_1.AccountKeyAlgorithm.TOKEN) {
66173
+ if (account.isToken()) {
65333
66174
  ret.supply = BigInt(row.supply ?? 0);
65334
66175
  }
66176
+ if (account.isMultisig() && row.multisigQuorum !== undefined) {
66177
+ ret.multisigQuorum = BigInt(row.multisigQuorum);
66178
+ }
65335
66179
  return (ret);
65336
66180
  }
65337
66181
  _validateAccountInfoKeys(account, info) {
65338
66182
  const validKeys = ['name', 'description', 'metadata'];
65339
66183
  if (account.isIdentifier()) {
65340
66184
  validKeys.push('defaultPermission');
65341
- }
65342
- if (account.keyType === account_1.AccountKeyAlgorithm.TOKEN) {
65343
- validKeys.push('supply');
66185
+ if (account.isToken()) {
66186
+ validKeys.push('supply');
66187
+ }
66188
+ if (account.isMultisig()) {
66189
+ validKeys.push('multisigQuorum');
66190
+ }
65344
66191
  }
65345
66192
  const keys = Object.keys(info);
65346
66193
  const foundBannedKey = keys.find(function (key) {
@@ -65350,6 +66197,33 @@ class LedgerStorageBase {
65350
66197
  throw (new ledger_1.default('LEDGER_INVALID_ACCOUNT_INFO_KEY', `Invalid AccountInfo field ${foundBannedKey}`));
65351
66198
  }
65352
66199
  }
66200
+ /**
66201
+ * @param moment - The date to use as the base for the timestamp.
66202
+ * @param momentBits - The number of bits to use for the timestamp
66203
+ * @param totalLength - The total length of the generated number in bits
66204
+ * @param randomData - A hexadecimal string to use as the random data.
66205
+ * @param timestampFuzzMS - The number of milliseconds to fuzz the timestamp by, defaults to 1n (precise).
66206
+ * @param optimistic - If true, the timestamp will be incremented by 1 quanta, defaults to false.
66207
+ * @returns A bigint representing the noisy timestamp.
66208
+ */
66209
+ _generateNoisyTimestamp(moment, momentBits, totalLength, randomData, timestampFuzzMS = 1, optimistic = false) {
66210
+ if (timestampFuzzMS > Number.MAX_SAFE_INTEGER) {
66211
+ throw (new Error('timestampFuzzMs is too large'));
66212
+ }
66213
+ const timestampFuzz = BigInt(Math.ceil(Math.log2(Number(timestampFuzzMS))));
66214
+ const length = totalLength - momentBits;
66215
+ if (BigInt(randomData.length * 8) < (length + timestampFuzz)) {
66216
+ throw (new Error('randomData is too short for the specified bit length'));
66217
+ }
66218
+ if (length < 0n) {
66219
+ throw (new Error('momentBits should be less than totalLength'));
66220
+ }
66221
+ const timestamp = BigInt(moment.valueOf()) >> timestampFuzz;
66222
+ const mask = (1n << (length + timestampFuzz)) - 1n;
66223
+ const upperBits = (timestamp + (optimistic ? 1n : 0n)) << (length + timestampFuzz);
66224
+ const lowerBits = (0, helper_1.bufferToBigInt)(randomData) & mask;
66225
+ return (upperBits | lowerBits);
66226
+ }
65353
66227
  async getHeadBlock(transaction, account, from) {
65354
66228
  const response = await this.getHeadBlocks(transaction, [account], from);
65355
66229
  const pubKey = account.publicKeyString.get();
@@ -65366,9 +66240,9 @@ class LedgerStorageBase {
65366
66240
  }
65367
66241
  return (null);
65368
66242
  }
65369
- async gc(transaction) {
66243
+ async gc(transaction, timeLimitMS = 280000) {
65370
66244
  let lastGCResult = false;
65371
- for (const startTime = Date.now(); Date.now() - startTime < 280000;) {
66245
+ for (const startTime = Date.now(); Date.now() - startTime < timeLimitMS;) {
65372
66246
  const gcResult = await this.gcBatch(transaction);
65373
66247
  lastGCResult = gcResult;
65374
66248
  if (!gcResult) {
@@ -65428,8 +66302,38 @@ Object.defineProperty(exports, "__esModule", ({ value: true }));
65428
66302
  exports.computeEffectOfBlocks = computeEffectOfBlocks;
65429
66303
  const account_1 = __importStar(__webpack_require__(9415));
65430
66304
  const block_1 = __webpack_require__(6158);
66305
+ const operations_1 = __webpack_require__(2778);
65431
66306
  const permissions_1 = __webpack_require__(5860);
65432
66307
  const certificate_1 = __webpack_require__(5661);
66308
+ ;
66309
+ /**
66310
+ * Base Fee Units per Block
66311
+ */
66312
+ const baseBlockFeeUnit = 1000n;
66313
+ /**
66314
+ * Fee Unit for an Opening Block
66315
+ */
66316
+ const openingBlockFeeUnit = 10000n;
66317
+ /**
66318
+ * Operation specific Fee Units
66319
+ */
66320
+ const operationFeeUnitOverrides = {
66321
+ [operations_1.OperationType.SEND]: 10n,
66322
+ [operations_1.OperationType.SET_REP]: 20n,
66323
+ [operations_1.OperationType.SET_INFO]: 100n,
66324
+ [operations_1.OperationType.MODIFY_PERMISSIONS]: 20n,
66325
+ [operations_1.OperationType.CREATE_IDENTIFIER]: 200n,
66326
+ [operations_1.OperationType.TOKEN_ADMIN_SUPPLY]: 10n,
66327
+ [operations_1.OperationType.TOKEN_ADMIN_MODIFY_BALANCE]: 10n,
66328
+ [operations_1.OperationType.RECEIVE]: 10n,
66329
+ [operations_1.OperationType.MANAGE_CERTIFICATE]: 100n
66330
+ };
66331
+ /**
66332
+ * Get the Fee Unit for a given operation type
66333
+ */
66334
+ function getOperationFeeUnit(operation) {
66335
+ return (operationFeeUnitOverrides[operation]);
66336
+ }
65433
66337
  function addOrCombineRequirements(existing, addition, alwaysCombine) {
65434
66338
  const resp = [...existing];
65435
66339
  let additionTarget;
@@ -65532,6 +66436,19 @@ function addPermissionRequirement(state, requirement) {
65532
66436
  const existing = state.accounts[principalPubKey].fields.permissionRequirements ?? [];
65533
66437
  state.accounts[principalPubKey].fields.permissionRequirements = addOrCombineRequirements(existing, requirement, true);
65534
66438
  }
66439
+ function updateMinSignerSetLength(state, multisigAccount, count) {
66440
+ const multisigPublicKey = multisigAccount.publicKeyString.get();
66441
+ if (state.accounts[multisigPublicKey] === undefined) {
66442
+ state.accounts[multisigPublicKey] = {
66443
+ account: multisigAccount,
66444
+ fields: {}
66445
+ };
66446
+ }
66447
+ const current = state.accounts[multisigPublicKey].fields.minSignerSetLength;
66448
+ if (current === undefined || current > count) {
66449
+ state.accounts[multisigPublicKey].fields.minSignerSetLength = count;
66450
+ }
66451
+ }
65535
66452
  function modifyBalanceInState(balanceState) {
65536
66453
  const { state, account, token, method, amount, otherAccount } = balanceState;
65537
66454
  const accountPubKey = account.publicKeyString.get();
@@ -65576,6 +66493,32 @@ function modifyBalanceInState(balanceState) {
65576
66493
  }
65577
66494
  accountBalanceInfo[tokenPubKey] = tokenField;
65578
66495
  }
66496
+ function updateAccountInfoInState(state, account, info) {
66497
+ const accountPubKey = account.publicKeyString.get();
66498
+ const toUpdate = {
66499
+ name: info.name,
66500
+ description: info.description,
66501
+ metadata: info.metadata
66502
+ };
66503
+ if (account.isIdentifier()) {
66504
+ if (info.defaultPermission !== undefined) {
66505
+ toUpdate.defaultPermission = info.defaultPermission;
66506
+ }
66507
+ if (account.isMultisig() && info.multisigQuorum !== undefined) {
66508
+ toUpdate.multisigQuorum = info.multisigQuorum;
66509
+ }
66510
+ }
66511
+ else {
66512
+ state.possibleNewAccounts.add(account);
66513
+ }
66514
+ if (!state.accounts[accountPubKey]) {
66515
+ state.accounts[accountPubKey] = {
66516
+ account: account,
66517
+ fields: {}
66518
+ };
66519
+ }
66520
+ state.accounts[accountPubKey].fields.info = toUpdate;
66521
+ }
65579
66522
  /**
65580
66523
  * Compute the effect of a SEND operation
65581
66524
  */
@@ -65703,34 +66646,39 @@ function computeEffectOfOperationCREATE_IDENTIFIER(state, block, operation, cont
65703
66646
  }
65704
66647
  state.possibleNewAccounts.add(operation.identifier);
65705
66648
  state.accounts[accountPubKey].fields.createRequests?.push({
65706
- previousBlockHash: block.previous,
65707
- account: block.account,
65708
- requestedIdentifier: operation.identifier,
65709
- operationIndex: context.operationIndex
65710
- });
65711
- addPermission(state, {
65712
- principal: block.account,
65713
- entity: operation.identifier,
65714
- method: block_1.Block.AdjustMethod.SET,
65715
- permissions: new permissions_1.Permissions(['OWNER'])
66649
+ createdIdentifier: operation.identifier,
66650
+ createArguments: operation.createArguments
65716
66651
  });
65717
- }
65718
- function computeEffectOfOperationSET_INFO(state, block, operation) {
65719
- const accountPubKey = block.account.publicKeyString.get();
65720
- const toUpdate = {
65721
- name: operation.name,
65722
- description: operation.description,
65723
- metadata: operation.metadata
65724
- };
65725
- if (block.account.isIdentifier()) {
65726
- if (operation.defaultPermission !== undefined) {
65727
- toUpdate.defaultPermission = operation.defaultPermission;
66652
+ if (operation.identifier.isMultisig()) {
66653
+ if (!operation.createArguments || operation.createArguments.type !== account_1.AccountKeyAlgorithm.MULTISIG) {
66654
+ throw (new Error('Invalid identifier creation arguments'));
66655
+ }
66656
+ updateAccountInfoInState(state, operation.identifier, { multisigQuorum: operation.createArguments.quorum });
66657
+ for (const multisigSigner of operation.createArguments.signers) {
66658
+ addPermission(state, {
66659
+ principal: multisigSigner,
66660
+ entity: operation.identifier,
66661
+ method: block_1.Block.AdjustMethod.SET,
66662
+ permissions: new permissions_1.Permissions(['MULTISIG_SIGNER'])
66663
+ });
65728
66664
  }
65729
66665
  }
65730
66666
  else {
65731
- state.possibleNewAccounts.add(block.account);
66667
+ addPermission(state, {
66668
+ principal: block.account,
66669
+ entity: operation.identifier,
66670
+ method: block_1.Block.AdjustMethod.SET,
66671
+ permissions: new permissions_1.Permissions(['OWNER'])
66672
+ });
65732
66673
  }
65733
- state.accounts[accountPubKey].fields.info = toUpdate;
66674
+ }
66675
+ function computeEffectOfOperationSET_INFO(state, block, operation) {
66676
+ updateAccountInfoInState(state, block.account, {
66677
+ name: operation.name,
66678
+ description: operation.description,
66679
+ metadata: operation.metadata,
66680
+ defaultPermission: operation.defaultPermission
66681
+ });
65734
66682
  }
65735
66683
  function computeEffectOfOperationMODIFY_PERMISSIONS(state, block, operation) {
65736
66684
  state.possibleNewAccounts.add(operation.principal);
@@ -65971,7 +66919,7 @@ function computePermissionEffect(state, type, effect, block, operation, context)
65971
66919
  };
65972
66920
  switch (type) {
65973
66921
  case 'SIGNER':
65974
- baseRequirement.principal = block.signer;
66922
+ baseRequirement.principal = block.principal;
65975
66923
  baseRequirement.entity = block.account;
65976
66924
  break;
65977
66925
  case 'ACCOUNT':
@@ -66027,7 +66975,8 @@ function computeEffectOfBlocks(blocks, ledger) {
66027
66975
  possibleNewAccounts: new account_1.default.Set(),
66028
66976
  metadata: {
66029
66977
  blockCount: 0,
66030
- operationCount: 0
66978
+ operationCount: 0,
66979
+ feeUnits: 0n
66031
66980
  }
66032
66981
  };
66033
66982
  let onlyReturnTouched = false;
@@ -66042,13 +66991,26 @@ function computeEffectOfBlocks(blocks, ledger) {
66042
66991
  */
66043
66992
  for (const block of blocks) {
66044
66993
  accumulatedEffects.metadata.blockCount++;
66994
+ accumulatedEffects.metadata.feeUnits += baseBlockFeeUnit;
66045
66995
  const blockAccountPubKey = block.account.publicKeyString.get();
66046
- accumulatedEffects.touched.add(block.signer);
66996
+ const signerQueue = [block.signer];
66997
+ while (signerQueue.length > 0) {
66998
+ // We can assume that the signerFieldQueue is not empty here since the loop condition checks it
66999
+ // eslint-disable-next-line @typescript-eslint/no-non-null-assertion
67000
+ const signer = signerQueue.shift();
67001
+ if (account_1.default.isInstance(signer)) {
67002
+ accumulatedEffects.touched.add(signer);
67003
+ continue;
67004
+ }
67005
+ accumulatedEffects.touched.add(signer[0]);
67006
+ signerQueue.push(...signer[1]);
67007
+ }
66047
67008
  if (block.$opening) {
66048
67009
  accumulatedEffects.possibleNewAccounts.add(block.account);
67010
+ accumulatedEffects.metadata.feeUnits += openingBlockFeeUnit;
66049
67011
  }
66050
- if (!(block.signer.comparePublicKey(block.account))) {
66051
- accumulatedEffects.possibleNewAccounts.add(block.signer);
67012
+ if (!(block.principal.comparePublicKey(block.account))) {
67013
+ accumulatedEffects.possibleNewAccounts.add(block.principal);
66052
67014
  }
66053
67015
  if (accumulatedEffects.accounts[blockAccountPubKey] === undefined) {
66054
67016
  accumulatedEffects.accounts[blockAccountPubKey] = {
@@ -66063,12 +67025,13 @@ function computeEffectOfBlocks(blocks, ledger) {
66063
67025
  const context = {
66064
67026
  ledger,
66065
67027
  operationIndex: Number(operationIndex),
66066
- signedByDifferent: !block.account.comparePublicKey(block.signer),
67028
+ signedByDifferent: !block.account.comparePublicKey(block.principal),
66067
67029
  openingBlock: block.$opening
66068
67030
  };
66069
67031
  const operation = block.operations[operationIndex];
66070
67032
  const handler = operationHandlers[operation.type];
66071
67033
  accumulatedEffects.metadata.operationCount++;
67034
+ accumulatedEffects.metadata.feeUnits += getOperationFeeUnit(operation.type);
66072
67035
  if (handler.accountPermissionACL) {
66073
67036
  computePermissionEffect(accumulatedEffects, 'ACCOUNT', handler.accountPermissionACL, block, operation, context);
66074
67037
  }
@@ -66078,6 +67041,30 @@ function computeEffectOfBlocks(blocks, ledger) {
66078
67041
  permissionEffect = handler.signerPermissionACL;
66079
67042
  }
66080
67043
  computePermissionEffect(accumulatedEffects, 'SIGNER', permissionEffect, block, operation, context);
67044
+ if (Array.isArray(block.signer)) {
67045
+ const signerFieldQueue = [block.signer];
67046
+ while (signerFieldQueue.length > 0) {
67047
+ // We can assume that the signerFieldQueue is not empty here since the loop condition checks it
67048
+ // eslint-disable-next-line @typescript-eslint/no-non-null-assertion
67049
+ const [multisig, signers] = signerFieldQueue.shift();
67050
+ updateMinSignerSetLength(accumulatedEffects, multisig, BigInt(signers.length));
67051
+ for (const signer of signers) {
67052
+ let principal;
67053
+ if (account_1.default.isInstance(signer)) {
67054
+ principal = signer;
67055
+ }
67056
+ else {
67057
+ principal = signer[0];
67058
+ signerFieldQueue.push(signer);
67059
+ }
67060
+ addPermissionRequirement(accumulatedEffects, {
67061
+ entity: multisig,
67062
+ principal: principal,
67063
+ permissions: new permissions_1.Permissions(['MULTISIG_SIGNER'])
67064
+ });
67065
+ }
67066
+ }
67067
+ }
66081
67068
  }
66082
67069
  handler.effectGenerator(accumulatedEffects, block, operation, context);
66083
67070
  }
@@ -66191,7 +67178,7 @@ var __classPrivateFieldGet = (this && this.__classPrivateFieldGet) || function (
66191
67178
  var __importDefault = (this && this.__importDefault) || function (mod) {
66192
67179
  return (mod && mod.__esModule) ? mod : { "default": mod };
66193
67180
  };
66194
- var _LedgerAtomicInterface_instances, _LedgerAtomicInterface_network, _LedgerAtomicInterface_subnet, _LedgerAtomicInterface_kind, _LedgerAtomicInterface_privateKey, _LedgerAtomicInterface_storage, _LedgerAtomicInterface_transaction, _LedgerAtomicInterface_ledger, _LedgerAtomicInterface_cache, _LedgerAtomicInterface_assertTransaction, _LedgerAtomicInterface_validateVotingWeight, _LedgerAtomicInterface_listAccountInfo, _LedgerAtomicInterface_checkSingleAccountPermissions, _LedgerAtomicInterface_checkPermissionRequirements, _LedgerAtomicInterface_validateLedgerOutcome, _Ledger_storage, _Ledger_config;
67181
+ var _LedgerAtomicInterface_instances, _LedgerAtomicInterface_network, _LedgerAtomicInterface_subnet, _LedgerAtomicInterface_kind, _LedgerAtomicInterface_privateKey, _LedgerAtomicInterface_computeFeeFromBlocks, _LedgerAtomicInterface_storage, _LedgerAtomicInterface_ledger, _LedgerAtomicInterface_cache, _LedgerAtomicInterface_transaction, _LedgerAtomicInterface_assertTransaction, _LedgerAtomicInterface_validateVotingWeight, _LedgerAtomicInterface_listAccountInfo, _LedgerAtomicInterface_checkSingleAccountPermissions, _LedgerAtomicInterface_checkPermissionRequirements, _LedgerAtomicInterface_validateLedgerOutcome, _LedgerAtomicInterface_validateBlocksForVote, _LedgerAtomicInterface_voteOrQuoteWithFees, _Ledger_storage, _Ledger_config;
66195
67182
  Object.defineProperty(exports, "__esModule", ({ value: true }));
66196
67183
  exports.Ledger = exports.LedgerKind = void 0;
66197
67184
  const vote_1 = __webpack_require__(1130);
@@ -66205,6 +67192,7 @@ const effects_1 = __webpack_require__(7346);
66205
67192
  const conversion_1 = __webpack_require__(2360);
66206
67193
  const cache_1 = __importDefault(__webpack_require__(5834));
66207
67194
  const timing_1 = __webpack_require__(2895);
67195
+ const operations_1 = __webpack_require__(2778);
66208
67196
  /**
66209
67197
  * Kind of ledger
66210
67198
  */
@@ -66223,14 +67211,16 @@ class LedgerAtomicInterface {
66223
67211
  _LedgerAtomicInterface_subnet.set(this, void 0);
66224
67212
  _LedgerAtomicInterface_kind.set(this, void 0);
66225
67213
  _LedgerAtomicInterface_privateKey.set(this, void 0);
67214
+ _LedgerAtomicInterface_computeFeeFromBlocks.set(this, void 0);
66226
67215
  _LedgerAtomicInterface_storage.set(this, void 0);
66227
- _LedgerAtomicInterface_transaction.set(this, void 0);
66228
67216
  _LedgerAtomicInterface_ledger.set(this, void 0);
66229
67217
  _LedgerAtomicInterface_cache.set(this, void 0);
67218
+ _LedgerAtomicInterface_transaction.set(this, void 0);
66230
67219
  __classPrivateFieldSet(this, _LedgerAtomicInterface_network, config.network, "f");
66231
67220
  __classPrivateFieldSet(this, _LedgerAtomicInterface_subnet, config.subnet, "f");
66232
67221
  __classPrivateFieldSet(this, _LedgerAtomicInterface_kind, config.kind, "f");
66233
67222
  __classPrivateFieldSet(this, _LedgerAtomicInterface_privateKey, config.privateKey, "f");
67223
+ __classPrivateFieldSet(this, _LedgerAtomicInterface_computeFeeFromBlocks, config.computeFeeFromBlocks, "f");
66234
67224
  __classPrivateFieldSet(this, _LedgerAtomicInterface_ledger, ledger, "f");
66235
67225
  __classPrivateFieldSet(this, _LedgerAtomicInterface_storage, storage, "f");
66236
67226
  __classPrivateFieldSet(this, _LedgerAtomicInterface_transaction, transaction, "f");
@@ -66258,16 +67248,27 @@ class LedgerAtomicInterface {
66258
67248
  __classPrivateFieldSet(this, _LedgerAtomicInterface_transaction, null, "f");
66259
67249
  await __classPrivateFieldGet(this, _LedgerAtomicInterface_storage, "f").abortTransaction(transaction);
66260
67250
  }
66261
- async vote(blocks, otherVotes) {
66262
- const transaction = __classPrivateFieldGet(this, _LedgerAtomicInterface_instances, "m", _LedgerAtomicInterface_assertTransaction).call(this);
66263
- if (__classPrivateFieldGet(this, _LedgerAtomicInterface_ledger, "f").ledgerWriteMode !== 'read-write') {
66264
- throw (new Error(`May not issue votes in read-only mode, in ${__classPrivateFieldGet(this, _LedgerAtomicInterface_ledger, "f").ledgerWriteMode} mode`));
67251
+ async vote(blocks, otherVotes, quote) {
67252
+ if (blocks.length === 0) {
67253
+ throw (new ledger_1.default('LEDGER_MISSING_BLOCKS', 'At least one block is required to issue a vote'));
66265
67254
  }
66266
67255
  if (!__classPrivateFieldGet(this, _LedgerAtomicInterface_privateKey, "f")) {
66267
67256
  throw (new Error('Cannot vote on block, no private key loaded'));
66268
67257
  }
67258
+ if (__classPrivateFieldGet(this, _LedgerAtomicInterface_ledger, "f").ledgerWriteMode !== 'read-write') {
67259
+ throw (new Error(`May not issue votes in read-only mode, in ${__classPrivateFieldGet(this, _LedgerAtomicInterface_ledger, "f").ledgerWriteMode} mode`));
67260
+ }
66269
67261
  const privateKey = __classPrivateFieldGet(this, _LedgerAtomicInterface_privateKey, "f");
66270
67262
  const ledgerPubKey = privateKey.publicKeyString.get();
67263
+ if (quote !== undefined) {
67264
+ if (otherVotes !== undefined) {
67265
+ throw (new ledger_1.default('LEDGER_PERM_VOTE_WITH_QUOTE', 'Quote should not be included when requesting permanent votes'));
67266
+ }
67267
+ if (!quote.issuer.comparePublicKey(ledgerPubKey)) {
67268
+ throw (new ledger_1.default('LEDGER_QUOTE_MISMATCH', 'Provided quote does not match issuer public key'));
67269
+ }
67270
+ }
67271
+ const transaction = __classPrivateFieldGet(this, _LedgerAtomicInterface_instances, "m", _LedgerAtomicInterface_assertTransaction).call(this);
66271
67272
  /**
66272
67273
  * If there are other votes, ensure one of them was issued by
66273
67274
  * us and the blocks are in the same order as the set of
@@ -66277,7 +67278,18 @@ class LedgerAtomicInterface {
66277
67278
  let foundOurVote = false;
66278
67279
  const seenVoteUIDs = new Set();
66279
67280
  const seenVoteIssuers = new account_1.default.Set();
67281
+ const possibleFeeBlock = blocks.at(-1);
67282
+ let hasFeeBlock = false;
67283
+ let blockCount = blocks.length;
67284
+ if (possibleFeeBlock?.purpose === block_1.BlockPurpose.FEE) {
67285
+ hasFeeBlock = true;
67286
+ blockCount--;
67287
+ }
67288
+ const requiredFees = new Map();
66280
67289
  for (const checkVote of otherVotes) {
67290
+ if (checkVote.quote === true) {
67291
+ throw (new ledger_1.default('LEDGER_PERM_VOTE_WITH_QUOTE', 'Cannot request permanent votes with quotes'));
67292
+ }
66281
67293
  if (seenVoteUIDs.has(checkVote.$id)) {
66282
67294
  throw (new ledger_1.default('LEDGER_DUPLICATE_VOTE_FOUND', 'Duplicate vote UID found'));
66283
67295
  }
@@ -66286,13 +67298,16 @@ class LedgerAtomicInterface {
66286
67298
  }
66287
67299
  seenVoteIssuers.add(checkVote.issuer);
66288
67300
  seenVoteUIDs.add(checkVote.$id);
67301
+ if (checkVote.fee !== undefined) {
67302
+ requiredFees.set(checkVote.issuer, checkVote.fee);
67303
+ }
66289
67304
  if (checkVote.$permanent) {
66290
67305
  throw (new ledger_1.default('LEDGER_CANNOT_EXCHANGE_PERM_VOTE', 'Asked to exchange a permanent vote for a permanent vote'));
66291
67306
  }
66292
- let blocksDifferFromVoteBlocks = checkVote.blocks.length !== blocks.length;
67307
+ let blocksDifferFromVoteBlocks = checkVote.blocks.length !== blockCount;
66293
67308
  /* If they do not differ from length alone, compare block hashes */
66294
67309
  if (!blocksDifferFromVoteBlocks) {
66295
- for (let blockIndex = 0; blockIndex < blocks.length; blockIndex++) {
67310
+ for (let blockIndex = 0; blockIndex < blockCount; blockIndex++) {
66296
67311
  if (!blocks[blockIndex].hash.compareHexString(checkVote.blocks[blockIndex])) {
66297
67312
  blocksDifferFromVoteBlocks = true;
66298
67313
  break;
@@ -66306,69 +67321,43 @@ class LedgerAtomicInterface {
66306
67321
  foundOurVote = true;
66307
67322
  }
66308
67323
  }
66309
- if (!foundOurVote) {
66310
- throw (new ledger_1.default('LEDGER_NO_PERM_WITHOUT_SELF_TEMP', 'Asked to give a permanent vote without a temporary vote from us'));
66311
- }
66312
- }
66313
- /**
66314
- * Create a map of all blocks by their hash
66315
- */
66316
- const blockHashMap = {};
66317
- for (const block of blocks) {
66318
- blockHashMap[block.hash.toString()] = block;
66319
- }
66320
- const seenBlockHashes = new block_1.BlockHash.Set();
66321
- const usedPreviousBlockHashes = new block_1.BlockHash.Set();
66322
- const blocksToCheckOurVotesFor = [];
66323
- const needToGetHeadFor = new account_1.default.Set();
66324
- const expectedHead = {};
66325
- for (const block of blocks) {
66326
- const prevBlockHash = block.previous;
66327
- seenBlockHashes.add(block.hash);
66328
- if (block.network !== __classPrivateFieldGet(this, _LedgerAtomicInterface_network, "f")) {
66329
- throw (new ledger_1.default('LEDGER_INVALID_NETWORK', 'Cannot vote on block for a different network'));
66330
- }
66331
- if (block.subnet !== __classPrivateFieldGet(this, _LedgerAtomicInterface_subnet, "f")) {
66332
- throw (new ledger_1.default('LEDGER_INVALID_SUBNET', 'Cannot vote on block for a different subnet'));
66333
- }
66334
- if (usedPreviousBlockHashes.has(prevBlockHash)) {
66335
- throw (new ledger_1.default('LEDGER_PREVIOUS_ALREADY_USED', `Invalid reference to block, previous: ${prevBlockHash} has already been used`));
67324
+ if (requiredFees.size > 0) {
67325
+ if (!hasFeeBlock) {
67326
+ throw (new ledger_1.default('LEDGER_MISSING_REQUIRED_FEE_BLOCK', 'Missing fee block but votes require it'));
67327
+ }
67328
+ if (requiredFees.size !== possibleFeeBlock?.operations.length) {
67329
+ throw (new ledger_1.default('LEDGER_REQUIRED_FEE_MISMATCH', 'Fee Block Operations do not match required fees'));
67330
+ }
66336
67331
  }
66337
- usedPreviousBlockHashes.add(prevBlockHash);
66338
- /**
66339
- * Only allow this vote if it is the successor the current
66340
- * HEAD block for the account, or if no blocks exist on the
66341
- * account and its an opening block, or if the predecessor
66342
- * block is also being voted on
66343
- */
66344
- let predecessorBeingVotedOn = false;
66345
- if (!block.$opening) {
66346
- const prevBlock = blockHashMap[prevBlockHash.toString()];
66347
- if (prevBlock !== undefined) {
66348
- predecessorBeingVotedOn = true;
66349
- if (!(prevBlock.account.comparePublicKey(block.account))) {
66350
- throw (new ledger_1.default('LEDGER_INVALID_CHAIN', 'Invalid chain, changes accounts'));
66351
- }
66352
- if (!seenBlockHashes.has(prevBlockHash)) {
66353
- throw (new ledger_1.default('LEDGER_PREVIOUS_NOT_SEEN', `Invalid reference to block, out-of-order: ${prevBlockHash} has not already been seen`));
67332
+ // Verify that all required fees have been included in the fee block
67333
+ for (const [issuer, fee] of requiredFees) {
67334
+ const foundFee = possibleFeeBlock?.operations.find((operation) => {
67335
+ const expectedPayTo = fee.payTo ?? issuer;
67336
+ const expectedToken = fee.token ?? __classPrivateFieldGet(this, _LedgerAtomicInterface_ledger, "f").baseToken;
67337
+ if (operation.type === operations_1.OperationType.SEND && operation.to.comparePublicKey(expectedPayTo)) {
67338
+ if (operation.amount !== fee.amount) {
67339
+ throw (new ledger_1.default('LEDGER_FEE_AMOUNT_MISMATCH', `Fee Amount Mismatch, found: ${operation.amount} expected: ${fee.amount}`));
67340
+ }
67341
+ if (!operation.token.comparePublicKey(expectedToken)) {
67342
+ throw (new ledger_1.default('LEDGER_FEE_TOKEN_MISMATCH', `Fee Token Mismatch, found: ${operation.token.publicKeyString.get()} expected: ${expectedToken.publicKeyString.get()}`));
67343
+ }
67344
+ return (true);
66354
67345
  }
67346
+ return (false);
67347
+ });
67348
+ if (foundFee === undefined) {
67349
+ throw (new ledger_1.default('LEDGER_FEE_MISSING', `Missing Required Fee for ${fee.payTo?.publicKeyString.get() ?? issuer.publicKeyString.get()}`));
66355
67350
  }
66356
67351
  }
66357
- if (!predecessorBeingVotedOn) {
66358
- const pubKey = block.account.publicKeyString.get();
66359
- needToGetHeadFor.add(block.account);
66360
- expectedHead[pubKey] = block;
67352
+ if (!foundOurVote) {
67353
+ throw (new ledger_1.default('LEDGER_NO_PERM_WITHOUT_SELF_TEMP', 'Asked to give a permanent vote without a temporary vote from us'));
66361
67354
  }
66362
- /**
66363
- * Ensure we have no active vote for another conflicting successor of this block's parent (previous),
66364
- * which could cause a fork
66365
- */
66366
- blocksToCheckOurVotesFor.push(block);
66367
67355
  }
67356
+ const allLedgerHeads = await __classPrivateFieldGet(this, _LedgerAtomicInterface_instances, "m", _LedgerAtomicInterface_validateBlocksForVote).call(this, blocks);
67357
+ const needToGetHeadFor = new account_1.default.Set(allLedgerHeads.keys());
66368
67358
  const allHeads = await __classPrivateFieldGet(this, _LedgerAtomicInterface_storage, "f").getHeadBlockHashes(transaction, needToGetHeadFor);
66369
- for (const pubKey in expectedHead) {
66370
- const expectedBlock = expectedHead[pubKey];
66371
- const accountHead = allHeads[pubKey];
67359
+ for (const [account, expectedBlock] of allLedgerHeads.entries()) {
67360
+ const accountHead = allHeads[account.publicKeyString.get()];
66372
67361
  if (accountHead === null) {
66373
67362
  if (!expectedBlock.$opening) {
66374
67363
  throw (new ledger_1.default('LEDGER_NOT_OPENING', 'Cannot vote on non-opening block for an empty account'));
@@ -66382,9 +67371,13 @@ class LedgerAtomicInterface {
66382
67371
  throw (new ledger_1.default('LEDGER_NOT_SUCCESSOR', 'The block is not the successor to the account head block'));
66383
67372
  }
66384
67373
  }
66385
- const previousToCheckFor = blocksToCheckOurVotesFor.map(b => b.previous);
67374
+ /**
67375
+ * Ensure we have no active vote for another conflicting successor of this block's parent (previous),
67376
+ * which could cause a fork
67377
+ */
67378
+ const previousToCheckFor = blocks.map(b => b.previous);
66386
67379
  const allPrevious = await __classPrivateFieldGet(this, _LedgerAtomicInterface_storage, "f").getVotesFromMultiplePrevious(transaction, previousToCheckFor, 'both', account_1.default.toAccount(ledgerPubKey));
66387
- for (const block of blocksToCheckOurVotesFor) {
67380
+ for (const block of blocks) {
66388
67381
  const previousVotes = allPrevious[block.previous.toString()];
66389
67382
  if (previousVotes !== null && previousVotes.length > 0) {
66390
67383
  /**
@@ -66407,32 +67400,7 @@ class LedgerAtomicInterface {
66407
67400
  * If no other votes have been supplied, validate that the blocks are valid, and issue a short vote
66408
67401
  */
66409
67402
  if (otherVotes === undefined) {
66410
- await __classPrivateFieldGet(this, _LedgerAtomicInterface_instances, "m", _LedgerAtomicInterface_validateLedgerOutcome).call(this, blocks);
66411
- const now = Date.now();
66412
- for (const block of blocks) {
66413
- const blockDate = block.date.valueOf();
66414
- const timeOffset = 5 /* m */ * 60 /* s */ * 1000 /* ms */;
66415
- /**
66416
- * Do not allow short votes on blocks from the distant past
66417
- */
66418
- if (blockDate < (now - timeOffset) || blockDate > (now + timeOffset)) {
66419
- throw (new Error(`Refusing to issue vote for block dated ${block.date.toISOString()}`));
66420
- }
66421
- }
66422
- /**
66423
- * Serial number
66424
- */
66425
- const serial = await __classPrivateFieldGet(this, _LedgerAtomicInterface_storage, "f").getNextSerialNumber(__classPrivateFieldGet(this, _LedgerAtomicInterface_transaction, "f"));
66426
- /**
66427
- * Short expiry (5 minutes)
66428
- */
66429
- const pendingVoteExpiry = new Date();
66430
- pendingVoteExpiry.setUTCMinutes(pendingVoteExpiry.getUTCMinutes() + 5);
66431
- const wipVote = new vote_1.VoteBuilder(privateKey);
66432
- for (const block of blocks) {
66433
- wipVote.addBlock(block);
66434
- }
66435
- const vote = await wipVote.seal(serial, pendingVoteExpiry);
67403
+ const vote = await __classPrivateFieldGet(this, _LedgerAtomicInterface_instances, "m", _LedgerAtomicInterface_voteOrQuoteWithFees).call(this, blocks, 'VOTE', quote);
66436
67404
  const blocksAndVote = vote_1.VoteStaple.fromVotesAndBlocks([vote], blocks);
66437
67405
  await __classPrivateFieldGet(this, _LedgerAtomicInterface_storage, "f").addPendingVote(transaction, blocksAndVote);
66438
67406
  return (vote);
@@ -66462,6 +67430,11 @@ class LedgerAtomicInterface {
66462
67430
  await __classPrivateFieldGet(this, _LedgerAtomicInterface_storage, "f").addPendingVote(transaction, blocksAndVote);
66463
67431
  return (vote);
66464
67432
  }
67433
+ async quote(blocks) {
67434
+ await __classPrivateFieldGet(this, _LedgerAtomicInterface_instances, "m", _LedgerAtomicInterface_validateBlocksForVote).call(this, blocks);
67435
+ const quote = await __classPrivateFieldGet(this, _LedgerAtomicInterface_instances, "m", _LedgerAtomicInterface_voteOrQuoteWithFees).call(this, blocks, 'QUOTE');
67436
+ return (quote);
67437
+ }
66465
67438
  async add(votesAndBlocks, from) {
66466
67439
  const transaction = __classPrivateFieldGet(this, _LedgerAtomicInterface_instances, "m", _LedgerAtomicInterface_assertTransaction).call(this);
66467
67440
  switch (__classPrivateFieldGet(this, _LedgerAtomicInterface_ledger, "f").ledgerWriteMode) {
@@ -66781,9 +67754,13 @@ class LedgerAtomicInterface {
66781
67754
  }
66782
67755
  return (retval);
66783
67756
  }
66784
- async gc() {
67757
+ async gc(timeLimitMS) {
66785
67758
  const transaction = __classPrivateFieldGet(this, _LedgerAtomicInterface_instances, "m", _LedgerAtomicInterface_assertTransaction).call(this);
66786
- return (await __classPrivateFieldGet(this, _LedgerAtomicInterface_storage, "f").gc(transaction));
67759
+ return (await __classPrivateFieldGet(this, _LedgerAtomicInterface_storage, "f").gc(transaction, timeLimitMS));
67760
+ }
67761
+ async getFee(blocks, effectsInput) {
67762
+ const effects = effectsInput ?? (0, effects_1.computeEffectOfBlocks)(blocks, __classPrivateFieldGet(this, _LedgerAtomicInterface_ledger, "f"));
67763
+ return (__classPrivateFieldGet(this, _LedgerAtomicInterface_computeFeeFromBlocks, "f").call(this, __classPrivateFieldGet(this, _LedgerAtomicInterface_ledger, "f"), blocks, effects));
66787
67764
  }
66788
67765
  async _testingRunStorageFunction(code) {
66789
67766
  const transaction = __classPrivateFieldGet(this, _LedgerAtomicInterface_instances, "m", _LedgerAtomicInterface_assertTransaction).call(this);
@@ -66791,7 +67768,7 @@ class LedgerAtomicInterface {
66791
67768
  return (retval);
66792
67769
  }
66793
67770
  }
66794
- _LedgerAtomicInterface_network = new WeakMap(), _LedgerAtomicInterface_subnet = new WeakMap(), _LedgerAtomicInterface_kind = new WeakMap(), _LedgerAtomicInterface_privateKey = new WeakMap(), _LedgerAtomicInterface_storage = new WeakMap(), _LedgerAtomicInterface_transaction = new WeakMap(), _LedgerAtomicInterface_ledger = new WeakMap(), _LedgerAtomicInterface_cache = new WeakMap(), _LedgerAtomicInterface_instances = new WeakSet(), _LedgerAtomicInterface_assertTransaction = function _LedgerAtomicInterface_assertTransaction() {
67771
+ _LedgerAtomicInterface_network = new WeakMap(), _LedgerAtomicInterface_subnet = new WeakMap(), _LedgerAtomicInterface_kind = new WeakMap(), _LedgerAtomicInterface_privateKey = new WeakMap(), _LedgerAtomicInterface_computeFeeFromBlocks = new WeakMap(), _LedgerAtomicInterface_storage = new WeakMap(), _LedgerAtomicInterface_ledger = new WeakMap(), _LedgerAtomicInterface_cache = new WeakMap(), _LedgerAtomicInterface_transaction = new WeakMap(), _LedgerAtomicInterface_instances = new WeakSet(), _LedgerAtomicInterface_assertTransaction = function _LedgerAtomicInterface_assertTransaction() {
66795
67772
  if (__classPrivateFieldGet(this, _LedgerAtomicInterface_transaction, "f") === null) {
66796
67773
  throw (new Error('Attempt to use closed transaction'));
66797
67774
  }
@@ -66858,36 +67835,56 @@ _LedgerAtomicInterface_network = new WeakMap(), _LedgerAtomicInterface_subnet =
66858
67835
  throw (new ledger_1.default('LEDGER_INVALID_PERMISSIONS', `${accountPubKey} does not have required permissions to perform action on ${reqEntityKey}/${reqTargetKey} -- needs [${baseFlagsStr}]/[${externalOffsetsStr}]`));
66859
67836
  }
66860
67837
  }
66861
- }, _LedgerAtomicInterface_checkPermissionRequirements = async function _LedgerAtomicInterface_checkPermissionRequirements(allRequirements) {
67838
+ }, _LedgerAtomicInterface_checkPermissionRequirements = async function _LedgerAtomicInterface_checkPermissionRequirements(effects) {
66862
67839
  __classPrivateFieldGet(this, _LedgerAtomicInterface_instances, "m", _LedgerAtomicInterface_assertTransaction).call(this);
66863
67840
  const newOwners = {};
66864
- const requirementsByPrincipal = {};
66865
- const needToGetAccountInfoFor = new account_1.default.Set();
66866
- for (const singleRequirement of allRequirements) {
66867
- const principal = singleRequirement.principal;
66868
- const principalPubKey = principal.publicKeyString.get();
66869
- if (!requirementsByPrincipal[principalPubKey]) {
66870
- requirementsByPrincipal[principalPubKey] = [];
66871
- }
66872
- requirementsByPrincipal[principalPubKey].push(singleRequirement);
66873
- const { entity, permissions } = singleRequirement;
66874
- const entityKey = entity.publicKeyString.get();
66875
- if (permissions === null) {
66876
- continue;
66877
- }
66878
- if (permissions.has(['OWNER'])) {
66879
- if (newOwners[entityKey] === undefined) {
66880
- newOwners[entityKey] = {
66881
- entity, owners: []
66882
- };
67841
+ const requirementsByPrincipal = {};
67842
+ const needToGetAccountInfoFor = new account_1.default.Set();
67843
+ const allAccountsChanges = Object.values(effects);
67844
+ const foundMultisigSignerLengths = [];
67845
+ for (const { account, fields } of allAccountsChanges) {
67846
+ if (account.isMultisig()) {
67847
+ if (fields.minSignerSetLength !== undefined) {
67848
+ needToGetAccountInfoFor.add(account);
67849
+ foundMultisigSignerLengths.push([account, fields.minSignerSetLength]);
67850
+ }
67851
+ }
67852
+ for (const singleRequirement of fields.permissionRequirements ?? []) {
67853
+ const principal = singleRequirement.principal;
67854
+ const principalPubKey = principal.publicKeyString.get();
67855
+ if (!requirementsByPrincipal[principalPubKey]) {
67856
+ requirementsByPrincipal[principalPubKey] = [];
67857
+ }
67858
+ requirementsByPrincipal[principalPubKey].push(singleRequirement);
67859
+ const { entity, permissions } = singleRequirement;
67860
+ const entityKey = entity.publicKeyString.get();
67861
+ if (permissions === null) {
67862
+ continue;
67863
+ }
67864
+ if (permissions.has(['OWNER'])) {
67865
+ if (newOwners[entityKey] === undefined) {
67866
+ newOwners[entityKey] = {
67867
+ entity, owners: []
67868
+ };
67869
+ }
67870
+ newOwners[entityKey].owners.push(principal);
67871
+ }
67872
+ if (permissions.base.isValidForDefault && entity.isIdentifier()) {
67873
+ needToGetAccountInfoFor.add(entity);
66883
67874
  }
66884
- newOwners[entityKey].owners.push(principal);
66885
- }
66886
- if (permissions.base.isValidForDefault && entity.isIdentifier()) {
66887
- needToGetAccountInfoFor.add(entity);
66888
67875
  }
66889
67876
  }
66890
67877
  const foundAccountInfo = await __classPrivateFieldGet(this, _LedgerAtomicInterface_instances, "m", _LedgerAtomicInterface_listAccountInfo).call(this, needToGetAccountInfoFor);
67878
+ for (const [multisig, foundSingerLength] of foundMultisigSignerLengths) {
67879
+ const multisigPubKey = multisig.publicKeyString.get();
67880
+ const foundInfo = foundAccountInfo[multisigPubKey];
67881
+ if (!foundInfo?.multisigQuorum) {
67882
+ throw (new Error(`Multisig quorum not found for ${multisigPubKey}`));
67883
+ }
67884
+ if (foundInfo.multisigQuorum > foundSingerLength) {
67885
+ throw (new ledger_1.default('LEDGER_INVALID_PERMISSIONS', `Quorum of ${foundInfo.multisigQuorum} not reached for ${multisigPubKey} -- got ${foundSingerLength}`));
67886
+ }
67887
+ }
66891
67888
  const checkPromises = [];
66892
67889
  for (const principalPubKey in requirementsByPrincipal) {
66893
67890
  const accountRequirements = requirementsByPrincipal[principalPubKey];
@@ -66908,7 +67905,7 @@ async function _LedgerAtomicInterface_validateLedgerOutcome(blocks) {
66908
67905
  const ownersByIdentifier = {};
66909
67906
  // 'ADD' or 'REMOVE' an owner from ownersByIdentifier
66910
67907
  const modifyOwners = (method, entity, principal) => {
66911
- if (entity.isIdentifier() === false) {
67908
+ if (entity.isIdentifier() === false || entity.isMultisig()) {
66912
67909
  return;
66913
67910
  }
66914
67911
  const entityPubKey = entity.assertIdentifier().publicKeyString.get();
@@ -66928,18 +67925,14 @@ async function _LedgerAtomicInterface_validateLedgerOutcome(blocks) {
66928
67925
  break;
66929
67926
  }
66930
67927
  };
66931
- const accountEffects = (0, effects_1.computeEffectOfBlocks)(blocks, __classPrivateFieldGet(this, _LedgerAtomicInterface_ledger, "f")).accounts;
67928
+ const effects = (0, effects_1.computeEffectOfBlocks)(blocks, __classPrivateFieldGet(this, _LedgerAtomicInterface_ledger, "f"));
67929
+ const accountEffects = effects.accounts;
66932
67930
  const allAccountsChanges = Object.values(accountEffects);
66933
67931
  /**
66934
67932
  * Ensure all required permissions are met
66935
67933
  * See which accounts are now owners, and add those accounts to the set that we have
66936
67934
  */
66937
- const allPermissionRequirements = [];
66938
- for (const accountChanges of allAccountsChanges) {
66939
- const requirements = accountChanges.fields.permissionRequirements ?? [];
66940
- allPermissionRequirements.push(...requirements);
66941
- }
66942
- const { newOwners } = await __classPrivateFieldGet(this, _LedgerAtomicInterface_instances, "m", _LedgerAtomicInterface_checkPermissionRequirements).call(this, allPermissionRequirements);
67935
+ const { newOwners } = await __classPrivateFieldGet(this, _LedgerAtomicInterface_instances, "m", _LedgerAtomicInterface_checkPermissionRequirements).call(this, accountEffects);
66943
67936
  for (const entityPubKey in newOwners) {
66944
67937
  const { entity, owners } = newOwners[entityPubKey];
66945
67938
  for (const newOwner of owners) {
@@ -66953,7 +67946,7 @@ async function _LedgerAtomicInterface_validateLedgerOutcome(blocks) {
66953
67946
  */
66954
67947
  const createRequests = fields.createRequests ?? [];
66955
67948
  for (const createRequest of createRequests) {
66956
- modifyOwners('ADD', createRequest.requestedIdentifier, account);
67949
+ modifyOwners('ADD', createRequest.createdIdentifier, account);
66957
67950
  }
66958
67951
  /**
66959
67952
  * If an account was granted permissions, we should take that into effect
@@ -67005,6 +67998,98 @@ async function _LedgerAtomicInterface_validateLedgerOutcome(blocks) {
67005
67998
  }
67006
67999
  }
67007
68000
  }
68001
+ return (effects);
68002
+ }, _LedgerAtomicInterface_validateBlocksForVote = async function _LedgerAtomicInterface_validateBlocksForVote(blocks) {
68003
+ /**
68004
+ * Create a map of all blocks by their hash
68005
+ */
68006
+ const blockHashMap = {};
68007
+ for (const block of blocks) {
68008
+ blockHashMap[block.hash.toString()] = block;
68009
+ }
68010
+ const seenBlockHashes = new block_1.BlockHash.Set();
68011
+ const usedPreviousBlockHashes = new block_1.BlockHash.Set();
68012
+ const allLedgerHeads = new Map();
68013
+ for (const block of blocks) {
68014
+ const prevBlockHash = block.previous;
68015
+ seenBlockHashes.add(block.hash);
68016
+ if (block.network !== __classPrivateFieldGet(this, _LedgerAtomicInterface_network, "f")) {
68017
+ throw (new ledger_1.default('LEDGER_INVALID_NETWORK', 'Cannot vote on block for a different network'));
68018
+ }
68019
+ if (block.subnet !== __classPrivateFieldGet(this, _LedgerAtomicInterface_subnet, "f")) {
68020
+ throw (new ledger_1.default('LEDGER_INVALID_SUBNET', 'Cannot vote on block for a different subnet'));
68021
+ }
68022
+ if (usedPreviousBlockHashes.has(prevBlockHash)) {
68023
+ throw (new ledger_1.default('LEDGER_PREVIOUS_ALREADY_USED', `Invalid reference to block, previous: ${prevBlockHash} has already been used`));
68024
+ }
68025
+ usedPreviousBlockHashes.add(prevBlockHash);
68026
+ /**
68027
+ * Only allow this vote if it is the successor the current
68028
+ * HEAD block for the account, or if no blocks exist on the
68029
+ * account and its an opening block, or if the predecessor
68030
+ * block is also being voted on
68031
+ */
68032
+ let predecessorBeingVotedOn = false;
68033
+ if (!block.$opening) {
68034
+ const prevBlock = blockHashMap[prevBlockHash.toString()];
68035
+ if (prevBlock !== undefined) {
68036
+ predecessorBeingVotedOn = true;
68037
+ if (!(prevBlock.account.comparePublicKey(block.account))) {
68038
+ throw (new ledger_1.default('LEDGER_INVALID_CHAIN', 'Invalid chain, changes accounts'));
68039
+ }
68040
+ if (!seenBlockHashes.has(prevBlockHash)) {
68041
+ throw (new ledger_1.default('LEDGER_PREVIOUS_NOT_SEEN', `Invalid reference to block, out-of-order: ${prevBlockHash} has not already been seen`));
68042
+ }
68043
+ }
68044
+ }
68045
+ if (!predecessorBeingVotedOn) {
68046
+ allLedgerHeads.set(block.account, block);
68047
+ }
68048
+ }
68049
+ return (allLedgerHeads);
68050
+ }, _LedgerAtomicInterface_voteOrQuoteWithFees = async function _LedgerAtomicInterface_voteOrQuoteWithFees(blocks, type, quote) {
68051
+ if (__classPrivateFieldGet(this, _LedgerAtomicInterface_ledger, "f").ledgerWriteMode !== 'read-write') {
68052
+ throw (new Error(`May not issue votes in read-only mode, in ${__classPrivateFieldGet(this, _LedgerAtomicInterface_ledger, "f").ledgerWriteMode} mode`));
68053
+ }
68054
+ if (!__classPrivateFieldGet(this, _LedgerAtomicInterface_privateKey, "f")) {
68055
+ throw (new Error('Cannot vote on block, no private key loaded'));
68056
+ }
68057
+ __classPrivateFieldGet(this, _LedgerAtomicInterface_instances, "m", _LedgerAtomicInterface_assertTransaction).call(this);
68058
+ const effects = await __classPrivateFieldGet(this, _LedgerAtomicInterface_instances, "m", _LedgerAtomicInterface_validateLedgerOutcome).call(this, blocks);
68059
+ const now = Date.now();
68060
+ for (const block of blocks) {
68061
+ const blockDate = block.date.valueOf();
68062
+ const timeOffset = 5 /* m */ * 60 /* s */ * 1000 /* ms */;
68063
+ /**
68064
+ * Do not allow short votes on blocks from the distant past
68065
+ */
68066
+ if (blockDate < (now - timeOffset) || blockDate > (now + timeOffset)) {
68067
+ throw (new Error(`Refusing to issue vote for block dated ${block.date.toISOString()}`));
68068
+ }
68069
+ }
68070
+ /**
68071
+ * Serial number
68072
+ */
68073
+ const serial = await __classPrivateFieldGet(this, _LedgerAtomicInterface_storage, "f").getNextSerialNumber(__classPrivateFieldGet(this, _LedgerAtomicInterface_transaction, "f"));
68074
+ /**
68075
+ * Short expiry (5 minutes)
68076
+ */
68077
+ const pendingVoteExpiry = new Date();
68078
+ pendingVoteExpiry.setUTCMinutes(pendingVoteExpiry.getUTCMinutes() + 5);
68079
+ const builderType = (type === 'QUOTE') ? vote_1.VoteQuoteBuilder : vote_1.VoteBuilder;
68080
+ const builder = new builderType(__classPrivateFieldGet(this, _LedgerAtomicInterface_privateKey, "f"));
68081
+ for (const block of blocks) {
68082
+ builder.addBlock(block);
68083
+ }
68084
+ /**
68085
+ * If a quote was provided use it as the fee, otherwise generate new fee
68086
+ */
68087
+ const fee = quote?.fee ?? await this.getFee(blocks, effects);
68088
+ if (fee !== null) {
68089
+ builder.addFee(fee);
68090
+ }
68091
+ const voteOrQuote = await builder.seal(serial, pendingVoteExpiry);
68092
+ return (voteOrQuote);
67008
68093
  };
67009
68094
  /**
67010
68095
  * The core Ledger components
@@ -67041,6 +68126,26 @@ class Ledger {
67041
68126
  copy(newNode) {
67042
68127
  return (new Ledger(__classPrivateFieldGet(this, _Ledger_config, "f"), newNode, __classPrivateFieldGet(this, _Ledger_storage, "f")));
67043
68128
  }
68129
+ getFeePayToAndToken(accounts, token) {
68130
+ const retval = {};
68131
+ if (accounts !== undefined && accounts.length > 0) {
68132
+ // Get a random fee account from the set of possible accounts
68133
+ const feeAccount = accounts[Math.floor(Math.random() * accounts.length)];
68134
+ // If the fee account matches the ledger private key then we can omit the account
68135
+ // Fee is then paid to the vote issuer
68136
+ if (!feeAccount.comparePublicKey(__classPrivateFieldGet(this, _Ledger_config, "f").privateKey?.publicKeyString.get())) {
68137
+ retval.payTo = feeAccount;
68138
+ }
68139
+ }
68140
+ if (token !== undefined) {
68141
+ // If base token matches ledger fee token then we can omit the token
68142
+ // Fee is then paid using the base token
68143
+ if (!this.baseToken.comparePublicKey(token)) {
68144
+ retval.token = token;
68145
+ }
68146
+ }
68147
+ return (retval);
68148
+ }
67044
68149
  /**
67045
68150
  * Execute some code with a transaction held, if the code fails the
67046
68151
  * transaction is aborted, otherwise it is committed
@@ -67162,6 +68267,11 @@ class Ledger {
67162
68267
  return (await transaction.vote(...args));
67163
68268
  }));
67164
68269
  }
68270
+ async quote(...args) {
68271
+ return (await this.run('db-quote', async function (transaction) {
68272
+ return (await transaction.quote(...args));
68273
+ }));
68274
+ }
67165
68275
  async add(...args) {
67166
68276
  return (await this.run('db-add', async function (transaction) {
67167
68277
  return (await transaction.add(...args));
@@ -67272,6 +68382,11 @@ class Ledger {
67272
68382
  return (await transaction.gc(...args));
67273
68383
  }));
67274
68384
  }
68385
+ async getFee(...args) {
68386
+ return (await this.run('db-getFee', async function (transaction) {
68387
+ return (await transaction.getFee(...args));
68388
+ }));
68389
+ }
67275
68390
  async stats() {
67276
68391
  const env_2 = { stack: [], error: void 0, hasError: false };
67277
68392
  try {
@@ -67819,9 +68934,9 @@ var __classPrivateFieldGet = (this && this.__classPrivateFieldGet) || function (
67819
68934
  var __importDefault = (this && this.__importDefault) || function (mod) {
67820
68935
  return (mod && mod.__esModule) ? mod : { "default": mod };
67821
68936
  };
67822
- var _P2PWebSocket_underlyingSocket, _P2PWebSocket_socket, _P2PWebSocket_switch, _P2PSwitch_instances, _P2PSwitch_connectedPeersCleanup, _P2PSwitch_connectedPeersRemote, _P2PSwitch_connectedPeersLocal, _P2PSwitch_localNode, _P2PSwitch_manualPeersCheckIntervals, _P2PSwitch_asyncSends, _P2PSwitch_messageFilterCache, _P2PSwitch_connectedPeerConnection, _P2PSwitch_connectedPeers, _P2PSwitch_updateLastSeenPeer, _P2PSwitch_peersCacheSet, _P2PSwitch_peersCached, _P2PSwitch_relayActiveState, _P2PSwitch_performPeerCleanup, _P2PSwitch_getLocalPeerInfo, _P2PSwitch_emitOutgoingGreeting, _P2PSwitch_localNodeKeyOrNull, _P2PSwitch_handleIncomingGreeting, _P2PSwitch_updateConnTimeout, _P2PSwitch_connectToPeer, _P2PSwitch_passesFilter;
68937
+ var _P2PHttpConnection_switch, _P2PWebSocket_underlyingSocket, _P2PWebSocket_socket, _P2PWebSocket_switch, _P2PSwitch_instances, _P2PSwitch_connectedPeersCleanup, _P2PSwitch_connectedPeersRemote, _P2PSwitch_connectedPeersLocal, _P2PSwitch_localNode, _P2PSwitch_manualPeersCheckIntervals, _P2PSwitch_asyncSends, _P2PSwitch_messageFilterCache, _P2PSwitch_connectedPeerConnection, _P2PSwitch_connectedPeers, _P2PSwitch_updateLastSeenPeer, _P2PSwitch_peersCacheSet, _P2PSwitch_peersCached, _P2PSwitch_relayActiveState, _P2PSwitch_performPeerCleanup, _P2PSwitch_getLocalPeerInfo, _P2PSwitch_emitOutgoingGreeting, _P2PSwitch_localNodeKeyOrNull, _P2PSwitch_handleIncomingGreeting, _P2PSwitch_updateConnTimeout, _P2PSwitch_connectToPeer, _P2PSwitch_passesFilter;
67823
68938
  Object.defineProperty(exports, "__esModule", ({ value: true }));
67824
- exports.Testing = exports.P2PSwitch = exports.P2PWebSocket = void 0;
68939
+ exports.Testing = exports.P2PSwitch = exports.P2PWebSocket = exports.P2PHttpConnection = void 0;
67825
68940
  exports.generateP2PPeerSigned = generateP2PPeerSigned;
67826
68941
  exports.P2PPeerFromJSO = P2PPeerFromJSO;
67827
68942
  exports.P2PPeerToJSO = P2PPeerToJSO;
@@ -67838,6 +68953,7 @@ const helper_1 = __webpack_require__(3208);
67838
68953
  const kv_memory_1 = __importDefault(__webpack_require__(1557));
67839
68954
  const vote_1 = __webpack_require__(1130);
67840
68955
  const effects_1 = __webpack_require__(7346);
68956
+ const version_1 = __webpack_require__(5672);
67841
68957
  const defaultP2PConfig = {
67842
68958
  timeoutIdle: 10 /* s */ * 1000 /* ms */,
67843
68959
  timeoutIdleGreeting: 5 /* s */ * 1000 /* ms */,
@@ -67846,12 +68962,13 @@ const defaultP2PConfig = {
67846
68962
  manualPeersCheckInFreq: 10 /* m */ * 60 /* s */ * 1000 /* ms */,
67847
68963
  seenMessageTTL: 1 /* m */ * 60 /* s */ * 1000 /* ms */,
67848
68964
  forwardingPeerCount: 16,
67849
- kv: null
68965
+ kv: null,
68966
+ useHTTPRepublish: false
67850
68967
  };
67851
68968
  /**
67852
68969
  * Convert a peer to a printable string
67853
68970
  */
67854
- function printablePeer(peer) {
68971
+ function printablePeer(peer, endpoint) {
67855
68972
  if (peer === null) {
67856
68973
  return ('null (not yet greeted)');
67857
68974
  }
@@ -67859,7 +68976,7 @@ function printablePeer(peer) {
67859
68976
  case node_1.NodeKind.PARTICIPANT:
67860
68977
  return (`listener_${peer.id}`);
67861
68978
  case node_1.NodeKind.REPRESENTATIVE:
67862
- return (`rep_${peer.key.publicKeyString.get()}@${peer.endpoints.p2p}`);
68979
+ return (`rep_${peer.key.publicKeyString.get()}@${endpoint ?? peer.endpoints.p2p}`);
67863
68980
  }
67864
68981
  return (null);
67865
68982
  }
@@ -67893,6 +69010,7 @@ function validateP2PPeer(peer) {
67893
69010
  checkVersion,
67894
69011
  peer.endpoints.p2p,
67895
69012
  peer.endpoints.api,
69013
+ peer.preferUpdates,
67896
69014
  peer.kind,
67897
69015
  peer.key.publicKeyAndType
67898
69016
  ];
@@ -67916,6 +69034,7 @@ async function generateP2PPeerSignature(peer) {
67916
69034
  version,
67917
69035
  peer.endpoints.p2p,
67918
69036
  peer.endpoints.api,
69037
+ peer.preferUpdates,
67919
69038
  peer.kind,
67920
69039
  peer.key.publicKeyAndType
67921
69040
  ];
@@ -67967,13 +69086,20 @@ function P2PPeerFromJSO(object) {
67967
69086
  if (typeof endpoints.p2p !== 'string' || typeof endpoints.api !== 'string') {
67968
69087
  return (null);
67969
69088
  }
69089
+ if (typeof object.preferUpdates !== 'string') {
69090
+ return (null);
69091
+ }
69092
+ if (object.preferUpdates !== 'http' && object.preferUpdates !== 'websocket') {
69093
+ return (null);
69094
+ }
67970
69095
  if (typeof object.key !== 'string') {
67971
69096
  return (null);
67972
69097
  }
67973
69098
  const retvalUnsigned = {
67974
69099
  kind: node_1.NodeKind.REPRESENTATIVE,
67975
69100
  key: account_1.default.fromPublicKeyString(object.key).assertAccount(),
67976
- endpoints: endpoints
69101
+ endpoints: endpoints,
69102
+ preferUpdates: object.preferUpdates
67977
69103
  };
67978
69104
  let retval;
67979
69105
  if (typeof object.signature === 'string') {
@@ -68035,6 +69161,7 @@ function P2PPeerToJSO(peer) {
68035
69161
  return ({
68036
69162
  kind: peer.kind,
68037
69163
  endpoints: peer.endpoints,
69164
+ preferUpdates: peer.preferUpdates,
68038
69165
  key: peer.key.publicKeyString.get(),
68039
69166
  ...additionalAttributes
68040
69167
  });
@@ -68067,6 +69194,12 @@ function isP2PPeer(checkObject) {
68067
69194
  if (!('p2p' in checkObject.endpoints) || !('api' in checkObject.endpoints)) {
68068
69195
  return (false);
68069
69196
  }
69197
+ if (!('preferUpdates' in checkObject)) {
69198
+ return (false);
69199
+ }
69200
+ if (checkObject.preferUpdates !== 'http' && checkObject.preferUpdates !== 'websocket') {
69201
+ return (false);
69202
+ }
68070
69203
  if (!('key' in checkObject)) {
68071
69204
  return (false);
68072
69205
  }
@@ -68176,6 +69309,78 @@ async function waitForPeer(conn) {
68176
69309
  }, 10);
68177
69310
  })));
68178
69311
  }
69312
+ class P2PHttpConnection {
69313
+ /**
69314
+ * Initiate an outbound http connection and attach it to the specified switch
69315
+ */
69316
+ static async initiate(peer, p2pSwitch) {
69317
+ if (!('endpoints' in peer)) {
69318
+ return (null);
69319
+ }
69320
+ if (!('api' in peer.endpoints)) {
69321
+ return (null);
69322
+ }
69323
+ if (!('preferUpdates' in peer) || peer.preferUpdates !== 'http') {
69324
+ return (null);
69325
+ }
69326
+ const conn = new P2PHttpConnection(peer, p2pSwitch);
69327
+ await p2pSwitch.registerConnection(conn);
69328
+ return (conn);
69329
+ }
69330
+ constructor(peer, p2pSwitch) {
69331
+ _P2PHttpConnection_switch.set(this, void 0);
69332
+ this.abort = false;
69333
+ this.validatedPeer = null;
69334
+ this.timeout = 0;
69335
+ this.peer = peer;
69336
+ __classPrivateFieldSet(this, _P2PHttpConnection_switch, p2pSwitch, "f");
69337
+ }
69338
+ get connString() {
69339
+ if (this.peerString === null) {
69340
+ throw (new Error('HTTP Connection should have a peerString'));
69341
+ }
69342
+ return (this.peerString);
69343
+ }
69344
+ get peerString() {
69345
+ if (this.peer.kind === node_1.NodeKind.PARTICIPANT) {
69346
+ throw (new Error('HTTP Connections cannot be participants'));
69347
+ }
69348
+ return (printablePeer(this.peer, this.peer.endpoints.api));
69349
+ }
69350
+ async send(messageBuffer) {
69351
+ if (this.peer.kind !== node_1.NodeKind.REPRESENTATIVE) {
69352
+ return (false);
69353
+ }
69354
+ __classPrivateFieldGet(this, _P2PHttpConnection_switch, "f")._log.debug(`Called send on http connection: ${this.peerString}`);
69355
+ const localGreetingInfo = await __classPrivateFieldGet(this, _P2PHttpConnection_switch, "f").getOutgoingGreetingInfo();
69356
+ const fetchURL = `${this.peer.endpoints.api}/p2p/message`;
69357
+ try {
69358
+ await fetch(fetchURL, {
69359
+ method: 'POST',
69360
+ headers: {
69361
+ 'content-type': 'application/json',
69362
+ 'user-agent': `KeetaNet/v${version_1.version} (JS)`
69363
+ },
69364
+ body: JSON.stringify({
69365
+ message: messageBuffer.toString(),
69366
+ greeting: localGreetingInfo
69367
+ })
69368
+ });
69369
+ }
69370
+ catch (postMessageError) {
69371
+ __classPrivateFieldGet(this, _P2PHttpConnection_switch, "f")._log.debug(`Failed to post message: ${postMessageError}`);
69372
+ }
69373
+ return (true);
69374
+ }
69375
+ async close() {
69376
+ this.abort = true;
69377
+ __classPrivateFieldGet(this, _P2PHttpConnection_switch, "f")._log.debug(`Called close on http connection: ${this.peerString}`);
69378
+ await __classPrivateFieldGet(this, _P2PHttpConnection_switch, "f").unregisterConnection(this);
69379
+ }
69380
+ }
69381
+ exports.P2PHttpConnection = P2PHttpConnection;
69382
+ _P2PHttpConnection_switch = new WeakMap();
69383
+ P2PHttpConnection.isInstance = (0, helper_1.checkableGenerator)(P2PHttpConnection);
68179
69384
  /**
68180
69385
  * A P2PConnection using the "ws" package
68181
69386
  */
@@ -68470,7 +69675,12 @@ class P2PSwitch {
68470
69675
  * been confirmed
68471
69676
  */
68472
69677
  const repLastSeenLimit = Math.max(this.config.timeoutIdle, this.config.manualPeersCheckInFreq) * 10;
68473
- let knownPeers = await this.config.kv.getAll('knownPeers');
69678
+ const potentialKnownPeers = await this.config.kv.getAll('knownPeers');
69679
+ // Filter for only valid entries in case the format becomes invalidated in the future
69680
+ let knownPeers = Object.fromEntries(Object.entries(potentialKnownPeers).filter(([_, value]) => {
69681
+ const peer = P2PPeerFromJSO(value);
69682
+ return (peer !== null);
69683
+ }));
68474
69684
  const lastSeenPeers = await this.config.kv.getAll('lastSeenPeers');
68475
69685
  const retval = [];
68476
69686
  /**
@@ -68724,6 +69934,13 @@ class P2PSwitch {
68724
69934
  async selfPeer() {
68725
69935
  return (await __classPrivateFieldGet(this, _P2PSwitch_instances, "m", _P2PSwitch_getLocalPeerInfo).call(this));
68726
69936
  }
69937
+ async getOutgoingGreetingInfo() {
69938
+ const greetingInfo = await __classPrivateFieldGet(this, _P2PSwitch_instances, "m", _P2PSwitch_getLocalPeerInfo).call(this);
69939
+ if (greetingInfo === null) {
69940
+ throw (new Error('Invalid NodeKind for emitting outgoing greeting'));
69941
+ }
69942
+ return (P2PPeerToJSO(greetingInfo));
69943
+ }
68727
69944
  /**
68728
69945
  * Receive a message from a connection
68729
69946
  *
@@ -68774,7 +69991,7 @@ class P2PSwitch {
68774
69991
  let forward = true;
68775
69992
  let acceptable = true;
68776
69993
  let rebroadcastOnly = false;
68777
- if (from.peer === null) {
69994
+ if (from.peer === null || (P2PHttpConnection.isInstance(from) && message.type === 'greeting')) {
68778
69995
  /**
68779
69996
  * By default do not forward messages from un-greeted peers
68780
69997
  */
@@ -69231,6 +70448,23 @@ class P2PSwitch {
69231
70448
  }
69232
70449
  return (false);
69233
70450
  }
70451
+ /**
70452
+ * TODO - make this private after refactoring websockets to handle higher load
70453
+ * https://github.com/KeetaNetwork/node/issues/785
70454
+ */
70455
+ async haveAnyFilter(data) {
70456
+ const kvFilters = await this.config.kv.getAll('messageFilters');
70457
+ for (const key in kvFilters) {
70458
+ const kvFilter = kvFilters[key];
70459
+ if (kvFilter && typeof kvFilter === 'string') {
70460
+ const filter = account_1.default.fromPublicKeyAndType(kvFilter);
70461
+ const voteStaple = new vote_1.VoteStaple(data);
70462
+ const { touched } = (0, effects_1.computeEffectOfBlocks)(voteStaple.blocks);
70463
+ return (touched.has(filter));
70464
+ }
70465
+ }
70466
+ return (false);
70467
+ }
69234
70468
  }
69235
70469
  exports.P2PSwitch = P2PSwitch;
69236
70470
  _P2PSwitch_connectedPeersCleanup = new WeakMap(), _P2PSwitch_connectedPeersRemote = new WeakMap(), _P2PSwitch_connectedPeersLocal = new WeakMap(), _P2PSwitch_localNode = new WeakMap(), _P2PSwitch_manualPeersCheckIntervals = new WeakMap(), _P2PSwitch_asyncSends = new WeakMap(), _P2PSwitch_messageFilterCache = new WeakMap(), _P2PSwitch_peersCacheSet = new WeakMap(), _P2PSwitch_instances = new WeakSet(), _P2PSwitch_connectedPeerConnection =
@@ -69402,7 +70636,8 @@ async function _P2PSwitch_relayActiveState(conn) {
69402
70636
  endpoints: {
69403
70637
  p2p: __classPrivateFieldGet(this, _P2PSwitch_localNode, "f").config.endpoints.p2p,
69404
70638
  api: __classPrivateFieldGet(this, _P2PSwitch_localNode, "f").config.endpoints.api
69405
- }
70639
+ },
70640
+ preferUpdates: this.config.useHTTPRepublish ? 'http' : 'websocket'
69406
70641
  });
69407
70642
  if (greetingInfoSigned === null) {
69408
70643
  throw (new Error('internal error: Could not generate signature'));
@@ -69416,11 +70651,7 @@ async function _P2PSwitch_relayActiveState(conn) {
69416
70651
  return (greetingInfo);
69417
70652
  }, _P2PSwitch_emitOutgoingGreeting = async function _P2PSwitch_emitOutgoingGreeting(to) {
69418
70653
  const messageID = uuid.v4();
69419
- const greetingInfo = await __classPrivateFieldGet(this, _P2PSwitch_instances, "m", _P2PSwitch_getLocalPeerInfo).call(this);
69420
- if (greetingInfo === null) {
69421
- throw (new Error('Invalid NodeKind for emitting outgoing greeting'));
69422
- }
69423
- const greeting = P2PPeerToJSO(greetingInfo);
70654
+ const greeting = await this.getOutgoingGreetingInfo();
69424
70655
  this._log.debug('Sending greeting to', to.connString);
69425
70656
  return (await this.sendMessage(to, messageID, 'greeting', greeting, 0));
69426
70657
  }, _P2PSwitch_localNodeKeyOrNull = async function _P2PSwitch_localNodeKeyOrNull() {
@@ -69483,23 +70714,28 @@ async function _P2PSwitch_relayActiveState(conn) {
69483
70714
  }
69484
70715
  }, _P2PSwitch_connectToPeer = async function _P2PSwitch_connectToPeer(peer, logId) {
69485
70716
  this._log.debug(`[${logId}]`, 'Trying to connect to peer', printablePeer(peer));
69486
- let ws = null;
69487
- try {
69488
- ws = await P2PWebSocket.initiate(peer, this);
70717
+ let p2pConnection = null;
70718
+ if (peer.kind === node_1.NodeKind.REPRESENTATIVE && peer.preferUpdates === 'http') {
70719
+ p2pConnection = await P2PHttpConnection.initiate(peer, this);
69489
70720
  }
69490
- catch (connectError) {
69491
- /* Ignored */
70721
+ else {
70722
+ try {
70723
+ p2pConnection = await P2PWebSocket.initiate(peer, this);
70724
+ }
70725
+ catch (connectError) {
70726
+ /* Ignored */
70727
+ }
69492
70728
  }
69493
- if (ws === null) {
70729
+ if (p2pConnection === null) {
69494
70730
  return (null);
69495
70731
  }
69496
70732
  /**
69497
70733
  * Since we established an outbound connection to this
69498
70734
  * peer we already know their information
69499
70735
  */
69500
- ws.validatedPeer = peer;
69501
- await this.registerConnection(ws);
69502
- await waitForPeer(ws);
70736
+ p2pConnection.validatedPeer = peer;
70737
+ await this.registerConnection(p2pConnection);
70738
+ await waitForPeer(p2pConnection);
69503
70739
  /*
69504
70740
  * Since we successfully connected to the peer, update the
69505
70741
  * last seen information
@@ -69517,7 +70753,7 @@ async function _P2PSwitch_relayActiveState(conn) {
69517
70753
  catch (addPeerError) {
69518
70754
  this._log.error('Failed to add peer:', addPeerError);
69519
70755
  }
69520
- return (ws);
70756
+ return (p2pConnection);
69521
70757
  }, _P2PSwitch_passesFilter = async function _P2PSwitch_passesFilter(target, data) {
69522
70758
  let filter = __classPrivateFieldGet(this, _P2PSwitch_messageFilterCache, "f")[target.connString];
69523
70759
  if (filter === undefined) {
@@ -69594,7 +70830,8 @@ var BaseFlag;
69594
70830
  BaseFlag[BaseFlag["TOKEN_ADMIN_MODIFY_BALANCE"] = 7] = "TOKEN_ADMIN_MODIFY_BALANCE";
69595
70831
  BaseFlag[BaseFlag["PERMISSION_DELEGATE_ADD"] = 11] = "PERMISSION_DELEGATE_ADD";
69596
70832
  BaseFlag[BaseFlag["PERMISSION_DELEGATE_REMOVE"] = 12] = "PERMISSION_DELEGATE_REMOVE";
69597
- BaseFlag[BaseFlag["MANAGE_CERTIFICATE"] = 13] = "MANAGE_CERTIFICATE"; /* 0x2000 */
70833
+ BaseFlag[BaseFlag["MANAGE_CERTIFICATE"] = 13] = "MANAGE_CERTIFICATE";
70834
+ BaseFlag[BaseFlag["MULTISIG_SIGNER"] = 14] = "MULTISIG_SIGNER"; /* 0x4000 */
69598
70835
  })(BaseFlag || (BaseFlag = {}));
69599
70836
  /**
69600
70837
  * Handles what flags are in what groups, groups cannot be mixed (except BASE)
@@ -69608,6 +70845,8 @@ var BasePermissionGroup;
69608
70845
  BasePermissionGroup[BasePermissionGroup["NETWORK"] = 3] = "NETWORK";
69609
70846
  BasePermissionGroup[BasePermissionGroup["TOKEN"] = 4] = "TOKEN";
69610
70847
  BasePermissionGroup[BasePermissionGroup["STORAGE"] = 5] = "STORAGE";
70848
+ BasePermissionGroup[BasePermissionGroup["NONIDENTIFIER_OR_MULTISIG"] = 6] = "NONIDENTIFIER_OR_MULTISIG";
70849
+ BasePermissionGroup[BasePermissionGroup["MULTISIG"] = 7] = "MULTISIG";
69611
70850
  })(BasePermissionGroup || (BasePermissionGroup = {}));
69612
70851
  const basePermissionRules = {
69613
70852
  ACCESS: {
@@ -69693,6 +70932,12 @@ const basePermissionRules = {
69693
70932
  entity: BasePermissionGroup.ANY,
69694
70933
  principal: BasePermissionGroup.ANY,
69695
70934
  target: BasePermissionGroup.NEVER
70935
+ },
70936
+ MULTISIG_SIGNER: {
70937
+ canBeDefault: false,
70938
+ entity: BasePermissionGroup.MULTISIG,
70939
+ principal: BasePermissionGroup.NONIDENTIFIER_OR_MULTISIG,
70940
+ target: BasePermissionGroup.NEVER
69696
70941
  }
69697
70942
  };
69698
70943
  const basePermissionSetOffsets = {};
@@ -69833,6 +71078,10 @@ class BaseSet extends PermissionSetHolder {
69833
71078
  return (true);
69834
71079
  case _a.BasePermissionGroup.NEVER:
69835
71080
  return (false);
71081
+ case _a.BasePermissionGroup.NONIDENTIFIER_OR_MULTISIG:
71082
+ return (account.isAccount() || account.isMultisig());
71083
+ case _a.BasePermissionGroup.MULTISIG:
71084
+ return (account.isMultisig());
69836
71085
  }
69837
71086
  return (false);
69838
71087
  }
@@ -70389,6 +71638,7 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
70389
71638
  var _ValidateASN1_schema, _BufferStorageASN1_data;
70390
71639
  Object.defineProperty(exports, "__esModule", ({ value: true }));
70391
71640
  exports._Testing = exports.ASN1BigIntToBuffer = exports.ASN1IntegerToBigInt = exports.JStoASN1 = exports.ASN1toJS = exports.BufferStorageASN1 = exports.ValidateASN1 = exports.asn1 = void 0;
71641
+ exports.isASN1Object = isASN1Object;
70392
71642
  exports.isValidSequenceSchema = isValidSequenceSchema;
70393
71643
  const asn1js = __importStar(__webpack_require__(7813));
70394
71644
  const helper_1 = __webpack_require__(3208);
@@ -70454,20 +71704,29 @@ function jsIntegerToBigInt(value) {
70454
71704
  }
70455
71705
  return (BigInt(valueStr));
70456
71706
  }
71707
+ function isASN1Object(input) {
71708
+ if (input === null || input === undefined || typeof input !== 'object') {
71709
+ return (false);
71710
+ }
71711
+ if (!('type' in input) || typeof input.type !== 'string') {
71712
+ return (false);
71713
+ }
71714
+ return (true);
71715
+ }
70457
71716
  function isASN1OID(input) {
70458
- if (typeof input !== 'object') {
71717
+ if (!isASN1Object(input)) {
70459
71718
  return (false);
70460
71719
  }
70461
71720
  if (input.type !== 'oid') {
70462
71721
  return (false);
70463
71722
  }
70464
- if (typeof input.oid !== 'string') {
71723
+ if (!('oid' in input) || typeof input.oid !== 'string') {
70465
71724
  return (false);
70466
71725
  }
70467
71726
  return (true);
70468
71727
  }
70469
71728
  function isASN1String(input) {
70470
- if (typeof input !== 'object' || input === null) {
71729
+ if (!isASN1Object(input)) {
70471
71730
  return (false);
70472
71731
  }
70473
71732
  if (!('type' in input) || input.type !== 'string') {
@@ -70490,13 +71749,16 @@ function isASN1String(input) {
70490
71749
  return (true);
70491
71750
  }
70492
71751
  function isASN1Set(input) {
70493
- if (typeof input !== 'object') {
71752
+ if (!isASN1Object(input)) {
70494
71753
  return (false);
70495
71754
  }
70496
71755
  if (input.type !== 'set') {
70497
71756
  return (false);
70498
71757
  }
70499
- if (!isASN1OID(input.name)) {
71758
+ if (!('name' in input) || !isASN1OID(input.name)) {
71759
+ return (false);
71760
+ }
71761
+ if (!('value' in input)) {
70500
71762
  return (false);
70501
71763
  }
70502
71764
  if (typeof input.value !== 'string') {
@@ -70507,7 +71769,7 @@ function isASN1Set(input) {
70507
71769
  return (true);
70508
71770
  }
70509
71771
  function isASN1ContextTag(input) {
70510
- if (typeof input !== 'object' || input === null) {
71772
+ if (!isASN1Object(input)) {
70511
71773
  return (false);
70512
71774
  }
70513
71775
  if (!('type' in input) || input.type !== 'context') {
@@ -70522,19 +71784,19 @@ function isASN1ContextTag(input) {
70522
71784
  return (true);
70523
71785
  }
70524
71786
  function isASN1BitString(input) {
70525
- if (typeof input !== 'object') {
71787
+ if (!isASN1Object(input)) {
70526
71788
  return (false);
70527
71789
  }
70528
71790
  if (input.type !== 'bitstring') {
70529
71791
  return (false);
70530
71792
  }
70531
- if (!(0, helper_1.isBuffer)(input.value)) {
71793
+ if (!('value' in input) || !(0, helper_1.isBuffer)(input.value)) {
70532
71794
  return (false);
70533
71795
  }
70534
71796
  return (true);
70535
71797
  }
70536
71798
  function isASN1Date(input) {
70537
- if (typeof input !== 'object' || input === null) {
71799
+ if (!isASN1Object(input)) {
70538
71800
  return (false);
70539
71801
  }
70540
71802
  if (!('type' in input) || input.type !== 'date') {
@@ -71143,7 +72405,11 @@ class ValidateASN1 {
71143
72405
  * Given a schema, validate the ASN.1 object against it and return the
71144
72406
  * object as the validated type
71145
72407
  */
71146
- static againstSchema(input, schema) {
72408
+ static againstSchema(input, schemaIn) {
72409
+ let schema = schemaIn;
72410
+ if (typeof schema === 'function') {
72411
+ schema = schema();
72412
+ }
71147
72413
  let needsMoreAnalysis = false;
71148
72414
  if (util_1.types.isDate(input) && schema === ValidateASN1.IsDate) {
71149
72415
  /* XXX:TODO */
@@ -71397,16 +72663,36 @@ class ValidateASN1 {
71397
72663
  if (input.length < minLength || input.length > maxLength) {
71398
72664
  throw (new Error(`Expected Array length between [${minLength}, ${maxLength}], got ${input.length}`));
71399
72665
  }
71400
- // eslint-disable-next-line @typescript-eslint/consistent-type-assertions
71401
- return schema.map(function (item, i) {
71402
- /*
71403
- * We need to cast to "any" to avoid
71404
- * typing errors with TypeScript's
71405
- * validation with recursive types
71406
- */
72666
+ const output = [];
72667
+ for (let i = 0; i < schema.length; i++) {
72668
+ // If the schema is optional, we check two paths, if the value is present or not.
72669
+ // This will break the loop and leave the rest of the validation to the recursive call.
72670
+ if (typeof schema[i] === 'object' && 'optional' in schema[i]) {
72671
+ // We only need to take two paths for optional values when we are before the last value, and the value is not undefined
72672
+ if (i < schema.length - 1 && input[i] !== undefined) {
72673
+ const remainingSchema = schema.slice(i + 1);
72674
+ try {
72675
+ // Try to validate against schema assuming optional is present
72676
+ // @ts-ignore
72677
+ output.push(...ValidateASN1.againstSchema(input.slice(i), [schema[i].optional, ...remainingSchema]));
72678
+ }
72679
+ catch {
72680
+ /* ignore error because we are going to try without the optional value */
72681
+ // @ts-ignore
72682
+ output.push(undefined, ...ValidateASN1.againstSchema(input.slice(i), remainingSchema));
72683
+ }
72684
+ break;
72685
+ }
72686
+ }
71407
72687
  // @ts-ignore
71408
- return (ValidateASN1.againstSchema(input[i], item));
71409
- });
72688
+ output.push(ValidateASN1.againstSchema(input[i], schema[i]));
72689
+ }
72690
+ // If the end of the output is only optional values, exclude undefined values.
72691
+ while (output.length > 0 && output.at(-1) === undefined) {
72692
+ output.pop();
72693
+ }
72694
+ // eslint-disable-next-line @typescript-eslint/consistent-type-assertions
72695
+ return output;
71410
72696
  }
71411
72697
  else {
71412
72698
  throw (new Error(`Internal error: Unsupported schema type ${JSON.stringify(schema)}`));
@@ -71697,16 +72983,23 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
71697
72983
  };
71698
72984
  var _BufferStorage_key;
71699
72985
  Object.defineProperty(exports, "__esModule", ({ value: true }));
71700
- exports.BufferStorage = void 0;
72986
+ exports.Buffer = exports.BufferStorage = void 0;
71701
72987
  exports.DecodeBase32 = DecodeBase32;
71702
72988
  exports.EncodeBase32 = EncodeBase32;
71703
72989
  exports.DecodeBase64 = DecodeBase64;
71704
72990
  exports.EncodeBase64 = EncodeBase64;
71705
72991
  exports.ZlibInflate = ZlibInflate;
71706
72992
  exports.ZlibDeflate = ZlibDeflate;
72993
+ exports.ZlibInflateAsync = ZlibInflateAsync;
72994
+ exports.ZlibDeflateAsync = ZlibDeflateAsync;
71707
72995
  const helper_1 = __webpack_require__(3208);
71708
72996
  const rfc4648_1 = __webpack_require__(9211);
72997
+ const buffer_1 = __webpack_require__(181);
72998
+ Object.defineProperty(exports, "Buffer", ({ enumerable: true, get: function () { return buffer_1.Buffer; } }));
72999
+ const util_1 = __webpack_require__(9023);
71709
73000
  const zlib_1 = __importDefault(__webpack_require__(3106));
73001
+ const inflateAsync = (0, util_1.promisify)(zlib_1.default.inflate);
73002
+ const deflateAsync = (0, util_1.promisify)(zlib_1.default.deflate);
71710
73003
  /**
71711
73004
  * RFC 4648 Base32 Decoder
71712
73005
  */
@@ -71729,16 +73022,24 @@ function EncodeBase32(data) {
71729
73022
  }).toLowerCase());
71730
73023
  }
71731
73024
  function DecodeBase64(data) {
71732
- return ((0, helper_1.bufferToArrayBuffer)(Buffer.from(data, 'base64')));
73025
+ return ((0, helper_1.bufferToArrayBuffer)(buffer_1.Buffer.from(data, 'base64')));
71733
73026
  }
71734
73027
  function EncodeBase64(data) {
71735
- return (Buffer.from(data).toString('base64'));
73028
+ return (buffer_1.Buffer.from(data).toString('base64'));
71736
73029
  }
71737
73030
  function ZlibInflate(data, options) {
71738
- return ((0, helper_1.bufferToArrayBuffer)(zlib_1.default.inflateSync(Buffer.from(data), options)));
73031
+ return ((0, helper_1.bufferToArrayBuffer)(zlib_1.default.inflateSync(buffer_1.Buffer.from(data), options)));
71739
73032
  }
71740
73033
  function ZlibDeflate(data, options) {
71741
- return ((0, helper_1.bufferToArrayBuffer)(zlib_1.default.deflateSync(Buffer.from(data), options)));
73034
+ return ((0, helper_1.bufferToArrayBuffer)(zlib_1.default.deflateSync(buffer_1.Buffer.from(data), options)));
73035
+ }
73036
+ async function ZlibInflateAsync(data, options = {}) {
73037
+ const buffer = await inflateAsync(buffer_1.Buffer.from(data), options);
73038
+ return ((0, helper_1.bufferToArrayBuffer)(buffer));
73039
+ }
73040
+ async function ZlibDeflateAsync(data, options = {}) {
73041
+ const buffer = await deflateAsync(buffer_1.Buffer.from(data), options);
73042
+ return ((0, helper_1.bufferToArrayBuffer)(buffer));
71742
73043
  }
71743
73044
  class BufferStorage {
71744
73045
  constructor(key, length) {
@@ -71748,7 +73049,7 @@ class BufferStorage {
71748
73049
  /*
71749
73050
  * Convert from a hex-encoded string into a buffer
71750
73051
  */
71751
- const buffer_key = Buffer.from(key, 'hex');
73052
+ const buffer_key = buffer_1.Buffer.from(key, 'hex');
71752
73053
  if (buffer_key.length !== length) {
71753
73054
  throw (new Error(`When decoding buffer we got different number of bytes than expected (${buffer_key.length} expected ${length})`));
71754
73055
  }
@@ -71761,11 +73062,11 @@ class BufferStorage {
71761
73062
  }
71762
73063
  value = '0'.repeat(length * 2) + value;
71763
73064
  value = value.slice(length * 2 * -1);
71764
- __classPrivateFieldSet(this, _BufferStorage_key, Buffer.from(value, 'hex'), "f");
73065
+ __classPrivateFieldSet(this, _BufferStorage_key, buffer_1.Buffer.from(value, 'hex'), "f");
71765
73066
  }
71766
73067
  else {
71767
- if (Buffer.from(key).length !== length) {
71768
- throw (new Error(`When storing buffer we got different number of bytes than expected (${Buffer.from(key).length} expected ${length})`));
73068
+ if (buffer_1.Buffer.from(key).length !== length) {
73069
+ throw (new Error(`When storing buffer we got different number of bytes than expected (${buffer_1.Buffer.from(key).length} expected ${length})`));
71769
73070
  }
71770
73071
  __classPrivateFieldSet(this, _BufferStorage_key, key, "f");
71771
73072
  }
@@ -71777,14 +73078,14 @@ class BufferStorage {
71777
73078
  return (__classPrivateFieldGet(this, _BufferStorage_key, "f").byteLength);
71778
73079
  }
71779
73080
  getBuffer() {
71780
- return (Buffer.from(__classPrivateFieldGet(this, _BufferStorage_key, "f")));
73081
+ return (buffer_1.Buffer.from(__classPrivateFieldGet(this, _BufferStorage_key, "f")));
71781
73082
  }
71782
73083
  toString(encoding = 'hex') {
71783
73084
  switch (encoding) {
71784
73085
  case 'hex':
71785
- return (Buffer.from(__classPrivateFieldGet(this, _BufferStorage_key, "f")).toString(encoding).toUpperCase());
73086
+ return (buffer_1.Buffer.from(__classPrivateFieldGet(this, _BufferStorage_key, "f")).toString(encoding).toUpperCase());
71786
73087
  case 'base64':
71787
- return (Buffer.from(__classPrivateFieldGet(this, _BufferStorage_key, "f")).toString(encoding));
73088
+ return (buffer_1.Buffer.from(__classPrivateFieldGet(this, _BufferStorage_key, "f")).toString(encoding));
71788
73089
  case 'base32':
71789
73090
  return (EncodeBase32(__classPrivateFieldGet(this, _BufferStorage_key, "f")));
71790
73091
  default:
@@ -71809,11 +73110,11 @@ class BufferStorage {
71809
73110
  return (false);
71810
73111
  }
71811
73112
  if (typeof compareWith === 'string') {
71812
- const asBuf = Buffer.from(compareWith, 'hex');
73113
+ const asBuf = buffer_1.Buffer.from(compareWith, 'hex');
71813
73114
  if (asBuf.length !== this.length) {
71814
73115
  return (false);
71815
73116
  }
71816
- compareWith = new BufferStorage(Buffer.from(compareWith, 'hex'), this.length);
73117
+ compareWith = new BufferStorage(buffer_1.Buffer.from(compareWith, 'hex'), this.length);
71817
73118
  }
71818
73119
  return (this.toString('hex') === compareWith.toString('hex'));
71819
73120
  }
@@ -71867,9 +73168,9 @@ var __classPrivateFieldGet = (this && this.__classPrivateFieldGet) || function (
71867
73168
  var __importDefault = (this && this.__importDefault) || function (mod) {
71868
73169
  return (mod && mod.__esModule) ? mod : { "default": mod };
71869
73170
  };
71870
- var _CertificateBuilder_params, _Certificate_instances, _Certificate_raw, _Certificate_hash, _Certificate_extensionsRaw, _Certificate_extensionsProcessed, _Certificate_finalizeConstructionCalled, _Certificate_processExtensionsInternal, _Certificate_processBaseExtensions, _Certificate_processBaseExtension, _Certificate_assertAllCriticalExtensionsProcessed, _Certificate_checkValid, _Certificate_checkIssued, _CertificateBundle_raw, _CertificateBundle_contents;
73171
+ var _CertificateBuilder_params, _CertificateBundle_raw, _CertificateBundle_contents, _Certificate_instances, _Certificate_raw, _Certificate_hash, _Certificate_extensionsRaw, _Certificate_extensionsProcessed, _Certificate_finalizeConstructionCalled, _Certificate_processExtensionsInternal, _Certificate_processBaseExtensions, _Certificate_processBaseExtension, _Certificate_assertAllCriticalExtensionsProcessed, _Certificate_checkValid, _Certificate_checkIssued;
71871
73172
  Object.defineProperty(exports, "__esModule", ({ value: true }));
71872
- exports.CertificateBundle = exports.Certificate = exports.CertificateHash = exports.CertificateBuilder = void 0;
73173
+ exports.Certificate = exports.CertificateBundle = exports.CertificateHash = exports.CertificateBuilder = void 0;
71873
73174
  const ASN1 = __importStar(__webpack_require__(6045));
71874
73175
  const account_1 = __importStar(__webpack_require__(9415));
71875
73176
  const never_1 = __webpack_require__(8692);
@@ -72001,17 +73302,45 @@ function fromDNSequenceToString(dn) {
72001
73302
  const retval = parts.join(', ');
72002
73303
  return (retval);
72003
73304
  }
73305
+ const defaultHashName = HashLib.HashFunctionName;
72004
73306
  class CertificateBuilder {
72005
73307
  constructor(params) {
72006
73308
  _CertificateBuilder_params.set(this, void 0);
72007
73309
  __classPrivateFieldSet(this, _CertificateBuilder_params, {
72008
- hashLib: {
72009
- hash: HashLib.Hash,
72010
- name: HashLib.HashFunctionName
72011
- },
72012
73310
  ...params
72013
73311
  }, "f");
72014
73312
  }
73313
+ static hashName(params, purpose) {
73314
+ const hashLib = params.hashLib;
73315
+ if (hashLib !== undefined) {
73316
+ switch (hashLib.name) {
73317
+ case 'sha256':
73318
+ case 'sha3-256':
73319
+ return (hashLib.name);
73320
+ default:
73321
+ throw (new Error(`Unsupported hash algorithm "${hashLib.name}"`));
73322
+ }
73323
+ }
73324
+ const hashName = params.hashParams?.defaults?.[purpose] ?? defaultHashName;
73325
+ return (hashName);
73326
+ }
73327
+ static hash(params, purpose, ...data) {
73328
+ /*
73329
+ * If the deprecated hashLib parameter is set, then use it
73330
+ * regardless of the algo parameter for backwards compatibility
73331
+ * even though it is not recommended to use it anymore
73332
+ */
73333
+ const hashLib = params.hashLib;
73334
+ if (hashLib !== undefined) {
73335
+ return (hashLib.hash(...data));
73336
+ }
73337
+ const hashName = this.hashName(params, purpose);
73338
+ const hashFunction = params.hashParams.functions?.[hashName];
73339
+ if (hashFunction === undefined) {
73340
+ throw (new Error(`Hash function "${hashName}" not found for purpose "${purpose}"`));
73341
+ }
73342
+ return (hashFunction(...data));
73343
+ }
72015
73344
  /**
72016
73345
  * Construct an extension
72017
73346
  */
@@ -72030,12 +73359,8 @@ class CertificateBuilder {
72030
73359
  /**
72031
73360
  * Convert a KeetaNet Account to a Key ID (for Subject Key Identifier)
72032
73361
  */
72033
- accountToKeyId(account) {
72034
- const hashLib = __classPrivateFieldGet(this, _CertificateBuilder_params, "f").hashLib;
72035
- if (hashLib === undefined) {
72036
- throw (new Error('"hashLib" not set'));
72037
- }
72038
- return (Buffer.from(hashLib.hash(Buffer.concat([
73362
+ accountToKeyId(params, account, purpose) {
73363
+ return (Buffer.from(CertificateBuilder.hash(params, purpose, Buffer.concat([
72039
73364
  Buffer.from('KeetaKey', 'utf-8'),
72040
73365
  account.publicKeyAndType
72041
73366
  ]), 20)));
@@ -72099,10 +73424,11 @@ class CertificateBuilder {
72099
73424
  extensions.push(
72100
73425
  /** Extension: Authority Key Identifier */
72101
73426
  CertificateBuilder.extension('2.5.29.35', [
72102
- { type: 'context', value: 0, kind: 'implicit', contains: this.accountToKeyId(params.issuer) }
73427
+ /** XXX:TODO: Copy the key ID from the issuer certificate's Subject Key Identifier if known */
73428
+ { type: 'context', value: 0, kind: 'implicit', contains: this.accountToKeyId(params, params.issuer, 'aki') }
72103
73429
  ]),
72104
73430
  /** Extension: Subject Key Identifier */
72105
- CertificateBuilder.extension('2.5.29.14', this.accountToKeyId(params.subjectPublicKey)));
73431
+ CertificateBuilder.extension('2.5.29.14', this.accountToKeyId(params, params.subjectPublicKey, 'ski')));
72106
73432
  return (extensions);
72107
73433
  }
72108
73434
  /**
@@ -72111,7 +73437,26 @@ class CertificateBuilder {
72111
73437
  getFinalParams(params) {
72112
73438
  const finalParams = {
72113
73439
  ...__classPrivateFieldGet(this, _CertificateBuilder_params, "f"),
72114
- ...params
73440
+ ...params,
73441
+ hashParams: {
73442
+ ...__classPrivateFieldGet(this, _CertificateBuilder_params, "f")?.hashParams,
73443
+ ...params?.hashParams,
73444
+ functions: {
73445
+ 'sha256': function (data, len) {
73446
+ throw (new Error('not implemented, please provide an implementation'));
73447
+ },
73448
+ [defaultHashName]: HashLib.Hash,
73449
+ ...__classPrivateFieldGet(this, _CertificateBuilder_params, "f")?.hashParams?.functions,
73450
+ ...params?.hashParams?.functions
73451
+ },
73452
+ defaults: {
73453
+ signature: defaultHashName,
73454
+ ski: defaultHashName,
73455
+ aki: defaultHashName,
73456
+ ...__classPrivateFieldGet(this, _CertificateBuilder_params, "f")?.hashParams?.defaults,
73457
+ ...params?.hashParams?.defaults
73458
+ }
73459
+ }
72115
73460
  };
72116
73461
  /* Validate that required parameters are set */
72117
73462
  const issuer = finalParams.issuer;
@@ -72135,8 +73480,9 @@ class CertificateBuilder {
72135
73480
  throw (new Error('"serialNumber" not set'));
72136
73481
  }
72137
73482
  const hashLib = finalParams.hashLib;
72138
- if (hashLib === undefined) {
72139
- throw (new Error('"hashLib" not set'));
73483
+ const hashParams = finalParams.hashParams;
73484
+ if (hashParams === undefined) {
73485
+ throw (new Error('"hashParams" not set'));
72140
73486
  }
72141
73487
  return ({
72142
73488
  ...finalParams,
@@ -72145,7 +73491,8 @@ class CertificateBuilder {
72145
73491
  validFrom,
72146
73492
  validTo,
72147
73493
  serial,
72148
- hashLib
73494
+ hashLib,
73495
+ hashParams
72149
73496
  });
72150
73497
  }
72151
73498
  /**
@@ -72153,13 +73500,13 @@ class CertificateBuilder {
72153
73500
  */
72154
73501
  async buildDER(params) {
72155
73502
  const finalParams = this.getFinalParams(params);
72156
- const hashLib = finalParams.hashLib;
72157
73503
  const { oid: signatureAlgorithmOID, hashData: hashData } = (function () {
73504
+ const hashName = CertificateBuilder.hashName(finalParams, 'signature');
72158
73505
  switch (finalParams.issuer.keyType) {
72159
73506
  case account_1.AccountKeyAlgorithm.ECDSA_SECP256K1:
72160
73507
  case account_1.AccountKeyAlgorithm.ECDSA_SECP256R1:
72161
73508
  return ({
72162
- oid: `${hashLib.name}WithEcDSA`,
73509
+ oid: `${hashName}WithEcDSA`,
72163
73510
  hashData: true
72164
73511
  });
72165
73512
  case account_1.AccountKeyAlgorithm.ED25519:
@@ -72227,7 +73574,7 @@ class CertificateBuilder {
72227
73574
  */
72228
73575
  let toSign;
72229
73576
  if (hashData) {
72230
- toSign = Buffer.from(hashLib.hash(tbsCertificateBuffer));
73577
+ toSign = Buffer.from(CertificateBuilder.hash(finalParams, 'signature', tbsCertificateBuffer));
72231
73578
  }
72232
73579
  else {
72233
73580
  toSign = tbsCertificateBuffer;
@@ -72261,37 +73608,115 @@ class CertificateBuilder {
72261
73608
  ...options
72262
73609
  }));
72263
73610
  }
72264
- }
72265
- exports.CertificateBuilder = CertificateBuilder;
72266
- _CertificateBuilder_params = new WeakMap();
72267
- /**
72268
- * Certificate hash
72269
- */
72270
- class CertificateHash extends buffer_1.BufferStorage {
72271
- get hashFunctionName() {
72272
- return (HashLib.Hash.functionName);
73611
+ }
73612
+ exports.CertificateBuilder = CertificateBuilder;
73613
+ _CertificateBuilder_params = new WeakMap();
73614
+ /**
73615
+ * Certificate hash
73616
+ */
73617
+ class CertificateHash extends buffer_1.BufferStorage {
73618
+ get hashFunctionName() {
73619
+ return (HashLib.Hash.functionName);
73620
+ }
73621
+ constructor(certificateHash) {
73622
+ super(certificateHash, 32);
73623
+ }
73624
+ static fromData(data) {
73625
+ return (new this(HashLib.Hash(data)));
73626
+ }
73627
+ toJSON() {
73628
+ return (this.toString());
73629
+ }
73630
+ toString() {
73631
+ // eslint-disable-next-line @typescript-eslint/consistent-type-assertions
73632
+ return super.toString('hex');
73633
+ }
73634
+ }
73635
+ exports.CertificateHash = CertificateHash;
73636
+ CertificateHash.isInstance = (0, helper_1.checkableGenerator)(CertificateHash);
73637
+ CertificateHash.Set = (0, helper_1.setGenerator)(CertificateHash, function (value) {
73638
+ return (value.toString());
73639
+ }, function (value) {
73640
+ return (new CertificateHash(Buffer.from(value, 'hex')));
73641
+ });
73642
+ const CertificateBundleSchemaInternal = {
73643
+ sequenceOf: CertificateSchemaInternal
73644
+ };
73645
+ class CertificateBundle {
73646
+ constructor(input) {
73647
+ _CertificateBundle_raw.set(this, void 0);
73648
+ _CertificateBundle_contents.set(this, void 0);
73649
+ if (CertificateBundle.isInstance(input)) {
73650
+ __classPrivateFieldSet(this, _CertificateBundle_raw, input.getDER(), "f");
73651
+ }
73652
+ else if (Array.isArray(input) || input instanceof Set) {
73653
+ if (input instanceof Set) {
73654
+ input = Array.from(input);
73655
+ }
73656
+ const decodedInput = input.map(function (certificate) {
73657
+ let decoded;
73658
+ // eslint-disable-next-line @typescript-eslint/no-use-before-define
73659
+ if (Certificate.isCertificate(certificate)) {
73660
+ decoded = new ASN1.BufferStorageASN1(certificate.toDER());
73661
+ }
73662
+ else {
73663
+ // eslint-disable-next-line @typescript-eslint/no-use-before-define
73664
+ decoded = new ASN1.BufferStorageASN1(new Certificate(certificate).toDER());
73665
+ }
73666
+ // For some reason the typescript compiler cannot understand this, but we do not care about it being typed because we are validating it right after.
73667
+ // @ts-ignore
73668
+ const output = decoded.getASN1();
73669
+ return (output);
73670
+ });
73671
+ __classPrivateFieldSet(this, _CertificateBundle_raw, new ASN1.BufferStorageASN1(decodedInput, CertificateBundleSchemaInternal).getDER(), "f");
73672
+ }
73673
+ else {
73674
+ if (typeof input === 'string') {
73675
+ input = Buffer.from(input, 'base64');
73676
+ }
73677
+ if (Buffer.isBuffer(input)) {
73678
+ input = (0, helper_1.bufferToArrayBuffer)(input);
73679
+ }
73680
+ __classPrivateFieldSet(this, _CertificateBundle_raw, input, "f");
73681
+ }
73682
+ const decoded = new ASN1.BufferStorageASN1(__classPrivateFieldGet(this, _CertificateBundle_raw, "f"), CertificateBundleSchemaInternal);
73683
+ __classPrivateFieldSet(this, _CertificateBundle_contents, [], "f");
73684
+ const seenHashes = new CertificateHash.Set();
73685
+ for (const item of decoded.getASN1()) {
73686
+ const certificateValue = new ASN1.BufferStorageASN1(item, CertificateSchemaInternal);
73687
+ // eslint-disable-next-line @typescript-eslint/no-use-before-define
73688
+ const certificate = new Certificate(certificateValue.getDER());
73689
+ const hash = certificate.hash();
73690
+ if (seenHashes.has(hash)) {
73691
+ throw (new certificate_1.default('CERTIFICATE_DUPLICATE_INCLUDED', `Duplicate certificate ${hash} within certificate bundle`));
73692
+ }
73693
+ seenHashes.add(hash);
73694
+ __classPrivateFieldGet(this, _CertificateBundle_contents, "f").push(certificate);
73695
+ }
73696
+ }
73697
+ get bundleSize() {
73698
+ return (__classPrivateFieldGet(this, _CertificateBundle_contents, "f").length);
72273
73699
  }
72274
- constructor(certificateHash) {
72275
- super(certificateHash, 32);
73700
+ getDER() {
73701
+ return (__classPrivateFieldGet(this, _CertificateBundle_raw, "f"));
72276
73702
  }
72277
- static fromData(data) {
72278
- return (new this(HashLib.Hash(data)));
73703
+ getDERBuffer() {
73704
+ return (Buffer.from(this.getDER()));
72279
73705
  }
72280
- toJSON() {
72281
- return (this.toString());
73706
+ getCertificates() {
73707
+ return (__classPrivateFieldGet(this, _CertificateBundle_contents, "f"));
72282
73708
  }
72283
- toString() {
72284
- // eslint-disable-next-line @typescript-eslint/consistent-type-assertions
72285
- return super.toString('hex');
73709
+ toJSON() {
73710
+ return ({
73711
+ certificates: this.getCertificates().map(function (certificate) {
73712
+ return (certificate.toPEM());
73713
+ })
73714
+ });
72286
73715
  }
72287
73716
  }
72288
- exports.CertificateHash = CertificateHash;
72289
- CertificateHash.isInstance = (0, helper_1.checkableGenerator)(CertificateHash);
72290
- CertificateHash.Set = (0, helper_1.setGenerator)(CertificateHash, function (value) {
72291
- return (value.toString());
72292
- }, function (value) {
72293
- return (new CertificateHash(Buffer.from(value, 'hex')));
72294
- });
73717
+ exports.CertificateBundle = CertificateBundle;
73718
+ _CertificateBundle_raw = new WeakMap(), _CertificateBundle_contents = new WeakMap();
73719
+ CertificateBundle.isInstance = (0, helper_1.checkableGenerator)(CertificateBundle);
72295
73720
  class Certificate {
72296
73721
  /**
72297
73722
  * Is a certificate object?
@@ -72400,8 +73825,10 @@ class Certificate {
72400
73825
  this.notAfter = notAfter.date;
72401
73826
  this.subject = fromDNSequenceToString(subject);
72402
73827
  this.issuer = fromDNSequenceToString(issuer);
72403
- this.subjectDN = subject;
72404
- this.issuerDN = issuer;
73828
+ this.subjectDN = fromDNSequence(subject);
73829
+ this.issuerDN = fromDNSequence(issuer);
73830
+ this.subjectDNSet = subject;
73831
+ this.issuerDNSet = issuer;
72405
73832
  /*
72406
73833
  * Compare the signature algorithm in the certificate with
72407
73834
  * the signature algorithm in the signature
@@ -72738,6 +74165,18 @@ class Certificate {
72738
74165
  }
72739
74166
  return (issuerCert.subjectPublicKey);
72740
74167
  }
74168
+ /**
74169
+ * Get the extensions present in the certificate -- this is the raw
74170
+ * extensions as they were parsed from the certificate, and may
74171
+ * contain extensions that are not processed by this class.
74172
+ */
74173
+ getExtensions() {
74174
+ this.assertConstructed();
74175
+ if (__classPrivateFieldGet(this, _Certificate_extensionsRaw, "f") === undefined) {
74176
+ return (undefined);
74177
+ }
74178
+ return (__classPrivateFieldGet(this, _Certificate_extensionsRaw, "f"));
74179
+ }
72741
74180
  assertConstructed() {
72742
74181
  if (!__classPrivateFieldGet(this, _Certificate_finalizeConstructionCalled, "f")) {
72743
74182
  throw (new Error('finalizeConstruction not called'));
@@ -72785,6 +74224,16 @@ class Certificate {
72785
74224
  ].join('\n') + '\n';
72786
74225
  return (certificatePEM);
72787
74226
  }
74227
+ /**
74228
+ * The string representation of the certificate
74229
+ * is a PEM encoded certificate -- this misses
74230
+ * some of the internal details like chain
74231
+ * and verified, but is usually what someone
74232
+ * wants to see when they call toString()
74233
+ */
74234
+ toString() {
74235
+ return (this.toPEM());
74236
+ }
72788
74237
  /**
72789
74238
  * Compute a hash of the certificate
72790
74239
  */
@@ -72818,8 +74267,8 @@ class Certificate {
72818
74267
  issuer: this.issuer,
72819
74268
  subjectPublicKey: this.subjectPublicKey,
72820
74269
  baseExtensions: this.baseExtensions,
72821
- subjectDN: fromDNSequence(this.subjectDN),
72822
- issuerDN: fromDNSequence(this.issuerDN),
74270
+ subjectDN: fromDNSequence(this.subjectDNSet),
74271
+ issuerDN: fromDNSequence(this.issuerDNSet),
72823
74272
  $hash: this.hash(),
72824
74273
  ...additionalFields
72825
74274
  });
@@ -72945,8 +74394,8 @@ _Certificate_raw = new WeakMap(), _Certificate_hash = new WeakMap(), _Certificat
72945
74394
  /**
72946
74395
  * Compare the issuerDN and the subjectDN byte-for-byte
72947
74396
  */
72948
- const issuerDN = new ASN1.BufferStorageASN1(issuer.subjectDN);
72949
- const subjectIssuerDN = new ASN1.BufferStorageASN1(this.issuerDN);
74397
+ const issuerDN = new ASN1.BufferStorageASN1(issuer.subjectDNSet);
74398
+ const subjectIssuerDN = new ASN1.BufferStorageASN1(this.issuerDNSet);
72950
74399
  const issuerDER = issuerDN.getDERBuffer();
72951
74400
  const subjectIssuerDER = subjectIssuerDN.getDERBuffer();
72952
74401
  if (!issuerDER.equals(subjectIssuerDER)) {
@@ -72997,85 +74446,18 @@ _Certificate_raw = new WeakMap(), _Certificate_hash = new WeakMap(), _Certificat
72997
74446
  * The Certificate Builder
72998
74447
  */
72999
74448
  Certificate.Builder = CertificateBuilder;
74449
+ /**
74450
+ * The certificate bundle
74451
+ */
74452
+ Certificate.Bundle = CertificateBundle;
74453
+ /**
74454
+ * The certificate hash information
74455
+ */
74456
+ Certificate.Hash = CertificateHash;
73000
74457
  /**
73001
74458
  * Object type ID for {@link Certificate.isCertificate}
73002
74459
  */
73003
74460
  Certificate.certificateObjectTypeID = '8d05dca5-5f42-4dc9-8bf9-f534c6570994:CERTIFICATE';
73004
- const CertificateBundleSchemaInternal = {
73005
- sequenceOf: CertificateSchemaInternal
73006
- };
73007
- class CertificateBundle {
73008
- constructor(input) {
73009
- _CertificateBundle_raw.set(this, void 0);
73010
- _CertificateBundle_contents.set(this, void 0);
73011
- if (CertificateBundle.isInstance(input)) {
73012
- __classPrivateFieldSet(this, _CertificateBundle_raw, input.getDER(), "f");
73013
- }
73014
- else if (Array.isArray(input) || input instanceof Set) {
73015
- if (input instanceof Set) {
73016
- input = Array.from(input);
73017
- }
73018
- const decodedInput = input.map(function (certificate) {
73019
- let decoded;
73020
- if (Certificate.isCertificate(certificate)) {
73021
- decoded = new ASN1.BufferStorageASN1(certificate.toDER());
73022
- }
73023
- else {
73024
- decoded = new ASN1.BufferStorageASN1(new Certificate(certificate).toDER());
73025
- }
73026
- // For some reason the typescript compiler cannot understand this, but we do not care about it being typed because we are validating it right after.
73027
- // @ts-ignore
73028
- const output = decoded.getASN1();
73029
- return (output);
73030
- });
73031
- __classPrivateFieldSet(this, _CertificateBundle_raw, new ASN1.BufferStorageASN1(decodedInput, CertificateBundleSchemaInternal).getDER(), "f");
73032
- }
73033
- else {
73034
- if (typeof input === 'string') {
73035
- input = Buffer.from(input, 'base64');
73036
- }
73037
- if (Buffer.isBuffer(input)) {
73038
- input = (0, helper_1.bufferToArrayBuffer)(input);
73039
- }
73040
- __classPrivateFieldSet(this, _CertificateBundle_raw, input, "f");
73041
- }
73042
- const decoded = new ASN1.BufferStorageASN1(__classPrivateFieldGet(this, _CertificateBundle_raw, "f"), CertificateBundleSchemaInternal);
73043
- __classPrivateFieldSet(this, _CertificateBundle_contents, [], "f");
73044
- const seenHashes = new CertificateHash.Set();
73045
- for (const item of decoded.getASN1()) {
73046
- const certificateValue = new ASN1.BufferStorageASN1(item, CertificateSchemaInternal);
73047
- const certificate = new Certificate(certificateValue.getDER());
73048
- const hash = certificate.hash();
73049
- if (seenHashes.has(hash)) {
73050
- throw (new certificate_1.default('CERTIFICATE_DUPLICATE_INCLUDED', `Duplicate certificate ${hash} within certificate bundle`));
73051
- }
73052
- seenHashes.add(hash);
73053
- __classPrivateFieldGet(this, _CertificateBundle_contents, "f").push(certificate);
73054
- }
73055
- }
73056
- get bundleSize() {
73057
- return (__classPrivateFieldGet(this, _CertificateBundle_contents, "f").length);
73058
- }
73059
- getDER() {
73060
- return (__classPrivateFieldGet(this, _CertificateBundle_raw, "f"));
73061
- }
73062
- getDERBuffer() {
73063
- return (Buffer.from(this.getDER()));
73064
- }
73065
- getCertificates() {
73066
- return (__classPrivateFieldGet(this, _CertificateBundle_contents, "f"));
73067
- }
73068
- toJSON() {
73069
- return ({
73070
- certificates: this.getCertificates().map(function (certificate) {
73071
- return (certificate.toPEM());
73072
- })
73073
- });
73074
- }
73075
- }
73076
- exports.CertificateBundle = CertificateBundle;
73077
- _CertificateBundle_raw = new WeakMap(), _CertificateBundle_contents = new WeakMap();
73078
- CertificateBundle.isInstance = (0, helper_1.checkableGenerator)(CertificateBundle);
73079
74461
 
73080
74462
 
73081
74463
  /***/ }),
@@ -73620,6 +75002,29 @@ Hash.functionLength = exports.HashFunctionLength;
73620
75002
 
73621
75003
  "use strict";
73622
75004
 
75005
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
75006
+ if (k2 === undefined) k2 = k;
75007
+ var desc = Object.getOwnPropertyDescriptor(m, k);
75008
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
75009
+ desc = { enumerable: true, get: function() { return m[k]; } };
75010
+ }
75011
+ Object.defineProperty(o, k2, desc);
75012
+ }) : (function(o, m, k, k2) {
75013
+ if (k2 === undefined) k2 = k;
75014
+ o[k2] = m[k];
75015
+ }));
75016
+ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
75017
+ Object.defineProperty(o, "default", { enumerable: true, value: v });
75018
+ }) : function(o, v) {
75019
+ o["default"] = v;
75020
+ });
75021
+ var __importStar = (this && this.__importStar) || function (mod) {
75022
+ if (mod && mod.__esModule) return mod;
75023
+ var result = {};
75024
+ if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
75025
+ __setModuleDefault(result, mod);
75026
+ return result;
75027
+ };
73623
75028
  var __classPrivateFieldGet = (this && this.__classPrivateFieldGet) || function (receiver, state, kind, f) {
73624
75029
  if (kind === "a" && !f) throw new TypeError("Private accessor was defined without a getter");
73625
75030
  if (typeof state === "function" ? receiver !== state || !f : !state.has(receiver)) throw new TypeError("Cannot read private member from an object whose class did not declare it");
@@ -73636,8 +75041,9 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
73636
75041
  };
73637
75042
  var _AsyncDisposableStackPolyfill_instances, _AsyncDisposableStackPolyfill_toDispose, _AsyncDisposableStackPolyfill_validateNotDisposed, _a;
73638
75043
  Object.defineProperty(exports, "__esModule", ({ value: true }));
73639
- exports.AsyncDisposableStack = void 0;
75044
+ exports.crypto = exports.AsyncDisposableStack = void 0;
73640
75045
  exports.bufferToArrayBuffer = bufferToArrayBuffer;
75046
+ exports.bufferToBigInt = bufferToBigInt;
73641
75047
  exports.isIntegerOrBigInt = isIntegerOrBigInt;
73642
75048
  exports.isBuffer = isBuffer;
73643
75049
  exports.arrayRepeat = arrayRepeat;
@@ -73657,9 +75063,14 @@ exports.setGenerator = setGenerator;
73657
75063
  const crypto_1 = __importDefault(__webpack_require__(6982));
73658
75064
  const util_1 = __webpack_require__(9023);
73659
75065
  const hash_1 = __webpack_require__(7908);
75066
+ const uuid = __importStar(__webpack_require__(5827));
73660
75067
  const loggingLevels = ['debug', 'error'];
73661
75068
  const configuredLoggingLevel = process.env['KEETANET_DEBUG']?.toLowerCase();
73662
75069
  const configuredLoggingFilter = new RegExp(process.env['KEETANET_DEBUG_FILTER'] ?? '', 'i');
75070
+ const randomBytes = crypto_1.default.randomBytes.bind(crypto_1.default);
75071
+ const randomUUID = crypto_1.default.randomUUID ? crypto_1.default.randomUUID.bind(crypto_1.default) : function () {
75072
+ return (uuid.v4());
75073
+ };
73663
75074
  function bufferToArrayBuffer(input) {
73664
75075
  const out = new ArrayBuffer(input.length);
73665
75076
  const view = new Uint8Array(out);
@@ -73668,6 +75079,13 @@ function bufferToArrayBuffer(input) {
73668
75079
  }
73669
75080
  return (out);
73670
75081
  }
75082
+ function bufferToBigInt(buffer) {
75083
+ let result = 0n;
75084
+ for (const byte of buffer) {
75085
+ result = (result << 8n) + BigInt(byte);
75086
+ }
75087
+ return (result);
75088
+ }
73671
75089
  /**
73672
75090
  * Check if a value is an integer or a bigint.
73673
75091
  */
@@ -73741,7 +75159,7 @@ function randomString(requestedLength = 32) {
73741
75159
  bytesToGen = 1;
73742
75160
  }
73743
75161
  // Generate bytes and convert to hex string
73744
- let generated = crypto_1.default.randomBytes(bytesToGen).toString('hex');
75162
+ let generated = randomBytes(bytesToGen).toString('hex');
73745
75163
  // If you requested an odd length, remove last character
73746
75164
  // This is one byte is 2 characters, so we cannot directly generate odd lengths
73747
75165
  if (requestedLength % 2 === 1) {
@@ -74027,7 +75445,11 @@ function setGenerator(parent, rawEncode, rawDecode) {
74027
75445
  _map.set(this, void 0);
74028
75446
  this[_b] = `${parent.name}Set`;
74029
75447
  __classPrivateFieldSet(this, _map, new Map(), "f");
74030
- __classPrivateFieldSet(this, _set, new Set(data.map(item => encode(item, __classPrivateFieldGet(this, _map, "f")))), "f");
75448
+ __classPrivateFieldSet(this, _set, new Set, "f");
75449
+ // Use a loop since data could be an Iterable not always an array
75450
+ for (const item of data) {
75451
+ __classPrivateFieldGet(this, _set, "f").add(encode(item, __classPrivateFieldGet(this, _map, "f")));
75452
+ }
74031
75453
  }
74032
75454
  // Fit with new JS spec
74033
75455
  // https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Set/isSubsetOf
@@ -74134,6 +75556,12 @@ function setGenerator(parent, rawEncode, rawDecode) {
74134
75556
  }
74135
75557
  });
74136
75558
  }
75559
+ exports.crypto = {
75560
+ randomUUID: randomUUID,
75561
+ randomBytes: randomBytes,
75562
+ createCipheriv: crypto_1.default.createCipheriv.bind(crypto_1.default),
75563
+ createDecipheriv: crypto_1.default.createDecipheriv.bind(crypto_1.default)
75564
+ };
74137
75565
 
74138
75566
 
74139
75567
  /***/ }),
@@ -74239,7 +75667,7 @@ async function generateInitialVoteStaple(options) {
74239
75667
  blocks.recipientSupply = blocks.recipient;
74240
75668
  blocks.recipient = await new block_1.default.Builder({
74241
75669
  network: network,
74242
- signer: recipient,
75670
+ account: recipient,
74243
75671
  previous: getPrevious(recipient),
74244
75672
  operations: [{
74245
75673
  type: block_1.default.OperationType.SET_REP,
@@ -74343,9 +75771,9 @@ var __classPrivateFieldGet = (this && this.__classPrivateFieldGet) || function (
74343
75771
  var __importDefault = (this && this.__importDefault) || function (mod) {
74344
75772
  return (mod && mod.__esModule) ? mod : { "default": mod };
74345
75773
  };
74346
- var _VoteBlockHashMap_instances, _VoteBlockHashMap_valueMap, _VoteBlockHashMap_keyMap, _VoteBlockHashMap_getLookupKey, _a, _PossiblyExpiredVote_vote, _PossiblyExpiredVote_options, _PossiblyExpiredVote__hash, _PossiblyExpiredVote__blocksHash, _VoteBlockBundle_value, _VoteBlockBundle_valueCompressed, _VoteBlockBundle__hash, _VoteBlockBundle__blocksHash, _VoteBuilder_account, _VoteBuilder_blocks;
75774
+ var _VoteBlockHashMap_instances, _VoteBlockHashMap_valueMap, _VoteBlockHashMap_keyMap, _VoteBlockHashMap_getLookupKey, _a, _VoteLikeBase_vote, _VoteLikeBase_options, _VoteLikeBase__hash, _VoteLikeBase__blocksHash, _VoteBlockBundle_value, _VoteBlockBundle_valueCompressed, _VoteBlockBundle__hash, _VoteBlockBundle__blocksHash, _BaseVoteBuilder_account, _BaseVoteBuilder_blocks, _BaseVoteBuilder_fee;
74347
75775
  Object.defineProperty(exports, "__esModule", ({ value: true }));
74348
- exports.Testing = exports.VoteBuilder = exports.VoteStaple = exports.VoteBlockBundle = exports.Vote = exports.PossiblyExpiredVote = exports.VoteBlockHash = exports.VoteBlockHashMap = void 0;
75776
+ exports.Testing = exports.VoteQuoteBuilder = exports.VoteBuilder = exports.BaseVoteBuilder = exports.VoteStaple = exports.VoteBlockBundle = exports.VoteQuote = exports.Vote = exports.PossiblyExpiredVote = exports.VoteBlockHash = exports.VoteBlockHashMap = void 0;
74349
75777
  const block_1 = __webpack_require__(6158);
74350
75778
  const hash_1 = __webpack_require__(7908);
74351
75779
  const account_1 = __importStar(__webpack_require__(9415));
@@ -74362,6 +75790,17 @@ class VoteHash extends buffer_1.BufferStorage {
74362
75790
  }
74363
75791
  }
74364
75792
  VoteHash.isInstance = (0, helper_1.checkableGenerator)(VoteHash);
75793
+ const feeExtensionSchema = {
75794
+ type: 'context',
75795
+ value: 0,
75796
+ kind: 'explicit',
75797
+ contains: [
75798
+ asn1_1.ValidateASN1.IsBoolean,
75799
+ asn1_1.ValidateASN1.IsInteger,
75800
+ { optional: { type: 'context', value: 0, kind: 'implicit', contains: asn1_1.ValidateASN1.IsOctetString } },
75801
+ { optional: { type: 'context', value: 1, kind: 'implicit', contains: asn1_1.ValidateASN1.IsOctetString } }
75802
+ ]
75803
+ };
74365
75804
  /**
74366
75805
  * Parse a set of distinguished names
74367
75806
  */
@@ -74402,14 +75841,8 @@ function findRDN(input, findOID) {
74402
75841
  }
74403
75842
  function blockHashesFromVote(input) {
74404
75843
  const blockHashInformation = (0, asn1_1.ASN1toJS)(input.buffer);
74405
- if (blockHashInformation === undefined || blockHashInformation === null) {
74406
- throw (new vote_1.default('VOTE_MALFORMED_HASHES_FROM_VOTE_INVALID_INPUT', 'internal error: hashData extension contains Null or unknown tag'));
74407
- }
74408
- if (typeof blockHashInformation === 'bigint' || typeof blockHashInformation !== 'object') {
74409
- throw (new vote_1.default('VOTE_MALFORMED_HASHES_FROM_VOTE_INVALID_INPUT', 'internal error: hashData extension contains bigint or non object value'));
74410
- }
74411
- if (Buffer.isBuffer(blockHashInformation) || util_1.types.isDate(blockHashInformation) || Array.isArray(blockHashInformation)) {
74412
- throw (new vote_1.default('VOTE_MALFORMED_HASHES_FROM_VOTE_INVALID_INPUT', 'internal error: hashData extension contains incorrect data type'));
75844
+ if (!(0, asn1_1.isASN1Object)(blockHashInformation)) {
75845
+ throw (new vote_1.default('VOTE_MALFORMED_HASHES_FROM_VOTE_INVALID_INPUT', 'internal error: hashData extensions is not valid asn1 object'));
74413
75846
  }
74414
75847
  if (blockHashInformation.type !== 'context') {
74415
75848
  throw (new vote_1.default('VOTE_MALFORMED_HASHES_FROM_VOTE_INVALID_TYPE', 'internal error: hashData extension does not contain a context-specific tag'));
@@ -74447,6 +75880,54 @@ function blockHashesFromVote(input) {
74447
75880
  }
74448
75881
  return (output);
74449
75882
  }
75883
+ function feeFromVote(input) {
75884
+ const feeInformationAnyJS = (0, asn1_1.ASN1toJS)(input.buffer);
75885
+ const feeSchemaChecker = new asn1_1.ValidateASN1(feeExtensionSchema);
75886
+ const feeInformation = (function () {
75887
+ try {
75888
+ return (feeSchemaChecker.validate(feeInformationAnyJS));
75889
+ }
75890
+ catch (asn1ValidateError) {
75891
+ let message = 'internal error: fee asn1 schema is not the right format';
75892
+ if (asn1ValidateError instanceof Error) {
75893
+ message = `${message}: ${asn1ValidateError.message}`;
75894
+ }
75895
+ throw (new vote_1.default('VOTE_MALFORMED_FEES_FROM_VOTE_INVALID_INPUT', message));
75896
+ }
75897
+ })();
75898
+ const feeData = feeInformation.contains;
75899
+ const quote = feeData[0];
75900
+ const retval = {
75901
+ quote: quote,
75902
+ fee: {
75903
+ amount: feeData[1]
75904
+ }
75905
+ };
75906
+ const payToAsn1 = feeData[2];
75907
+ if (payToAsn1 !== undefined) {
75908
+ const payTo = account_1.default.fromPublicKeyAndType(Buffer.from(payToAsn1.contains));
75909
+ if (payTo.isStorage()) {
75910
+ retval.fee.payTo = payTo;
75911
+ }
75912
+ else {
75913
+ try {
75914
+ retval.fee.payTo = payTo.assertAccount();
75915
+ }
75916
+ catch {
75917
+ throw (new vote_1.default('VOTE_MALFORMED_FEES_PAY_TO_INVALID', 'internal error: payTo is not an Account or Storage Address'));
75918
+ }
75919
+ }
75920
+ }
75921
+ const tokenAsn1 = feeData[3];
75922
+ if (tokenAsn1 !== undefined) {
75923
+ const token = account_1.default.fromPublicKeyAndType(Buffer.from(tokenAsn1.contains));
75924
+ if (!token.isToken()) {
75925
+ throw (new vote_1.default('VOTE_MALFORMED_FEES_TOKEN_NOT_TOKEN', 'internal error: fees extension token is not a valid token'));
75926
+ }
75927
+ retval.fee.token = token;
75928
+ }
75929
+ return (retval);
75930
+ }
74450
75931
  /**
74451
75932
  * Convert an ASN1Date to a Date
74452
75933
  */
@@ -74577,17 +76058,41 @@ class VoteBlockHash extends buffer_1.BufferStorage {
74577
76058
  exports.VoteBlockHash = VoteBlockHash;
74578
76059
  VoteBlockHash.isInstance = (0, helper_1.checkableGenerator)(VoteBlockHash);
74579
76060
  VoteBlockHash.Map = VoteBlockHashMap;
74580
- class PossiblyExpiredVote {
76061
+ class VoteLikeBase {
76062
+ getClass() {
76063
+ // eslint-disable-next-line @typescript-eslint/consistent-type-assertions
76064
+ return this.constructor;
76065
+ }
74581
76066
  static isValidJSON(voteJSON) {
74582
76067
  for (const checkField of ['issuer', 'serial', 'blocks', 'validityFrom', 'validityTo', 'signature']) {
74583
76068
  if (voteJSON[checkField] === undefined) {
74584
76069
  return (false);
74585
76070
  }
74586
76071
  }
76072
+ if ('fee' in voteJSON) {
76073
+ const fee = voteJSON['fee'];
76074
+ if (fee === undefined) {
76075
+ return (false);
76076
+ }
76077
+ if (fee['amount'] === undefined) {
76078
+ return (false);
76079
+ }
76080
+ if ('payTo' in fee && fee['payTo'] === undefined) {
76081
+ return (false);
76082
+ }
76083
+ if ('token' in fee && fee['token'] === undefined) {
76084
+ return (false);
76085
+ }
76086
+ }
76087
+ if ('quote' in voteJSON) {
76088
+ if (voteJSON['quote'] === undefined) {
76089
+ return (false);
76090
+ }
76091
+ }
74587
76092
  return (true);
74588
76093
  }
74589
76094
  static fromJSON(voteJSON, options = {}) {
74590
- if (!PossiblyExpiredVote.isValidJSON(voteJSON)) {
76095
+ if (!VoteLikeBase.isValidJSON(voteJSON)) {
74591
76096
  throw (new vote_1.default('VOTE_INVALID_CONSTRUCTION_JSON', 'Cannot construct vote, it is not a valid vote JSON object'));
74592
76097
  }
74593
76098
  const issuer = account_1.default.toAccount(voteJSON.issuer);
@@ -74606,31 +76111,43 @@ class PossiblyExpiredVote {
74606
76111
  const validTo = new Date(voteJSON.validityTo);
74607
76112
  const validFrom = new Date(voteJSON.validityFrom);
74608
76113
  const signatureStorage = new buffer_1.BufferStorage(signature, signature.byteLength);
76114
+ if (this.expectedQuoteValue !== (voteJSON.quote ?? false)) {
76115
+ throw (new vote_1.default('VOTE_MALFORMED_FEES_QUOTE_INVALID', `internal error: fee quote mismatch found ${voteJSON.quote} - expected ${this.expectedQuoteValue}`));
76116
+ }
76117
+ if (voteJSON.quote === true && voteJSON.fee === undefined) {
76118
+ throw (new vote_1.default('VOTE_FEE_QUOTE_MISSING_FEES', 'internal error: requested quote but no fees provided'));
76119
+ }
76120
+ if (voteJSON.fee !== undefined) {
76121
+ voteBuilder.addFee(voteJSON.fee);
76122
+ }
74609
76123
  const { voteData, tbsCertificate, signatureInfo } = voteBuilder.generateVoteData(BigInt(voteJSON.serial), validTo, validFrom);
74610
- const vote = voteBuilder.createVote(voteData, tbsCertificate, signatureInfo, signatureStorage, options);
74611
- return (vote);
76124
+ const vote = voteBuilder.createVote(voteData, tbsCertificate, signatureInfo, signatureStorage);
76125
+ // eslint-disable-next-line @typescript-eslint/consistent-type-assertions
76126
+ return new this(vote, options);
74612
76127
  }
74613
76128
  constructor(vote, options = {}) {
74614
76129
  this.$trusted = false;
74615
76130
  this.$permanent = false;
74616
- _PossiblyExpiredVote_vote.set(this, void 0);
74617
- _PossiblyExpiredVote_options.set(this, void 0);
74618
- _PossiblyExpiredVote__hash.set(this, void 0);
74619
- _PossiblyExpiredVote__blocksHash.set(this, void 0);
74620
- __classPrivateFieldSet(this, _PossiblyExpiredVote_options, { ...options }, "f");
74621
- if (PossiblyExpiredVote.isInstance(vote, false)) {
76131
+ _VoteLikeBase_vote.set(this, void 0);
76132
+ _VoteLikeBase_options.set(this, void 0);
76133
+ _VoteLikeBase__hash.set(this, void 0);
76134
+ _VoteLikeBase__blocksHash.set(this, void 0);
76135
+ __classPrivateFieldSet(this, _VoteLikeBase_options, { ...options }, "f");
76136
+ if (VoteLikeBase.isInstance(vote, false)) {
74622
76137
  this.issuer = vote.issuer;
74623
76138
  this.serial = vote.serial;
74624
76139
  this.blocks = vote.blocks;
74625
76140
  this.validityFrom = vote.validityFrom;
74626
76141
  this.validityTo = vote.validityTo;
74627
76142
  this.signature = vote.signature;
76143
+ this.fee = vote.fee;
76144
+ this.quote = vote.quote;
74628
76145
  this.$trusted = vote.$trusted;
74629
76146
  this.$permanent = vote.$permanent;
74630
76147
  this.$uid = vote.$uid;
74631
76148
  this.$id = vote.$id;
74632
- __classPrivateFieldSet(this, _PossiblyExpiredVote_vote, __classPrivateFieldGet(vote, _PossiblyExpiredVote_vote, "f"), "f");
74633
- __classPrivateFieldSet(this, _PossiblyExpiredVote_options, __classPrivateFieldGet(vote, _PossiblyExpiredVote_options, "f"), "f");
76149
+ __classPrivateFieldSet(this, _VoteLikeBase_vote, __classPrivateFieldGet(vote, _VoteLikeBase_vote, "f"), "f");
76150
+ __classPrivateFieldSet(this, _VoteLikeBase_options, __classPrivateFieldGet(vote, _VoteLikeBase_options, "f"), "f");
74634
76151
  return;
74635
76152
  }
74636
76153
  if (typeof vote === 'string') {
@@ -74643,18 +76160,18 @@ class PossiblyExpiredVote {
74643
76160
  vote = (0, helper_1.bufferToArrayBuffer)(vote);
74644
76161
  }
74645
76162
  if (!(util_1.types.isArrayBuffer(vote))) {
74646
- if (PossiblyExpiredVote.isValidJSON(vote)) {
74647
- vote = PossiblyExpiredVote.fromJSON(vote).toBytes();
76163
+ if (VoteLikeBase.isValidJSON(vote)) {
76164
+ vote = VoteLikeBase.fromJSON(vote).toBytes();
74648
76165
  }
74649
76166
  else {
74650
- throw (new vote_1.default('VOTE_INVALID_CONSTRUCTION', 'internal error: invalid vote constructor argument in PossiblyExpiredVote'));
76167
+ throw (new vote_1.default('VOTE_INVALID_CONSTRUCTION', 'internal error: invalid vote constructor argument in VoteLikeBase'));
74651
76168
  }
74652
76169
  }
74653
- __classPrivateFieldSet(this, _PossiblyExpiredVote_vote, vote, "f");
76170
+ __classPrivateFieldSet(this, _VoteLikeBase_vote, vote, "f");
74654
76171
  /**
74655
76172
  * Vote Wrapper contains the vote, signature info, and signature
74656
76173
  */
74657
- const voteWrapper = (0, asn1_1.ASN1toJS)(__classPrivateFieldGet(this, _PossiblyExpiredVote_vote, "f"));
76174
+ const voteWrapper = (0, asn1_1.ASN1toJS)(__classPrivateFieldGet(this, _VoteLikeBase_vote, "f"));
74658
76175
  if (!Array.isArray(voteWrapper)) {
74659
76176
  throw (new vote_1.default('VOTE_MALFORMED_WRAPPER', 'internal error: Malformed vote wrapper (must be a sequence)'));
74660
76177
  }
@@ -74754,13 +76271,13 @@ class PossiblyExpiredVote {
74754
76271
  * Votes must not be expired
74755
76272
  */
74756
76273
  const expirationCheckMomentISO = new Date(expirationCheckMoment).toISOString();
74757
- if (expirationCheckMoment < (this.validityFrom.valueOf() - PossiblyExpiredVote.allowedSlop)) {
76274
+ if (expirationCheckMoment < (this.validityFrom.valueOf() - VoteLikeBase.allowedSlop)) {
74758
76275
  throw (new vote_1.default('VOTE_MOMENT_BEFORE_VALIDITY_FROM', `Vote was issued in the future (issued on ${validFrom.toISOString()}; moment: ${expirationCheckMomentISO})`));
74759
76276
  }
74760
76277
  /**
74761
76278
  * If the vote is forever viable, it is a permanent vote
74762
76279
  */
74763
- if (this.validityTo.valueOf() > (expirationCheckMoment + PossiblyExpiredVote.permanentVoteThreshold)) {
76280
+ if (this.validityTo.valueOf() > (expirationCheckMoment + VoteLikeBase.permanentVoteThreshold)) {
74764
76281
  this.$permanent = true;
74765
76282
  }
74766
76283
  /**
@@ -74825,6 +76342,7 @@ class PossiblyExpiredVote {
74825
76342
  throw (new vote_1.default('VOTE_MALFORMED_VOTE_EXTENSIONS', 'internal error: Expected extensions to be a Sequence'));
74826
76343
  }
74827
76344
  let blocks;
76345
+ let feeAndKind;
74828
76346
  for (const extensionInfo of extensions) {
74829
76347
  if (!Array.isArray(extensionInfo)) {
74830
76348
  throw (new vote_1.default('VOTE_MALFORMED_VOTE_EXTENSIONS_VALUE', 'internal error: Expected each extension to be a Sequence'));
@@ -74848,13 +76366,17 @@ class PossiblyExpiredVote {
74848
76366
  critical = criticalCheck;
74849
76367
  }
74850
76368
  const extensionData = extensionInfo.shift();
76369
+ if (!(Buffer.isBuffer(extensionData))) {
76370
+ throw (new vote_1.default('VOTE_MALFORMED_VOTE_EXTENSIONS_DATA', `internal error: ${extensionOID.oid} extensions are always Octet String`));
76371
+ }
74851
76372
  switch (extensionOID.oid) {
74852
76373
  case 'hashData':
74853
- if (!(Buffer.isBuffer(extensionData))) {
74854
- throw (new vote_1.default('VOTE_MALFORMED_VOTE_EXTENSIONS_VALUE_HASH_DATA', 'internal error: hashData extensions are always Octet String'));
74855
- }
74856
76374
  blocks = blockHashesFromVote(extensionData);
74857
76375
  break;
76376
+ case '1.3.6.1.4.1.62675.0.1.0':
76377
+ case 'fees': // replace with fees 1.3.6.1.4.1.62675.0.1.0
76378
+ feeAndKind = feeFromVote(extensionData);
76379
+ break;
74858
76380
  default:
74859
76381
  if (critical) {
74860
76382
  throw (new vote_1.default('VOTE_MALFORMED_VOTE_EXTENSIONS_VALUE_CRITICAL_TYPE', `internal error: Unknown critical extension ${extensionOID.oid}`));
@@ -74868,6 +76390,17 @@ class PossiblyExpiredVote {
74868
76390
  throw (new vote_1.default('VOTE_MALFORMED_VOTE_NO_BLOCKS_FOUND', 'No block hashes found within vote'));
74869
76391
  }
74870
76392
  this.blocks = blocks;
76393
+ if (feeAndKind !== undefined) {
76394
+ if (this.$permanent) {
76395
+ throw (new vote_1.default('VOTE_MALFORMED_FEES_IN_PERMANENT_VOTE', 'Permanent Vote cannot have fees'));
76396
+ }
76397
+ // Get the expected quote value from any child instances and compare
76398
+ if (feeAndKind.quote !== this.getClass().expectedQuoteValue) {
76399
+ throw (new vote_1.default('VOTE_MALFORMED_FEES_QUOTE_INVALID', `internal error: fee quote mismatch found ${feeAndKind.quote} - expected ${this.getClass().expectedQuoteValue}`));
76400
+ }
76401
+ this.fee = feeAndKind.fee;
76402
+ this.quote = feeAndKind.quote;
76403
+ }
74871
76404
  /**
74872
76405
  * Get the signature data
74873
76406
  */
@@ -74954,19 +76487,19 @@ class PossiblyExpiredVote {
74954
76487
  }
74955
76488
  }
74956
76489
  toBytes() {
74957
- return (__classPrivateFieldGet(this, _PossiblyExpiredVote_vote, "f"));
76490
+ return (__classPrivateFieldGet(this, _VoteLikeBase_vote, "f"));
74958
76491
  }
74959
76492
  get hash() {
74960
- if (!__classPrivateFieldGet(this, _PossiblyExpiredVote__hash, "f")) {
74961
- __classPrivateFieldSet(this, _PossiblyExpiredVote__hash, new VoteHash((0, hash_1.Hash)(Buffer.from(this.toBytes()))), "f");
76493
+ if (!__classPrivateFieldGet(this, _VoteLikeBase__hash, "f")) {
76494
+ __classPrivateFieldSet(this, _VoteLikeBase__hash, new VoteHash((0, hash_1.Hash)(Buffer.from(this.toBytes()))), "f");
74962
76495
  }
74963
- return (__classPrivateFieldGet(this, _PossiblyExpiredVote__hash, "f"));
76496
+ return (__classPrivateFieldGet(this, _VoteLikeBase__hash, "f"));
74964
76497
  }
74965
76498
  get blocksHash() {
74966
- if (!__classPrivateFieldGet(this, _PossiblyExpiredVote__blocksHash, "f")) {
74967
- __classPrivateFieldSet(this, _PossiblyExpiredVote__blocksHash, VoteBlockHash.fromVote(this), "f");
76499
+ if (!__classPrivateFieldGet(this, _VoteLikeBase__blocksHash, "f")) {
76500
+ __classPrivateFieldSet(this, _VoteLikeBase__blocksHash, VoteBlockHash.fromVote(this), "f");
74968
76501
  }
74969
- return (__classPrivateFieldGet(this, _PossiblyExpiredVote__blocksHash, "f"));
76502
+ return (__classPrivateFieldGet(this, _VoteLikeBase__blocksHash, "f"));
74970
76503
  }
74971
76504
  toString() {
74972
76505
  return (Buffer.from(this.toBytes()).toString('base64'));
@@ -74976,6 +76509,12 @@ class PossiblyExpiredVote {
74976
76509
  if (options?.addBinary) {
74977
76510
  additionalFields['$binary'] = Buffer.from(this.toBytes()).toString('base64');
74978
76511
  }
76512
+ if (this.fee !== undefined) {
76513
+ additionalFields['fee'] = this.fee;
76514
+ }
76515
+ if (this.quote !== undefined) {
76516
+ additionalFields['quote'] = this.quote;
76517
+ }
74979
76518
  return ({
74980
76519
  issuer: this.issuer,
74981
76520
  serial: this.serial,
@@ -74992,8 +76531,8 @@ class PossiblyExpiredVote {
74992
76531
  }
74993
76532
  expirationCheckMoment() {
74994
76533
  let now;
74995
- if (__classPrivateFieldGet(this, _PossiblyExpiredVote_options, "f").now) {
74996
- now = __classPrivateFieldGet(this, _PossiblyExpiredVote_options, "f").now.valueOf();
76534
+ if (__classPrivateFieldGet(this, _VoteLikeBase_options, "f").now) {
76535
+ now = __classPrivateFieldGet(this, _VoteLikeBase_options, "f").now.valueOf();
74997
76536
  }
74998
76537
  else {
74999
76538
  now = Date.now();
@@ -75004,17 +76543,27 @@ class PossiblyExpiredVote {
75004
76543
  const now = this.expirationCheckMoment();
75005
76544
  const from = this.validityFrom.valueOf();
75006
76545
  const to = this.validityTo.valueOf();
75007
- if ((now + PossiblyExpiredVote.allowedSlop) < from || (now - PossiblyExpiredVote.allowedSlop) > to) {
76546
+ if ((now + VoteLikeBase.allowedSlop) < from || (now - VoteLikeBase.allowedSlop) > to) {
75008
76547
  return (true);
75009
76548
  }
75010
76549
  return (false);
75011
76550
  }
75012
76551
  }
76552
+ _VoteLikeBase_vote = new WeakMap(), _VoteLikeBase_options = new WeakMap(), _VoteLikeBase__hash = new WeakMap(), _VoteLikeBase__blocksHash = new WeakMap();
76553
+ VoteLikeBase.expectedQuoteValue = false;
76554
+ VoteLikeBase.allowedSlop = 60 /* s */ * 1000 /* ms */;
76555
+ VoteLikeBase.permanentVoteThreshold = 100 /* y */ * 365 /* d */ * 86400 /* s */ * 1000 /* ms */;
76556
+ VoteLikeBase.VoteBlocksHash = VoteBlockHash;
76557
+ VoteLikeBase.isInstance = (0, helper_1.checkableGenerator)(VoteLikeBase);
76558
+ class PossiblyExpiredVote extends VoteLikeBase {
76559
+ constructor(vote, options = {}) {
76560
+ super(vote, options);
76561
+ if (this.quote === true) {
76562
+ throw (new vote_1.default('VOTE_FEE_IS_QUOTE', `Tried to construct a vote but fee kind is QUOTE`));
76563
+ }
76564
+ }
76565
+ }
75013
76566
  exports.PossiblyExpiredVote = PossiblyExpiredVote;
75014
- _PossiblyExpiredVote_vote = new WeakMap(), _PossiblyExpiredVote_options = new WeakMap(), _PossiblyExpiredVote__hash = new WeakMap(), _PossiblyExpiredVote__blocksHash = new WeakMap();
75015
- PossiblyExpiredVote.allowedSlop = 60 /* s */ * 1000 /* ms */;
75016
- PossiblyExpiredVote.permanentVoteThreshold = 100 /* y */ * 365 /* d */ * 86400 /* s */ * 1000 /* ms */;
75017
- PossiblyExpiredVote.VoteBlocksHash = VoteBlockHash;
75018
76567
  PossiblyExpiredVote.isInstance = (0, helper_1.checkableGenerator)(PossiblyExpiredVote);
75019
76568
  /**
75020
76569
  * A vote is a certificate issued indicating that the issuer "vouches" for the
@@ -75033,6 +76582,26 @@ class Vote extends PossiblyExpiredVote {
75033
76582
  }
75034
76583
  exports.Vote = Vote;
75035
76584
  Vote.isInstance = (0, helper_1.checkableGenerator)(Vote);
76585
+ /**
76586
+ * A VoteQuote is a certificate issued indicating what the issuer will charge for fees
76587
+ */
76588
+ class VoteQuote extends VoteLikeBase {
76589
+ constructor(vote, options = {}) {
76590
+ super(vote, options);
76591
+ // We add this so both classes have different signatures
76592
+ this.isVoteQuote = true;
76593
+ if (this.expired) {
76594
+ const expirationCheckMomentISO = new Date(this.expirationCheckMoment()).toISOString();
76595
+ throw (new vote_1.default('VOTE_EXPIRED', `VoteQuote is expired (expired on ${this.validityTo.toISOString()}; issued on ${this.validityFrom.toISOString()}; moment: ${expirationCheckMomentISO})`));
76596
+ }
76597
+ if (!this.quote) {
76598
+ throw (new vote_1.default('VOTE_FEE_NOT_QUOTE', `Tried to construct a quote but fee kind is note QUOTE`));
76599
+ }
76600
+ }
76601
+ }
76602
+ exports.VoteQuote = VoteQuote;
76603
+ VoteQuote.expectedQuoteValue = true;
76604
+ VoteQuote.isInstance = (0, helper_1.checkableGenerator)(VoteQuote);
75036
76605
  /**
75037
76606
  * A vote staple is a distributable block consisting of one or more blocks
75038
76607
  * and one or more votes.
@@ -75250,8 +76819,11 @@ class VoteBlockBundle {
75250
76819
  votesStapled = (0, helper_1.bufferToArrayBuffer)(votesStapled);
75251
76820
  }
75252
76821
  if (!(util_1.types.isArrayBuffer(votesStapled))) {
75253
- if (VoteBlockBundle.isValidJSON(votesStapled)) {
75254
- votesStapled = VoteBlockBundle.fromJSON(votesStapled).toBytes(true);
76822
+ if (votesStapled instanceof VoteBlockBundle) {
76823
+ votesStapled = votesStapled.toBytes(true);
76824
+ }
76825
+ else if (VoteBlockBundle.isValidJSON(votesStapled)) {
76826
+ votesStapled = VoteBlockBundle.fromJSON(votesStapled, voteOptions).toBytes(true);
75255
76827
  }
75256
76828
  else {
75257
76829
  throw (new vote_1.default('VOTE_STAPLE_INVALID_CONSTRUCTION', 'internal error: votesStapled must be an ArrayBuffer'));
@@ -75458,36 +77030,61 @@ class VoteStaple extends VoteBlockBundle {
75458
77030
  }
75459
77031
  exports.VoteStaple = VoteStaple;
75460
77032
  VoteStaple.isInstance = (0, helper_1.checkableGenerator)(VoteStaple);
75461
- class VoteBuilder {
75462
- constructor(account, blocks = []) {
75463
- _VoteBuilder_account.set(this, void 0);
75464
- _VoteBuilder_blocks.set(this, void 0);
77033
+ class BaseVoteBuilder {
77034
+ constructor(account, blocks = [], options) {
77035
+ _BaseVoteBuilder_account.set(this, void 0);
77036
+ _BaseVoteBuilder_blocks.set(this, void 0);
77037
+ _BaseVoteBuilder_fee.set(this, undefined);
77038
+ this.quote = false;
75465
77039
  if (!account_1.default.isInstance(account)) {
75466
77040
  throw (new vote_1.default('VOTE_BUILDER_INVALID_CONSTRUCTION', 'internal error: account must be an Account'));
75467
77041
  }
75468
- __classPrivateFieldSet(this, _VoteBuilder_account, account, "f");
75469
- __classPrivateFieldSet(this, _VoteBuilder_blocks, [], "f");
77042
+ __classPrivateFieldSet(this, _BaseVoteBuilder_account, account, "f");
77043
+ __classPrivateFieldSet(this, _BaseVoteBuilder_blocks, [], "f");
77044
+ __classPrivateFieldSet(this, _BaseVoteBuilder_fee, options?.fee, "f");
75470
77045
  this.addBlocks(blocks);
75471
77046
  }
75472
77047
  addBlocks(blocks) {
75473
77048
  for (const block of blocks) {
75474
77049
  if (block_1.Block.isInstance(block)) {
75475
- __classPrivateFieldGet(this, _VoteBuilder_blocks, "f").push(block.hash);
77050
+ __classPrivateFieldGet(this, _BaseVoteBuilder_blocks, "f").push(block.hash);
75476
77051
  continue;
75477
77052
  }
75478
77053
  if (typeof block === 'string') {
75479
- __classPrivateFieldGet(this, _VoteBuilder_blocks, "f").push(new block_1.BlockHash(block));
77054
+ __classPrivateFieldGet(this, _BaseVoteBuilder_blocks, "f").push(new block_1.BlockHash(block));
75480
77055
  continue;
75481
77056
  }
75482
77057
  if (!block_1.BlockHash.isInstance(block)) {
75483
77058
  throw (new vote_1.default('VOTE_BUILDER_INVALID_BLOCK_TYPE', 'internal error: block must be Block, BlockHash, or string'));
75484
77059
  }
75485
- __classPrivateFieldGet(this, _VoteBuilder_blocks, "f").push(block);
77060
+ __classPrivateFieldGet(this, _BaseVoteBuilder_blocks, "f").push(block);
75486
77061
  }
75487
77062
  }
75488
77063
  addBlock(block) {
75489
77064
  this.addBlocks([block]);
75490
77065
  }
77066
+ addFee(feeInput) {
77067
+ const fee = { amount: BigInt(feeInput.amount) };
77068
+ const payTo = account_1.default.toAccount(feeInput.payTo);
77069
+ if (payTo !== undefined) {
77070
+ if (payTo.isStorage()) {
77071
+ fee.payTo = payTo;
77072
+ }
77073
+ else {
77074
+ fee.payTo = payTo.assertAccount();
77075
+ }
77076
+ }
77077
+ const token = account_1.default.toAccount(feeInput.token);
77078
+ if (token !== undefined) {
77079
+ if (token.isToken()) {
77080
+ fee.token = token;
77081
+ }
77082
+ else {
77083
+ throw (new vote_1.default('VOTE_MALFORMED_FEES_TOKEN_NOT_TOKEN', 'Fee Token should be of type TOKEN'));
77084
+ }
77085
+ }
77086
+ __classPrivateFieldSet(this, _BaseVoteBuilder_fee, fee, "f");
77087
+ }
75491
77088
  generateVoteData(serial, validTo, validFrom) {
75492
77089
  /**
75493
77090
  * Signature algorithm identifier
@@ -75497,8 +77094,9 @@ class VoteBuilder {
75497
77094
  * Whether or not to hash the data we are signing
75498
77095
  */
75499
77096
  let hashData = false;
75500
- switch (__classPrivateFieldGet(this, _VoteBuilder_account, "f").keyType) {
77097
+ switch (__classPrivateFieldGet(this, _BaseVoteBuilder_account, "f").keyType) {
75501
77098
  case account_1.AccountKeyAlgorithm.ECDSA_SECP256K1:
77099
+ case account_1.AccountKeyAlgorithm.ECDSA_SECP256R1:
75502
77100
  {
75503
77101
  /*
75504
77102
  * Use the default hashing function
@@ -75520,11 +77118,36 @@ class VoteBuilder {
75520
77118
  break;
75521
77119
  }
75522
77120
  /** Public Key */
75523
- const publicKey = __classPrivateFieldGet(this, _VoteBuilder_account, "f").publicKey.ASN1.getASN1();
77121
+ const publicKey = __classPrivateFieldGet(this, _BaseVoteBuilder_account, "f").publicKey.ASN1.getASN1();
75524
77122
  /** Signature Information */
75525
77123
  const signatureInfo = [
75526
77124
  { type: 'oid', oid: signatureInfoOID }
75527
77125
  ];
77126
+ let feeExtension = undefined;
77127
+ if (__classPrivateFieldGet(this, _BaseVoteBuilder_fee, "f") !== undefined) {
77128
+ /** Amount for this vote */
77129
+ const feeData = [this.quote, __classPrivateFieldGet(this, _BaseVoteBuilder_fee, "f").amount];
77130
+ /** Account to pay the fee too */
77131
+ const payToPublicKey = __classPrivateFieldGet(this, _BaseVoteBuilder_fee, "f").payTo?.publicKeyAndType;
77132
+ if (payToPublicKey !== undefined) {
77133
+ feeData.push({ type: 'context', value: 0, kind: 'implicit', contains: payToPublicKey });
77134
+ }
77135
+ /** Token in which to pay the fee */
77136
+ const tokenPublicKey = __classPrivateFieldGet(this, _BaseVoteBuilder_fee, "f").token?.publicKeyAndType;
77137
+ if (tokenPublicKey !== undefined) {
77138
+ feeData.push({ type: 'context', value: 1, kind: 'implicit', contains: tokenPublicKey });
77139
+ }
77140
+ feeExtension = [
77141
+ { type: 'oid', oid: '1.3.6.1.4.1.62675.0.1.0' }, // replace with 'fees' - 1.3.6.1.4.1.62675.0.1.0
77142
+ true,
77143
+ Buffer.from((0, asn1_1.JStoASN1)({
77144
+ type: 'context',
77145
+ value: 0,
77146
+ kind: 'explicit',
77147
+ contains: feeData
77148
+ }).toBER(false))
77149
+ ];
77150
+ }
75528
77151
  /*
75529
77152
  * Certificate to be signed
75530
77153
  */
@@ -75547,7 +77170,7 @@ class VoteBuilder {
75547
77170
  type: 'oid',
75548
77171
  oid: 'commonName'
75549
77172
  },
75550
- value: { type: 'string', kind: 'utf8', value: __classPrivateFieldGet(this, _VoteBuilder_account, "f").publicKeyString.get() }
77173
+ value: { type: 'string', kind: 'utf8', value: __classPrivateFieldGet(this, _BaseVoteBuilder_account, "f").publicKeyString.get() }
75551
77174
  }
75552
77175
  ],
75553
77176
  /** Validity */
@@ -75597,12 +77220,13 @@ class VoteBuilder {
75597
77220
  /** Hash algorithm used to hash blocks */
75598
77221
  { type: 'oid', oid: hash_1.Hash.functionName },
75599
77222
  /** List of block hashes */
75600
- __classPrivateFieldGet(this, _VoteBuilder_blocks, "f").map(function (blockhash) {
77223
+ __classPrivateFieldGet(this, _BaseVoteBuilder_blocks, "f").map(function (blockhash) {
75601
77224
  return (blockhash.getBuffer());
75602
77225
  })
75603
77226
  ]
75604
77227
  }).toBER(false))
75605
- ]
77228
+ ],
77229
+ ...(feeExtension ? [feeExtension] : [])
75606
77230
  ]
75607
77231
  }
75608
77232
  ];
@@ -75620,11 +77244,11 @@ class VoteBuilder {
75620
77244
  signatureInfo: signatureInfo
75621
77245
  });
75622
77246
  }
75623
- createVote(voteData, tbsCertificate, signatureInfo, signature, voteOptions = {}) {
77247
+ createVote(voteData, tbsCertificate, signatureInfo, signature) {
75624
77248
  /**
75625
77249
  * Double-check that the signature we just created is valid for the data
75626
77250
  */
75627
- const verification = __classPrivateFieldGet(this, _VoteBuilder_account, "f").verify(voteData, signature, {
77251
+ const verification = __classPrivateFieldGet(this, _BaseVoteBuilder_account, "f").verify(voteData, signature, {
75628
77252
  raw: true,
75629
77253
  forCert: true
75630
77254
  });
@@ -75643,15 +77267,18 @@ class VoteBuilder {
75643
77267
  * Vote: A DER-encoded certificate
75644
77268
  */
75645
77269
  const vote = certificate.toBER(false);
75646
- return (new Vote(vote, voteOptions));
77270
+ return (vote);
75647
77271
  }
75648
- async seal(serial, validTo, validFrom, voteOptions = {}) {
77272
+ async generate(serial, validTo, validFrom) {
75649
77273
  if (validFrom === undefined) {
75650
77274
  validFrom = new Date();
75651
77275
  }
75652
77276
  if (typeof serial !== 'bigint') {
75653
77277
  throw (new vote_1.default('VOTE_BUILDER_INVALID_SERIAL', `internal error: serial must be a bigint, instead got ${serial}`));
75654
77278
  }
77279
+ if (validTo === null && __classPrivateFieldGet(this, _BaseVoteBuilder_fee, "f") !== undefined) {
77280
+ throw (new vote_1.default('VOTE_MALFORMED_FEES_IN_PERMANENT_VOTE', 'internal error: permanent votes should not have fees'));
77281
+ }
75655
77282
  if (validTo === null) {
75656
77283
  /**
75657
77284
  * Issue a permanent vote
@@ -75663,23 +77290,51 @@ class VoteBuilder {
75663
77290
  if (!(util_1.types.isDate(validFrom)) || !(util_1.types.isDate(validTo))) {
75664
77291
  throw (new vote_1.default('VOTE_BUILDER_INVALID_VALID_TO_FROM', 'internal error: validFrom must be Date'));
75665
77292
  }
77293
+ if (this.quote && __classPrivateFieldGet(this, _BaseVoteBuilder_fee, "f") === undefined) {
77294
+ throw (new vote_1.default('VOTE_FEE_QUOTE_MISSING_FEES', 'internal error: requested quote but no fees provided'));
77295
+ }
75666
77296
  const { voteData, tbsCertificate, signatureInfo } = this.generateVoteData(serial, validTo, validFrom);
75667
- const signature = await __classPrivateFieldGet(this, _VoteBuilder_account, "f").sign(voteData, {
77297
+ const signature = await __classPrivateFieldGet(this, _BaseVoteBuilder_account, "f").sign(voteData, {
75668
77298
  raw: true,
75669
77299
  forCert: true
75670
77300
  });
75671
- const vote = this.createVote(voteData, tbsCertificate, signatureInfo, signature, voteOptions);
77301
+ const voteLike = this.createVote(voteData, tbsCertificate, signatureInfo, signature);
77302
+ return (voteLike);
77303
+ }
77304
+ }
77305
+ exports.BaseVoteBuilder = BaseVoteBuilder;
77306
+ _BaseVoteBuilder_account = new WeakMap(), _BaseVoteBuilder_blocks = new WeakMap(), _BaseVoteBuilder_fee = new WeakMap();
77307
+ BaseVoteBuilder.isInstance = (0, helper_1.checkableGenerator)(BaseVoteBuilder);
77308
+ class VoteBuilder extends BaseVoteBuilder {
77309
+ async seal(serial, validTo, validFrom, voteOptions = {}) {
77310
+ const vote = await super.generate(serial, validTo, validFrom);
75672
77311
  return (new Vote(vote, voteOptions));
75673
77312
  }
75674
77313
  }
75675
77314
  exports.VoteBuilder = VoteBuilder;
75676
- _VoteBuilder_account = new WeakMap(), _VoteBuilder_blocks = new WeakMap();
75677
77315
  VoteBuilder.isInstance = (0, helper_1.checkableGenerator)(VoteBuilder);
75678
- PossiblyExpiredVote.Staple = VoteStaple;
75679
- PossiblyExpiredVote.Builder = VoteBuilder;
77316
+ class VoteQuoteBuilder extends BaseVoteBuilder {
77317
+ constructor() {
77318
+ super(...arguments);
77319
+ this.quote = true;
77320
+ }
77321
+ async seal(serial, validTo, validFrom, voteOptions = {}) {
77322
+ const voteQuote = await super.generate(serial, validTo, validFrom);
77323
+ return (new VoteQuote(voteQuote, voteOptions));
77324
+ }
77325
+ }
77326
+ exports.VoteQuoteBuilder = VoteQuoteBuilder;
77327
+ VoteQuoteBuilder.isInstance = (0, helper_1.checkableGenerator)(VoteQuoteBuilder);
77328
+ // Add respective builders to each
77329
+ VoteLikeBase.Builder = BaseVoteBuilder;
77330
+ VoteQuote.Builder = VoteQuoteBuilder;
77331
+ Vote.Builder = VoteBuilder;
77332
+ // Add to default export
77333
+ Vote.Staple = VoteStaple;
77334
+ Vote.Quote = VoteQuote;
75680
77335
  exports["default"] = Vote;
75681
77336
  /** @internal */
75682
- exports.Testing = { findRDN, blockHashesFromVote };
77337
+ exports.Testing = { findRDN, blockHashesFromVote, feeFromVote };
75683
77338
 
75684
77339
 
75685
77340
  /***/ }),
@@ -75691,7 +77346,7 @@ exports.Testing = { findRDN, blockHashesFromVote };
75691
77346
 
75692
77347
  Object.defineProperty(exports, "__esModule", ({ value: true }));
75693
77348
  exports.version = void 0;
75694
- exports.version = '0.12.0+g0baa5ce2aac600e17a0fe832eadebcacebe23bf1';
77349
+ exports.version = '0.14.0+g8b0bdc16c0cba85135437a9ffb3a8cea2dae170d';
75695
77350
  exports["default"] = exports.version;
75696
77351
 
75697
77352