meshtrade 1.22.0__tar.gz → 1.23.0__tar.gz
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.
Potentially problematic release.
This version of meshtrade might be problematic. Click here for more details.
- {meshtrade-1.22.0 → meshtrade-1.23.0}/PKG-INFO +1 -1
- {meshtrade-1.22.0 → meshtrade-1.23.0}/pyproject.toml +1 -1
- meshtrade-1.23.0/python/src/meshtrade/compliance/client/v1/client_roles.py +123 -0
- meshtrade-1.23.0/python/src/meshtrade/iam/api_user/v1/api_user_state_machine.py +104 -0
- {meshtrade-1.22.0 → meshtrade-1.23.0}/python/src/meshtrade/iam/role/v1/__init__.py +2 -2
- meshtrade-1.23.0/python/src/meshtrade/iam/role/v1/role.py +174 -0
- meshtrade-1.23.0/python/src/meshtrade/ledger/transaction/v1/transaction_state_machine.py +75 -0
- meshtrade-1.23.0/python/src/meshtrade/reporting/account_report/v1/income_entry.py +35 -0
- meshtrade-1.23.0/python/src/meshtrade/type/v1/amount.py +502 -0
- {meshtrade-1.22.0 → meshtrade-1.23.0}/python/src/meshtrade/type/v1/decimal_built_in_conversions.py +8 -3
- meshtrade-1.23.0/python/src/meshtrade/type/v1/decimal_operations.py +354 -0
- meshtrade-1.23.0/python/src/meshtrade/type/v1/ledger.py +100 -0
- meshtrade-1.23.0/python/src/meshtrade/type/v1/token.py +144 -0
- {meshtrade-1.22.0 → meshtrade-1.23.0}/python/src/meshtrade.egg-info/PKG-INFO +1 -1
- {meshtrade-1.22.0 → meshtrade-1.23.0}/python/src/meshtrade.egg-info/SOURCES.txt +6 -0
- meshtrade-1.22.0/python/src/meshtrade/iam/role/v1/role.py +0 -23
- meshtrade-1.22.0/python/src/meshtrade/type/v1/amount.py +0 -78
- meshtrade-1.22.0/python/src/meshtrade/type/v1/ledger.py +0 -25
- {meshtrade-1.22.0 → meshtrade-1.23.0}/README.md +0 -0
- {meshtrade-1.22.0 → meshtrade-1.23.0}/python/src/buf/validate/validate_pb2.py +0 -0
- {meshtrade-1.22.0 → meshtrade-1.23.0}/python/src/buf/validate/validate_pb2.pyi +0 -0
- {meshtrade-1.22.0 → meshtrade-1.23.0}/python/src/meshtrade/__init__.py +0 -0
- {meshtrade-1.22.0 → meshtrade-1.23.0}/python/src/meshtrade/common/__init__.py +0 -0
- {meshtrade-1.22.0 → meshtrade-1.23.0}/python/src/meshtrade/common/config.py +0 -0
- {meshtrade-1.22.0 → meshtrade-1.23.0}/python/src/meshtrade/common/grpc_client.py +0 -0
- {meshtrade-1.22.0 → meshtrade-1.23.0}/python/src/meshtrade/common/service_options.py +0 -0
- {meshtrade-1.22.0 → meshtrade-1.23.0}/python/src/meshtrade/compliance/__init__.py +0 -0
- {meshtrade-1.22.0 → meshtrade-1.23.0}/python/src/meshtrade/compliance/client/__init__.py +0 -0
- {meshtrade-1.22.0 → meshtrade-1.23.0}/python/src/meshtrade/compliance/client/v1/__init__.py +0 -0
- {meshtrade-1.22.0 → meshtrade-1.23.0}/python/src/meshtrade/compliance/client/v1/client_pb2.py +0 -0
- {meshtrade-1.22.0 → meshtrade-1.23.0}/python/src/meshtrade/compliance/client/v1/client_pb2.pyi +0 -0
- {meshtrade-1.22.0 → meshtrade-1.23.0}/python/src/meshtrade/compliance/client/v1/client_pb2_grpc.py +0 -0
- {meshtrade-1.22.0 → meshtrade-1.23.0}/python/src/meshtrade/compliance/client/v1/company_pb2.py +0 -0
- {meshtrade-1.22.0 → meshtrade-1.23.0}/python/src/meshtrade/compliance/client/v1/company_pb2.pyi +0 -0
- {meshtrade-1.22.0 → meshtrade-1.23.0}/python/src/meshtrade/compliance/client/v1/company_pb2_grpc.py +0 -0
- {meshtrade-1.22.0 → meshtrade-1.23.0}/python/src/meshtrade/compliance/client/v1/company_representative_pb2.py +0 -0
- {meshtrade-1.22.0 → meshtrade-1.23.0}/python/src/meshtrade/compliance/client/v1/company_representative_pb2.pyi +0 -0
- {meshtrade-1.22.0 → meshtrade-1.23.0}/python/src/meshtrade/compliance/client/v1/company_representative_pb2_grpc.py +0 -0
- {meshtrade-1.22.0 → meshtrade-1.23.0}/python/src/meshtrade/compliance/client/v1/company_representative_role_pb2.py +0 -0
- {meshtrade-1.22.0 → meshtrade-1.23.0}/python/src/meshtrade/compliance/client/v1/company_representative_role_pb2.pyi +0 -0
- {meshtrade-1.22.0 → meshtrade-1.23.0}/python/src/meshtrade/compliance/client/v1/company_representative_role_pb2_grpc.py +0 -0
- {meshtrade-1.22.0 → meshtrade-1.23.0}/python/src/meshtrade/compliance/client/v1/fund_pb2.py +0 -0
- {meshtrade-1.22.0 → meshtrade-1.23.0}/python/src/meshtrade/compliance/client/v1/fund_pb2.pyi +0 -0
- {meshtrade-1.22.0 → meshtrade-1.23.0}/python/src/meshtrade/compliance/client/v1/fund_pb2_grpc.py +0 -0
- {meshtrade-1.22.0 → meshtrade-1.23.0}/python/src/meshtrade/compliance/client/v1/identification_document_type_pb2.py +0 -0
- {meshtrade-1.22.0 → meshtrade-1.23.0}/python/src/meshtrade/compliance/client/v1/identification_document_type_pb2.pyi +0 -0
- {meshtrade-1.22.0 → meshtrade-1.23.0}/python/src/meshtrade/compliance/client/v1/identification_document_type_pb2_grpc.py +0 -0
- {meshtrade-1.22.0 → meshtrade-1.23.0}/python/src/meshtrade/compliance/client/v1/industry_classification_pb2.py +0 -0
- {meshtrade-1.22.0 → meshtrade-1.23.0}/python/src/meshtrade/compliance/client/v1/industry_classification_pb2.pyi +0 -0
- {meshtrade-1.22.0 → meshtrade-1.23.0}/python/src/meshtrade/compliance/client/v1/industry_classification_pb2_grpc.py +0 -0
- {meshtrade-1.22.0 → meshtrade-1.23.0}/python/src/meshtrade/compliance/client/v1/natural_person_connection_type_pb2.py +0 -0
- {meshtrade-1.22.0 → meshtrade-1.23.0}/python/src/meshtrade/compliance/client/v1/natural_person_connection_type_pb2.pyi +0 -0
- {meshtrade-1.22.0 → meshtrade-1.23.0}/python/src/meshtrade/compliance/client/v1/natural_person_connection_type_pb2_grpc.py +0 -0
- {meshtrade-1.22.0 → meshtrade-1.23.0}/python/src/meshtrade/compliance/client/v1/natural_person_pb2.py +0 -0
- {meshtrade-1.22.0 → meshtrade-1.23.0}/python/src/meshtrade/compliance/client/v1/natural_person_pb2.pyi +0 -0
- {meshtrade-1.22.0 → meshtrade-1.23.0}/python/src/meshtrade/compliance/client/v1/natural_person_pb2_grpc.py +0 -0
- {meshtrade-1.22.0 → meshtrade-1.23.0}/python/src/meshtrade/compliance/client/v1/pep_status_pb2.py +0 -0
- {meshtrade-1.22.0 → meshtrade-1.23.0}/python/src/meshtrade/compliance/client/v1/pep_status_pb2.pyi +0 -0
- {meshtrade-1.22.0 → meshtrade-1.23.0}/python/src/meshtrade/compliance/client/v1/pep_status_pb2_grpc.py +0 -0
- {meshtrade-1.22.0 → meshtrade-1.23.0}/python/src/meshtrade/compliance/client/v1/service_meshpy.py +0 -0
- {meshtrade-1.22.0 → meshtrade-1.23.0}/python/src/meshtrade/compliance/client/v1/service_pb2.py +0 -0
- {meshtrade-1.22.0 → meshtrade-1.23.0}/python/src/meshtrade/compliance/client/v1/service_pb2.pyi +0 -0
- {meshtrade-1.22.0 → meshtrade-1.23.0}/python/src/meshtrade/compliance/client/v1/service_pb2_grpc.py +0 -0
- {meshtrade-1.22.0 → meshtrade-1.23.0}/python/src/meshtrade/compliance/client/v1/source_of_income_and_wealth_pb2.py +0 -0
- {meshtrade-1.22.0 → meshtrade-1.23.0}/python/src/meshtrade/compliance/client/v1/source_of_income_and_wealth_pb2.pyi +0 -0
- {meshtrade-1.22.0 → meshtrade-1.23.0}/python/src/meshtrade/compliance/client/v1/source_of_income_and_wealth_pb2_grpc.py +0 -0
- {meshtrade-1.22.0 → meshtrade-1.23.0}/python/src/meshtrade/compliance/client/v1/tax_residency_pb2.py +0 -0
- {meshtrade-1.22.0 → meshtrade-1.23.0}/python/src/meshtrade/compliance/client/v1/tax_residency_pb2.pyi +0 -0
- {meshtrade-1.22.0 → meshtrade-1.23.0}/python/src/meshtrade/compliance/client/v1/tax_residency_pb2_grpc.py +0 -0
- {meshtrade-1.22.0 → meshtrade-1.23.0}/python/src/meshtrade/compliance/client/v1/trust_pb2.py +0 -0
- {meshtrade-1.22.0 → meshtrade-1.23.0}/python/src/meshtrade/compliance/client/v1/trust_pb2.pyi +0 -0
- {meshtrade-1.22.0 → meshtrade-1.23.0}/python/src/meshtrade/compliance/client/v1/trust_pb2_grpc.py +0 -0
- {meshtrade-1.22.0 → meshtrade-1.23.0}/python/src/meshtrade/compliance/client/v1/verification_status_pb2.py +0 -0
- {meshtrade-1.22.0 → meshtrade-1.23.0}/python/src/meshtrade/compliance/client/v1/verification_status_pb2.pyi +0 -0
- {meshtrade-1.22.0 → meshtrade-1.23.0}/python/src/meshtrade/compliance/client/v1/verification_status_pb2_grpc.py +0 -0
- {meshtrade-1.22.0 → meshtrade-1.23.0}/python/src/meshtrade/iam/__init__.py +0 -0
- {meshtrade-1.22.0 → meshtrade-1.23.0}/python/src/meshtrade/iam/api_user/v1/__init__.py +0 -0
- {meshtrade-1.22.0 → meshtrade-1.23.0}/python/src/meshtrade/iam/api_user/v1/api_credentials.py +0 -0
- {meshtrade-1.22.0 → meshtrade-1.23.0}/python/src/meshtrade/iam/api_user/v1/api_credentials_pb2.py +0 -0
- {meshtrade-1.22.0 → meshtrade-1.23.0}/python/src/meshtrade/iam/api_user/v1/api_credentials_pb2.pyi +0 -0
- {meshtrade-1.22.0 → meshtrade-1.23.0}/python/src/meshtrade/iam/api_user/v1/api_credentials_pb2_grpc.py +0 -0
- {meshtrade-1.22.0 → meshtrade-1.23.0}/python/src/meshtrade/iam/api_user/v1/api_user_pb2.py +0 -0
- {meshtrade-1.22.0 → meshtrade-1.23.0}/python/src/meshtrade/iam/api_user/v1/api_user_pb2.pyi +0 -0
- {meshtrade-1.22.0 → meshtrade-1.23.0}/python/src/meshtrade/iam/api_user/v1/api_user_pb2_grpc.py +0 -0
- {meshtrade-1.22.0 → meshtrade-1.23.0}/python/src/meshtrade/iam/api_user/v1/service.py +0 -0
- {meshtrade-1.22.0 → meshtrade-1.23.0}/python/src/meshtrade/iam/api_user/v1/service_meshpy.py +0 -0
- {meshtrade-1.22.0 → meshtrade-1.23.0}/python/src/meshtrade/iam/api_user/v1/service_pb2.py +0 -0
- {meshtrade-1.22.0 → meshtrade-1.23.0}/python/src/meshtrade/iam/api_user/v1/service_pb2.pyi +0 -0
- {meshtrade-1.22.0 → meshtrade-1.23.0}/python/src/meshtrade/iam/api_user/v1/service_pb2_grpc.py +0 -0
- {meshtrade-1.22.0 → meshtrade-1.23.0}/python/src/meshtrade/iam/group/__init__.py +0 -0
- {meshtrade-1.22.0 → meshtrade-1.23.0}/python/src/meshtrade/iam/group/v1/__init__.py +0 -0
- {meshtrade-1.22.0 → meshtrade-1.23.0}/python/src/meshtrade/iam/group/v1/group_pb2.py +0 -0
- {meshtrade-1.22.0 → meshtrade-1.23.0}/python/src/meshtrade/iam/group/v1/group_pb2.pyi +0 -0
- {meshtrade-1.22.0 → meshtrade-1.23.0}/python/src/meshtrade/iam/group/v1/group_pb2_grpc.py +0 -0
- {meshtrade-1.22.0 → meshtrade-1.23.0}/python/src/meshtrade/iam/group/v1/service_meshpy.py +0 -0
- {meshtrade-1.22.0 → meshtrade-1.23.0}/python/src/meshtrade/iam/group/v1/service_pb2.py +0 -0
- {meshtrade-1.22.0 → meshtrade-1.23.0}/python/src/meshtrade/iam/group/v1/service_pb2.pyi +0 -0
- {meshtrade-1.22.0 → meshtrade-1.23.0}/python/src/meshtrade/iam/group/v1/service_pb2_grpc.py +0 -0
- {meshtrade-1.22.0 → meshtrade-1.23.0}/python/src/meshtrade/iam/role/v1/role_pb2.py +0 -0
- {meshtrade-1.22.0 → meshtrade-1.23.0}/python/src/meshtrade/iam/role/v1/role_pb2.pyi +0 -0
- {meshtrade-1.22.0 → meshtrade-1.23.0}/python/src/meshtrade/iam/role/v1/role_pb2_grpc.py +0 -0
- {meshtrade-1.22.0 → meshtrade-1.23.0}/python/src/meshtrade/iam/user/v1/__init__.py +0 -0
- {meshtrade-1.22.0 → meshtrade-1.23.0}/python/src/meshtrade/iam/user/v1/service_meshpy.py +0 -0
- {meshtrade-1.22.0 → meshtrade-1.23.0}/python/src/meshtrade/iam/user/v1/service_pb2.py +0 -0
- {meshtrade-1.22.0 → meshtrade-1.23.0}/python/src/meshtrade/iam/user/v1/service_pb2.pyi +0 -0
- {meshtrade-1.22.0 → meshtrade-1.23.0}/python/src/meshtrade/iam/user/v1/service_pb2_grpc.py +0 -0
- {meshtrade-1.22.0 → meshtrade-1.23.0}/python/src/meshtrade/iam/user/v1/user_pb2.py +0 -0
- {meshtrade-1.22.0 → meshtrade-1.23.0}/python/src/meshtrade/iam/user/v1/user_pb2.pyi +0 -0
- {meshtrade-1.22.0 → meshtrade-1.23.0}/python/src/meshtrade/iam/user/v1/user_pb2_grpc.py +0 -0
- {meshtrade-1.22.0 → meshtrade-1.23.0}/python/src/meshtrade/ledger/__init__.py +0 -0
- {meshtrade-1.22.0 → meshtrade-1.23.0}/python/src/meshtrade/ledger/transaction/__init__.py +0 -0
- {meshtrade-1.22.0 → meshtrade-1.23.0}/python/src/meshtrade/ledger/transaction/v1/__init__.py +0 -0
- {meshtrade-1.22.0 → meshtrade-1.23.0}/python/src/meshtrade/ledger/transaction/v1/service_meshpy.py +0 -0
- {meshtrade-1.22.0 → meshtrade-1.23.0}/python/src/meshtrade/ledger/transaction/v1/service_pb2.py +0 -0
- {meshtrade-1.22.0 → meshtrade-1.23.0}/python/src/meshtrade/ledger/transaction/v1/service_pb2.pyi +0 -0
- {meshtrade-1.22.0 → meshtrade-1.23.0}/python/src/meshtrade/ledger/transaction/v1/service_pb2_grpc.py +0 -0
- {meshtrade-1.22.0 → meshtrade-1.23.0}/python/src/meshtrade/ledger/transaction/v1/transaction_action_pb2.py +0 -0
- {meshtrade-1.22.0 → meshtrade-1.23.0}/python/src/meshtrade/ledger/transaction/v1/transaction_action_pb2.pyi +0 -0
- {meshtrade-1.22.0 → meshtrade-1.23.0}/python/src/meshtrade/ledger/transaction/v1/transaction_action_pb2_grpc.py +0 -0
- {meshtrade-1.22.0 → meshtrade-1.23.0}/python/src/meshtrade/ledger/transaction/v1/transaction_state_pb2.py +0 -0
- {meshtrade-1.22.0 → meshtrade-1.23.0}/python/src/meshtrade/ledger/transaction/v1/transaction_state_pb2.pyi +0 -0
- {meshtrade-1.22.0 → meshtrade-1.23.0}/python/src/meshtrade/ledger/transaction/v1/transaction_state_pb2_grpc.py +0 -0
- {meshtrade-1.22.0 → meshtrade-1.23.0}/python/src/meshtrade/option/v1/__init__.py +0 -0
- {meshtrade-1.22.0 → meshtrade-1.23.0}/python/src/meshtrade/option/v1/method_type_pb2.py +0 -0
- {meshtrade-1.22.0 → meshtrade-1.23.0}/python/src/meshtrade/option/v1/method_type_pb2.pyi +0 -0
- {meshtrade-1.22.0 → meshtrade-1.23.0}/python/src/meshtrade/option/v1/method_type_pb2_grpc.py +0 -0
- {meshtrade-1.22.0 → meshtrade-1.23.0}/python/src/meshtrade/reporting/account_report/v1/__init__.py +0 -0
- {meshtrade-1.22.0 → meshtrade-1.23.0}/python/src/meshtrade/reporting/account_report/v1/account_report_pb2.py +0 -0
- {meshtrade-1.22.0 → meshtrade-1.23.0}/python/src/meshtrade/reporting/account_report/v1/account_report_pb2.pyi +0 -0
- {meshtrade-1.22.0 → meshtrade-1.23.0}/python/src/meshtrade/reporting/account_report/v1/account_report_pb2_grpc.py +0 -0
- {meshtrade-1.22.0 → meshtrade-1.23.0}/python/src/meshtrade/reporting/account_report/v1/disclaimer_pb2.py +0 -0
- {meshtrade-1.22.0 → meshtrade-1.23.0}/python/src/meshtrade/reporting/account_report/v1/disclaimer_pb2.pyi +0 -0
- {meshtrade-1.22.0 → meshtrade-1.23.0}/python/src/meshtrade/reporting/account_report/v1/disclaimer_pb2_grpc.py +0 -0
- {meshtrade-1.22.0 → meshtrade-1.23.0}/python/src/meshtrade/reporting/account_report/v1/fee_entry_pb2.py +0 -0
- {meshtrade-1.22.0 → meshtrade-1.23.0}/python/src/meshtrade/reporting/account_report/v1/fee_entry_pb2.pyi +0 -0
- {meshtrade-1.22.0 → meshtrade-1.23.0}/python/src/meshtrade/reporting/account_report/v1/fee_entry_pb2_grpc.py +0 -0
- {meshtrade-1.22.0 → meshtrade-1.23.0}/python/src/meshtrade/reporting/account_report/v1/income_entry_pb2.py +0 -0
- {meshtrade-1.22.0 → meshtrade-1.23.0}/python/src/meshtrade/reporting/account_report/v1/income_entry_pb2.pyi +0 -0
- {meshtrade-1.22.0 → meshtrade-1.23.0}/python/src/meshtrade/reporting/account_report/v1/income_entry_pb2_grpc.py +0 -0
- {meshtrade-1.22.0 → meshtrade-1.23.0}/python/src/meshtrade/reporting/account_report/v1/service_meshpy.py +0 -0
- {meshtrade-1.22.0 → meshtrade-1.23.0}/python/src/meshtrade/reporting/account_report/v1/service_pb2.py +0 -0
- {meshtrade-1.22.0 → meshtrade-1.23.0}/python/src/meshtrade/reporting/account_report/v1/service_pb2.pyi +0 -0
- {meshtrade-1.22.0 → meshtrade-1.23.0}/python/src/meshtrade/reporting/account_report/v1/service_pb2_grpc.py +0 -0
- {meshtrade-1.22.0 → meshtrade-1.23.0}/python/src/meshtrade/reporting/account_report/v1/trading_statement_entry_pb2.py +0 -0
- {meshtrade-1.22.0 → meshtrade-1.23.0}/python/src/meshtrade/reporting/account_report/v1/trading_statement_entry_pb2.pyi +0 -0
- {meshtrade-1.22.0 → meshtrade-1.23.0}/python/src/meshtrade/reporting/account_report/v1/trading_statement_entry_pb2_grpc.py +0 -0
- {meshtrade-1.22.0 → meshtrade-1.23.0}/python/src/meshtrade/studio/instrument/v1/__init__.py +0 -0
- {meshtrade-1.22.0 → meshtrade-1.23.0}/python/src/meshtrade/studio/instrument/v1/instrument_pb2.py +0 -0
- {meshtrade-1.22.0 → meshtrade-1.23.0}/python/src/meshtrade/studio/instrument/v1/instrument_pb2.pyi +0 -0
- {meshtrade-1.22.0 → meshtrade-1.23.0}/python/src/meshtrade/studio/instrument/v1/instrument_pb2_grpc.py +0 -0
- {meshtrade-1.22.0 → meshtrade-1.23.0}/python/src/meshtrade/studio/instrument/v1/instrument_type_pb2.py +0 -0
- {meshtrade-1.22.0 → meshtrade-1.23.0}/python/src/meshtrade/studio/instrument/v1/instrument_type_pb2.pyi +0 -0
- {meshtrade-1.22.0 → meshtrade-1.23.0}/python/src/meshtrade/studio/instrument/v1/instrument_type_pb2_grpc.py +0 -0
- {meshtrade-1.22.0 → meshtrade-1.23.0}/python/src/meshtrade/studio/instrument/v1/unit_pb2.py +0 -0
- {meshtrade-1.22.0 → meshtrade-1.23.0}/python/src/meshtrade/studio/instrument/v1/unit_pb2.pyi +0 -0
- {meshtrade-1.22.0 → meshtrade-1.23.0}/python/src/meshtrade/studio/instrument/v1/unit_pb2_grpc.py +0 -0
- {meshtrade-1.22.0 → meshtrade-1.23.0}/python/src/meshtrade/trading/__init__.py +0 -0
- {meshtrade-1.22.0 → meshtrade-1.23.0}/python/src/meshtrade/trading/limit_order/__init__.py +0 -0
- {meshtrade-1.22.0 → meshtrade-1.23.0}/python/src/meshtrade/trading/limit_order/v1/__init__.py +0 -0
- {meshtrade-1.22.0 → meshtrade-1.23.0}/python/src/meshtrade/trading/limit_order/v1/limit_order_pb2.py +0 -0
- {meshtrade-1.22.0 → meshtrade-1.23.0}/python/src/meshtrade/trading/limit_order/v1/limit_order_pb2.pyi +0 -0
- {meshtrade-1.22.0 → meshtrade-1.23.0}/python/src/meshtrade/trading/limit_order/v1/limit_order_pb2_grpc.py +0 -0
- {meshtrade-1.22.0 → meshtrade-1.23.0}/python/src/meshtrade/trading/limit_order/v1/service_meshpy.py +0 -0
- {meshtrade-1.22.0 → meshtrade-1.23.0}/python/src/meshtrade/trading/limit_order/v1/service_pb2.py +0 -0
- {meshtrade-1.22.0 → meshtrade-1.23.0}/python/src/meshtrade/trading/limit_order/v1/service_pb2.pyi +0 -0
- {meshtrade-1.22.0 → meshtrade-1.23.0}/python/src/meshtrade/trading/limit_order/v1/service_pb2_grpc.py +0 -0
- {meshtrade-1.22.0 → meshtrade-1.23.0}/python/src/meshtrade/trading/market_order/v1/__init__.py +0 -0
- {meshtrade-1.22.0 → meshtrade-1.23.0}/python/src/meshtrade/trading/market_order/v1/market_order_pb2.py +0 -0
- {meshtrade-1.22.0 → meshtrade-1.23.0}/python/src/meshtrade/trading/market_order/v1/market_order_pb2.pyi +0 -0
- {meshtrade-1.22.0 → meshtrade-1.23.0}/python/src/meshtrade/trading/market_order/v1/market_order_pb2_grpc.py +0 -0
- {meshtrade-1.22.0 → meshtrade-1.23.0}/python/src/meshtrade/trading/market_order/v1/service_meshpy.py +0 -0
- {meshtrade-1.22.0 → meshtrade-1.23.0}/python/src/meshtrade/trading/market_order/v1/service_pb2.py +0 -0
- {meshtrade-1.22.0 → meshtrade-1.23.0}/python/src/meshtrade/trading/market_order/v1/service_pb2.pyi +0 -0
- {meshtrade-1.22.0 → meshtrade-1.23.0}/python/src/meshtrade/trading/market_order/v1/service_pb2_grpc.py +0 -0
- {meshtrade-1.22.0 → meshtrade-1.23.0}/python/src/meshtrade/type/__init__.py +0 -0
- {meshtrade-1.22.0 → meshtrade-1.23.0}/python/src/meshtrade/type/v1/__init__.py +0 -0
- {meshtrade-1.22.0 → meshtrade-1.23.0}/python/src/meshtrade/type/v1/address_pb2.py +0 -0
- {meshtrade-1.22.0 → meshtrade-1.23.0}/python/src/meshtrade/type/v1/address_pb2.pyi +0 -0
- {meshtrade-1.22.0 → meshtrade-1.23.0}/python/src/meshtrade/type/v1/address_pb2_grpc.py +0 -0
- {meshtrade-1.22.0 → meshtrade-1.23.0}/python/src/meshtrade/type/v1/amount_pb2.py +0 -0
- {meshtrade-1.22.0 → meshtrade-1.23.0}/python/src/meshtrade/type/v1/amount_pb2.pyi +0 -0
- {meshtrade-1.22.0 → meshtrade-1.23.0}/python/src/meshtrade/type/v1/amount_pb2_grpc.py +0 -0
- {meshtrade-1.22.0 → meshtrade-1.23.0}/python/src/meshtrade/type/v1/contact_details_pb2.py +0 -0
- {meshtrade-1.22.0 → meshtrade-1.23.0}/python/src/meshtrade/type/v1/contact_details_pb2.pyi +0 -0
- {meshtrade-1.22.0 → meshtrade-1.23.0}/python/src/meshtrade/type/v1/contact_details_pb2_grpc.py +0 -0
- {meshtrade-1.22.0 → meshtrade-1.23.0}/python/src/meshtrade/type/v1/date.py +0 -0
- {meshtrade-1.22.0 → meshtrade-1.23.0}/python/src/meshtrade/type/v1/date_pb2.py +0 -0
- {meshtrade-1.22.0 → meshtrade-1.23.0}/python/src/meshtrade/type/v1/date_pb2.pyi +0 -0
- {meshtrade-1.22.0 → meshtrade-1.23.0}/python/src/meshtrade/type/v1/date_pb2_grpc.py +0 -0
- {meshtrade-1.22.0 → meshtrade-1.23.0}/python/src/meshtrade/type/v1/decimal_pb2.py +0 -0
- {meshtrade-1.22.0 → meshtrade-1.23.0}/python/src/meshtrade/type/v1/decimal_pb2.pyi +0 -0
- {meshtrade-1.22.0 → meshtrade-1.23.0}/python/src/meshtrade/type/v1/decimal_pb2_grpc.py +0 -0
- {meshtrade-1.22.0 → meshtrade-1.23.0}/python/src/meshtrade/type/v1/ledger_pb2.py +0 -0
- {meshtrade-1.22.0 → meshtrade-1.23.0}/python/src/meshtrade/type/v1/ledger_pb2.pyi +0 -0
- {meshtrade-1.22.0 → meshtrade-1.23.0}/python/src/meshtrade/type/v1/ledger_pb2_grpc.py +0 -0
- {meshtrade-1.22.0 → meshtrade-1.23.0}/python/src/meshtrade/type/v1/sorting_pb2.py +0 -0
- {meshtrade-1.22.0 → meshtrade-1.23.0}/python/src/meshtrade/type/v1/sorting_pb2.pyi +0 -0
- {meshtrade-1.22.0 → meshtrade-1.23.0}/python/src/meshtrade/type/v1/sorting_pb2_grpc.py +0 -0
- {meshtrade-1.22.0 → meshtrade-1.23.0}/python/src/meshtrade/type/v1/time_of_day.py +0 -0
- {meshtrade-1.22.0 → meshtrade-1.23.0}/python/src/meshtrade/type/v1/time_of_day_pb2.py +0 -0
- {meshtrade-1.22.0 → meshtrade-1.23.0}/python/src/meshtrade/type/v1/time_of_day_pb2.pyi +0 -0
- {meshtrade-1.22.0 → meshtrade-1.23.0}/python/src/meshtrade/type/v1/time_of_day_pb2_grpc.py +0 -0
- {meshtrade-1.22.0 → meshtrade-1.23.0}/python/src/meshtrade/type/v1/token_pb2.py +0 -0
- {meshtrade-1.22.0 → meshtrade-1.23.0}/python/src/meshtrade/type/v1/token_pb2.pyi +0 -0
- {meshtrade-1.22.0 → meshtrade-1.23.0}/python/src/meshtrade/type/v1/token_pb2_grpc.py +0 -0
- {meshtrade-1.22.0 → meshtrade-1.23.0}/python/src/meshtrade/wallet/__init__.py +0 -0
- {meshtrade-1.22.0 → meshtrade-1.23.0}/python/src/meshtrade/wallet/account/v1/__init__.py +0 -0
- {meshtrade-1.22.0 → meshtrade-1.23.0}/python/src/meshtrade/wallet/account/v1/account_pb2.py +0 -0
- {meshtrade-1.22.0 → meshtrade-1.23.0}/python/src/meshtrade/wallet/account/v1/account_pb2.pyi +0 -0
- {meshtrade-1.22.0 → meshtrade-1.23.0}/python/src/meshtrade/wallet/account/v1/account_pb2_grpc.py +0 -0
- {meshtrade-1.22.0 → meshtrade-1.23.0}/python/src/meshtrade/wallet/account/v1/service_meshpy.py +0 -0
- {meshtrade-1.22.0 → meshtrade-1.23.0}/python/src/meshtrade/wallet/account/v1/service_pb2.py +0 -0
- {meshtrade-1.22.0 → meshtrade-1.23.0}/python/src/meshtrade/wallet/account/v1/service_pb2.pyi +0 -0
- {meshtrade-1.22.0 → meshtrade-1.23.0}/python/src/meshtrade/wallet/account/v1/service_pb2_grpc.py +0 -0
- {meshtrade-1.22.0 → meshtrade-1.23.0}/python/src/meshtrade.egg-info/dependency_links.txt +0 -0
- {meshtrade-1.22.0 → meshtrade-1.23.0}/python/src/meshtrade.egg-info/requires.txt +0 -0
- {meshtrade-1.22.0 → meshtrade-1.23.0}/python/src/meshtrade.egg-info/top_level.txt +0 -0
- {meshtrade-1.22.0 → meshtrade-1.23.0}/setup.cfg +0 -0
|
@@ -0,0 +1,123 @@
|
|
|
1
|
+
"""Client roles utility functions."""
|
|
2
|
+
|
|
3
|
+
from meshtrade.compliance.client.v1.client_pb2 import Client
|
|
4
|
+
from meshtrade.iam.role.v1 import role_pb2
|
|
5
|
+
from meshtrade.iam.role.v1.role_pb2 import Role
|
|
6
|
+
|
|
7
|
+
# Cache for client default roles extracted from protobuf
|
|
8
|
+
_client_default_roles: list[Role] | None = None
|
|
9
|
+
_client_default_roles_error: str | None = None
|
|
10
|
+
|
|
11
|
+
|
|
12
|
+
def _initialize_client_default_roles() -> None:
|
|
13
|
+
"""Initialize client default roles from protobuf extensions.
|
|
14
|
+
|
|
15
|
+
This function is called once to extract roles from the Client message's
|
|
16
|
+
message_roles extension. Results are cached for subsequent calls.
|
|
17
|
+
"""
|
|
18
|
+
global _client_default_roles, _client_default_roles_error
|
|
19
|
+
|
|
20
|
+
if _client_default_roles is not None or _client_default_roles_error is not None:
|
|
21
|
+
return
|
|
22
|
+
|
|
23
|
+
try:
|
|
24
|
+
# Get the Client message descriptor
|
|
25
|
+
client_descriptor = Client.DESCRIPTOR
|
|
26
|
+
|
|
27
|
+
# Get message options
|
|
28
|
+
options = client_descriptor.GetOptions()
|
|
29
|
+
|
|
30
|
+
# Get the message_roles extension descriptor
|
|
31
|
+
message_roles_ext = role_pb2.message_roles
|
|
32
|
+
|
|
33
|
+
# Check if extension is present
|
|
34
|
+
# Type ignore: protobuf extension API has overly strict type stubs
|
|
35
|
+
if not options.HasExtension(message_roles_ext): # type: ignore[arg-type]
|
|
36
|
+
_client_default_roles_error = f"proto message {client_descriptor.full_name} does not define extension {message_roles_ext.full_name}"
|
|
37
|
+
return
|
|
38
|
+
|
|
39
|
+
# Get the RoleList from the extension
|
|
40
|
+
# Type ignore: protobuf extension API has overly strict type stubs
|
|
41
|
+
role_list = options.Extensions[message_roles_ext] # type: ignore[arg-type]
|
|
42
|
+
|
|
43
|
+
# Extract roles and make a copy
|
|
44
|
+
_client_default_roles = list(role_list.roles)
|
|
45
|
+
|
|
46
|
+
except Exception as e:
|
|
47
|
+
_client_default_roles_error = f"failed to extract roles from Client message: {e}"
|
|
48
|
+
|
|
49
|
+
|
|
50
|
+
def get_client_default_roles() -> list[Role]:
|
|
51
|
+
"""Get default roles for a client.
|
|
52
|
+
|
|
53
|
+
Returns the roles declared on the meshtrade.compliance.client.v1.Client
|
|
54
|
+
message via the meshtrade.iam.role.v1.message_roles option. The returned
|
|
55
|
+
list is a copy so callers can safely mutate it without affecting subsequent reads.
|
|
56
|
+
|
|
57
|
+
Returns:
|
|
58
|
+
List of default Role values for clients
|
|
59
|
+
Empty list if retrieval fails
|
|
60
|
+
"""
|
|
61
|
+
try:
|
|
62
|
+
return must_get_client_default_roles()
|
|
63
|
+
except ValueError:
|
|
64
|
+
return []
|
|
65
|
+
|
|
66
|
+
|
|
67
|
+
def must_get_client_default_roles() -> list[Role]:
|
|
68
|
+
"""Get default roles for a client, raising error on failure.
|
|
69
|
+
|
|
70
|
+
Returns the roles declared on the meshtrade.compliance.client.v1.Client
|
|
71
|
+
message via the meshtrade.iam.role.v1.message_roles option. The returned
|
|
72
|
+
list is a copy so callers can safely mutate it without affecting subsequent reads.
|
|
73
|
+
|
|
74
|
+
Returns:
|
|
75
|
+
List of default Role values for clients
|
|
76
|
+
|
|
77
|
+
Raises:
|
|
78
|
+
ValueError: If default roles cannot be determined
|
|
79
|
+
"""
|
|
80
|
+
_initialize_client_default_roles()
|
|
81
|
+
|
|
82
|
+
if _client_default_roles_error is not None:
|
|
83
|
+
raise ValueError(_client_default_roles_error)
|
|
84
|
+
|
|
85
|
+
if _client_default_roles is None:
|
|
86
|
+
raise ValueError("client default roles not initialized")
|
|
87
|
+
|
|
88
|
+
# Return a copy to prevent mutation
|
|
89
|
+
return list(_client_default_roles)
|
|
90
|
+
|
|
91
|
+
|
|
92
|
+
def get_client_default_role_index() -> dict[Role, bool]:
|
|
93
|
+
"""Get default roles as a lookup index.
|
|
94
|
+
|
|
95
|
+
Builds a set-like map keyed by roles declared on the
|
|
96
|
+
meshtrade.compliance.client.v1.Client message. The map's values are always
|
|
97
|
+
True; the structure is intended for efficient membership checks.
|
|
98
|
+
|
|
99
|
+
Returns:
|
|
100
|
+
Dictionary mapping Role to True for default roles
|
|
101
|
+
Empty dict if retrieval fails
|
|
102
|
+
"""
|
|
103
|
+
try:
|
|
104
|
+
return must_get_client_default_role_index()
|
|
105
|
+
except ValueError:
|
|
106
|
+
return {}
|
|
107
|
+
|
|
108
|
+
|
|
109
|
+
def must_get_client_default_role_index() -> dict[Role, bool]:
|
|
110
|
+
"""Get default roles as lookup index, raising error on failure.
|
|
111
|
+
|
|
112
|
+
Builds a set-like map keyed by roles declared on the
|
|
113
|
+
meshtrade.compliance.client.v1.Client message. The map's values are always
|
|
114
|
+
True; the structure is intended for efficient membership checks.
|
|
115
|
+
|
|
116
|
+
Returns:
|
|
117
|
+
Dictionary mapping Role to True for default roles
|
|
118
|
+
|
|
119
|
+
Raises:
|
|
120
|
+
ValueError: If default roles cannot be determined
|
|
121
|
+
"""
|
|
122
|
+
roles = must_get_client_default_roles()
|
|
123
|
+
return dict.fromkeys(roles, True)
|
|
@@ -0,0 +1,104 @@
|
|
|
1
|
+
"""API User state machine validation and transition logic.
|
|
2
|
+
|
|
3
|
+
This module provides validation and state machine functions for API User states
|
|
4
|
+
and actions, implementing the API User lifecycle management logic.
|
|
5
|
+
"""
|
|
6
|
+
|
|
7
|
+
from meshtrade.iam.api_user.v1.api_user_pb2 import APIUserAction, APIUserState
|
|
8
|
+
|
|
9
|
+
|
|
10
|
+
def api_user_state_is_valid(state: APIUserState | None) -> bool:
|
|
11
|
+
"""Check if the APIUserState is a valid enum value.
|
|
12
|
+
|
|
13
|
+
Args:
|
|
14
|
+
state: The APIUserState to validate (can be None)
|
|
15
|
+
|
|
16
|
+
Returns:
|
|
17
|
+
True if the state is a valid enum value, False otherwise
|
|
18
|
+
|
|
19
|
+
None Safety:
|
|
20
|
+
Returns False if state is None
|
|
21
|
+
|
|
22
|
+
Example:
|
|
23
|
+
>>> api_user_state_is_valid(APIUserState.API_USER_STATE_ACTIVE)
|
|
24
|
+
True
|
|
25
|
+
>>> api_user_state_is_valid(999) # Invalid enum value
|
|
26
|
+
False
|
|
27
|
+
>>> api_user_state_is_valid(None)
|
|
28
|
+
False
|
|
29
|
+
"""
|
|
30
|
+
if state is None:
|
|
31
|
+
return False
|
|
32
|
+
return state in APIUserState.values()
|
|
33
|
+
|
|
34
|
+
|
|
35
|
+
def api_user_state_is_valid_and_defined(state: APIUserState) -> bool:
|
|
36
|
+
"""Check if the APIUserState is valid and not unspecified.
|
|
37
|
+
|
|
38
|
+
Args:
|
|
39
|
+
state: The APIUserState to validate
|
|
40
|
+
|
|
41
|
+
Returns:
|
|
42
|
+
True if the state is valid and not UNSPECIFIED, False otherwise
|
|
43
|
+
|
|
44
|
+
Example:
|
|
45
|
+
>>> api_user_state_is_valid_and_defined(APIUserState.API_USER_STATE_ACTIVE)
|
|
46
|
+
True
|
|
47
|
+
>>> api_user_state_is_valid_and_defined(APIUserState.API_USER_STATE_UNSPECIFIED)
|
|
48
|
+
False
|
|
49
|
+
"""
|
|
50
|
+
return api_user_state_is_valid(state) and state != APIUserState.API_USER_STATE_UNSPECIFIED
|
|
51
|
+
|
|
52
|
+
|
|
53
|
+
def api_user_state_can_perform_action_at_state(state: APIUserState | None, action: APIUserAction | None) -> bool:
|
|
54
|
+
"""Check if the given action can be performed at the current state.
|
|
55
|
+
|
|
56
|
+
This implements the state machine logic for API User lifecycle management.
|
|
57
|
+
|
|
58
|
+
State Transitions:
|
|
59
|
+
- INACTIVE -> ACTIVATE -> ACTIVE
|
|
60
|
+
- ACTIVE -> DEACTIVATE -> INACTIVE
|
|
61
|
+
- UPDATE action allowed in any state
|
|
62
|
+
|
|
63
|
+
Args:
|
|
64
|
+
state: The current APIUserState (can be None)
|
|
65
|
+
action: The APIUserAction to perform (can be None)
|
|
66
|
+
|
|
67
|
+
Returns:
|
|
68
|
+
True if the action can be performed at the given state, False otherwise
|
|
69
|
+
|
|
70
|
+
None Safety:
|
|
71
|
+
Returns False if either state or action is None
|
|
72
|
+
|
|
73
|
+
Example:
|
|
74
|
+
>>> can_perform_action_at_state(
|
|
75
|
+
... APIUserState.API_USER_STATE_INACTIVE,
|
|
76
|
+
... APIUserAction.API_USER_ACTION_ACTIVATE
|
|
77
|
+
... )
|
|
78
|
+
True
|
|
79
|
+
>>> can_perform_action_at_state(
|
|
80
|
+
... APIUserState.API_USER_STATE_INACTIVE,
|
|
81
|
+
... APIUserAction.API_USER_ACTION_DEACTIVATE
|
|
82
|
+
... )
|
|
83
|
+
False
|
|
84
|
+
"""
|
|
85
|
+
if state is None or action is None:
|
|
86
|
+
return False
|
|
87
|
+
|
|
88
|
+
# Define actions that are allowed regardless of state (update operations)
|
|
89
|
+
general_update_actions = {
|
|
90
|
+
APIUserAction.API_USER_ACTION_UPDATE: True,
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
if state == APIUserState.API_USER_STATE_INACTIVE:
|
|
94
|
+
if action == APIUserAction.API_USER_ACTION_ACTIVATE:
|
|
95
|
+
return True
|
|
96
|
+
return general_update_actions.get(action, False)
|
|
97
|
+
|
|
98
|
+
elif state == APIUserState.API_USER_STATE_ACTIVE:
|
|
99
|
+
if action == APIUserAction.API_USER_ACTION_DEACTIVATE:
|
|
100
|
+
return True
|
|
101
|
+
return general_update_actions.get(action, False)
|
|
102
|
+
|
|
103
|
+
else:
|
|
104
|
+
return False
|
|
@@ -29,7 +29,7 @@ from .role_pb2 import Role, RoleList
|
|
|
29
29
|
#
|
|
30
30
|
# ===================================================================
|
|
31
31
|
|
|
32
|
-
from .role import
|
|
32
|
+
from .role import role_full_resource_name_from_group
|
|
33
33
|
|
|
34
34
|
# ===================================================================
|
|
35
35
|
# MODULE EXPORTS
|
|
@@ -40,5 +40,5 @@ __all__ = [
|
|
|
40
40
|
"Role",
|
|
41
41
|
"RoleList",
|
|
42
42
|
# Manual exports
|
|
43
|
-
"
|
|
43
|
+
"role_full_resource_name_from_group",
|
|
44
44
|
]
|
|
@@ -0,0 +1,174 @@
|
|
|
1
|
+
"""Role utility functions for Mesh API.
|
|
2
|
+
|
|
3
|
+
This module provides helper functions for working with Role enums and their resource names.
|
|
4
|
+
All functions use the 3-part integer format: groups/{groupID}/{roleNumber}
|
|
5
|
+
for cross-language compatibility.
|
|
6
|
+
"""
|
|
7
|
+
|
|
8
|
+
from meshtrade.iam.role.v1.role_pb2 import Role
|
|
9
|
+
|
|
10
|
+
|
|
11
|
+
def role_is_valid(role: Role) -> bool:
|
|
12
|
+
"""Check if role value is valid (within enum range).
|
|
13
|
+
|
|
14
|
+
Args:
|
|
15
|
+
role: Role enum value (integer)
|
|
16
|
+
|
|
17
|
+
Returns:
|
|
18
|
+
True if role is a valid enum value
|
|
19
|
+
|
|
20
|
+
Example:
|
|
21
|
+
>>> role_is_valid(Role.ROLE_IAM_ADMIN)
|
|
22
|
+
True
|
|
23
|
+
>>> role_is_valid(99999999)
|
|
24
|
+
False
|
|
25
|
+
"""
|
|
26
|
+
return role in Role.values()
|
|
27
|
+
|
|
28
|
+
|
|
29
|
+
def role_is_valid_and_specified(role: Role) -> bool:
|
|
30
|
+
"""Check if role is valid and not UNSPECIFIED.
|
|
31
|
+
|
|
32
|
+
Args:
|
|
33
|
+
role: Role enum value (integer)
|
|
34
|
+
|
|
35
|
+
Returns:
|
|
36
|
+
True if role is valid and not ROLE_UNSPECIFIED
|
|
37
|
+
|
|
38
|
+
Example:
|
|
39
|
+
>>> role_is_valid_and_specified(Role.ROLE_IAM_ADMIN)
|
|
40
|
+
True
|
|
41
|
+
>>> role_is_valid_and_specified(Role.ROLE_UNSPECIFIED)
|
|
42
|
+
False
|
|
43
|
+
"""
|
|
44
|
+
return role_is_valid(role) and role != Role.ROLE_UNSPECIFIED
|
|
45
|
+
|
|
46
|
+
|
|
47
|
+
def role_full_resource_name_from_group_id(role: Role, group_id: str) -> str:
|
|
48
|
+
"""Generate full resource name from role and group ID.
|
|
49
|
+
|
|
50
|
+
Format: groups/{group_id}/{role_int}
|
|
51
|
+
|
|
52
|
+
Args:
|
|
53
|
+
role: Role enum value (integer)
|
|
54
|
+
group_id: Group ID (UUID)
|
|
55
|
+
|
|
56
|
+
Returns:
|
|
57
|
+
Full resource name string using integer format
|
|
58
|
+
|
|
59
|
+
Example:
|
|
60
|
+
>>> role_full_resource_name_from_group_id(Role.ROLE_IAM_ADMIN, "01DD32GZ7R0000000000000001")
|
|
61
|
+
'groups/01DD32GZ7R0000000000000001/3000000'
|
|
62
|
+
"""
|
|
63
|
+
return f"groups/{group_id}/{int(role)}"
|
|
64
|
+
|
|
65
|
+
|
|
66
|
+
def role_full_resource_name_from_group(role: Role, group: str) -> str:
|
|
67
|
+
"""Generate full resource name from role and group resource name.
|
|
68
|
+
|
|
69
|
+
Args:
|
|
70
|
+
role: Role enum value (integer)
|
|
71
|
+
group: Group resource name (e.g., "groups/{id}")
|
|
72
|
+
|
|
73
|
+
Returns:
|
|
74
|
+
Full resource name string using integer format
|
|
75
|
+
|
|
76
|
+
Raises:
|
|
77
|
+
ValueError: If group format is invalid
|
|
78
|
+
|
|
79
|
+
Example:
|
|
80
|
+
>>> role_full_resource_name_from_group(Role.ROLE_IAM_ADMIN, "groups/01DD32GZ7R0000000000000001")
|
|
81
|
+
'groups/01DD32GZ7R0000000000000001/3000000'
|
|
82
|
+
"""
|
|
83
|
+
if not group.startswith("groups/"):
|
|
84
|
+
raise ValueError(f"invalid group format, expected groups/{{groupID}}, got: {group}")
|
|
85
|
+
|
|
86
|
+
group_id = group[len("groups/") :]
|
|
87
|
+
if not group_id:
|
|
88
|
+
raise ValueError(f"group ID cannot be empty in group resource name: {group}")
|
|
89
|
+
|
|
90
|
+
return role_full_resource_name_from_group_id(role, group_id)
|
|
91
|
+
|
|
92
|
+
|
|
93
|
+
def role_from_full_resource_name(full_resource_name: str) -> Role:
|
|
94
|
+
"""Extract Role from full resource name.
|
|
95
|
+
|
|
96
|
+
Args:
|
|
97
|
+
full_resource_name: Full resource name (e.g., "groups/{id}/{role_int}")
|
|
98
|
+
|
|
99
|
+
Returns:
|
|
100
|
+
Role enum value (integer), or ROLE_UNSPECIFIED if parsing fails
|
|
101
|
+
|
|
102
|
+
Example:
|
|
103
|
+
>>> role_from_full_resource_name("groups/01DD32GZ7R0000000000000001/3000000")
|
|
104
|
+
3000000
|
|
105
|
+
>>> role_from_full_resource_name("invalid/format")
|
|
106
|
+
0
|
|
107
|
+
"""
|
|
108
|
+
from typing import cast
|
|
109
|
+
|
|
110
|
+
try:
|
|
111
|
+
_, role_int = parse_role_parts(full_resource_name)
|
|
112
|
+
# Python protobuf enums are integers, safe to cast
|
|
113
|
+
return cast(Role, role_int)
|
|
114
|
+
except ValueError:
|
|
115
|
+
return Role.ROLE_UNSPECIFIED
|
|
116
|
+
|
|
117
|
+
|
|
118
|
+
def parse_role_parts(role_full_resource_name: str) -> tuple[str, int]:
|
|
119
|
+
"""Parse full resource name into group ID and Role.
|
|
120
|
+
|
|
121
|
+
Expected format: groups/{group_id}/{role_int}
|
|
122
|
+
|
|
123
|
+
Args:
|
|
124
|
+
role_full_resource_name: Full resource name
|
|
125
|
+
|
|
126
|
+
Returns:
|
|
127
|
+
Tuple of (group_id, role_int)
|
|
128
|
+
|
|
129
|
+
Raises:
|
|
130
|
+
ValueError: If format is invalid or role number cannot be parsed
|
|
131
|
+
|
|
132
|
+
Example:
|
|
133
|
+
>>> parse_role_parts("groups/01DD32GZ7R0000000000000001/3000000")
|
|
134
|
+
('01DD32GZ7R0000000000000001', 3000000)
|
|
135
|
+
"""
|
|
136
|
+
parts = role_full_resource_name.split("/")
|
|
137
|
+
if len(parts) != 3 or parts[0] != "groups":
|
|
138
|
+
raise ValueError(f"invalid role format, expected groups/{{groupID}}/{{role}}, got {role_full_resource_name}")
|
|
139
|
+
|
|
140
|
+
group_id = parts[1]
|
|
141
|
+
if not group_id:
|
|
142
|
+
raise ValueError("group ID cannot be empty")
|
|
143
|
+
|
|
144
|
+
try:
|
|
145
|
+
role_int = int(parts[2])
|
|
146
|
+
except ValueError as e:
|
|
147
|
+
raise ValueError(f"error parsing role enum value '{parts[2]}'") from e
|
|
148
|
+
|
|
149
|
+
if role_int < 0:
|
|
150
|
+
raise ValueError(f"invalid role number in full resource name: {role_full_resource_name}")
|
|
151
|
+
|
|
152
|
+
return group_id, role_int
|
|
153
|
+
|
|
154
|
+
|
|
155
|
+
def must_parse_role_parts(role_full_resource_name: str) -> tuple[str, int]:
|
|
156
|
+
"""Parse role parts, raising error on failure.
|
|
157
|
+
|
|
158
|
+
This is an alias for parse_role_parts.
|
|
159
|
+
Both functions raise ValueError on parsing errors.
|
|
160
|
+
|
|
161
|
+
Args:
|
|
162
|
+
role_full_resource_name: Full resource name
|
|
163
|
+
|
|
164
|
+
Returns:
|
|
165
|
+
Tuple of (group_id, role_int)
|
|
166
|
+
|
|
167
|
+
Raises:
|
|
168
|
+
ValueError: If format is invalid
|
|
169
|
+
|
|
170
|
+
Example:
|
|
171
|
+
>>> must_parse_role_parts("groups/01DD32GZ7R0000000000000001/3000000")
|
|
172
|
+
('01DD32GZ7R0000000000000001', 3000000)
|
|
173
|
+
"""
|
|
174
|
+
return parse_role_parts(role_full_resource_name)
|
|
@@ -0,0 +1,75 @@
|
|
|
1
|
+
"""Transaction state machine validation and transition logic.
|
|
2
|
+
|
|
3
|
+
This module provides state machine functions for transaction states and actions,
|
|
4
|
+
implementing the transaction lifecycle management logic.
|
|
5
|
+
"""
|
|
6
|
+
|
|
7
|
+
from meshtrade.ledger.transaction.v1.transaction_action_pb2 import TransactionAction
|
|
8
|
+
from meshtrade.ledger.transaction.v1.transaction_state_pb2 import TransactionState
|
|
9
|
+
|
|
10
|
+
|
|
11
|
+
def transaction_state_can_perform_action_at_state(state: TransactionState | None, action: TransactionAction | None) -> bool:
|
|
12
|
+
"""Check if the given action can be performed at the current transaction state.
|
|
13
|
+
|
|
14
|
+
This implements the state machine logic for transaction lifecycle management.
|
|
15
|
+
|
|
16
|
+
State Transitions:
|
|
17
|
+
- DRAFT -> BUILD/COMMIT -> SIGNING_IN_PROGRESS
|
|
18
|
+
- SIGNING_IN_PROGRESS -> SIGN/MARK_PENDING -> PENDING
|
|
19
|
+
- PENDING -> SUBMIT -> SUBMISSION_IN_PROGRESS
|
|
20
|
+
- SUBMISSION_IN_PROGRESS -> SUBMIT (retry) -> INDETERMINATE or SUCCESS/FAILED
|
|
21
|
+
- INDETERMINATE -> SUBMIT (retry) -> SUCCESS/FAILED
|
|
22
|
+
- FAILED/SUCCESSFUL -> No further actions allowed (terminal states)
|
|
23
|
+
|
|
24
|
+
Args:
|
|
25
|
+
state: The current TransactionState (can be None)
|
|
26
|
+
action: The TransactionAction to perform (can be None)
|
|
27
|
+
|
|
28
|
+
Returns:
|
|
29
|
+
True if the action can be performed at the given state, False otherwise
|
|
30
|
+
|
|
31
|
+
None Safety:
|
|
32
|
+
Returns False if either state or action is None
|
|
33
|
+
|
|
34
|
+
Example:
|
|
35
|
+
>>> transaction_state_can_perform_action_at_state(
|
|
36
|
+
... TransactionState.TRANSACTION_STATE_DRAFT,
|
|
37
|
+
... TransactionAction.TRANSACTION_ACTION_BUILD
|
|
38
|
+
... )
|
|
39
|
+
True
|
|
40
|
+
>>> transaction_state_can_perform_action_at_state(
|
|
41
|
+
... TransactionState.TRANSACTION_STATE_SUCCESSFUL,
|
|
42
|
+
... TransactionAction.TRANSACTION_ACTION_SUBMIT
|
|
43
|
+
... )
|
|
44
|
+
False
|
|
45
|
+
"""
|
|
46
|
+
if state is None or action is None:
|
|
47
|
+
return False
|
|
48
|
+
|
|
49
|
+
if state == TransactionState.TRANSACTION_STATE_DRAFT:
|
|
50
|
+
return action in {
|
|
51
|
+
TransactionAction.TRANSACTION_ACTION_BUILD,
|
|
52
|
+
TransactionAction.TRANSACTION_ACTION_COMMIT,
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
elif state == TransactionState.TRANSACTION_STATE_SIGNING_IN_PROGRESS:
|
|
56
|
+
return action in {
|
|
57
|
+
TransactionAction.TRANSACTION_ACTION_SIGN,
|
|
58
|
+
TransactionAction.TRANSACTION_ACTION_MARK_PENDING,
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
elif state in {
|
|
62
|
+
TransactionState.TRANSACTION_STATE_PENDING,
|
|
63
|
+
TransactionState.TRANSACTION_STATE_SUBMISSION_IN_PROGRESS,
|
|
64
|
+
TransactionState.TRANSACTION_STATE_INDETERMINATE,
|
|
65
|
+
}:
|
|
66
|
+
return action == TransactionAction.TRANSACTION_ACTION_SUBMIT
|
|
67
|
+
|
|
68
|
+
elif state in {
|
|
69
|
+
TransactionState.TRANSACTION_STATE_FAILED,
|
|
70
|
+
TransactionState.TRANSACTION_STATE_SUCCESSFUL,
|
|
71
|
+
}:
|
|
72
|
+
return False
|
|
73
|
+
|
|
74
|
+
else:
|
|
75
|
+
return False
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
"""Income entry utility functions."""
|
|
2
|
+
|
|
3
|
+
from meshtrade.reporting.account_report.v1.income_entry_pb2 import IncomeNarrative
|
|
4
|
+
|
|
5
|
+
|
|
6
|
+
def income_narrative_pretty_string(narrative: IncomeNarrative) -> str:
|
|
7
|
+
"""Generate human-readable string for income narrative.
|
|
8
|
+
|
|
9
|
+
Converts enum values to concise, display-friendly strings suitable for
|
|
10
|
+
reports and user interfaces.
|
|
11
|
+
|
|
12
|
+
Args:
|
|
13
|
+
narrative: IncomeNarrative enum value
|
|
14
|
+
|
|
15
|
+
Returns:
|
|
16
|
+
Pretty-printed string representation:
|
|
17
|
+
- "-" for unspecified narratives
|
|
18
|
+
- Descriptive names for known types (e.g., "Yield", "Dividend")
|
|
19
|
+
- Empty string for unknown values
|
|
20
|
+
"""
|
|
21
|
+
if narrative == IncomeNarrative.INCOME_NARRATIVE_UNSPECIFIED:
|
|
22
|
+
return "-"
|
|
23
|
+
if narrative == IncomeNarrative.INCOME_NARRATIVE_YIELD:
|
|
24
|
+
return "Yield"
|
|
25
|
+
if narrative == IncomeNarrative.INCOME_NARRATIVE_DIVIDEND:
|
|
26
|
+
return "Dividend"
|
|
27
|
+
if narrative == IncomeNarrative.INCOME_NARRATIVE_INTEREST:
|
|
28
|
+
return "Interest"
|
|
29
|
+
if narrative == IncomeNarrative.INCOME_NARRATIVE_PRINCIPAL:
|
|
30
|
+
return "Principal"
|
|
31
|
+
if narrative == IncomeNarrative.INCOME_NARRATIVE_DISTRIBUTION:
|
|
32
|
+
return "Distribution"
|
|
33
|
+
if narrative == IncomeNarrative.INCOME_NARRATIVE_PROFIT_DISTRIBUTION:
|
|
34
|
+
return "Profit Distribution"
|
|
35
|
+
return ""
|