@keetanetwork/keetanet-client 0.16.0 → 0.16.2

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 (210) hide show
  1. package/client/builder.d.ts +3 -3
  2. package/client/client_common_tests.d.ts +23 -4
  3. package/client/index-browser.d.ts +15 -13
  4. package/client/index-browser.js +878 -351
  5. package/client/index.d.ts +15 -13
  6. package/client/index.js +737 -253
  7. package/docs/assets/hierarchy.js +1 -1
  8. package/docs/assets/search.js +1 -1
  9. package/docs/classes/KeetaNetSDK.Client.html +10 -10
  10. package/docs/classes/KeetaNetSDK.Referenced.Account.html +34 -31
  11. package/docs/classes/KeetaNetSDK.Referenced.BaseSet.html +1 -1
  12. package/docs/classes/KeetaNetSDK.Referenced.BaseVoteBuilder.html +2 -2
  13. package/docs/classes/KeetaNetSDK.Referenced.Block.html +3 -3
  14. package/docs/classes/KeetaNetSDK.Referenced.BlockBuilder.html +1 -1
  15. package/docs/classes/KeetaNetSDK.Referenced.BlockHash.html +1 -1
  16. package/docs/classes/KeetaNetSDK.Referenced.BlockOperation.html +1 -1
  17. package/docs/classes/KeetaNetSDK.Referenced.BlockOperationCREATE_IDENTIFIER.html +2 -2
  18. package/docs/classes/KeetaNetSDK.Referenced.BlockOperationMANAGE_CERTIFICATE.html +2 -2
  19. package/docs/classes/KeetaNetSDK.Referenced.BlockOperationMODIFY_PERMISSIONS.html +2 -2
  20. package/docs/classes/KeetaNetSDK.Referenced.BlockOperationRECEIVE.html +2 -2
  21. package/docs/classes/KeetaNetSDK.Referenced.BlockOperationSEND.html +2 -2
  22. package/docs/classes/KeetaNetSDK.Referenced.BlockOperationSET_INFO.html +2 -2
  23. package/docs/classes/KeetaNetSDK.Referenced.BlockOperationSET_REP.html +2 -2
  24. package/docs/classes/KeetaNetSDK.Referenced.BlockOperationTOKEN_ADMIN_MODIFY_BALANCE.html +2 -2
  25. package/docs/classes/KeetaNetSDK.Referenced.BlockOperationTOKEN_ADMIN_SUPPLY.html +2 -2
  26. package/docs/classes/KeetaNetSDK.Referenced.Certificate.html +7 -7
  27. package/docs/classes/KeetaNetSDK.Referenced.CertificateBundle.html +1 -1
  28. package/docs/classes/KeetaNetSDK.Referenced.CertificateHash.html +1 -1
  29. package/docs/classes/KeetaNetSDK.Referenced.ECDSAKeyPair.html +1 -1
  30. package/docs/classes/KeetaNetSDK.Referenced.ECDSASECP256K1KeyPair.html +1 -1
  31. package/docs/classes/KeetaNetSDK.Referenced.ECDSASECP256K1PrivateKey.html +1 -1
  32. package/docs/classes/KeetaNetSDK.Referenced.ECDSASECP256K1PublicKey.html +1 -1
  33. package/docs/classes/KeetaNetSDK.Referenced.ECDSASECP256K1Signature.html +1 -1
  34. package/docs/classes/KeetaNetSDK.Referenced.ECDSASECP256R1KeyPair.html +1 -1
  35. package/docs/classes/KeetaNetSDK.Referenced.ECDSASECP256R1PrivateKey.html +1 -1
  36. package/docs/classes/KeetaNetSDK.Referenced.ECDSASECP256R1PublicKey.html +1 -1
  37. package/docs/classes/KeetaNetSDK.Referenced.ECDSASECP256R1Signature.html +1 -1
  38. package/docs/classes/KeetaNetSDK.Referenced.ED25519KeyPair.html +1 -1
  39. package/docs/classes/KeetaNetSDK.Referenced.ED25519PrivateKey.html +1 -1
  40. package/docs/classes/KeetaNetSDK.Referenced.ED25519PublicKey.html +1 -1
  41. package/docs/classes/KeetaNetSDK.Referenced.ED25519Signature.html +1 -1
  42. package/docs/classes/KeetaNetSDK.Referenced.ExternalKeyPair.html +1 -1
  43. package/docs/classes/KeetaNetSDK.Referenced.ExternalSet.html +1 -1
  44. package/docs/classes/KeetaNetSDK.Referenced.IdempotentKey.html +1 -1
  45. package/docs/classes/KeetaNetSDK.Referenced.IdentifierKey.html +1 -1
  46. package/docs/classes/KeetaNetSDK.Referenced.IdentifierKeyPair.html +4 -4
  47. package/docs/classes/KeetaNetSDK.Referenced.KeetaNetError.html +2 -2
  48. package/docs/classes/KeetaNetSDK.Referenced.KeetaNetErrorBase.html +1 -1
  49. package/docs/classes/KeetaNetSDK.Referenced.KeetaNetLedgerError.html +1 -1
  50. package/docs/classes/KeetaNetSDK.Referenced.KeetaNetLedgerIdempotentKeyError.html +1 -1
  51. package/docs/classes/KeetaNetSDK.Referenced.KeetaNetLedgerVoteError.html +1 -1
  52. package/docs/classes/KeetaNetSDK.Referenced.KeyInterface.html +1 -1
  53. package/docs/classes/KeetaNetSDK.Referenced.KeyStorage.html +1 -1
  54. package/docs/classes/KeetaNetSDK.Referenced.Ledger.html +2 -2
  55. package/docs/classes/KeetaNetSDK.Referenced.LedgerAtomicInterface.html +1 -1
  56. package/docs/classes/KeetaNetSDK.Referenced.P2PSwitch.html +2 -2
  57. package/docs/classes/KeetaNetSDK.Referenced.PermissionSetHolder.html +1 -1
  58. package/docs/classes/KeetaNetSDK.Referenced.PossiblyExpiredVote.html +2 -2
  59. package/docs/classes/KeetaNetSDK.Referenced.PossiblyUnsignedBlock.html +3 -3
  60. package/docs/classes/KeetaNetSDK.Referenced.SignatureStorage.html +1 -1
  61. package/docs/classes/KeetaNetSDK.Referenced.Stats.html +1 -1
  62. package/docs/classes/KeetaNetSDK.Referenced.StatsPending.html +1 -1
  63. package/docs/classes/KeetaNetSDK.Referenced.UnsignedBlock.html +3 -3
  64. package/docs/classes/KeetaNetSDK.Referenced.UserClientBuilder.html +11 -11
  65. package/docs/classes/KeetaNetSDK.Referenced.Vote.html +2 -2
  66. package/docs/classes/KeetaNetSDK.Referenced.VoteBlockBundle.html +4 -4
  67. package/docs/classes/KeetaNetSDK.Referenced.VoteBlockHash.html +1 -1
  68. package/docs/classes/KeetaNetSDK.Referenced.VoteBuilder.html +2 -2
  69. package/docs/classes/KeetaNetSDK.Referenced.VoteHash.html +1 -1
  70. package/docs/classes/KeetaNetSDK.Referenced.VoteLikeBase.html +2 -2
  71. package/docs/classes/KeetaNetSDK.Referenced.VoteQuote.html +2 -2
  72. package/docs/classes/KeetaNetSDK.Referenced.VoteQuoteBuilder.html +2 -2
  73. package/docs/classes/KeetaNetSDK.Referenced.VoteStaple.html +4 -4
  74. package/docs/classes/KeetaNetSDK.Referenced.VoteStapleHash.html +1 -1
  75. package/docs/classes/KeetaNetSDK.Referenced.src_lib_utils_buffer.BufferStorage.html +1 -1
  76. package/docs/classes/KeetaNetSDK.UserClient.html +20 -20
  77. package/docs/documents/GETTING-STARTED.html +1 -1
  78. package/docs/enums/KeetaNetSDK.Referenced.AccountKeyAlgorithm.html +8 -8
  79. package/docs/functions/KeetaNetSDK.Referenced.src_lib_utils_domain-separation.applyNamespace.html +5 -0
  80. package/docs/functions/KeetaNetSDK.Referenced.src_lib_utils_helper.getTypedObjectEntries.html +1 -0
  81. package/docs/hierarchy.html +1 -1
  82. package/docs/interfaces/KeetaNetSDK.Referenced.ACLEntry.html +1 -1
  83. package/docs/interfaces/KeetaNetSDK.Referenced.ACLUpdate.html +1 -1
  84. package/docs/interfaces/KeetaNetSDK.Referenced.ASN1ExplicitContextTag.html +1 -1
  85. package/docs/interfaces/KeetaNetSDK.Referenced.ASN1ImplicitContextTag.html +1 -1
  86. package/docs/interfaces/KeetaNetSDK.Referenced.ASN1Object.html +1 -1
  87. package/docs/interfaces/KeetaNetSDK.Referenced.BaseAccountInfo.html +10 -0
  88. package/docs/interfaces/KeetaNetSDK.Referenced.BaseExternalKeyPairFunctions.html +1 -1
  89. package/docs/interfaces/KeetaNetSDK.Referenced.BaseGenerationConfig.html +2 -2
  90. package/docs/interfaces/KeetaNetSDK.Referenced.BaseIdentifierAccountInfo.html +12 -0
  91. package/docs/interfaces/KeetaNetSDK.Referenced.BaseIdentifierCreateArguments.html +1 -1
  92. package/docs/interfaces/KeetaNetSDK.Referenced.BlockJSONOperation.html +1 -1
  93. package/docs/interfaces/KeetaNetSDK.Referenced.BlockJSONOperationCREATE_IDENTIFIER.html +2 -2
  94. package/docs/interfaces/KeetaNetSDK.Referenced.BlockJSONOperationMANAGE_CERTIFICATE.html +2 -2
  95. package/docs/interfaces/KeetaNetSDK.Referenced.BlockJSONOperationMODIFY_PERMISSIONS.html +1 -1
  96. package/docs/interfaces/KeetaNetSDK.Referenced.BlockJSONOperationRECEIVE.html +1 -1
  97. package/docs/interfaces/KeetaNetSDK.Referenced.BlockJSONOperationSEND.html +1 -1
  98. package/docs/interfaces/KeetaNetSDK.Referenced.BlockJSONOperationSET_INFO.html +1 -1
  99. package/docs/interfaces/KeetaNetSDK.Referenced.BlockJSONOperationSET_REP.html +1 -1
  100. package/docs/interfaces/KeetaNetSDK.Referenced.BlockJSONOperationTOKEN_ADMIN_MODIFY_BALANCE.html +1 -1
  101. package/docs/interfaces/KeetaNetSDK.Referenced.BlockJSONOperationTOKEN_ADMIN_SUPPLY.html +1 -1
  102. package/docs/interfaces/KeetaNetSDK.Referenced.BlockV1Canonical.html +1 -1
  103. package/docs/interfaces/KeetaNetSDK.Referenced.BlockV1JSON.html +2 -2
  104. package/docs/interfaces/KeetaNetSDK.Referenced.BlockV2Canonical.html +1 -1
  105. package/docs/interfaces/KeetaNetSDK.Referenced.BuilderBlockOptions.html +2 -2
  106. package/docs/interfaces/KeetaNetSDK.Referenced.Constructor.html +1 -1
  107. package/docs/interfaces/KeetaNetSDK.Referenced.DisposableTimingHandle.html +1 -1
  108. package/docs/interfaces/KeetaNetSDK.Referenced.ECDSA_SECP256K1AccountInfo.html +10 -0
  109. package/docs/interfaces/KeetaNetSDK.Referenced.ECDSA_SECP256R1AccountInfo.html +10 -0
  110. package/docs/interfaces/KeetaNetSDK.Referenced.ED25519AccountInfo.html +10 -0
  111. package/docs/interfaces/KeetaNetSDK.Referenced.ExternalKeyPairFunctionsNoEncryption.html +1 -1
  112. package/docs/interfaces/KeetaNetSDK.Referenced.ExternalKeyPairFunctionsSupportsEncryption.html +1 -1
  113. package/docs/interfaces/KeetaNetSDK.Referenced.FeeAmountAndToken.html +2 -2
  114. package/docs/interfaces/KeetaNetSDK.Referenced.FeeAmountAndTokenJSON.html +2 -2
  115. package/docs/interfaces/KeetaNetSDK.Referenced.IdentifierCreateRequest.html +2 -2
  116. package/docs/interfaces/KeetaNetSDK.Referenced.InitialConfigSupply.html +2 -2
  117. package/docs/interfaces/KeetaNetSDK.Referenced.InstanceSet.html +1 -1
  118. package/docs/interfaces/KeetaNetSDK.Referenced.KVGenericOptionsType.html +1 -1
  119. package/docs/interfaces/KeetaNetSDK.Referenced.KVSetOptionsType.html +1 -1
  120. package/docs/interfaces/KeetaNetSDK.Referenced.LedgerConfig.html +4 -4
  121. package/docs/interfaces/KeetaNetSDK.Referenced.LedgerStorageAPI.html +5 -5
  122. package/docs/interfaces/KeetaNetSDK.Referenced.ModifyTokenBalanceEntry.html +1 -1
  123. package/docs/interfaces/KeetaNetSDK.Referenced.MultiSigIdentifierCreateArguments.html +2 -2
  124. package/docs/interfaces/KeetaNetSDK.Referenced.MultisigAccountInfo.html +14 -0
  125. package/docs/interfaces/KeetaNetSDK.Referenced.MultisigConfig.html +2 -2
  126. package/docs/interfaces/KeetaNetSDK.Referenced.NetworkAccountInfo.html +12 -0
  127. package/docs/interfaces/KeetaNetSDK.Referenced.NodeConfig.html +4 -4
  128. package/docs/interfaces/KeetaNetSDK.Referenced.NumericValueEntry.html +1 -1
  129. package/docs/interfaces/KeetaNetSDK.Referenced.P2PPeerBase.html +1 -1
  130. package/docs/interfaces/KeetaNetSDK.Referenced.P2PPeerListener.html +1 -1
  131. package/docs/interfaces/KeetaNetSDK.Referenced.P2PPeerRepBase.html +1 -1
  132. package/docs/interfaces/KeetaNetSDK.Referenced.PendingOperations.html +2 -2
  133. package/docs/interfaces/KeetaNetSDK.Referenced.PendingOperationsJSON.html +2 -2
  134. package/docs/interfaces/KeetaNetSDK.Referenced.PrincipalACLWithInfoParsed.html +3 -10
  135. package/docs/interfaces/KeetaNetSDK.Referenced.PublicKeyStorage.html +1 -1
  136. package/docs/interfaces/KeetaNetSDK.Referenced.PublishOptions.html +1 -1
  137. package/docs/interfaces/KeetaNetSDK.Referenced.RequestTokenReceiveEntry.html +1 -1
  138. package/docs/interfaces/KeetaNetSDK.Referenced.StorageAccountInfo.html +12 -0
  139. package/docs/interfaces/KeetaNetSDK.Referenced.TokenAccountInfo.html +14 -0
  140. package/docs/interfaces/KeetaNetSDK.Referenced.TokenNumericEntry.html +1 -1
  141. package/docs/interfaces/KeetaNetSDK.Referenced.UserClientConfig.html +2 -2
  142. package/docs/interfaces/KeetaNetSDK.Referenced.UserClientOptions.html +1 -1
  143. package/docs/interfaces/KeetaNetSDK.Referenced.VoteJSON.html +2 -2
  144. package/docs/interfaces/KeetaNetSDK.Referenced.VoteStapleJSON.html +2 -2
  145. package/docs/interfaces/KeetaNetSDK.Referenced.WithIsInstance.html +1 -1
  146. package/docs/interfaces/KeetaNetSDK.Referenced.signOptionsType.html +16 -3
  147. package/docs/interfaces/KeetaNetSDK.Referenced.src_lib_utils_asn1.ASN1BitString.html +1 -1
  148. package/docs/interfaces/KeetaNetSDK.Referenced.src_lib_utils_asn1.ASN1Date.html +1 -1
  149. package/docs/interfaces/KeetaNetSDK.Referenced.src_lib_utils_asn1.ASN1OID.html +1 -1
  150. package/docs/interfaces/KeetaNetSDK.Referenced.src_lib_utils_asn1.ASN1Set.html +1 -1
  151. package/docs/interfaces/KeetaNetSDK.Referenced.src_lib_utils_asn1.ASN1String.html +1 -1
  152. package/docs/interfaces/KeetaNetSDK.Referenced.src_lib_utils_asn1.ASN1Struct.html +1 -1
  153. package/docs/modules/KeetaNetSDK.Referenced.html +1 -1
  154. package/docs/modules/KeetaNetSDK.Referenced.src_lib_utils_domain-separation.html +1 -0
  155. package/docs/modules/KeetaNetSDK.Referenced.src_lib_utils_helper.html +1 -1
  156. package/docs/types/KeetaNetSDK.Referenced.AccountInfo.html +1 -0
  157. package/docs/types/KeetaNetSDK.Referenced.AccountInfoForType.html +1 -0
  158. package/docs/types/KeetaNetSDK.Referenced.AccountInfoResponse.html +2 -2
  159. package/docs/types/KeetaNetSDK.Referenced.AccountInfoWithoutAccount.html +1 -0
  160. package/docs/types/{KeetaNetSDK.Referenced.src_lib_utils_helper.DistributiveOmit.html → KeetaNetSDK.Referenced.DistributiveOmit.html} +1 -1
  161. package/docs/types/KeetaNetSDK.Referenced.GetAccountStateAPIResponseFormatted.html +5 -12
  162. package/docs/types/KeetaNetSDK.Referenced.KeyPairAccountInfo.html +1 -0
  163. package/docs/types/KeetaNetSDK.Referenced.KeyPairKeyAlgorithm.html +1 -0
  164. package/docs/types/KeetaNetSDK.Referenced.NetworkAddress.html +1 -1
  165. package/docs/types/KeetaNetSDK.Referenced.StorageAddress.html +1 -1
  166. package/docs/types/KeetaNetSDK.Referenced.TokenAddress.html +1 -1
  167. package/docs/types/KeetaNetSDK.Referenced.TokenOrPending.html +1 -1
  168. package/docs/types/KeetaNetSDK.Referenced.UserEditableAccountInfo.html +1 -1
  169. package/docs/types/KeetaNetSDK.Referenced.VoteBuilderOptions.html +2 -2
  170. package/docs/types/KeetaNetSDK.Referenced.src_lib_utils_conversion.ToJSONSerializable.html +1 -1
  171. package/docs/types/KeetaNetSDK.Referenced.src_lib_utils_initial.BaseNetworkInfo.html +1 -1
  172. package/docs/variables/KeetaNetSDK.Referenced.allFullErrorCodes.html +1 -1
  173. package/docs/variables/KeetaNetSDK.Referenced.identifierKeyTypes.html +1 -1
  174. package/docs/variables/KeetaNetSDK.Referenced.src_lib_utils_domain-separation.KeetaNamespaceVersion.html +3 -0
  175. package/docs/variables/KeetaNetSDK.Referenced.src_lib_utils_domain-separation.MaxNamespaceLength.html +3 -0
  176. package/docs/variables/KeetaNetSDK.Referenced.src_lib_utils_domain-separation.namespacePrefixSchema.html +9 -0
  177. package/docs/variables/KeetaNetSDK.lib.html +2 -2
  178. package/lib/account.d.ts +39 -1
  179. package/lib/block/index.d.ts +126 -108
  180. package/lib/block/operations.d.ts +11 -0
  181. package/lib/error/account.d.ts +2 -2
  182. package/lib/error/index.d.ts +1 -1
  183. package/lib/error/vote.d.ts +2 -2
  184. package/lib/index.d.ts +4 -2
  185. package/lib/ledger/common.d.ts +15 -3
  186. package/lib/ledger/db_dynamodb.d.ts +6 -6
  187. package/lib/ledger/db_postgres.d.ts +3 -3
  188. package/lib/ledger/db_spanner.d.ts +4 -4
  189. package/lib/ledger/db_spanner_helper.d.ts +2 -2
  190. package/lib/ledger/db_sqlite.d.ts +3 -3
  191. package/lib/ledger/effects.d.ts +3 -1
  192. package/lib/ledger/index.d.ts +9 -9
  193. package/lib/ledger/types.d.ts +43 -9
  194. package/lib/log/target_gcp.js +3 -0
  195. package/lib/log/target_https.js +7 -0
  196. package/lib/utils/certificate.d.ts +13 -12
  197. package/lib/utils/conversion.d.ts +12 -3
  198. package/lib/utils/domain-separation.d.ts +31 -0
  199. package/lib/utils/external-keys/gcp-kms.d.ts +53 -0
  200. package/lib/utils/external-keys/gcp-kms.js +328 -0
  201. package/lib/utils/external-keys/passkey-prf.d.ts +1 -3
  202. package/lib/utils/external-keys/passkey-prf.js +6 -0
  203. package/lib/utils/helper.d.ts +1 -0
  204. package/lib/utils/initial.d.ts +3 -2
  205. package/lib/utils/never.d.ts +4 -0
  206. package/lib/vote.d.ts +96 -89
  207. package/npm-shrinkwrap.json +30 -12
  208. package/package.json +2 -2
  209. package/version.d.ts +1 -1
  210. package/docs/interfaces/KeetaNetSDK.Referenced.AccountInfo.html +0 -14
