@aptos-labs/ts-sdk 2.0.0 → 2.0.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (481) hide show
  1. package/dist/common/{accountAddress-D0xKX-UM.d.ts → accountAddress-AL8HRxQC.d.ts} +8 -0
  2. package/dist/common/chunk-ZMDE3DNL.js.map +1 -1
  3. package/dist/common/cli/index.d.ts +1 -1
  4. package/dist/common/cli/index.js.map +1 -1
  5. package/dist/common/index.d.ts +22 -3
  6. package/dist/common/index.js +30 -30
  7. package/dist/common/index.js.map +1 -1
  8. package/dist/esm/account/AbstractKeylessAccount.mjs +1 -1
  9. package/dist/esm/account/AbstractedAccount.mjs +1 -1
  10. package/dist/esm/account/Account.mjs +1 -1
  11. package/dist/esm/account/AccountUtils.mjs +1 -1
  12. package/dist/esm/account/DerivableAbstractedAccount.mjs +1 -1
  13. package/dist/esm/account/Ed25519Account.mjs +1 -1
  14. package/dist/esm/account/EphemeralKeyPair.mjs +1 -1
  15. package/dist/esm/account/FederatedKeylessAccount.mjs +1 -1
  16. package/dist/esm/account/KeylessAccount.mjs +1 -1
  17. package/dist/esm/account/MultiEd25519Account.mjs +1 -1
  18. package/dist/esm/account/MultiKeyAccount.mjs +1 -1
  19. package/dist/esm/account/SingleKeyAccount.mjs +1 -1
  20. package/dist/esm/account/index.mjs +1 -1
  21. package/dist/esm/account/utils.mjs +1 -1
  22. package/dist/esm/api/account/abstraction.mjs +1 -1
  23. package/dist/esm/api/account.mjs +1 -1
  24. package/dist/esm/api/ans.mjs +1 -1
  25. package/dist/esm/api/aptos.mjs +1 -1
  26. package/dist/esm/api/coin.d.mts +3 -3
  27. package/dist/esm/api/coin.mjs +1 -1
  28. package/dist/esm/api/digitalAsset.d.mts +1 -1
  29. package/dist/esm/api/digitalAsset.mjs +1 -1
  30. package/dist/esm/api/event.mjs +1 -1
  31. package/dist/esm/api/faucet.mjs +1 -1
  32. package/dist/esm/api/fungibleAsset.mjs +1 -1
  33. package/dist/esm/api/general.mjs +1 -1
  34. package/dist/esm/api/index.mjs +1 -1
  35. package/dist/esm/api/keyless.mjs +1 -1
  36. package/dist/esm/api/object.mjs +1 -1
  37. package/dist/esm/api/staking.mjs +1 -1
  38. package/dist/esm/api/table.mjs +1 -1
  39. package/dist/esm/api/transaction.mjs +1 -1
  40. package/dist/esm/api/transactionSubmission/build.mjs +1 -1
  41. package/dist/esm/api/transactionSubmission/management.mjs +1 -1
  42. package/dist/esm/api/transactionSubmission/sign.mjs +1 -1
  43. package/dist/esm/api/transactionSubmission/simulate.mjs +1 -1
  44. package/dist/esm/api/transactionSubmission/submit.mjs +1 -1
  45. package/dist/esm/api/utils.mjs +1 -1
  46. package/dist/esm/bcs/deserializer.d.mts +8 -0
  47. package/dist/esm/bcs/deserializer.mjs +1 -1
  48. package/dist/esm/bcs/index.mjs +1 -1
  49. package/dist/esm/bcs/serializable/moveStructs.mjs +1 -1
  50. package/dist/esm/{chunk-34R7FSQF.mjs → chunk-57J5YBMT.mjs} +2 -2
  51. package/dist/esm/{chunk-USB3LA6B.mjs → chunk-AMAPBD4D.mjs} +2 -2
  52. package/dist/esm/chunk-BK56GLTP.mjs +4 -0
  53. package/dist/esm/chunk-BK56GLTP.mjs.map +1 -0
  54. package/dist/esm/{chunk-G7WH6GQP.mjs → chunk-CFQFFP6N.mjs} +2 -2
  55. package/dist/esm/{chunk-4JT5AESZ.mjs → chunk-CO67Y6YE.mjs} +2 -2
  56. package/dist/esm/chunk-CW35YAMN.mjs +2 -0
  57. package/dist/esm/{chunk-HW7TSJI2.mjs → chunk-CZYH3G7E.mjs} +2 -2
  58. package/dist/esm/chunk-FLZPUYXQ.mjs +2 -0
  59. package/dist/esm/chunk-FLZPUYXQ.mjs.map +1 -0
  60. package/dist/esm/{chunk-ZNLOQO4Q.mjs → chunk-GBNAG7KK.mjs} +2 -2
  61. package/dist/esm/{chunk-6UZHMEK3.mjs → chunk-HETYL3WN.mjs} +2 -2
  62. package/dist/esm/{chunk-SE2VS7WM.mjs → chunk-KRBZ54CY.mjs} +2 -2
  63. package/dist/esm/{chunk-G6HENV5D.mjs → chunk-Q4W3WJ2U.mjs} +2 -2
  64. package/dist/esm/{chunk-EF4FA5I6.mjs → chunk-RQX6JOEN.mjs} +2 -2
  65. package/dist/esm/{chunk-MA4QUN6P.mjs → chunk-U7HD6PQV.mjs} +2 -2
  66. package/dist/esm/{chunk-TDGLYA35.mjs → chunk-UOP7GBXB.mjs} +2 -2
  67. package/dist/esm/{chunk-K43K3YG7.mjs → chunk-UQWF24SS.mjs} +2 -2
  68. package/dist/esm/{chunk-2UBI3AZJ.mjs → chunk-V2QSMVJ5.mjs} +2 -2
  69. package/dist/esm/{chunk-TLFZOAAB.mjs → chunk-V74WPKSY.mjs} +2 -2
  70. package/dist/esm/chunk-VEGW6HP5.mjs +2 -0
  71. package/dist/esm/{chunk-HLF3U7IS.mjs.map → chunk-VEGW6HP5.mjs.map} +1 -1
  72. package/dist/esm/client/core.mjs +1 -1
  73. package/dist/esm/client/get.mjs +1 -1
  74. package/dist/esm/client/index.mjs +1 -1
  75. package/dist/esm/client/post.mjs +1 -1
  76. package/dist/esm/core/crypto/abstraction.mjs +1 -1
  77. package/dist/esm/core/crypto/deserializationUtils.d.mts +36 -0
  78. package/dist/esm/core/crypto/deserializationUtils.mjs +2 -0
  79. package/dist/esm/core/crypto/deserializationUtils.mjs.map +1 -0
  80. package/dist/esm/core/crypto/ed25519.mjs +1 -1
  81. package/dist/esm/core/crypto/ephemeral.mjs +1 -1
  82. package/dist/esm/core/crypto/federatedKeyless.mjs +1 -1
  83. package/dist/esm/core/crypto/index.d.mts +1 -0
  84. package/dist/esm/core/crypto/index.mjs +1 -1
  85. package/dist/esm/core/crypto/keyless.mjs +1 -1
  86. package/dist/esm/core/crypto/multiEd25519.mjs +1 -1
  87. package/dist/esm/core/crypto/multiKey.mjs +1 -1
  88. package/dist/esm/core/crypto/proof.mjs +1 -1
  89. package/dist/esm/core/crypto/publicKey.mjs +1 -1
  90. package/dist/esm/core/crypto/secp256k1.mjs +1 -1
  91. package/dist/esm/core/crypto/signature.mjs +1 -1
  92. package/dist/esm/core/crypto/singleKey.mjs +1 -1
  93. package/dist/esm/core/index.d.mts +1 -0
  94. package/dist/esm/core/index.mjs +1 -1
  95. package/dist/esm/errors/index.mjs +1 -1
  96. package/dist/esm/index.d.mts +1 -0
  97. package/dist/esm/index.mjs +1 -1
  98. package/dist/esm/internal/abstraction.mjs +1 -1
  99. package/dist/esm/internal/account.mjs +1 -1
  100. package/dist/esm/internal/ans.mjs +1 -1
  101. package/dist/esm/internal/coin.mjs +1 -1
  102. package/dist/esm/internal/digitalAsset.mjs +1 -1
  103. package/dist/esm/internal/event.mjs +1 -1
  104. package/dist/esm/internal/faucet.mjs +1 -1
  105. package/dist/esm/internal/fungibleAsset.mjs +1 -1
  106. package/dist/esm/internal/general.mjs +1 -1
  107. package/dist/esm/internal/keyless.mjs +1 -1
  108. package/dist/esm/internal/object.mjs +1 -1
  109. package/dist/esm/internal/staking.mjs +1 -1
  110. package/dist/esm/internal/table.mjs +1 -1
  111. package/dist/esm/internal/transaction.mjs +1 -1
  112. package/dist/esm/internal/transactionSubmission.mjs +1 -1
  113. package/dist/esm/internal/utils/index.mjs +1 -1
  114. package/dist/esm/internal/utils/utils.mjs +1 -1
  115. package/dist/esm/internal/view.mjs +1 -1
  116. package/dist/esm/transactions/authenticator/account.mjs +1 -1
  117. package/dist/esm/transactions/authenticator/index.mjs +1 -1
  118. package/dist/esm/transactions/authenticator/transaction.mjs +1 -1
  119. package/dist/esm/transactions/index.mjs +1 -1
  120. package/dist/esm/transactions/instances/index.mjs +1 -1
  121. package/dist/esm/transactions/instances/moduleId.mjs +1 -1
  122. package/dist/esm/transactions/instances/multiAgentTransaction.mjs +1 -1
  123. package/dist/esm/transactions/instances/rawTransaction.mjs +1 -1
  124. package/dist/esm/transactions/instances/rotationProofChallenge.mjs +1 -1
  125. package/dist/esm/transactions/instances/signedTransaction.mjs +1 -1
  126. package/dist/esm/transactions/instances/simpleTransaction.mjs +1 -1
  127. package/dist/esm/transactions/instances/transactionPayload.mjs +1 -1
  128. package/dist/esm/transactions/management/accountSequenceNumber.mjs +1 -1
  129. package/dist/esm/transactions/management/index.mjs +1 -1
  130. package/dist/esm/transactions/management/transactionWorker.mjs +1 -1
  131. package/dist/esm/transactions/transactionBuilder/helpers.mjs +1 -1
  132. package/dist/esm/transactions/transactionBuilder/index.mjs +1 -1
  133. package/dist/esm/transactions/transactionBuilder/remoteAbi.mjs +1 -1
  134. package/dist/esm/transactions/transactionBuilder/signingMessage.mjs +1 -1
  135. package/dist/esm/transactions/transactionBuilder/transactionBuilder.mjs +1 -1
  136. package/dist/esm/transactions/typeTag/index.mjs +1 -1
  137. package/dist/esm/transactions/typeTag/parser.mjs +1 -1
  138. package/dist/esm/utils/index.mjs +1 -1
  139. package/dist/esm/utils/normalizeBundle.mjs +1 -1
  140. package/dist/esm/version.d.mts +1 -1
  141. package/dist/esm/version.mjs +1 -1
  142. package/package.json +3 -3
  143. package/src/bcs/deserializer.ts +13 -0
  144. package/src/core/crypto/deserializationUtils.ts +106 -0
  145. package/src/core/crypto/index.ts +1 -0
  146. package/src/internal/move/jwks/build/jwk/BuildInfo.yaml +56 -0
  147. package/src/internal/move/jwks/build/jwk/bytecode_modules/dependencies/AptosFramework/account.mv +0 -0
  148. package/src/internal/move/jwks/build/jwk/bytecode_modules/dependencies/AptosFramework/aggregator.mv +0 -0
  149. package/src/internal/move/jwks/build/jwk/bytecode_modules/dependencies/AptosFramework/aggregator_factory.mv +0 -0
  150. package/src/internal/move/jwks/build/jwk/bytecode_modules/dependencies/AptosFramework/aggregator_v2.mv +0 -0
  151. package/src/internal/move/jwks/build/jwk/bytecode_modules/dependencies/AptosFramework/aptos_account.mv +0 -0
  152. package/src/internal/move/jwks/build/jwk/bytecode_modules/dependencies/AptosFramework/aptos_coin.mv +0 -0
  153. package/src/internal/move/jwks/build/jwk/bytecode_modules/dependencies/AptosFramework/aptos_governance.mv +0 -0
  154. package/src/internal/move/jwks/build/jwk/bytecode_modules/dependencies/AptosFramework/block.mv +0 -0
  155. package/src/internal/move/jwks/build/jwk/bytecode_modules/dependencies/AptosFramework/chain_id.mv +0 -0
  156. package/src/internal/move/jwks/build/jwk/bytecode_modules/dependencies/AptosFramework/chain_status.mv +0 -0
  157. package/src/internal/move/jwks/build/jwk/bytecode_modules/dependencies/AptosFramework/code.mv +0 -0
  158. package/src/internal/move/jwks/build/jwk/bytecode_modules/dependencies/AptosFramework/coin.mv +0 -0
  159. package/src/internal/move/jwks/build/jwk/bytecode_modules/dependencies/AptosFramework/config_buffer.mv +0 -0
  160. package/src/internal/move/jwks/build/jwk/bytecode_modules/dependencies/AptosFramework/consensus_config.mv +0 -0
  161. package/src/internal/move/jwks/build/jwk/bytecode_modules/dependencies/AptosFramework/create_signer.mv +0 -0
  162. package/src/internal/move/jwks/build/jwk/bytecode_modules/dependencies/AptosFramework/delegation_pool.mv +0 -0
  163. package/src/internal/move/jwks/build/jwk/bytecode_modules/dependencies/AptosFramework/dispatchable_fungible_asset.mv +0 -0
  164. package/src/internal/move/jwks/build/jwk/bytecode_modules/dependencies/AptosFramework/dkg.mv +0 -0
  165. package/src/internal/move/jwks/build/jwk/bytecode_modules/dependencies/AptosFramework/event.mv +0 -0
  166. package/src/internal/move/jwks/build/jwk/bytecode_modules/dependencies/AptosFramework/execution_config.mv +0 -0
  167. package/src/internal/move/jwks/build/jwk/bytecode_modules/dependencies/AptosFramework/function_info.mv +0 -0
  168. package/src/internal/move/jwks/build/jwk/bytecode_modules/dependencies/AptosFramework/fungible_asset.mv +0 -0
  169. package/src/internal/move/jwks/build/jwk/bytecode_modules/dependencies/AptosFramework/gas_schedule.mv +0 -0
  170. package/src/internal/move/jwks/build/jwk/bytecode_modules/dependencies/AptosFramework/genesis.mv +0 -0
  171. package/src/internal/move/jwks/build/jwk/bytecode_modules/dependencies/AptosFramework/governance_proposal.mv +0 -0
  172. package/src/internal/move/jwks/build/jwk/bytecode_modules/dependencies/AptosFramework/guid.mv +0 -0
  173. package/src/internal/move/jwks/build/jwk/bytecode_modules/dependencies/AptosFramework/jwk_consensus_config.mv +0 -0
  174. package/src/internal/move/jwks/build/jwk/bytecode_modules/dependencies/AptosFramework/jwks.mv +0 -0
  175. package/src/internal/move/jwks/build/jwk/bytecode_modules/dependencies/AptosFramework/keyless_account.mv +0 -0
  176. package/src/internal/move/jwks/build/jwk/bytecode_modules/dependencies/AptosFramework/managed_coin.mv +0 -0
  177. package/src/internal/move/jwks/build/jwk/bytecode_modules/dependencies/AptosFramework/multisig_account.mv +0 -0
  178. package/src/internal/move/jwks/build/jwk/bytecode_modules/dependencies/AptosFramework/object.mv +0 -0
  179. package/src/internal/move/jwks/build/jwk/bytecode_modules/dependencies/AptosFramework/object_code_deployment.mv +0 -0
  180. package/src/internal/move/jwks/build/jwk/bytecode_modules/dependencies/AptosFramework/optional_aggregator.mv +0 -0
  181. package/src/internal/move/jwks/build/jwk/bytecode_modules/dependencies/AptosFramework/primary_fungible_store.mv +0 -0
  182. package/src/internal/move/jwks/build/jwk/bytecode_modules/dependencies/AptosFramework/randomness.mv +0 -0
  183. package/src/internal/move/jwks/build/jwk/bytecode_modules/dependencies/AptosFramework/randomness_api_v0_config.mv +0 -0
  184. package/src/internal/move/jwks/build/jwk/bytecode_modules/dependencies/AptosFramework/randomness_config.mv +0 -0
  185. package/src/internal/move/jwks/build/jwk/bytecode_modules/dependencies/AptosFramework/randomness_config_seqnum.mv +0 -0
  186. package/src/internal/move/jwks/build/jwk/bytecode_modules/dependencies/AptosFramework/reconfiguration.mv +0 -0
  187. package/src/internal/move/jwks/build/jwk/bytecode_modules/dependencies/AptosFramework/reconfiguration_state.mv +0 -0
  188. package/src/internal/move/jwks/build/jwk/bytecode_modules/dependencies/AptosFramework/reconfiguration_with_dkg.mv +0 -0
  189. package/src/internal/move/jwks/build/jwk/bytecode_modules/dependencies/AptosFramework/resource_account.mv +0 -0
  190. package/src/internal/move/jwks/build/jwk/bytecode_modules/dependencies/AptosFramework/stake.mv +0 -0
  191. package/src/internal/move/jwks/build/jwk/bytecode_modules/dependencies/AptosFramework/staking_config.mv +0 -0
  192. package/src/internal/move/jwks/build/jwk/bytecode_modules/dependencies/AptosFramework/staking_contract.mv +0 -0
  193. package/src/internal/move/jwks/build/jwk/bytecode_modules/dependencies/AptosFramework/staking_proxy.mv +0 -0
  194. package/src/internal/move/jwks/build/jwk/bytecode_modules/dependencies/AptosFramework/state_storage.mv +0 -0
  195. package/src/internal/move/jwks/build/jwk/bytecode_modules/dependencies/AptosFramework/storage_gas.mv +0 -0
  196. package/src/internal/move/jwks/build/jwk/bytecode_modules/dependencies/AptosFramework/system_addresses.mv +0 -0
  197. package/src/internal/move/jwks/build/jwk/bytecode_modules/dependencies/AptosFramework/timestamp.mv +0 -0
  198. package/src/internal/move/jwks/build/jwk/bytecode_modules/dependencies/AptosFramework/transaction_context.mv +0 -0
  199. package/src/internal/move/jwks/build/jwk/bytecode_modules/dependencies/AptosFramework/transaction_fee.mv +0 -0
  200. package/src/internal/move/jwks/build/jwk/bytecode_modules/dependencies/AptosFramework/transaction_validation.mv +0 -0
  201. package/src/internal/move/jwks/build/jwk/bytecode_modules/dependencies/AptosFramework/util.mv +0 -0
  202. package/src/internal/move/jwks/build/jwk/bytecode_modules/dependencies/AptosFramework/validator_consensus_info.mv +0 -0
  203. package/src/internal/move/jwks/build/jwk/bytecode_modules/dependencies/AptosFramework/version.mv +0 -0
  204. package/src/internal/move/jwks/build/jwk/bytecode_modules/dependencies/AptosFramework/vesting.mv +0 -0
  205. package/src/internal/move/jwks/build/jwk/bytecode_modules/dependencies/AptosFramework/voting.mv +0 -0
  206. package/src/internal/move/jwks/build/jwk/bytecode_modules/dependencies/AptosStdlib/any.mv +0 -0
  207. package/src/internal/move/jwks/build/jwk/bytecode_modules/dependencies/AptosStdlib/aptos_hash.mv +0 -0
  208. package/src/internal/move/jwks/build/jwk/bytecode_modules/dependencies/AptosStdlib/big_vector.mv +0 -0
  209. package/src/internal/move/jwks/build/jwk/bytecode_modules/dependencies/AptosStdlib/bls12381.mv +0 -0
  210. package/src/internal/move/jwks/build/jwk/bytecode_modules/dependencies/AptosStdlib/bls12381_algebra.mv +0 -0
  211. package/src/internal/move/jwks/build/jwk/bytecode_modules/dependencies/AptosStdlib/bn254_algebra.mv +0 -0
  212. package/src/internal/move/jwks/build/jwk/bytecode_modules/dependencies/AptosStdlib/capability.mv +0 -0
  213. package/src/internal/move/jwks/build/jwk/bytecode_modules/dependencies/AptosStdlib/comparator.mv +0 -0
  214. package/src/internal/move/jwks/build/jwk/bytecode_modules/dependencies/AptosStdlib/copyable_any.mv +0 -0
  215. package/src/internal/move/jwks/build/jwk/bytecode_modules/dependencies/AptosStdlib/crypto_algebra.mv +0 -0
  216. package/src/internal/move/jwks/build/jwk/bytecode_modules/dependencies/AptosStdlib/debug.mv +0 -0
  217. package/src/internal/move/jwks/build/jwk/bytecode_modules/dependencies/AptosStdlib/ed25519.mv +0 -0
  218. package/src/internal/move/jwks/build/jwk/bytecode_modules/dependencies/AptosStdlib/fixed_point64.mv +0 -0
  219. package/src/internal/move/jwks/build/jwk/bytecode_modules/dependencies/AptosStdlib/from_bcs.mv +0 -0
  220. package/src/internal/move/jwks/build/jwk/bytecode_modules/dependencies/AptosStdlib/math128.mv +0 -0
  221. package/src/internal/move/jwks/build/jwk/bytecode_modules/dependencies/AptosStdlib/math64.mv +0 -0
  222. package/src/internal/move/jwks/build/jwk/bytecode_modules/dependencies/AptosStdlib/math_fixed.mv +0 -0
  223. package/src/internal/move/jwks/build/jwk/bytecode_modules/dependencies/AptosStdlib/math_fixed64.mv +0 -0
  224. package/src/internal/move/jwks/build/jwk/bytecode_modules/dependencies/AptosStdlib/multi_ed25519.mv +0 -0
  225. package/src/internal/move/jwks/build/jwk/bytecode_modules/dependencies/AptosStdlib/pool_u64.mv +0 -0
  226. package/src/internal/move/jwks/build/jwk/bytecode_modules/dependencies/AptosStdlib/pool_u64_unbound.mv +0 -0
  227. package/src/internal/move/jwks/build/jwk/bytecode_modules/dependencies/AptosStdlib/ristretto255.mv +0 -0
  228. package/src/internal/move/jwks/build/jwk/bytecode_modules/dependencies/AptosStdlib/ristretto255_bulletproofs.mv +0 -0
  229. package/src/internal/move/jwks/build/jwk/bytecode_modules/dependencies/AptosStdlib/ristretto255_elgamal.mv +0 -0
  230. package/src/internal/move/jwks/build/jwk/bytecode_modules/dependencies/AptosStdlib/ristretto255_pedersen.mv +0 -0
  231. package/src/internal/move/jwks/build/jwk/bytecode_modules/dependencies/AptosStdlib/secp256k1.mv +0 -0
  232. package/src/internal/move/jwks/build/jwk/bytecode_modules/dependencies/AptosStdlib/simple_map.mv +0 -0
  233. package/src/internal/move/jwks/build/jwk/bytecode_modules/dependencies/AptosStdlib/smart_table.mv +0 -0
  234. package/src/internal/move/jwks/build/jwk/bytecode_modules/dependencies/AptosStdlib/smart_vector.mv +0 -0
  235. package/src/internal/move/jwks/build/jwk/bytecode_modules/dependencies/AptosStdlib/string_utils.mv +0 -0
  236. package/src/internal/move/jwks/build/jwk/bytecode_modules/dependencies/AptosStdlib/table.mv +0 -0
  237. package/src/internal/move/jwks/build/jwk/bytecode_modules/dependencies/AptosStdlib/table_with_length.mv +0 -0
  238. package/src/internal/move/jwks/build/jwk/bytecode_modules/dependencies/AptosStdlib/type_info.mv +0 -0
  239. package/src/internal/move/jwks/build/jwk/bytecode_modules/dependencies/MoveStdlib/acl.mv +0 -0
  240. package/src/internal/move/jwks/build/jwk/bytecode_modules/dependencies/MoveStdlib/bcs.mv +0 -0
  241. package/src/internal/move/jwks/build/jwk/bytecode_modules/dependencies/MoveStdlib/bit_vector.mv +0 -0
  242. package/src/internal/move/jwks/build/jwk/bytecode_modules/dependencies/MoveStdlib/error.mv +0 -0
  243. package/src/internal/move/jwks/build/jwk/bytecode_modules/dependencies/MoveStdlib/features.mv +0 -0
  244. package/src/internal/move/jwks/build/jwk/bytecode_modules/dependencies/MoveStdlib/fixed_point32.mv +0 -0
  245. package/src/internal/move/jwks/build/jwk/bytecode_modules/dependencies/MoveStdlib/hash.mv +0 -0
  246. package/src/internal/move/jwks/build/jwk/bytecode_modules/dependencies/MoveStdlib/option.mv +0 -0
  247. package/src/internal/move/jwks/build/jwk/bytecode_modules/dependencies/MoveStdlib/signer.mv +0 -0
  248. package/src/internal/move/jwks/build/jwk/bytecode_modules/dependencies/MoveStdlib/string.mv +0 -0
  249. package/src/internal/move/jwks/build/jwk/bytecode_modules/dependencies/MoveStdlib/vector.mv +0 -0
  250. package/src/internal/move/jwks/build/jwk/bytecode_scripts/main.mv +0 -0
  251. package/src/internal/move/jwks/build/jwk/source_maps/dependencies/AptosFramework/account.mvsm +0 -0
  252. package/src/internal/move/jwks/build/jwk/source_maps/dependencies/AptosFramework/aggregator.mvsm +0 -0
  253. package/src/internal/move/jwks/build/jwk/source_maps/dependencies/AptosFramework/aggregator_factory.mvsm +0 -0
  254. package/src/internal/move/jwks/build/jwk/source_maps/dependencies/AptosFramework/aggregator_v2.mvsm +0 -0
  255. package/src/internal/move/jwks/build/jwk/source_maps/dependencies/AptosFramework/aptos_account.mvsm +0 -0
  256. package/src/internal/move/jwks/build/jwk/source_maps/dependencies/AptosFramework/aptos_coin.mvsm +0 -0
  257. package/src/internal/move/jwks/build/jwk/source_maps/dependencies/AptosFramework/aptos_governance.mvsm +0 -0
  258. package/src/internal/move/jwks/build/jwk/source_maps/dependencies/AptosFramework/block.mvsm +0 -0
  259. package/src/internal/move/jwks/build/jwk/source_maps/dependencies/AptosFramework/chain_id.mvsm +0 -0
  260. package/src/internal/move/jwks/build/jwk/source_maps/dependencies/AptosFramework/chain_status.mvsm +0 -0
  261. package/src/internal/move/jwks/build/jwk/source_maps/dependencies/AptosFramework/code.mvsm +0 -0
  262. package/src/internal/move/jwks/build/jwk/source_maps/dependencies/AptosFramework/coin.mvsm +0 -0
  263. package/src/internal/move/jwks/build/jwk/source_maps/dependencies/AptosFramework/config_buffer.mvsm +0 -0
  264. package/src/internal/move/jwks/build/jwk/source_maps/dependencies/AptosFramework/consensus_config.mvsm +0 -0
  265. package/src/internal/move/jwks/build/jwk/source_maps/dependencies/AptosFramework/create_signer.mvsm +0 -0
  266. package/src/internal/move/jwks/build/jwk/source_maps/dependencies/AptosFramework/delegation_pool.mvsm +0 -0
  267. package/src/internal/move/jwks/build/jwk/source_maps/dependencies/AptosFramework/dispatchable_fungible_asset.mvsm +0 -0
  268. package/src/internal/move/jwks/build/jwk/source_maps/dependencies/AptosFramework/dkg.mvsm +0 -0
  269. package/src/internal/move/jwks/build/jwk/source_maps/dependencies/AptosFramework/event.mvsm +0 -0
  270. package/src/internal/move/jwks/build/jwk/source_maps/dependencies/AptosFramework/execution_config.mvsm +0 -0
  271. package/src/internal/move/jwks/build/jwk/source_maps/dependencies/AptosFramework/function_info.mvsm +0 -0
  272. package/src/internal/move/jwks/build/jwk/source_maps/dependencies/AptosFramework/fungible_asset.mvsm +0 -0
  273. package/src/internal/move/jwks/build/jwk/source_maps/dependencies/AptosFramework/gas_schedule.mvsm +0 -0
  274. package/src/internal/move/jwks/build/jwk/source_maps/dependencies/AptosFramework/genesis.mvsm +0 -0
  275. package/src/internal/move/jwks/build/jwk/source_maps/dependencies/AptosFramework/governance_proposal.mvsm +0 -0
  276. package/src/internal/move/jwks/build/jwk/source_maps/dependencies/AptosFramework/guid.mvsm +0 -0
  277. package/src/internal/move/jwks/build/jwk/source_maps/dependencies/AptosFramework/jwk_consensus_config.mvsm +0 -0
  278. package/src/internal/move/jwks/build/jwk/source_maps/dependencies/AptosFramework/jwks.mvsm +0 -0
  279. package/src/internal/move/jwks/build/jwk/source_maps/dependencies/AptosFramework/keyless_account.mvsm +0 -0
  280. package/src/internal/move/jwks/build/jwk/source_maps/dependencies/AptosFramework/managed_coin.mvsm +0 -0
  281. package/src/internal/move/jwks/build/jwk/source_maps/dependencies/AptosFramework/multisig_account.mvsm +0 -0
  282. package/src/internal/move/jwks/build/jwk/source_maps/dependencies/AptosFramework/object.mvsm +0 -0
  283. package/src/internal/move/jwks/build/jwk/source_maps/dependencies/AptosFramework/object_code_deployment.mvsm +0 -0
  284. package/src/internal/move/jwks/build/jwk/source_maps/dependencies/AptosFramework/optional_aggregator.mvsm +0 -0
  285. package/src/internal/move/jwks/build/jwk/source_maps/dependencies/AptosFramework/primary_fungible_store.mvsm +0 -0
  286. package/src/internal/move/jwks/build/jwk/source_maps/dependencies/AptosFramework/randomness.mvsm +0 -0
  287. package/src/internal/move/jwks/build/jwk/source_maps/dependencies/AptosFramework/randomness_api_v0_config.mvsm +0 -0
  288. package/src/internal/move/jwks/build/jwk/source_maps/dependencies/AptosFramework/randomness_config.mvsm +0 -0
  289. package/src/internal/move/jwks/build/jwk/source_maps/dependencies/AptosFramework/randomness_config_seqnum.mvsm +0 -0
  290. package/src/internal/move/jwks/build/jwk/source_maps/dependencies/AptosFramework/reconfiguration.mvsm +0 -0
  291. package/src/internal/move/jwks/build/jwk/source_maps/dependencies/AptosFramework/reconfiguration_state.mvsm +0 -0
  292. package/src/internal/move/jwks/build/jwk/source_maps/dependencies/AptosFramework/reconfiguration_with_dkg.mvsm +0 -0
  293. package/src/internal/move/jwks/build/jwk/source_maps/dependencies/AptosFramework/resource_account.mvsm +0 -0
  294. package/src/internal/move/jwks/build/jwk/source_maps/dependencies/AptosFramework/stake.mvsm +0 -0
  295. package/src/internal/move/jwks/build/jwk/source_maps/dependencies/AptosFramework/staking_config.mvsm +0 -0
  296. package/src/internal/move/jwks/build/jwk/source_maps/dependencies/AptosFramework/staking_contract.mvsm +0 -0
  297. package/src/internal/move/jwks/build/jwk/source_maps/dependencies/AptosFramework/staking_proxy.mvsm +0 -0
  298. package/src/internal/move/jwks/build/jwk/source_maps/dependencies/AptosFramework/state_storage.mvsm +0 -0
  299. package/src/internal/move/jwks/build/jwk/source_maps/dependencies/AptosFramework/storage_gas.mvsm +0 -0
  300. package/src/internal/move/jwks/build/jwk/source_maps/dependencies/AptosFramework/system_addresses.mvsm +0 -0
  301. package/src/internal/move/jwks/build/jwk/source_maps/dependencies/AptosFramework/timestamp.mvsm +0 -0
  302. package/src/internal/move/jwks/build/jwk/source_maps/dependencies/AptosFramework/transaction_context.mvsm +0 -0
  303. package/src/internal/move/jwks/build/jwk/source_maps/dependencies/AptosFramework/transaction_fee.mvsm +0 -0
  304. package/src/internal/move/jwks/build/jwk/source_maps/dependencies/AptosFramework/transaction_validation.mvsm +0 -0
  305. package/src/internal/move/jwks/build/jwk/source_maps/dependencies/AptosFramework/util.mvsm +0 -0
  306. package/src/internal/move/jwks/build/jwk/source_maps/dependencies/AptosFramework/validator_consensus_info.mvsm +0 -0
  307. package/src/internal/move/jwks/build/jwk/source_maps/dependencies/AptosFramework/version.mvsm +0 -0
  308. package/src/internal/move/jwks/build/jwk/source_maps/dependencies/AptosFramework/vesting.mvsm +0 -0
  309. package/src/internal/move/jwks/build/jwk/source_maps/dependencies/AptosFramework/voting.mvsm +0 -0
  310. package/src/internal/move/jwks/build/jwk/source_maps/dependencies/AptosStdlib/any.mvsm +0 -0
  311. package/src/internal/move/jwks/build/jwk/source_maps/dependencies/AptosStdlib/aptos_hash.mvsm +0 -0
  312. package/src/internal/move/jwks/build/jwk/source_maps/dependencies/AptosStdlib/big_vector.mvsm +0 -0
  313. package/src/internal/move/jwks/build/jwk/source_maps/dependencies/AptosStdlib/bls12381.mvsm +0 -0
  314. package/src/internal/move/jwks/build/jwk/source_maps/dependencies/AptosStdlib/bls12381_algebra.mvsm +0 -0
  315. package/src/internal/move/jwks/build/jwk/source_maps/dependencies/AptosStdlib/bn254_algebra.mvsm +0 -0
  316. package/src/internal/move/jwks/build/jwk/source_maps/dependencies/AptosStdlib/capability.mvsm +0 -0
  317. package/src/internal/move/jwks/build/jwk/source_maps/dependencies/AptosStdlib/comparator.mvsm +0 -0
  318. package/src/internal/move/jwks/build/jwk/source_maps/dependencies/AptosStdlib/copyable_any.mvsm +0 -0
  319. package/src/internal/move/jwks/build/jwk/source_maps/dependencies/AptosStdlib/crypto_algebra.mvsm +0 -0
  320. package/src/internal/move/jwks/build/jwk/source_maps/dependencies/AptosStdlib/debug.mvsm +0 -0
  321. package/src/internal/move/jwks/build/jwk/source_maps/dependencies/AptosStdlib/ed25519.mvsm +0 -0
  322. package/src/internal/move/jwks/build/jwk/source_maps/dependencies/AptosStdlib/fixed_point64.mvsm +0 -0
  323. package/src/internal/move/jwks/build/jwk/source_maps/dependencies/AptosStdlib/from_bcs.mvsm +0 -0
  324. package/src/internal/move/jwks/build/jwk/source_maps/dependencies/AptosStdlib/math128.mvsm +0 -0
  325. package/src/internal/move/jwks/build/jwk/source_maps/dependencies/AptosStdlib/math64.mvsm +0 -0
  326. package/src/internal/move/jwks/build/jwk/source_maps/dependencies/AptosStdlib/math_fixed.mvsm +0 -0
  327. package/src/internal/move/jwks/build/jwk/source_maps/dependencies/AptosStdlib/math_fixed64.mvsm +0 -0
  328. package/src/internal/move/jwks/build/jwk/source_maps/dependencies/AptosStdlib/multi_ed25519.mvsm +0 -0
  329. package/src/internal/move/jwks/build/jwk/source_maps/dependencies/AptosStdlib/pool_u64.mvsm +0 -0
  330. package/src/internal/move/jwks/build/jwk/source_maps/dependencies/AptosStdlib/pool_u64_unbound.mvsm +0 -0
  331. package/src/internal/move/jwks/build/jwk/source_maps/dependencies/AptosStdlib/ristretto255.mvsm +0 -0
  332. package/src/internal/move/jwks/build/jwk/source_maps/dependencies/AptosStdlib/ristretto255_bulletproofs.mvsm +0 -0
  333. package/src/internal/move/jwks/build/jwk/source_maps/dependencies/AptosStdlib/ristretto255_elgamal.mvsm +0 -0
  334. package/src/internal/move/jwks/build/jwk/source_maps/dependencies/AptosStdlib/ristretto255_pedersen.mvsm +0 -0
  335. package/src/internal/move/jwks/build/jwk/source_maps/dependencies/AptosStdlib/secp256k1.mvsm +0 -0
  336. package/src/internal/move/jwks/build/jwk/source_maps/dependencies/AptosStdlib/simple_map.mvsm +0 -0
  337. package/src/internal/move/jwks/build/jwk/source_maps/dependencies/AptosStdlib/smart_table.mvsm +0 -0
  338. package/src/internal/move/jwks/build/jwk/source_maps/dependencies/AptosStdlib/smart_vector.mvsm +0 -0
  339. package/src/internal/move/jwks/build/jwk/source_maps/dependencies/AptosStdlib/string_utils.mvsm +0 -0
  340. package/src/internal/move/jwks/build/jwk/source_maps/dependencies/AptosStdlib/table.mvsm +0 -0
  341. package/src/internal/move/jwks/build/jwk/source_maps/dependencies/AptosStdlib/table_with_length.mvsm +0 -0
  342. package/src/internal/move/jwks/build/jwk/source_maps/dependencies/AptosStdlib/type_info.mvsm +0 -0
  343. package/src/internal/move/jwks/build/jwk/source_maps/dependencies/MoveStdlib/acl.mvsm +0 -0
  344. package/src/internal/move/jwks/build/jwk/source_maps/dependencies/MoveStdlib/bcs.mvsm +0 -0
  345. package/src/internal/move/jwks/build/jwk/source_maps/dependencies/MoveStdlib/bit_vector.mvsm +0 -0
  346. package/src/internal/move/jwks/build/jwk/source_maps/dependencies/MoveStdlib/error.mvsm +0 -0
  347. package/src/internal/move/jwks/build/jwk/source_maps/dependencies/MoveStdlib/features.mvsm +0 -0
  348. package/src/internal/move/jwks/build/jwk/source_maps/dependencies/MoveStdlib/fixed_point32.mvsm +0 -0
  349. package/src/internal/move/jwks/build/jwk/source_maps/dependencies/MoveStdlib/hash.mvsm +0 -0
  350. package/src/internal/move/jwks/build/jwk/source_maps/dependencies/MoveStdlib/option.mvsm +0 -0
  351. package/src/internal/move/jwks/build/jwk/source_maps/dependencies/MoveStdlib/signer.mvsm +0 -0
  352. package/src/internal/move/jwks/build/jwk/source_maps/dependencies/MoveStdlib/string.mvsm +0 -0
  353. package/src/internal/move/jwks/build/jwk/source_maps/dependencies/MoveStdlib/vector.mvsm +0 -0
  354. package/src/internal/move/jwks/build/jwk/source_maps/main.mvsm +0 -0
  355. package/src/internal/move/jwks/build/jwk/sources/dependencies/AptosFramework/account.move +1533 -0
  356. package/src/internal/move/jwks/build/jwk/sources/dependencies/AptosFramework/aggregator.move +48 -0
  357. package/src/internal/move/jwks/build/jwk/sources/dependencies/AptosFramework/aggregator_factory.move +66 -0
  358. package/src/internal/move/jwks/build/jwk/sources/dependencies/AptosFramework/aggregator_v2.move +280 -0
  359. package/src/internal/move/jwks/build/jwk/sources/dependencies/AptosFramework/aptos_account.move +443 -0
  360. package/src/internal/move/jwks/build/jwk/sources/dependencies/AptosFramework/aptos_coin.move +204 -0
  361. package/src/internal/move/jwks/build/jwk/sources/dependencies/AptosFramework/aptos_governance.move +1387 -0
  362. package/src/internal/move/jwks/build/jwk/sources/dependencies/AptosFramework/block.move +394 -0
  363. package/src/internal/move/jwks/build/jwk/sources/dependencies/AptosFramework/chain_id.move +41 -0
  364. package/src/internal/move/jwks/build/jwk/sources/dependencies/AptosFramework/chain_status.move +48 -0
  365. package/src/internal/move/jwks/build/jwk/sources/dependencies/AptosFramework/code.move +367 -0
  366. package/src/internal/move/jwks/build/jwk/sources/dependencies/AptosFramework/coin.move +2214 -0
  367. package/src/internal/move/jwks/build/jwk/sources/dependencies/AptosFramework/config_buffer.move +101 -0
  368. package/src/internal/move/jwks/build/jwk/sources/dependencies/AptosFramework/consensus_config.move +77 -0
  369. package/src/internal/move/jwks/build/jwk/sources/dependencies/AptosFramework/create_signer.move +21 -0
  370. package/src/internal/move/jwks/build/jwk/sources/dependencies/AptosFramework/delegation_pool.move +5568 -0
  371. package/src/internal/move/jwks/build/jwk/sources/dependencies/AptosFramework/dispatchable_fungible_asset.move +228 -0
  372. package/src/internal/move/jwks/build/jwk/sources/dependencies/AptosFramework/dkg.move +121 -0
  373. package/src/internal/move/jwks/build/jwk/sources/dependencies/AptosFramework/event.move +92 -0
  374. package/src/internal/move/jwks/build/jwk/sources/dependencies/AptosFramework/execution_config.move +66 -0
  375. package/src/internal/move/jwks/build/jwk/sources/dependencies/AptosFramework/function_info.move +100 -0
  376. package/src/internal/move/jwks/build/jwk/sources/dependencies/AptosFramework/fungible_asset.move +1566 -0
  377. package/src/internal/move/jwks/build/jwk/sources/dependencies/AptosFramework/gas_schedule.move +176 -0
  378. package/src/internal/move/jwks/build/jwk/sources/dependencies/AptosFramework/genesis.move +550 -0
  379. package/src/internal/move/jwks/build/jwk/sources/dependencies/AptosFramework/governance_proposal.move +23 -0
  380. package/src/internal/move/jwks/build/jwk/sources/dependencies/AptosFramework/guid.move +68 -0
  381. package/src/internal/move/jwks/build/jwk/sources/dependencies/AptosFramework/jwk_consensus_config.move +148 -0
  382. package/src/internal/move/jwks/build/jwk/sources/dependencies/AptosFramework/jwks.move +817 -0
  383. package/src/internal/move/jwks/build/jwk/sources/dependencies/AptosFramework/keyless_account.move +312 -0
  384. package/src/internal/move/jwks/build/jwk/sources/dependencies/AptosFramework/managed_coin.move +205 -0
  385. package/src/internal/move/jwks/build/jwk/sources/dependencies/AptosFramework/multisig_account.move +2477 -0
  386. package/src/internal/move/jwks/build/jwk/sources/dependencies/AptosFramework/object.move +1073 -0
  387. package/src/internal/move/jwks/build/jwk/sources/dependencies/AptosFramework/object_code_deployment.move +147 -0
  388. package/src/internal/move/jwks/build/jwk/sources/dependencies/AptosFramework/optional_aggregator.move +295 -0
  389. package/src/internal/move/jwks/build/jwk/sources/dependencies/AptosFramework/primary_fungible_store.move +405 -0
  390. package/src/internal/move/jwks/build/jwk/sources/dependencies/AptosFramework/randomness.move +574 -0
  391. package/src/internal/move/jwks/build/jwk/sources/dependencies/AptosFramework/randomness_api_v0_config.move +57 -0
  392. package/src/internal/move/jwks/build/jwk/sources/dependencies/AptosFramework/randomness_config.move +153 -0
  393. package/src/internal/move/jwks/build/jwk/sources/dependencies/AptosFramework/randomness_config_seqnum.move +49 -0
  394. package/src/internal/move/jwks/build/jwk/sources/dependencies/AptosFramework/reconfiguration.move +237 -0
  395. package/src/internal/move/jwks/build/jwk/sources/dependencies/AptosFramework/reconfiguration_state.move +132 -0
  396. package/src/internal/move/jwks/build/jwk/sources/dependencies/AptosFramework/reconfiguration_with_dkg.move +69 -0
  397. package/src/internal/move/jwks/build/jwk/sources/dependencies/AptosFramework/resource_account.move +267 -0
  398. package/src/internal/move/jwks/build/jwk/sources/dependencies/AptosFramework/stake.move +3286 -0
  399. package/src/internal/move/jwks/build/jwk/sources/dependencies/AptosFramework/staking_config.move +686 -0
  400. package/src/internal/move/jwks/build/jwk/sources/dependencies/AptosFramework/staking_contract.move +1618 -0
  401. package/src/internal/move/jwks/build/jwk/sources/dependencies/AptosFramework/staking_proxy.move +228 -0
  402. package/src/internal/move/jwks/build/jwk/sources/dependencies/AptosFramework/state_storage.move +90 -0
  403. package/src/internal/move/jwks/build/jwk/sources/dependencies/AptosFramework/storage_gas.move +622 -0
  404. package/src/internal/move/jwks/build/jwk/sources/dependencies/AptosFramework/system_addresses.move +82 -0
  405. package/src/internal/move/jwks/build/jwk/sources/dependencies/AptosFramework/timestamp.move +88 -0
  406. package/src/internal/move/jwks/build/jwk/sources/dependencies/AptosFramework/transaction_context.move +262 -0
  407. package/src/internal/move/jwks/build/jwk/sources/dependencies/AptosFramework/transaction_fee.move +457 -0
  408. package/src/internal/move/jwks/build/jwk/sources/dependencies/AptosFramework/transaction_validation.move +501 -0
  409. package/src/internal/move/jwks/build/jwk/sources/dependencies/AptosFramework/util.move +16 -0
  410. package/src/internal/move/jwks/build/jwk/sources/dependencies/AptosFramework/validator_consensus_info.move +42 -0
  411. package/src/internal/move/jwks/build/jwk/sources/dependencies/AptosFramework/version.move +115 -0
  412. package/src/internal/move/jwks/build/jwk/sources/dependencies/AptosFramework/vesting.move +2183 -0
  413. package/src/internal/move/jwks/build/jwk/sources/dependencies/AptosFramework/voting.move +1279 -0
  414. package/src/internal/move/jwks/build/jwk/sources/dependencies/AptosStdlib/any.move +57 -0
  415. package/src/internal/move/jwks/build/jwk/sources/dependencies/AptosStdlib/aptos_hash.move +253 -0
  416. package/src/internal/move/jwks/build/jwk/sources/dependencies/AptosStdlib/big_vector.move +469 -0
  417. package/src/internal/move/jwks/build/jwk/sources/dependencies/AptosStdlib/bls12381.move +985 -0
  418. package/src/internal/move/jwks/build/jwk/sources/dependencies/AptosStdlib/bls12381_algebra.move +802 -0
  419. package/src/internal/move/jwks/build/jwk/sources/dependencies/AptosStdlib/bn254_algebra.move +855 -0
  420. package/src/internal/move/jwks/build/jwk/sources/dependencies/AptosStdlib/capability.move +193 -0
  421. package/src/internal/move/jwks/build/jwk/sources/dependencies/AptosStdlib/comparator.move +173 -0
  422. package/src/internal/move/jwks/build/jwk/sources/dependencies/AptosStdlib/copyable_any.move +45 -0
  423. package/src/internal/move/jwks/build/jwk/sources/dependencies/AptosStdlib/crypto_algebra.move +351 -0
  424. package/src/internal/move/jwks/build/jwk/sources/dependencies/AptosStdlib/debug.move +278 -0
  425. package/src/internal/move/jwks/build/jwk/sources/dependencies/AptosStdlib/ed25519.move +262 -0
  426. package/src/internal/move/jwks/build/jwk/sources/dependencies/AptosStdlib/fixed_point64.move +447 -0
  427. package/src/internal/move/jwks/build/jwk/sources/dependencies/AptosStdlib/from_bcs.move +91 -0
  428. package/src/internal/move/jwks/build/jwk/sources/dependencies/AptosStdlib/math128.move +381 -0
  429. package/src/internal/move/jwks/build/jwk/sources/dependencies/AptosStdlib/math64.move +336 -0
  430. package/src/internal/move/jwks/build/jwk/sources/dependencies/AptosStdlib/math_fixed.move +139 -0
  431. package/src/internal/move/jwks/build/jwk/sources/dependencies/AptosStdlib/math_fixed64.move +142 -0
  432. package/src/internal/move/jwks/build/jwk/sources/dependencies/AptosStdlib/multi_ed25519.move +482 -0
  433. package/src/internal/move/jwks/build/jwk/sources/dependencies/AptosStdlib/pool_u64.move +571 -0
  434. package/src/internal/move/jwks/build/jwk/sources/dependencies/AptosStdlib/pool_u64_unbound.move +270 -0
  435. package/src/internal/move/jwks/build/jwk/sources/dependencies/AptosStdlib/ristretto255.move +1310 -0
  436. package/src/internal/move/jwks/build/jwk/sources/dependencies/AptosStdlib/ristretto255_bulletproofs.move +253 -0
  437. package/src/internal/move/jwks/build/jwk/sources/dependencies/AptosStdlib/ristretto255_elgamal.move +234 -0
  438. package/src/internal/move/jwks/build/jwk/sources/dependencies/AptosStdlib/ristretto255_pedersen.move +158 -0
  439. package/src/internal/move/jwks/build/jwk/sources/dependencies/AptosStdlib/secp256k1.move +114 -0
  440. package/src/internal/move/jwks/build/jwk/sources/dependencies/AptosStdlib/simple_map.move +319 -0
  441. package/src/internal/move/jwks/build/jwk/sources/dependencies/AptosStdlib/smart_table.move +769 -0
  442. package/src/internal/move/jwks/build/jwk/sources/dependencies/AptosStdlib/smart_vector.move +766 -0
  443. package/src/internal/move/jwks/build/jwk/sources/dependencies/AptosStdlib/string_utils.move +148 -0
  444. package/src/internal/move/jwks/build/jwk/sources/dependencies/AptosStdlib/table.move +152 -0
  445. package/src/internal/move/jwks/build/jwk/sources/dependencies/AptosStdlib/table_with_length.move +141 -0
  446. package/src/internal/move/jwks/build/jwk/sources/dependencies/AptosStdlib/type_info.move +351 -0
  447. package/src/internal/move/jwks/build/jwk/sources/dependencies/MoveStdlib/acl.move +46 -0
  448. package/src/internal/move/jwks/build/jwk/sources/dependencies/MoveStdlib/bcs.move +27 -0
  449. package/src/internal/move/jwks/build/jwk/sources/dependencies/MoveStdlib/bit_vector.move +239 -0
  450. package/src/internal/move/jwks/build/jwk/sources/dependencies/MoveStdlib/error.move +88 -0
  451. package/src/internal/move/jwks/build/jwk/sources/dependencies/MoveStdlib/features.move +780 -0
  452. package/src/internal/move/jwks/build/jwk/sources/dependencies/MoveStdlib/fixed_point32.move +295 -0
  453. package/src/internal/move/jwks/build/jwk/sources/dependencies/MoveStdlib/hash.move +8 -0
  454. package/src/internal/move/jwks/build/jwk/sources/dependencies/MoveStdlib/option.move +356 -0
  455. package/src/internal/move/jwks/build/jwk/sources/dependencies/MoveStdlib/signer.move +21 -0
  456. package/src/internal/move/jwks/build/jwk/sources/dependencies/MoveStdlib/string.move +93 -0
  457. package/src/internal/move/jwks/build/jwk/sources/dependencies/MoveStdlib/vector.move +669 -0
  458. package/src/internal/move/jwks/build/jwk/sources/main.move +20 -0
  459. package/src/version.ts +1 -1
  460. package/dist/esm/chunk-5YLNYSBT.mjs +0 -4
  461. package/dist/esm/chunk-5YLNYSBT.mjs.map +0 -1
  462. package/dist/esm/chunk-DLIBG6H7.mjs +0 -2
  463. package/dist/esm/chunk-DLIBG6H7.mjs.map +0 -1
  464. package/dist/esm/chunk-HLF3U7IS.mjs +0 -2
  465. package/dist/esm/chunk-RIRJNQ7B.mjs +0 -2
  466. /package/dist/esm/{chunk-34R7FSQF.mjs.map → chunk-57J5YBMT.mjs.map} +0 -0
  467. /package/dist/esm/{chunk-USB3LA6B.mjs.map → chunk-AMAPBD4D.mjs.map} +0 -0
  468. /package/dist/esm/{chunk-G7WH6GQP.mjs.map → chunk-CFQFFP6N.mjs.map} +0 -0
  469. /package/dist/esm/{chunk-4JT5AESZ.mjs.map → chunk-CO67Y6YE.mjs.map} +0 -0
  470. /package/dist/esm/{chunk-RIRJNQ7B.mjs.map → chunk-CW35YAMN.mjs.map} +0 -0
  471. /package/dist/esm/{chunk-HW7TSJI2.mjs.map → chunk-CZYH3G7E.mjs.map} +0 -0
  472. /package/dist/esm/{chunk-ZNLOQO4Q.mjs.map → chunk-GBNAG7KK.mjs.map} +0 -0
  473. /package/dist/esm/{chunk-6UZHMEK3.mjs.map → chunk-HETYL3WN.mjs.map} +0 -0
  474. /package/dist/esm/{chunk-SE2VS7WM.mjs.map → chunk-KRBZ54CY.mjs.map} +0 -0
  475. /package/dist/esm/{chunk-G6HENV5D.mjs.map → chunk-Q4W3WJ2U.mjs.map} +0 -0
  476. /package/dist/esm/{chunk-EF4FA5I6.mjs.map → chunk-RQX6JOEN.mjs.map} +0 -0
  477. /package/dist/esm/{chunk-MA4QUN6P.mjs.map → chunk-U7HD6PQV.mjs.map} +0 -0
  478. /package/dist/esm/{chunk-TDGLYA35.mjs.map → chunk-UOP7GBXB.mjs.map} +0 -0
  479. /package/dist/esm/{chunk-K43K3YG7.mjs.map → chunk-UQWF24SS.mjs.map} +0 -0
  480. /package/dist/esm/{chunk-2UBI3AZJ.mjs.map → chunk-V2QSMVJ5.mjs.map} +0 -0
  481. /package/dist/esm/{chunk-TLFZOAAB.mjs.map → chunk-V74WPKSY.mjs.map} +0 -0
