chia-blockchain 2.5.6rc2__py3-none-any.whl → 2.5.7rc2__py3-none-any.whl

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 (371) hide show
  1. chia/_tests/blockchain/blockchain_test_utils.py +6 -7
  2. chia/_tests/blockchain/test_augmented_chain.py +4 -3
  3. chia/_tests/blockchain/test_blockchain.py +10 -5
  4. chia/_tests/clvm/coin_store.py +1 -1
  5. chia/_tests/cmds/cmd_test_utils.py +84 -97
  6. chia/_tests/cmds/test_dev_gh.py +1 -1
  7. chia/_tests/cmds/test_farm_cmd.py +56 -2
  8. chia/_tests/cmds/wallet/test_consts.py +3 -1
  9. chia/_tests/cmds/wallet/test_did.py +3 -8
  10. chia/_tests/cmds/wallet/test_nft.py +6 -6
  11. chia/_tests/cmds/wallet/test_notifications.py +39 -21
  12. chia/_tests/cmds/wallet/test_vcs.py +2 -1
  13. chia/_tests/cmds/wallet/test_wallet.py +160 -136
  14. chia/_tests/conftest.py +51 -26
  15. chia/_tests/core/cmds/test_wallet.py +4 -3
  16. chia/_tests/core/consensus/test_pot_iterations.py +71 -24
  17. chia/_tests/core/custom_types/test_proof_of_space.py +60 -30
  18. chia/_tests/core/custom_types/test_spend_bundle.py +1 -4
  19. chia/_tests/core/data_layer/conftest.py +7 -2
  20. chia/_tests/core/data_layer/old_format/__init__.py +0 -0
  21. chia/_tests/core/data_layer/old_format/files/2e2e2e2e2e2e2e2e2e2e2e2e2e2e2e2e2e2e2e2e2e2e612073746f7265206964-005876c1cdc4d5f1726551b207b9f63efc9cd2f72df80a3a26a1ba73d40d6745-delta-23-v1.0.dat +0 -0
  22. chia/_tests/core/data_layer/old_format/files/2e2e2e2e2e2e2e2e2e2e2e2e2e2e2e2e2e2e2e2e2e2e612073746f7265206964-005876c1cdc4d5f1726551b207b9f63efc9cd2f72df80a3a26a1ba73d40d6745-full-23-v1.0.dat +0 -0
  23. chia/_tests/core/data_layer/old_format/files/2e2e2e2e2e2e2e2e2e2e2e2e2e2e2e2e2e2e2e2e2e2e612073746f7265206964-01b36e72a975cdc00d6514eea81668d19e8ea3150217ae98cb3361688a016fab-delta-9-v1.0.dat +0 -0
  24. chia/_tests/core/data_layer/old_format/files/2e2e2e2e2e2e2e2e2e2e2e2e2e2e2e2e2e2e2e2e2e2e612073746f7265206964-01b36e72a975cdc00d6514eea81668d19e8ea3150217ae98cb3361688a016fab-full-9-v1.0.dat +0 -0
  25. chia/_tests/core/data_layer/old_format/files/2e2e2e2e2e2e2e2e2e2e2e2e2e2e2e2e2e2e2e2e2e2e612073746f7265206964-06147c3b12d73e9b83b686a8c10b4a36a513c8a93c0ff99ae197f06326278be9-delta-5-v1.0.dat +0 -0
  26. chia/_tests/core/data_layer/old_format/files/2e2e2e2e2e2e2e2e2e2e2e2e2e2e2e2e2e2e2e2e2e2e612073746f7265206964-06147c3b12d73e9b83b686a8c10b4a36a513c8a93c0ff99ae197f06326278be9-full-5-v1.0.dat +0 -0
  27. chia/_tests/core/data_layer/old_format/files/2e2e2e2e2e2e2e2e2e2e2e2e2e2e2e2e2e2e2e2e2e2e612073746f7265206964-073c051a5934ad3b8db39eee2189e4300e55f48aaa17ff4ae30eeae088ff544a-delta-22-v1.0.dat +0 -0
  28. chia/_tests/core/data_layer/old_format/files/2e2e2e2e2e2e2e2e2e2e2e2e2e2e2e2e2e2e2e2e2e2e612073746f7265206964-073c051a5934ad3b8db39eee2189e4300e55f48aaa17ff4ae30eeae088ff544a-full-22-v1.0.dat +0 -0
  29. chia/_tests/core/data_layer/old_format/files/2e2e2e2e2e2e2e2e2e2e2e2e2e2e2e2e2e2e2e2e2e2e612073746f7265206964-0cc077559b9c7b4aefe8f8f591c195e0779bebdf89f2ad8285a00ea5f859d965-delta-1-v1.0.dat +0 -0
  30. chia/_tests/core/data_layer/old_format/files/2e2e2e2e2e2e2e2e2e2e2e2e2e2e2e2e2e2e2e2e2e2e612073746f7265206964-0cc077559b9c7b4aefe8f8f591c195e0779bebdf89f2ad8285a00ea5f859d965-full-1-v1.0.dat +0 -0
  31. chia/_tests/core/data_layer/old_format/files/2e2e2e2e2e2e2e2e2e2e2e2e2e2e2e2e2e2e2e2e2e2e612073746f7265206964-16377275567b723b20936d3f1ec0a2fd83f6ac379b922351a5e4c54949069f3b-delta-2-v1.0.dat +0 -0
  32. chia/_tests/core/data_layer/old_format/files/2e2e2e2e2e2e2e2e2e2e2e2e2e2e2e2e2e2e2e2e2e2e612073746f7265206964-16377275567b723b20936d3f1ec0a2fd83f6ac379b922351a5e4c54949069f3b-full-2-v1.0.dat +0 -0
  33. chia/_tests/core/data_layer/old_format/files/2e2e2e2e2e2e2e2e2e2e2e2e2e2e2e2e2e2e2e2e2e2e612073746f7265206964-1cb824a7a5f02cd30ac6c38e8f6216780d9bfa2d24811d282a368dcd541438a7-delta-29-v1.0.dat +0 -0
  34. chia/_tests/core/data_layer/old_format/files/2e2e2e2e2e2e2e2e2e2e2e2e2e2e2e2e2e2e2e2e2e2e612073746f7265206964-1cb824a7a5f02cd30ac6c38e8f6216780d9bfa2d24811d282a368dcd541438a7-full-29-v1.0.dat +0 -0
  35. chia/_tests/core/data_layer/old_format/files/2e2e2e2e2e2e2e2e2e2e2e2e2e2e2e2e2e2e2e2e2e2e612073746f7265206964-27b89dc4809ebc5a3b87757d35e95e2761d978cf121e44fa2773a5c06e4cc7b5-delta-28-v1.0.dat +0 -0
  36. chia/_tests/core/data_layer/old_format/files/2e2e2e2e2e2e2e2e2e2e2e2e2e2e2e2e2e2e2e2e2e2e612073746f7265206964-27b89dc4809ebc5a3b87757d35e95e2761d978cf121e44fa2773a5c06e4cc7b5-full-28-v1.0.dat +0 -0
  37. chia/_tests/core/data_layer/old_format/files/2e2e2e2e2e2e2e2e2e2e2e2e2e2e2e2e2e2e2e2e2e2e612073746f7265206964-28a6b7c134abfaeb0ab58a018313f6c87a61a40a4d9ec9bedf53aa1d12f3ee37-delta-7-v1.0.dat +0 -0
  38. chia/_tests/core/data_layer/old_format/files/2e2e2e2e2e2e2e2e2e2e2e2e2e2e2e2e2e2e2e2e2e2e612073746f7265206964-28a6b7c134abfaeb0ab58a018313f6c87a61a40a4d9ec9bedf53aa1d12f3ee37-full-7-v1.0.dat +0 -0
  39. chia/_tests/core/data_layer/old_format/files/2e2e2e2e2e2e2e2e2e2e2e2e2e2e2e2e2e2e2e2e2e2e612073746f7265206964-30a6bfe7cecbeda259a295dc6de3a436357f52388c3b03d86901e7da68565aeb-delta-19-v1.0.dat +0 -0
  40. chia/_tests/core/data_layer/old_format/files/2e2e2e2e2e2e2e2e2e2e2e2e2e2e2e2e2e2e2e2e2e2e612073746f7265206964-30a6bfe7cecbeda259a295dc6de3a436357f52388c3b03d86901e7da68565aeb-full-19-v1.0.dat +0 -0
  41. chia/_tests/core/data_layer/old_format/files/2e2e2e2e2e2e2e2e2e2e2e2e2e2e2e2e2e2e2e2e2e2e612073746f7265206964-343a2bf9add798e3ac2e6a571823cf9fa7e8a1bed532143354ead2648bd036ef-delta-10-v1.0.dat +0 -0
  42. chia/_tests/core/data_layer/old_format/files/2e2e2e2e2e2e2e2e2e2e2e2e2e2e2e2e2e2e2e2e2e2e612073746f7265206964-343a2bf9add798e3ac2e6a571823cf9fa7e8a1bed532143354ead2648bd036ef-full-10-v1.0.dat +0 -0
  43. chia/_tests/core/data_layer/old_format/files/2e2e2e2e2e2e2e2e2e2e2e2e2e2e2e2e2e2e2e2e2e2e612073746f7265206964-4d90efbc1fb3df324193831ea4a57dd5e10e67d9653343eb18d178272adb0447-delta-17-v1.0.dat +0 -0
  44. chia/_tests/core/data_layer/old_format/files/2e2e2e2e2e2e2e2e2e2e2e2e2e2e2e2e2e2e2e2e2e2e612073746f7265206964-4d90efbc1fb3df324193831ea4a57dd5e10e67d9653343eb18d178272adb0447-full-17-v1.0.dat +0 -0
  45. chia/_tests/core/data_layer/old_format/files/2e2e2e2e2e2e2e2e2e2e2e2e2e2e2e2e2e2e2e2e2e2e612073746f7265206964-4dd2ea099e91635c441f40b36d3f84078a2d818d2dc601c7278e72cbdfe3eca8-delta-20-v1.0.dat +0 -0
  46. chia/_tests/core/data_layer/old_format/files/2e2e2e2e2e2e2e2e2e2e2e2e2e2e2e2e2e2e2e2e2e2e612073746f7265206964-4dd2ea099e91635c441f40b36d3f84078a2d818d2dc601c7278e72cbdfe3eca8-full-20-v1.0.dat +0 -0
  47. chia/_tests/core/data_layer/old_format/files/2e2e2e2e2e2e2e2e2e2e2e2e2e2e2e2e2e2e2e2e2e2e612073746f7265206964-509effbdca78639023b933ce6c08a0465fb247e1cd5329e9e9c553940e4b6e46-delta-31-v1.0.dat +0 -0
  48. chia/_tests/core/data_layer/old_format/files/2e2e2e2e2e2e2e2e2e2e2e2e2e2e2e2e2e2e2e2e2e2e612073746f7265206964-509effbdca78639023b933ce6c08a0465fb247e1cd5329e9e9c553940e4b6e46-full-31-v1.0.dat +0 -0
  49. chia/_tests/core/data_layer/old_format/files/2e2e2e2e2e2e2e2e2e2e2e2e2e2e2e2e2e2e2e2e2e2e612073746f7265206964-5379a4d9ff29c29d1ef0906d22e82c52472753d31806189ab813c43365341b78-delta-40-v1.0.dat +0 -0
  50. chia/_tests/core/data_layer/old_format/files/2e2e2e2e2e2e2e2e2e2e2e2e2e2e2e2e2e2e2e2e2e2e612073746f7265206964-5379a4d9ff29c29d1ef0906d22e82c52472753d31806189ab813c43365341b78-full-40-v1.0.dat +0 -0
  51. chia/_tests/core/data_layer/old_format/files/2e2e2e2e2e2e2e2e2e2e2e2e2e2e2e2e2e2e2e2e2e2e612073746f7265206964-55908eda5686a8f89e4c50672cbe893ec1734fb23449dc03325efe7c414f9aa4-delta-49-v1.0.dat +0 -0
  52. chia/_tests/core/data_layer/old_format/files/2e2e2e2e2e2e2e2e2e2e2e2e2e2e2e2e2e2e2e2e2e2e612073746f7265206964-55908eda5686a8f89e4c50672cbe893ec1734fb23449dc03325efe7c414f9aa4-full-49-v1.0.dat +0 -0
  53. chia/_tests/core/data_layer/old_format/files/2e2e2e2e2e2e2e2e2e2e2e2e2e2e2e2e2e2e2e2e2e2e612073746f7265206964-57cc2691fb1fb986c99a58bcb0e029d0cd0cff41553d703147c54196d7d9ca63-delta-14-v1.0.dat +0 -0
  54. chia/_tests/core/data_layer/old_format/files/2e2e2e2e2e2e2e2e2e2e2e2e2e2e2e2e2e2e2e2e2e2e612073746f7265206964-57cc2691fb1fb986c99a58bcb0e029d0cd0cff41553d703147c54196d7d9ca63-full-14-v1.0.dat +0 -0
  55. chia/_tests/core/data_layer/old_format/files/2e2e2e2e2e2e2e2e2e2e2e2e2e2e2e2e2e2e2e2e2e2e612073746f7265206964-5943bf8ae4f5e59969d8570e4f40a8223299febdcfbcf188b3b3e2ab11044e18-delta-34-v1.0.dat +0 -0
  56. chia/_tests/core/data_layer/old_format/files/2e2e2e2e2e2e2e2e2e2e2e2e2e2e2e2e2e2e2e2e2e2e612073746f7265206964-5943bf8ae4f5e59969d8570e4f40a8223299febdcfbcf188b3b3e2ab11044e18-full-34-v1.0.dat +0 -0
  57. chia/_tests/core/data_layer/old_format/files/2e2e2e2e2e2e2e2e2e2e2e2e2e2e2e2e2e2e2e2e2e2e612073746f7265206964-6518527b7c939bee60ce6b024cbe90d3b9d8913c56b8ce11a4df5da7ff7db1c8-delta-8-v1.0.dat +0 -0
  58. chia/_tests/core/data_layer/old_format/files/2e2e2e2e2e2e2e2e2e2e2e2e2e2e2e2e2e2e2e2e2e2e612073746f7265206964-6518527b7c939bee60ce6b024cbe90d3b9d8913c56b8ce11a4df5da7ff7db1c8-full-8-v1.0.dat +0 -0
  59. chia/_tests/core/data_layer/old_format/files/2e2e2e2e2e2e2e2e2e2e2e2e2e2e2e2e2e2e2e2e2e2e612073746f7265206964-66ff26a26620379e14a7c91252d27ee4dbe06ad69a3a390a88642fe757f2b288-delta-45-v1.0.dat +0 -0
  60. chia/_tests/core/data_layer/old_format/files/2e2e2e2e2e2e2e2e2e2e2e2e2e2e2e2e2e2e2e2e2e2e612073746f7265206964-66ff26a26620379e14a7c91252d27ee4dbe06ad69a3a390a88642fe757f2b288-full-45-v1.0.dat +0 -0
  61. chia/_tests/core/data_layer/old_format/files/2e2e2e2e2e2e2e2e2e2e2e2e2e2e2e2e2e2e2e2e2e2e612073746f7265206964-6bd0a508ee2c4afbe9d4daa811139fd6e54e7f4e16850cbce999fa30f8bdccd2-delta-6-v1.0.dat +0 -0
  62. chia/_tests/core/data_layer/old_format/files/2e2e2e2e2e2e2e2e2e2e2e2e2e2e2e2e2e2e2e2e2e2e612073746f7265206964-6bd0a508ee2c4afbe9d4daa811139fd6e54e7f4e16850cbce999fa30f8bdccd2-full-6-v1.0.dat +0 -0
  63. chia/_tests/core/data_layer/old_format/files/2e2e2e2e2e2e2e2e2e2e2e2e2e2e2e2e2e2e2e2e2e2e612073746f7265206964-6ce850d0d77ca743fcc2fc792747472e5d2c1c0813aa43abbb370554428fc897-delta-48-v1.0.dat +0 -0
  64. chia/_tests/core/data_layer/old_format/files/2e2e2e2e2e2e2e2e2e2e2e2e2e2e2e2e2e2e2e2e2e2e612073746f7265206964-6ce850d0d77ca743fcc2fc792747472e5d2c1c0813aa43abbb370554428fc897-full-48-v1.0.dat +0 -0
  65. chia/_tests/core/data_layer/old_format/files/2e2e2e2e2e2e2e2e2e2e2e2e2e2e2e2e2e2e2e2e2e2e612073746f7265206964-6eb4ca2e1552b156c5969396b49070eb08ad6c96b347359387519be59f7ccaed-delta-26-v1.0.dat +0 -0
  66. chia/_tests/core/data_layer/old_format/files/2e2e2e2e2e2e2e2e2e2e2e2e2e2e2e2e2e2e2e2e2e2e612073746f7265206964-6eb4ca2e1552b156c5969396b49070eb08ad6c96b347359387519be59f7ccaed-full-26-v1.0.dat +0 -0
  67. chia/_tests/core/data_layer/old_format/files/2e2e2e2e2e2e2e2e2e2e2e2e2e2e2e2e2e2e2e2e2e2e612073746f7265206964-71c797fb7592d3f0a5a20c79ab8497ddaa0fd9ec17712e109d25c91b3f3c76e5-delta-3-v1.0.dat +0 -0
  68. chia/_tests/core/data_layer/old_format/files/2e2e2e2e2e2e2e2e2e2e2e2e2e2e2e2e2e2e2e2e2e2e612073746f7265206964-71c797fb7592d3f0a5a20c79ab8497ddaa0fd9ec17712e109d25c91b3f3c76e5-full-3-v1.0.dat +0 -0
  69. chia/_tests/core/data_layer/old_format/files/2e2e2e2e2e2e2e2e2e2e2e2e2e2e2e2e2e2e2e2e2e2e612073746f7265206964-73357026053d5a4969e7a6b9aeeef91c14cc6d5f32fc700fe6d21d2a1b22496c-delta-25-v1.0.dat +0 -0
  70. chia/_tests/core/data_layer/old_format/files/2e2e2e2e2e2e2e2e2e2e2e2e2e2e2e2e2e2e2e2e2e2e612073746f7265206964-73357026053d5a4969e7a6b9aeeef91c14cc6d5f32fc700fe6d21d2a1b22496c-full-25-v1.0.dat +0 -0
  71. chia/_tests/core/data_layer/old_format/files/2e2e2e2e2e2e2e2e2e2e2e2e2e2e2e2e2e2e2e2e2e2e612073746f7265206964-7c897e5c46e834ced65bde7de87716acfaa5dffbdb30b5cd9377d8c319df2034-delta-35-v1.0.dat +0 -0
  72. chia/_tests/core/data_layer/old_format/files/2e2e2e2e2e2e2e2e2e2e2e2e2e2e2e2e2e2e2e2e2e2e612073746f7265206964-7c897e5c46e834ced65bde7de87716acfaa5dffbdb30b5cd9377d8c319df2034-full-35-v1.0.dat +0 -0
  73. chia/_tests/core/data_layer/old_format/files/2e2e2e2e2e2e2e2e2e2e2e2e2e2e2e2e2e2e2e2e2e2e612073746f7265206964-87b8394d80d08117a5a1cd04ed8a682564eab7197a2c090159863591b5108874-delta-4-v1.0.dat +0 -0
  74. chia/_tests/core/data_layer/old_format/files/2e2e2e2e2e2e2e2e2e2e2e2e2e2e2e2e2e2e2e2e2e2e612073746f7265206964-87b8394d80d08117a5a1cd04ed8a682564eab7197a2c090159863591b5108874-full-4-v1.0.dat +0 -0
  75. chia/_tests/core/data_layer/old_format/files/2e2e2e2e2e2e2e2e2e2e2e2e2e2e2e2e2e2e2e2e2e2e612073746f7265206964-89eb40b9cc0921c5f5c3feb20927c13a9ada5760f82d219dcee153b7d400165c-delta-41-v1.0.dat +0 -0
  76. chia/_tests/core/data_layer/old_format/files/2e2e2e2e2e2e2e2e2e2e2e2e2e2e2e2e2e2e2e2e2e2e612073746f7265206964-89eb40b9cc0921c5f5c3feb20927c13a9ada5760f82d219dcee153b7d400165c-full-41-v1.0.dat +0 -0
  77. chia/_tests/core/data_layer/old_format/files/2e2e2e2e2e2e2e2e2e2e2e2e2e2e2e2e2e2e2e2e2e2e612073746f7265206964-8b649433156b8c924436cdec9c6de26106fd6f73a0528570f48748f7b40d7f8a-delta-21-v1.0.dat +0 -0
  78. chia/_tests/core/data_layer/old_format/files/2e2e2e2e2e2e2e2e2e2e2e2e2e2e2e2e2e2e2e2e2e2e612073746f7265206964-8b649433156b8c924436cdec9c6de26106fd6f73a0528570f48748f7b40d7f8a-full-21-v1.0.dat +0 -0
  79. chia/_tests/core/data_layer/old_format/files/2e2e2e2e2e2e2e2e2e2e2e2e2e2e2e2e2e2e2e2e2e2e612073746f7265206964-8d364023a0834c8c3077e236a465493acbf488e4f9d1f4c6cc230343c10a8f7d-delta-42-v1.0.dat +0 -0
  80. chia/_tests/core/data_layer/old_format/files/2e2e2e2e2e2e2e2e2e2e2e2e2e2e2e2e2e2e2e2e2e2e612073746f7265206964-8d364023a0834c8c3077e236a465493acbf488e4f9d1f4c6cc230343c10a8f7d-full-42-v1.0.dat +0 -0
  81. chia/_tests/core/data_layer/old_format/files/2e2e2e2e2e2e2e2e2e2e2e2e2e2e2e2e2e2e2e2e2e2e612073746f7265206964-925689e24a3d98d98676d816cdd8b73e7b2df057d9d4503da9b27bf91d79666c-delta-38-v1.0.dat +0 -0
  82. chia/_tests/core/data_layer/old_format/files/2e2e2e2e2e2e2e2e2e2e2e2e2e2e2e2e2e2e2e2e2e2e612073746f7265206964-925689e24a3d98d98676d816cdd8b73e7b2df057d9d4503da9b27bf91d79666c-full-38-v1.0.dat +0 -0
  83. chia/_tests/core/data_layer/old_format/files/2e2e2e2e2e2e2e2e2e2e2e2e2e2e2e2e2e2e2e2e2e2e612073746f7265206964-937be3d428b19f521be4f98faecc3307ae11ee731c76992f417fa4268d13859e-delta-11-v1.0.dat +0 -0
  84. chia/_tests/core/data_layer/old_format/files/2e2e2e2e2e2e2e2e2e2e2e2e2e2e2e2e2e2e2e2e2e2e612073746f7265206964-937be3d428b19f521be4f98faecc3307ae11ee731c76992f417fa4268d13859e-full-11-v1.0.dat +0 -0
  85. chia/_tests/core/data_layer/old_format/files/2e2e2e2e2e2e2e2e2e2e2e2e2e2e2e2e2e2e2e2e2e2e612073746f7265206964-97f34af499b79e2111fc296a598fc9654c2467ea038dfea41fd58241fb3642de-delta-32-v1.0.dat +0 -0
  86. chia/_tests/core/data_layer/old_format/files/2e2e2e2e2e2e2e2e2e2e2e2e2e2e2e2e2e2e2e2e2e2e612073746f7265206964-97f34af499b79e2111fc296a598fc9654c2467ea038dfea41fd58241fb3642de-full-32-v1.0.dat +0 -0
  87. chia/_tests/core/data_layer/old_format/files/2e2e2e2e2e2e2e2e2e2e2e2e2e2e2e2e2e2e2e2e2e2e612073746f7265206964-9d1b737243b8a1d0022f2b36ac53333c6280354a74d77f2a3642dcab35204e59-delta-33-v1.0.dat +0 -0
  88. chia/_tests/core/data_layer/old_format/files/2e2e2e2e2e2e2e2e2e2e2e2e2e2e2e2e2e2e2e2e2e2e612073746f7265206964-9d1b737243b8a1d0022f2b36ac53333c6280354a74d77f2a3642dcab35204e59-full-33-v1.0.dat +0 -0
  89. chia/_tests/core/data_layer/old_format/files/2e2e2e2e2e2e2e2e2e2e2e2e2e2e2e2e2e2e2e2e2e2e612073746f7265206964-a6663f98ef6ddf6db55f01163e34bb2e87aa82f0347e79ce31e8dbfa390c480c-delta-47-v1.0.dat +0 -0
  90. chia/_tests/core/data_layer/old_format/files/2e2e2e2e2e2e2e2e2e2e2e2e2e2e2e2e2e2e2e2e2e2e612073746f7265206964-a6663f98ef6ddf6db55f01163e34bb2e87aa82f0347e79ce31e8dbfa390c480c-full-47-v1.0.dat +0 -0
  91. chia/_tests/core/data_layer/old_format/files/2e2e2e2e2e2e2e2e2e2e2e2e2e2e2e2e2e2e2e2e2e2e612073746f7265206964-aa77376d1ccd3664e5c6366e010c52a978fedbf40f5ce262fee71b2e7fe0c6a9-delta-50-v1.0.dat +0 -0
  92. chia/_tests/core/data_layer/old_format/files/2e2e2e2e2e2e2e2e2e2e2e2e2e2e2e2e2e2e2e2e2e2e612073746f7265206964-aa77376d1ccd3664e5c6366e010c52a978fedbf40f5ce262fee71b2e7fe0c6a9-full-50-v1.0.dat +0 -0
  93. chia/_tests/core/data_layer/old_format/files/2e2e2e2e2e2e2e2e2e2e2e2e2e2e2e2e2e2e2e2e2e2e612073746f7265206964-b0f28514741ed1a71f5c6544bf92f9e0e493c5f3cf28328909771d8404eff626-delta-24-v1.0.dat +0 -0
  94. chia/_tests/core/data_layer/old_format/files/2e2e2e2e2e2e2e2e2e2e2e2e2e2e2e2e2e2e2e2e2e2e612073746f7265206964-b0f28514741ed1a71f5c6544bf92f9e0e493c5f3cf28328909771d8404eff626-full-24-v1.0.dat +0 -0
  95. chia/_tests/core/data_layer/old_format/files/2e2e2e2e2e2e2e2e2e2e2e2e2e2e2e2e2e2e2e2e2e2e612073746f7265206964-b3efee5358e6eb89ab3b60db2d128d57eef39e8538fb63c5632412d4f8e7d09e-delta-44-v1.0.dat +0 -0
  96. chia/_tests/core/data_layer/old_format/files/2e2e2e2e2e2e2e2e2e2e2e2e2e2e2e2e2e2e2e2e2e2e612073746f7265206964-b3efee5358e6eb89ab3b60db2d128d57eef39e8538fb63c5632412d4f8e7d09e-full-44-v1.0.dat +0 -0
  97. chia/_tests/core/data_layer/old_format/files/2e2e2e2e2e2e2e2e2e2e2e2e2e2e2e2e2e2e2e2e2e2e612073746f7265206964-bb0b56b6eb7acbb4e80893b04c72412fe833418232e1ed7b06d97d7a7f08b4e1-delta-16-v1.0.dat +0 -0
  98. chia/_tests/core/data_layer/old_format/files/2e2e2e2e2e2e2e2e2e2e2e2e2e2e2e2e2e2e2e2e2e2e612073746f7265206964-bb0b56b6eb7acbb4e80893b04c72412fe833418232e1ed7b06d97d7a7f08b4e1-full-16-v1.0.dat +0 -0
  99. chia/_tests/core/data_layer/old_format/files/2e2e2e2e2e2e2e2e2e2e2e2e2e2e2e2e2e2e2e2e2e2e612073746f7265206964-bc45262b757ff494b53bd2a8fba0f5511cc1f9c2a2c5360e04ea8cebbf6409df-delta-13-v1.0.dat +0 -0
  100. chia/_tests/core/data_layer/old_format/files/2e2e2e2e2e2e2e2e2e2e2e2e2e2e2e2e2e2e2e2e2e2e612073746f7265206964-bc45262b757ff494b53bd2a8fba0f5511cc1f9c2a2c5360e04ea8cebbf6409df-full-13-v1.0.dat +0 -0
  101. chia/_tests/core/data_layer/old_format/files/2e2e2e2e2e2e2e2e2e2e2e2e2e2e2e2e2e2e2e2e2e2e612073746f7265206964-bd0494ba430aff13458b557113b073d226eaf11257dfe26ff3323fa1cfe1335b-delta-39-v1.0.dat +0 -0
  102. chia/_tests/core/data_layer/old_format/files/2e2e2e2e2e2e2e2e2e2e2e2e2e2e2e2e2e2e2e2e2e2e612073746f7265206964-bd0494ba430aff13458b557113b073d226eaf11257dfe26ff3323fa1cfe1335b-full-39-v1.0.dat +0 -0
  103. chia/_tests/core/data_layer/old_format/files/2e2e2e2e2e2e2e2e2e2e2e2e2e2e2e2e2e2e2e2e2e2e612073746f7265206964-cd04f5fbba1553fa728b4dd8131d4723aaac288e0c7dc080447fbf0872c0a6eb-delta-36-v1.0.dat +0 -0
  104. chia/_tests/core/data_layer/old_format/files/2e2e2e2e2e2e2e2e2e2e2e2e2e2e2e2e2e2e2e2e2e2e612073746f7265206964-cd04f5fbba1553fa728b4dd8131d4723aaac288e0c7dc080447fbf0872c0a6eb-full-36-v1.0.dat +0 -0
  105. chia/_tests/core/data_layer/old_format/files/2e2e2e2e2e2e2e2e2e2e2e2e2e2e2e2e2e2e2e2e2e2e612073746f7265206964-cdd2399557fb3163a848f08831fdc833703354edb19a0d32a965fdb140f160c2-delta-18-v1.0.dat +0 -0
  106. chia/_tests/core/data_layer/old_format/files/2e2e2e2e2e2e2e2e2e2e2e2e2e2e2e2e2e2e2e2e2e2e612073746f7265206964-cdd2399557fb3163a848f08831fdc833703354edb19a0d32a965fdb140f160c2-full-18-v1.0.dat +0 -0
  107. chia/_tests/core/data_layer/old_format/files/2e2e2e2e2e2e2e2e2e2e2e2e2e2e2e2e2e2e2e2e2e2e612073746f7265206964-cf7a08fca7b1332095242e4d9800f4b94a3f4eaae88fe8407da42736d54b9e18-delta-37-v1.0.dat +0 -0
  108. chia/_tests/core/data_layer/old_format/files/2e2e2e2e2e2e2e2e2e2e2e2e2e2e2e2e2e2e2e2e2e2e612073746f7265206964-cf7a08fca7b1332095242e4d9800f4b94a3f4eaae88fe8407da42736d54b9e18-full-37-v1.0.dat +0 -0
  109. chia/_tests/core/data_layer/old_format/files/2e2e2e2e2e2e2e2e2e2e2e2e2e2e2e2e2e2e2e2e2e2e612073746f7265206964-d1f97465a9f52187e2ef3a0d811a1258f52380a65340c55f3e8e65b92753bc13-delta-15-v1.0.dat +0 -0
  110. chia/_tests/core/data_layer/old_format/files/2e2e2e2e2e2e2e2e2e2e2e2e2e2e2e2e2e2e2e2e2e2e612073746f7265206964-d1f97465a9f52187e2ef3a0d811a1258f52380a65340c55f3e8e65b92753bc13-full-15-v1.0.dat +0 -0
  111. chia/_tests/core/data_layer/old_format/files/2e2e2e2e2e2e2e2e2e2e2e2e2e2e2e2e2e2e2e2e2e2e612073746f7265206964-e475eccd4ee597e5ff67b1a249e37d65d6e3f754c3f0379fdb43692513588fef-delta-46-v1.0.dat +0 -0
  112. chia/_tests/core/data_layer/old_format/files/2e2e2e2e2e2e2e2e2e2e2e2e2e2e2e2e2e2e2e2e2e2e612073746f7265206964-e475eccd4ee597e5ff67b1a249e37d65d6e3f754c3f0379fdb43692513588fef-full-46-v1.0.dat +0 -0
  113. chia/_tests/core/data_layer/old_format/files/2e2e2e2e2e2e2e2e2e2e2e2e2e2e2e2e2e2e2e2e2e2e612073746f7265206964-e82e63517d78fd65b23a05c3b9a98cf905ddad7026995a238bfe634006b84cd0-delta-27-v1.0.dat +0 -0
  114. chia/_tests/core/data_layer/old_format/files/2e2e2e2e2e2e2e2e2e2e2e2e2e2e2e2e2e2e2e2e2e2e612073746f7265206964-e82e63517d78fd65b23a05c3b9a98cf905ddad7026995a238bfe634006b84cd0-full-27-v1.0.dat +0 -0
  115. chia/_tests/core/data_layer/old_format/files/2e2e2e2e2e2e2e2e2e2e2e2e2e2e2e2e2e2e2e2e2e2e612073746f7265206964-ed2cf0fd6c0f6237c87c161e1fca303b3fbe6c04e01f652b88720b4572143349-delta-12-v1.0.dat +0 -0
  116. chia/_tests/core/data_layer/old_format/files/2e2e2e2e2e2e2e2e2e2e2e2e2e2e2e2e2e2e2e2e2e2e612073746f7265206964-ed2cf0fd6c0f6237c87c161e1fca303b3fbe6c04e01f652b88720b4572143349-full-12-v1.0.dat +0 -0
  117. chia/_tests/core/data_layer/old_format/files/2e2e2e2e2e2e2e2e2e2e2e2e2e2e2e2e2e2e2e2e2e2e612073746f7265206964-f6e454eaf24a83c46a7bed4c19260a0a3ce0ed5c51739cb6d748d4913dc2ef58-delta-30-v1.0.dat +0 -0
  118. chia/_tests/core/data_layer/old_format/files/2e2e2e2e2e2e2e2e2e2e2e2e2e2e2e2e2e2e2e2e2e2e612073746f7265206964-f6e454eaf24a83c46a7bed4c19260a0a3ce0ed5c51739cb6d748d4913dc2ef58-full-30-v1.0.dat +0 -0
  119. chia/_tests/core/data_layer/old_format/files/2e2e2e2e2e2e2e2e2e2e2e2e2e2e2e2e2e2e2e2e2e2e612073746f7265206964-f7ad2bdf86d9609b4d6381086ec1e296bf558e2ff467ead29dd7fa6e31bacc56-delta-43-v1.0.dat +0 -0
  120. chia/_tests/core/data_layer/old_format/files/2e2e2e2e2e2e2e2e2e2e2e2e2e2e2e2e2e2e2e2e2e2e612073746f7265206964-f7ad2bdf86d9609b4d6381086ec1e296bf558e2ff467ead29dd7fa6e31bacc56-full-43-v1.0.dat +0 -0
  121. chia/_tests/core/data_layer/old_format/files/__init__.py +0 -0
  122. chia/_tests/core/data_layer/old_format/old_db.sqlite +0 -0
  123. chia/_tests/core/data_layer/test_data_layer_util.py +18 -21
  124. chia/_tests/core/data_layer/test_data_rpc.py +77 -28
  125. chia/_tests/core/data_layer/test_data_store.py +637 -700
  126. chia/_tests/core/data_layer/test_data_store_schema.py +2 -209
  127. chia/_tests/core/full_node/ram_db.py +1 -1
  128. chia/_tests/core/full_node/stores/test_block_store.py +4 -10
  129. chia/_tests/core/full_node/stores/test_coin_store.py +1 -1
  130. chia/_tests/core/full_node/test_address_manager.py +3 -3
  131. chia/_tests/core/full_node/test_block_height_map.py +1 -1
  132. chia/_tests/core/full_node/test_full_node.py +91 -30
  133. chia/_tests/core/full_node/test_generator_tools.py +17 -10
  134. chia/_tests/core/mempool/test_mempool.py +190 -90
  135. chia/_tests/core/mempool/test_mempool_fee_estimator.py +2 -4
  136. chia/_tests/core/mempool/test_mempool_item_queries.py +1 -1
  137. chia/_tests/core/mempool/test_mempool_manager.py +134 -75
  138. chia/_tests/core/mempool/test_singleton_fast_forward.py +9 -27
  139. chia/_tests/core/server/serve.py +0 -2
  140. chia/_tests/core/server/test_rate_limits.py +400 -347
  141. chia/_tests/core/server/test_server.py +2 -2
  142. chia/_tests/core/services/test_services.py +7 -7
  143. chia/_tests/core/test_cost_calculation.py +31 -10
  144. chia/_tests/core/test_crawler.py +4 -4
  145. chia/_tests/core/test_db_conversion.py +7 -14
  146. chia/_tests/core/test_db_validation.py +2 -6
  147. chia/_tests/core/test_farmer_harvester_rpc.py +34 -1
  148. chia/_tests/core/test_full_node_rpc.py +28 -24
  149. chia/_tests/core/test_merkle_set.py +1 -4
  150. chia/_tests/core/test_seeder.py +1 -1
  151. chia/_tests/core/util/test_keychain.py +2 -2
  152. chia/_tests/core/util/test_lru_cache.py +16 -0
  153. chia/_tests/core/util/test_streamable.py +85 -4
  154. chia/_tests/environments/wallet.py +4 -1
  155. chia/_tests/farmer_harvester/test_farmer.py +8 -6
  156. chia/_tests/farmer_harvester/test_farmer_harvester.py +306 -8
  157. chia/_tests/farmer_harvester/test_filter_prefix_bits.py +3 -3
  158. chia/_tests/farmer_harvester/test_third_party_harvesters.py +11 -11
  159. chia/_tests/fee_estimation/test_fee_estimation_integration.py +2 -2
  160. chia/_tests/fee_estimation/test_fee_estimation_rpc.py +1 -1
  161. chia/_tests/fee_estimation/test_fee_estimation_unit_tests.py +1 -2
  162. chia/_tests/generator/test_rom.py +2 -1
  163. chia/_tests/harvester/__init__.py +0 -0
  164. chia/_tests/harvester/config.py +4 -0
  165. chia/_tests/harvester/test_harvester_api.py +157 -0
  166. chia/_tests/plot_sync/test_plot_sync.py +6 -3
  167. chia/_tests/plot_sync/test_receiver.py +16 -4
  168. chia/_tests/plot_sync/test_sender.py +8 -7
  169. chia/_tests/plot_sync/test_sync_simulated.py +15 -13
  170. chia/_tests/plot_sync/util.py +3 -2
  171. chia/_tests/plotting/test_plot_manager.py +21 -5
  172. chia/_tests/plotting/test_prover.py +106 -0
  173. chia/_tests/pools/test_pool_cmdline.py +7 -6
  174. chia/_tests/pools/test_pool_puzzles_lifecycle.py +10 -3
  175. chia/_tests/pools/test_pool_rpc.py +92 -64
  176. chia/_tests/solver/__init__.py +0 -0
  177. chia/_tests/solver/config.py +4 -0
  178. chia/_tests/solver/test_solver_service.py +29 -0
  179. chia/_tests/timelord/test_new_peak.py +1 -1
  180. chia/_tests/timelord/test_timelord.py +1 -1
  181. chia/_tests/util/benchmarks.py +5 -12
  182. chia/_tests/util/blockchain.py +1 -1
  183. chia/_tests/util/build_network_protocol_files.py +7 -0
  184. chia/_tests/util/network_protocol_data.py +26 -0
  185. chia/_tests/util/protocol_messages_bytes-v1.0 +0 -0
  186. chia/_tests/util/protocol_messages_json.py +19 -0
  187. chia/_tests/util/setup_nodes.py +21 -2
  188. chia/_tests/util/spend_sim.py +9 -3
  189. chia/_tests/util/test_condition_tools.py +3 -2
  190. chia/_tests/util/test_full_block_utils.py +10 -9
  191. chia/_tests/util/test_misc.py +10 -10
  192. chia/_tests/util/test_network.py +32 -1
  193. chia/_tests/util/test_network_protocol_files.py +333 -318
  194. chia/_tests/util/test_network_protocol_json.py +6 -0
  195. chia/_tests/util/test_network_protocol_test.py +27 -0
  196. chia/_tests/util/test_priority_mutex.py +1 -1
  197. chia/_tests/util/test_replace_str_to_bytes.py +6 -6
  198. chia/_tests/wallet/cat_wallet/test_cat_wallet.py +17 -13
  199. chia/_tests/wallet/cat_wallet/test_trades.py +55 -55
  200. chia/_tests/wallet/did_wallet/test_did.py +118 -1229
  201. chia/_tests/wallet/nft_wallet/config.py +1 -1
  202. chia/_tests/wallet/nft_wallet/test_nft_1_offers.py +73 -96
  203. chia/_tests/wallet/nft_wallet/test_nft_bulk_mint.py +15 -12
  204. chia/_tests/wallet/nft_wallet/test_nft_offers.py +67 -134
  205. chia/_tests/wallet/nft_wallet/test_nft_wallet.py +31 -26
  206. chia/_tests/wallet/rpc/test_wallet_rpc.py +765 -371
  207. chia/_tests/wallet/sync/test_wallet_sync.py +6 -0
  208. chia/_tests/wallet/test_new_wallet_protocol.py +1 -1
  209. chia/_tests/wallet/test_signer_protocol.py +2 -2
  210. chia/_tests/wallet/test_singleton_lifecycle_fast.py +3 -4
  211. chia/_tests/wallet/test_transaction_store.py +42 -33
  212. chia/_tests/wallet/test_wallet.py +22 -31
  213. chia/_tests/wallet/test_wallet_state_manager.py +14 -7
  214. chia/_tests/wallet/vc_wallet/test_vc_wallet.py +53 -32
  215. chia/apis.py +2 -0
  216. chia/cmds/beta.py +7 -3
  217. chia/cmds/chia.py +2 -0
  218. chia/cmds/cmd_classes.py +11 -27
  219. chia/cmds/cmds_util.py +3 -0
  220. chia/cmds/coin_funcs.py +27 -22
  221. chia/cmds/configure.py +42 -18
  222. chia/cmds/dev/data.py +22 -3
  223. chia/cmds/farm.py +32 -0
  224. chia/cmds/farm_funcs.py +54 -5
  225. chia/cmds/init_funcs.py +4 -0
  226. chia/cmds/keys_funcs.py +8 -10
  227. chia/cmds/peer_funcs.py +8 -10
  228. chia/cmds/plotnft_funcs.py +24 -16
  229. chia/cmds/rpc.py +11 -1
  230. chia/cmds/show_funcs.py +5 -5
  231. chia/cmds/solver.py +33 -0
  232. chia/cmds/solver_funcs.py +21 -0
  233. chia/cmds/wallet.py +1 -1
  234. chia/cmds/wallet_funcs.py +149 -96
  235. chia/consensus/block_body_validation.py +8 -9
  236. chia/consensus/block_creation.py +9 -10
  237. chia/consensus/block_header_validation.py +61 -69
  238. chia/{full_node → consensus}/block_height_map.py +2 -1
  239. chia/consensus/block_height_map_protocol.py +21 -0
  240. chia/consensus/block_rewards.py +12 -12
  241. chia/consensus/blockchain.py +8 -18
  242. chia/consensus/default_constants.py +6 -6
  243. chia/consensus/generator_tools.py +1 -1
  244. chia/consensus/get_block_challenge.py +24 -25
  245. chia/consensus/pos_quality.py +28 -2
  246. chia/consensus/pot_iterations.py +15 -17
  247. chia/daemon/keychain_proxy.py +5 -0
  248. chia/daemon/server.py +2 -3
  249. chia/data_layer/data_layer.py +32 -24
  250. chia/data_layer/data_layer_errors.py +5 -0
  251. chia/data_layer/data_layer_rpc_api.py +1 -1
  252. chia/data_layer/data_layer_service.py +8 -0
  253. chia/data_layer/data_layer_util.py +49 -89
  254. chia/data_layer/data_layer_wallet.py +20 -17
  255. chia/data_layer/data_store.py +1051 -1462
  256. chia/data_layer/download_data.py +44 -115
  257. chia/{server → data_layer}/start_data_layer.py +2 -1
  258. chia/data_layer/util/benchmark.py +38 -53
  259. chia/farmer/farmer.py +3 -0
  260. chia/farmer/farmer_api.py +104 -5
  261. chia/farmer/farmer_rpc_api.py +20 -0
  262. chia/farmer/farmer_rpc_client.py +6 -2
  263. chia/farmer/farmer_service.py +8 -0
  264. chia/{server → farmer}/start_farmer.py +4 -3
  265. chia/full_node/block_store.py +20 -10
  266. chia/full_node/coin_store.py +12 -4
  267. chia/full_node/eligible_coin_spends.py +17 -72
  268. chia/full_node/full_node.py +68 -71
  269. chia/full_node/full_node_api.py +26 -32
  270. chia/full_node/full_node_rpc_api.py +44 -32
  271. chia/full_node/full_node_rpc_client.py +67 -79
  272. chia/full_node/full_node_service.py +8 -0
  273. chia/full_node/full_node_store.py +5 -3
  274. chia/full_node/mempool.py +14 -14
  275. chia/full_node/mempool_manager.py +67 -89
  276. chia/{server → full_node}/start_full_node.py +1 -1
  277. chia/full_node/subscriptions.py +2 -2
  278. chia/full_node/weight_proof.py +14 -15
  279. chia/harvester/harvester.py +8 -1
  280. chia/harvester/harvester_api.py +178 -44
  281. chia/harvester/harvester_service.py +8 -0
  282. chia/{server → harvester}/start_harvester.py +1 -1
  283. chia/introducer/introducer_service.py +8 -0
  284. chia/{server → introducer}/start_introducer.py +1 -1
  285. chia/plot_sync/receiver.py +6 -1
  286. chia/plot_sync/sender.py +7 -4
  287. chia/plotting/cache.py +37 -28
  288. chia/plotting/check_plots.py +83 -48
  289. chia/plotting/create_plots.py +3 -4
  290. chia/plotting/manager.py +18 -13
  291. chia/plotting/prover.py +153 -0
  292. chia/plotting/util.py +14 -6
  293. chia/pools/pool_wallet.py +6 -4
  294. chia/protocols/harvester_protocol.py +14 -0
  295. chia/protocols/outbound_message.py +1 -0
  296. chia/protocols/pool_protocol.py +1 -1
  297. chia/protocols/protocol_message_types.py +7 -0
  298. chia/protocols/shared_protocol.py +2 -0
  299. chia/protocols/solver_protocol.py +18 -0
  300. chia/rpc/rpc_server.py +1 -1
  301. chia/seeder/crawl_store.py +4 -8
  302. chia/seeder/crawler.py +2 -2
  303. chia/seeder/crawler_service.py +8 -0
  304. chia/seeder/start_crawler.py +1 -1
  305. chia/server/address_manager.py +12 -15
  306. chia/server/introducer_peers.py +1 -1
  307. chia/server/node_discovery.py +9 -10
  308. chia/server/rate_limit_numbers.py +157 -168
  309. chia/server/rate_limits.py +44 -41
  310. chia/server/resolve_peer_info.py +5 -0
  311. chia/server/server.py +17 -7
  312. chia/server/start_service.py +0 -1
  313. chia/simulator/block_tools.py +92 -58
  314. chia/simulator/full_node_simulator.py +1 -1
  315. chia/simulator/setup_services.py +51 -15
  316. chia/solver/__init__.py +0 -0
  317. chia/solver/solver.py +100 -0
  318. chia/solver/solver_api.py +59 -0
  319. chia/solver/solver_rpc_api.py +31 -0
  320. chia/solver/solver_rpc_client.py +16 -0
  321. chia/solver/solver_service.py +8 -0
  322. chia/solver/start_solver.py +102 -0
  323. {mozilla-ca → chia/ssl}/cacert.pem +0 -27
  324. chia/ssl/create_ssl.py +3 -2
  325. chia/{server → timelord}/start_timelord.py +1 -1
  326. chia/timelord/timelord.py +12 -13
  327. chia/timelord/timelord_service.py +8 -0
  328. chia/types/blockchain_format/proof_of_space.py +61 -17
  329. chia/types/coin_spend.py +0 -8
  330. chia/types/internal_mempool_item.py +3 -3
  331. chia/types/mempool_item.py +15 -8
  332. chia/types/mempool_submission_status.py +1 -1
  333. chia/util/config.py +1 -3
  334. chia/util/db_wrapper.py +7 -8
  335. chia/util/initial-config.yaml +46 -0
  336. chia/util/lru_cache.py +8 -4
  337. chia/util/network.py +9 -0
  338. chia/util/service_groups.py +3 -1
  339. chia/util/streamable.py +38 -8
  340. chia/util/virtual_project_analysis.py +1 -1
  341. chia/wallet/cat_wallet/cat_outer_puzzle.py +7 -4
  342. chia/wallet/cat_wallet/cat_wallet.py +13 -7
  343. chia/wallet/cat_wallet/r_cat_wallet.py +4 -1
  344. chia/wallet/conditions.py +1 -3
  345. chia/wallet/did_wallet/did_wallet.py +27 -332
  346. chia/wallet/nft_wallet/nft_puzzle_utils.py +1 -1
  347. chia/wallet/nft_wallet/nft_wallet.py +9 -7
  348. chia/wallet/puzzle_drivers.py +7 -8
  349. chia/{server → wallet}/start_wallet.py +1 -1
  350. chia/wallet/trade_manager.py +12 -9
  351. chia/wallet/transaction_record.py +14 -51
  352. chia/wallet/util/clvm_streamable.py +28 -41
  353. chia/wallet/util/merkle_utils.py +2 -2
  354. chia/wallet/util/tx_config.py +3 -6
  355. chia/wallet/vc_wallet/cr_cat_wallet.py +12 -6
  356. chia/wallet/vc_wallet/vc_wallet.py +13 -15
  357. chia/wallet/wallet.py +5 -3
  358. chia/wallet/wallet_node.py +25 -30
  359. chia/wallet/wallet_request_types.py +538 -101
  360. chia/wallet/wallet_rpc_api.py +398 -570
  361. chia/wallet/wallet_rpc_client.py +144 -332
  362. chia/wallet/wallet_service.py +8 -0
  363. chia/wallet/wallet_state_manager.py +53 -42
  364. chia/wallet/wallet_transaction_store.py +13 -5
  365. {chia_blockchain-2.5.6rc2.dist-info → chia_blockchain-2.5.7rc2.dist-info}/METADATA +31 -31
  366. {chia_blockchain-2.5.6rc2.dist-info → chia_blockchain-2.5.7rc2.dist-info}/RECORD +369 -241
  367. {chia_blockchain-2.5.6rc2.dist-info → chia_blockchain-2.5.7rc2.dist-info}/WHEEL +1 -1
  368. {chia_blockchain-2.5.6rc2.dist-info → chia_blockchain-2.5.7rc2.dist-info}/entry_points.txt +8 -7
  369. chia/full_node/mempool_check_conditions.py +0 -102
  370. chia/server/aliases.py +0 -35
  371. {chia_blockchain-2.5.6rc2.dist-info → chia_blockchain-2.5.7rc2.dist-info/licenses}/LICENSE +0 -0