package/client/index.js CHANGED
@@ -57355,6 +57355,8 @@ class UserClientBuilder {
57355
57355
  const [base, external] = operations.info.defaultPermission.map(function (intString) {
57356
57356
  return (BigInt(intString));
57357
57357
  });
57358
+ // This is correct as we are constructing this from data that was only set if it was valid
57359
+ // eslint-disable-next-line @typescript-eslint/consistent-type-assertions
57358
57360
  newInfo.defaultPermission = new permissions_1.Permissions(base, external);
57359
57361
  }
57360
57362
  pendingOperations.info = newInfo;
@@ -57588,11 +57590,33 @@ class UserClientBuilder {
57588
57590
  const operations = [];
57589
57591
  for (const vote of staple.votes) {
57590
57592
  if (vote.fee !== undefined) {
57593
+ // Handle both single fee and array of fees
57594
+ // Select one fee: prefer one with undefined token (baseToken) or matching baseToken
57595
+ const fees = Array.isArray(vote.fee) ? vote.fee : [vote.fee];
57596
+ // If there are no fees, skip this vote
57597
+ if (fees.length === 0) {
57598
+ continue;
57599
+ }
57600
+ // If fee options contains an amount of 0, skip this vote
57601
+ if (fees.some(fee => fee.amount === 0n)) {
57602
+ continue;
57603
+ }
57604
+ // Find fee with undefined token or matching baseToken
57605
+ let selectedFee = fees.find((fee) => {
57606
+ if (fee.token === undefined || fee.token.comparePublicKey(baseToken)) {
57607
+ return (true);
57608
+ }
57609
+ return (false);
57610
+ });
57611
+ // If no matching fee, use the first one
57612
+ if (!selectedFee) {
57613
+ selectedFee = fees[0];
57614
+ }
57591
57615
  operations.push({
57592
57616
  type: operations_1.OperationType.SEND,
57593
- amount: vote.fee.amount,
57594
- to: vote.fee.payTo ?? vote.issuer,
57595
- token: vote.fee.token ?? baseToken
57617
+ amount: selectedFee.amount,
57618
+ to: selectedFee.payTo ?? vote.issuer,
57619
+ token: selectedFee.token ?? baseToken
57596
57620
  });
57597
57621
  }
57598
57622
  }
@@ -57709,12 +57733,16 @@ class UserClientBuilder {
57709
57733
  }
57710
57734
  operations.push(...receiveOperations);
57711
57735
  if (pending.info) {
57736
+ let defaultPermission;
57737
+ if ('defaultPermission' in pending.info) {
57738
+ defaultPermission = pending.info.defaultPermission;
57739
+ }
57712
57740
  operations.push({
57713
57741
  type: block_1.Block.OperationType.SET_INFO,
57714
57742
  name: pending.info.name,
57715
57743
  description: pending.info.description,
57716
57744
  metadata: pending.info.metadata,
57717
- defaultPermission: pending.info.defaultPermission
57745
+ defaultPermission: defaultPermission
57718
57746
  });
57719
57747
  }
57720
57748
  if (pending.setRep) {
@@ -58106,7 +58134,7 @@ var __classPrivateFieldGet = (this && this.__classPrivateFieldGet) || function (
58106
58134
  var __importDefault = (this && this.__importDefault) || function (mod) {
58107
58135
  return (mod && mod.__esModule) ? mod : { "default": mod };
58108
58136
  };
58109
- 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;
58137
+ 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_votesRequireFees, _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;
58110
58138
  Object.defineProperty(exports, "__esModule", ({ value: true }));
58111
58139
  exports.lib = exports.UserClient = exports.Client = void 0;
58112
58140
  exports.blockGenerator = blockGenerator;
@@ -58350,13 +58378,7 @@ class Client {
58350
58378
  */
58351
58379
  async transmit(blocks, options) {
58352
58380
  const tempVotes = await __classPrivateFieldGet(this, _Client_instances, "m", _Client_requestVotes).call(this, blocks, undefined, undefined, options?.quotes);
58353
- let requiresFee = false;
58354
- for (const vote of tempVotes) {
58355
- if (vote.fee !== undefined) {
58356
- requiresFee = true;
58357
- }
58358
- }
58359
- if (requiresFee) {
58381
+ if (__classPrivateFieldGet(this, _Client_instances, "m", _Client_votesRequireFees).call(this, tempVotes)) {
58360
58382
  if (options?.generateFeeBlock === undefined) {
58361
58383
  throw (new Error('Votes require fees but generateFeeBlock was not defined'));
58362
58384
  }
@@ -58528,9 +58550,10 @@ class Client {
58528
58550
  }
58529
58551
  });
58530
58552
  const parsed = response.access.map((entry) => {
58553
+ const entity = lib_1.default.Account.fromPublicKeyString(entry.entity);
58531
58554
  return ({
58532
- entity: lib_1.default.Account.fromPublicKeyString(entry.entity),
58533
- info: __classPrivateFieldGet(this, _Client_instances, "m", _Client_formatAccountInfo).call(this, entry.info),
58555
+ entity: entity,
58556
+ info: __classPrivateFieldGet(this, _Client_instances, "m", _Client_formatAccountInfo).call(this, entry.info, entity),
58534
58557
  balances: __classPrivateFieldGet(this, _Client_instances, "m", _Client_formatAllBalances).call(this, entry.balances),
58535
58558
  principals: __classPrivateFieldGet(this, _Client_instances, "m", _Client_parsePermissionEntries).call(this, entry.principals)
58536
58559
  });
@@ -59295,15 +59318,8 @@ class Client {
59295
59318
  tempVotes = [...tempVotes, ...newTempVotes];
59296
59319
  }
59297
59320
  const missingPermReps = __classPrivateFieldGet(this, _Client_reps, "f").filter(rep => !permReps.includes(rep));
59298
- // If any of the temporary votes require a fee, we need to generate a fee block
59299
- let requiresFee = false;
59300
- for (const vote of tempVotes) {
59301
- if (vote.fee !== undefined) {
59302
- requiresFee = true;
59303
- }
59304
- }
59305
59321
  // If we need a fee block and don't have any permanent votes, we need to generate a fee block
59306
- if (requiresFee && permVotes.length === 0) {
59322
+ if (__classPrivateFieldGet(this, _Client_instances, "m", _Client_votesRequireFees).call(this, tempVotes) && permVotes.length === 0) {
59307
59323
  if (options?.generateFeeBlock === undefined) {
59308
59324
  throw (new Error('Votes require fees but generateFeeBlock was not defined'));
59309
59325
  }
@@ -59798,6 +59814,22 @@ async function _Client_apiRaw(rep, api, method, options = {}) {
59798
59814
  return (currentHeadBlock);
59799
59815
  }
59800
59816
  });
59817
+ }, _Client_votesRequireFees = function _Client_votesRequireFees(tempVotes) {
59818
+ let requiresFees = false;
59819
+ for (const vote of tempVotes) {
59820
+ if (vote.fee !== undefined) {
59821
+ const voteFee = Array.isArray(vote.fee) ? vote.fee : [vote.fee];
59822
+ // Check if user has the option to pay zero (any fee with amount === 0)
59823
+ // If a zero-amount option exists, fee block is optional for this vote
59824
+ const hasZeroFeeOption = voteFee.some(fee => fee.amount === 0n);
59825
+ // If no zero option exists (requires payment), fee block is required
59826
+ if (!hasZeroFeeOption) {
59827
+ requiresFees = true;
59828
+ break;
59829
+ }
59830
+ }
59831
+ }
59832
+ return (requiresFees);
59801
59833
  }, _Client_urlSeparatedAccounts = function _Client_urlSeparatedAccounts(accounts) {
59802
59834
  const pubKeys = accounts.map(account => account_1.default.toPublicKeyString(account));
59803
59835
  return (pubKeys.join(','));
@@ -59811,22 +59843,35 @@ async function _Client_apiRaw(rep, api, method, options = {}) {
59811
59843
  }, _Client_parseResponsePermissions = function _Client_parseResponsePermissions(permissions) {
59812
59844
  const [base, external] = permissions.map(val => BigInt(val));
59813
59845
  return (new lib_1.default.Permissions(base, external));
59814
- }, _Client_formatAccountInfo = function _Client_formatAccountInfo(raw) {
59815
- const info = {
59846
+ }, _Client_formatAccountInfo = function _Client_formatAccountInfo(raw, account) {
59847
+ let ret = {
59816
59848
  name: raw.name,
59817
59849
  description: raw.description,
59818
59850
  metadata: raw.metadata
59819
59851
  };
59820
- if (raw.supply !== undefined) {
59821
- info.supply = BigInt(raw.supply);
59822
- }
59823
- if (raw.defaultPermission !== undefined) {
59824
- info.defaultPermission = __classPrivateFieldGet(this, _Client_instances, "m", _Client_parseResponsePermissions).call(this, raw.defaultPermission);
59825
- }
59826
- if (raw.multisigQuorum !== undefined) {
59827
- info.multisigQuorum = BigInt(raw.multisigQuorum);
59852
+ if (account.isIdentifier()) {
59853
+ ret = {
59854
+ ...ret,
59855
+ defaultPermission: raw.defaultPermission !== undefined ? __classPrivateFieldGet(this, _Client_instances, "m", _Client_parseResponsePermissions).call(this, raw.defaultPermission) : undefined
59856
+ };
59857
+ if (account.isMultisig()) {
59858
+ if (raw.multisigQuorum !== undefined) {
59859
+ ret = {
59860
+ ...ret,
59861
+ multisigQuorum: raw.multisigQuorum !== null ? BigInt(raw.multisigQuorum) : null
59862
+ };
59863
+ }
59864
+ }
59865
+ else if (account.isToken()) {
59866
+ if (raw.supply !== undefined) {
59867
+ ret = {
59868
+ ...ret,
59869
+ supply: BigInt(raw.supply)
59870
+ };
59871
+ }
59872
+ }
59828
59873
  }
59829
- return (info);
59874
+ return (ret);
59830
59875
  }, _Client_parseAccountInfo = function _Client_parseAccountInfo(account, accountInfo) {
59831
59876
  account = account_1.default.toAccount(account);
59832
59877
  if (!account.comparePublicKey(accountInfo.account)) {
@@ -59844,11 +59889,11 @@ async function _Client_apiRaw(rep, api, method, options = {}) {
59844
59889
  currentRepresentative = lib_1.default.Account.fromPublicKeyString(accountInfo.representative).assertAccount();
59845
59890
  }
59846
59891
  return ({
59847
- account: lib_1.default.Account.fromPublicKeyString(accountInfo.account),
59892
+ account: lib_1.default.Account.fromPublicKeyString(accountInfo.account).assertKeyType(account.keyType),
59848
59893
  currentHeadBlock: currentHeadBlock,
59849
59894
  currentHeadBlockHeight: accountInfo.currentHeadBlockHeight,
59850
59895
  representative: currentRepresentative,
59851
- info: __classPrivateFieldGet(this, _Client_instances, "m", _Client_formatAccountInfo).call(this, accountInfo.info),
59896
+ info: __classPrivateFieldGet(this, _Client_instances, "m", _Client_formatAccountInfo).call(this, accountInfo.info, account),
59852
59897
  balances: __classPrivateFieldGet(this, _Client_instances, "m", _Client_formatAllBalances).call(this, accountInfo.balances)
59853
59898
  });
59854
59899
  }, _Client_parsePermissionEntries = function _Client_parsePermissionEntries(entries) {
@@ -61331,6 +61376,7 @@ const p256_1 = __webpack_require__(5897);
61331
61376
  const buffer_1 = __webpack_require__(3310);
61332
61377
  const helper_1 = __webpack_require__(3208);
61333
61378
  const hash_1 = __webpack_require__(7908);
61379
+ const domain_separation_1 = __webpack_require__(9061);
61334
61380
  const asn1_1 = __webpack_require__(6045);
61335
61381
  const block_1 = __importStar(__webpack_require__(6158));
61336
61382
  const account_1 = __importDefault(__webpack_require__(4642));
@@ -61601,7 +61647,7 @@ class ExternalKeyPair extends KeyInterface {
61601
61647
  return (__classPrivateFieldGet(this, _ExternalKeyPair_functions, "f").decrypt(...parameters));
61602
61648
  }
61603
61649
  get supportsEncryption() {
61604
- return (true);
61650
+ return (__classPrivateFieldGet(this, _ExternalKeyPair_functions, "f").supportsEncryption);
61605
61651
  }
61606
61652
  get keyType() {
61607
61653
  return (__classPrivateFieldGet(this, _ExternalKeyPair_keyType, "f"));
@@ -62607,6 +62653,9 @@ class Account {
62607
62653
  if (__classPrivateFieldGet(this, _Account_privateKeyPair, "f") === null) {
62608
62654
  throw (new Error('May not sign unless a private key is available'));
62609
62655
  }
62656
+ if (options.namespace !== undefined) {
62657
+ data = (0, domain_separation_1.applyNamespace)(options.namespace, data);
62658
+ }
62610
62659
  if (!__classPrivateFieldGet(this, _Account_keyPairHandlesHashing, "f") && !options.raw) {
62611
62660
  data = (0, hash_1.Hash)(Buffer.from(data));
62612
62661
  }
@@ -62621,6 +62670,9 @@ class Account {
62621
62670
  forCert: false,
62622
62671
  ...options
62623
62672
  };
62673
+ if (options.namespace !== undefined) {
62674
+ data = (0, domain_separation_1.applyNamespace)(options.namespace, data);
62675
+ }
62624
62676
  if (!__classPrivateFieldGet(this, _Account_keyPairHandlesHashing, "f") && !options.raw) {
62625
62677
  data = (0, hash_1.Hash)(Buffer.from(data));
62626
62678
  }
@@ -62753,10 +62805,11 @@ class Account {
62753
62805
  * Determine if an account is an identifier
62754
62806
  */
62755
62807
  isIdentifier() {
62756
- // We are checking here, so it is safe to assert the type
62757
- // eslint-disable-next-line @typescript-eslint/consistent-type-assertions
62758
- return (identifierKeyTypes.includes(this.keyType));
62808
+ return (Account.isIdentifierKeyType(__classPrivateFieldGet(this, _Account_keyType, "f")));
62759
62809
  }
62810
+ /**
62811
+ * Determine if an account is a regular (non-identifier)
62812
+ */
62760
62813
  isAccount() {
62761
62814
  return (!this.isIdentifier());
62762
62815
  }
@@ -62789,7 +62842,7 @@ class Account {
62789
62842
  }
62790
62843
  assertAccount() {
62791
62844
  if (this.isIdentifier() !== false) {
62792
- throw (new Error('Required Account but got Identifier'));
62845
+ throw (new account_1.default('ACCOUNT_NOT_ACCOUNT', 'Required Account but got Identifier'));
62793
62846
  }
62794
62847
  // We need to assert this type because we are changing what the constructed type is
62795
62848
  // eslint-disable-next-line @typescript-eslint/consistent-type-assertions
@@ -62797,7 +62850,7 @@ class Account {
62797
62850
  }
62798
62851
  assertIdentifier() {
62799
62852
  if (this.isIdentifier() !== true) {
62800
- throw (new Error(`Required Identifier but got Account, ${this.keyType}`));
62853
+ throw (new account_1.default('ACCOUNT_NOT_IDENTIFIER', `Required Identifier but got Account, ${this.keyType}`));
62801
62854
  }
62802
62855
  // We need to assert this type because we are changing what the constructed type is
62803
62856
  // eslint-disable-next-line @typescript-eslint/consistent-type-assertions
@@ -62814,6 +62867,18 @@ _Account_privateKeyPair = new WeakMap(), _Account_publicKeyPair = new WeakMap(),
62814
62867
  */
62815
62868
  Account.AccountKeyAlgorithm = AccountKeyAlgorithm;
62816
62869
  Account.ExternalKeyPair = ExternalKeyPair;
62870
+ /**
62871
+ * Access to the underlying Key Pair classes for advanced use cases.
62872
+ */
62873
+ Account.KeyPairs = {
62874
+ [AccountKeyAlgorithm.ECDSA_SECP256K1]: ECDSASECP256K1KeyPair,
62875
+ [AccountKeyAlgorithm.ECDSA_SECP256R1]: ECDSASECP256R1KeyPair,
62876
+ [AccountKeyAlgorithm.ED25519]: ED25519KeyPair,
62877
+ [AccountKeyAlgorithm.NETWORK]: IdentifierKeyPair,
62878
+ [AccountKeyAlgorithm.TOKEN]: IdentifierKeyPair,
62879
+ [AccountKeyAlgorithm.STORAGE]: IdentifierKeyPair,
62880
+ [AccountKeyAlgorithm.MULTISIG]: IdentifierKeyPair
62881
+ };
62817
62882
  Account.isInstance = (0, helper_2.checkableGenerator)(Account);
62818
62883
  Account.Set = (0, helper_1.setGenerator)(Account, function (account) {
62819
62884
  const retval = account.publicKeyAndTypeString;
@@ -63753,7 +63818,7 @@ _a = PossiblyUnsignedBlock, _PossiblyUnsignedBlock_valueBytes = new WeakMap(), _
63753
63818
  if (!recalculatedBytesBuffer.equals(existingBytesBuffer)) {
63754
63819
  const existingBytesHash = Buffer.from((0, hash_1.Hash)(existingBytesBuffer)).toString('hex').toUpperCase();
63755
63820
  const recalculatedBytesHash = Buffer.from((0, hash_1.Hash)(recalculatedBytesBuffer)).toString('hex').toUpperCase();
63756
- throw (new block_1.default('BLOCK_INVALID_SIGNATURE', `Block signed bytes (${existingBytesHash}) do not match calculated bytes (${recalculatedBytesHash})`));
63821
+ throw (new block_1.default('BLOCK_INVALID_SIGNATURE', `Block signed bytes (${existingBytesHash}) do not match calculated bytes (${recalculatedBytesHash}) for block with hash ${this.hash.toString()}`));
63757
63822
  }
63758
63823
  }, _PossiblyUnsignedBlock_validateOperationsPurpose = function _PossiblyUnsignedBlock_validateOperationsPurpose() {
63759
63824
  /**
@@ -63914,8 +63979,9 @@ class UnsignedBlock extends PossiblyUnsignedBlock {
63914
63979
  async seal() {
63915
63980
  const signers = UnsignedBlock.getSortedRequiredSigners(this.signer);
63916
63981
  const hash = this.hash;
63982
+ const ancillaryData = this.toBytes(false);
63917
63983
  const signatures = await Promise.all(signers.map(async function (signer) {
63918
- const signature = await signer.sign(hash.getBuffer());
63984
+ const signature = await signer.sign(hash.getBuffer(), { ancillaryData });
63919
63985
  return (signature.getBuffer());
63920
63986
  }));
63921
63987
  const shared = {
@@ -64440,6 +64506,29 @@ function operationTypeToNumber(str) {
64440
64506
  }
64441
64507
  return (type);
64442
64508
  }
64509
+ function makeEncodeDecodePermission(emptyValue) {
64510
+ return {
64511
+ encode: (data) => {
64512
+ if (!data) {
64513
+ return (emptyValue);
64514
+ }
64515
+ const encoded = permissions_1.Permissions.FromAcceptedTypes(data);
64516
+ return ([encoded.base.bigint, encoded.external.bigint]);
64517
+ },
64518
+ decode: (data) => {
64519
+ if (!data) {
64520
+ return (emptyValue);
64521
+ }
64522
+ if (!Array.isArray(data) || data.length !== 2) {
64523
+ throw (new Error('Invalid permissions data'));
64524
+ }
64525
+ if (typeof data[0] !== 'bigint' || typeof data[1] !== 'bigint') {
64526
+ throw (new Error('Invalid permissions data types'));
64527
+ }
64528
+ return (new permissions_1.Permissions(data[0], data[1]));
64529
+ }
64530
+ };
64531
+ }
64443
64532
  /**
64444
64533
  * Schema for each operation as well as names of each field within the block operations
64445
64534
  */
@@ -64464,17 +64553,25 @@ const BlockOperationASN1SchemaBase = {
64464
64553
  { name: 'name', schema: { type: 'string', kind: 'utf8' } },
64465
64554
  { name: 'description', schema: { type: 'string', kind: 'utf8' } },
64466
64555
  { name: 'metadata', schema: { type: 'string', kind: 'utf8' } },
64467
- { name: 'defaultPermission', schema: { optional: [asn1_1.ValidateASN1.IsInteger, asn1_1.ValidateASN1.IsInteger] } }
64556
+ {
64557
+ name: 'defaultPermission',
64558
+ schema: { optional: [asn1_1.ValidateASN1.IsInteger, asn1_1.ValidateASN1.IsInteger] },
64559
+ ...(makeEncodeDecodePermission(undefined))
64560
+ }
64468
64561
  ],
64469
64562
  'MODIFY_PERMISSIONS': [
64470
64563
  { name: 'principal', schema: asn1_1.ValidateASN1.IsOctetString },
64471
64564
  { name: 'method', schema: asn1_1.ValidateASN1.IsInteger },
64472
- { name: 'permissions', schema: {
64565
+ {
64566
+ name: 'permissions',
64567
+ schema: {
64473
64568
  choice: [
64474
64569
  asn1_1.ValidateASN1.IsNull,
64475
64570
  [asn1_1.ValidateASN1.IsInteger, asn1_1.ValidateASN1.IsInteger]
64476
64571
  ]
64477
- } },
64572
+ },
64573
+ ...(makeEncodeDecodePermission(null))
64574
+ },
64478
64575
  { name: 'target', schema: { optional: asn1_1.ValidateASN1.IsOctetString } }
64479
64576
  ],
64480
64577
  'CREATE_IDENTIFIER': [
@@ -64495,6 +64592,62 @@ const BlockOperationASN1SchemaBase = {
64495
64592
  }
64496
64593
  ]
64497
64594
  }
64595
+ },
64596
+ encode: (data) => {
64597
+ if (!data) {
64598
+ return (null);
64599
+ }
64600
+ if (data.type === account_1.AccountKeyAlgorithm.MULTISIG) {
64601
+ return ({
64602
+ type: 'context',
64603
+ kind: 'explicit',
64604
+ value: data.type,
64605
+ contains: [
64606
+ data.signers.map(function (signer) {
64607
+ return (signer.publicKeyAndType);
64608
+ }),
64609
+ data.quorum
64610
+ ]
64611
+ });
64612
+ }
64613
+ else {
64614
+ throw (new Error(`Unrecognized createArguments type for CREATE_IDENTIFIER operation`));
64615
+ }
64616
+ },
64617
+ decode: (data) => {
64618
+ if (!data) {
64619
+ return (undefined);
64620
+ }
64621
+ if (!asn1_1.ASN1CheckUtilities.isASN1ContextTag(data, 'explicit')) {
64622
+ throw (new Error('Invalid createArgs type for CREATE_IDENTIFIER operation'));
64623
+ }
64624
+ if (data.value === account_1.AccountKeyAlgorithm.MULTISIG) {
64625
+ if (!Array.isArray(data.contains) || data.contains.length !== 2) {
64626
+ throw (new Error('Invalid createArgs container'));
64627
+ }
64628
+ if (!Array.isArray(data.contains[0]) || typeof data.contains[1] !== 'bigint') {
64629
+ throw (new Error('Invalid createArgs container'));
64630
+ }
64631
+ return ({
64632
+ type: data.value,
64633
+ signers: data.contains[0].map(function (value) {
64634
+ if (!Buffer.isBuffer(value)) {
64635
+ throw (new Error(`Invalid signer value, expected Buffer, got ${typeof value}`));
64636
+ }
64637
+ const account = account_1.default.fromPublicKeyAndType(value);
64638
+ if (account.isAccount() || account.isMultisig()) {
64639
+ return (account);
64640
+ }
64641
+ else {
64642
+ throw (new Error('Signer for multisig must be an account or another multisig'));
64643
+ }
64644
+ }),
64645
+ quorum: BigInt(data.contains[1])
64646
+ });
64647
+ }
64648
+ else {
64649
+ throw (new Error('unrecognized type for multisig create arguments'));
64650
+ }
64498
64651
  }
64499
64652
  }
64500
64653
  ],
@@ -64509,10 +64662,60 @@ const BlockOperationASN1SchemaBase = {
64509
64662
  ],
64510
64663
  'MANAGE_CERTIFICATE': [
64511
64664
  { name: 'method', schema: asn1_1.ValidateASN1.IsInteger },
64512
- { name: 'certificateOrHash', schema: asn1_1.ValidateASN1.IsOctetString },
64513
- { name: 'intermediateCertificates', schema: {
64665
+ {
64666
+ name: 'certificateOrHash',
64667
+ schema: asn1_1.ValidateASN1.IsOctetString,
64668
+ encode: (data) => {
64669
+ if (certificate_1.Certificate.isCertificate(data)) {
64670
+ return (Buffer.from(data.toDER()));
64671
+ }
64672
+ else if (certificate_1.CertificateHash.isInstance(data)) {
64673
+ return (data.getBuffer());
64674
+ }
64675
+ else {
64676
+ throw (new Error('Invalid certificate or hash data type'));
64677
+ }
64678
+ },
64679
+ decode: (data) => {
64680
+ if (!(0, helper_1.isBuffer)(data)) {
64681
+ throw (new Error('Invalid certificate or hash data type'));
64682
+ }
64683
+ if (data.length === 32) {
64684
+ return (new certificate_1.CertificateHash(data.toString('hex')));
64685
+ }
64686
+ else {
64687
+ return (new certificate_1.Certificate(data));
64688
+ }
64689
+ }
64690
+ },
64691
+ {
64692
+ name: 'intermediateCertificates',
64693
+ schema: {
64514
64694
  optional: { choice: [asn1_1.ValidateASN1.IsNull, { sequenceOf: asn1_1.ValidateASN1.IsOctetString }] }
64515
- } }
64695
+ },
64696
+ decode: (data) => {
64697
+ if (!data) {
64698
+ return (null);
64699
+ }
64700
+ if (!Array.isArray(data)) {
64701
+ throw (new Error('Invalid intermediate certificates data'));
64702
+ }
64703
+ return (new certificate_1.CertificateBundle(data.map(function (certificate) {
64704
+ if (!(0, helper_1.isBuffer)(certificate)) {
64705
+ throw (new Error('Invalid intermediate certificate data type'));
64706
+ }
64707
+ return (new certificate_1.Certificate(certificate));
64708
+ })));
64709
+ },
64710
+ encode: (data) => {
64711
+ if (!data) {
64712
+ return (null);
64713
+ }
64714
+ return (data.getCertificates().map(function (certificate) {
64715
+ return (Buffer.from(certificate.toDER()));
64716
+ }));
64717
+ }
64718
+ }
64516
64719
  ]
64517
64720
  };
64518
64721
  /**
@@ -64818,8 +65021,8 @@ class BlockOperationSET_REP extends BlockOperation {
64818
65021
  }
64819
65022
  validate(context) {
64820
65023
  const { block } = context;
64821
- if (block.account.isIdentifier()) {
64822
- throw (new block_1.default('BLOCK_NO_IDENTIFIER_OP', 'Identifier accounts cannot use SET_REP'));
65024
+ if (!(0, common_1.canDelegate)(block.account.keyType)) {
65025
+ throw (new block_1.default('BLOCK_NO_IDENTIFIER_OP', `${account_1.AccountKeyAlgorithm[block.account.keyType]} accounts cannot use SET_REP`));
64823
65026
  }
64824
65027
  if (this.to.isIdentifier()) {
64825
65028
  throw (new block_1.default('BLOCK_NO_IDENTIFIER_OP', 'Cannot delegate to an identifier'));
@@ -65399,13 +65602,14 @@ function ExportBlockOperations(operations) {
65399
65602
  for (const entry of operations) {
65400
65603
  const operationContainer = [];
65401
65604
  const typeStr = operationTypeToString(entry.type);
65402
- const operationSchema = BlockOperationASN1SchemaBase[typeStr];
65403
- if (!typeStr || !operationSchema) {
65605
+ const operationSchemas = BlockOperationASN1SchemaBase[typeStr];
65606
+ if (!typeStr || !operationSchemas) {
65404
65607
  throw (new Error(`Unable to serialize operation with type ${entry.type} ${(0, conversion_1.toJSONSerializable)(entry)}`));
65405
65608
  }
65406
65609
  // We want to be able to read any key on the operation, so we need to cast it to any
65407
65610
  const unTypedEntry = entry;
65408
- for (const { name: key, schema } of operationSchema) {
65611
+ for (const operationSchema of operationSchemas) {
65612
+ const { name: key, schema } = operationSchema;
65409
65613
  let valueToWrite = unTypedEntry[key];
65410
65614
  if (valueToWrite === undefined) {
65411
65615
  if (typeof schema === 'object' && schema && !('optional' in schema)) {
@@ -65413,21 +65617,8 @@ function ExportBlockOperations(operations) {
65413
65617
  }
65414
65618
  continue;
65415
65619
  }
65416
- else if (typeStr === 'CREATE_IDENTIFIER' && key === 'createArguments') {
65417
- // We are checking this in other places, and if this argument changes there will be many other things that break beforehand
65418
- // eslint-disable-next-line @typescript-eslint/consistent-type-assertions
65419
- const typedValue = valueToWrite;
65420
- valueToWrite = {
65421
- type: 'context',
65422
- kind: 'explicit',
65423
- value: valueToWrite.type,
65424
- contains: [
65425
- typedValue.signers.map(function (signer) {
65426
- return (signer.publicKeyAndType);
65427
- }),
65428
- typedValue.quorum
65429
- ]
65430
- };
65620
+ else if ('encode' in operationSchema) {
65621
+ valueToWrite = operationSchema.encode(valueToWrite);
65431
65622
  }
65432
65623
  else if (typeof valueToWrite === 'string') {
65433
65624
  valueToWrite = { type: 'string', kind: 'utf8', value: valueToWrite };
@@ -65435,20 +65626,12 @@ function ExportBlockOperations(operations) {
65435
65626
  else if (account_1.default.isInstance(valueToWrite)) {
65436
65627
  valueToWrite = valueToWrite.publicKeyAndType;
65437
65628
  }
65438
- else if (permissions_1.Permissions.isInstance(valueToWrite)) {
65439
- valueToWrite = [valueToWrite.base.bigint, valueToWrite.external.bigint];
65440
- }
65441
65629
  else if (certificate_1.Certificate.isCertificate(valueToWrite)) {
65442
65630
  valueToWrite = Buffer.from(valueToWrite.toDER());
65443
65631
  }
65444
65632
  else if (certificate_1.CertificateHash.isInstance(valueToWrite)) {
65445
65633
  valueToWrite = valueToWrite.getBuffer();
65446
65634
  }
65447
- else if (certificate_1.CertificateBundle.isInstance(valueToWrite)) {
65448
- valueToWrite = valueToWrite.getCertificates().map(function (certificate) {
65449
- return (Buffer.from(certificate.toDER()));
65450
- });
65451
- }
65452
65635
  operationContainer.push(valueToWrite);
65453
65636
  }
65454
65637
  container.push({
@@ -65474,19 +65657,23 @@ function ImportOperationsASN1(input, network) {
65474
65657
  throw (new Error(`Found entry which is not a Sequence ${typeof entry}`));
65475
65658
  }
65476
65659
  const typeStr = operationTypeToString(type);
65477
- const operationSchema = BlockOperationASN1SchemaBase[typeStr];
65478
- if (!operationSchema) {
65660
+ const operationSchemas = BlockOperationASN1SchemaBase[typeStr];
65661
+ if (!operationSchemas) {
65479
65662
  throw (new Error(`Found valid operation ${typeStr} with invalid keys`));
65480
65663
  }
65481
65664
  operation.type = type;
65482
65665
  let keyIndex = -1;
65483
- for (const { name: key } of operationSchema) {
65666
+ for (const operationSchema of operationSchemas) {
65667
+ const key = operationSchema.name;
65484
65668
  keyIndex++;
65485
65669
  const keyValueIn = entry[keyIndex];
65486
65670
  let keyValueOut = undefined;
65487
65671
  if (keyValueIn === undefined) {
65488
65672
  break;
65489
65673
  }
65674
+ else if ('decode' in operationSchema) {
65675
+ keyValueOut = operationSchema.decode(keyValueIn);
65676
+ }
65490
65677
  else if (['bigint', 'string', 'boolean'].includes(typeof keyValueIn)) {
65491
65678
  keyValueOut = keyValueIn;
65492
65679
  }
@@ -65496,58 +65683,8 @@ function ImportOperationsASN1(input, network) {
65496
65683
  else if (keyValueIn === null) {
65497
65684
  keyValueOut = null;
65498
65685
  }
65499
- else if (Array.isArray(keyValueIn) && key.toLowerCase().includes('permission')) {
65500
- // We are parsing a Permission
65501
- const [base, external] = keyValueIn;
65502
- const newKeyValue = new permissions_1.Permissions(base, external);
65503
- newKeyValue.validate(network);
65504
- keyValueOut = newKeyValue;
65505
- }
65506
- else if (key === 'createArguments' && typeStr === 'CREATE_IDENTIFIER') {
65507
- if (!asn1_1.ASN1CheckUtilities.isASN1ContextTag(keyValueIn, 'explicit')) {
65508
- throw (new Error('Invalid createArgs type for CREATE_IDENTIFIER operation'));
65509
- }
65510
- if (keyValueIn.value !== account_1.AccountKeyAlgorithm.MULTISIG) {
65511
- throw (new Error('unrecognized type for multisig create arguments'));
65512
- }
65513
- if (!Array.isArray(keyValueIn.contains) || keyValueIn.contains.length !== 2) {
65514
- throw (new Error('Invalid createArgs container'));
65515
- }
65516
- if (!Array.isArray(keyValueIn.contains[0])) {
65517
- throw (new Error('Invalid createArgs container'));
65518
- }
65519
- keyValueOut = {
65520
- type: keyValueIn.value,
65521
- signers: keyValueIn.contains[0].map(function (value) {
65522
- if (!Buffer.isBuffer(value)) {
65523
- throw (new Error(`Invalid signer value, expected Buffer, got ${typeof value}`));
65524
- }
65525
- return (account_1.default.fromPublicKeyAndType(value));
65526
- }),
65527
- quorum: keyValueIn.contains[1]
65528
- };
65529
- }
65530
- else if (Array.isArray(keyValueIn) && key === 'intermediateCertificates') {
65531
- keyValueOut = new certificate_1.CertificateBundle(keyValueIn.map(function (certificate) {
65532
- return (new certificate_1.Certificate(certificate));
65533
- }));
65534
- }
65535
65686
  else if ((0, helper_1.isBuffer)(keyValueIn)) {
65536
- if (type === OperationType.MANAGE_CERTIFICATE && key === 'certificateOrHash') {
65537
- const method = (0, _1.toAdjustMethod)(operation['method']);
65538
- if (method === _1.AdjustMethod.SUBTRACT) {
65539
- keyValueOut = new certificate_1.CertificateHash(keyValueIn);
65540
- }
65541
- else if (method === _1.AdjustMethod.ADD) {
65542
- keyValueOut = new certificate_1.Certificate(keyValueIn);
65543
- }
65544
- else {
65545
- throw (new Error(`Unrecognized method for MANAGE_CERTIFICATE operation: ${method}`));
65546
- }
65547
- }
65548
- else {
65549
- keyValueOut = account_1.default.fromPublicKeyAndType(keyValueIn);
65550
- }
65687
+ keyValueOut = account_1.default.fromPublicKeyAndType(keyValueIn);
65551
65688
  }
65552
65689
  else if (typeof keyValueIn === 'object' && keyValueIn !== null) {
65553
65690
  if (('type' in keyValueIn) && ('kind' in keyValueIn) && ('value' in keyValueIn)) {
@@ -65589,12 +65726,16 @@ exports.AccountErrorCodes = [
65589
65726
  'INVALID_CONSTRUCTION',
65590
65727
  'NO_IDENTIFIER_SIGN',
65591
65728
  'NO_IDENTIFIER_VERIFY',
65729
+ 'NOT_ACCOUNT',
65730
+ 'NOT_IDENTIFIER',
65592
65731
  'INVALID_IDENTIFIER_CONSTRUCTION',
65593
65732
  'SEED_INDEX_UNDEFINED',
65594
65733
  'SEED_INDEX_NEGATIVE',
65595
65734
  'SEED_INDEX_NOT_INT',
65596
65735
  'SEED_INDEX_TOO_LARGE',
65597
- 'ENCRYPTION_NOT_SUPPORTED'
65736
+ 'ENCRYPTION_NOT_SUPPORTED',
65737
+ 'NAMESPACE_EMPTY',
65738
+ 'NAMESPACE_TOO_LONG'
65598
65739
  ];
65599
65740
  exports.FullAccountErrorCodes = exports.AccountErrorCodes.map(code => `${AccountErrorType}_${code}`);
65600
65741
  class KeetaNetAccountError extends base_1.KeetaNetErrorBase {
@@ -66220,6 +66361,7 @@ exports.VoteErrorCodes = [
66220
66361
  'BUILDER_INVALID_BLOCK_TYPE',
66221
66362
  'BUILDER_INVALID_SERIAL',
66222
66363
  'BUILDER_INVALID_VALID_TO_FROM',
66364
+ 'BUILDER_INVALID_FEE',
66223
66365
  /**
66224
66366
  * Malformed ASN.1 Errors
66225
66367
  */
@@ -66274,6 +66416,8 @@ exports.VoteErrorCodes = [
66274
66416
  'MALFORMED_FEES_AMOUNT',
66275
66417
  'MALFORMED_FEES_FROM_VOTE_INVALID_INPUT',
66276
66418
  'MALFORMED_FEES_IN_PERMANENT_VOTE',
66419
+ 'MALFORMED_FEES_INVALID_QUOTE_VALUE',
66420
+ 'MALFORMED_FEES_MULTIPLE_FEE_EMPTY',
66277
66421
  'MALFORMED_FEES_PAY_TO_INVALID',
66278
66422
  'MALFORMED_FEES_TOKEN_NOT_TOKEN',
66279
66423
  // Fee Quote Errors
@@ -66340,6 +66484,7 @@ const error_1 = __webpack_require__(5390);
66340
66484
  const ASN1 = __importStar(__webpack_require__(6045));
66341
66485
  const Bloom = __importStar(__webpack_require__(7313));
66342
66486
  const Buffer = __importStar(__webpack_require__(3310));
66487
+ const DomainSeparation = __importStar(__webpack_require__(9061));
66343
66488
  const Hash = __importStar(__webpack_require__(7908));
66344
66489
  const Helper = __importStar(__webpack_require__(3208));
66345
66490
  const Initial = __importStar(__webpack_require__(3750));
@@ -66364,11 +66509,12 @@ exports["default"] = {
66364
66509
  ASN1,
66365
66510
  Bloom,
66366
66511
  Buffer,
66512
+ Certificate,
66513
+ Conversion,
66514
+ DomainSeparation,
66367
66515
  Hash,
66368
66516
  Helper,
66369
- Initial,
66370
- Conversion,
66371
- Certificate
66517
+ Initial
66372
66518
  }
66373
66519
  };
66374
66520
 
@@ -66643,6 +66789,7 @@ exports.validateSupply = validateSupply;
66643
66789
  exports.validateNumericValue = validateNumericValue;
66644
66790
  exports.validateBlockSignerCount = validateBlockSignerCount;
66645
66791
  exports.validateBlockSignerDepth = validateBlockSignerDepth;
66792
+ exports.canDelegate = canDelegate;
66646
66793
  exports.computeLedgerEffect = computeLedgerEffect;
66647
66794
  exports.addTimeStatistic = addTimeStatistic;
66648
66795
  exports.assertLedgerStorage = assertLedgerStorage;
@@ -66704,6 +66851,29 @@ function validateBlockSignerDepth(depth, network) {
66704
66851
  throw (new block_2.default('BLOCK_INVALID_MULTISIG_SIGNER_DEPTH', `signer depth does not fit proper format -- GOT: '${depth}' MaxValue: ${maxValue}`));
66705
66852
  }
66706
66853
  }
66854
+ /**
66855
+ * Determines if an account type can delegate voting weight via SET_REP.
66856
+ *
66857
+ * Regular accounts (ECDSA_SECP256K1, ED25519, ECDSA_SECP256R1) can always delegate.
66858
+ * Among identifier accounts, only STORAGE accounts can delegate.
66859
+ * TOKEN, NETWORK, and MULTISIG identifier accounts cannot delegate.
66860
+ *
66861
+ * @param keyType - The account key algorithm type to check
66862
+ * @returns true if the account type can use SET_REP to delegate, false otherwise
66863
+ *
66864
+ */
66865
+ function canDelegate(keyType) {
66866
+ // Regular accounts (non-identifiers) can always delegate
66867
+ if (!account_1.default.isIdentifierKeyType(keyType)) {
66868
+ return (true);
66869
+ }
66870
+ // Among identifiers, only STORAGE can delegate
66871
+ if (keyType === account_1.AccountKeyAlgorithm.STORAGE) {
66872
+ return (true);
66873
+ }
66874
+ // Other identifier accounts cannot delegate
66875
+ return (false);
66876
+ }
66707
66877
  /**
66708
66878
  * Compute effects on the ledger from block effects
66709
66879
  */
@@ -66747,7 +66917,10 @@ async function computeLedgerEffect(options, effects, storageProvider, network, t
66747
66917
  if (getAccountInfoPromises[accountPubKey] === undefined) {
66748
66918
  getAccountInfoPromises[accountPubKey] = storageProvider.getAccountInfo(transaction, account);
66749
66919
  }
66750
- return (await getAccountInfoPromises[accountPubKey]);
66920
+ // We know this is correct as we are accessing the object via the account's public key
66921
+ // eslint-disable-next-line @typescript-eslint/consistent-type-assertions
66922
+ const resolved = await getAccountInfoPromises[accountPubKey];
66923
+ return (resolved);
66751
66924
  };
66752
66925
  const getPermissionPromises = {};
66753
66926
  const getPermissions = async (account, entityList) => {
@@ -66782,7 +66955,7 @@ async function computeLedgerEffect(options, effects, storageProvider, network, t
66782
66955
  const delegationField = effects[accountPubKey]?.fields.delegation;
66783
66956
  const isDelegating = delegationField !== undefined;
66784
66957
  let requestedRep = false;
66785
- if (isDelegating && computeWeights && getFinalNumericValues && account.isAccount()) {
66958
+ if (isDelegating && computeWeights && getFinalNumericValues && canDelegate(account.keyType)) {
66786
66959
  requestedRep = true;
66787
66960
  prefetchPromises.push(getRep(account, getFinalNumericValues));
66788
66961
  prefetchPromises.push(getWeight(delegationField.delegateTo));
@@ -66810,7 +66983,7 @@ async function computeLedgerEffect(options, effects, storageProvider, network, t
66810
66983
  if ((possibleNegative && checkRangeConstraints) || set || getFinalNumericValues || (isDelegating && computeWeights)) {
66811
66984
  prefetchPromises.push(getPreviousBalance(account, token));
66812
66985
  }
66813
- if (computeWeights && isBaseToken && account.isAccount() && !requestedRep) {
66986
+ if (computeWeights && isBaseToken && canDelegate(account.keyType) && !requestedRep) {
66814
66987
  requestedRep = true;
66815
66988
  prefetchPromises.push(getRep(account, getFinalNumericValues));
66816
66989
  }
@@ -66946,7 +67119,7 @@ async function computeLedgerEffect(options, effects, storageProvider, network, t
66946
67119
  }
66947
67120
  const delegationField = effects[accountPubKey]?.fields.delegation;
66948
67121
  const isDelegating = delegationField !== undefined;
66949
- if (isDelegating && account.isAccount() && computeWeights) {
67122
+ if (isDelegating && canDelegate(account.keyType) && computeWeights) {
66950
67123
  const currentDelegation = await getRep(account, getFinalNumericValues);
66951
67124
  const previousBalance = await getPreviousBalance(account, baseToken);
66952
67125
  await modifyWeight(delegationField.delegateTo, previousBalance);
@@ -67000,7 +67173,7 @@ async function computeLedgerEffect(options, effects, storageProvider, network, t
67000
67173
  receivable[otherAccountPubKey][tokenPubKey] += balanceChange;
67001
67174
  }
67002
67175
  const isBaseToken = baseToken.comparePublicKey(tokenAcct);
67003
- if (isBaseToken && account.isAccount() && computeWeights) {
67176
+ if (isBaseToken && canDelegate(account.keyType) && computeWeights) {
67004
67177
  if (isDelegating) {
67005
67178
  await modifyWeight(delegationField.delegateTo, balanceChange);
67006
67179
  }
@@ -67180,7 +67353,8 @@ class LedgerStorageBase {
67180
67353
  return blockHeights;
67181
67354
  }
67182
67355
  _formatAccountInfoFromRow(account, row = {}) {
67183
- const ret = {
67356
+ const shared = {
67357
+ account: account,
67184
67358
  name: row.name ?? '',
67185
67359
  description: row.description ?? '',
67186
67360
  metadata: row.metadata ?? ''
@@ -67194,15 +67368,42 @@ class LedgerStorageBase {
67194
67368
  if (!permissions_1.Permissions.ExternalSet.isInstance(externalSet)) {
67195
67369
  externalSet = BigInt(externalSet);
67196
67370
  }
67197
- ret.defaultPermission = new permissions_1.Permissions(baseSet, externalSet);
67371
+ const identifierShared = {
67372
+ ...shared,
67373
+ defaultPermission: new permissions_1.Permissions(baseSet, externalSet)
67374
+ };
67375
+ if (account.isToken()) {
67376
+ return ({
67377
+ ...identifierShared,
67378
+ account: account,
67379
+ supply: BigInt(row.supply ?? 0)
67380
+ });
67381
+ }
67382
+ else if (account.isMultisig()) {
67383
+ return ({
67384
+ ...identifierShared,
67385
+ account: account,
67386
+ multisigQuorum: row.multisigQuorum ? BigInt(row.multisigQuorum) : null
67387
+ });
67388
+ }
67389
+ else if (account.isNetwork()) {
67390
+ return ({ ...identifierShared, account });
67391
+ }
67392
+ else if (account.isStorage()) {
67393
+ return ({ ...identifierShared, account });
67394
+ }
67395
+ else {
67396
+ throw (new Error('Unsupported identifier account type for AccountInfo'));
67397
+ }
67198
67398
  }
67199
- if (account.isToken()) {
67200
- ret.supply = BigInt(row.supply ?? 0);
67399
+ else if (account.isAccount()) {
67400
+ // We know that this type is correct, the only way to avoid this assertion is to have an if statement for every single account type which would be unwieldy
67401
+ // eslint-disable-next-line @typescript-eslint/consistent-type-assertions
67402
+ return ({ ...shared, account: account });
67201
67403
  }
67202
- if (account.isMultisig() && row.multisigQuorum !== undefined) {
67203
- ret.multisigQuorum = BigInt(row.multisigQuorum);
67404
+ else {
67405
+ throw (new Error('Unsupported account type for AccountInfo'));
67204
67406
  }
67205
- return (ret);
67206
67407
  }
67207
67408
  _validateAccountInfoKeys(account, info) {
67208
67409
  const validKeys = ['name', 'description', 'metadata'];
@@ -67217,6 +67418,7 @@ class LedgerStorageBase {
67217
67418
  }
67218
67419
  const keys = Object.keys(info);
67219
67420
  const foundBannedKey = keys.find(function (key) {
67421
+ // eslint-disable-next-line @typescript-eslint/consistent-type-assertions
67220
67422
  return (validKeys.includes(key) === false);
67221
67423
  });
67222
67424
  if (foundBannedKey !== undefined) {
@@ -67446,7 +67648,7 @@ function addPermissionRequirement(state, requirement) {
67446
67648
  }
67447
67649
  if (state.accounts[entityPubKey] !== undefined) {
67448
67650
  const entityInfo = state.accounts[entityPubKey].fields.info;
67449
- if (entityInfo !== undefined) {
67651
+ if (entityInfo !== undefined && 'defaultPermission' in entityInfo) {
67450
67652
  const defaultPermission = entityInfo.defaultPermission;
67451
67653
  if (defaultPermission !== undefined) {
67452
67654
  if (requirement.permissions === null || defaultPermission.has(requirement.permissions)) {
@@ -67517,17 +67719,25 @@ function modifyBalanceInState(balanceState) {
67517
67719
  }
67518
67720
  function updateAccountInfoInState(state, account, info) {
67519
67721
  const accountPubKey = account.publicKeyString.get();
67520
- const toUpdate = {
67722
+ let toUpdate = {
67521
67723
  name: info.name,
67522
67724
  description: info.description,
67523
67725
  metadata: info.metadata
67524
67726
  };
67525
67727
  if (account.isIdentifier()) {
67526
- if (info.defaultPermission !== undefined) {
67527
- toUpdate.defaultPermission = info.defaultPermission;
67728
+ if ('defaultPermission' in info && info.defaultPermission !== undefined) {
67729
+ toUpdate = {
67730
+ ...toUpdate,
67731
+ defaultPermission: info.defaultPermission
67732
+ };
67528
67733
  }
67529
- if (account.isMultisig() && info.multisigQuorum !== undefined) {
67530
- toUpdate.multisigQuorum = info.multisigQuorum;
67734
+ if (account.isMultisig()) {
67735
+ if ('multisigQuorum' in info && info.multisigQuorum !== undefined) {
67736
+ toUpdate = {
67737
+ ...toUpdate,
67738
+ multisigQuorum: info.multisigQuorum
67739
+ };
67740
+ }
67531
67741
  }
67532
67742
  }
67533
67743
  else {
@@ -68216,6 +68426,7 @@ const never_1 = __webpack_require__(8692);
68216
68426
  const ledger_1 = __webpack_require__(452);
68217
68427
  const permissions_1 = __webpack_require__(5860);
68218
68428
  const effects_1 = __webpack_require__(7346);
68429
+ const types_1 = __webpack_require__(5773);
68219
68430
  const conversion_1 = __webpack_require__(2360);
68220
68431
  const cache_1 = __importDefault(__webpack_require__(5834));
68221
68432
  const timing_1 = __webpack_require__(2895);
@@ -68375,6 +68586,14 @@ class LedgerAtomicInterface {
68375
68586
  if (!quote.issuer.comparePublicKey(ledgerPubKey)) {
68376
68587
  throw (new ledger_1.KeetaNetLedgerError('LEDGER_QUOTE_MISMATCH', 'Provided quote does not match issuer public key'));
68377
68588
  }
68589
+ if (quote.blocks.length !== blocks.length) {
68590
+ throw (new ledger_1.KeetaNetLedgerError('LEDGER_QUOTE_MISMATCH', 'Provided quote does not match blocks length'));
68591
+ }
68592
+ for (let blockIndex = 0; blockIndex < blocks.length; blockIndex++) {
68593
+ if (!blocks[blockIndex].hash.compareHexString(quote.blocks[blockIndex])) {
68594
+ throw (new ledger_1.KeetaNetLedgerError('LEDGER_QUOTE_MISMATCH', 'Provided quote does not match blocks content'));
68595
+ }
68596
+ }
68378
68597
  }
68379
68598
  /**
68380
68599
  * Verify some attributes about the other votes if they are provided
@@ -68399,6 +68618,7 @@ class LedgerAtomicInterface {
68399
68618
  }
68400
68619
  }
68401
68620
  const requiredFees = new Map();
68621
+ const optionalFees = new Map();
68402
68622
  for (const checkVote of otherVotes) {
68403
68623
  if (checkVote.quote === true) {
68404
68624
  throw (new ledger_1.KeetaNetLedgerError('LEDGER_VOTE_WITH_QUOTE', 'Cannot request votes with quote as supporting votes'));
@@ -68412,7 +68632,18 @@ class LedgerAtomicInterface {
68412
68632
  seenVoteIssuers.add(checkVote.issuer);
68413
68633
  seenVoteUIDs.add(checkVote.$id);
68414
68634
  if (checkVote.fee !== undefined) {
68415
- requiredFees.set(checkVote.issuer, checkVote.fee);
68635
+ const checkVoteFee = Array.isArray(checkVote.fee) ? checkVote.fee : [checkVote.fee];
68636
+ // Check if user has the option to pay zero (any fee with amount === 0)
68637
+ // If a zero-amount option exists, fee block is optional; otherwise required
68638
+ const hasZeroFeeOption = checkVoteFee.some(fee => fee.amount === 0n);
68639
+ if (hasZeroFeeOption) {
68640
+ // At least one fee option is zero amount - fee block is optional, but if included should match one of the provided options
68641
+ optionalFees.set(checkVote.issuer, checkVote.fee);
68642
+ }
68643
+ else if (checkVoteFee.length > 0) {
68644
+ // All fee options require payment (no zero option) - fee block MUST be present and operation should match at least one fee option
68645
+ requiredFees.set(checkVote.issuer, checkVote.fee);
68646
+ }
68416
68647
  }
68417
68648
  /*
68418
68649
  * Handle errors specific to requesting a permanent vote
@@ -68439,38 +68670,71 @@ class LedgerAtomicInterface {
68439
68670
  foundOurVote = true;
68440
68671
  }
68441
68672
  }
68673
+ let finalRequiredFees = requiredFees;
68442
68674
  /*
68443
68675
  * We only care about fees if we are issuing a permanent vote,
68444
68676
  * if we are issuing a temporary vote the fees will be checked
68445
68677
  * when the permanent vote is requested
68446
68678
  */
68447
68679
  if (outcome === 'permanent') {
68448
- if (requiredFees.size > 0) {
68449
- if (!hasFeeBlock) {
68450
- throw (new ledger_1.KeetaNetLedgerError('LEDGER_MISSING_REQUIRED_FEE_BLOCK', 'Missing fee block but votes require it'));
68680
+ if (requiredFees.size > 0 || optionalFees.size > 0) {
68681
+ // If fees are required then a fee block should have been provided
68682
+ if (requiredFees.size > 0) {
68683
+ if (!hasFeeBlock) {
68684
+ throw (new ledger_1.KeetaNetLedgerError('LEDGER_MISSING_REQUIRED_FEE_BLOCK', 'Missing fee block but votes require it'));
68685
+ }
68451
68686
  }
68452
- if (requiredFees.size !== possibleFeeBlock?.operations.length) {
68453
- throw (new ledger_1.KeetaNetLedgerError('LEDGER_REQUIRED_FEE_MISMATCH', 'Fee Block Operations do not match required fees'));
68687
+ // We can only validate operations match if we have a fee block
68688
+ if (hasFeeBlock) {
68689
+ // Each vote requires exactly one fee payment, regardless of array size
68690
+ // Optional fees may or may not be included in the operations but if they are they should match
68691
+ if (optionalFees.size > 0) {
68692
+ if (possibleFeeBlock?.operations.length !== requiredFees.size &&
68693
+ possibleFeeBlock?.operations.length !== (requiredFees.size + optionalFees.size)) {
68694
+ throw (new ledger_1.KeetaNetLedgerError('LEDGER_REQUIRED_FEE_MISMATCH', 'Fee Block Operations do not match required fees or required and optional fees'));
68695
+ }
68696
+ // If user provided optional fees then we should validate they match
68697
+ if (possibleFeeBlock?.operations.length === (requiredFees.size + optionalFees.size)) {
68698
+ finalRequiredFees = new Map([...requiredFees, ...optionalFees]);
68699
+ }
68700
+ }
68701
+ else {
68702
+ if (requiredFees.size !== possibleFeeBlock?.operations.length) {
68703
+ throw (new ledger_1.KeetaNetLedgerError('LEDGER_REQUIRED_FEE_MISMATCH', 'Fee Block Operations do not match required fees'));
68704
+ }
68705
+ }
68454
68706
  }
68455
68707
  }
68456
- // Verify that all required fees have been included in the fee block
68457
- for (const [issuer, fee] of requiredFees) {
68458
- const foundFee = possibleFeeBlock?.operations.find((operation) => {
68708
+ // Verify that at least one required fee option has been satisfied for each vote
68709
+ for (const [issuer, feeOrFees] of finalRequiredFees) {
68710
+ // Handle both single fee and array of fees
68711
+ const fees = Array.isArray(feeOrFees) ? feeOrFees : [feeOrFees];
68712
+ // Check if at least one fee option is satisfied
68713
+ let foundMatchingFee = false;
68714
+ for (const fee of fees) {
68459
68715
  const expectedPayTo = fee.payTo ?? issuer;
68460
68716
  const expectedToken = fee.token ?? __classPrivateFieldGet(this, _LedgerAtomicInterface_ledger, "f").baseToken;
68461
- if (operation.type === operations_1.OperationType.SEND && operation.to.comparePublicKey(expectedPayTo)) {
68462
- if (operation.amount !== fee.amount) {
68463
- throw (new ledger_1.KeetaNetLedgerError('LEDGER_FEE_AMOUNT_MISMATCH', `Fee Amount Mismatch, found: ${operation.amount} expected: ${fee.amount}`));
68464
- }
68465
- if (!operation.token.comparePublicKey(expectedToken)) {
68466
- throw (new ledger_1.KeetaNetLedgerError('LEDGER_FEE_TOKEN_MISMATCH', `Fee Token Mismatch, found: ${operation.token.publicKeyString.get()} expected: ${expectedToken.publicKeyString.get()}`));
68717
+ const foundFee = possibleFeeBlock?.operations.find((operation) => {
68718
+ if (operation.type === operations_1.OperationType.SEND && operation.to.comparePublicKey(expectedPayTo)) {
68719
+ if (operation.amount === fee.amount && operation.token.comparePublicKey(expectedToken)) {
68720
+ return (true);
68721
+ }
68467
68722
  }
68468
- return (true);
68723
+ return (false);
68724
+ });
68725
+ if (foundFee !== undefined) {
68726
+ foundMatchingFee = true;
68727
+ break; // Found a matching fee, no need to check others
68469
68728
  }
68470
- return (false);
68471
- });
68472
- if (foundFee === undefined) {
68473
- throw (new ledger_1.KeetaNetLedgerError('LEDGER_FEE_MISSING', `Missing Required Fee for ${fee.payTo?.publicKeyString.get() ?? issuer.publicKeyString.get()}`));
68729
+ }
68730
+ if (!foundMatchingFee) {
68731
+ // Build helpful error message showing what fees were expected
68732
+ const feeOptions = fees.map(fee => {
68733
+ const payTo = fee.payTo ?? issuer;
68734
+ const token = fee.token ?? __classPrivateFieldGet(this, _LedgerAtomicInterface_ledger, "f").baseToken;
68735
+ return (`${fee.amount} ${token.publicKeyString.get()} to ${payTo.publicKeyString.get()}`);
68736
+ }).join(' OR ');
68737
+ throw (new ledger_1.KeetaNetLedgerError('LEDGER_FEE_MISSING', `Missing Required Fee for ${issuer.publicKeyString.get()}. Expected one of: ${feeOptions}`));
68474
68738
  }
68475
68739
  }
68476
68740
  }
@@ -68747,6 +69011,10 @@ class LedgerAtomicInterface {
68747
69011
  return (retval);
68748
69012
  }
68749
69013
  async getAccountRep(account) {
69014
+ const acct = account_1.default.toAccount(account);
69015
+ if (!(0, common_1.canDelegate)(acct.keyType)) {
69016
+ return (null);
69017
+ }
68750
69018
  const transaction = __classPrivateFieldGet(this, _LedgerAtomicInterface_instances, "m", _LedgerAtomicInterface_assertTransaction).call(this);
68751
69019
  const retval = await __classPrivateFieldGet(this, _LedgerAtomicInterface_storage, "f").getAccountRep(transaction, account);
68752
69020
  return (retval);
@@ -69030,12 +69298,13 @@ _LedgerAtomicInterface_network = new WeakMap(), _LedgerAtomicInterface_subnet =
69030
69298
  for (const requirement of requirements) {
69031
69299
  const reqEntityKey = requirement.entity.publicKeyString.get();
69032
69300
  const foundACLRow = (0, common_1.findPermissionMatch)(requirement, gotPermissions);
69301
+ const foundAccountInfo = accountInfos[reqEntityKey];
69033
69302
  let foundPermission;
69034
69303
  if (foundACLRow?.permissions) {
69035
69304
  foundPermission = foundACLRow?.permissions;
69036
69305
  }
69037
- else if (accountInfos[reqEntityKey]?.defaultPermission) {
69038
- foundPermission = accountInfos[reqEntityKey].defaultPermission;
69306
+ else if (foundAccountInfo && (0, types_1.isIdentifierAccountInfo)(foundAccountInfo) && foundAccountInfo.defaultPermission) {
69307
+ foundPermission = foundAccountInfo.defaultPermission;
69039
69308
  }
69040
69309
  else {
69041
69310
  foundPermission = new permissions_1.Permissions();
@@ -69095,7 +69364,7 @@ _LedgerAtomicInterface_network = new WeakMap(), _LedgerAtomicInterface_subnet =
69095
69364
  for (const [multisig, foundSingerLength] of foundMultisigSignerLengths) {
69096
69365
  const multisigPubKey = multisig.publicKeyString.get();
69097
69366
  const foundInfo = foundAccountInfo[multisigPubKey];
69098
- if (!foundInfo?.multisigQuorum) {
69367
+ if (!('multisigQuorum' in foundInfo) || !foundInfo?.multisigQuorum) {
69099
69368
  throw (new Error(`Multisig quorum not found for ${multisigPubKey}`));
69100
69369
  }
69101
69370
  if (foundInfo.multisigQuorum > foundSingerLength) {
@@ -69376,7 +69645,12 @@ async function _LedgerAtomicInterface_validateLedgerOutcome(blocks) {
69376
69645
  */
69377
69646
  if (requireBlockTimestampCheck) {
69378
69647
  const fee = quote?.fee ?? await this.getFee(blocks, effects);
69379
- if (fee !== null) {
69648
+ // We add an explicit fee of 0 if one is not provided.
69649
+ // Since the quote identifier is in the fee data and needs to be parsed correctly.
69650
+ if (fee === null || (Array.isArray(fee) && fee.length === 0)) {
69651
+ builder.addFee({ amount: 0n });
69652
+ }
69653
+ else {
69380
69654
  builder.addFee(fee);
69381
69655
  }
69382
69656
  }
@@ -69628,9 +69902,9 @@ class Ledger {
69628
69902
  return (await transaction.getAccountRep(...args));
69629
69903
  }));
69630
69904
  }
69631
- async getAccountInfo(...args) {
69905
+ async getAccountInfo(account) {
69632
69906
  return (await this.runReadOnly('db-getAccountInfo', async function (transaction) {
69633
- return (await transaction.getAccountInfo(...args));
69907
+ return (await transaction.getAccountInfo(account));
69634
69908
  }));
69635
69909
  }
69636
69910
  async getBlock(...args) {
@@ -69716,6 +69990,28 @@ Ledger.isInstance = (0, helper_1.checkableGenerator)(Ledger);
69716
69990
  exports["default"] = Ledger;
69717
69991
 
69718
69992
 
69993
+ /***/ }),
69994
+
69995
+ /***/ 5773:
69996
+ /***/ ((__unused_webpack_module, exports) => {
69997
+
69998
+ "use strict";
69999
+
70000
+ Object.defineProperty(exports, "__esModule", ({ value: true }));
70001
+ exports.isIdentifierAccountInfo = isIdentifierAccountInfo;
70002
+ exports.isKeyPairAccountInfo = isKeyPairAccountInfo;
70003
+ exports.isAccountInfoOfType = isAccountInfoOfType;
70004
+ function isIdentifierAccountInfo(info) {
70005
+ return (info.account.isIdentifier());
70006
+ }
70007
+ function isKeyPairAccountInfo(info) {
70008
+ return (info.account.isAccount());
70009
+ }
70010
+ function isAccountInfoOfType(info, type) {
70011
+ return (info.account.isKeyType(type));
70012
+ }
70013
+
70014
+
69719
70015
  /***/ }),
69720
70016
 
69721
70017
  /***/ 7364:
@@ -77461,6 +77757,9 @@ function convertSingleValue(value, opts = {}) {
77461
77757
  return (checkPrefix(out, prefix, opts));
77462
77758
  }
77463
77759
  function toJSONSerializable(data, opts) {
77760
+ if (data === undefined) {
77761
+ throw (new Error('undefined is not JSON serializable'));
77762
+ }
77464
77763
  return (JSON.parse(JSON.stringify(convertSingleValue(data, opts))));
77465
77764
  }
77466
77765
  function objectToBuffer(data, opts = {}) {
@@ -77476,6 +77775,76 @@ function parseHexBigIntString(input) {
77476
77775
  }
77477
77776
 
77478
77777
 
77778
+ /***/ }),
77779
+
77780
+ /***/ 9061:
77781
+ /***/ (function(__unused_webpack_module, exports, __webpack_require__) {
77782
+
77783
+ "use strict";
77784
+
77785
+ var __importDefault = (this && this.__importDefault) || function (mod) {
77786
+ return (mod && mod.__esModule) ? mod : { "default": mod };
77787
+ };
77788
+ Object.defineProperty(exports, "__esModule", ({ value: true }));
77789
+ exports.namespacePrefixSchema = exports.MaxNamespaceLength = exports.KeetaNamespaceVersion = void 0;
77790
+ exports.applyNamespace = applyNamespace;
77791
+ const account_1 = __importDefault(__webpack_require__(4642));
77792
+ const asn1_1 = __webpack_require__(6045);
77793
+ /**
77794
+ * Version for Keeta's domain separation namespace schema, encoded as the
77795
+ * `INTEGER` field of `namespacePrefixSchema`.
77796
+ */
77797
+ exports.KeetaNamespaceVersion = 0;
77798
+ /**
77799
+ * Maximum domain separation namespace length in bytes (for strings,
77800
+ * this is the UTF-8 byte length, not the character count).
77801
+ */
77802
+ exports.MaxNamespaceLength = 255;
77803
+ /**
77804
+ * Schema for the namespace prefix:
77805
+ *
77806
+ * ```asn1
77807
+ * NamespacePrefix ::= SEQUENCE {
77808
+ * version INTEGER,
77809
+ * namespace OCTET STRING,
77810
+ * data OCTET STRING
77811
+ * }
77812
+ * ```
77813
+ */
77814
+ exports.namespacePrefixSchema = [
77815
+ asn1_1.ValidateASN1.IsInteger,
77816
+ asn1_1.ValidateASN1.IsOctetString,
77817
+ asn1_1.ValidateASN1.IsOctetString
77818
+ ];
77819
+ /**
77820
+ * Apply the `NamespacePrefix` domain separator to `data`.
77821
+ *
77822
+ * String namespaces are UTF-8 encoded; ArrayBuffer namespaces are used
77823
+ * verbatim. Namespace length MUST be 1-`MaxNamespaceLength` bytes after
77824
+ * encoding.
77825
+ */
77826
+ function applyNamespace(namespace, data) {
77827
+ let namespaceBytes;
77828
+ if (typeof namespace === 'string') {
77829
+ namespaceBytes = new TextEncoder().encode(namespace);
77830
+ }
77831
+ else {
77832
+ namespaceBytes = new Uint8Array(namespace);
77833
+ }
77834
+ if (namespaceBytes.length === 0) {
77835
+ throw (new account_1.default('ACCOUNT_NAMESPACE_EMPTY', 'Domain separation namespace must not be empty'));
77836
+ }
77837
+ if (namespaceBytes.length > exports.MaxNamespaceLength) {
77838
+ throw (new account_1.default('ACCOUNT_NAMESPACE_TOO_LONG', `Domain separation namespace must be 1-${exports.MaxNamespaceLength} bytes, got: ${namespaceBytes.length}`));
77839
+ }
77840
+ return ((0, asn1_1.JStoASN1)([
77841
+ exports.KeetaNamespaceVersion,
77842
+ Buffer.from(namespaceBytes),
77843
+ Buffer.from(data)
77844
+ ]).toBER(false));
77845
+ }
77846
+
77847
+
77479
77848
  /***/ }),
77480
77849
 
77481
77850
  /***/ 9240:
@@ -77964,6 +78333,7 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
77964
78333
  var _AsyncDisposableStackPolyfill_instances, _AsyncDisposableStackPolyfill_toDispose, _AsyncDisposableStackPolyfill_validateNotDisposed, _a;
77965
78334
  Object.defineProperty(exports, "__esModule", ({ value: true }));
77966
78335
  exports.util = exports.crypto = exports.AsyncDisposableStack = void 0;
78336
+ exports.getTypedObjectEntries = getTypedObjectEntries;
77967
78337
  exports.validateBase64ToBuffer = validateBase64ToBuffer;
77968
78338
  exports.bufferToArrayBuffer = bufferToArrayBuffer;
77969
78339
  exports.bufferToBigInt = bufferToBigInt;
@@ -77986,6 +78356,11 @@ const crypto_1 = __importDefault(__webpack_require__(6982));
77986
78356
  const util_1 = __webpack_require__(9023);
77987
78357
  const hash_1 = __webpack_require__(7908);
77988
78358
  const uuid = __importStar(__webpack_require__(5827));
78359
+ // Helper to get properly typed entries from an object
78360
+ function getTypedObjectEntries(obj) {
78361
+ // eslint-disable-next-line @typescript-eslint/consistent-type-assertions
78362
+ return Object.entries(obj);
78363
+ }
77989
78364
  const randomBytes = crypto_1.default.randomBytes.bind(crypto_1.default);
77990
78365
  const randomUUID = crypto_1.default.randomUUID ? crypto_1.default.randomUUID.bind(crypto_1.default) : function () {
77991
78366
  return (uuid.v4());
@@ -78669,7 +79044,7 @@ var __classPrivateFieldGet = (this && this.__classPrivateFieldGet) || function (
78669
79044
  var __importDefault = (this && this.__importDefault) || function (mod) {
78670
79045
  return (mod && mod.__esModule) ? mod : { "default": mod };
78671
79046
  };
78672
- var _VoteBlockHashMap_instances, _VoteBlockHashMap_valueMap, _VoteBlockHashMap_keyMap, _VoteBlockHashMap_getLookupKey, _a, _VoteLikeBase_vote, _VoteLikeBase_options, _VoteLikeBase__hash, _VoteLikeBase__blocksHash, _VoteBlockBundle_instances, _VoteBlockBundle_value, _VoteBlockBundle_valueCompressed, _VoteBlockBundle__hash, _VoteBlockBundle__blocksHash, _VoteBlockBundle__blockHashes, _VoteBlockBundle__votes, _VoteBlockBundle__blocks, _VoteBlockBundle__touchedAccounts, _VoteBlockBundle_votesRaw, _VoteBlockBundle_blocksRaw, _VoteBlockBundle_options, _VoteBlockBundle__asn1Validated, _VoteBlockBundle__blocksAndVotesRaw_get, _VoteBlockBundle__blocksRaw_get, _VoteBlockBundle__votesRaw_get, _VoteBlockBundle_blockHashes_get, _BaseVoteBuilder_account, _BaseVoteBuilder_blocks, _BaseVoteBuilder_fee;
79047
+ var _VoteBlockHashMap_instances, _VoteBlockHashMap_valueMap, _VoteBlockHashMap_keyMap, _VoteBlockHashMap_getLookupKey, _a, _VoteLikeBase_vote, _VoteLikeBase_options, _VoteLikeBase__hash, _VoteLikeBase__blocksHash, _VoteBlockBundle_instances, _VoteBlockBundle_value, _VoteBlockBundle_valueCompressed, _VoteBlockBundle__hash, _VoteBlockBundle__blocksHash, _VoteBlockBundle__blockHashes, _VoteBlockBundle__votes, _VoteBlockBundle__blocks, _VoteBlockBundle__touchedAccounts, _VoteBlockBundle_votesRaw, _VoteBlockBundle_blocksRaw, _VoteBlockBundle_options, _VoteBlockBundle__asn1Validated, _VoteBlockBundle__blocksAndVotesRaw_get, _VoteBlockBundle__blocksRaw_get, _VoteBlockBundle__votesRaw_get, _VoteBlockBundle_blockHashes_get, _BaseVoteBuilder_instances, _BaseVoteBuilder_account, _BaseVoteBuilder_blocks, _BaseVoteBuilder_fee, _BaseVoteBuilder_formatSingleFeeEntry, _BaseVoteBuilder_formatSingleFeeEntryData;
78673
79048
  Object.defineProperty(exports, "__esModule", ({ value: true }));
78674
79049
  exports.Testing = exports.VoteQuoteBuilder = exports.VoteBuilder = exports.BaseVoteBuilder = exports.VoteStaple = exports.VoteBlockBundle = exports.VoteQuote = exports.Vote = exports.PossiblyExpiredVote = exports.VoteBlockHash = exports.VoteBlockHashMap = void 0;
78675
79050
  /*
@@ -78696,15 +79071,31 @@ class VoteHash extends buffer_1.BufferStorage {
78696
79071
  }
78697
79072
  }
78698
79073
  VoteHash.isInstance = (0, helper_1.checkableGenerator)(VoteHash);
79074
+ const singleFeeEntrySchema = [
79075
+ asn1_1.ValidateASN1.IsBoolean,
79076
+ asn1_1.ValidateASN1.IsInteger,
79077
+ { optional: { type: 'context', value: 0, kind: 'implicit', contains: asn1_1.ValidateASN1.IsOctetString } },
79078
+ { optional: { type: 'context', value: 1, kind: 'implicit', contains: asn1_1.ValidateASN1.IsOctetString } }
79079
+ ];
79080
+ const multipleFeeEntrySchema = {
79081
+ type: 'context',
79082
+ value: 0,
79083
+ kind: 'explicit',
79084
+ contains: { sequenceOf: singleFeeEntrySchema }
79085
+ };
78699
79086
  const feeExtensionSchema = {
79087
+ type: 'context',
79088
+ value: 0,
79089
+ kind: 'explicit',
79090
+ contains: { choice: [singleFeeEntrySchema, multipleFeeEntrySchema] }
79091
+ };
79092
+ const hashDataSchema = {
78700
79093
  type: 'context',
78701
79094
  value: 0,
78702
79095
  kind: 'explicit',
78703
79096
  contains: [
78704
- asn1_1.ValidateASN1.IsBoolean,
78705
- asn1_1.ValidateASN1.IsInteger,
78706
- { optional: { type: 'context', value: 0, kind: 'implicit', contains: asn1_1.ValidateASN1.IsOctetString } },
78707
- { optional: { type: 'context', value: 1, kind: 'implicit', contains: asn1_1.ValidateASN1.IsOctetString } }
79097
+ asn1_1.ValidateASN1.IsOID,
79098
+ { sequenceOf: asn1_1.ValidateASN1.IsOctetString }
78708
79099
  ]
78709
79100
  };
78710
79101
  /**
@@ -78786,38 +79177,22 @@ function blockHashesFromVote(input) {
78786
79177
  }
78787
79178
  return (output);
78788
79179
  }
78789
- function feeFromVote(input) {
78790
- const feeInformationAnyJS = (0, asn1_1.ASN1toJS)(input.buffer);
78791
- const feeSchemaChecker = new asn1_1.ValidateASN1(feeExtensionSchema);
78792
- const feeInformation = (function () {
78793
- try {
78794
- return (feeSchemaChecker.validate(feeInformationAnyJS));
78795
- }
78796
- catch (asn1ValidateError) {
78797
- let message = 'internal error: fee asn1 schema is not the right format';
78798
- if (asn1ValidateError instanceof Error) {
78799
- message = `${message}: ${asn1ValidateError.message}`;
78800
- }
78801
- throw (new vote_1.default('VOTE_MALFORMED_FEES_FROM_VOTE_INVALID_INPUT', message));
78802
- }
78803
- })();
78804
- const feeData = feeInformation.contains;
78805
- const quote = feeData[0];
78806
- const retval = {
78807
- quote: quote,
78808
- fee: {
78809
- amount: feeData[1]
78810
- }
79180
+ function parseSingleFeeEntry(feeData) {
79181
+ const fee = {
79182
+ amount: feeData[1]
78811
79183
  };
79184
+ if (fee.amount < 0n) {
79185
+ throw (new vote_1.default('VOTE_MALFORMED_FEES_AMOUNT', 'internal error: fee amount cannot be negative'));
79186
+ }
78812
79187
  const payToAsn1 = feeData[2];
78813
79188
  if (payToAsn1 !== undefined) {
78814
79189
  const payTo = account_1.default.fromPublicKeyAndType(Buffer.from(payToAsn1.contains));
78815
79190
  if (payTo.isStorage()) {
78816
- retval.fee.payTo = payTo;
79191
+ fee.payTo = payTo;
78817
79192
  }
78818
79193
  else {
78819
79194
  try {
78820
- retval.fee.payTo = payTo.assertAccount();
79195
+ fee.payTo = payTo.assertAccount();
78821
79196
  }
78822
79197
  catch {
78823
79198
  throw (new vote_1.default('VOTE_MALFORMED_FEES_PAY_TO_INVALID', 'internal error: payTo is not an Account or Storage Address'));
@@ -78830,9 +79205,68 @@ function feeFromVote(input) {
78830
79205
  if (!token.isToken()) {
78831
79206
  throw (new vote_1.default('VOTE_MALFORMED_FEES_TOKEN_NOT_TOKEN', 'internal error: fees extension token is not a valid token'));
78832
79207
  }
78833
- retval.fee.token = token;
79208
+ fee.token = token;
79209
+ }
79210
+ return (fee);
79211
+ }
79212
+ function feeFromVote(input) {
79213
+ const feeInformationAnyJS = (0, asn1_1.ASN1toJS)((0, helper_1.bufferToArrayBuffer)(input));
79214
+ const feeSchemaChecker = new asn1_1.ValidateASN1(feeExtensionSchema);
79215
+ const feeInformation = (function () {
79216
+ try {
79217
+ return (feeSchemaChecker.validate(feeInformationAnyJS));
79218
+ }
79219
+ catch (asn1ValidateError) {
79220
+ let message = 'internal error: fee asn1 schema is not the right format';
79221
+ if (asn1ValidateError instanceof Error) {
79222
+ message = `${message}: ${asn1ValidateError.message}`;
79223
+ }
79224
+ throw (new vote_1.default('VOTE_MALFORMED_FEES_FROM_VOTE_INVALID_INPUT', message));
79225
+ }
79226
+ })();
79227
+ const feeData = feeInformation.contains;
79228
+ /**
79229
+ * Detect format: check if single fee entry (array of attributes) or multiple fee format (context object)
79230
+ * We've already validated the object against the schema so we know it's one or the other
79231
+ */
79232
+ if (Array.isArray(feeData)) {
79233
+ const quote = feeData[0];
79234
+ const fee = parseSingleFeeEntry(feeData);
79235
+ return ({
79236
+ quote: quote,
79237
+ fee: fee
79238
+ });
79239
+ }
79240
+ else {
79241
+ // New array format - explicit sequence of fee entries
79242
+ const multiFeeData = feeData.contains;
79243
+ if (multiFeeData.length === 0) {
79244
+ throw (new vote_1.default('VOTE_MALFORMED_FEES_MULTIPLE_FEE_EMPTY', 'internal error: multiple fee entries must not be an empty array'));
79245
+ }
79246
+ const feeList = [];
79247
+ let quote;
79248
+ for (const entry of multiFeeData) {
79249
+ // Schema already validated, but need to narrow the type
79250
+ if (!Array.isArray(entry)) {
79251
+ throw (new vote_1.default('VOTE_MALFORMED_FEES_FROM_VOTE_INVALID_INPUT', 'internal error: each fee entry must be a Sequence'));
79252
+ }
79253
+ const entryQuote = entry[0];
79254
+ if (quote === undefined) {
79255
+ quote = entryQuote;
79256
+ }
79257
+ else if (quote !== entryQuote) {
79258
+ throw (new vote_1.default('VOTE_MALFORMED_FEES_INVALID_QUOTE_VALUE', 'internal error: all fee entries must have the same quote value'));
79259
+ }
79260
+ feeList.push(parseSingleFeeEntry(entry));
79261
+ }
79262
+ if (quote === undefined) {
79263
+ throw (new vote_1.default('VOTE_MALFORMED_FEES_INVALID_QUOTE_VALUE', 'internal error: quote value should not be undefined'));
79264
+ }
79265
+ return ({
79266
+ quote: quote,
79267
+ fee: feeList
79268
+ });
78834
79269
  }
78835
- return (retval);
78836
79270
  }
78837
79271
  /**
78838
79272
  * Convert an ASN1Date to a Date
@@ -78980,14 +79414,22 @@ class VoteLikeBase {
78980
79414
  if (fee === undefined) {
78981
79415
  return (false);
78982
79416
  }
78983
- if (fee['amount'] === undefined) {
79417
+ // Handle both single fee and list of fee choices
79418
+ const feeList = Array.isArray(fee) ? fee : [fee];
79419
+ // Reject empty fee arrays to avoid downstream encoding/decoding issues
79420
+ if (feeList.length === 0) {
78984
79421
  return (false);
78985
79422
  }
78986
- if ('payTo' in fee && fee['payTo'] === undefined) {
78987
- return (false);
78988
- }
78989
- if ('token' in fee && fee['token'] === undefined) {
78990
- return (false);
79423
+ for (const feeEntry of feeList) {
79424
+ if (feeEntry['amount'] === undefined) {
79425
+ return (false);
79426
+ }
79427
+ if ('payTo' in feeEntry && feeEntry['payTo'] === undefined) {
79428
+ return (false);
79429
+ }
79430
+ if ('token' in feeEntry && feeEntry['token'] === undefined) {
79431
+ return (false);
79432
+ }
78991
79433
  }
78992
79434
  }
78993
79435
  if ('quote' in voteJSON) {
@@ -78998,7 +79440,7 @@ class VoteLikeBase {
78998
79440
  return (true);
78999
79441
  }
79000
79442
  static fromJSON(voteJSON, options = {}) {
79001
- if (!VoteLikeBase.isValidJSON(voteJSON)) {
79443
+ if (!this.isValidJSON(voteJSON)) {
79002
79444
  throw (new vote_1.default('VOTE_INVALID_CONSTRUCTION_JSON', 'Cannot construct vote, it is not a valid vote JSON object'));
79003
79445
  }
79004
79446
  const issuer = account_1.default.toAccount(voteJSON.issuer);
@@ -79066,8 +79508,8 @@ class VoteLikeBase {
79066
79508
  vote = (0, helper_1.bufferToArrayBuffer)(vote);
79067
79509
  }
79068
79510
  if (!(util_1.types.isArrayBuffer(vote))) {
79069
- if (VoteLikeBase.isValidJSON(vote)) {
79070
- vote = VoteLikeBase.fromJSON(vote).toBytes();
79511
+ if (this.getClass().isValidJSON(vote)) {
79512
+ vote = this.getClass().fromJSON(vote).toBytes();
79071
79513
  }
79072
79514
  else {
79073
79515
  throw (new vote_1.default('VOTE_INVALID_CONSTRUCTION', 'internal error: invalid vote constructor argument in VoteLikeBase'));
@@ -79177,13 +79619,13 @@ class VoteLikeBase {
79177
79619
  * Votes must not be expired
79178
79620
  */
79179
79621
  const expirationCheckMomentISO = new Date(expirationCheckMoment).toISOString();
79180
- if (expirationCheckMoment < (this.validityFrom.valueOf() - VoteLikeBase.allowedSlop)) {
79622
+ if (expirationCheckMoment < (this.validityFrom.valueOf() - this.getClass().allowedSlop)) {
79181
79623
  throw (new vote_1.default('VOTE_MOMENT_BEFORE_VALIDITY_FROM', `Vote was issued in the future (issued on ${validFrom.toISOString()}; moment: ${expirationCheckMomentISO})`));
79182
79624
  }
79183
79625
  /**
79184
79626
  * If the vote is forever viable, it is a permanent vote
79185
79627
  */
79186
- if (this.validityTo.valueOf() > (expirationCheckMoment + VoteLikeBase.permanentVoteThreshold)) {
79628
+ if (this.validityTo.valueOf() > (expirationCheckMoment + this.getClass().permanentVoteThreshold)) {
79187
79629
  this.$permanent = true;
79188
79630
  }
79189
79631
  /**
@@ -79449,7 +79891,7 @@ class VoteLikeBase {
79449
79891
  const now = this.expirationCheckMoment();
79450
79892
  const from = this.validityFrom.valueOf();
79451
79893
  const to = this.validityTo.valueOf();
79452
- if ((now + VoteLikeBase.allowedSlop) < from || (now - VoteLikeBase.allowedSlop) > to) {
79894
+ if ((now + this.getClass().allowedSlop) < from || (now - this.getClass().allowedSlop) > to) {
79453
79895
  return (true);
79454
79896
  }
79455
79897
  return (false);
@@ -80058,6 +80500,7 @@ exports.VoteStaple = VoteStaple;
80058
80500
  VoteStaple.isInstance = (0, helper_1.checkableGenerator)(VoteStaple);
80059
80501
  class BaseVoteBuilder {
80060
80502
  constructor(account, blocks = [], options) {
80503
+ _BaseVoteBuilder_instances.add(this);
80061
80504
  _BaseVoteBuilder_account.set(this, void 0);
80062
80505
  _BaseVoteBuilder_blocks.set(this, void 0);
80063
80506
  _BaseVoteBuilder_fee.set(this, undefined);
@@ -80090,26 +80533,22 @@ class BaseVoteBuilder {
80090
80533
  this.addBlocks([block]);
80091
80534
  }
80092
80535
  addFee(feeInput) {
80093
- const fee = { amount: BigInt(feeInput.amount) };
80094
- const payTo = account_1.default.toAccount(feeInput.payTo);
80095
- if (payTo !== undefined) {
80096
- if (payTo.isStorage()) {
80097
- fee.payTo = payTo;
80536
+ if (Array.isArray(feeInput)) {
80537
+ if (feeInput.length === 0) {
80538
+ throw (new vote_1.default('VOTE_BUILDER_INVALID_FEE', 'Fee array cannot be empty'));
80098
80539
  }
80099
- else {
80100
- fee.payTo = payTo.assertAccount();
80540
+ // List of fee choices format (array)
80541
+ const feeList = [];
80542
+ for (const feeEntry of feeInput) {
80543
+ feeList.push(__classPrivateFieldGet(this, _BaseVoteBuilder_instances, "m", _BaseVoteBuilder_formatSingleFeeEntry).call(this, feeEntry));
80101
80544
  }
80545
+ __classPrivateFieldSet(this, _BaseVoteBuilder_fee, feeList, "f");
80102
80546
  }
80103
- const token = account_1.default.toAccount(feeInput.token);
80104
- if (token !== undefined) {
80105
- if (token.isToken()) {
80106
- fee.token = token;
80107
- }
80108
- else {
80109
- throw (new vote_1.default('VOTE_MALFORMED_FEES_TOKEN_NOT_TOKEN', 'Fee Token should be of type TOKEN'));
80110
- }
80547
+ else {
80548
+ // Single fee
80549
+ const fee = __classPrivateFieldGet(this, _BaseVoteBuilder_instances, "m", _BaseVoteBuilder_formatSingleFeeEntry).call(this, feeInput);
80550
+ __classPrivateFieldSet(this, _BaseVoteBuilder_fee, fee, "f");
80111
80551
  }
80112
- __classPrivateFieldSet(this, _BaseVoteBuilder_fee, fee, "f");
80113
80552
  }
80114
80553
  generateVoteData(serial, validTo, validFrom) {
80115
80554
  /**
@@ -80151,17 +80590,18 @@ class BaseVoteBuilder {
80151
80590
  ];
80152
80591
  let feeExtension = undefined;
80153
80592
  if (__classPrivateFieldGet(this, _BaseVoteBuilder_fee, "f") !== undefined) {
80154
- /** Amount for this vote */
80155
- const feeData = [this.quote, __classPrivateFieldGet(this, _BaseVoteBuilder_fee, "f").amount];
80156
- /** Account to pay the fee too */
80157
- const payToPublicKey = __classPrivateFieldGet(this, _BaseVoteBuilder_fee, "f").payTo?.publicKeyAndType;
80158
- if (payToPublicKey !== undefined) {
80159
- feeData.push({ type: 'context', value: 0, kind: 'implicit', contains: payToPublicKey });
80160
- }
80161
- /** Token in which to pay the fee */
80162
- const tokenPublicKey = __classPrivateFieldGet(this, _BaseVoteBuilder_fee, "f").token?.publicKeyAndType;
80163
- if (tokenPublicKey !== undefined) {
80164
- feeData.push({ type: 'context', value: 1, kind: 'implicit', contains: tokenPublicKey });
80593
+ let feeDataContent;
80594
+ if (Array.isArray(__classPrivateFieldGet(this, _BaseVoteBuilder_fee, "f"))) {
80595
+ // List of fee choices format (array)
80596
+ const feeDataArray = [];
80597
+ for (const fee of __classPrivateFieldGet(this, _BaseVoteBuilder_fee, "f")) {
80598
+ feeDataArray.push(__classPrivateFieldGet(this, _BaseVoteBuilder_instances, "m", _BaseVoteBuilder_formatSingleFeeEntryData).call(this, fee));
80599
+ }
80600
+ feeDataContent = { type: 'context', value: 0, kind: 'explicit', contains: feeDataArray };
80601
+ }
80602
+ else {
80603
+ // Single fee format
80604
+ feeDataContent = __classPrivateFieldGet(this, _BaseVoteBuilder_instances, "m", _BaseVoteBuilder_formatSingleFeeEntryData).call(this, __classPrivateFieldGet(this, _BaseVoteBuilder_fee, "f"));
80165
80605
  }
80166
80606
  feeExtension = [
80167
80607
  { 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
@@ -80170,7 +80610,7 @@ class BaseVoteBuilder {
80170
80610
  type: 'context',
80171
80611
  value: 0,
80172
80612
  kind: 'explicit',
80173
- contains: feeData
80613
+ contains: feeDataContent
80174
80614
  }).toBER(false))
80175
80615
  ];
80176
80616
  }
@@ -80329,7 +80769,51 @@ class BaseVoteBuilder {
80329
80769
  }
80330
80770
  }
80331
80771
  exports.BaseVoteBuilder = BaseVoteBuilder;
80332
- _BaseVoteBuilder_account = new WeakMap(), _BaseVoteBuilder_blocks = new WeakMap(), _BaseVoteBuilder_fee = new WeakMap();
80772
+ _BaseVoteBuilder_account = new WeakMap(), _BaseVoteBuilder_blocks = new WeakMap(), _BaseVoteBuilder_fee = new WeakMap(), _BaseVoteBuilder_instances = new WeakSet(), _BaseVoteBuilder_formatSingleFeeEntry = function _BaseVoteBuilder_formatSingleFeeEntry(feeInput) {
80773
+ if (feeInput.amount === undefined) {
80774
+ throw (new vote_1.default('VOTE_BUILDER_INVALID_FEE', 'Fee amount is required'));
80775
+ }
80776
+ if (BigInt(feeInput.amount) < 0n) {
80777
+ throw (new vote_1.default('VOTE_BUILDER_INVALID_FEE', 'Fee amount cannot be negative'));
80778
+ }
80779
+ const fee = { amount: BigInt(feeInput.amount) };
80780
+ const payTo = account_1.default.toAccount(feeInput.payTo);
80781
+ if (payTo !== undefined) {
80782
+ if (payTo.isStorage()) {
80783
+ fee.payTo = payTo;
80784
+ }
80785
+ else {
80786
+ fee.payTo = payTo.assertAccount();
80787
+ }
80788
+ }
80789
+ const token = account_1.default.toAccount(feeInput.token);
80790
+ if (token !== undefined) {
80791
+ if (token.isToken()) {
80792
+ fee.token = token;
80793
+ }
80794
+ else {
80795
+ throw (new vote_1.default('VOTE_MALFORMED_FEES_TOKEN_NOT_TOKEN', 'Fee Token should be of type TOKEN'));
80796
+ }
80797
+ }
80798
+ return (fee);
80799
+ }, _BaseVoteBuilder_formatSingleFeeEntryData = function _BaseVoteBuilder_formatSingleFeeEntryData(feeInput) {
80800
+ /** Account to pay the fee too */
80801
+ let payToData = undefined;
80802
+ if (feeInput.payTo?.publicKeyAndType !== undefined) {
80803
+ payToData = { type: 'context', value: 0, kind: 'implicit', contains: feeInput.payTo.publicKeyAndType };
80804
+ }
80805
+ /** Token in which to pay the fee */
80806
+ let tokenData = undefined;
80807
+ if (feeInput.token?.publicKeyAndType !== undefined) {
80808
+ tokenData = { type: 'context', value: 1, kind: 'implicit', contains: feeInput.token.publicKeyAndType };
80809
+ }
80810
+ return ([
80811
+ this.quote,
80812
+ feeInput.amount,
80813
+ payToData,
80814
+ tokenData
80815
+ ]);
80816
+ };
80333
80817
  BaseVoteBuilder.isInstance = (0, helper_1.checkableGenerator)(BaseVoteBuilder);
80334
80818
  class VoteBuilder extends BaseVoteBuilder {
80335
80819
  async seal(serial, validTo, validFrom, voteOptions = {}) {
@@ -80360,7 +80844,7 @@ Vote.Staple = VoteStaple;
80360
80844
  Vote.Quote = VoteQuote;
80361
80845
  exports["default"] = Vote;
80362
80846
  /** @internal */
80363
- exports.Testing = { findRDN, blockHashesFromVote, feeFromVote };
80847
+ exports.Testing = { findRDN, blockHashesFromVote, feeFromVote, hashDataSchema, feeExtensionSchema };
80364
80848
 
80365
80849
 
80366
80850
  /***/ }),
@@ -80372,7 +80856,7 @@ exports.Testing = { findRDN, blockHashesFromVote, feeFromVote };
80372
80856
 
80373
80857
  Object.defineProperty(exports, "__esModule", ({ value: true }));
80374
80858
  exports.version = void 0;
80375
- exports.version = '0.16.0+g906ddd004c65d7e5d33559183bed9119e681c5ae';
80859
+ exports.version = '0.16.2+g2c1441eed2a1c71a895d0fb5166c431799b3d3ca';
80376
80860
  exports["default"] = exports.version;
80377
80861
 
80378
80862