@@ -0,0 +1,2477 @@
1
+ /// Enhanced multisig account standard on Aptos. This is different from the native multisig scheme support enforced via
2
+ /// the account's auth key.
3
+ ///
4
+ /// This module allows creating a flexible and powerful multisig account with seamless support for updating owners
5
+ /// without changing the auth key. Users can choose to store transaction payloads waiting for owner signatures on chain
6
+ /// or off chain (primary consideration is decentralization/transparency vs gas cost).
7
+ ///
8
+ /// The multisig account is a resource account underneath. By default, it has no auth key and can only be controlled via
9
+ /// the special multisig transaction flow. However, owners can create a transaction to change the auth key to match a
10
+ /// private key off chain if so desired.
11
+ ///
12
+ /// Transactions need to be executed in order of creation, similar to transactions for a normal Aptos account (enforced
13
+ /// with account nonce).
14
+ ///
15
+ /// The flow is like below:
16
+ /// 1. Owners can create a new multisig account by calling create (signer is default single owner) or with
17
+ /// create_with_owners where multiple initial owner addresses can be specified. This is different (and easier) from
18
+ /// the native multisig scheme where the owners' public keys have to be specified. Here, only addresses are needed.
19
+ /// 2. Owners can be added/removed any time by calling add_owners or remove_owners. The transactions to do still need
20
+ /// to follow the k-of-n scheme specified for the multisig account.
21
+ /// 3. To create a new transaction, an owner can call create_transaction with the transaction payload. This will store
22
+ /// the full transaction payload on chain, which adds decentralization (censorship is not possible as the data is
23
+ /// available on chain) and makes it easier to fetch all transactions waiting for execution. If saving gas is desired,
24
+ /// an owner can alternatively call create_transaction_with_hash where only the payload hash is stored. Later execution
25
+ /// will be verified using the hash. Only owners can create transactions and a transaction id (incremeting id) will be
26
+ /// assigned.
27
+ /// 4. To approve or reject a transaction, other owners can call approve() or reject() with the transaction id.
28
+ /// 5. If there are enough approvals, any owner can execute the transaction using the special MultisigTransaction type
29
+ /// with the transaction id if the full payload is already stored on chain or with the transaction payload if only a
30
+ /// hash is stored. Transaction execution will first check with this module that the transaction payload has gotten
31
+ /// enough signatures. If so, it will be executed as the multisig account. The owner who executes will pay for gas.
32
+ /// 6. If there are enough rejections, any owner can finalize the rejection by calling execute_rejected_transaction().
33
+ ///
34
+ /// Note that this multisig account model is not designed to use with a large number of owners. The more owners there
35
+ /// are, the more expensive voting on transactions will become. If a large number of owners is designed, such as in a
36
+ /// flat governance structure, clients are encouraged to write their own modules on top of this multisig account module
37
+ /// and implement the governance voting logic on top.
38
+ module aptos_framework::multisig_account {
39
+ use aptos_framework::account::{Self, SignerCapability, new_event_handle, create_resource_address};
40
+ use aptos_framework::aptos_coin::AptosCoin;
41
+ use aptos_framework::chain_id;
42
+ use aptos_framework::create_signer::create_signer;
43
+ use aptos_framework::coin;
44
+ use aptos_framework::event::{EventHandle, emit_event, emit};
45
+ use aptos_framework::timestamp::now_seconds;
46
+ use aptos_std::simple_map::{Self, SimpleMap};
47
+ use aptos_std::table::{Self, Table};
48
+ use std::bcs::to_bytes;
49
+ use std::error;
50
+ use std::hash::sha3_256;
51
+ use std::option::{Self, Option};
52
+ use std::signer::address_of;
53
+ use std::string::String;
54
+ use std::vector;
55
+
56
+ /// The salt used to create a resource account during multisig account creation.
57
+ /// This is used to avoid conflicts with other modules that also create resource accounts with the same owner
58
+ /// account.
59
+ const DOMAIN_SEPARATOR: vector<u8> = b"aptos_framework::multisig_account";
60
+
61
+ // Any error codes > 2000 can be thrown as part of transaction prologue.
62
+ /// Owner list cannot contain the same address more than once.
63
+ const EDUPLICATE_OWNER: u64 = 1;
64
+ /// Specified account is not a multisig account.
65
+ const EACCOUNT_NOT_MULTISIG: u64 = 2002;
66
+ /// Account executing this operation is not an owner of the multisig account.
67
+ const ENOT_OWNER: u64 = 2003;
68
+ /// Transaction payload cannot be empty.
69
+ const EPAYLOAD_CANNOT_BE_EMPTY: u64 = 4;
70
+ /// Multisig account must have at least one owner.
71
+ const ENOT_ENOUGH_OWNERS: u64 = 5;
72
+ /// Transaction with specified id cannot be found.
73
+ const ETRANSACTION_NOT_FOUND: u64 = 2006;
74
+ /// Provided target function does not match the hash stored in the on-chain transaction.
75
+ const EPAYLOAD_DOES_NOT_MATCH_HASH: u64 = 2008;
76
+ /// Transaction has not received enough approvals to be executed.
77
+ const ENOT_ENOUGH_APPROVALS: u64 = 2009;
78
+ /// Provided target function does not match the payload stored in the on-chain transaction.
79
+ const EPAYLOAD_DOES_NOT_MATCH: u64 = 2010;
80
+ /// Transaction has not received enough rejections to be officially rejected.
81
+ const ENOT_ENOUGH_REJECTIONS: u64 = 10;
82
+ /// Number of signatures required must be more than zero and at most the total number of owners.
83
+ const EINVALID_SIGNATURES_REQUIRED: u64 = 11;
84
+ /// Payload hash must be exactly 32 bytes (sha3-256).
85
+ const EINVALID_PAYLOAD_HASH: u64 = 12;
86
+ /// The multisig account itself cannot be an owner.
87
+ const EOWNER_CANNOT_BE_MULTISIG_ACCOUNT_ITSELF: u64 = 13;
88
+ /// Multisig accounts has not been enabled on this current network yet.
89
+ const EMULTISIG_ACCOUNTS_NOT_ENABLED_YET: u64 = 14;
90
+ /// The number of metadata keys and values don't match.
91
+ const ENUMBER_OF_METADATA_KEYS_AND_VALUES_DONT_MATCH: u64 = 15;
92
+ /// The specified metadata contains duplicate attributes (keys).
93
+ const EDUPLICATE_METADATA_KEY: u64 = 16;
94
+ /// The sequence number provided is invalid. It must be between [1, next pending transaction - 1].
95
+ const EINVALID_SEQUENCE_NUMBER: u64 = 17;
96
+ /// Provided owners to remove and new owners overlap.
97
+ const EOWNERS_TO_REMOVE_NEW_OWNERS_OVERLAP: u64 = 18;
98
+ /// The number of pending transactions has exceeded the maximum allowed.
99
+ const EMAX_PENDING_TRANSACTIONS_EXCEEDED: u64 = 19;
100
+ /// The multisig v2 enhancement feature is not enabled.
101
+ const EMULTISIG_V2_ENHANCEMENT_NOT_ENABLED: u64 = 20;
102
+
103
+
104
+ const ZERO_AUTH_KEY: vector<u8> = x"0000000000000000000000000000000000000000000000000000000000000000";
105
+
106
+ const MAX_PENDING_TRANSACTIONS: u64 = 20;
107
+
108
+ /// Represents a multisig account's configurations and transactions.
109
+ /// This will be stored in the multisig account (created as a resource account separate from any owner accounts).
110
+ struct MultisigAccount has key {
111
+ // The list of all owner addresses.
112
+ owners: vector<address>,
113
+ // The number of signatures required to pass a transaction (k in k-of-n).
114
+ num_signatures_required: u64,
115
+ // Map from transaction id (incrementing id) to transactions to execute for this multisig account.
116
+ // Already executed transactions are deleted to save on storage but can always be accessed via events.
117
+ transactions: Table<u64, MultisigTransaction>,
118
+ // The sequence number assigned to the last executed or rejected transaction. Used to enforce in-order
119
+ // executions of proposals, similar to sequence number for a normal (single-user) account.
120
+ last_executed_sequence_number: u64,
121
+ // The sequence number to assign to the next transaction. This is not always last_executed_sequence_number + 1
122
+ // as there can be multiple pending transactions. The number of pending transactions should be equal to
123
+ // next_sequence_number - (last_executed_sequence_number + 1).
124
+ next_sequence_number: u64,
125
+ // The signer capability controlling the multisig (resource) account. This can be exchanged for the signer.
126
+ // Currently not used as the MultisigTransaction can validate and create a signer directly in the VM but
127
+ // this can be useful to have for on-chain composability in the future.
128
+ signer_cap: Option<SignerCapability>,
129
+ // The multisig account's metadata such as name, description, etc. This can be updated through the multisig
130
+ // transaction flow (i.e. self-update).
131
+ // Note: Attributes can be arbitrarily set by the multisig account and thus will only be used for off-chain
132
+ // display purposes only. They don't change any on-chain semantics of the multisig account.
133
+ metadata: SimpleMap<String, vector<u8>>,
134
+
135
+ // Events.
136
+ add_owners_events: EventHandle<AddOwnersEvent>,
137
+ remove_owners_events: EventHandle<RemoveOwnersEvent>,
138
+ update_signature_required_events: EventHandle<UpdateSignaturesRequiredEvent>,
139
+ create_transaction_events: EventHandle<CreateTransactionEvent>,
140
+ vote_events: EventHandle<VoteEvent>,
141
+ execute_rejected_transaction_events: EventHandle<ExecuteRejectedTransactionEvent>,
142
+ execute_transaction_events: EventHandle<TransactionExecutionSucceededEvent>,
143
+ transaction_execution_failed_events: EventHandle<TransactionExecutionFailedEvent>,
144
+ metadata_updated_events: EventHandle<MetadataUpdatedEvent>,
145
+ }
146
+
147
+ /// A transaction to be executed in a multisig account.
148
+ /// This must contain either the full transaction payload or its hash (stored as bytes).
149
+ struct MultisigTransaction has copy, drop, store {
150
+ payload: Option<vector<u8>>,
151
+ payload_hash: Option<vector<u8>>,
152
+ // Mapping from owner adress to vote (yes for approve, no for reject). Uses a simple map to deduplicate.
153
+ votes: SimpleMap<address, bool>,
154
+ // The owner who created this transaction.
155
+ creator: address,
156
+ // The timestamp in seconds when the transaction was created.
157
+ creation_time_secs: u64,
158
+ }
159
+
160
+ /// Contains information about execution failure.
161
+ struct ExecutionError has copy, drop, store {
162
+ // The module where the error occurs.
163
+ abort_location: String,
164
+ // There are 3 error types, stored as strings:
165
+ // 1. VMError. Indicates an error from the VM, e.g. out of gas, invalid auth key, etc.
166
+ // 2. MoveAbort. Indicates an abort, e.g. assertion failure, from inside the executed Move code.
167
+ // 3. MoveExecutionFailure. Indicates an error from Move code where the VM could not continue. For example,
168
+ // arithmetic failures.
169
+ error_type: String,
170
+ // The detailed error code explaining which error occurred.
171
+ error_code: u64,
172
+ }
173
+
174
+ /// Used only for verifying multisig account creation on top of existing accounts.
175
+ struct MultisigAccountCreationMessage has copy, drop {
176
+ // Chain id is included to prevent cross-chain replay.
177
+ chain_id: u8,
178
+ // Account address is included to prevent cross-account replay (when multiple accounts share the same auth key).
179
+ account_address: address,
180
+ // Sequence number is not needed for replay protection as the multisig account can only be created once.
181
+ // But it's included to ensure timely execution of account creation.
182
+ sequence_number: u64,
183
+ // The list of owners for the multisig account.
184
+ owners: vector<address>,
185
+ // The number of signatures required (signature threshold).
186
+ num_signatures_required: u64,
187
+ }
188
+
189
+ /// Used only for verifying multisig account creation on top of existing accounts and rotating the auth key to 0x0.
190
+ struct MultisigAccountCreationWithAuthKeyRevocationMessage has copy, drop {
191
+ // Chain id is included to prevent cross-chain replay.
192
+ chain_id: u8,
193
+ // Account address is included to prevent cross-account replay (when multiple accounts share the same auth key).
194
+ account_address: address,
195
+ // Sequence number is not needed for replay protection as the multisig account can only be created once.
196
+ // But it's included to ensure timely execution of account creation.
197
+ sequence_number: u64,
198
+ // The list of owners for the multisig account.
199
+ owners: vector<address>,
200
+ // The number of signatures required (signature threshold).
201
+ num_signatures_required: u64,
202
+ }
203
+
204
+ /// Event emitted when new owners are added to the multisig account.
205
+ struct AddOwnersEvent has drop, store {
206
+ owners_added: vector<address>,
207
+ }
208
+
209
+ #[event]
210
+ struct AddOwners has drop, store {
211
+ multisig_account: address,
212
+ owners_added: vector<address>,
213
+ }
214
+
215
+ /// Event emitted when new owners are removed from the multisig account.
216
+ struct RemoveOwnersEvent has drop, store {
217
+ owners_removed: vector<address>,
218
+ }
219
+
220
+ #[event]
221
+ struct RemoveOwners has drop, store {
222
+ multisig_account: address,
223
+ owners_removed: vector<address>,
224
+ }
225
+
226
+ /// Event emitted when the number of signatures required is updated.
227
+ struct UpdateSignaturesRequiredEvent has drop, store {
228
+ old_num_signatures_required: u64,
229
+ new_num_signatures_required: u64,
230
+ }
231
+
232
+ #[event]
233
+ struct UpdateSignaturesRequired has drop, store {
234
+ multisig_account: address,
235
+ old_num_signatures_required: u64,
236
+ new_num_signatures_required: u64,
237
+ }
238
+
239
+ /// Event emitted when a transaction is created.
240
+ struct CreateTransactionEvent has drop, store {
241
+ creator: address,
242
+ sequence_number: u64,
243
+ transaction: MultisigTransaction,
244
+ }
245
+
246
+ #[event]
247
+ struct CreateTransaction has drop, store {
248
+ multisig_account: address,
249
+ creator: address,
250
+ sequence_number: u64,
251
+ transaction: MultisigTransaction,
252
+ }
253
+
254
+ /// Event emitted when an owner approves or rejects a transaction.
255
+ struct VoteEvent has drop, store {
256
+ owner: address,
257
+ sequence_number: u64,
258
+ approved: bool,
259
+ }
260
+
261
+ #[event]
262
+ struct Vote has drop, store {
263
+ multisig_account: address,
264
+ owner: address,
265
+ sequence_number: u64,
266
+ approved: bool,
267
+ }
268
+
269
+ /// Event emitted when a transaction is officially rejected because the number of rejections has reached the
270
+ /// number of signatures required.
271
+ struct ExecuteRejectedTransactionEvent has drop, store {
272
+ sequence_number: u64,
273
+ num_rejections: u64,
274
+ executor: address,
275
+ }
276
+
277
+ #[event]
278
+ struct ExecuteRejectedTransaction has drop, store {
279
+ multisig_account: address,
280
+ sequence_number: u64,
281
+ num_rejections: u64,
282
+ executor: address,
283
+ }
284
+
285
+ /// Event emitted when a transaction is executed.
286
+ struct TransactionExecutionSucceededEvent has drop, store {
287
+ executor: address,
288
+ sequence_number: u64,
289
+ transaction_payload: vector<u8>,
290
+ num_approvals: u64,
291
+ }
292
+
293
+ #[event]
294
+ struct TransactionExecutionSucceeded has drop, store {
295
+ multisig_account: address,
296
+ executor: address,
297
+ sequence_number: u64,
298
+ transaction_payload: vector<u8>,
299
+ num_approvals: u64,
300
+ }
301
+
302
+ /// Event emitted when a transaction's execution failed.
303
+ struct TransactionExecutionFailedEvent has drop, store {
304
+ executor: address,
305
+ sequence_number: u64,
306
+ transaction_payload: vector<u8>,
307
+ num_approvals: u64,
308
+ execution_error: ExecutionError,
309
+ }
310
+
311
+ #[event]
312
+ struct TransactionExecutionFailed has drop, store {
313
+ multisig_account: address,
314
+ executor: address,
315
+ sequence_number: u64,
316
+ transaction_payload: vector<u8>,
317
+ num_approvals: u64,
318
+ execution_error: ExecutionError,
319
+ }
320
+
321
+ /// Event emitted when a transaction's metadata is updated.
322
+ struct MetadataUpdatedEvent has drop, store {
323
+ old_metadata: SimpleMap<String, vector<u8>>,
324
+ new_metadata: SimpleMap<String, vector<u8>>,
325
+ }
326
+
327
+ #[event]
328
+ struct MetadataUpdated has drop, store {
329
+ multisig_account: address,
330
+ old_metadata: SimpleMap<String, vector<u8>>,
331
+ new_metadata: SimpleMap<String, vector<u8>>,
332
+ }
333
+
334
+ ////////////////////////// View functions ///////////////////////////////
335
+
336
+ #[view]
337
+ /// Return the multisig account's metadata.
338
+ public fun metadata(multisig_account: address): SimpleMap<String, vector<u8>> acquires MultisigAccount {
339
+ borrow_global<MultisigAccount>(multisig_account).metadata
340
+ }
341
+
342
+ #[view]
343
+ /// Return the number of signatures required to execute or execute-reject a transaction in the provided
344
+ /// multisig account.
345
+ public fun num_signatures_required(multisig_account: address): u64 acquires MultisigAccount {
346
+ borrow_global<MultisigAccount>(multisig_account).num_signatures_required
347
+ }
348
+
349
+ #[view]
350
+ /// Return a vector of all of the provided multisig account's owners.
351
+ public fun owners(multisig_account: address): vector<address> acquires MultisigAccount {
352
+ borrow_global<MultisigAccount>(multisig_account).owners
353
+ }
354
+
355
+ #[view]
356
+ /// Return true if the provided owner is an owner of the provided multisig account.
357
+ public fun is_owner(owner: address, multisig_account: address): bool acquires MultisigAccount {
358
+ vector::contains(&borrow_global<MultisigAccount>(multisig_account).owners, &owner)
359
+ }
360
+
361
+ #[view]
362
+ /// Return the transaction with the given transaction id.
363
+ public fun get_transaction(
364
+ multisig_account: address,
365
+ sequence_number: u64,
366
+ ): MultisigTransaction acquires MultisigAccount {
367
+ let multisig_account_resource = borrow_global<MultisigAccount>(multisig_account);
368
+ assert!(
369
+ sequence_number > 0 && sequence_number < multisig_account_resource.next_sequence_number,
370
+ error::invalid_argument(EINVALID_SEQUENCE_NUMBER),
371
+ );
372
+ *table::borrow(&multisig_account_resource.transactions, sequence_number)
373
+ }
374
+
375
+ #[view]
376
+ /// Return all pending transactions.
377
+ public fun get_pending_transactions(
378
+ multisig_account: address
379
+ ): vector<MultisigTransaction> acquires MultisigAccount {
380
+ let pending_transactions: vector<MultisigTransaction> = vector[];
381
+ let multisig_account = borrow_global<MultisigAccount>(multisig_account);
382
+ let i = multisig_account.last_executed_sequence_number + 1;
383
+ let next_sequence_number = multisig_account.next_sequence_number;
384
+ while (i < next_sequence_number) {
385
+ vector::push_back(&mut pending_transactions, *table::borrow(&multisig_account.transactions, i));
386
+ i = i + 1;
387
+ };
388
+ pending_transactions
389
+ }
390
+
391
+ #[view]
392
+ /// Return the payload for the next transaction in the queue.
393
+ public fun get_next_transaction_payload(
394
+ multisig_account: address, provided_payload: vector<u8>): vector<u8> acquires MultisigAccount {
395
+ let multisig_account_resource = borrow_global<MultisigAccount>(multisig_account);
396
+ let sequence_number = multisig_account_resource.last_executed_sequence_number + 1;
397
+ let transaction = table::borrow(&multisig_account_resource.transactions, sequence_number);
398
+
399
+ if (option::is_some(&transaction.payload)) {
400
+ *option::borrow(&transaction.payload)
401
+ } else {
402
+ provided_payload
403
+ }
404
+ }
405
+
406
+ #[view]
407
+ /// Return true if the transaction with given transaction id can be executed now.
408
+ public fun can_be_executed(multisig_account: address, sequence_number: u64): bool acquires MultisigAccount {
409
+ assert_valid_sequence_number(multisig_account, sequence_number);
410
+ let (num_approvals, _) = num_approvals_and_rejections(multisig_account, sequence_number);
411
+ sequence_number == last_resolved_sequence_number(multisig_account) + 1 &&
412
+ num_approvals >= num_signatures_required(multisig_account)
413
+ }
414
+
415
+ #[view]
416
+ /// Return true if the owner can execute the transaction with given transaction id now.
417
+ public fun can_execute(owner: address, multisig_account: address, sequence_number: u64): bool acquires MultisigAccount {
418
+ assert_valid_sequence_number(multisig_account, sequence_number);
419
+ let (num_approvals, _) = num_approvals_and_rejections(multisig_account, sequence_number);
420
+ if (!has_voted_for_approval(multisig_account, sequence_number, owner)) {
421
+ num_approvals = num_approvals + 1;
422
+ };
423
+ is_owner(owner, multisig_account) &&
424
+ sequence_number == last_resolved_sequence_number(multisig_account) + 1 &&
425
+ num_approvals >= num_signatures_required(multisig_account)
426
+ }
427
+
428
+ #[view]
429
+ /// Return true if the transaction with given transaction id can be officially rejected.
430
+ public fun can_be_rejected(multisig_account: address, sequence_number: u64): bool acquires MultisigAccount {
431
+ assert_valid_sequence_number(multisig_account, sequence_number);
432
+ let (_, num_rejections) = num_approvals_and_rejections(multisig_account, sequence_number);
433
+ sequence_number == last_resolved_sequence_number(multisig_account) + 1 &&
434
+ num_rejections >= num_signatures_required(multisig_account)
435
+ }
436
+
437
+ #[view]
438
+ /// Return true if the owner can execute the "rejected" transaction with given transaction id now.
439
+ public fun can_reject(owner: address, multisig_account: address, sequence_number: u64): bool acquires MultisigAccount {
440
+ assert_valid_sequence_number(multisig_account, sequence_number);
441
+ let (_, num_rejections) = num_approvals_and_rejections(multisig_account, sequence_number);
442
+ if (!has_voted_for_rejection(multisig_account, sequence_number, owner)) {
443
+ num_rejections = num_rejections + 1;
444
+ };
445
+ is_owner(owner, multisig_account) &&
446
+ sequence_number == last_resolved_sequence_number(multisig_account) + 1 &&
447
+ num_rejections >= num_signatures_required(multisig_account)
448
+ }
449
+
450
+ #[view]
451
+ /// Return the predicted address for the next multisig account if created from the given creator address.
452
+ public fun get_next_multisig_account_address(creator: address): address {
453
+ let owner_nonce = account::get_sequence_number(creator);
454
+ create_resource_address(&creator, create_multisig_account_seed(to_bytes(&owner_nonce)))
455
+ }
456
+
457
+ #[view]
458
+ /// Return the id of the last transaction that was executed (successful or failed) or removed.
459
+ public fun last_resolved_sequence_number(multisig_account: address): u64 acquires MultisigAccount {
460
+ let multisig_account_resource = borrow_global_mut<MultisigAccount>(multisig_account);
461
+ multisig_account_resource.last_executed_sequence_number
462
+ }
463
+
464
+ #[view]
465
+ /// Return the id of the next transaction created.
466
+ public fun next_sequence_number(multisig_account: address): u64 acquires MultisigAccount {
467
+ let multisig_account_resource = borrow_global_mut<MultisigAccount>(multisig_account);
468
+ multisig_account_resource.next_sequence_number
469
+ }
470
+
471
+ #[view]
472
+ /// Return a bool tuple indicating whether an owner has voted and if so, whether they voted yes or no.
473
+ public fun vote(
474
+ multisig_account: address, sequence_number: u64, owner: address): (bool, bool) acquires MultisigAccount {
475
+ let multisig_account_resource = borrow_global_mut<MultisigAccount>(multisig_account);
476
+ assert!(
477
+ sequence_number > 0 && sequence_number < multisig_account_resource.next_sequence_number,
478
+ error::invalid_argument(EINVALID_SEQUENCE_NUMBER),
479
+ );
480
+ let transaction = table::borrow(&multisig_account_resource.transactions, sequence_number);
481
+ let votes = &transaction.votes;
482
+ let voted = simple_map::contains_key(votes, &owner);
483
+ let vote = voted && *simple_map::borrow(votes, &owner);
484
+ (voted, vote)
485
+ }
486
+
487
+ #[view]
488
+ public fun available_transaction_queue_capacity(multisig_account: address): u64 acquires MultisigAccount {
489
+ let multisig_account_resource = borrow_global_mut<MultisigAccount>(multisig_account);
490
+ let num_pending_transactions = multisig_account_resource.next_sequence_number - multisig_account_resource.last_executed_sequence_number - 1;
491
+ if (num_pending_transactions > MAX_PENDING_TRANSACTIONS) {
492
+ 0
493
+ } else {
494
+ MAX_PENDING_TRANSACTIONS - num_pending_transactions
495
+ }
496
+ }
497
+
498
+ ////////////////////////// Multisig account creation functions ///////////////////////////////
499
+
500
+ /// Creates a new multisig account on top of an existing account.
501
+ ///
502
+ /// This offers a migration path for an existing account with a multi-ed25519 auth key (native multisig account).
503
+ /// In order to ensure a malicious module cannot obtain backdoor control over an existing account, a signed message
504
+ /// with a valid signature from the account's auth key is required.
505
+ ///
506
+ /// Note that this does not revoke auth key-based control over the account. Owners should separately rotate the auth
507
+ /// key after they are fully migrated to the new multisig account. Alternatively, they can call
508
+ /// create_with_existing_account_and_revoke_auth_key instead.
509
+ public entry fun create_with_existing_account(
510
+ multisig_address: address,
511
+ owners: vector<address>,
512
+ num_signatures_required: u64,
513
+ account_scheme: u8,
514
+ account_public_key: vector<u8>,
515
+ create_multisig_account_signed_message: vector<u8>,
516
+ metadata_keys: vector<String>,
517
+ metadata_values: vector<vector<u8>>,
518
+ ) acquires MultisigAccount {
519
+ // Verify that the `MultisigAccountCreationMessage` has the right information and is signed by the account
520
+ // owner's key.
521
+ let proof_challenge = MultisigAccountCreationMessage {
522
+ chain_id: chain_id::get(),
523
+ account_address: multisig_address,
524
+ sequence_number: account::get_sequence_number(multisig_address),
525
+ owners,
526
+ num_signatures_required,
527
+ };
528
+ account::verify_signed_message(
529
+ multisig_address,
530
+ account_scheme,
531
+ account_public_key,
532
+ create_multisig_account_signed_message,
533
+ proof_challenge,
534
+ );
535
+
536
+ // We create the signer for the multisig account here since this is required to add the MultisigAccount resource
537
+ // This should be safe and authorized because we have verified the signed message from the existing account
538
+ // that authorizes creating a multisig account with the specified owners and signature threshold.
539
+ let multisig_account = &create_signer(multisig_address);
540
+ create_with_owners_internal(
541
+ multisig_account,
542
+ owners,
543
+ num_signatures_required,
544
+ option::none<SignerCapability>(),
545
+ metadata_keys,
546
+ metadata_values,
547
+ );
548
+ }
549
+
550
+ /// Creates a new multisig account on top of an existing account and immediately rotate the origin auth key to 0x0.
551
+ ///
552
+ /// Note: If the original account is a resource account, this does not revoke all control over it as if any
553
+ /// SignerCapability of the resource account still exists, it can still be used to generate the signer for the
554
+ /// account.
555
+ public entry fun create_with_existing_account_and_revoke_auth_key(
556
+ multisig_address: address,
557
+ owners: vector<address>,
558
+ num_signatures_required: u64,
559
+ account_scheme: u8,
560
+ account_public_key: vector<u8>,
561
+ create_multisig_account_signed_message: vector<u8>,
562
+ metadata_keys: vector<String>,
563
+ metadata_values: vector<vector<u8>>,
564
+ ) acquires MultisigAccount {
565
+ // Verify that the `MultisigAccountCreationMessage` has the right information and is signed by the account
566
+ // owner's key.
567
+ let proof_challenge = MultisigAccountCreationWithAuthKeyRevocationMessage {
568
+ chain_id: chain_id::get(),
569
+ account_address: multisig_address,
570
+ sequence_number: account::get_sequence_number(multisig_address),
571
+ owners,
572
+ num_signatures_required,
573
+ };
574
+ account::verify_signed_message(
575
+ multisig_address,
576
+ account_scheme,
577
+ account_public_key,
578
+ create_multisig_account_signed_message,
579
+ proof_challenge,
580
+ );
581
+
582
+ // We create the signer for the multisig account here since this is required to add the MultisigAccount resource
583
+ // This should be safe and authorized because we have verified the signed message from the existing account
584
+ // that authorizes creating a multisig account with the specified owners and signature threshold.
585
+ let multisig_account = &create_signer(multisig_address);
586
+ create_with_owners_internal(
587
+ multisig_account,
588
+ owners,
589
+ num_signatures_required,
590
+ option::none<SignerCapability>(),
591
+ metadata_keys,
592
+ metadata_values,
593
+ );
594
+
595
+ // Rotate the account's auth key to 0x0, which effectively revokes control via auth key.
596
+ let multisig_address = address_of(multisig_account);
597
+ account::rotate_authentication_key_internal(multisig_account, ZERO_AUTH_KEY);
598
+ // This also needs to revoke any signer capability or rotation capability that exists for the account to
599
+ // completely remove all access to the account.
600
+ if (account::is_signer_capability_offered(multisig_address)) {
601
+ account::revoke_any_signer_capability(multisig_account);
602
+ };
603
+ if (account::is_rotation_capability_offered(multisig_address)) {
604
+ account::revoke_any_rotation_capability(multisig_account);
605
+ };
606
+ }
607
+
608
+ /// Creates a new multisig account and add the signer as a single owner.
609
+ public entry fun create(
610
+ owner: &signer,
611
+ num_signatures_required: u64,
612
+ metadata_keys: vector<String>,
613
+ metadata_values: vector<vector<u8>>,
614
+ ) acquires MultisigAccount {
615
+ create_with_owners(owner, vector[], num_signatures_required, metadata_keys, metadata_values);
616
+ }
617
+
618
+ /// Creates a new multisig account with the specified additional owner list and signatures required.
619
+ ///
620
+ /// @param additional_owners The owner account who calls this function cannot be in the additional_owners and there
621
+ /// cannot be any duplicate owners in the list.
622
+ /// @param num_signatures_required The number of signatures required to execute a transaction. Must be at least 1 and
623
+ /// at most the total number of owners.
624
+ public entry fun create_with_owners(
625
+ owner: &signer,
626
+ additional_owners: vector<address>,
627
+ num_signatures_required: u64,
628
+ metadata_keys: vector<String>,
629
+ metadata_values: vector<vector<u8>>,
630
+ ) acquires MultisigAccount {
631
+ let (multisig_account, multisig_signer_cap) = create_multisig_account(owner);
632
+ vector::push_back(&mut additional_owners, address_of(owner));
633
+ create_with_owners_internal(
634
+ &multisig_account,
635
+ additional_owners,
636
+ num_signatures_required,
637
+ option::some(multisig_signer_cap),
638
+ metadata_keys,
639
+ metadata_values,
640
+ );
641
+ }
642
+
643
+ /// Like `create_with_owners`, but removes the calling account after creation.
644
+ ///
645
+ /// This is for creating a vanity multisig account from a bootstrapping account that should not
646
+ /// be an owner after the vanity multisig address has been secured.
647
+ public entry fun create_with_owners_then_remove_bootstrapper(
648
+ bootstrapper: &signer,
649
+ owners: vector<address>,
650
+ num_signatures_required: u64,
651
+ metadata_keys: vector<String>,
652
+ metadata_values: vector<vector<u8>>,
653
+ ) acquires MultisigAccount {
654
+ let bootstrapper_address = address_of(bootstrapper);
655
+ create_with_owners(
656
+ bootstrapper,
657
+ owners,
658
+ num_signatures_required,
659
+ metadata_keys,
660
+ metadata_values
661
+ );
662
+ update_owner_schema(
663
+ get_next_multisig_account_address(bootstrapper_address),
664
+ vector[],
665
+ vector[bootstrapper_address],
666
+ option::none()
667
+ );
668
+ }
669
+
670
+ fun create_with_owners_internal(
671
+ multisig_account: &signer,
672
+ owners: vector<address>,
673
+ num_signatures_required: u64,
674
+ multisig_account_signer_cap: Option<SignerCapability>,
675
+ metadata_keys: vector<String>,
676
+ metadata_values: vector<vector<u8>>,
677
+ ) acquires MultisigAccount {
678
+ assert!(features::multisig_accounts_enabled(), error::unavailable(EMULTISIG_ACCOUNTS_NOT_ENABLED_YET));
679
+ assert!(
680
+ num_signatures_required > 0 && num_signatures_required <= vector::length(&owners),
681
+ error::invalid_argument(EINVALID_SIGNATURES_REQUIRED),
682
+ );
683
+
684
+ let multisig_address = address_of(multisig_account);
685
+ validate_owners(&owners, multisig_address);
686
+ move_to(multisig_account, MultisigAccount {
687
+ owners,
688
+ num_signatures_required,
689
+ transactions: table::new<u64, MultisigTransaction>(),
690
+ metadata: simple_map::create<String, vector<u8>>(),
691
+ // First transaction will start at id 1 instead of 0.
692
+ last_executed_sequence_number: 0,
693
+ next_sequence_number: 1,
694
+ signer_cap: multisig_account_signer_cap,
695
+ add_owners_events: new_event_handle<AddOwnersEvent>(multisig_account),
696
+ remove_owners_events: new_event_handle<RemoveOwnersEvent>(multisig_account),
697
+ update_signature_required_events: new_event_handle<UpdateSignaturesRequiredEvent>(multisig_account),
698
+ create_transaction_events: new_event_handle<CreateTransactionEvent>(multisig_account),
699
+ vote_events: new_event_handle<VoteEvent>(multisig_account),
700
+ execute_rejected_transaction_events: new_event_handle<ExecuteRejectedTransactionEvent>(multisig_account),
701
+ execute_transaction_events: new_event_handle<TransactionExecutionSucceededEvent>(multisig_account),
702
+ transaction_execution_failed_events: new_event_handle<TransactionExecutionFailedEvent>(multisig_account),
703
+ metadata_updated_events: new_event_handle<MetadataUpdatedEvent>(multisig_account),
704
+ });
705
+
706
+ update_metadata_internal(multisig_account, metadata_keys, metadata_values, false);
707
+ }
708
+
709
+ ////////////////////////// Self-updates ///////////////////////////////
710
+
711
+ /// Similar to add_owners, but only allow adding one owner.
712
+ entry fun add_owner(multisig_account: &signer, new_owner: address) acquires MultisigAccount {
713
+ add_owners(multisig_account, vector[new_owner]);
714
+ }
715
+
716
+ /// Add new owners to the multisig account. This can only be invoked by the multisig account itself, through the
717
+ /// proposal flow.
718
+ ///
719
+ /// Note that this function is not public so it can only be invoked directly instead of via a module or script. This
720
+ /// ensures that a multisig transaction cannot lead to another module obtaining the multisig signer and using it to
721
+ /// maliciously alter the owners list.
722
+ entry fun add_owners(
723
+ multisig_account: &signer, new_owners: vector<address>) acquires MultisigAccount {
724
+ update_owner_schema(
725
+ address_of(multisig_account),
726
+ new_owners,
727
+ vector[],
728
+ option::none()
729
+ );
730
+ }
731
+
732
+ /// Add owners then update number of signatures required, in a single operation.
733
+ entry fun add_owners_and_update_signatures_required(
734
+ multisig_account: &signer,
735
+ new_owners: vector<address>,
736
+ new_num_signatures_required: u64
737
+ ) acquires MultisigAccount {
738
+ update_owner_schema(
739
+ address_of(multisig_account),
740
+ new_owners,
741
+ vector[],
742
+ option::some(new_num_signatures_required)
743
+ );
744
+ }
745
+
746
+ /// Similar to remove_owners, but only allow removing one owner.
747
+ entry fun remove_owner(
748
+ multisig_account: &signer, owner_to_remove: address) acquires MultisigAccount {
749
+ remove_owners(multisig_account, vector[owner_to_remove]);
750
+ }
751
+
752
+ /// Remove owners from the multisig account. This can only be invoked by the multisig account itself, through the
753
+ /// proposal flow.
754
+ ///
755
+ /// This function skips any owners who are not in the multisig account's list of owners.
756
+ /// Note that this function is not public so it can only be invoked directly instead of via a module or script. This
757
+ /// ensures that a multisig transaction cannot lead to another module obtaining the multisig signer and using it to
758
+ /// maliciously alter the owners list.
759
+ entry fun remove_owners(
760
+ multisig_account: &signer, owners_to_remove: vector<address>) acquires MultisigAccount {
761
+ update_owner_schema(
762
+ address_of(multisig_account),
763
+ vector[],
764
+ owners_to_remove,
765
+ option::none()
766
+ );
767
+ }
768
+
769
+ /// Swap an owner in for an old one, without changing required signatures.
770
+ entry fun swap_owner(
771
+ multisig_account: &signer,
772
+ to_swap_in: address,
773
+ to_swap_out: address
774
+ ) acquires MultisigAccount {
775
+ update_owner_schema(
776
+ address_of(multisig_account),
777
+ vector[to_swap_in],
778
+ vector[to_swap_out],
779
+ option::none()
780
+ );
781
+ }
782
+
783
+ /// Swap owners in and out, without changing required signatures.
784
+ entry fun swap_owners(
785
+ multisig_account: &signer,
786
+ to_swap_in: vector<address>,
787
+ to_swap_out: vector<address>
788
+ ) acquires MultisigAccount {
789
+ update_owner_schema(
790
+ address_of(multisig_account),
791
+ to_swap_in,
792
+ to_swap_out,
793
+ option::none()
794
+ );
795
+ }
796
+
797
+ /// Swap owners in and out, updating number of required signatures.
798
+ entry fun swap_owners_and_update_signatures_required(
799
+ multisig_account: &signer,
800
+ new_owners: vector<address>,
801
+ owners_to_remove: vector<address>,
802
+ new_num_signatures_required: u64
803
+ ) acquires MultisigAccount {
804
+ update_owner_schema(
805
+ address_of(multisig_account),
806
+ new_owners,
807
+ owners_to_remove,
808
+ option::some(new_num_signatures_required)
809
+ );
810
+ }
811
+
812
+ /// Update the number of signatures required to execute transaction in the specified multisig account.
813
+ ///
814
+ /// This can only be invoked by the multisig account itself, through the proposal flow.
815
+ /// Note that this function is not public so it can only be invoked directly instead of via a module or script. This
816
+ /// ensures that a multisig transaction cannot lead to another module obtaining the multisig signer and using it to
817
+ /// maliciously alter the number of signatures required.
818
+ entry fun update_signatures_required(
819
+ multisig_account: &signer, new_num_signatures_required: u64) acquires MultisigAccount {
820
+ update_owner_schema(
821
+ address_of(multisig_account),
822
+ vector[],
823
+ vector[],
824
+ option::some(new_num_signatures_required)
825
+ );
826
+ }
827
+
828
+ /// Allow the multisig account to update its own metadata. Note that this overrides the entire existing metadata.
829
+ /// If any attributes are not specified in the metadata, they will be removed!
830
+ ///
831
+ /// This can only be invoked by the multisig account itself, through the proposal flow.
832
+ /// Note that this function is not public so it can only be invoked directly instead of via a module or script. This
833
+ /// ensures that a multisig transaction cannot lead to another module obtaining the multisig signer and using it to
834
+ /// maliciously alter the number of signatures required.
835
+ entry fun update_metadata(
836
+ multisig_account: &signer, keys: vector<String>, values: vector<vector<u8>>) acquires MultisigAccount {
837
+ update_metadata_internal(multisig_account, keys, values, true);
838
+ }
839
+
840
+ fun update_metadata_internal(
841
+ multisig_account: &signer,
842
+ keys: vector<String>,
843
+ values: vector<vector<u8>>,
844
+ emit_event: bool,
845
+ ) acquires MultisigAccount {
846
+ let num_attributes = vector::length(&keys);
847
+ assert!(
848
+ num_attributes == vector::length(&values),
849
+ error::invalid_argument(ENUMBER_OF_METADATA_KEYS_AND_VALUES_DONT_MATCH),
850
+ );
851
+
852
+ let multisig_address = address_of(multisig_account);
853
+ assert_multisig_account_exists(multisig_address);
854
+ let multisig_account_resource = borrow_global_mut<MultisigAccount>(multisig_address);
855
+ let old_metadata = multisig_account_resource.metadata;
856
+ multisig_account_resource.metadata = simple_map::create<String, vector<u8>>();
857
+ let metadata = &mut multisig_account_resource.metadata;
858
+ let i = 0;
859
+ while (i < num_attributes) {
860
+ let key = *vector::borrow(&keys, i);
861
+ let value = *vector::borrow(&values, i);
862
+ assert!(
863
+ !simple_map::contains_key(metadata, &key),
864
+ error::invalid_argument(EDUPLICATE_METADATA_KEY),
865
+ );
866
+
867
+ simple_map::add(metadata, key, value);
868
+ i = i + 1;
869
+ };
870
+
871
+ if (emit_event) {
872
+ if (std::features::module_event_migration_enabled()) {
873
+ emit(
874
+ MetadataUpdated {
875
+ multisig_account: multisig_address,
876
+ old_metadata,
877
+ new_metadata: multisig_account_resource.metadata,
878
+ }
879
+ )
880
+ };
881
+ emit_event(
882
+ &mut multisig_account_resource.metadata_updated_events,
883
+ MetadataUpdatedEvent {
884
+ old_metadata,
885
+ new_metadata: multisig_account_resource.metadata,
886
+ }
887
+ );
888
+ };
889
+ }
890
+
891
+ ////////////////////////// Multisig transaction flow ///////////////////////////////
892
+
893
+ /// Create a multisig transaction, which will have one approval initially (from the creator).
894
+ public entry fun create_transaction(
895
+ owner: &signer,
896
+ multisig_account: address,
897
+ payload: vector<u8>,
898
+ ) acquires MultisigAccount {
899
+ assert!(vector::length(&payload) > 0, error::invalid_argument(EPAYLOAD_CANNOT_BE_EMPTY));
900
+
901
+ assert_multisig_account_exists(multisig_account);
902
+ assert_is_owner(owner, multisig_account);
903
+
904
+ let creator = address_of(owner);
905
+ let transaction = MultisigTransaction {
906
+ payload: option::some(payload),
907
+ payload_hash: option::none<vector<u8>>(),
908
+ votes: simple_map::create<address, bool>(),
909
+ creator,
910
+ creation_time_secs: now_seconds(),
911
+ };
912
+ add_transaction(creator, multisig_account, transaction);
913
+ }
914
+
915
+ /// Create a multisig transaction with a transaction hash instead of the full payload.
916
+ /// This means the payload will be stored off chain for gas saving. Later, during execution, the executor will need
917
+ /// to provide the full payload, which will be validated against the hash stored on-chain.
918
+ public entry fun create_transaction_with_hash(
919
+ owner: &signer,
920
+ multisig_account: address,
921
+ payload_hash: vector<u8>,
922
+ ) acquires MultisigAccount {
923
+ // Payload hash is a sha3-256 hash, so it must be exactly 32 bytes.
924
+ assert!(vector::length(&payload_hash) == 32, error::invalid_argument(EINVALID_PAYLOAD_HASH));
925
+
926
+ assert_multisig_account_exists(multisig_account);
927
+ assert_is_owner(owner, multisig_account);
928
+
929
+ let creator = address_of(owner);
930
+ let transaction = MultisigTransaction {
931
+ payload: option::none<vector<u8>>(),
932
+ payload_hash: option::some(payload_hash),
933
+ votes: simple_map::create<address, bool>(),
934
+ creator,
935
+ creation_time_secs: now_seconds(),
936
+ };
937
+ add_transaction(creator, multisig_account, transaction);
938
+ }
939
+
940
+ /// Approve a multisig transaction.
941
+ public entry fun approve_transaction(
942
+ owner: &signer, multisig_account: address, sequence_number: u64) acquires MultisigAccount {
943
+ vote_transanction(owner, multisig_account, sequence_number, true);
944
+ }
945
+
946
+ /// Reject a multisig transaction.
947
+ public entry fun reject_transaction(
948
+ owner: &signer, multisig_account: address, sequence_number: u64) acquires MultisigAccount {
949
+ vote_transanction(owner, multisig_account, sequence_number, false);
950
+ }
951
+
952
+ /// Generic function that can be used to either approve or reject a multisig transaction
953
+ /// Retained for backward compatibility: the function with the typographical error in its name
954
+ /// will continue to be an accessible entry point.
955
+ public entry fun vote_transanction(
956
+ owner: &signer, multisig_account: address, sequence_number: u64, approved: bool) acquires MultisigAccount {
957
+ assert_multisig_account_exists(multisig_account);
958
+ let multisig_account_resource = borrow_global_mut<MultisigAccount>(multisig_account);
959
+ assert_is_owner_internal(owner, multisig_account_resource);
960
+
961
+ assert!(
962
+ table::contains(&multisig_account_resource.transactions, sequence_number),
963
+ error::not_found(ETRANSACTION_NOT_FOUND),
964
+ );
965
+ let transaction = table::borrow_mut(&mut multisig_account_resource.transactions, sequence_number);
966
+ let votes = &mut transaction.votes;
967
+ let owner_addr = address_of(owner);
968
+
969
+ if (simple_map::contains_key(votes, &owner_addr)) {
970
+ *simple_map::borrow_mut(votes, &owner_addr) = approved;
971
+ } else {
972
+ simple_map::add(votes, owner_addr, approved);
973
+ };
974
+
975
+ if (std::features::module_event_migration_enabled()) {
976
+ emit(
977
+ Vote {
978
+ multisig_account,
979
+ owner: owner_addr,
980
+ sequence_number,
981
+ approved,
982
+ }
983
+ );
984
+ };
985
+ emit_event(
986
+ &mut multisig_account_resource.vote_events,
987
+ VoteEvent {
988
+ owner: owner_addr,
989
+ sequence_number,
990
+ approved,
991
+ }
992
+ );
993
+ }
994
+
995
+ /// Generic function that can be used to either approve or reject a multisig transaction
996
+ public entry fun vote_transaction(
997
+ owner: &signer, multisig_account: address, sequence_number: u64, approved: bool) acquires MultisigAccount {
998
+ assert!(features::multisig_v2_enhancement_feature_enabled(), error::invalid_state(EMULTISIG_V2_ENHANCEMENT_NOT_ENABLED));
999
+ vote_transanction(owner, multisig_account, sequence_number, approved);
1000
+ }
1001
+
1002
+ /// Generic function that can be used to either approve or reject a batch of transactions within a specified range.
1003
+ public entry fun vote_transactions(
1004
+ owner: &signer, multisig_account: address, starting_sequence_number: u64, final_sequence_number: u64, approved: bool) acquires MultisigAccount {
1005
+ assert!(features::multisig_v2_enhancement_feature_enabled(), error::invalid_state(EMULTISIG_V2_ENHANCEMENT_NOT_ENABLED));
1006
+ let sequence_number = starting_sequence_number;
1007
+ while(sequence_number <= final_sequence_number) {
1008
+ vote_transanction(owner, multisig_account, sequence_number, approved);
1009
+ sequence_number = sequence_number + 1;
1010
+ }
1011
+ }
1012
+
1013
+ /// Remove the next transaction if it has sufficient owner rejections.
1014
+ public entry fun execute_rejected_transaction(
1015
+ owner: &signer,
1016
+ multisig_account: address,
1017
+ ) acquires MultisigAccount {
1018
+ assert_multisig_account_exists(multisig_account);
1019
+ assert_is_owner(owner, multisig_account);
1020
+
1021
+ let sequence_number = last_resolved_sequence_number(multisig_account) + 1;
1022
+ let owner_addr = address_of(owner);
1023
+ if (features::multisig_v2_enhancement_feature_enabled()) {
1024
+ // Implicitly vote for rejection if the owner has not voted for rejection yet.
1025
+ if (!has_voted_for_rejection(multisig_account, sequence_number, owner_addr)) {
1026
+ reject_transaction(owner, multisig_account, sequence_number);
1027
+ }
1028
+ };
1029
+
1030
+ let multisig_account_resource = borrow_global_mut<MultisigAccount>(multisig_account);
1031
+ let (_, num_rejections) = remove_executed_transaction(multisig_account_resource);
1032
+ assert!(
1033
+ num_rejections >= multisig_account_resource.num_signatures_required,
1034
+ error::invalid_state(ENOT_ENOUGH_REJECTIONS),
1035
+ );
1036
+
1037
+ if (std::features::module_event_migration_enabled()) {
1038
+ emit(
1039
+ ExecuteRejectedTransaction {
1040
+ multisig_account,
1041
+ sequence_number,
1042
+ num_rejections,
1043
+ executor: address_of(owner),
1044
+ }
1045
+ );
1046
+ };
1047
+ emit_event(
1048
+ &mut multisig_account_resource.execute_rejected_transaction_events,
1049
+ ExecuteRejectedTransactionEvent {
1050
+ sequence_number,
1051
+ num_rejections,
1052
+ executor: owner_addr,
1053
+ }
1054
+ );
1055
+ }
1056
+
1057
+ /// Remove the next transactions until the final_sequence_number if they have sufficient owner rejections.
1058
+ public entry fun execute_rejected_transactions(
1059
+ owner: &signer,
1060
+ multisig_account: address,
1061
+ final_sequence_number: u64,
1062
+ ) acquires MultisigAccount {
1063
+ assert!(features::multisig_v2_enhancement_feature_enabled(), error::invalid_state(EMULTISIG_V2_ENHANCEMENT_NOT_ENABLED));
1064
+ assert!(last_resolved_sequence_number(multisig_account) < final_sequence_number, error::invalid_argument(EINVALID_SEQUENCE_NUMBER));
1065
+ assert!(final_sequence_number < next_sequence_number(multisig_account), error::invalid_argument(EINVALID_SEQUENCE_NUMBER));
1066
+ while(last_resolved_sequence_number(multisig_account) < final_sequence_number) {
1067
+ execute_rejected_transaction(owner, multisig_account);
1068
+ }
1069
+ }
1070
+
1071
+ ////////////////////////// To be called by VM only ///////////////////////////////
1072
+
1073
+ /// Called by the VM as part of transaction prologue, which is invoked during mempool transaction validation and as
1074
+ /// the first step of transaction execution.
1075
+ ///
1076
+ /// Transaction payload is optional if it's already stored on chain for the transaction.
1077
+ fun validate_multisig_transaction(
1078
+ owner: &signer, multisig_account: address, payload: vector<u8>) acquires MultisigAccount {
1079
+ assert_multisig_account_exists(multisig_account);
1080
+ assert_is_owner(owner, multisig_account);
1081
+ let sequence_number = last_resolved_sequence_number(multisig_account) + 1;
1082
+ assert_transaction_exists(multisig_account, sequence_number);
1083
+
1084
+ if (features::multisig_v2_enhancement_feature_enabled()) {
1085
+ assert!(
1086
+ can_execute(address_of(owner), multisig_account, sequence_number),
1087
+ error::invalid_argument(ENOT_ENOUGH_APPROVALS),
1088
+ );
1089
+ }
1090
+ else {
1091
+ assert!(
1092
+ can_be_executed(multisig_account, sequence_number),
1093
+ error::invalid_argument(ENOT_ENOUGH_APPROVALS),
1094
+ );
1095
+ };
1096
+
1097
+ // If the transaction payload is not stored on chain, verify that the provided payload matches the hashes stored
1098
+ // on chain.
1099
+ let multisig_account_resource = borrow_global<MultisigAccount>(multisig_account);
1100
+ let transaction = table::borrow(&multisig_account_resource.transactions, sequence_number);
1101
+ if (option::is_some(&transaction.payload_hash)) {
1102
+ let payload_hash = option::borrow(&transaction.payload_hash);
1103
+ assert!(
1104
+ sha3_256(payload) == *payload_hash,
1105
+ error::invalid_argument(EPAYLOAD_DOES_NOT_MATCH_HASH),
1106
+ );
1107
+ };
1108
+
1109
+ // If the transaction payload is stored on chain and there is a provided payload,
1110
+ // verify that the provided payload matches the stored payload.
1111
+ if (features::abort_if_multisig_payload_mismatch_enabled()
1112
+ && option::is_some(&transaction.payload)
1113
+ && !vector::is_empty(&payload)
1114
+ ) {
1115
+ let stored_payload = option::borrow(&transaction.payload);
1116
+ assert!(
1117
+ payload == *stored_payload,
1118
+ error::invalid_argument(EPAYLOAD_DOES_NOT_MATCH),
1119
+ );
1120
+ }
1121
+ }
1122
+
1123
+ /// Post-execution cleanup for a successful multisig transaction execution.
1124
+ /// This function is private so no other code can call this beside the VM itself as part of MultisigTransaction.
1125
+ fun successful_transaction_execution_cleanup(
1126
+ executor: address,
1127
+ multisig_account: address,
1128
+ transaction_payload: vector<u8>,
1129
+ ) acquires MultisigAccount {
1130
+ let num_approvals = transaction_execution_cleanup_common(executor, multisig_account);
1131
+ let multisig_account_resource = borrow_global_mut<MultisigAccount>(multisig_account);
1132
+ if (std::features::module_event_migration_enabled()) {
1133
+ emit(
1134
+ TransactionExecutionSucceeded {
1135
+ multisig_account,
1136
+ sequence_number: multisig_account_resource.last_executed_sequence_number,
1137
+ transaction_payload,
1138
+ num_approvals,
1139
+ executor,
1140
+ }
1141
+ );
1142
+ };
1143
+ emit_event(
1144
+ &mut multisig_account_resource.execute_transaction_events,
1145
+ TransactionExecutionSucceededEvent {
1146
+ sequence_number: multisig_account_resource.last_executed_sequence_number,
1147
+ transaction_payload,
1148
+ num_approvals,
1149
+ executor,
1150
+ }
1151
+ );
1152
+ }
1153
+
1154
+ /// Post-execution cleanup for a failed multisig transaction execution.
1155
+ /// This function is private so no other code can call this beside the VM itself as part of MultisigTransaction.
1156
+ fun failed_transaction_execution_cleanup(
1157
+ executor: address,
1158
+ multisig_account: address,
1159
+ transaction_payload: vector<u8>,
1160
+ execution_error: ExecutionError,
1161
+ ) acquires MultisigAccount {
1162
+ let num_approvals = transaction_execution_cleanup_common(executor, multisig_account);
1163
+ let multisig_account_resource = borrow_global_mut<MultisigAccount>(multisig_account);
1164
+ if (std::features::module_event_migration_enabled()) {
1165
+ emit(
1166
+ TransactionExecutionFailed {
1167
+ multisig_account,
1168
+ executor,
1169
+ sequence_number: multisig_account_resource.last_executed_sequence_number,
1170
+ transaction_payload,
1171
+ num_approvals,
1172
+ execution_error,
1173
+ }
1174
+ );
1175
+ };
1176
+ emit_event(
1177
+ &mut multisig_account_resource.transaction_execution_failed_events,
1178
+ TransactionExecutionFailedEvent {
1179
+ executor,
1180
+ sequence_number: multisig_account_resource.last_executed_sequence_number,
1181
+ transaction_payload,
1182
+ num_approvals,
1183
+ execution_error,
1184
+ }
1185
+ );
1186
+ }
1187
+
1188
+ ////////////////////////// Private functions ///////////////////////////////
1189
+
1190
+ inline fun transaction_execution_cleanup_common(executor: address, multisig_account: address): u64 acquires MultisigAccount {
1191
+ let sequence_number = last_resolved_sequence_number(multisig_account) + 1;
1192
+ let implicit_approval = !has_voted_for_approval(multisig_account, sequence_number, executor);
1193
+
1194
+ let multisig_account_resource = borrow_global_mut<MultisigAccount>(multisig_account);
1195
+ let (num_approvals, _) = remove_executed_transaction(multisig_account_resource);
1196
+
1197
+ if (features::multisig_v2_enhancement_feature_enabled() && implicit_approval) {
1198
+ if (std::features::module_event_migration_enabled()) {
1199
+ emit(
1200
+ Vote {
1201
+ multisig_account,
1202
+ owner: executor,
1203
+ sequence_number,
1204
+ approved: true,
1205
+ }
1206
+ );
1207
+ };
1208
+ num_approvals = num_approvals + 1;
1209
+ emit_event(
1210
+ &mut multisig_account_resource.vote_events,
1211
+ VoteEvent {
1212
+ owner: executor,
1213
+ sequence_number,
1214
+ approved: true,
1215
+ }
1216
+ );
1217
+ };
1218
+
1219
+ num_approvals
1220
+ }
1221
+
1222
+ // Remove the next transaction in the queue as it's been executed and return the number of approvals it had.
1223
+ fun remove_executed_transaction(multisig_account_resource: &mut MultisigAccount): (u64, u64) {
1224
+ let sequence_number = multisig_account_resource.last_executed_sequence_number + 1;
1225
+ let transaction = table::remove(&mut multisig_account_resource.transactions, sequence_number);
1226
+ multisig_account_resource.last_executed_sequence_number = sequence_number;
1227
+ num_approvals_and_rejections_internal(&multisig_account_resource.owners, &transaction)
1228
+ }
1229
+
1230
+ inline fun add_transaction(
1231
+ creator: address,
1232
+ multisig_account: address,
1233
+ transaction: MultisigTransaction
1234
+ ) {
1235
+ if (features::multisig_v2_enhancement_feature_enabled()) {
1236
+ assert!(
1237
+ available_transaction_queue_capacity(multisig_account) > 0,
1238
+ error::invalid_state(EMAX_PENDING_TRANSACTIONS_EXCEEDED)
1239
+ );
1240
+ };
1241
+
1242
+ let multisig_account_resource = borrow_global_mut<MultisigAccount>(multisig_account);
1243
+
1244
+ // The transaction creator also automatically votes for the transaction.
1245
+ simple_map::add(&mut transaction.votes, creator, true);
1246
+
1247
+ let sequence_number = multisig_account_resource.next_sequence_number;
1248
+ multisig_account_resource.next_sequence_number = sequence_number + 1;
1249
+ table::add(&mut multisig_account_resource.transactions, sequence_number, transaction);
1250
+ if (std::features::module_event_migration_enabled()) {
1251
+ emit(
1252
+ CreateTransaction { multisig_account: multisig_account, creator, sequence_number, transaction }
1253
+ );
1254
+ };
1255
+ emit_event(
1256
+ &mut multisig_account_resource.create_transaction_events,
1257
+ CreateTransactionEvent { creator, sequence_number, transaction },
1258
+ );
1259
+ }
1260
+
1261
+ fun create_multisig_account(owner: &signer): (signer, SignerCapability) {
1262
+ let owner_nonce = account::get_sequence_number(address_of(owner));
1263
+ let (multisig_signer, multisig_signer_cap) =
1264
+ account::create_resource_account(owner, create_multisig_account_seed(to_bytes(&owner_nonce)));
1265
+ // Register the account to receive APT as this is not done by default as part of the resource account creation
1266
+ // flow.
1267
+ if (!coin::is_account_registered<AptosCoin>(address_of(&multisig_signer))) {
1268
+ coin::register<AptosCoin>(&multisig_signer);
1269
+ };
1270
+
1271
+ (multisig_signer, multisig_signer_cap)
1272
+ }
1273
+
1274
+ fun create_multisig_account_seed(seed: vector<u8>): vector<u8> {
1275
+ // Generate a seed that will be used to create the resource account that hosts the multisig account.
1276
+ let multisig_account_seed = vector::empty<u8>();
1277
+ vector::append(&mut multisig_account_seed, DOMAIN_SEPARATOR);
1278
+ vector::append(&mut multisig_account_seed, seed);
1279
+
1280
+ multisig_account_seed
1281
+ }
1282
+
1283
+ fun validate_owners(owners: &vector<address>, multisig_account: address) {
1284
+ let distinct_owners: vector<address> = vector[];
1285
+ vector::for_each_ref(owners, |owner| {
1286
+ let owner = *owner;
1287
+ assert!(owner != multisig_account, error::invalid_argument(EOWNER_CANNOT_BE_MULTISIG_ACCOUNT_ITSELF));
1288
+ let (found, _) = vector::index_of(&distinct_owners, &owner);
1289
+ assert!(!found, error::invalid_argument(EDUPLICATE_OWNER));
1290
+ vector::push_back(&mut distinct_owners, owner);
1291
+ });
1292
+ }
1293
+
1294
+ inline fun assert_is_owner_internal(owner: &signer, multisig_account: &MultisigAccount) {
1295
+ assert!(
1296
+ vector::contains(&multisig_account.owners, &address_of(owner)),
1297
+ error::permission_denied(ENOT_OWNER),
1298
+ );
1299
+ }
1300
+
1301
+ inline fun assert_is_owner(owner: &signer, multisig_account: address) acquires MultisigAccount {
1302
+ let multisig_account_resource = borrow_global<MultisigAccount>(multisig_account);
1303
+ assert_is_owner_internal(owner, multisig_account_resource);
1304
+ }
1305
+
1306
+ inline fun num_approvals_and_rejections_internal(owners: &vector<address>, transaction: &MultisigTransaction): (u64, u64) {
1307
+ let num_approvals = 0;
1308
+ let num_rejections = 0;
1309
+
1310
+ let votes = &transaction.votes;
1311
+ vector::for_each_ref(owners, |owner| {
1312
+ if (simple_map::contains_key(votes, owner)) {
1313
+ if (*simple_map::borrow(votes, owner)) {
1314
+ num_approvals = num_approvals + 1;
1315
+ } else {
1316
+ num_rejections = num_rejections + 1;
1317
+ };
1318
+ }
1319
+ });
1320
+
1321
+ (num_approvals, num_rejections)
1322
+ }
1323
+
1324
+ inline fun num_approvals_and_rejections(multisig_account: address, sequence_number: u64): (u64, u64) acquires MultisigAccount {
1325
+ let multisig_account_resource = borrow_global<MultisigAccount>(multisig_account);
1326
+ let transaction = table::borrow(&multisig_account_resource.transactions, sequence_number);
1327
+ num_approvals_and_rejections_internal(&multisig_account_resource.owners, transaction)
1328
+ }
1329
+
1330
+ inline fun has_voted_for_approval(multisig_account: address, sequence_number: u64, owner: address): bool acquires MultisigAccount {
1331
+ let (voted, vote) = vote(multisig_account, sequence_number, owner);
1332
+ voted && vote
1333
+ }
1334
+
1335
+ inline fun has_voted_for_rejection(multisig_account: address, sequence_number: u64, owner: address): bool acquires MultisigAccount {
1336
+ let (voted, vote) = vote(multisig_account, sequence_number, owner);
1337
+ voted && !vote
1338
+ }
1339
+
1340
+ inline fun assert_multisig_account_exists(multisig_account: address) {
1341
+ assert!(exists<MultisigAccount>(multisig_account), error::invalid_state(EACCOUNT_NOT_MULTISIG));
1342
+ }
1343
+
1344
+ inline fun assert_valid_sequence_number(multisig_account: address, sequence_number: u64) acquires MultisigAccount {
1345
+ let multisig_account_resource = borrow_global<MultisigAccount>(multisig_account);
1346
+ assert!(
1347
+ sequence_number > 0 && sequence_number < multisig_account_resource.next_sequence_number,
1348
+ error::invalid_argument(EINVALID_SEQUENCE_NUMBER),
1349
+ );
1350
+ }
1351
+
1352
+ inline fun assert_transaction_exists(multisig_account: address, sequence_number: u64) acquires MultisigAccount {
1353
+ let multisig_account_resource = borrow_global<MultisigAccount>(multisig_account);
1354
+ assert!(
1355
+ table::contains(&multisig_account_resource.transactions, sequence_number),
1356
+ error::not_found(ETRANSACTION_NOT_FOUND),
1357
+ );
1358
+ }
1359
+
1360
+ /// Add new owners, remove owners to remove, update signatures required.
1361
+ fun update_owner_schema(
1362
+ multisig_address: address,
1363
+ new_owners: vector<address>,
1364
+ owners_to_remove: vector<address>,
1365
+ optional_new_num_signatures_required: Option<u64>,
1366
+ ) acquires MultisigAccount {
1367
+ assert_multisig_account_exists(multisig_address);
1368
+ let multisig_account_ref_mut =
1369
+ borrow_global_mut<MultisigAccount>(multisig_address);
1370
+ // Verify no overlap between new owners and owners to remove.
1371
+ vector::for_each_ref(&new_owners, |new_owner_ref| {
1372
+ assert!(
1373
+ !vector::contains(&owners_to_remove, new_owner_ref),
1374
+ error::invalid_argument(EOWNERS_TO_REMOVE_NEW_OWNERS_OVERLAP)
1375
+ )
1376
+ });
1377
+ // If new owners provided, try to add them and emit an event.
1378
+ if (vector::length(&new_owners) > 0) {
1379
+ vector::append(&mut multisig_account_ref_mut.owners, new_owners);
1380
+ validate_owners(
1381
+ &multisig_account_ref_mut.owners,
1382
+ multisig_address
1383
+ );
1384
+ if (std::features::module_event_migration_enabled()) {
1385
+ emit(AddOwners { multisig_account: multisig_address, owners_added: new_owners });
1386
+ };
1387
+ emit_event(
1388
+ &mut multisig_account_ref_mut.add_owners_events,
1389
+ AddOwnersEvent { owners_added: new_owners }
1390
+ );
1391
+ };
1392
+ // If owners to remove provided, try to remove them.
1393
+ if (vector::length(&owners_to_remove) > 0) {
1394
+ let owners_ref_mut = &mut multisig_account_ref_mut.owners;
1395
+ let owners_removed = vector[];
1396
+ vector::for_each_ref(&owners_to_remove, |owner_to_remove_ref| {
1397
+ let (found, index) =
1398
+ vector::index_of(owners_ref_mut, owner_to_remove_ref);
1399
+ if (found) {
1400
+ vector::push_back(
1401
+ &mut owners_removed,
1402
+ vector::swap_remove(owners_ref_mut, index)
1403
+ );
1404
+ }
1405
+ });
1406
+ // Only emit event if owner(s) actually removed.
1407
+ if (vector::length(&owners_removed) > 0) {
1408
+ if (std::features::module_event_migration_enabled()) {
1409
+ emit(
1410
+ RemoveOwners { multisig_account: multisig_address, owners_removed }
1411
+ );
1412
+ };
1413
+ emit_event(
1414
+ &mut multisig_account_ref_mut.remove_owners_events,
1415
+ RemoveOwnersEvent { owners_removed }
1416
+ );
1417
+ }
1418
+ };
1419
+ // If new signature count provided, try to update count.
1420
+ if (option::is_some(&optional_new_num_signatures_required)) {
1421
+ let new_num_signatures_required =
1422
+ option::extract(&mut optional_new_num_signatures_required);
1423
+ assert!(
1424
+ new_num_signatures_required > 0,
1425
+ error::invalid_argument(EINVALID_SIGNATURES_REQUIRED)
1426
+ );
1427
+ let old_num_signatures_required =
1428
+ multisig_account_ref_mut.num_signatures_required;
1429
+ // Only apply update and emit event if a change indicated.
1430
+ if (new_num_signatures_required != old_num_signatures_required) {
1431
+ multisig_account_ref_mut.num_signatures_required =
1432
+ new_num_signatures_required;
1433
+ if (std::features::module_event_migration_enabled()) {
1434
+ emit(
1435
+ UpdateSignaturesRequired {
1436
+ multisig_account: multisig_address,
1437
+ old_num_signatures_required,
1438
+ new_num_signatures_required,
1439
+ }
1440
+ );
1441
+ };
1442
+ emit_event(
1443
+ &mut multisig_account_ref_mut.update_signature_required_events,
1444
+ UpdateSignaturesRequiredEvent {
1445
+ old_num_signatures_required,
1446
+ new_num_signatures_required,
1447
+ }
1448
+ );
1449
+ }
1450
+ };
1451
+ // Verify number of owners.
1452
+ let num_owners = vector::length(&multisig_account_ref_mut.owners);
1453
+ assert!(
1454
+ num_owners >= multisig_account_ref_mut.num_signatures_required,
1455
+ error::invalid_state(ENOT_ENOUGH_OWNERS)
1456
+ );
1457
+ }
1458
+
1459
+ ////////////////////////// Tests ///////////////////////////////
1460
+
1461
+ #[test_only]
1462
+ use aptos_framework::aptos_account::create_account;
1463
+ #[test_only]
1464
+ use aptos_framework::timestamp;
1465
+ #[test_only]
1466
+ use aptos_std::from_bcs;
1467
+ #[test_only]
1468
+ use aptos_std::multi_ed25519;
1469
+ #[test_only]
1470
+ use std::string::utf8;
1471
+ use std::features;
1472
+ #[test_only]
1473
+ use aptos_framework::aptos_coin;
1474
+ #[test_only]
1475
+ use aptos_framework::coin::{destroy_mint_cap, destroy_burn_cap};
1476
+
1477
+ #[test_only]
1478
+ const PAYLOAD: vector<u8> = vector[1, 2, 3];
1479
+ #[test_only]
1480
+ const ERROR_TYPE: vector<u8> = b"MoveAbort";
1481
+ #[test_only]
1482
+ const ABORT_LOCATION: vector<u8> = b"abort_location";
1483
+ #[test_only]
1484
+ const ERROR_CODE: u64 = 10;
1485
+
1486
+ #[test_only]
1487
+ fun execution_error(): ExecutionError {
1488
+ ExecutionError {
1489
+ abort_location: utf8(ABORT_LOCATION),
1490
+ error_type: utf8(ERROR_TYPE),
1491
+ error_code: ERROR_CODE,
1492
+ }
1493
+ }
1494
+
1495
+ #[test_only]
1496
+ fun setup() {
1497
+ let framework_signer = &create_signer(@0x1);
1498
+ features::change_feature_flags_for_testing(
1499
+ framework_signer, vector[features::get_multisig_accounts_feature(), features::get_multisig_v2_enhancement_feature(), features::get_abort_if_multisig_payload_mismatch_feature()], vector[]);
1500
+ timestamp::set_time_has_started_for_testing(framework_signer);
1501
+ chain_id::initialize_for_test(framework_signer, 1);
1502
+ let (burn, mint) = aptos_coin::initialize_for_test(framework_signer);
1503
+ destroy_mint_cap(mint);
1504
+ destroy_burn_cap(burn);
1505
+ }
1506
+
1507
+ #[test_only]
1508
+ fun setup_disabled() {
1509
+ let framework_signer = &create_signer(@0x1);
1510
+ features::change_feature_flags_for_testing(
1511
+ framework_signer, vector[], vector[features::get_multisig_accounts_feature()]);
1512
+ timestamp::set_time_has_started_for_testing(framework_signer);
1513
+ chain_id::initialize_for_test(framework_signer, 1);
1514
+ let (burn, mint) = aptos_coin::initialize_for_test(framework_signer);
1515
+ destroy_mint_cap(mint);
1516
+ destroy_burn_cap(burn);
1517
+ }
1518
+
1519
+ #[test(owner_1 = @0x123, owner_2 = @0x124, owner_3 = @0x125)]
1520
+ public entry fun test_end_to_end(
1521
+ owner_1: &signer, owner_2: &signer, owner_3: &signer) acquires MultisigAccount {
1522
+ setup();
1523
+ let owner_1_addr = address_of(owner_1);
1524
+ let owner_2_addr = address_of(owner_2);
1525
+ let owner_3_addr = address_of(owner_3);
1526
+ create_account(owner_1_addr);
1527
+ let multisig_account = get_next_multisig_account_address(owner_1_addr);
1528
+ create_with_owners(owner_1, vector[owner_2_addr, owner_3_addr], 2, vector[], vector[]);
1529
+
1530
+ // Create three transactions.
1531
+ create_transaction(owner_1, multisig_account, PAYLOAD);
1532
+ create_transaction(owner_2, multisig_account, PAYLOAD);
1533
+ create_transaction_with_hash(owner_3, multisig_account, sha3_256(PAYLOAD));
1534
+ assert!(get_pending_transactions(multisig_account) == vector[
1535
+ get_transaction(multisig_account, 1),
1536
+ get_transaction(multisig_account, 2),
1537
+ get_transaction(multisig_account, 3),
1538
+ ], 0);
1539
+
1540
+ // Owner 3 doesn't need to explicitly approve as they created the transaction.
1541
+ approve_transaction(owner_1, multisig_account, 3);
1542
+ // Third transaction has 2 approvals but cannot be executed out-of-order.
1543
+ assert!(!can_be_executed(multisig_account, 3), 0);
1544
+
1545
+ // Owner 1 doesn't need to explicitly approve as they created the transaction.
1546
+ approve_transaction(owner_2, multisig_account, 1);
1547
+ // First transaction has 2 approvals so it can be executed.
1548
+ assert!(can_be_executed(multisig_account, 1), 1);
1549
+ // First transaction was executed successfully.
1550
+ successful_transaction_execution_cleanup(owner_2_addr, multisig_account, vector[]);
1551
+ assert!(get_pending_transactions(multisig_account) == vector[
1552
+ get_transaction(multisig_account, 2),
1553
+ get_transaction(multisig_account, 3),
1554
+ ], 0);
1555
+
1556
+ reject_transaction(owner_1, multisig_account, 2);
1557
+ reject_transaction(owner_3, multisig_account, 2);
1558
+ // Second transaction has 1 approval (owner 3) and 2 rejections (owners 1 & 2) and thus can be removed.
1559
+ assert!(can_be_rejected(multisig_account, 2), 2);
1560
+ execute_rejected_transaction(owner_1, multisig_account);
1561
+ assert!(get_pending_transactions(multisig_account) == vector[
1562
+ get_transaction(multisig_account, 3),
1563
+ ], 0);
1564
+
1565
+ // Third transaction can be executed now but execution fails.
1566
+ failed_transaction_execution_cleanup(owner_3_addr, multisig_account, PAYLOAD, execution_error());
1567
+ assert!(get_pending_transactions(multisig_account) == vector[], 0);
1568
+ }
1569
+
1570
+ #[test(owner_1 = @0x123, owner_2 = @0x124, owner_3 = @0x125)]
1571
+ public entry fun test_end_to_end_with_implicit_votes(
1572
+ owner_1: &signer, owner_2: &signer, owner_3: &signer) acquires MultisigAccount {
1573
+ setup();
1574
+ let owner_1_addr = address_of(owner_1);
1575
+ let owner_2_addr = address_of(owner_2);
1576
+ let owner_3_addr = address_of(owner_3);
1577
+ create_account(owner_1_addr);
1578
+ let multisig_account = get_next_multisig_account_address(owner_1_addr);
1579
+ create_with_owners(owner_1, vector[owner_2_addr, owner_3_addr], 2, vector[], vector[]);
1580
+
1581
+ // Create three transactions.
1582
+ create_transaction(owner_1, multisig_account, PAYLOAD);
1583
+ create_transaction(owner_2, multisig_account, PAYLOAD);
1584
+ assert!(get_pending_transactions(multisig_account) == vector[
1585
+ get_transaction(multisig_account, 1),
1586
+ get_transaction(multisig_account, 2),
1587
+ ], 0);
1588
+
1589
+ reject_transaction(owner_2, multisig_account, 1);
1590
+ // Owner 2 can execute the transaction, implicitly voting to approve it,
1591
+ // which overrides their previous vote for rejection.
1592
+ assert!(can_execute(owner_2_addr, multisig_account, 1), 1);
1593
+ // First transaction was executed successfully.
1594
+ successful_transaction_execution_cleanup(owner_2_addr, multisig_account,vector[]);
1595
+ assert!(get_pending_transactions(multisig_account) == vector[
1596
+ get_transaction(multisig_account, 2),
1597
+ ], 0);
1598
+
1599
+ reject_transaction(owner_1, multisig_account, 2);
1600
+ // Owner 3 can execute-reject the transaction, implicitly voting to reject it.
1601
+ assert!(can_reject(owner_3_addr, multisig_account, 2), 2);
1602
+ execute_rejected_transaction(owner_3, multisig_account);
1603
+ assert!(get_pending_transactions(multisig_account) == vector[], 0);
1604
+ }
1605
+
1606
+ #[test(owner = @0x123)]
1607
+ public entry fun test_create_with_single_owner(owner: &signer) acquires MultisigAccount {
1608
+ setup();
1609
+ let owner_addr = address_of(owner);
1610
+ create_account(owner_addr);
1611
+ create(owner, 1, vector[], vector[]);
1612
+ let multisig_account = get_next_multisig_account_address(owner_addr);
1613
+ assert_multisig_account_exists(multisig_account);
1614
+ assert!(owners(multisig_account) == vector[owner_addr], 0);
1615
+ }
1616
+
1617
+ #[test(owner_1 = @0x123, owner_2 = @0x124, owner_3 = @0x125)]
1618
+ public entry fun test_create_with_as_many_sigs_required_as_num_owners(
1619
+ owner_1: &signer, owner_2: &signer, owner_3: &signer) acquires MultisigAccount {
1620
+ setup();
1621
+ let owner_1_addr = address_of(owner_1);
1622
+ create_account(owner_1_addr);
1623
+ create_with_owners(owner_1, vector[address_of(owner_2), address_of(owner_3)], 3, vector[], vector[]);
1624
+ let multisig_account = get_next_multisig_account_address(owner_1_addr);
1625
+ assert_multisig_account_exists(multisig_account);
1626
+ }
1627
+
1628
+ #[test(owner = @0x123)]
1629
+ #[expected_failure(abort_code = 0x1000B, location = Self)]
1630
+ public entry fun test_create_with_zero_signatures_required_should_fail(
1631
+ owner: &signer) acquires MultisigAccount {
1632
+ setup();
1633
+ create_account(address_of(owner));
1634
+ create(owner, 0, vector[], vector[]);
1635
+ }
1636
+
1637
+ #[test(owner = @0x123)]
1638
+ #[expected_failure(abort_code = 0x1000B, location = Self)]
1639
+ public entry fun test_create_with_too_many_signatures_required_should_fail(
1640
+ owner: &signer) acquires MultisigAccount {
1641
+ setup();
1642
+ create_account(address_of(owner));
1643
+ create(owner, 2, vector[], vector[]);
1644
+ }
1645
+
1646
+ #[test(owner_1 = @0x123, owner_2 = @0x124, owner_3 = @0x125)]
1647
+ #[expected_failure(abort_code = 0x10001, location = Self)]
1648
+ public entry fun test_create_with_duplicate_owners_should_fail(
1649
+ owner_1: &signer, owner_2: &signer, owner_3: &signer) acquires MultisigAccount {
1650
+ setup();
1651
+ create_account(address_of(owner_1));
1652
+ create_with_owners(
1653
+ owner_1,
1654
+ vector[
1655
+ // Duplicate owner 2 addresses.
1656
+ address_of(owner_2),
1657
+ address_of(owner_3),
1658
+ address_of(owner_2),
1659
+ ],
1660
+ 2,
1661
+ vector[],
1662
+ vector[]);
1663
+ }
1664
+
1665
+ #[test(owner = @0x123)]
1666
+ #[expected_failure(abort_code = 0xD000E, location = Self)]
1667
+ public entry fun test_create_with_without_feature_flag_enabled_should_fail(
1668
+ owner: &signer) acquires MultisigAccount {
1669
+ setup_disabled();
1670
+ create_account(address_of(owner));
1671
+ create(owner, 2, vector[], vector[]);
1672
+ }
1673
+
1674
+ #[test(owner_1 = @0x123, owner_2 = @0x124, owner_3 = @0x125)]
1675
+ #[expected_failure(abort_code = 0x10001, location = Self)]
1676
+ public entry fun test_create_with_creator_in_additional_owners_list_should_fail(
1677
+ owner_1: &signer, owner_2: &signer, owner_3: &signer) acquires MultisigAccount {
1678
+ setup();
1679
+ create_account(address_of(owner_1));
1680
+ create_with_owners(owner_1, vector[
1681
+ // Duplicate owner 1 addresses.
1682
+ address_of(owner_1),
1683
+ address_of(owner_2),
1684
+ address_of(owner_3),
1685
+ ], 2,
1686
+ vector[],
1687
+ vector[],
1688
+ );
1689
+ }
1690
+
1691
+ #[test]
1692
+ public entry fun test_create_multisig_account_on_top_of_existing_multi_ed25519_account()
1693
+ acquires MultisigAccount {
1694
+ setup();
1695
+ let (curr_sk, curr_pk) = multi_ed25519::generate_keys(2, 3);
1696
+ let pk_unvalidated = multi_ed25519::public_key_to_unvalidated(&curr_pk);
1697
+ let auth_key = multi_ed25519::unvalidated_public_key_to_authentication_key(&pk_unvalidated);
1698
+ let multisig_address = from_bcs::to_address(auth_key);
1699
+ create_account(multisig_address);
1700
+
1701
+ let expected_owners = vector[@0x123, @0x124, @0x125];
1702
+ let proof = MultisigAccountCreationMessage {
1703
+ chain_id: chain_id::get(),
1704
+ account_address: multisig_address,
1705
+ sequence_number: account::get_sequence_number(multisig_address),
1706
+ owners: expected_owners,
1707
+ num_signatures_required: 2,
1708
+ };
1709
+ let signed_proof = multi_ed25519::sign_struct(&curr_sk, proof);
1710
+ create_with_existing_account(
1711
+ multisig_address,
1712
+ expected_owners,
1713
+ 2,
1714
+ 1, // MULTI_ED25519_SCHEME
1715
+ multi_ed25519::unvalidated_public_key_to_bytes(&pk_unvalidated),
1716
+ multi_ed25519::signature_to_bytes(&signed_proof),
1717
+ vector[],
1718
+ vector[],
1719
+ );
1720
+ assert_multisig_account_exists(multisig_address);
1721
+ assert!(owners(multisig_address) == expected_owners, 0);
1722
+ }
1723
+
1724
+ #[test]
1725
+ public entry fun test_create_multisig_account_on_top_of_existing_multi_ed25519_account_and_revoke_auth_key()
1726
+ acquires MultisigAccount {
1727
+ setup();
1728
+ let (curr_sk, curr_pk) = multi_ed25519::generate_keys(2, 3);
1729
+ let pk_unvalidated = multi_ed25519::public_key_to_unvalidated(&curr_pk);
1730
+ let auth_key = multi_ed25519::unvalidated_public_key_to_authentication_key(&pk_unvalidated);
1731
+ let multisig_address = from_bcs::to_address(auth_key);
1732
+ create_account(multisig_address);
1733
+
1734
+ // Create both a signer capability and rotation capability offers
1735
+ account::set_rotation_capability_offer(multisig_address, @0x123);
1736
+ account::set_signer_capability_offer(multisig_address, @0x123);
1737
+
1738
+ let expected_owners = vector[@0x123, @0x124, @0x125];
1739
+ let proof = MultisigAccountCreationWithAuthKeyRevocationMessage {
1740
+ chain_id: chain_id::get(),
1741
+ account_address: multisig_address,
1742
+ sequence_number: account::get_sequence_number(multisig_address),
1743
+ owners: expected_owners,
1744
+ num_signatures_required: 2,
1745
+ };
1746
+ let signed_proof = multi_ed25519::sign_struct(&curr_sk, proof);
1747
+ create_with_existing_account_and_revoke_auth_key(
1748
+ multisig_address,
1749
+ expected_owners,
1750
+ 2,
1751
+ 1, // MULTI_ED25519_SCHEME
1752
+ multi_ed25519::unvalidated_public_key_to_bytes(&pk_unvalidated),
1753
+ multi_ed25519::signature_to_bytes(&signed_proof),
1754
+ vector[],
1755
+ vector[],
1756
+ );
1757
+ assert_multisig_account_exists(multisig_address);
1758
+ assert!(owners(multisig_address) == expected_owners, 0);
1759
+ assert!(account::get_authentication_key(multisig_address) == ZERO_AUTH_KEY, 1);
1760
+ // Verify that all capability offers have been wiped.
1761
+ assert!(!account::is_rotation_capability_offered(multisig_address), 2);
1762
+ assert!(!account::is_signer_capability_offered(multisig_address), 3);
1763
+ }
1764
+
1765
+ #[test(owner_1 = @0x123, owner_2 = @0x124, owner_3 = @0x125)]
1766
+ public entry fun test_update_signatures_required(
1767
+ owner_1: &signer, owner_2: &signer, owner_3: &signer) acquires MultisigAccount {
1768
+ setup();
1769
+ let owner_1_addr = address_of(owner_1);
1770
+ create_account(owner_1_addr);
1771
+ create_with_owners(owner_1, vector[address_of(owner_2), address_of(owner_3)], 1, vector[], vector[]);
1772
+ let multisig_account = get_next_multisig_account_address(owner_1_addr);
1773
+ assert!(num_signatures_required(multisig_account) == 1, 0);
1774
+ update_signatures_required(&create_signer(multisig_account), 2);
1775
+ assert!(num_signatures_required(multisig_account) == 2, 1);
1776
+ // As many signatures required as number of owners (3).
1777
+ update_signatures_required(&create_signer(multisig_account), 3);
1778
+ assert!(num_signatures_required(multisig_account) == 3, 2);
1779
+ }
1780
+
1781
+ #[test(owner = @0x123)]
1782
+ public entry fun test_update_metadata(owner: &signer) acquires MultisigAccount {
1783
+ setup();
1784
+ let owner_addr = address_of(owner);
1785
+ create_account(owner_addr);
1786
+ create(owner, 1, vector[], vector[]);
1787
+ let multisig_account = get_next_multisig_account_address(owner_addr);
1788
+ update_metadata(
1789
+ &create_signer(multisig_account),
1790
+ vector[utf8(b"key1"), utf8(b"key2")],
1791
+ vector[vector[1], vector[2]],
1792
+ );
1793
+ let updated_metadata = metadata(multisig_account);
1794
+ assert!(simple_map::length(&updated_metadata) == 2, 0);
1795
+ assert!(simple_map::borrow(&updated_metadata, &utf8(b"key1")) == &vector[1], 0);
1796
+ assert!(simple_map::borrow(&updated_metadata, &utf8(b"key2")) == &vector[2], 0);
1797
+ }
1798
+
1799
+ #[test(owner = @0x123)]
1800
+ #[expected_failure(abort_code = 0x1000B, location = Self)]
1801
+ public entry fun test_update_with_zero_signatures_required_should_fail(
1802
+ owner: & signer) acquires MultisigAccount {
1803
+ setup();
1804
+ create_account(address_of(owner));
1805
+ create(owner, 1, vector[], vector[]);
1806
+ let multisig_account = get_next_multisig_account_address(address_of(owner));
1807
+ update_signatures_required(&create_signer(multisig_account), 0);
1808
+ }
1809
+
1810
+ #[test(owner = @0x123)]
1811
+ #[expected_failure(abort_code = 0x30005, location = Self)]
1812
+ public entry fun test_update_with_too_many_signatures_required_should_fail(
1813
+ owner: &signer) acquires MultisigAccount {
1814
+ setup();
1815
+ create_account(address_of(owner));
1816
+ create(owner, 1, vector[], vector[]);
1817
+ let multisig_account = get_next_multisig_account_address(address_of(owner));
1818
+ update_signatures_required(&create_signer(multisig_account), 2);
1819
+ }
1820
+
1821
+ #[test(owner_1 = @0x123, owner_2 = @0x124, owner_3 = @0x125)]
1822
+ public entry fun test_add_owners(
1823
+ owner_1: &signer, owner_2: &signer, owner_3: &signer) acquires MultisigAccount {
1824
+ setup();
1825
+ create_account(address_of(owner_1));
1826
+ create(owner_1, 1, vector[], vector[]);
1827
+ let owner_1_addr = address_of(owner_1);
1828
+ let owner_2_addr = address_of(owner_2);
1829
+ let owner_3_addr = address_of(owner_3);
1830
+ let multisig_account = get_next_multisig_account_address(owner_1_addr);
1831
+ let multisig_signer = &create_signer(multisig_account);
1832
+ assert!(owners(multisig_account) == vector[owner_1_addr], 0);
1833
+ // Adding an empty vector of new owners should be no-op.
1834
+ add_owners(multisig_signer, vector[]);
1835
+ assert!(owners(multisig_account) == vector[owner_1_addr], 1);
1836
+ add_owners(multisig_signer, vector[owner_2_addr, owner_3_addr]);
1837
+ assert!(owners(multisig_account) == vector[owner_1_addr, owner_2_addr, owner_3_addr], 2);
1838
+ }
1839
+
1840
+ #[test(owner_1 = @0x123, owner_2 = @0x124, owner_3 = @0x125)]
1841
+ public entry fun test_remove_owners(
1842
+ owner_1: &signer, owner_2: &signer, owner_3: &signer) acquires MultisigAccount {
1843
+ setup();
1844
+ let owner_1_addr = address_of(owner_1);
1845
+ let owner_2_addr = address_of(owner_2);
1846
+ let owner_3_addr = address_of(owner_3);
1847
+ create_account(owner_1_addr);
1848
+ create_with_owners(owner_1, vector[owner_2_addr, owner_3_addr], 1, vector[], vector[]);
1849
+ let multisig_account = get_next_multisig_account_address(owner_1_addr);
1850
+ let multisig_signer = &create_signer(multisig_account);
1851
+ assert!(owners(multisig_account) == vector[owner_2_addr, owner_3_addr, owner_1_addr], 0);
1852
+ // Removing an empty vector of owners should be no-op.
1853
+ remove_owners(multisig_signer, vector[]);
1854
+ assert!(owners(multisig_account) == vector[owner_2_addr, owner_3_addr, owner_1_addr], 1);
1855
+ remove_owners(multisig_signer, vector[owner_2_addr]);
1856
+ assert!(owners(multisig_account) == vector[owner_1_addr, owner_3_addr], 2);
1857
+ // Removing owners that don't exist should be no-op.
1858
+ remove_owners(multisig_signer, vector[@0x130]);
1859
+ assert!(owners(multisig_account) == vector[owner_1_addr, owner_3_addr], 3);
1860
+ // Removing with duplicate owners should still work.
1861
+ remove_owners(multisig_signer, vector[owner_3_addr, owner_3_addr, owner_3_addr]);
1862
+ assert!(owners(multisig_account) == vector[owner_1_addr], 4);
1863
+ }
1864
+
1865
+ #[test(owner_1 = @0x123, owner_2 = @0x124, owner_3 = @0x125)]
1866
+ #[expected_failure(abort_code = 0x30005, location = Self)]
1867
+ public entry fun test_remove_all_owners_should_fail(
1868
+ owner_1: &signer, owner_2: &signer, owner_3: &signer) acquires MultisigAccount {
1869
+ setup();
1870
+ let owner_1_addr = address_of(owner_1);
1871
+ let owner_2_addr = address_of(owner_2);
1872
+ let owner_3_addr = address_of(owner_3);
1873
+ create_account(owner_1_addr);
1874
+ create_with_owners(owner_1, vector[owner_2_addr, owner_3_addr], 1, vector[], vector[]);
1875
+ let multisig_account = get_next_multisig_account_address(owner_1_addr);
1876
+ assert!(owners(multisig_account) == vector[owner_2_addr, owner_3_addr, owner_1_addr], 0);
1877
+ let multisig_signer = &create_signer(multisig_account);
1878
+ remove_owners(multisig_signer, vector[owner_1_addr, owner_2_addr, owner_3_addr]);
1879
+ }
1880
+
1881
+ #[test(owner_1 = @0x123, owner_2 = @0x124, owner_3 = @0x125)]
1882
+ #[expected_failure(abort_code = 0x30005, location = Self)]
1883
+ public entry fun test_remove_owners_with_fewer_remaining_than_signature_threshold_should_fail(
1884
+ owner_1: &signer, owner_2: &signer, owner_3: &signer) acquires MultisigAccount {
1885
+ setup();
1886
+ let owner_1_addr = address_of(owner_1);
1887
+ let owner_2_addr = address_of(owner_2);
1888
+ let owner_3_addr = address_of(owner_3);
1889
+ create_account(owner_1_addr);
1890
+ create_with_owners(owner_1, vector[owner_2_addr, owner_3_addr], 2, vector[], vector[]);
1891
+ let multisig_account = get_next_multisig_account_address(owner_1_addr);
1892
+ let multisig_signer = &create_signer(multisig_account);
1893
+ // Remove 2 owners so there's one left, which is less than the signature threshold of 2.
1894
+ remove_owners(multisig_signer, vector[owner_2_addr, owner_3_addr]);
1895
+ }
1896
+
1897
+ #[test(owner_1 = @0x123, owner_2 = @0x124, owner_3 = @0x125)]
1898
+ public entry fun test_create_transaction(
1899
+ owner_1: &signer, owner_2: &signer, owner_3: &signer) acquires MultisigAccount {
1900
+ setup();
1901
+ let owner_1_addr = address_of(owner_1);
1902
+ let owner_2_addr = address_of(owner_2);
1903
+ let owner_3_addr = address_of(owner_3);
1904
+ create_account(owner_1_addr);
1905
+ let multisig_account = get_next_multisig_account_address(owner_1_addr);
1906
+ create_with_owners(owner_1, vector[owner_2_addr, owner_3_addr], 2, vector[], vector[]);
1907
+
1908
+ create_transaction(owner_1, multisig_account, PAYLOAD);
1909
+ let transaction = get_transaction(multisig_account, 1);
1910
+ assert!(transaction.creator == owner_1_addr, 0);
1911
+ assert!(option::is_some(&transaction.payload), 1);
1912
+ assert!(option::is_none(&transaction.payload_hash), 2);
1913
+ let payload = option::extract(&mut transaction.payload);
1914
+ assert!(payload == PAYLOAD, 4);
1915
+ // Automatic yes vote from creator.
1916
+ assert!(simple_map::length(&transaction.votes) == 1, 5);
1917
+ assert!(*simple_map::borrow(&transaction.votes, &owner_1_addr), 5);
1918
+ }
1919
+
1920
+ #[test(owner = @0x123)]
1921
+ #[expected_failure(abort_code = 0x10004, location = Self)]
1922
+ public entry fun test_create_transaction_with_empty_payload_should_fail(
1923
+ owner: &signer) acquires MultisigAccount {
1924
+ setup();
1925
+ create_account(address_of(owner));
1926
+ create(owner, 1, vector[], vector[]);
1927
+ let multisig_account = get_next_multisig_account_address(address_of(owner));
1928
+ create_transaction(owner, multisig_account, vector[]);
1929
+ }
1930
+
1931
+ #[test(owner = @0x123, non_owner = @0x124)]
1932
+ #[expected_failure(abort_code = 0x507D3, location = Self)]
1933
+ public entry fun test_create_transaction_with_non_owner_should_fail(
1934
+ owner: &signer, non_owner: &signer) acquires MultisigAccount {
1935
+ setup();
1936
+ create_account(address_of(owner));
1937
+ create(owner, 1, vector[], vector[]);
1938
+ let multisig_account = get_next_multisig_account_address(address_of(owner));
1939
+ create_transaction(non_owner, multisig_account, PAYLOAD);
1940
+ }
1941
+
1942
+ #[test(owner = @0x123)]
1943
+ public entry fun test_create_transaction_with_hashes(
1944
+ owner: &signer) acquires MultisigAccount {
1945
+ setup();
1946
+ create_account(address_of(owner));
1947
+ create(owner, 1, vector[], vector[]);
1948
+ let multisig_account = get_next_multisig_account_address(address_of(owner));
1949
+ create_transaction_with_hash(owner, multisig_account, sha3_256(PAYLOAD));
1950
+ }
1951
+
1952
+ #[test(owner = @0x123)]
1953
+ #[expected_failure(abort_code = 0x1000C, location = Self)]
1954
+ public entry fun test_create_transaction_with_empty_hash_should_fail(
1955
+ owner: &signer) acquires MultisigAccount {
1956
+ setup();
1957
+ create_account(address_of(owner));
1958
+ create(owner, 1, vector[], vector[]);
1959
+ let multisig_account = get_next_multisig_account_address(address_of(owner));
1960
+ create_transaction_with_hash(owner, multisig_account, vector[]);
1961
+ }
1962
+
1963
+ #[test(owner = @0x123, non_owner = @0x124)]
1964
+ #[expected_failure(abort_code = 0x507D3, location = Self)]
1965
+ public entry fun test_create_transaction_with_hashes_and_non_owner_should_fail(
1966
+ owner: &signer, non_owner: &signer) acquires MultisigAccount {
1967
+ setup();
1968
+ create_account(address_of(owner));
1969
+ create(owner, 1, vector[], vector[]);
1970
+ let multisig_account = get_next_multisig_account_address(address_of(owner));
1971
+ create_transaction_with_hash(non_owner, multisig_account, sha3_256(PAYLOAD));
1972
+ }
1973
+
1974
+ #[test(owner_1 = @0x123, owner_2 = @0x124, owner_3 = @0x125)]
1975
+ public entry fun test_approve_transaction(
1976
+ owner_1: &signer, owner_2: &signer, owner_3: &signer) acquires MultisigAccount {
1977
+ setup();
1978
+ let owner_1_addr = address_of(owner_1);
1979
+ let owner_2_addr = address_of(owner_2);
1980
+ let owner_3_addr = address_of(owner_3);
1981
+ create_account(owner_1_addr);
1982
+ let multisig_account = get_next_multisig_account_address(owner_1_addr);
1983
+ create_with_owners(owner_1, vector[owner_2_addr, owner_3_addr], 2, vector[], vector[]);
1984
+
1985
+ create_transaction(owner_1, multisig_account, PAYLOAD);
1986
+ approve_transaction(owner_2, multisig_account, 1);
1987
+ approve_transaction(owner_3, multisig_account, 1);
1988
+ let transaction = get_transaction(multisig_account, 1);
1989
+ assert!(simple_map::length(&transaction.votes) == 3, 0);
1990
+ assert!(*simple_map::borrow(&transaction.votes, &owner_1_addr), 1);
1991
+ assert!(*simple_map::borrow(&transaction.votes, &owner_2_addr), 2);
1992
+ assert!(*simple_map::borrow(&transaction.votes, &owner_3_addr), 3);
1993
+ }
1994
+
1995
+ #[test(owner_1 = @0x123, owner_2 = @0x124, owner_3 = @0x125)]
1996
+ public entry fun test_validate_transaction_should_not_consider_removed_owners(
1997
+ owner_1: &signer, owner_2: &signer, owner_3: & signer) acquires MultisigAccount {
1998
+ setup();
1999
+ let owner_1_addr = address_of(owner_1);
2000
+ let owner_2_addr = address_of(owner_2);
2001
+ let owner_3_addr = address_of(owner_3);
2002
+ create_account(owner_1_addr);
2003
+ let multisig_account = get_next_multisig_account_address(owner_1_addr);
2004
+ create_with_owners(owner_1, vector[owner_2_addr, owner_3_addr], 2, vector[], vector[]);
2005
+
2006
+ // Owner 1 and 2 approved but then owner 1 got removed.
2007
+ create_transaction(owner_1, multisig_account, PAYLOAD);
2008
+ approve_transaction(owner_2, multisig_account, 1);
2009
+ // Before owner 1 is removed, the transaction technically has sufficient approvals.
2010
+ assert!(can_be_executed(multisig_account, 1), 0);
2011
+ let multisig_signer = &create_signer(multisig_account);
2012
+ remove_owners(multisig_signer, vector[owner_1_addr]);
2013
+ // Now that owner 1 is removed, their approval should be invalidated and the transaction no longer
2014
+ // has enough approvals to be executed.
2015
+ assert!(!can_be_executed(multisig_account, 1), 1);
2016
+ }
2017
+
2018
+ #[test(owner = @0x123)]
2019
+ #[expected_failure(abort_code = 0x607D6, location = Self)]
2020
+ public entry fun test_approve_transaction_with_invalid_sequence_number_should_fail(
2021
+ owner: &signer) acquires MultisigAccount {
2022
+ setup();
2023
+ create_account(address_of(owner));
2024
+ let multisig_account = get_next_multisig_account_address(address_of(owner));
2025
+ create(owner, 1, vector[], vector[]);
2026
+ // Transaction is created with id 1.
2027
+ create_transaction(owner, multisig_account, PAYLOAD);
2028
+ approve_transaction(owner, multisig_account, 2);
2029
+ }
2030
+
2031
+ #[test(owner = @0x123, non_owner = @0x124)]
2032
+ #[expected_failure(abort_code = 0x507D3, location = Self)]
2033
+ public entry fun test_approve_transaction_with_non_owner_should_fail(
2034
+ owner: &signer, non_owner: &signer) acquires MultisigAccount {
2035
+ setup();
2036
+ create_account(address_of(owner));
2037
+ let multisig_account = get_next_multisig_account_address(address_of(owner));
2038
+ create(owner, 1, vector[], vector[]);
2039
+ // Transaction is created with id 1.
2040
+ create_transaction(owner, multisig_account, PAYLOAD);
2041
+ approve_transaction(non_owner, multisig_account, 1);
2042
+ }
2043
+
2044
+ #[test(owner = @0x123)]
2045
+ public entry fun test_approval_transaction_after_rejecting(
2046
+ owner: &signer) acquires MultisigAccount {
2047
+ setup();
2048
+ let owner_addr = address_of(owner);
2049
+ create_account(owner_addr);
2050
+ let multisig_account = get_next_multisig_account_address(owner_addr);
2051
+ create(owner, 1, vector[], vector[]);
2052
+
2053
+ create_transaction(owner, multisig_account, PAYLOAD);
2054
+ reject_transaction(owner, multisig_account, 1);
2055
+ approve_transaction(owner, multisig_account, 1);
2056
+ let transaction = get_transaction(multisig_account, 1);
2057
+ assert!(*simple_map::borrow(&transaction.votes, &owner_addr), 1);
2058
+ }
2059
+
2060
+ #[test(owner_1 = @0x123, owner_2 = @0x124, owner_3 = @0x125)]
2061
+ public entry fun test_reject_transaction(
2062
+ owner_1: &signer, owner_2: &signer, owner_3: &signer) acquires MultisigAccount {
2063
+ setup();
2064
+ let owner_1_addr = address_of(owner_1);
2065
+ let owner_2_addr = address_of(owner_2);
2066
+ let owner_3_addr = address_of(owner_3);
2067
+ create_account(owner_1_addr);
2068
+ let multisig_account = get_next_multisig_account_address(owner_1_addr);
2069
+ create_with_owners(owner_1, vector[owner_2_addr, owner_3_addr], 2, vector[], vector[]);
2070
+
2071
+ create_transaction(owner_1, multisig_account, PAYLOAD);
2072
+ reject_transaction(owner_1, multisig_account, 1);
2073
+ reject_transaction(owner_2, multisig_account, 1);
2074
+ reject_transaction(owner_3, multisig_account, 1);
2075
+ let transaction = get_transaction(multisig_account, 1);
2076
+ assert!(simple_map::length(&transaction.votes) == 3, 0);
2077
+ assert!(!*simple_map::borrow(&transaction.votes, &owner_1_addr), 1);
2078
+ assert!(!*simple_map::borrow(&transaction.votes, &owner_2_addr), 2);
2079
+ assert!(!*simple_map::borrow(&transaction.votes, &owner_3_addr), 3);
2080
+ }
2081
+
2082
+ #[test(owner = @0x123)]
2083
+ public entry fun test_reject_transaction_after_approving(
2084
+ owner: &signer) acquires MultisigAccount {
2085
+ setup();
2086
+ let owner_addr = address_of(owner);
2087
+ create_account(owner_addr);
2088
+ let multisig_account = get_next_multisig_account_address(owner_addr);
2089
+ create(owner, 1, vector[], vector[]);
2090
+
2091
+ create_transaction(owner, multisig_account, PAYLOAD);
2092
+ reject_transaction(owner, multisig_account, 1);
2093
+ let transaction = get_transaction(multisig_account, 1);
2094
+ assert!(!*simple_map::borrow(&transaction.votes, &owner_addr), 1);
2095
+ }
2096
+
2097
+ #[test(owner = @0x123)]
2098
+ #[expected_failure(abort_code = 0x607D6, location = Self)]
2099
+ public entry fun test_reject_transaction_with_invalid_sequence_number_should_fail(
2100
+ owner: &signer) acquires MultisigAccount {
2101
+ setup();
2102
+ create_account(address_of(owner));
2103
+ let multisig_account = get_next_multisig_account_address(address_of(owner));
2104
+ create(owner, 1, vector[], vector[]);
2105
+ // Transaction is created with id 1.
2106
+ create_transaction(owner, multisig_account, PAYLOAD);
2107
+ reject_transaction(owner, multisig_account, 2);
2108
+ }
2109
+
2110
+ #[test(owner = @0x123, non_owner = @0x124)]
2111
+ #[expected_failure(abort_code = 0x507D3, location = Self)]
2112
+ public entry fun test_reject_transaction_with_non_owner_should_fail(
2113
+ owner: &signer, non_owner: &signer) acquires MultisigAccount {
2114
+ setup();
2115
+ create_account(address_of(owner));
2116
+ let multisig_account = get_next_multisig_account_address(address_of(owner));
2117
+ create(owner, 1, vector[], vector[]);
2118
+ reject_transaction(non_owner, multisig_account, 1);
2119
+ }
2120
+
2121
+ #[test(owner_1 = @0x123, owner_2 = @0x124, owner_3 = @0x125)]
2122
+ public entry fun test_execute_transaction_successful(
2123
+ owner_1: &signer, owner_2: &signer, owner_3: &signer) acquires MultisigAccount {
2124
+ setup();
2125
+ let owner_1_addr = address_of(owner_1);
2126
+ let owner_2_addr = address_of(owner_2);
2127
+ let owner_3_addr = address_of(owner_3);
2128
+ create_account(owner_1_addr);
2129
+ let multisig_account = get_next_multisig_account_address(owner_1_addr);
2130
+ create_with_owners(owner_1, vector[owner_2_addr, owner_3_addr], 2, vector[], vector[]);
2131
+
2132
+ create_transaction(owner_1, multisig_account, PAYLOAD);
2133
+ // Owner 1 doesn't need to explicitly approve as they created the transaction.
2134
+ approve_transaction(owner_2, multisig_account, 1);
2135
+ assert!(can_be_executed(multisig_account, 1), 1);
2136
+ assert!(table::contains(&borrow_global<MultisigAccount>(multisig_account).transactions, 1), 0);
2137
+ successful_transaction_execution_cleanup(owner_3_addr, multisig_account, vector[]);
2138
+ }
2139
+
2140
+ #[test(owner_1 = @0x123, owner_2 = @0x124, owner_3 = @0x125)]
2141
+ public entry fun test_execute_transaction_failed(
2142
+ owner_1: &signer, owner_2: &signer, owner_3: &signer) acquires MultisigAccount {
2143
+ setup();
2144
+ let owner_1_addr = address_of(owner_1);
2145
+ let owner_2_addr = address_of(owner_2);
2146
+ let owner_3_addr = address_of(owner_3);
2147
+ create_account(owner_1_addr);
2148
+ let multisig_account = get_next_multisig_account_address(owner_1_addr);
2149
+ create_with_owners(owner_1, vector[owner_2_addr, owner_3_addr], 2, vector[], vector[]);
2150
+
2151
+ create_transaction(owner_1, multisig_account, PAYLOAD);
2152
+ // Owner 1 doesn't need to explicitly approve as they created the transaction.
2153
+ approve_transaction(owner_2, multisig_account, 1);
2154
+ assert!(can_be_executed(multisig_account, 1), 1);
2155
+ assert!(table::contains(&borrow_global<MultisigAccount>(multisig_account).transactions, 1), 0);
2156
+ failed_transaction_execution_cleanup(owner_3_addr, multisig_account, vector[], execution_error());
2157
+ }
2158
+
2159
+ #[test(owner_1 = @0x123, owner_2 = @0x124, owner_3 = @0x125)]
2160
+ public entry fun test_execute_transaction_with_full_payload(
2161
+ owner_1: &signer, owner_2: &signer, owner_3: &signer) acquires MultisigAccount {
2162
+ setup();
2163
+ let owner_1_addr = address_of(owner_1);
2164
+ let owner_2_addr = address_of(owner_2);
2165
+ let owner_3_addr = address_of(owner_3);
2166
+ create_account(owner_1_addr);
2167
+ let multisig_account = get_next_multisig_account_address(owner_1_addr);
2168
+ create_with_owners(owner_1, vector[owner_2_addr, owner_3_addr], 2, vector[], vector[]);
2169
+
2170
+ create_transaction_with_hash(owner_3, multisig_account, sha3_256(PAYLOAD));
2171
+ // Owner 3 doesn't need to explicitly approve as they created the transaction.
2172
+ approve_transaction(owner_1, multisig_account, 1);
2173
+ assert!(can_be_executed(multisig_account, 1), 1);
2174
+ assert!(table::contains(&borrow_global<MultisigAccount>(multisig_account).transactions, 1), 0);
2175
+ successful_transaction_execution_cleanup(owner_3_addr, multisig_account, PAYLOAD);
2176
+ }
2177
+
2178
+ #[test(owner_1 = @0x123, owner_2 = @0x124, owner_3 = @0x125)]
2179
+ public entry fun test_execute_rejected_transaction(
2180
+ owner_1: &signer, owner_2: &signer, owner_3: &signer) acquires MultisigAccount {
2181
+ setup();
2182
+ let owner_1_addr = address_of(owner_1);
2183
+ let owner_2_addr = address_of(owner_2);
2184
+ let owner_3_addr = address_of(owner_3);
2185
+ create_account(owner_1_addr);
2186
+ let multisig_account = get_next_multisig_account_address(owner_1_addr);
2187
+ create_with_owners(owner_1, vector[owner_2_addr, owner_3_addr], 2, vector[], vector[]);
2188
+
2189
+ create_transaction(owner_1, multisig_account, PAYLOAD);
2190
+ reject_transaction(owner_2, multisig_account, 1);
2191
+ reject_transaction(owner_3, multisig_account, 1);
2192
+ assert!(can_be_rejected(multisig_account, 1), 1);
2193
+ assert!(table::contains(&borrow_global<MultisigAccount>(multisig_account).transactions, 1), 0);
2194
+ execute_rejected_transaction(owner_3, multisig_account);
2195
+ }
2196
+
2197
+ #[test(owner = @0x123, non_owner = @0x124)]
2198
+ #[expected_failure(abort_code = 0x507D3, location = Self)]
2199
+ public entry fun test_execute_rejected_transaction_with_non_owner_should_fail(
2200
+ owner: &signer, non_owner: &signer) acquires MultisigAccount {
2201
+ setup();
2202
+ create_account(address_of(owner));
2203
+ let multisig_account = get_next_multisig_account_address(address_of(owner));
2204
+ create(owner, 1, vector[], vector[]);
2205
+
2206
+ create_transaction(owner, multisig_account, PAYLOAD);
2207
+ reject_transaction(owner, multisig_account, 1);
2208
+ execute_rejected_transaction(non_owner, multisig_account);
2209
+ }
2210
+
2211
+ #[test(owner_1 = @0x123, owner_2 = @0x124, owner_3 = @0x125)]
2212
+ #[expected_failure(abort_code = 0x3000A, location = Self)]
2213
+ public entry fun test_execute_rejected_transaction_without_sufficient_rejections_should_fail(
2214
+ owner_1: &signer, owner_2: &signer, owner_3: &signer) acquires MultisigAccount {
2215
+ setup();
2216
+ let owner_1_addr = address_of(owner_1);
2217
+ let owner_2_addr = address_of(owner_2);
2218
+ let owner_3_addr = address_of(owner_3);
2219
+ create_account(owner_1_addr);
2220
+ let multisig_account = get_next_multisig_account_address(owner_1_addr);
2221
+ create_with_owners(owner_1, vector[owner_2_addr, owner_3_addr], 2, vector[], vector[]);
2222
+
2223
+ create_transaction(owner_1, multisig_account, PAYLOAD);
2224
+ approve_transaction(owner_2, multisig_account, 1);
2225
+ execute_rejected_transaction(owner_3, multisig_account);
2226
+ }
2227
+
2228
+ #[test(
2229
+ owner_1 = @0x123,
2230
+ owner_2 = @0x124,
2231
+ owner_3 = @0x125
2232
+ )]
2233
+ #[expected_failure(abort_code = 0x10012, location = Self)]
2234
+ fun test_update_owner_schema_overlap_should_fail(
2235
+ owner_1: &signer,
2236
+ owner_2: &signer,
2237
+ owner_3: &signer
2238
+ ) acquires MultisigAccount {
2239
+ setup();
2240
+ let owner_1_addr = address_of(owner_1);
2241
+ let owner_2_addr = address_of(owner_2);
2242
+ let owner_3_addr = address_of(owner_3);
2243
+ create_account(owner_1_addr);
2244
+ let multisig_address = get_next_multisig_account_address(owner_1_addr);
2245
+ create_with_owners(
2246
+ owner_1,
2247
+ vector[owner_2_addr, owner_3_addr],
2248
+ 2,
2249
+ vector[],
2250
+ vector[]
2251
+ );
2252
+ update_owner_schema(
2253
+ multisig_address,
2254
+ vector[owner_1_addr],
2255
+ vector[owner_1_addr],
2256
+ option::none()
2257
+ );
2258
+ }
2259
+
2260
+ #[test(owner_1 = @0x123, owner_2 = @0x124, owner_3 = @0x125)]
2261
+ #[expected_failure(abort_code = 196627, location = Self)]
2262
+ fun test_max_pending_transaction_limit_should_fail(
2263
+ owner_1: &signer,
2264
+ owner_2: &signer,
2265
+ owner_3: &signer
2266
+ ) acquires MultisigAccount {
2267
+ setup();
2268
+ let owner_1_addr = address_of(owner_1);
2269
+ let owner_2_addr = address_of(owner_2);
2270
+ let owner_3_addr = address_of(owner_3);
2271
+ create_account(owner_1_addr);
2272
+ let multisig_address = get_next_multisig_account_address(owner_1_addr);
2273
+ create_with_owners(
2274
+ owner_1,
2275
+ vector[owner_2_addr, owner_3_addr],
2276
+ 2,
2277
+ vector[],
2278
+ vector[]
2279
+ );
2280
+
2281
+ let remaining_iterations = MAX_PENDING_TRANSACTIONS + 1;
2282
+ while (remaining_iterations > 0) {
2283
+ create_transaction(owner_1, multisig_address, PAYLOAD);
2284
+ remaining_iterations = remaining_iterations - 1;
2285
+ }
2286
+ }
2287
+
2288
+ #[test_only]
2289
+ fun create_transaction_with_eviction(
2290
+ owner: &signer,
2291
+ multisig_account: address,
2292
+ payload: vector<u8>,
2293
+ ) acquires MultisigAccount {
2294
+ while(available_transaction_queue_capacity(multisig_account) == 0) {
2295
+ execute_rejected_transaction(owner, multisig_account)
2296
+ };
2297
+ create_transaction(owner, multisig_account, payload);
2298
+ }
2299
+
2300
+ #[test_only]
2301
+ fun vote_all_transactions(
2302
+ owner: &signer, multisig_account: address, approved: bool) acquires MultisigAccount {
2303
+ let starting_sequence_number = last_resolved_sequence_number(multisig_account) + 1;
2304
+ let final_sequence_number = next_sequence_number(multisig_account) - 1;
2305
+ vote_transactions(owner, multisig_account, starting_sequence_number, final_sequence_number, approved);
2306
+ }
2307
+
2308
+ #[test(owner_1 = @0x123, owner_2 = @0x124, owner_3 = @0x125)]
2309
+ fun test_dos_mitigation_end_to_end(
2310
+ owner_1: &signer,
2311
+ owner_2: &signer,
2312
+ owner_3: &signer
2313
+ ) acquires MultisigAccount {
2314
+ setup();
2315
+ let owner_1_addr = address_of(owner_1);
2316
+ let owner_2_addr = address_of(owner_2);
2317
+ let owner_3_addr = address_of(owner_3);
2318
+ create_account(owner_1_addr);
2319
+ let multisig_address = get_next_multisig_account_address(owner_1_addr);
2320
+ create_with_owners(
2321
+ owner_1,
2322
+ vector[owner_2_addr, owner_3_addr],
2323
+ 2,
2324
+ vector[],
2325
+ vector[]
2326
+ );
2327
+
2328
+ // owner_3 is compromised and creates a bunch of bogus transactions.
2329
+ let remaining_iterations = MAX_PENDING_TRANSACTIONS;
2330
+ while (remaining_iterations > 0) {
2331
+ create_transaction(owner_3, multisig_address, PAYLOAD);
2332
+ remaining_iterations = remaining_iterations - 1;
2333
+ };
2334
+
2335
+ // No one can create a transaction anymore because the transaction queue is full.
2336
+ assert!(available_transaction_queue_capacity(multisig_address) == 0, 0);
2337
+
2338
+ // owner_1 and owner_2 vote "no" on all transactions.
2339
+ vote_all_transactions(owner_1, multisig_address, false);
2340
+ vote_all_transactions(owner_2, multisig_address, false);
2341
+
2342
+ // owner_1 evicts a transaction and creates a transaction to remove the compromised owner.
2343
+ // Note that `PAYLOAD` is a placeholder and is not actually executed in this unit test.
2344
+ create_transaction_with_eviction(owner_1, multisig_address, PAYLOAD);
2345
+
2346
+ // owner_2 approves the eviction transaction.
2347
+ approve_transaction(owner_2, multisig_address, 11);
2348
+
2349
+ // owner_1 flushes the transaction queue except for the eviction transaction.
2350
+ execute_rejected_transactions(owner_1, multisig_address, 10);
2351
+
2352
+ // execute the eviction transaction to remove the compromised owner.
2353
+ assert!(can_be_executed(multisig_address, 11), 0);
2354
+ }
2355
+
2356
+ #[test(owner = @0x123, non_owner = @0x234)]
2357
+ #[expected_failure(abort_code = 329683, location = Self)]
2358
+ public entry fun test_create_transaction_should_fail_if_not_owner(
2359
+ owner: &signer,
2360
+ non_owner: &signer
2361
+ ) acquires MultisigAccount {
2362
+ setup();
2363
+ create_account(address_of(owner));
2364
+ let multisig_account = get_next_multisig_account_address(address_of(owner));
2365
+ create(owner, 1, vector[], vector[]);
2366
+ // Transaction is created with id 1.
2367
+ create_transaction(non_owner, multisig_account, PAYLOAD);
2368
+ }
2369
+
2370
+ #[test(owner = @0x123, non_owner = @0x234)]
2371
+ #[expected_failure(abort_code = 329683, location = Self)]
2372
+ public entry fun test_create_transaction_with_hash_should_fail_if_not_owner(
2373
+ owner: &signer,
2374
+ non_owner: &signer
2375
+ ) acquires MultisigAccount {
2376
+ setup();
2377
+ create_account(address_of(owner));
2378
+ let multisig_account = get_next_multisig_account_address(address_of(owner));
2379
+ create(owner, 1, vector[], vector[]);
2380
+ // Transaction is created with id 1.
2381
+ create_transaction_with_hash(non_owner, multisig_account, sha3_256(PAYLOAD));
2382
+ }
2383
+
2384
+ #[test(owner = @0x123, non_owner = @0x234)]
2385
+ #[expected_failure(abort_code = 329683, location = Self)]
2386
+ public entry fun test_reject_transaction_should_fail_if_not_owner(
2387
+ owner: &signer,
2388
+ non_owner: &signer
2389
+ ) acquires MultisigAccount {
2390
+ setup();
2391
+ create_account(address_of(owner));
2392
+ let multisig_account = get_next_multisig_account_address(address_of(owner));
2393
+ create(owner, 1, vector[], vector[]);
2394
+ // Transaction is created with id 1.
2395
+ create_transaction(owner, multisig_account, PAYLOAD);
2396
+ reject_transaction(non_owner, multisig_account, 1);
2397
+ }
2398
+
2399
+
2400
+ #[test(owner = @0x123, non_owner = @0x234)]
2401
+ #[expected_failure(abort_code = 329683, location = Self)]
2402
+ public entry fun test_approve_transaction_should_fail_if_not_owner(
2403
+ owner: &signer,
2404
+ non_owner: &signer
2405
+ ) acquires MultisigAccount {
2406
+ setup();
2407
+ create_account(address_of(owner));
2408
+ let multisig_account = get_next_multisig_account_address(address_of(owner));
2409
+ create(owner, 1, vector[], vector[]);
2410
+ // Transaction is created with id 1.
2411
+ create_transaction(owner, multisig_account, PAYLOAD);
2412
+ approve_transaction(non_owner, multisig_account, 1);
2413
+ }
2414
+
2415
+ #[test(owner = @0x123, non_owner = @0x234)]
2416
+ #[expected_failure(abort_code = 329683, location = Self)]
2417
+ public entry fun test_vote_transaction_should_fail_if_not_owner(
2418
+ owner: &signer,
2419
+ non_owner: &signer
2420
+ ) acquires MultisigAccount {
2421
+ setup();
2422
+ create_account(address_of(owner));
2423
+ let multisig_account = get_next_multisig_account_address(address_of(owner));
2424
+ create(owner, 1, vector[], vector[]);
2425
+ // Transaction is created with id 1.
2426
+ create_transaction(owner, multisig_account, PAYLOAD);
2427
+ vote_transaction(non_owner, multisig_account, 1, true);
2428
+ }
2429
+
2430
+ #[test(owner = @0x123, non_owner = @0x234)]
2431
+ #[expected_failure(abort_code = 329683, location = Self)]
2432
+ public entry fun test_vote_transactions_should_fail_if_not_owner(
2433
+ owner: &signer,
2434
+ non_owner: &signer
2435
+ ) acquires MultisigAccount {
2436
+ setup();
2437
+ create_account(address_of(owner));
2438
+ let multisig_account = get_next_multisig_account_address(address_of(owner));
2439
+ create(owner, 1, vector[], vector[]);
2440
+ // Transaction is created with id 1.
2441
+ create_transaction(owner, multisig_account, PAYLOAD);
2442
+ vote_transactions(non_owner, multisig_account, 1, 1, true);
2443
+ }
2444
+
2445
+ #[test(owner = @0x123, non_owner = @0x234)]
2446
+ #[expected_failure(abort_code = 329683, location = Self)]
2447
+ public entry fun test_execute_rejected_transaction_should_fail_if_not_owner(
2448
+ owner: &signer,
2449
+ non_owner: &signer
2450
+ ) acquires MultisigAccount {
2451
+ setup();
2452
+ create_account(address_of(owner));
2453
+ let multisig_account = get_next_multisig_account_address(address_of(owner));
2454
+ create(owner, 1, vector[], vector[]);
2455
+ // Transaction is created with id 1.
2456
+ create_transaction(owner, multisig_account, PAYLOAD);
2457
+ reject_transaction(owner, multisig_account, 1);
2458
+ execute_rejected_transaction(non_owner, multisig_account);
2459
+ }
2460
+
2461
+
2462
+ #[test(owner = @0x123, non_owner = @0x234)]
2463
+ #[expected_failure(abort_code = 329683, location = Self)]
2464
+ public entry fun test_execute_rejected_transactions_should_fail_if_not_owner(
2465
+ owner: &signer,
2466
+ non_owner: &signer
2467
+ ) acquires MultisigAccount {
2468
+ setup();
2469
+ create_account(address_of(owner));
2470
+ let multisig_account = get_next_multisig_account_address(address_of(owner));
2471
+ create(owner, 1, vector[], vector[]);
2472
+ // Transaction is created with id 1.
2473
+ create_transaction(owner, multisig_account, PAYLOAD);
2474
+ reject_transaction(owner, multisig_account, 1);
2475
+ execute_rejected_transactions(non_owner, multisig_account, 1);
2476
+ }
2477
+ }