@@ -27,7 +27,7 @@ from chia.types.coin_record import CoinRecord
27
27
  from chia.types.signing_mode import CHIP_0002_SIGN_MESSAGE_PREFIX, SigningMode
28
28
  from chia.util.bech32m import decode_puzzle_hash, encode_puzzle_hash
29
29
  from chia.util.byte_types import hexstr_to_bytes
30
- from chia.util.config import load_config, str2bool
30
+ from chia.util.config import load_config
31
31
  from chia.util.errors import KeychainIsLocked
32
32
  from chia.util.hash import std_hash
33
33
  from chia.util.keychain import bytes_to_mnemonic, generate_mnemonic
@@ -90,7 +90,7 @@ from chia.wallet.util.clvm_streamable import json_serialize_with_clvm_streamable
90
90
  from chia.wallet.util.compute_hints import compute_spend_hints_and_additions
91
91
  from chia.wallet.util.compute_memos import compute_memos
92
92
  from chia.wallet.util.curry_and_treehash import NIL_TREEHASH
93
- from chia.wallet.util.query_filter import FilterMode, HashFilter, TransactionTypeFilter
93
+ from chia.wallet.util.query_filter import FilterMode, HashFilter
94
94
  from chia.wallet.util.transaction_type import CLAWBACK_INCOMING_TRANSACTION_TYPES, TransactionType
95
95
  from chia.wallet.util.tx_config import DEFAULT_TX_CONFIG, TXConfig, TXConfigLoader
96
96
  from chia.wallet.util.wallet_sync_utils import fetch_coin_spend_for_coin_state
@@ -111,13 +111,29 @@ from chia.wallet.wallet_request_types import (
111
111
  AddKeyResponse,
112
112
  ApplySignatures,
113
113
  ApplySignaturesResponse,
114
+ BalanceResponse,
115
+ CATAssetIDToName,
116
+ CATAssetIDToNameResponse,
117
+ CATGetAssetID,
118
+ CATGetAssetIDResponse,
119
+ CATGetName,
120
+ CATGetNameResponse,
121
+ CATSetName,
122
+ CATSetNameResponse,
123
+ CATSpend,
124
+ CATSpendResponse,
114
125
  CheckDeleteKey,
115
126
  CheckDeleteKeyResponse,
127
+ CheckOfferValidity,
128
+ CheckOfferValidityResponse,
116
129
  CombineCoins,
117
130
  CombineCoinsResponse,
118
131
  CreateNewDL,
119
132
  CreateNewDLResponse,
133
+ DefaultCAT,
120
134
  DeleteKey,
135
+ DeleteNotifications,
136
+ DeleteUnconfirmedTransactions,
121
137
  DIDCreateBackupFile,
122
138
  DIDCreateBackupFileResponse,
123
139
  DIDFindLostDID,
@@ -132,10 +148,6 @@ from chia.wallet.wallet_request_types import (
132
148
  DIDGetMetadataResponse,
133
149
  DIDGetPubkey,
134
150
  DIDGetPubkeyResponse,
135
- DIDGetRecoveryInfo,
136
- DIDGetRecoveryInfoResponse,
137
- DIDGetRecoveryList,
138
- DIDGetRecoveryListResponse,
139
151
  DIDGetWalletName,
140
152
  DIDGetWalletNameResponse,
141
153
  DIDMessageSpend,
@@ -146,8 +158,6 @@ from chia.wallet.wallet_request_types import (
146
158
  DIDTransferDIDResponse,
147
159
  DIDUpdateMetadata,
148
160
  DIDUpdateMetadataResponse,
149
- DIDUpdateRecoveryIDs,
150
- DIDUpdateRecoveryIDsResponse,
151
161
  DLDeleteMirror,
152
162
  DLDeleteMirrorResponse,
153
163
  DLGetMirrors,
@@ -170,20 +180,46 @@ from chia.wallet.wallet_request_types import (
170
180
  Empty,
171
181
  ExecuteSigningInstructions,
172
182
  ExecuteSigningInstructionsResponse,
183
+ ExtendDerivationIndex,
184
+ ExtendDerivationIndexResponse,
173
185
  GatherSigningInfo,
174
186
  GatherSigningInfoResponse,
175
187
  GenerateMnemonicResponse,
188
+ GetCATListResponse,
189
+ GetCoinRecordsByNames,
190
+ GetCoinRecordsByNamesResponse,
191
+ GetCurrentDerivationIndexResponse,
176
192
  GetHeightInfoResponse,
177
193
  GetLoggedInFingerprintResponse,
194
+ GetNextAddress,
195
+ GetNextAddressResponse,
178
196
  GetNotifications,
179
197
  GetNotificationsResponse,
198
+ GetOffersCountResponse,
180
199
  GetPrivateKey,
181
200
  GetPrivateKeyFormat,
182
201
  GetPrivateKeyResponse,
183
202
  GetPublicKeysResponse,
203
+ GetSpendableCoins,
204
+ GetSpendableCoinsResponse,
205
+ GetStrayCATsResponse,
184
206
  GetSyncStatusResponse,
185
207
  GetTimestampForHeight,
186
208
  GetTimestampForHeightResponse,
209
+ GetTransaction,
210
+ GetTransactionCount,
211
+ GetTransactionCountResponse,
212
+ GetTransactionMemo,
213
+ GetTransactionMemoResponse,
214
+ GetTransactionResponse,
215
+ GetTransactions,
216
+ GetTransactionsResponse,
217
+ GetWalletBalance,
218
+ GetWalletBalanceResponse,
219
+ GetWalletBalances,
220
+ GetWalletBalancesResponse,
221
+ GetWallets,
222
+ GetWalletsResponse,
187
223
  LogIn,
188
224
  LogInResponse,
189
225
  NFTAddURI,
@@ -226,11 +262,25 @@ from chia.wallet.wallet_request_types import (
226
262
  PWSelfPoolResponse,
227
263
  PWStatus,
228
264
  PWStatusResponse,
265
+ SelectCoins,
266
+ SelectCoinsResponse,
267
+ SendNotification,
268
+ SendNotificationResponse,
269
+ SendTransaction,
270
+ SendTransactionResponse,
229
271
  SetWalletResyncOnStartup,
272
+ SignMessageByAddress,
273
+ SignMessageByAddressResponse,
274
+ SignMessageByID,
275
+ SignMessageByIDResponse,
276
+ SpendClawbackCoins,
277
+ SpendClawbackCoinsResponse,
230
278
  SplitCoins,
231
279
  SplitCoinsResponse,
280
+ StrayCAT,
232
281
  SubmitTransactions,
233
282
  SubmitTransactionsResponse,
283
+ TransactionRecordWithMetadata,
234
284
  VCAddProofs,
235
285
  VCGet,
236
286
  VCGetList,
@@ -247,6 +297,9 @@ from chia.wallet.wallet_request_types import (
247
297
  VCRevokeResponse,
248
298
  VCSpend,
249
299
  VCSpendResponse,
300
+ VerifySignature,
301
+ VerifySignatureResponse,
302
+ WalletInfoResponse,
250
303
  )
251
304
  from chia.wallet.wallet_spend_bundle import WalletSpendBundle
252
305
 
@@ -343,10 +396,7 @@ def tx_endpoint(
343
396
  else:
344
397
  response["unsigned_transactions"] = [tx.to_json_dict() for tx in unsigned_txs]
345
398
 
346
- response["transactions"] = [
347
- TransactionRecord.to_json_dict_convenience(tx, self.service.config)
348
- for tx in action_scope.side_effects.transactions
349
- ]
399
+ response["transactions"] = [tx.to_json_dict() for tx in action_scope.side_effects.transactions]
350
400
 
351
401
  # Some backwards compatibility code here because transaction information being returned was not uniform
352
402
  # until the "transactions" key was applied to all of them. Unfortunately, since .add_pending_transactions
@@ -450,6 +500,7 @@ REPLACEABLE_TRANSACTION_RECORD = TransactionRecord(
450
500
  confirmed_at_height=uint32(0),
451
501
  created_at_time=uint64(0),
452
502
  to_puzzle_hash=bytes32.zeros,
503
+ to_address=encode_puzzle_hash(bytes32.zeros, "replace"),
453
504
  amount=uint64(0),
454
505
  fee_amount=uint64(0),
455
506
  confirmed=False,
@@ -462,7 +513,7 @@ REPLACEABLE_TRANSACTION_RECORD = TransactionRecord(
462
513
  trade_id=None,
463
514
  type=uint32(0),
464
515
  name=bytes32.zeros,
465
- memos=[],
516
+ memos={},
466
517
  valid_times=ConditionValidTimes(),
467
518
  )
468
519
 
@@ -553,15 +604,10 @@ class WalletRpcApi:
553
604
  # DID Wallet
554
605
  "/did_set_wallet_name": self.did_set_wallet_name,
555
606
  "/did_get_wallet_name": self.did_get_wallet_name,
556
- "/did_update_recovery_ids": self.did_update_recovery_ids,
557
607
  "/did_update_metadata": self.did_update_metadata,
558
608
  "/did_get_pubkey": self.did_get_pubkey,
559
609
  "/did_get_did": self.did_get_did,
560
- "/did_recovery_spend": self.did_recovery_spend,
561
- "/did_get_recovery_list": self.did_get_recovery_list,
562
610
  "/did_get_metadata": self.did_get_metadata,
563
- "/did_create_attest": self.did_create_attest,
564
- "/did_get_information_needed_for_recovery": self.did_get_information_needed_for_recovery,
565
611
  "/did_get_current_coin_info": self.did_get_current_coin_info,
566
612
  "/did_create_backup_file": self.did_create_backup_file,
567
613
  "/did_transfer_did": self.did_transfer_did,
@@ -766,7 +812,7 @@ class WalletRpcApi:
766
812
  async def add_key(self, request: AddKey) -> AddKeyResponse:
767
813
  # Adding a key from 24 word mnemonic
768
814
  try:
769
- sk = await self.service.keychain_proxy.add_key(" ".join(request.mnemonic))
815
+ sk = await self.service.keychain_proxy.add_key(" ".join(request.mnemonic), label=request.label)
770
816
  except KeyError as e:
771
817
  raise ValueError(f"The word '{e.args[0]}' is incorrect.")
772
818
 
@@ -1017,39 +1063,40 @@ class WalletRpcApi:
1017
1063
  # Wallet Management
1018
1064
  ##########################################################################################
1019
1065
 
1020
- async def get_wallets(self, request: dict[str, Any]) -> EndpointResult:
1021
- include_data: bool = request.get("include_data", True)
1066
+ @marshal
1067
+ async def get_wallets(self, request: GetWallets) -> GetWalletsResponse:
1022
1068
  wallet_type: Optional[WalletType] = None
1023
- if "type" in request:
1024
- wallet_type = WalletType(request["type"])
1069
+ if request.type is not None:
1070
+ wallet_type = WalletType(request.type)
1025
1071
 
1026
1072
  wallets: list[WalletInfo] = await self.service.wallet_state_manager.get_all_wallet_info_entries(wallet_type)
1027
- if not include_data:
1028
- result: list[WalletInfo] = []
1029
- for wallet in wallets:
1030
- result.append(WalletInfo(wallet.id, wallet.name, wallet.type, ""))
1031
- wallets = result
1032
- response: EndpointResult = {"wallets": wallets}
1033
- if include_data:
1034
- response = {
1035
- "wallets": [
1036
- (
1037
- wallet
1038
- if wallet.type != WalletType.CRCAT
1039
- else {
1040
- **wallet.to_json_dict(),
1041
- "authorized_providers": [
1042
- p.hex() for p in CRCATInfo.from_bytes(bytes.fromhex(wallet.data)).authorized_providers
1043
- ],
1044
- "flags_needed": CRCATInfo.from_bytes(bytes.fromhex(wallet.data)).proofs_checker.flags,
1045
- }
1046
- )
1047
- for wallet in response["wallets"]
1048
- ]
1049
- }
1050
- if self.service.logged_in_fingerprint is not None:
1051
- response["fingerprint"] = self.service.logged_in_fingerprint
1052
- return response
1073
+ wallet_infos: list[WalletInfoResponse] = []
1074
+ for wallet in wallets:
1075
+ if request.include_data:
1076
+ data = wallet.data
1077
+ else:
1078
+ data = ""
1079
+
1080
+ if request.include_data and WalletType(wallet.type) is WalletType.CRCAT:
1081
+ crcat_info = CRCATInfo.from_bytes(bytes.fromhex(wallet.data))
1082
+ authorized_providers = crcat_info.authorized_providers
1083
+ proofs_checker_flags = crcat_info.proofs_checker.flags
1084
+ else:
1085
+ authorized_providers = []
1086
+ proofs_checker_flags = []
1087
+
1088
+ wallet_infos.append(
1089
+ WalletInfoResponse(
1090
+ wallet.id,
1091
+ wallet.name,
1092
+ wallet.type,
1093
+ data,
1094
+ authorized_providers,
1095
+ proofs_checker_flags,
1096
+ )
1097
+ )
1098
+
1099
+ return GetWalletsResponse(wallet_infos, uint32.construct_optional(self.service.logged_in_fingerprint))
1053
1100
 
1054
1101
  @tx_endpoint(push=True)
1055
1102
  async def create_new_wallet(
@@ -1108,19 +1155,15 @@ class WalletRpcApi:
1108
1155
 
1109
1156
  elif request["wallet_type"] == "did_wallet":
1110
1157
  if request["did_type"] == "new":
1111
- backup_dids = []
1112
- num_needed = 0
1113
- for d in request["backup_dids"]:
1114
- backup_dids.append(decode_puzzle_hash(d))
1115
- if len(backup_dids) > 0:
1116
- num_needed = uint64(request["num_of_backup_ids_needed"])
1158
+ if "backup_dids" in request and request["backup_dids"] != []:
1159
+ raise ValueError("Recovery options are no longer supported. `backup_dids` cannot be set.")
1117
1160
  metadata: dict[str, str] = {}
1118
1161
  if "metadata" in request:
1119
1162
  if type(request["metadata"]) is dict:
1120
1163
  metadata = request["metadata"]
1121
1164
 
1122
1165
  async with self.service.wallet_state_manager.lock:
1123
- did_wallet_name: str = request.get("wallet_name", None)
1166
+ did_wallet_name: Optional[str] = request.get("wallet_name", None)
1124
1167
  if did_wallet_name is not None:
1125
1168
  did_wallet_name = did_wallet_name.strip()
1126
1169
  did_wallet: DIDWallet = await DIDWallet.create_new_did_wallet(
@@ -1128,8 +1171,6 @@ class WalletRpcApi:
1128
1171
  main_wallet,
1129
1172
  uint64(request["amount"]),
1130
1173
  action_scope,
1131
- backup_dids,
1132
- uint64(num_needed),
1133
1174
  metadata,
1134
1175
  did_wallet_name,
1135
1176
  uint64(request.get("fee", 0)),
@@ -1278,7 +1319,7 @@ class WalletRpcApi:
1278
1319
  # Wallet
1279
1320
  ##########################################################################################
1280
1321
 
1281
- async def _get_wallet_balance(self, wallet_id: uint32) -> dict[str, Any]:
1322
+ async def _get_wallet_balance(self, wallet_id: uint32) -> BalanceResponse:
1282
1323
  wallet = self.service.wallet_state_manager.wallets[wallet_id]
1283
1324
  balance = await self.service.get_balance(wallet_id)
1284
1325
  wallet_balance = balance.to_json_dict()
@@ -1293,36 +1334,38 @@ class WalletRpcApi:
1293
1334
  assert isinstance(wallet, CRCATWallet)
1294
1335
  wallet_balance["pending_approval_balance"] = await wallet.get_pending_approval_balance()
1295
1336
 
1296
- return wallet_balance
1337
+ return BalanceResponse.from_json_dict(wallet_balance)
1297
1338
 
1298
- async def get_wallet_balance(self, request: dict[str, Any]) -> EndpointResult:
1299
- wallet_id = uint32(int(request["wallet_id"]))
1300
- wallet_balance = await self._get_wallet_balance(wallet_id)
1301
- return {"wallet_balance": wallet_balance}
1339
+ @marshal
1340
+ async def get_wallet_balance(self, request: GetWalletBalance) -> GetWalletBalanceResponse:
1341
+ return GetWalletBalanceResponse(await self._get_wallet_balance(request.wallet_id))
1302
1342
 
1303
- async def get_wallet_balances(self, request: dict[str, Any]) -> EndpointResult:
1304
- try:
1305
- wallet_ids: list[uint32] = [uint32(int(wallet_id)) for wallet_id in request["wallet_ids"]]
1306
- except (TypeError, KeyError):
1343
+ @marshal
1344
+ async def get_wallet_balances(self, request: GetWalletBalances) -> GetWalletBalancesResponse:
1345
+ if request.wallet_ids is not None:
1346
+ wallet_ids = request.wallet_ids
1347
+ else:
1307
1348
  wallet_ids = list(self.service.wallet_state_manager.wallets.keys())
1308
- wallet_balances: dict[uint32, dict[str, Any]] = {}
1309
- for wallet_id in wallet_ids:
1310
- wallet_balances[wallet_id] = await self._get_wallet_balance(wallet_id)
1311
- return {"wallet_balances": wallet_balances}
1349
+ return GetWalletBalancesResponse(
1350
+ {wallet_id: await self._get_wallet_balance(wallet_id) for wallet_id in wallet_ids}
1351
+ )
1312
1352
 
1313
- async def get_transaction(self, request: dict[str, Any]) -> EndpointResult:
1314
- transaction_id: bytes32 = bytes32.from_hexstr(request["transaction_id"])
1315
- tr: Optional[TransactionRecord] = await self.service.wallet_state_manager.get_transaction(transaction_id)
1353
+ @marshal
1354
+ async def get_transaction(self, request: GetTransaction) -> GetTransactionResponse:
1355
+ tr: Optional[TransactionRecord] = await self.service.wallet_state_manager.get_transaction(
1356
+ request.transaction_id
1357
+ )
1316
1358
  if tr is None:
1317
- raise ValueError(f"Transaction 0x{transaction_id.hex()} not found")
1359
+ raise ValueError(f"Transaction 0x{request.transaction_id.hex()} not found")
1318
1360
 
1319
- return {
1320
- "transaction": (await self._convert_tx_puzzle_hash(tr)).to_json_dict_convenience(self.service.config),
1321
- "transaction_id": tr.name,
1322
- }
1361
+ return GetTransactionResponse(
1362
+ await self._convert_tx_puzzle_hash(tr),
1363
+ tr.name,
1364
+ )
1323
1365
 
1324
- async def get_transaction_memo(self, request: dict[str, Any]) -> EndpointResult:
1325
- transaction_id: bytes32 = bytes32.from_hexstr(request["transaction_id"])
1366
+ @marshal
1367
+ async def get_transaction_memo(self, request: GetTransactionMemo) -> GetTransactionMemoResponse:
1368
+ transaction_id: bytes32 = request.transaction_id
1326
1369
  tr: Optional[TransactionRecord] = await self.service.wallet_state_manager.get_transaction(transaction_id)
1327
1370
  if tr is None:
1328
1371
  raise ValueError(f"Transaction 0x{transaction_id.hex()} not found")
@@ -1340,12 +1383,7 @@ class WalletRpcApi:
1340
1383
  else:
1341
1384
  raise ValueError(f"Transaction 0x{transaction_id.hex()} doesn't have any coin spend.")
1342
1385
  assert tr.spend_bundle is not None
1343
- memos: dict[bytes32, list[bytes]] = compute_memos(tr.spend_bundle)
1344
- response = {}
1345
- # Convert to hex string
1346
- for coin_id, memo_list in memos.items():
1347
- response[coin_id.hex()] = [memo.hex() for memo in memo_list]
1348
- return {transaction_id.hex(): response}
1386
+ return GetTransactionMemoResponse({transaction_id: compute_memos(tr.spend_bundle)})
1349
1387
 
1350
1388
  @tx_endpoint(push=False)
1351
1389
  @marshal
@@ -1502,36 +1540,26 @@ class WalletRpcApi:
1502
1540
 
1503
1541
  return CombineCoinsResponse([], []) # tx_endpoint will take care to fill this out
1504
1542
 
1505
- async def get_transactions(self, request: dict[str, Any]) -> EndpointResult:
1506
- wallet_id = int(request["wallet_id"])
1507
-
1508
- start = request.get("start", 0)
1509
- end = request.get("end", 50)
1510
- sort_key = request.get("sort_key", None)
1511
- reverse = request.get("reverse", False)
1512
-
1513
- to_address = request.get("to_address", None)
1543
+ @marshal
1544
+ async def get_transactions(self, request: GetTransactions) -> GetTransactionsResponse:
1514
1545
  to_puzzle_hash: Optional[bytes32] = None
1515
- if to_address is not None:
1516
- to_puzzle_hash = decode_puzzle_hash(to_address)
1517
- type_filter = None
1518
- if "type_filter" in request:
1519
- type_filter = TransactionTypeFilter.from_json_dict(request["type_filter"])
1546
+ if request.to_address is not None:
1547
+ to_puzzle_hash = decode_puzzle_hash(request.to_address)
1520
1548
 
1521
1549
  transactions = await self.service.wallet_state_manager.tx_store.get_transactions_between(
1522
- wallet_id,
1523
- start,
1524
- end,
1525
- sort_key=sort_key,
1526
- reverse=reverse,
1550
+ wallet_id=request.wallet_id,
1551
+ start=uint16(0) if request.start is None else request.start,
1552
+ end=uint16(50) if request.end is None else request.end,
1553
+ sort_key=request.sort_key,
1554
+ reverse=request.reverse,
1527
1555
  to_puzzle_hash=to_puzzle_hash,
1528
- type_filter=type_filter,
1529
- confirmed=request.get("confirmed", None),
1556
+ type_filter=request.type_filter,
1557
+ confirmed=request.confirmed,
1530
1558
  )
1531
1559
  tx_list = []
1532
1560
  # Format for clawback transactions
1533
1561
  for tr in transactions:
1534
- tx = (await self._convert_tx_puzzle_hash(tr)).to_json_dict_convenience(self.service.config)
1562
+ tx = (await self._convert_tx_puzzle_hash(tr)).to_json_dict()
1535
1563
  tx_list.append(tx)
1536
1564
  if tx["type"] not in CLAWBACK_INCOMING_TRANSACTION_TYPES:
1537
1565
  continue
@@ -1549,98 +1577,79 @@ class WalletRpcApi:
1549
1577
  continue
1550
1578
  tx["metadata"]["coin_id"] = coin.name().hex()
1551
1579
  tx["metadata"]["spent"] = record.spent
1552
- return {
1553
- "transactions": tx_list,
1554
- "wallet_id": wallet_id,
1555
- }
1580
+ return GetTransactionsResponse(
1581
+ transactions=[TransactionRecordWithMetadata.from_json_dict(tx) for tx in tx_list],
1582
+ wallet_id=request.wallet_id,
1583
+ )
1556
1584
 
1557
- async def get_transaction_count(self, request: dict[str, Any]) -> EndpointResult:
1558
- wallet_id = int(request["wallet_id"])
1559
- type_filter = None
1560
- if "type_filter" in request:
1561
- type_filter = TransactionTypeFilter.from_json_dict(request["type_filter"])
1585
+ @marshal
1586
+ async def get_transaction_count(self, request: GetTransactionCount) -> GetTransactionCountResponse:
1562
1587
  count = await self.service.wallet_state_manager.tx_store.get_transaction_count_for_wallet(
1563
- wallet_id, confirmed=request.get("confirmed", None), type_filter=type_filter
1588
+ request.wallet_id, confirmed=request.confirmed, type_filter=request.type_filter
1589
+ )
1590
+ return GetTransactionCountResponse(
1591
+ request.wallet_id,
1592
+ uint16(count),
1564
1593
  )
1565
- return {
1566
- "count": count,
1567
- "wallet_id": wallet_id,
1568
- }
1569
1594
 
1570
- async def get_next_address(self, request: dict[str, Any]) -> EndpointResult:
1595
+ @marshal
1596
+ async def get_next_address(self, request: GetNextAddress) -> GetNextAddressResponse:
1571
1597
  """
1572
1598
  Returns a new address
1573
1599
  """
1574
- if request["new_address"] is True:
1575
- create_new = True
1576
- else:
1577
- create_new = False
1578
- wallet_id = uint32(int(request["wallet_id"]))
1579
- wallet = self.service.wallet_state_manager.wallets[wallet_id]
1600
+ wallet = self.service.wallet_state_manager.wallets[request.wallet_id]
1580
1601
  selected = self.service.config["selected_network"]
1581
1602
  prefix = self.service.config["network_overrides"]["config"][selected]["address_prefix"]
1582
1603
  if wallet.type() in {WalletType.STANDARD_WALLET, WalletType.CAT, WalletType.CRCAT, WalletType.RCAT}:
1583
1604
  async with self.service.wallet_state_manager.new_action_scope(
1584
- DEFAULT_TX_CONFIG, push=request.get("save_derivations", True)
1605
+ DEFAULT_TX_CONFIG, push=request.save_derivations
1585
1606
  ) as action_scope:
1586
1607
  raw_puzzle_hash = await action_scope.get_puzzle_hash(
1587
- self.service.wallet_state_manager, override_reuse_puzhash_with=not create_new
1608
+ self.service.wallet_state_manager, override_reuse_puzhash_with=not request.new_address
1588
1609
  )
1589
1610
  address = encode_puzzle_hash(raw_puzzle_hash, prefix)
1590
1611
  else:
1591
1612
  raise ValueError(f"Wallet type {wallet.type()} cannot create puzzle hashes")
1592
1613
 
1593
- return {
1594
- "wallet_id": wallet_id,
1595
- "address": address,
1596
- }
1614
+ return GetNextAddressResponse(
1615
+ request.wallet_id,
1616
+ address,
1617
+ )
1597
1618
 
1598
1619
  @tx_endpoint(push=True)
1620
+ @marshal
1599
1621
  async def send_transaction(
1600
1622
  self,
1601
- request: dict[str, Any],
1623
+ request: SendTransaction,
1602
1624
  action_scope: WalletActionScope,
1603
1625
  extra_conditions: tuple[Condition, ...] = tuple(),
1604
- ) -> EndpointResult:
1626
+ ) -> SendTransactionResponse:
1605
1627
  if await self.service.wallet_state_manager.synced() is False:
1606
1628
  raise ValueError("Wallet needs to be fully synced before sending transactions")
1607
1629
 
1608
- wallet_id = uint32(request["wallet_id"])
1609
- wallet = self.service.wallet_state_manager.get_wallet(id=wallet_id, required_type=Wallet)
1630
+ wallet = self.service.wallet_state_manager.get_wallet(id=request.wallet_id, required_type=Wallet)
1610
1631
 
1611
1632
  # TODO: Add support for multiple puzhash/amount/memo sets
1612
- if not isinstance(request["amount"], int) or not isinstance(request["fee"], int):
1613
- raise ValueError("An integer amount or fee is required (too many decimals)")
1614
- amount: uint64 = uint64(request["amount"])
1615
- address = request["address"]
1616
1633
  selected_network = self.service.config["selected_network"]
1617
1634
  expected_prefix = self.service.config["network_overrides"]["config"][selected_network]["address_prefix"]
1618
- if address[0 : len(expected_prefix)] != expected_prefix:
1635
+ if request.address[0 : len(expected_prefix)] != expected_prefix:
1619
1636
  raise ValueError("Unexpected Address Prefix")
1620
- puzzle_hash: bytes32 = decode_puzzle_hash(address)
1621
-
1622
- memos: list[bytes] = []
1623
- if "memos" in request:
1624
- memos = [mem.encode("utf-8") for mem in request["memos"]]
1625
-
1626
- fee: uint64 = uint64(request.get("fee", 0))
1627
1637
 
1628
1638
  await wallet.generate_signed_transaction(
1629
- [amount],
1630
- [puzzle_hash],
1639
+ [request.amount],
1640
+ [decode_puzzle_hash(request.address)],
1631
1641
  action_scope,
1632
- fee,
1633
- memos=[memos],
1634
- puzzle_decorator_override=request.get("puzzle_decorator", None),
1642
+ request.fee,
1643
+ memos=[[mem.encode("utf-8") for mem in request.memos]],
1644
+ puzzle_decorator_override=[request.puzzle_decorator[0].to_json_dict()]
1645
+ if request.puzzle_decorator is not None
1646
+ else None,
1635
1647
  extra_conditions=extra_conditions,
1636
1648
  )
1637
1649
 
1638
1650
  # Transaction may not have been included in the mempool yet. Use get_transaction to check.
1639
- return {
1640
- "transaction": None, # tx_endpoint wrapper will take care of this
1641
- "transactions": None, # tx_endpoint wrapper will take care of this
1642
- "transaction_id": None, # tx_endpoint wrapper will take care of this
1643
- }
1651
+ # tx_endpoint will take care of the default values here
1652
+ return SendTransactionResponse([], [], transaction=REPLACEABLE_TRANSACTION_RECORD, transaction_id=bytes32.zeros)
1644
1653
 
1645
1654
  async def send_transaction_multi(self, request: dict[str, Any]) -> EndpointResult:
1646
1655
  if await self.service.wallet_state_manager.synced() is False:
@@ -1667,18 +1676,19 @@ class WalletRpcApi:
1667
1676
  # Transaction may not have been included in the mempool yet. Use get_transaction to check.
1668
1677
  return {
1669
1678
  "transaction": transaction,
1670
- "transaction_id": TransactionRecord.from_json_dict_convenience(transaction).name,
1679
+ "transaction_id": TransactionRecord.from_json_dict(transaction).name,
1671
1680
  "transactions": transactions,
1672
1681
  "unsigned_transactions": response["unsigned_transactions"],
1673
1682
  }
1674
1683
 
1675
1684
  @tx_endpoint(push=True, merge_spends=False)
1685
+ @marshal
1676
1686
  async def spend_clawback_coins(
1677
1687
  self,
1678
- request: dict[str, Any],
1688
+ request: SpendClawbackCoins,
1679
1689
  action_scope: WalletActionScope,
1680
1690
  extra_conditions: tuple[Condition, ...] = tuple(),
1681
- ) -> EndpointResult:
1691
+ ) -> SpendClawbackCoinsResponse:
1682
1692
  """Spend clawback coins that were sent (to claw them back) or received (to claim them).
1683
1693
 
1684
1694
  :param coin_ids: list of coin ids to be spent
@@ -1686,21 +1696,19 @@ class WalletRpcApi:
1686
1696
  :param fee: transaction fee in mojos
1687
1697
  :return:
1688
1698
  """
1689
- if "coin_ids" not in request:
1690
- raise ValueError("Coin IDs are required.")
1691
- coin_ids: list[bytes32] = [bytes32.from_hexstr(coin) for coin in request["coin_ids"]]
1692
- tx_fee: uint64 = uint64(request.get("fee", 0))
1693
1699
  # Get inner puzzle
1694
1700
  coin_records = await self.service.wallet_state_manager.coin_store.get_coin_records(
1695
- coin_id_filter=HashFilter.include(coin_ids),
1701
+ coin_id_filter=HashFilter.include(request.coin_ids),
1696
1702
  coin_type=CoinType.CLAWBACK,
1697
1703
  wallet_type=WalletType.STANDARD_WALLET,
1698
1704
  spent_range=UInt32Range(stop=uint32(0)),
1699
1705
  )
1700
1706
 
1701
1707
  coins: dict[Coin, ClawbackMetadata] = {}
1702
- batch_size = request.get(
1703
- "batch_size", self.service.wallet_state_manager.config.get("auto_claim", {}).get("batch_size", 50)
1708
+ batch_size = (
1709
+ request.batch_size
1710
+ if request.batch_size is not None
1711
+ else self.service.wallet_state_manager.config.get("auto_claim", {}).get("batch_size", 50)
1704
1712
  )
1705
1713
  for coin_id, coin_record in coin_records.coin_id_to_record.items():
1706
1714
  try:
@@ -1710,9 +1718,9 @@ class WalletRpcApi:
1710
1718
  if len(coins) >= batch_size:
1711
1719
  await self.service.wallet_state_manager.spend_clawback_coins(
1712
1720
  coins,
1713
- tx_fee,
1721
+ request.fee,
1714
1722
  action_scope,
1715
- request.get("force", False),
1723
+ request.force,
1716
1724
  extra_conditions=extra_conditions,
1717
1725
  )
1718
1726
  coins = {}
@@ -1721,101 +1729,87 @@ class WalletRpcApi:
1721
1729
  if len(coins) > 0:
1722
1730
  await self.service.wallet_state_manager.spend_clawback_coins(
1723
1731
  coins,
1724
- tx_fee,
1732
+ request.fee,
1725
1733
  action_scope,
1726
- request.get("force", False),
1734
+ request.force,
1727
1735
  extra_conditions=extra_conditions,
1728
1736
  )
1729
1737
 
1730
- return {
1731
- "success": True,
1732
- "transaction_ids": None, # tx_endpoint wrapper will take care of this
1733
- "transactions": None, # tx_endpoint wrapper will take care of this
1734
- }
1738
+ # tx_endpoint will fill in the default values here
1739
+ return SpendClawbackCoinsResponse([], [], transaction_ids=[])
1735
1740
 
1736
- async def delete_unconfirmed_transactions(self, request: dict[str, Any]) -> EndpointResult:
1737
- wallet_id = uint32(request["wallet_id"])
1738
- if wallet_id not in self.service.wallet_state_manager.wallets:
1739
- raise ValueError(f"Wallet id {wallet_id} does not exist")
1741
+ @marshal
1742
+ async def delete_unconfirmed_transactions(self, request: DeleteUnconfirmedTransactions) -> Empty:
1743
+ if request.wallet_id not in self.service.wallet_state_manager.wallets:
1744
+ raise ValueError(f"Wallet id {request.wallet_id} does not exist")
1740
1745
  if await self.service.wallet_state_manager.synced() is False:
1741
1746
  raise ValueError("Wallet needs to be fully synced.")
1742
1747
 
1743
1748
  async with self.service.wallet_state_manager.db_wrapper.writer():
1744
- await self.service.wallet_state_manager.tx_store.delete_unconfirmed_transactions(wallet_id)
1745
- wallet = self.service.wallet_state_manager.wallets[wallet_id]
1749
+ await self.service.wallet_state_manager.tx_store.delete_unconfirmed_transactions(request.wallet_id)
1750
+ wallet = self.service.wallet_state_manager.wallets[request.wallet_id]
1746
1751
  if wallet.type() == WalletType.POOLING_WALLET.value:
1747
1752
  assert isinstance(wallet, PoolWallet)
1748
1753
  wallet.target_state = None
1749
- return {}
1754
+ return Empty()
1750
1755
 
1756
+ @marshal
1751
1757
  async def select_coins(
1752
1758
  self,
1753
- request: dict[str, Any],
1754
- ) -> EndpointResult:
1759
+ request: SelectCoins,
1760
+ ) -> SelectCoinsResponse:
1755
1761
  assert self.service.logged_in_fingerprint is not None
1756
- tx_config_loader: TXConfigLoader = TXConfigLoader.from_json_dict(request)
1757
1762
 
1758
1763
  # Some backwards compat fill-ins
1759
- if tx_config_loader.excluded_coin_ids is None:
1760
- excluded_coins: Optional[list[dict[str, Any]]] = request.get("excluded_coins", request.get("exclude_coins"))
1761
- if excluded_coins is not None:
1762
- tx_config_loader = tx_config_loader.override(
1763
- excluded_coin_ids=[Coin.from_json_dict(c).name() for c in excluded_coins],
1764
+ if request.excluded_coin_ids is None:
1765
+ if request.exclude_coins is not None:
1766
+ request = request.override(
1767
+ excluded_coin_ids=[c.name() for c in request.exclude_coins],
1768
+ exclude_coins=None,
1764
1769
  )
1765
1770
 
1766
- tx_config: TXConfig = tx_config_loader.autofill(
1771
+ # don't love this snippet of code
1772
+ # but I think action scopes need to accept CoinSelectionConfigs
1773
+ # instead of solely TXConfigs in order for this to be less ugly
1774
+ autofilled_cs_config = request.autofill(
1767
1775
  constants=self.service.wallet_state_manager.constants,
1768
1776
  )
1777
+ tx_config = DEFAULT_TX_CONFIG.override(
1778
+ **{
1779
+ field.name: getattr(autofilled_cs_config, field.name)
1780
+ for field in dataclasses.fields(autofilled_cs_config)
1781
+ }
1782
+ )
1769
1783
 
1770
1784
  if await self.service.wallet_state_manager.synced() is False:
1771
1785
  raise ValueError("Wallet needs to be fully synced before selecting coins")
1772
1786
 
1773
- amount = uint64(request["amount"])
1774
- wallet_id = uint32(request["wallet_id"])
1775
-
1776
- wallet = self.service.wallet_state_manager.wallets[wallet_id]
1787
+ wallet = self.service.wallet_state_manager.wallets[request.wallet_id]
1777
1788
  async with self.service.wallet_state_manager.new_action_scope(tx_config, push=False) as action_scope:
1778
- selected_coins = await wallet.select_coins(amount, action_scope)
1789
+ selected_coins = await wallet.select_coins(request.amount, action_scope)
1779
1790
 
1780
- return {"coins": [coin.to_json_dict() for coin in selected_coins]}
1791
+ return SelectCoinsResponse(coins=list(selected_coins))
1781
1792
 
1782
- async def get_spendable_coins(self, request: dict[str, Any]) -> EndpointResult:
1793
+ @marshal
1794
+ async def get_spendable_coins(self, request: GetSpendableCoins) -> GetSpendableCoinsResponse:
1783
1795
  if await self.service.wallet_state_manager.synced() is False:
1784
1796
  raise ValueError("Wallet needs to be fully synced before getting all coins")
1785
1797
 
1786
- wallet_id = uint32(request["wallet_id"])
1787
- min_coin_amount = uint64(request.get("min_coin_amount", 0))
1788
- max_coin_amount: uint64 = uint64(request.get("max_coin_amount", 0))
1789
- if max_coin_amount == 0:
1790
- max_coin_amount = uint64(self.service.wallet_state_manager.constants.MAX_COIN_AMOUNT)
1791
- excluded_coin_amounts: Optional[list[uint64]] = request.get("excluded_coin_amounts")
1792
- if excluded_coin_amounts is not None:
1793
- excluded_coin_amounts = [uint64(a) for a in excluded_coin_amounts]
1794
- else:
1795
- excluded_coin_amounts = []
1796
- excluded_coins_input: Optional[dict[str, dict[str, Any]]] = request.get("excluded_coins")
1797
- if excluded_coins_input is not None:
1798
- excluded_coins = [Coin.from_json_dict(json_coin) for json_coin in excluded_coins_input.values()]
1799
- else:
1800
- excluded_coins = []
1801
- excluded_coin_ids_input: Optional[list[str]] = request.get("excluded_coin_ids")
1802
- if excluded_coin_ids_input is not None:
1803
- excluded_coin_ids = [bytes32.from_hexstr(hex_id) for hex_id in excluded_coin_ids_input]
1804
- else:
1805
- excluded_coin_ids = []
1806
1798
  state_mgr = self.service.wallet_state_manager
1807
- wallet = state_mgr.wallets[wallet_id]
1799
+ wallet = state_mgr.wallets[request.wallet_id]
1808
1800
  async with state_mgr.lock:
1809
- all_coin_records = await state_mgr.coin_store.get_unspent_coins_for_wallet(wallet_id)
1801
+ all_coin_records = await state_mgr.coin_store.get_unspent_coins_for_wallet(request.wallet_id)
1810
1802
  if wallet.type() in {WalletType.CAT, WalletType.CRCAT, WalletType.RCAT}:
1811
1803
  assert isinstance(wallet, CATWallet)
1812
1804
  spendable_coins: list[WalletCoinRecord] = await wallet.get_cat_spendable_coins(all_coin_records)
1813
1805
  else:
1814
- spendable_coins = list(await state_mgr.get_spendable_coins_for_wallet(wallet_id, all_coin_records))
1806
+ spendable_coins = list(
1807
+ await state_mgr.get_spendable_coins_for_wallet(request.wallet_id, all_coin_records)
1808
+ )
1815
1809
 
1816
1810
  # Now we get the unconfirmed transactions and manually derive the additions and removals.
1817
1811
  unconfirmed_transactions: list[TransactionRecord] = await state_mgr.tx_store.get_unconfirmed_for_wallet(
1818
- wallet_id
1812
+ request.wallet_id
1819
1813
  )
1820
1814
  unconfirmed_removal_ids: dict[bytes32, uint64] = {
1821
1815
  coin.name(): transaction.created_at_time
@@ -1826,54 +1820,54 @@ class WalletRpcApi:
1826
1820
  coin
1827
1821
  for transaction in unconfirmed_transactions
1828
1822
  for coin in transaction.additions
1829
- if await state_mgr.does_coin_belong_to_wallet(coin, wallet_id)
1823
+ if await state_mgr.does_coin_belong_to_wallet(coin, request.wallet_id)
1830
1824
  ]
1831
1825
  valid_spendable_cr: list[CoinRecord] = []
1832
1826
  unconfirmed_removals: list[CoinRecord] = []
1833
1827
  for coin_record in all_coin_records:
1834
1828
  if coin_record.name() in unconfirmed_removal_ids:
1835
1829
  unconfirmed_removals.append(coin_record.to_coin_record(unconfirmed_removal_ids[coin_record.name()]))
1830
+
1831
+ cs_config = request.autofill(constants=self.service.wallet_state_manager.constants)
1836
1832
  for coin_record in spendable_coins: # remove all the unconfirmed coins, exclude coins and dust.
1837
1833
  if coin_record.name() in unconfirmed_removal_ids:
1838
1834
  continue
1839
- if coin_record.coin in excluded_coins:
1835
+ if coin_record.coin.name() in cs_config.excluded_coin_ids:
1840
1836
  continue
1841
- if coin_record.name() in excluded_coin_ids:
1842
- continue
1843
- if coin_record.coin.amount < min_coin_amount or coin_record.coin.amount > max_coin_amount:
1837
+ if (coin_record.coin.amount < cs_config.min_coin_amount) or (
1838
+ coin_record.coin.amount > cs_config.max_coin_amount
1839
+ ):
1844
1840
  continue
1845
- if coin_record.coin.amount in excluded_coin_amounts:
1841
+ if coin_record.coin.amount in cs_config.excluded_coin_amounts:
1846
1842
  continue
1847
1843
  c_r = await state_mgr.get_coin_record_by_wallet_record(coin_record)
1848
1844
  assert c_r is not None and c_r.coin == coin_record.coin # this should never happen
1849
1845
  valid_spendable_cr.append(c_r)
1850
1846
 
1851
- return {
1852
- "confirmed_records": [cr.to_json_dict() for cr in valid_spendable_cr],
1853
- "unconfirmed_removals": [cr.to_json_dict() for cr in unconfirmed_removals],
1854
- "unconfirmed_additions": [coin.to_json_dict() for coin in unconfirmed_additions],
1855
- }
1847
+ return GetSpendableCoinsResponse(
1848
+ confirmed_records=valid_spendable_cr,
1849
+ unconfirmed_removals=unconfirmed_removals,
1850
+ unconfirmed_additions=unconfirmed_additions,
1851
+ )
1856
1852
 
1857
- async def get_coin_records_by_names(self, request: dict[str, Any]) -> EndpointResult:
1853
+ @marshal
1854
+ async def get_coin_records_by_names(self, request: GetCoinRecordsByNames) -> GetCoinRecordsByNamesResponse:
1858
1855
  if await self.service.wallet_state_manager.synced() is False:
1859
1856
  raise ValueError("Wallet needs to be fully synced before finding coin information")
1860
1857
 
1861
- if "names" not in request:
1862
- raise ValueError("Names not in request")
1863
- coin_ids = [bytes32.from_hexstr(name) for name in request["names"]]
1864
1858
  kwargs: dict[str, Any] = {
1865
- "coin_id_filter": HashFilter.include(coin_ids),
1859
+ "coin_id_filter": HashFilter.include(request.names),
1866
1860
  }
1867
1861
 
1868
1862
  confirmed_range = UInt32Range()
1869
- if "start_height" in request:
1870
- confirmed_range = dataclasses.replace(confirmed_range, start=uint32(request["start_height"]))
1871
- if "end_height" in request:
1872
- confirmed_range = dataclasses.replace(confirmed_range, stop=uint32(request["end_height"]))
1863
+ if request.start_height is not None:
1864
+ confirmed_range = dataclasses.replace(confirmed_range, start=request.start_height)
1865
+ if request.end_height is not None:
1866
+ confirmed_range = dataclasses.replace(confirmed_range, stop=request.end_height)
1873
1867
  if confirmed_range != UInt32Range():
1874
1868
  kwargs["confirmed_range"] = confirmed_range
1875
1869
 
1876
- if "include_spent_coins" in request and not str2bool(request["include_spent_coins"]):
1870
+ if not request.include_spent_coins:
1877
1871
  kwargs["spent_range"] = unspent_range
1878
1872
 
1879
1873
  async with self.service.wallet_state_manager.lock:
@@ -1881,33 +1875,30 @@ class WalletRpcApi:
1881
1875
  **kwargs
1882
1876
  )
1883
1877
  missed_coins: list[str] = [
1884
- "0x" + c_id.hex() for c_id in coin_ids if c_id not in [cr.name for cr in coin_records]
1878
+ "0x" + c_id.hex() for c_id in request.names if c_id not in [cr.name for cr in coin_records]
1885
1879
  ]
1886
1880
  if missed_coins:
1887
1881
  raise ValueError(f"Coin ID's: {missed_coins} not found.")
1888
1882
 
1889
- return {"coin_records": [cr.to_json_dict() for cr in coin_records]}
1883
+ return GetCoinRecordsByNamesResponse(coin_records)
1890
1884
 
1891
- async def get_current_derivation_index(self, request: dict[str, Any]) -> dict[str, Any]:
1885
+ @marshal
1886
+ async def get_current_derivation_index(self, request: Empty) -> GetCurrentDerivationIndexResponse:
1892
1887
  assert self.service.wallet_state_manager is not None
1893
1888
 
1894
1889
  index: Optional[uint32] = await self.service.wallet_state_manager.puzzle_store.get_last_derivation_path()
1895
1890
 
1896
- return {"success": True, "index": index}
1891
+ return GetCurrentDerivationIndexResponse(index)
1897
1892
 
1898
- async def extend_derivation_index(self, request: dict[str, Any]) -> dict[str, Any]:
1893
+ @marshal
1894
+ async def extend_derivation_index(self, request: ExtendDerivationIndex) -> ExtendDerivationIndexResponse:
1899
1895
  assert self.service.wallet_state_manager is not None
1900
1896
 
1901
- # Require a new max derivation index
1902
- if "index" not in request:
1903
- raise ValueError("Derivation index is required")
1904
-
1905
1897
  # Require that the wallet is fully synced
1906
1898
  synced = await self.service.wallet_state_manager.synced()
1907
1899
  if synced is False:
1908
1900
  raise ValueError("Wallet needs to be fully synced before extending derivation index")
1909
1901
 
1910
- index = uint32(request["index"])
1911
1902
  current: Optional[uint32] = await self.service.wallet_state_manager.puzzle_store.get_last_derivation_path()
1912
1903
 
1913
1904
  # Additional sanity check that the wallet is synced
@@ -1915,10 +1906,10 @@ class WalletRpcApi:
1915
1906
  raise ValueError("No current derivation record found, unable to extend index")
1916
1907
 
1917
1908
  # Require that the new index is greater than the current index
1918
- if index <= current:
1909
+ if request.index <= current:
1919
1910
  raise ValueError(f"New derivation index must be greater than current index: {current}")
1920
1911
 
1921
- if index - current > MAX_DERIVATION_INDEX_DELTA:
1912
+ if request.index - current > MAX_DERIVATION_INDEX_DELTA:
1922
1913
  raise ValueError(
1923
1914
  "Too many derivations requested. "
1924
1915
  f"Use a derivation index less than {current + MAX_DERIVATION_INDEX_DELTA + 1}"
@@ -1928,14 +1919,13 @@ class WalletRpcApi:
1928
1919
  # to preserve the current last used index, so we call create_more_puzzle_hashes with
1929
1920
  # mark_existing_as_used=False
1930
1921
  result = await self.service.wallet_state_manager.create_more_puzzle_hashes(
1931
- from_zero=False, mark_existing_as_used=False, up_to_index=index, num_additional_phs=0
1922
+ from_zero=False, mark_existing_as_used=False, up_to_index=request.index, num_additional_phs=0
1932
1923
  )
1933
1924
  await result.commit(self.service.wallet_state_manager)
1934
1925
 
1935
- updated: Optional[uint32] = await self.service.wallet_state_manager.puzzle_store.get_last_derivation_path()
1936
- updated_index = updated if updated is not None else None
1926
+ updated_index = await self.service.wallet_state_manager.puzzle_store.get_last_derivation_path()
1937
1927
 
1938
- return {"success": True, "index": updated_index}
1928
+ return ExtendDerivationIndexResponse(updated_index)
1939
1929
 
1940
1930
  @marshal
1941
1931
  async def get_notifications(self, request: GetNotifications) -> GetNotificationsResponse:
@@ -1954,145 +1944,132 @@ class WalletRpcApi:
1954
1944
 
1955
1945
  return GetNotificationsResponse(notifications)
1956
1946
 
1957
- async def delete_notifications(self, request: dict[str, Any]) -> EndpointResult:
1958
- ids: Optional[list[str]] = request.get("ids", None)
1959
- if ids is None:
1947
+ @marshal
1948
+ async def delete_notifications(self, request: DeleteNotifications) -> Empty:
1949
+ if request.ids is None:
1960
1950
  await self.service.wallet_state_manager.notification_manager.notification_store.delete_all_notifications()
1961
1951
  else:
1962
1952
  await self.service.wallet_state_manager.notification_manager.notification_store.delete_notifications(
1963
- [bytes32.from_hexstr(id) for id in ids]
1953
+ request.ids
1964
1954
  )
1965
1955
 
1966
- return {}
1956
+ return Empty()
1967
1957
 
1968
1958
  @tx_endpoint(push=True)
1959
+ @marshal
1969
1960
  async def send_notification(
1970
1961
  self,
1971
- request: dict[str, Any],
1962
+ request: SendNotification,
1972
1963
  action_scope: WalletActionScope,
1973
1964
  extra_conditions: tuple[Condition, ...] = tuple(),
1974
- ) -> EndpointResult:
1965
+ ) -> SendNotificationResponse:
1975
1966
  await self.service.wallet_state_manager.notification_manager.send_new_notification(
1976
- bytes32.from_hexstr(request["target"]),
1977
- bytes.fromhex(request["message"]),
1978
- uint64(request["amount"]),
1967
+ request.target,
1968
+ request.message,
1969
+ request.amount,
1979
1970
  action_scope,
1980
- request.get("fee", uint64(0)),
1971
+ request.fee,
1981
1972
  extra_conditions=extra_conditions,
1982
1973
  )
1983
1974
 
1984
- return {"tx": None, "transactions": None} # tx_endpoint wrapper will take care of this
1975
+ # tx_endpoint will take care of these default values
1976
+ return SendNotificationResponse([], [], tx=REPLACEABLE_TRANSACTION_RECORD)
1985
1977
 
1986
- async def verify_signature(self, request: dict[str, Any]) -> EndpointResult:
1978
+ @marshal
1979
+ async def verify_signature(self, request: VerifySignature) -> VerifySignatureResponse:
1987
1980
  """
1988
1981
  Given a public key, message and signature, verify if it is valid.
1989
1982
  :param request:
1990
1983
  :return:
1991
1984
  """
1992
- input_message: str = request["message"]
1993
- signing_mode_str: Optional[str] = request.get("signing_mode")
1994
1985
  # Default to BLS_MESSAGE_AUGMENTATION_HEX_INPUT as this RPC was originally designed to verify
1995
1986
  # signatures made by `chia keys sign`, which uses BLS_MESSAGE_AUGMENTATION_HEX_INPUT
1996
- if signing_mode_str is None:
1987
+ if request.signing_mode is None:
1997
1988
  signing_mode = SigningMode.BLS_MESSAGE_AUGMENTATION_HEX_INPUT
1998
1989
  else:
1999
1990
  try:
2000
- signing_mode = SigningMode(signing_mode_str)
1991
+ signing_mode = SigningMode(request.signing_mode)
2001
1992
  except ValueError:
2002
- raise ValueError(f"Invalid signing mode: {signing_mode_str!r}")
1993
+ raise ValueError(f"Invalid signing mode: {request.signing_mode!r}")
2003
1994
 
2004
1995
  if signing_mode in {SigningMode.CHIP_0002, SigningMode.CHIP_0002_P2_DELEGATED_CONDITIONS}:
2005
1996
  # CHIP-0002 message signatures are made over the tree hash of:
2006
1997
  # ("Chia Signed Message", message)
2007
- message_to_verify: bytes = Program.to((CHIP_0002_SIGN_MESSAGE_PREFIX, input_message)).get_tree_hash()
1998
+ message_to_verify: bytes = Program.to((CHIP_0002_SIGN_MESSAGE_PREFIX, request.message)).get_tree_hash()
2008
1999
  elif signing_mode == SigningMode.BLS_MESSAGE_AUGMENTATION_HEX_INPUT:
2009
2000
  # Message is expected to be a hex string
2010
- message_to_verify = hexstr_to_bytes(input_message)
2001
+ message_to_verify = hexstr_to_bytes(request.message)
2011
2002
  elif signing_mode == SigningMode.BLS_MESSAGE_AUGMENTATION_UTF8_INPUT:
2012
2003
  # Message is expected to be a UTF-8 string
2013
- message_to_verify = bytes(input_message, "utf-8")
2004
+ message_to_verify = bytes(request.message, "utf-8")
2014
2005
  else:
2015
- raise ValueError(f"Unsupported signing mode: {signing_mode_str!r}")
2006
+ raise ValueError(f"Unsupported signing mode: {request.signing_mode!r}")
2016
2007
 
2017
2008
  # Verify using the BLS message augmentation scheme
2018
2009
  is_valid = AugSchemeMPL.verify(
2019
- G1Element.from_bytes(hexstr_to_bytes(request["pubkey"])),
2010
+ request.pubkey,
2020
2011
  message_to_verify,
2021
- G2Element.from_bytes(hexstr_to_bytes(request["signature"])),
2012
+ request.signature,
2022
2013
  )
2023
- address = request.get("address")
2024
- if address is not None:
2014
+ if request.address is not None:
2025
2015
  # For signatures made by the sign_message_by_address/sign_message_by_id
2026
2016
  # endpoints, the "address" field should contain the p2_address of the NFT/DID
2027
2017
  # that was used to sign the message.
2028
- puzzle_hash: bytes32 = decode_puzzle_hash(address)
2018
+ puzzle_hash: bytes32 = decode_puzzle_hash(request.address)
2029
2019
  expected_puzzle_hash: Optional[bytes32] = None
2030
2020
  if signing_mode == SigningMode.CHIP_0002_P2_DELEGATED_CONDITIONS:
2031
- puzzle = p2_delegated_conditions.puzzle_for_pk(Program.to(hexstr_to_bytes(request["pubkey"])))
2021
+ puzzle = p2_delegated_conditions.puzzle_for_pk(Program.to(request.pubkey))
2032
2022
  expected_puzzle_hash = bytes32(puzzle.get_tree_hash())
2033
2023
  else:
2034
- expected_puzzle_hash = puzzle_hash_for_synthetic_public_key(
2035
- G1Element.from_bytes(hexstr_to_bytes(request["pubkey"]))
2036
- )
2024
+ expected_puzzle_hash = puzzle_hash_for_synthetic_public_key(request.pubkey)
2037
2025
  if puzzle_hash != expected_puzzle_hash:
2038
- return {"isValid": False, "error": "Public key doesn't match the address"}
2026
+ return VerifySignatureResponse(isValid=False, error="Public key doesn't match the address")
2039
2027
  if is_valid:
2040
- return {"isValid": is_valid}
2028
+ return VerifySignatureResponse(isValid=is_valid)
2041
2029
  else:
2042
- return {"isValid": False, "error": "Signature is invalid."}
2030
+ return VerifySignatureResponse(isValid=False, error="Signature is invalid.")
2043
2031
 
2044
- async def sign_message_by_address(self, request: dict[str, Any]) -> EndpointResult:
2032
+ @marshal
2033
+ async def sign_message_by_address(self, request: SignMessageByAddress) -> SignMessageByAddressResponse:
2045
2034
  """
2046
2035
  Given a derived P2 address, sign the message by its private key.
2047
2036
  :param request:
2048
2037
  :return:
2049
2038
  """
2050
- puzzle_hash: bytes32 = decode_puzzle_hash(request["address"])
2051
- is_hex: bool = request.get("is_hex", False)
2052
- if isinstance(is_hex, str):
2053
- is_hex = True if is_hex.lower() == "true" else False
2054
- safe_mode: bool = request.get("safe_mode", True)
2055
- if isinstance(safe_mode, str):
2056
- safe_mode = True if safe_mode.lower() == "true" else False
2039
+ puzzle_hash: bytes32 = decode_puzzle_hash(request.address)
2057
2040
  mode: SigningMode = SigningMode.CHIP_0002
2058
- if is_hex and safe_mode:
2041
+ if request.is_hex and request.safe_mode:
2059
2042
  mode = SigningMode.CHIP_0002_HEX_INPUT
2060
- elif not is_hex and not safe_mode:
2043
+ elif not request.is_hex and not request.safe_mode:
2061
2044
  mode = SigningMode.BLS_MESSAGE_AUGMENTATION_UTF8_INPUT
2062
- elif is_hex and not safe_mode:
2045
+ elif request.is_hex and not request.safe_mode:
2063
2046
  mode = SigningMode.BLS_MESSAGE_AUGMENTATION_HEX_INPUT
2064
2047
  pubkey, signature = await self.service.wallet_state_manager.main_wallet.sign_message(
2065
- request["message"], puzzle_hash, mode
2048
+ request.message, puzzle_hash, mode
2049
+ )
2050
+ return SignMessageByAddressResponse(
2051
+ pubkey=pubkey,
2052
+ signature=signature,
2053
+ signing_mode=mode.value,
2066
2054
  )
2067
- return {
2068
- "success": True,
2069
- "pubkey": str(pubkey),
2070
- "signature": str(signature),
2071
- "signing_mode": mode.value,
2072
- }
2073
2055
 
2074
- async def sign_message_by_id(self, request: dict[str, Any]) -> EndpointResult:
2056
+ @marshal
2057
+ async def sign_message_by_id(self, request: SignMessageByID) -> SignMessageByIDResponse:
2075
2058
  """
2076
2059
  Given a NFT/DID ID, sign the message by the P2 private key.
2077
2060
  :param request:
2078
2061
  :return:
2079
2062
  """
2080
- entity_id: bytes32 = decode_puzzle_hash(request["id"])
2063
+ entity_id: bytes32 = decode_puzzle_hash(request.id)
2081
2064
  selected_wallet: Optional[WalletProtocol[Any]] = None
2082
- is_hex: bool = request.get("is_hex", False)
2083
- if isinstance(is_hex, str):
2084
- is_hex = True if is_hex.lower() == "true" else False
2085
- safe_mode: bool = request.get("safe_mode", True)
2086
- if isinstance(safe_mode, str):
2087
- safe_mode = True if safe_mode.lower() == "true" else False
2088
2065
  mode: SigningMode = SigningMode.CHIP_0002
2089
- if is_hex and safe_mode:
2066
+ if request.is_hex and request.safe_mode:
2090
2067
  mode = SigningMode.CHIP_0002_HEX_INPUT
2091
- elif not is_hex and not safe_mode:
2068
+ elif not request.is_hex and not request.safe_mode:
2092
2069
  mode = SigningMode.BLS_MESSAGE_AUGMENTATION_UTF8_INPUT
2093
- elif is_hex and not safe_mode:
2070
+ elif request.is_hex and not request.safe_mode:
2094
2071
  mode = SigningMode.BLS_MESSAGE_AUGMENTATION_HEX_INPUT
2095
- if is_valid_address(request["id"], {AddressType.DID}, self.service.config):
2072
+ if is_valid_address(request.id, {AddressType.DID}, self.service.config):
2096
2073
  for wallet in self.service.wallet_state_manager.wallets.values():
2097
2074
  if wallet.type() == WalletType.DECENTRALIZED_ID.value:
2098
2075
  assert isinstance(wallet, DIDWallet)
@@ -2101,11 +2078,11 @@ class WalletRpcApi:
2101
2078
  selected_wallet = wallet
2102
2079
  break
2103
2080
  if selected_wallet is None:
2104
- return {"success": False, "error": f"DID for {entity_id.hex()} doesn't exist."}
2081
+ raise ValueError(f"DID for {entity_id.hex()} doesn't exist.")
2105
2082
  assert isinstance(selected_wallet, DIDWallet)
2106
- pubkey, signature = await selected_wallet.sign_message(request["message"], mode)
2083
+ pubkey, signature = await selected_wallet.sign_message(request.message, mode)
2107
2084
  latest_coin_id = (await selected_wallet.get_coin()).name()
2108
- elif is_valid_address(request["id"], {AddressType.NFT}, self.service.config):
2085
+ elif is_valid_address(request.id, {AddressType.NFT}, self.service.config):
2109
2086
  target_nft: Optional[NFTCoinInfo] = None
2110
2087
  for wallet in self.service.wallet_state_manager.wallets.values():
2111
2088
  if wallet.type() == WalletType.NFT.value:
@@ -2116,117 +2093,93 @@ class WalletRpcApi:
2116
2093
  target_nft = nft
2117
2094
  break
2118
2095
  if selected_wallet is None or target_nft is None:
2119
- return {"success": False, "error": f"NFT for {entity_id.hex()} doesn't exist."}
2096
+ raise ValueError(f"NFT for {entity_id.hex()} doesn't exist.")
2120
2097
 
2121
2098
  assert isinstance(selected_wallet, NFTWallet)
2122
- pubkey, signature = await selected_wallet.sign_message(request["message"], target_nft, mode)
2099
+ pubkey, signature = await selected_wallet.sign_message(request.message, target_nft, mode)
2123
2100
  latest_coin_id = target_nft.coin.name()
2124
2101
  else:
2125
- return {"success": False, "error": f"Unknown ID type, {request['id']}"}
2102
+ raise ValueError(f"Unknown ID type, {request.id}")
2126
2103
 
2127
- return {
2128
- "success": True,
2129
- "pubkey": str(pubkey),
2130
- "signature": str(signature),
2131
- "latest_coin_id": latest_coin_id.hex() if latest_coin_id is not None else None,
2132
- "signing_mode": mode.value,
2133
- }
2104
+ return SignMessageByIDResponse(
2105
+ pubkey=pubkey,
2106
+ signature=signature,
2107
+ latest_coin_id=latest_coin_id,
2108
+ signing_mode=mode.value,
2109
+ )
2134
2110
 
2135
2111
  ##########################################################################################
2136
2112
  # CATs and Trading
2137
2113
  ##########################################################################################
2138
2114
 
2139
- async def get_cat_list(self, request: dict[str, Any]) -> EndpointResult:
2140
- return {"cat_list": list(DEFAULT_CATS.values())}
2115
+ @marshal
2116
+ async def get_cat_list(self, request: Empty) -> GetCATListResponse:
2117
+ return GetCATListResponse([DefaultCAT.from_json_dict(default_cat) for default_cat in DEFAULT_CATS.values()])
2141
2118
 
2142
- async def cat_set_name(self, request: dict[str, Any]) -> EndpointResult:
2143
- wallet_id = uint32(request["wallet_id"])
2144
- wallet = self.service.wallet_state_manager.get_wallet(id=wallet_id, required_type=CATWallet)
2145
- await wallet.set_name(str(request["name"]))
2146
- return {"wallet_id": wallet_id}
2119
+ @marshal
2120
+ async def cat_set_name(self, request: CATSetName) -> CATSetNameResponse:
2121
+ wallet = self.service.wallet_state_manager.get_wallet(id=request.wallet_id, required_type=CATWallet)
2122
+ await wallet.set_name(request.name)
2123
+ return CATSetNameResponse(wallet_id=request.wallet_id)
2147
2124
 
2148
- async def cat_get_name(self, request: dict[str, Any]) -> EndpointResult:
2149
- wallet_id = uint32(request["wallet_id"])
2150
- wallet = self.service.wallet_state_manager.get_wallet(id=wallet_id, required_type=CATWallet)
2125
+ @marshal
2126
+ async def cat_get_name(self, request: CATGetName) -> CATGetNameResponse:
2127
+ wallet = self.service.wallet_state_manager.get_wallet(id=request.wallet_id, required_type=CATWallet)
2151
2128
  name: str = wallet.get_name()
2152
- return {"wallet_id": wallet_id, "name": name}
2129
+ return CATGetNameResponse(wallet_id=request.wallet_id, name=name)
2153
2130
 
2154
- async def get_stray_cats(self, request: dict[str, Any]) -> EndpointResult:
2131
+ @marshal
2132
+ async def get_stray_cats(self, request: Empty) -> GetStrayCATsResponse:
2155
2133
  """
2156
2134
  Get a list of all unacknowledged CATs
2157
2135
  :param request: RPC request
2158
2136
  :return: A list of unacknowledged CATs
2159
2137
  """
2160
2138
  cats = await self.service.wallet_state_manager.interested_store.get_unacknowledged_tokens()
2161
- return {"stray_cats": cats}
2139
+ return GetStrayCATsResponse(stray_cats=[StrayCAT.from_json_dict(cat) for cat in cats])
2162
2140
 
2163
2141
  @tx_endpoint(push=True)
2142
+ @marshal
2164
2143
  async def cat_spend(
2165
2144
  self,
2166
- request: dict[str, Any],
2145
+ request: CATSpend,
2167
2146
  action_scope: WalletActionScope,
2168
2147
  extra_conditions: tuple[Condition, ...] = tuple(),
2169
2148
  hold_lock: bool = True,
2170
- ) -> EndpointResult:
2149
+ ) -> CATSpendResponse:
2171
2150
  if await self.service.wallet_state_manager.synced() is False:
2172
2151
  raise ValueError("Wallet needs to be fully synced.")
2173
- wallet_id = uint32(request["wallet_id"])
2174
- wallet = self.service.wallet_state_manager.get_wallet(id=wallet_id, required_type=CATWallet)
2152
+ wallet = self.service.wallet_state_manager.get_wallet(id=request.wallet_id, required_type=CATWallet)
2175
2153
 
2176
2154
  amounts: list[uint64] = []
2177
2155
  puzzle_hashes: list[bytes32] = []
2178
2156
  memos: list[list[bytes]] = []
2179
- additions: Optional[list[dict[str, Any]]] = request.get("additions")
2180
- if not isinstance(request["fee"], int) or (additions is None and not isinstance(request["amount"], int)):
2181
- raise ValueError("An integer amount or fee is required (too many decimals)")
2182
- if additions is not None:
2183
- for addition in additions:
2184
- receiver_ph = bytes32.from_hexstr(addition["puzzle_hash"])
2185
- if len(receiver_ph) != 32:
2186
- raise ValueError(f"Address must be 32 bytes. {receiver_ph.hex()}")
2187
- amount = uint64(addition["amount"])
2188
- if amount > self.service.constants.MAX_COIN_AMOUNT:
2157
+ if request.additions is not None:
2158
+ for addition in request.additions:
2159
+ if addition.amount > self.service.constants.MAX_COIN_AMOUNT:
2189
2160
  raise ValueError(f"Coin amount cannot exceed {self.service.constants.MAX_COIN_AMOUNT}")
2190
- amounts.append(amount)
2191
- puzzle_hashes.append(receiver_ph)
2192
- if "memos" in addition:
2193
- memos.append([mem.encode("utf-8") for mem in addition["memos"]])
2161
+ amounts.append(addition.amount)
2162
+ puzzle_hashes.append(addition.puzzle_hash)
2163
+ if addition.memos is not None:
2164
+ memos.append([mem.encode("utf-8") for mem in addition.memos])
2194
2165
  else:
2195
- amounts.append(uint64(request["amount"]))
2196
- puzzle_hashes.append(decode_puzzle_hash(request["inner_address"]))
2197
- if "memos" in request:
2198
- memos.append([mem.encode("utf-8") for mem in request["memos"]])
2166
+ # Our __post_init__ guards against these not being None
2167
+ amounts.append(request.amount) # type: ignore[arg-type]
2168
+ puzzle_hashes.append(decode_puzzle_hash(request.inner_address)) # type: ignore[arg-type]
2169
+ if request.memos is not None:
2170
+ memos.append([mem.encode("utf-8") for mem in request.memos])
2199
2171
  coins: Optional[set[Coin]] = None
2200
- if "coins" in request and len(request["coins"]) > 0:
2201
- coins = {Coin.from_json_dict(coin_json) for coin_json in request["coins"]}
2202
- fee: uint64 = uint64(request.get("fee", 0))
2172
+ if request.coins is not None and len(request.coins) > 0:
2173
+ coins = set(request.coins)
2203
2174
 
2204
- cat_discrepancy_params: tuple[Optional[int], Optional[str], Optional[str]] = (
2205
- request.get("extra_delta", None),
2206
- request.get("tail_reveal", None),
2207
- request.get("tail_solution", None),
2208
- )
2209
- cat_discrepancy: Optional[tuple[int, Program, Program]] = None
2210
- if cat_discrepancy_params != (None, None, None):
2211
- if None in cat_discrepancy_params:
2212
- raise ValueError("Specifying extra_delta, tail_reveal, or tail_solution requires specifying the others")
2213
- else:
2214
- assert cat_discrepancy_params[0] is not None
2215
- assert cat_discrepancy_params[1] is not None
2216
- assert cat_discrepancy_params[2] is not None
2217
- cat_discrepancy = (
2218
- cat_discrepancy_params[0], # mypy sanitization
2219
- Program.fromhex(cat_discrepancy_params[1]),
2220
- Program.fromhex(cat_discrepancy_params[2]),
2221
- )
2222
2175
  if hold_lock:
2223
2176
  async with self.service.wallet_state_manager.lock:
2224
2177
  await wallet.generate_signed_transaction(
2225
2178
  amounts,
2226
2179
  puzzle_hashes,
2227
2180
  action_scope,
2228
- fee,
2229
- cat_discrepancy=cat_discrepancy,
2181
+ request.fee,
2182
+ cat_discrepancy=request.cat_discrepancy,
2230
2183
  coins=coins,
2231
2184
  memos=memos if memos else None,
2232
2185
  extra_conditions=extra_conditions,
@@ -2236,34 +2189,32 @@ class WalletRpcApi:
2236
2189
  amounts,
2237
2190
  puzzle_hashes,
2238
2191
  action_scope,
2239
- fee,
2240
- cat_discrepancy=cat_discrepancy,
2192
+ request.fee,
2193
+ cat_discrepancy=request.cat_discrepancy,
2241
2194
  coins=coins,
2242
2195
  memos=memos if memos else None,
2243
2196
  extra_conditions=extra_conditions,
2244
2197
  )
2245
2198
 
2246
- return {
2247
- "transaction": None, # tx_endpoint wrapper will take care of this
2248
- "transactions": None, # tx_endpoint wrapper will take care of this
2249
- "transaction_id": None, # tx_endpoint wrapper will take care of this
2250
- }
2199
+ # tx_endpoint will fill in these default values
2200
+ return CATSpendResponse([], [], transaction=REPLACEABLE_TRANSACTION_RECORD, transaction_id=bytes32.zeros)
2251
2201
 
2252
- async def cat_get_asset_id(self, request: dict[str, Any]) -> EndpointResult:
2253
- wallet_id = uint32(request["wallet_id"])
2254
- wallet = self.service.wallet_state_manager.get_wallet(id=wallet_id, required_type=CATWallet)
2202
+ @marshal
2203
+ async def cat_get_asset_id(self, request: CATGetAssetID) -> CATGetAssetIDResponse:
2204
+ wallet = self.service.wallet_state_manager.get_wallet(id=request.wallet_id, required_type=CATWallet)
2255
2205
  asset_id: str = wallet.get_asset_id()
2256
- return {"asset_id": asset_id, "wallet_id": wallet_id}
2206
+ return CATGetAssetIDResponse(asset_id=bytes32.from_hexstr(asset_id), wallet_id=request.wallet_id)
2257
2207
 
2258
- async def cat_asset_id_to_name(self, request: dict[str, Any]) -> EndpointResult:
2259
- wallet = await self.service.wallet_state_manager.get_wallet_for_asset_id(request["asset_id"])
2208
+ @marshal
2209
+ async def cat_asset_id_to_name(self, request: CATAssetIDToName) -> CATAssetIDToNameResponse:
2210
+ wallet = await self.service.wallet_state_manager.get_wallet_for_asset_id(request.asset_id.hex())
2260
2211
  if wallet is None:
2261
- if request["asset_id"] in DEFAULT_CATS:
2262
- return {"wallet_id": None, "name": DEFAULT_CATS[request["asset_id"]]["name"]}
2212
+ if request.asset_id.hex() in DEFAULT_CATS:
2213
+ return CATAssetIDToNameResponse(wallet_id=None, name=DEFAULT_CATS[request.asset_id.hex()]["name"])
2263
2214
  else:
2264
- raise ValueError("The asset ID specified does not belong to a wallet")
2215
+ return CATAssetIDToNameResponse(wallet_id=None, name=None)
2265
2216
  else:
2266
- return {"wallet_id": wallet.id(), "name": (wallet.get_name())}
2217
+ return CATAssetIDToNameResponse(wallet_id=wallet.id(), name=wallet.get_name())
2267
2218
 
2268
2219
  @tx_endpoint(push=False)
2269
2220
  async def create_offer_for_ids(
@@ -2387,15 +2338,14 @@ class WalletRpcApi:
2387
2338
  },
2388
2339
  }
2389
2340
 
2390
- async def check_offer_validity(self, request: dict[str, Any]) -> EndpointResult:
2391
- offer_hex: str = request["offer"]
2392
-
2393
- offer = Offer.from_bech32(offer_hex)
2341
+ @marshal
2342
+ async def check_offer_validity(self, request: CheckOfferValidity) -> CheckOfferValidityResponse:
2343
+ offer = Offer.from_bech32(request.offer)
2394
2344
  peer = self.service.get_full_node_peer()
2395
- return {
2396
- "valid": (await self.service.wallet_state_manager.trade_manager.check_offer_validity(offer, peer)),
2397
- "id": offer.name(),
2398
- }
2345
+ return CheckOfferValidityResponse(
2346
+ valid=(await self.service.wallet_state_manager.trade_manager.check_offer_validity(offer, peer)),
2347
+ id=offer.name(),
2348
+ )
2399
2349
 
2400
2350
  @tx_endpoint(push=True)
2401
2351
  async def take_offer(
@@ -2481,12 +2431,15 @@ class WalletRpcApi:
2481
2431
 
2482
2432
  return {"trade_records": result, "offers": offer_values}
2483
2433
 
2484
- async def get_offers_count(self, request: dict[str, Any]) -> EndpointResult:
2434
+ @marshal
2435
+ async def get_offers_count(self, request: Empty) -> GetOffersCountResponse:
2485
2436
  trade_mgr = self.service.wallet_state_manager.trade_manager
2486
2437
 
2487
2438
  (total, my_offers_count, taken_offers_count) = await trade_mgr.trade_store.get_trades_count()
2488
2439
 
2489
- return {"total": total, "my_offers_count": my_offers_count, "taken_offers_count": taken_offers_count}
2440
+ return GetOffersCountResponse(
2441
+ total=uint16(total), my_offers_count=uint16(my_offers_count), taken_offers_count=uint16(taken_offers_count)
2442
+ )
2490
2443
 
2491
2444
  @tx_endpoint(push=True)
2492
2445
  async def cancel_offer(
@@ -2587,31 +2540,6 @@ class WalletRpcApi:
2587
2540
  wallet = self.service.wallet_state_manager.get_wallet(id=request.wallet_id, required_type=DIDWallet)
2588
2541
  return DIDGetWalletNameResponse(request.wallet_id, wallet.get_name())
2589
2542
 
2590
- @tx_endpoint(push=True)
2591
- @marshal
2592
- async def did_update_recovery_ids(
2593
- self,
2594
- request: DIDUpdateRecoveryIDs,
2595
- action_scope: WalletActionScope,
2596
- extra_conditions: tuple[Condition, ...] = tuple(),
2597
- ) -> DIDUpdateRecoveryIDsResponse:
2598
- wallet = self.service.wallet_state_manager.get_wallet(id=request.wallet_id, required_type=DIDWallet)
2599
- recovery_list = [decode_puzzle_hash(puzzle_hash) for puzzle_hash in request.new_list]
2600
- new_amount_verifications_required = (
2601
- request.num_verifications_required
2602
- if request.num_verifications_required is not None
2603
- else uint64(len(recovery_list))
2604
- )
2605
- async with self.service.wallet_state_manager.lock:
2606
- update_success = await wallet.update_recovery_list(recovery_list, new_amount_verifications_required)
2607
- # Update coin with new ID info
2608
- if update_success:
2609
- await wallet.create_update_spend(action_scope, fee=request.fee, extra_conditions=extra_conditions)
2610
- # tx_endpoint will take care of default values here
2611
- return DIDUpdateRecoveryIDsResponse([], [])
2612
- else:
2613
- raise RuntimeError("updating recovery list failed")
2614
-
2615
2543
  @tx_endpoint(push=False)
2616
2544
  @marshal
2617
2545
  async def did_message_spend(
@@ -2906,68 +2834,14 @@ class WalletRpcApi:
2906
2834
  except RuntimeError:
2907
2835
  return DIDGetDIDResponse(wallet_id=request.wallet_id, my_did=my_did)
2908
2836
 
2909
- @marshal
2910
- async def did_get_recovery_list(self, request: DIDGetRecoveryList) -> DIDGetRecoveryListResponse:
2911
- wallet = self.service.wallet_state_manager.get_wallet(id=request.wallet_id, required_type=DIDWallet)
2912
- recovery_list = wallet.did_info.backup_ids
2913
- recovery_dids = []
2914
- for backup_id in recovery_list:
2915
- recovery_dids.append(encode_puzzle_hash(backup_id, AddressType.DID.hrp(self.service.config)))
2916
- return DIDGetRecoveryListResponse(
2917
- wallet_id=request.wallet_id,
2918
- recovery_list=recovery_dids,
2919
- num_required=uint16(wallet.did_info.num_of_backup_ids_needed),
2920
- )
2921
-
2922
2837
  @marshal
2923
2838
  async def did_get_metadata(self, request: DIDGetMetadata) -> DIDGetMetadataResponse:
2924
2839
  wallet = self.service.wallet_state_manager.get_wallet(id=request.wallet_id, required_type=DIDWallet)
2925
2840
  metadata = json.loads(wallet.did_info.metadata)
2926
- return DIDGetMetadataResponse(wallet_id=request.wallet_id, metadata=metadata)
2927
-
2928
- # TODO: this needs a test
2929
- # Don't need full @tx_endpoint decorator here, but "push" is still a valid option
2930
- async def did_recovery_spend(self, request: dict[str, Any]) -> EndpointResult: # pragma: no cover
2931
- wallet_id = uint32(request["wallet_id"])
2932
- wallet = self.service.wallet_state_manager.get_wallet(id=wallet_id, required_type=DIDWallet)
2933
- if len(request["attest_data"]) < wallet.did_info.num_of_backup_ids_needed:
2934
- return {"success": False, "reason": "insufficient messages"}
2935
- async with self.service.wallet_state_manager.lock:
2936
- (
2937
- info_list,
2938
- message_spend_bundle,
2939
- ) = await wallet.load_attest_files_for_recovery_spend(request["attest_data"])
2940
-
2941
- if "pubkey" in request:
2942
- pubkey = G1Element.from_bytes(hexstr_to_bytes(request["pubkey"]))
2943
- else:
2944
- assert wallet.did_info.temp_pubkey is not None
2945
- pubkey = G1Element.from_bytes(wallet.did_info.temp_pubkey)
2946
-
2947
- if "puzhash" in request:
2948
- puzhash = bytes32.from_hexstr(request["puzhash"])
2949
- else:
2950
- assert wallet.did_info.temp_puzhash is not None
2951
- puzhash = wallet.did_info.temp_puzhash
2952
-
2953
- assert wallet.did_info.temp_coin is not None
2954
- async with self.service.wallet_state_manager.new_action_scope(
2955
- DEFAULT_TX_CONFIG, push=request.get("push", True)
2956
- ) as action_scope:
2957
- await wallet.recovery_spend(
2958
- wallet.did_info.temp_coin,
2959
- puzhash,
2960
- info_list,
2961
- pubkey,
2962
- message_spend_bundle,
2963
- action_scope,
2964
- )
2965
- [tx] = action_scope.side_effects.transactions
2966
- return {
2967
- "success": True,
2968
- "spend_bundle": tx.spend_bundle,
2969
- "transactions": [tx.to_json_dict_convenience(self.service.config)],
2970
- }
2841
+ return DIDGetMetadataResponse(
2842
+ wallet_id=request.wallet_id,
2843
+ metadata=metadata,
2844
+ )
2971
2845
 
2972
2846
  @marshal
2973
2847
  async def did_get_pubkey(self, request: DIDGetPubkey) -> DIDGetPubkeyResponse:
@@ -2976,57 +2850,6 @@ class WalletRpcApi:
2976
2850
  (await wallet.wallet_state_manager.get_unused_derivation_record(request.wallet_id)).pubkey
2977
2851
  )
2978
2852
 
2979
- # TODO: this needs a test
2980
- @tx_endpoint(push=True)
2981
- async def did_create_attest(
2982
- self,
2983
- request: dict[str, Any],
2984
- action_scope: WalletActionScope,
2985
- extra_conditions: tuple[Condition, ...] = tuple(),
2986
- ) -> EndpointResult: # pragma: no cover
2987
- wallet_id = uint32(request["wallet_id"])
2988
- wallet = self.service.wallet_state_manager.get_wallet(id=wallet_id, required_type=DIDWallet)
2989
- async with self.service.wallet_state_manager.lock:
2990
- info = await wallet.get_info_for_recovery()
2991
- coin = bytes32.from_hexstr(request["coin_name"])
2992
- pubkey = G1Element.from_bytes(hexstr_to_bytes(request["pubkey"]))
2993
- message_spend_bundle, attest_data = await wallet.create_attestment(
2994
- coin,
2995
- bytes32.from_hexstr(request["puzhash"]),
2996
- pubkey,
2997
- action_scope,
2998
- extra_conditions=extra_conditions,
2999
- )
3000
- if info is not None:
3001
- return {
3002
- "success": True,
3003
- "message_spend_bundle": bytes(message_spend_bundle).hex(),
3004
- "info": [info[0].hex(), info[1].hex(), info[2]],
3005
- "attest_data": attest_data,
3006
- "transactions": None, # tx_endpoint wrapper will take care of this
3007
- }
3008
- else:
3009
- return {"success": False}
3010
-
3011
- @marshal
3012
- async def did_get_information_needed_for_recovery(self, request: DIDGetRecoveryInfo) -> DIDGetRecoveryInfoResponse:
3013
- did_wallet = self.service.wallet_state_manager.get_wallet(id=request.wallet_id, required_type=DIDWallet)
3014
- my_did = encode_puzzle_hash(
3015
- bytes32.from_hexstr(did_wallet.get_my_DID()), AddressType.DID.hrp(self.service.config)
3016
- )
3017
- assert did_wallet.did_info.temp_coin is not None
3018
- coin_name = did_wallet.did_info.temp_coin.name()
3019
- return DIDGetRecoveryInfoResponse(
3020
- wallet_id=request.wallet_id,
3021
- my_did=my_did,
3022
- coin_name=coin_name,
3023
- newpuzhash=did_wallet.did_info.temp_puzhash,
3024
- pubkey=G1Element.from_bytes(did_wallet.did_info.temp_pubkey)
3025
- if did_wallet.did_info.temp_pubkey is not None
3026
- else None,
3027
- backup_dids=did_wallet.did_info.backup_ids,
3028
- )
3029
-
3030
2853
  @marshal
3031
2854
  async def did_get_current_coin_info(self, request: DIDGetCurrentCoinInfo) -> DIDGetCurrentCoinInfoResponse:
3032
2855
  did_wallet = self.service.wallet_state_manager.get_wallet(id=request.wallet_id, required_type=DIDWallet)
@@ -3034,15 +2857,15 @@ class WalletRpcApi:
3034
2857
  bytes32.from_hexstr(did_wallet.get_my_DID()), AddressType.DID.hrp(self.service.config)
3035
2858
  )
3036
2859
 
3037
- did_coin_threeple = await did_wallet.get_info_for_recovery()
2860
+ assert did_wallet.did_info.current_inner is not None
2861
+ parent_coin = await did_wallet.get_coin()
3038
2862
  assert my_did is not None
3039
- assert did_coin_threeple is not None
3040
2863
  return DIDGetCurrentCoinInfoResponse(
3041
2864
  wallet_id=request.wallet_id,
3042
2865
  my_did=my_did,
3043
- did_parent=did_coin_threeple[0],
3044
- did_innerpuz=did_coin_threeple[1],
3045
- did_amount=did_coin_threeple[2],
2866
+ did_parent=parent_coin.parent_coin_info,
2867
+ did_innerpuz=did_wallet.did_info.current_inner.get_tree_hash(),
2868
+ did_amount=parent_coin.amount,
3046
2869
  )
3047
2870
 
3048
2871
  @marshal
@@ -3066,7 +2889,6 @@ class WalletRpcApi:
3066
2889
  await did_wallet.transfer_did(
3067
2890
  puzzle_hash,
3068
2891
  request.fee,
3069
- request.with_recovery_info,
3070
2892
  action_scope,
3071
2893
  extra_conditions=extra_conditions,
3072
2894
  )
@@ -3664,12 +3486,18 @@ class WalletRpcApi:
3664
3486
  fee_amount = 0
3665
3487
  blocks_won = 0
3666
3488
  last_height_farmed = uint32(0)
3489
+
3490
+ include_pool_rewards = request.get("include_pool_rewards", False)
3491
+
3667
3492
  for record in tx_records:
3668
3493
  if record.wallet_id not in self.service.wallet_state_manager.wallets:
3669
3494
  continue
3670
3495
  if record.type == TransactionType.COINBASE_REWARD.value:
3671
- if self.service.wallet_state_manager.wallets[record.wallet_id].type() == WalletType.POOLING_WALLET:
3672
- # Don't add pool rewards for pool wallets.
3496
+ if (
3497
+ not include_pool_rewards
3498
+ and self.service.wallet_state_manager.wallets[record.wallet_id].type() == WalletType.POOLING_WALLET
3499
+ ):
3500
+ # Don't add pool rewards for pool wallets unless explicitly requested
3673
3501
  continue
3674
3502
  pool_reward_amount += record.amount
3675
3503
  height = record.height_farmed(self.service.constants.GENESIS_CHALLENGE)