diff --git a/.flake8 b/.flake8 index b173e07f0..ea1bd4411 100644 --- a/.flake8 +++ b/.flake8 @@ -7,6 +7,9 @@ docstring-convention=google # E203 and W503 don't interact well with black ignore = D205,D212,D415,E203,W503 +exclude = + xrpl/openapi-codegen/* + # This is the line length that black uses # https://black.readthedocs.io/en/stable/the_black_code_style.html#line-length max-line-length = 88 diff --git a/mypy.ini b/mypy.ini index d1c0e9110..236f1ccdb 100644 --- a/mypy.ini +++ b/mypy.ini @@ -1,2 +1,2 @@ [mypy] -exclude = dist +exclude = ^(dist|xrpl/openapi-codegen) diff --git a/pyproject.toml b/pyproject.toml index 325162259..86cc2d7c9 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -79,6 +79,7 @@ build-backend = "poetry.core.masonry.api" [tool.coverage.run] branch = true source = ["xrpl"] +omit = ["xrpl/openapi-codegen/*"] [tool.coverage.report] show_missing = true diff --git a/xrpl/openapi-codegen/models/auth_account.py b/xrpl/openapi-codegen/models/auth_account.py new file mode 100644 index 000000000..01b0183b5 --- /dev/null +++ b/xrpl/openapi-codegen/models/auth_account.py @@ -0,0 +1,19 @@ +"""Model for AuthAccount.""" + +from dataclasses import dataclass +from xrpl.models.base_model import BaseModel +from xrpl.models.utils import REQUIRED +from xrpl.models.utils import require_kwargs_on_init + + +@require_kwargs_on_init +@dataclass(frozen=True) +class AuthAccount(BaseModel): + account: str = REQUIRED + """ + (Required) The address of the account to authorize. + """ + + def _get_errors(self: AuthAccount) -> Dict[str, str]: + errors = super._get_errors() + return errors diff --git a/xrpl/openapi-codegen/models/authorize_credentials.py b/xrpl/openapi-codegen/models/authorize_credentials.py new file mode 100644 index 000000000..d87c7f8cf --- /dev/null +++ b/xrpl/openapi-codegen/models/authorize_credentials.py @@ -0,0 +1,24 @@ +"""Model for AuthorizeCredentials.""" + +from dataclasses import dataclass +from xrpl.models.base_model import BaseModel +from xrpl.models.utils import REQUIRED +from xrpl.models.utils import require_kwargs_on_init + + +@require_kwargs_on_init +@dataclass(frozen=True) +class AuthorizeCredentials(BaseModel): + """ + Represents a credential used for preauthorization. + """ + + issuer: str = REQUIRED + """ + (Required) The issuer of the credential. + """ + + credential_type: str = REQUIRED + """ + (Required) The credential type of the credential. + """ diff --git a/xrpl/openapi-codegen/models/currency.py b/xrpl/openapi-codegen/models/currency.py new file mode 100644 index 000000000..8342b2a6b --- /dev/null +++ b/xrpl/openapi-codegen/models/currency.py @@ -0,0 +1,10 @@ +""" +The XRP Ledger has two kinds of money: XRP, and issued currencies. Both types have high + precision, although their formats are different. +""" + +from typing import Union +from xrpl.models.issued_currency import IssuedCurrency +from xrpl.models.xrp import XRP + +Currency = Union[IssuedCurrency, XRP] diff --git a/xrpl/openapi-codegen/models/issued_currency.py b/xrpl/openapi-codegen/models/issued_currency.py new file mode 100644 index 000000000..f93559907 --- /dev/null +++ b/xrpl/openapi-codegen/models/issued_currency.py @@ -0,0 +1,25 @@ +"""Model for IssuedCurrency.""" + +from dataclasses import dataclass +from typing import Optional +from xrpl.models.base_model import BaseModel +from xrpl.models.utils import require_kwargs_on_init + + +@require_kwargs_on_init +@dataclass(frozen=True) +class IssuedCurrency(BaseModel): + currency: Optional[str] = None + """ + Arbitrary currency code for the token. + """ + + issuer: Optional[str] = None + """ + Generally, the account that issues this token. In special cases, this can refer to the + account that holds the token instead (for example, in a Clawback transaction). + """ + + def _get_errors(self: IssuedCurrency) -> Dict[str, str]: + errors = super._get_errors() + return errors diff --git a/xrpl/openapi-codegen/models/memo.py b/xrpl/openapi-codegen/models/memo.py new file mode 100644 index 000000000..349345889 --- /dev/null +++ b/xrpl/openapi-codegen/models/memo.py @@ -0,0 +1,29 @@ +"""Model for Memo.""" + +from dataclasses import dataclass +from typing import Optional +from xrpl.models.base_model import BaseModel +from xrpl.models.utils import require_kwargs_on_init + + +@require_kwargs_on_init +@dataclass(frozen=True) +class Memo(BaseModel): + memo_data: Optional[str] = None + """ + Arbitrary hex value, conventionally containing the content of the memo. + """ + + memo_format: Optional[str] = None + """ + Hex value representing characters allowed in URLs. Conventionally containing information + on how the memo is encoded, for example as a [MIME + type](https://www.iana.org/assignments/media-types/media-types.xhtml). + """ + + memo_type: Optional[str] = None + """ + Hex value representing characters allowed in URLs. Conventionally, a unique relation + (according to [RFC 5988](https://datatracker.ietf.org/doc/html/rfc5988#section-4)) that + defines the format of this memo. + """ diff --git a/xrpl/openapi-codegen/models/path_step.py b/xrpl/openapi-codegen/models/path_step.py new file mode 100644 index 000000000..8f68e2e55 --- /dev/null +++ b/xrpl/openapi-codegen/models/path_step.py @@ -0,0 +1,47 @@ +"""Model for PathStep.""" + +from dataclasses import dataclass +from typing import Optional +from xrpl.models.base_model import BaseModel +from xrpl.models.utils import require_kwargs_on_init + + +@require_kwargs_on_init +@dataclass(frozen=True) +class PathStep(BaseModel): + """ + A PathStep represents an individual step along a Path. + """ + + account: Optional[str] = None + """ + (Optional) If present, this path step represents rippling through the specified address. + MUST NOT be provided if this step specifies the currency or issuer fields. + """ + + currency: Optional[str] = None + """ + (Optional) If present, this path step represents changing currencies through an order + book. The currency specified indicates the new currency. MUST NOT be provided if this + step specifies the account field. + """ + + issuer: Optional[str] = None + """ + (Optional) If present, this path step represents changing currencies and this address + defines the issuer of the new currency. If omitted in a step with a non-XRP currency, a + previous step of the path defines the issuer. If present when currency is omitted, + indicates a path step that uses an order book between same-named currencies with + different issuers. MUST be omitted if the currency is XRP. MUST NOT be provided if this + step specifies the account field. + """ + + type: Optional[int] = None + """ + DEPRECATED (Optional) An indicator of which other fields are present. + """ + + type_hex: Optional[str] = None + """ + DEPRECATED: (Optional) A hexadecimal representation of the type field. + """ diff --git a/xrpl/openapi-codegen/models/price_data.py b/xrpl/openapi-codegen/models/price_data.py new file mode 100644 index 000000000..a33586487 --- /dev/null +++ b/xrpl/openapi-codegen/models/price_data.py @@ -0,0 +1,59 @@ +"""Model for PriceData.""" + +from dataclasses import dataclass +from typing import Optional +from xrpl.models.base_model import BaseModel +from xrpl.models.utils import REQUIRED +from xrpl.models.utils import require_kwargs_on_init + + +@require_kwargs_on_init +@dataclass(frozen=True) +class PriceData(BaseModel): + base_asset: str = REQUIRED + """ + The primary asset in a trading pair (e.g., BTC in BTC/USD). Any valid identifier, such + as a stock symbol, bond CUSIP, or currency code, is allowed. + """ + + quote_asset: str = REQUIRED + """ + The quote asset in a trading pair, denoting the price of one unit of the base asset + (e.g., USD in BTC/USD). + """ + + asset_price: Optional[str] = None + """ + The asset price after applying the Scale precision level. Recommended to be provided as + a hexadecimal, but decimal numbers are accepted. Not included if the last update + transaction didn't include the BaseAsset/QuoteAsset pair. + """ + + scale: Optional[int] = None + """ + The scaling factor to apply to an asset price. If Scale is 6 and the original price is + 0.155, then the scaled price is 155000. Valid scale ranges are 0-10. Not included if + the last update transaction didn't include the BaseAsset/QuoteAsset pair. + """ + + def _get_errors(self: PriceData) -> Dict[str, str]: + errors = super._get_errors() + if (self.asset_price is not None) != (self.scale is not None): + errors["PriceData"] = ( + "Both `asset_price` and `scale` are required if any is presented." + ) + if ( + self.asset_price is not None + and self.asset_price != REQUIRED + and not self.asset_price.isnumeric() + ): + errors["PriceData"] = "`asset_price` must be numeric." + if self.scale is not None and self.scale < 0: + errors["PriceData"] = ( + "Field `scale` must have a value greater than or equal to 0" + ) + if self.scale is not None and self.scale > 10: + errors["PriceData"] = ( + "Field `scale` must have a value less than or equal to 10" + ) + return errors diff --git a/xrpl/openapi-codegen/models/requests/__init__.py b/xrpl/openapi-codegen/models/requests/__init__.py new file mode 100644 index 000000000..db32a2b21 --- /dev/null +++ b/xrpl/openapi-codegen/models/requests/__init__.py @@ -0,0 +1,21 @@ +"""Request models.""" + +from xrpl.models.requests.account_channels import AccountChannels +from xrpl.models.requests.account_info import AccountInfo +from xrpl.models.requests.account_lines import AccountLines +from xrpl.models.requests.lookup_by_ledger_request import LookupByLedgerRequest +from xrpl.models.requests.lookup_by_ledger_request import ( + LookupByLedgerRequestLedgerIndex, +) +from xrpl.models.requests.request import Request +from xrpl.models.requests.server_info import ServerInfo + +__all__ = [ + AccountChannels, + AccountInfo, + AccountLines, + LookupByLedgerRequest, + LookupByLedgerRequestLedgerIndex, + Request, + ServerInfo, +] diff --git a/xrpl/openapi-codegen/models/requests/account_channels.py b/xrpl/openapi-codegen/models/requests/account_channels.py new file mode 100644 index 000000000..7deb4b8a6 --- /dev/null +++ b/xrpl/openapi-codegen/models/requests/account_channels.py @@ -0,0 +1,57 @@ +"""Model for AccountChannels request type.""" + +from dataclasses import dataclass, field +from typing import Any, Optional, Union +from xrpl.models.requests.request import RequestMethod +from xrpl.models.utils import REQUIRED +from xrpl.models.requests.base_request import BaseRequest +from xrpl.models.requests.lookup_by_ledger import LookupByLedgerRequest +from xrpl.models.utils import require_kwargs_on_init + + +@require_kwargs_on_init +@dataclass(frozen=True) +class AccountChannels(BaseRequest, LookupByLedgerRequest): + """ + The account_channels method returns information about an account's Payment Channels. + This includes only channels where the specified account is the channel's source, not the + destination. (A channel's source and owner are the same.) All information retrieved is + relative to a particular version of the ledger. Returns an AccountChannelsResponse. + """ + + method: RequestMethod = field(default=RequestMethod.ACCOUNT_CHANNELS, init=False) + + account: str = REQUIRED + """ + The unique identifier of an account, typically the account's address. + """ + + destination_account: Optional[str] = None + """ + The unique identifier of an account, typically the account's address. If provided, + filter results to payment channels whose destination is this account. + """ + + limit: Optional[Union[float, int]] = None + """ + Limit the number of transactions to retrieve. Cannot be less than 10 or more than 400. + The default is 200. + """ + + marker: Optional[Any] = None + """ + Value from a previous paginated response. Resume retrieving data where that response + left off. + """ + + def _get_errors(self: AccountChannels) -> Dict[str, str]: + errors = super._get_errors() + if self.limit is not None and self.limit < 10: + errors["AccountChannels"] = ( + "Field `limit` must have a value greater than or equal to 10" + ) + if self.limit is not None and self.limit > 400: + errors["AccountChannels"] = ( + "Field `limit` must have a value less than or equal to 400" + ) + return errors diff --git a/xrpl/openapi-codegen/models/requests/account_info.py b/xrpl/openapi-codegen/models/requests/account_info.py new file mode 100644 index 000000000..08cb2fa71 --- /dev/null +++ b/xrpl/openapi-codegen/models/requests/account_info.py @@ -0,0 +1,40 @@ +"""Model for AccountInfo request type.""" + +from dataclasses import dataclass, field +from typing import Optional +from xrpl.models.requests.request import RequestMethod +from xrpl.models.utils import REQUIRED +from xrpl.models.requests.base_request import BaseRequest +from xrpl.models.requests.lookup_by_ledger import LookupByLedgerRequest +from xrpl.models.utils import require_kwargs_on_init + + +@require_kwargs_on_init +@dataclass(frozen=True) +class AccountInfo(BaseRequest, LookupByLedgerRequest): + """ + The account_info command retrieves information about an account, its activity, and its + XRP balance. All information retrieved is relative to a particular version of the + ledger. Returns an AccountInfoResponse + """ + + method: RequestMethod = field(default=RequestMethod.ACCOUNT_INFO, init=False) + + account: str = REQUIRED + """ + The account to look up. + """ + + queue: Optional[bool] = None + """ + If true, return stats about queued transactions sent by this account. Can only be used + when querying for the data from the current open ledger. Not available from servers in + Reporting Mode. + """ + + signer_lists: Optional[bool] = None + """ + API v1: If true, return any SignerList objects associated with this account. API v2: + Identical to v1, but also returns an invalidParams error if you provide a non-boolean + value. + """ diff --git a/xrpl/openapi-codegen/models/requests/account_lines.py b/xrpl/openapi-codegen/models/requests/account_lines.py new file mode 100644 index 000000000..aea7c581c --- /dev/null +++ b/xrpl/openapi-codegen/models/requests/account_lines.py @@ -0,0 +1,44 @@ +"""Model for AccountLines request type.""" + +from dataclasses import dataclass, field +from typing import Any, Dict, Optional +from xrpl.models.requests.request import RequestMethod +from xrpl.models.utils import REQUIRED +from xrpl.models.requests.base_request import BaseRequest +from xrpl.models.requests.lookup_by_ledger import LookupByLedgerRequest +from xrpl.models.utils import require_kwargs_on_init + + +@require_kwargs_on_init +@dataclass(frozen=True) +class AccountLines(BaseRequest, LookupByLedgerRequest): + """ + The account_lines command retrieves information about an account's trust lines, + including balances in all non-XRP currencies and assets. All information retrieved is + relative to a particular version of the ledger. Returns an AccountLinesResponse + """ + + method: RequestMethod = field(default=RequestMethod.ACCOUNT_LINES, init=False) + + account: str = REQUIRED + """ + The account to look up trust lines for. + """ + + peer: Optional[str] = None + """ + (Optional) A second account; if provided, filter results to trust lines connecting the + two accounts. + """ + + limit: Optional[int] = None + """ + (Optional) Limit the number of trust lines to retrieve. Must be within the inclusive + range 10 to 400. Default is 200. + """ + + marker: Optional[Dict[str, Any]] = None + """ + (Optional) Value from a previous paginated response. Resume retrieving data where that + response left off. + """ diff --git a/xrpl/openapi-codegen/models/requests/base_request.py b/xrpl/openapi-codegen/models/requests/base_request.py new file mode 100644 index 000000000..a494d1204 --- /dev/null +++ b/xrpl/openapi-codegen/models/requests/base_request.py @@ -0,0 +1,19 @@ +"""Model for Request.""" + +from dataclasses import dataclass +from typing import Optional +from xrpl.models.base_model import BaseModel +from xrpl.models.utils import require_kwargs_on_init + + +@require_kwargs_on_init +@dataclass(frozen=True) +class Request(BaseModel): + """ + Information which could be included in every request sent to rippled + """ + + api_version: Optional[int] = None + """ + The API version to use. If omitted, uses version 1. + """ diff --git a/xrpl/openapi-codegen/models/requests/lookup_by_ledger.py b/xrpl/openapi-codegen/models/requests/lookup_by_ledger.py new file mode 100644 index 000000000..e195cbf96 --- /dev/null +++ b/xrpl/openapi-codegen/models/requests/lookup_by_ledger.py @@ -0,0 +1,21 @@ +"""Model for LookupByLedgerRequest.""" + +from dataclasses import dataclass +from typing import Optional, Union +from xrpl.models.base_model import BaseModel +from xrpl.models.utils import require_kwargs_on_init + + +@require_kwargs_on_init +@dataclass(frozen=True) +class LookupByLedgerRequest(BaseModel): + """ + Additional information shared in requests which search for specific ledger data. + """ + + ledger_hash: Optional[str] = None + """ + A 20-byte hex string for the ledger version to use. + """ + + ledger_index: Optional[Union[str, int]] = None diff --git a/xrpl/openapi-codegen/models/requests/lookup_by_ledger_ledger_index.py b/xrpl/openapi-codegen/models/requests/lookup_by_ledger_ledger_index.py new file mode 100644 index 000000000..13de97789 --- /dev/null +++ b/xrpl/openapi-codegen/models/requests/lookup_by_ledger_ledger_index.py @@ -0,0 +1,7 @@ +""" +The ledger index of the ledger to use, or a shortcut string. +""" + +from typing import Union + +LookupByLedgerRequestLedgerIndex = Union[int, str] diff --git a/xrpl/openapi-codegen/models/requests/server_info.py b/xrpl/openapi-codegen/models/requests/server_info.py new file mode 100644 index 000000000..2d75fef91 --- /dev/null +++ b/xrpl/openapi-codegen/models/requests/server_info.py @@ -0,0 +1,24 @@ +"""Model for ServerInfo request type.""" + +from dataclasses import dataclass, field +from typing import Optional +from xrpl.models.base_model import BaseModel +from xrpl.models.requests.request import RequestMethod +from xrpl.models.utils import require_kwargs_on_init + + +@require_kwargs_on_init +@dataclass(frozen=True) +class ServerInfo(BaseModel): + """ + The server_info command asks the server for a human-readable version of various + information about the rippled server being queried. + """ + + method: RequestMethod = field(default=RequestMethod.SERVER_INFO, init=False) + + counters: Optional[bool] = None + """ + If true, return metrics about the job queue, ledger store, and API method activity. The + default is false. + """ diff --git a/xrpl/openapi-codegen/models/requests/submit_base.py b/xrpl/openapi-codegen/models/requests/submit_base.py new file mode 100644 index 000000000..1f9a5548b --- /dev/null +++ b/xrpl/openapi-codegen/models/requests/submit_base.py @@ -0,0 +1,31 @@ +"""Model for SubmitBase request type.""" + +from dataclasses import dataclass, field +from xrpl.models.base_model import BaseModel +from xrpl.models.requests.request import RequestMethod +from xrpl.models.utils import require_kwargs_on_init + + +@require_kwargs_on_init +@dataclass(frozen=True) +class SubmitBase(BaseModel): + """ + The submit method applies a transaction and sends it to the network to be confirmed and + included in future ledgers. This command has two modes: - Submit-only mode takes a + signed, serialized transaction as a binary blob, and submits it to the network as-is. + Since signed transaction objects are immutable, no part of the transaction can be + modified or automatically filled in after submission. - Sign-and-submit mode takes a + JSON-formatted Transaction object, completes and signs the transaction in the same + manner as the sign method, and then submits the signed transaction. We recommend only + using this mode for testing and development. To send a transaction as robustly as + possible, you should construct and sign it in advance, persist it somewhere that you can + access even after a power outage, then submit it as a tx_blob. After submission, monitor + the network with the tx method command to see if the transaction was successfully + applied; if a restart or other problem occurs, you can safely re-submit the tx_blob + transaction: it won't be applied twice since it has the same sequence number as the old + transaction. + """ + + method: RequestMethod = field(default=RequestMethod.SUBMIT, init=False) + + method: str diff --git a/xrpl/openapi-codegen/models/requests/submit_v1.py b/xrpl/openapi-codegen/models/requests/submit_v1.py new file mode 100644 index 000000000..71a847c73 --- /dev/null +++ b/xrpl/openapi-codegen/models/requests/submit_v1.py @@ -0,0 +1,5 @@ +from typing import Union +from xrpl.models.sign_and_submit_mode_v1 import SignAndSubmitModeV1 +from xrpl.models.submit_only_mode import SubmitOnlyMode + +SubmitRequestV1 = Union[SignAndSubmitModeV1, SubmitOnlyMode] diff --git a/xrpl/openapi-codegen/models/sign_and_submit_mode_base.py b/xrpl/openapi-codegen/models/sign_and_submit_mode_base.py new file mode 100644 index 000000000..33c38643d --- /dev/null +++ b/xrpl/openapi-codegen/models/sign_and_submit_mode_base.py @@ -0,0 +1,86 @@ +"""Model for SignAndSubmitModeBase.""" + +from dataclasses import dataclass +from typing import Optional +from xrpl.models.base_model import BaseModel +from xrpl.models.utils import require_kwargs_on_init + + +@require_kwargs_on_init +@dataclass(frozen=True) +class SignAndSubmitModeBase(BaseModel): + """ + A mode for signing a transaction and immediately submitting it. This mode is intended + for testing. + """ + + secret: Optional[str] = None + """ + (Optional) Secret key of the account supplying the transaction, used to sign it. Do not + send your secret to untrusted servers or through unsecured network connections. Cannot + be used with key_type, seed, seed_hex, or passphrase. + """ + + seed: Optional[str] = None + """ + (Optional) Secret key of the account supplying the transaction, used to sign it. Must be + in the XRP Ledger's base58 format. If provided, you must also specify the key_type. + Cannot be used with secret, seed_hex, or passphrase. + """ + + seed_hex: Optional[str] = None + """ + (Optional) Secret key of the account supplying the transaction, used to sign it. Must be + in hexadecimal format. If provided, you must also specify the key_type. Cannot be used + with secret, seed, or passphrase. + """ + + passphrase: Optional[str] = None + """ + (Optional) Secret key of the account supplying the transaction, used to sign it, as a + string passphrase. If provided, you must also specify the key_type. Cannot be used with + secret, seed, or seed_hex. + """ + + key_type: Optional[str] = None + """ + (Optional) Type of cryptographic key provided in this request. Valid types are secp256k1 + or ed25519. Defaults to secp256k1. Cannot be used with secret. Caution: Ed25519 support + is experimental. + """ + + fail_hard: Optional[bool] = None + """ + (Optional) If true, and the transaction fails locally, do not retry or relay the + transaction to other servers. Default is false. Updated in: rippled 1.5.0 + """ + + offline: Optional[bool] = None + """ + (Optional) If true, when constructing the transaction, do not try to automatically fill + in or validate values. Default is false. + """ + + build_path: Optional[bool] = None + """ + (Optional) If this field is provided, the server auto-fills the Paths field of a Payment + transaction before signing. Omit this field if the transaction is a direct XRP payment + or if it is not a Payment-type transaction. Caution: The server looks for the presence + or absence of this field, not its value. This behavior may change. (Issue #3272) + """ + + fee_mult_max: Optional[int] = None + """ + (Optional) Sign-and-submit fails with the error rpcHIGH_FEE if the auto-filled Fee value + would be greater than the reference transaction cost x fee_mult_max ÷ fee_div_max. This + field has no effect if you explicitly specify the Fee field of the transaction. Default + is 10. + """ + + fee_div_max: Optional[int] = None + """ + (Optional) Sign-and-submit fails with the error rpcHIGH_FEE if the auto-filled Fee value + would be greater than the reference transaction cost x fee_mult_max ÷ fee_div_max. This + field has no effect if you explicitly specify the Fee field of the transaction. Default + is 1. + """ diff --git a/xrpl/openapi-codegen/models/sign_and_submit_mode_v1.py b/xrpl/openapi-codegen/models/sign_and_submit_mode_v1.py new file mode 100644 index 000000000..011d1bc71 --- /dev/null +++ b/xrpl/openapi-codegen/models/sign_and_submit_mode_v1.py @@ -0,0 +1,16 @@ +"""Model for SignAndSubmitModeV1.""" + +from dataclasses import dataclass +from typing import Any, Dict +from xrpl.models.utils import REQUIRED +from xrpl.models.sign_and_submit_mode_base import SignAndSubmitModeBase +from xrpl.models.utils import require_kwargs_on_init + + +@require_kwargs_on_init +@dataclass(frozen=True) +class SignAndSubmitModeV1(SignAndSubmitModeBase): + tx_json: Dict[str, Any] = REQUIRED + """ + Transaction definition in JSON format, optionally omitting any auto-fillable fields. + """ diff --git a/xrpl/openapi-codegen/models/submit_only_mode.py b/xrpl/openapi-codegen/models/submit_only_mode.py new file mode 100644 index 000000000..f034e38e8 --- /dev/null +++ b/xrpl/openapi-codegen/models/submit_only_mode.py @@ -0,0 +1,27 @@ +"""Model for SubmitOnlyMode.""" + +from dataclasses import dataclass +from typing import Optional +from xrpl.models.base_model import BaseModel +from xrpl.models.utils import REQUIRED +from xrpl.models.utils import require_kwargs_on_init + + +@require_kwargs_on_init +@dataclass(frozen=True) +class SubmitOnlyMode(BaseModel): + """ + A submit-only request for submitting transactions. + """ + + tx_blob: str = REQUIRED + """ + Hex representation of the signed transaction to submit. Can be a multi-signed + transaction. + """ + + fail_hard: Optional[bool] = None + """ + If true, and the transaction fails locally, do not retry or relay the transaction to + other servers. Default is false. + """ diff --git a/xrpl/openapi-codegen/models/token_amount.py b/xrpl/openapi-codegen/models/token_amount.py new file mode 100644 index 000000000..c120efec8 --- /dev/null +++ b/xrpl/openapi-codegen/models/token_amount.py @@ -0,0 +1,47 @@ +"""Model for TokenAmount.""" + +from dataclasses import dataclass +from typing import Optional +from xrpl.models.base_model import BaseModel +from xrpl.models.utils import require_kwargs_on_init + + +@require_kwargs_on_init +@dataclass(frozen=True) +class TokenAmount(BaseModel): + """ + Specifies an amount of a (fungible) token. + """ + + currency: Optional[str] = None + """ + Arbitrary currency code for the token. Cannot be XRP. + """ + + value: Optional[str] = None + """ + Quoted decimal representation of the amount of the token. This can include scientific + notation, such as 1.23e11 meaning 123,000,000,000. Both e and E may be used. This can be + negative when displaying balances, but negative values are disallowed in other contexts + such as specifying how much to send. + """ + + issuer: Optional[str] = None + """ + Generally, the account that issues this token. In special cases, this can refer to the + account that holds the token instead (for example, in a Clawback transaction). + """ + + def _get_errors(self: TokenAmount) -> Dict[str, str]: + errors = super._get_errors() + if ( + self.value is not None + and self.value != REQUIRED + and not self.value.isnumeric() + ): + errors["TokenAmount"] = "`value` must be numeric." + if not re.match(r"/^[-+]?[0-9]*\.?[0-9]+([eE][-+]?[0-9]+)?$/", self.value): + errors["TokenAmount"] = ( + "Field `value` must match the pattern `/^[-+]?[0-9]*\.?[0-9]+([eE][-+]?[0-9]+)?$/`" + ) + return errors diff --git a/xrpl/openapi-codegen/models/transactions/__init__.py b/xrpl/openapi-codegen/models/transactions/__init__.py new file mode 100644 index 000000000..bf968c356 --- /dev/null +++ b/xrpl/openapi-codegen/models/transactions/__init__.py @@ -0,0 +1,156 @@ +""" +Model objects for specific `types of Transactions +`_ in the XRP Ledger. +""" + +from xrpl.models.transactions.account_delete import AccountDelete +from xrpl.models.transactions.account_set import AccountSet +from xrpl.models.transactions.account_set import AccountSetAsfFlag +from xrpl.models.transactions.account_set import AccountSetFlag +from xrpl.models.transactions.amm_bid import AMMBid +from xrpl.models.transactions.amm_bid import AuthAccount +from xrpl.models.transactions.amm_create import AMMCreate +from xrpl.models.transactions.amm_delete import AMMDelete +from xrpl.models.transactions.amm_deposit import AMMDeposit +from xrpl.models.transactions.amm_deposit import AMMDepositFlag +from xrpl.models.transactions.amm_vote import AMMVote +from xrpl.models.transactions.amm_withdraw import AMMWithdraw +from xrpl.models.transactions.amm_withdraw import AMMWithdrawFlag +from xrpl.models.transactions.check_cancel import CheckCancel +from xrpl.models.transactions.check_cash import CheckCash +from xrpl.models.transactions.check_create import CheckCreate +from xrpl.models.transactions.clawback import Clawback +from xrpl.models.transactions.clawback import TokenAmount +from xrpl.models.transactions.credential_accept import CredentialAccept +from xrpl.models.transactions.credential_create import CredentialCreate +from xrpl.models.transactions.credential_delete import CredentialDelete +from xrpl.models.transactions.deposit_preauth import DepositPreauth +from xrpl.models.transactions.did_delete import DIDDelete +from xrpl.models.transactions.did_set import DIDSet +from xrpl.models.transactions.escrow_cancel import EscrowCancel +from xrpl.models.transactions.escrow_create import EscrowCreate +from xrpl.models.transactions.escrow_finish import EscrowFinish +from xrpl.models.transactions.mptoken_authorize import MPTokenAuthorize +from xrpl.models.transactions.mptoken_authorize import MPTokenAuthorizeFlag +from xrpl.models.transactions.mptoken_issuance_create import MPTokenIssuanceCreate +from xrpl.models.transactions.mptoken_issuance_create import MPTokenIssuanceCreateFlag +from xrpl.models.transactions.mptoken_issuance_destroy import MPTokenIssuanceDestroy +from xrpl.models.transactions.mptoken_issuance_set import MPTokenIssuanceSet +from xrpl.models.transactions.mptoken_issuance_set import MPTokenIssuanceSetFlag +from xrpl.models.transactions.nftoken_accept_offer import NFTokenAcceptOffer +from xrpl.models.transactions.nftoken_burn import NFTokenBurn +from xrpl.models.transactions.nftoken_cancel_offer import NFTokenCancelOffer +from xrpl.models.transactions.nftoken_create_offer import NFTokenCreateOffer +from xrpl.models.transactions.nftoken_create_offer import NFTokenCreateOfferFlag +from xrpl.models.transactions.nftoken_mint import NFTokenMint +from xrpl.models.transactions.nftoken_mint import NFTokenMintFlag +from xrpl.models.transactions.offer_cancel import OfferCancel +from xrpl.models.transactions.offer_create import OfferCreate +from xrpl.models.transactions.offer_create import OfferCreateFlag +from xrpl.models.transactions.oracle_delete import OracleDelete +from xrpl.models.transactions.oracle_set import OracleSet +from xrpl.models.transactions.oracle_set import PriceData +from xrpl.models.transactions.payment import Payment +from xrpl.models.transactions.payment import PaymentFlag +from xrpl.models.transactions.payment_channel_claim import PaymentChannelClaim +from xrpl.models.transactions.payment_channel_claim import PaymentChannelClaimFlag +from xrpl.models.transactions.payment_channel_create import PaymentChannelCreate +from xrpl.models.transactions.payment_channel_fund import PaymentChannelFund +from xrpl.models.transactions.set_regular_key import SetRegularKey +from xrpl.models.transactions.ticket_create import TicketCreate +from xrpl.models.transactions.transaction import Memo +from xrpl.models.transactions.transaction import Transaction +from xrpl.models.transactions.trust_set import TrustSet +from xrpl.models.transactions.trust_set import TrustSetFlag +from xrpl.models.transactions.xchain_account_create_commit import ( + XChainAccountCreateCommit, +) +from xrpl.models.transactions.xchain_account_create_commit import XChainBridge +from xrpl.models.transactions.xchain_add_account_create_attestation import ( + XChainAddAccountCreateAttestation, +) +from xrpl.models.transactions.xchain_add_account_create_attestation import XChainBridge +from xrpl.models.transactions.xchain_add_claim_attestation import ( + XChainAddClaimAttestation, +) +from xrpl.models.transactions.xchain_add_claim_attestation import XChainBridge +from xrpl.models.transactions.xchain_claim import XChainBridge +from xrpl.models.transactions.xchain_claim import XChainClaim +from xrpl.models.transactions.xchain_commit import XChainBridge +from xrpl.models.transactions.xchain_commit import XChainCommit +from xrpl.models.transactions.xchain_create_bridge import XChainBridge +from xrpl.models.transactions.xchain_create_bridge import XChainCreateBridge +from xrpl.models.transactions.xchain_modify_bridge import XChainBridge +from xrpl.models.transactions.xchain_modify_bridge import XChainModifyBridge +from xrpl.models.transactions.xchain_modify_bridge import XChainModifyBridgeFlag + +__all__ = [ + AMMBid, + AMMCreate, + AMMDelete, + AMMDeposit, + AMMDepositFlag, + AMMVote, + AMMWithdraw, + AMMWithdrawFlag, + AccountDelete, + AccountSet, + AccountSetAsfFlag, + AccountSetFlag, + AuthAccount, + CheckCancel, + CheckCash, + CheckCreate, + Clawback, + CredentialAccept, + CredentialCreate, + CredentialDelete, + DIDDelete, + DIDSet, + DepositPreauth, + EscrowCancel, + EscrowCreate, + EscrowFinish, + MPTokenAuthorize, + MPTokenAuthorizeFlag, + MPTokenIssuanceCreate, + MPTokenIssuanceCreateFlag, + MPTokenIssuanceDestroy, + MPTokenIssuanceSet, + MPTokenIssuanceSetFlag, + Memo, + NFTokenAcceptOffer, + NFTokenBurn, + NFTokenCancelOffer, + NFTokenCreateOffer, + NFTokenCreateOfferFlag, + NFTokenMint, + NFTokenMintFlag, + OfferCancel, + OfferCreate, + OfferCreateFlag, + OracleDelete, + OracleSet, + Payment, + PaymentChannelClaim, + PaymentChannelClaimFlag, + PaymentChannelCreate, + PaymentChannelFund, + PaymentFlag, + PriceData, + SetRegularKey, + TicketCreate, + TokenAmount, + Transaction, + TrustSet, + TrustSetFlag, + XChainAccountCreateCommit, + XChainAddAccountCreateAttestation, + XChainAddClaimAttestation, + XChainBridge, + XChainClaim, + XChainCommit, + XChainCreateBridge, + XChainModifyBridge, + XChainModifyBridgeFlag, +] diff --git a/xrpl/openapi-codegen/models/transactions/account_delete.py b/xrpl/openapi-codegen/models/transactions/account_delete.py new file mode 100644 index 000000000..faed6ae73 --- /dev/null +++ b/xrpl/openapi-codegen/models/transactions/account_delete.py @@ -0,0 +1,58 @@ +"""Model for AccountDelete transaction type.""" + +from dataclasses import dataclass, field +from typing import List, Optional +from xrpl.models.transactions.types import TransactionType +from xrpl.models.utils import REQUIRED +from xrpl.models.transactions.transaction import Transaction +from xrpl.models.utils import require_kwargs_on_init + + +@require_kwargs_on_init +@dataclass(frozen=True) +class AccountDelete(Transaction): + """ + An AccountDelete transaction deletes an account and any objects it owns in the XRP + Ledger, if possible, sending the account's remaining XRP to a specified destination + account. + """ + + transaction_type: TransactionType = field( + default=TransactionType.ACCOUNT_DELETE, init=False + ) + + credential_ids: Optional[List[str]] = None + """ + (Optional) Set of Credentials to authorize a deposit made by this transaction. Each + member of the array must be the ledger entry ID of a Credential entry in the ledger. For + details, see Credential IDs. + """ + + destination: str = REQUIRED + """ + (Required) The address of an account to receive any leftover XRP after deleting the + sending account. Must be a funded account in the ledger, and must not be the sending + account. + """ + + destination_tag: Optional[int] = None + """ + (Optional) Arbitrary destination tag that identifies a hosted recipient or other + information for the recipient of the deleted account's leftover XRP. + """ + + def _get_errors(self: AccountDelete) -> Dict[str, str]: + errors = super._get_errors() + if self.credential_ids is not None and len(self.credential_ids) < 1: + errors["AccountDelete"] = ( + "Field `credential_ids` must have a length greater than or equal to 1" + ) + if self.credential_ids is not None and len(self.credential_ids) > 8: + errors["AccountDelete"] = ( + "Field `credential_ids` must have a length less than or equal to 8" + ) + if len(self.credential_ids) != len(set(self.credential_ids)): + errors["AccountDelete"] = ( + "`credential_ids` list cannot contain duplicate values" + ) + return errors diff --git a/xrpl/openapi-codegen/models/transactions/account_set.py b/xrpl/openapi-codegen/models/transactions/account_set.py new file mode 100644 index 000000000..b33de71f0 --- /dev/null +++ b/xrpl/openapi-codegen/models/transactions/account_set.py @@ -0,0 +1,269 @@ +"""Model for AccountSet transaction type.""" + +from dataclasses import dataclass, field +from enum import Enum +from typing import Optional +from xrpl.models.transactions.types import TransactionType +from xrpl.models.account_set_asf_flag import AccountSetAsfFlag +from xrpl.models.account_set_flag import AccountSetFlag +from xrpl.models.transactions.transaction import Transaction +from xrpl.models.utils import require_kwargs_on_init + + +@require_kwargs_on_init +@dataclass(frozen=True) +class AccountSet(Transaction): + """ + An AccountSet transaction modifies the properties of an account in the XRP Ledger. + """ + + transaction_type: TransactionType = field( + default=TransactionType.ACCOUNT_SET, init=False + ) + + clear_flag: Optional[AccountSetAsfFlag] = None + """ + (Optional) Unique identifier of a flag to disable for this account. + """ + + domain: Optional[str] = None + """ + (Optional) The domain that owns this account, as a string of hex representing the ASCII + for the domain in lowercase. Cannot be more than 256 bytes in length. + """ + + email_hash: Optional[str] = None + """ + (Optional) An arbitrary 128-bit value. Conventionally, clients treat this as the md5 + hash of an email address to use for displaying a Gravatar image. + """ + + message_key: Optional[str] = None + """ + (Optional) Public key for sending encrypted messages to this account. To set the key, it + must be exactly 33 bytes, with the first byte indicating the key type: 0x02 or 0x03 for + secp256k1 keys, 0xED for Ed25519 keys. To remove the key, use an empty value. + """ + + nf_token_minter: Optional[str] = None + """ + (Optional) Another account that can mint NFTokens for you. (Added by the + NonFungibleTokensV1_1 amendment.) + """ + + set_flag: Optional[AccountSetAsfFlag] = None + """ + (Optional) Integer flag to enable for this account. + """ + + transfer_rate: Optional[int] = None + """ + (Optional) The fee to charge when users transfer this account's tokens, represented as + billionths of a unit. Cannot be more than 2000000000 or less than 1000000000, except for + the special case 0 meaning no fee. + """ + + tick_size: Optional[int] = None + """ + (Optional) Tick size to use for offers involving a currency issued by this address. The + exchange rates of those offers is rounded to this many significant digits. Valid values + are 3 to 15 inclusive, or 0 to disable. (Added by the TickSize amendment.) + """ + + wallet_locator: Optional[str] = None + """ + (Optional) An arbitrary 256-bit value. If specified, the value is stored as part of the + account but has no inherent meaning or requirements. + """ + + wallet_size: Optional[int] = None + """ + (Optional) Not used. This field is valid in AccountSet transactions but does nothing. + """ + + def _get_errors(self: AccountSet) -> Dict[str, str]: + errors = super._get_errors() + if self.set_flag is not None and self.set_flag == self.clear_flag: + errors[AccountSet] = "set_flag must not be equal to clear_flag." + # This check is only applicable if the flag belongs to the `flags` field inherited from base Transaction. + # For other cases such as `set_flag` or `clear_flag` field in account_info transaction, please fix accordingly. + if ( + self.has_flag(AccountSetFlag.ASF_AUTHORIZED_NFTOKEN_MINTER) + and self.nftoken_minter is None + ): + errors["AccountSet"] = ( + "`nftoken_minter` must be set with flag `ASF_AUTHORIZED_NFTOKEN_MINTER`" + ) + # This check is only applicable if the flag belongs to the `flags` field inherited from base Transaction. + # For other cases such as `set_flag` or `clear_flag` field in account_info transaction, please fix accordingly. + if ( + not self.has_flag(AccountSetFlag.ASF_AUTHORIZED_NFTOKEN_MINTER) + and self.nftoken_minter is not None + ): + errors["AccountSet"] = ( + "`nftoken_minter` must not be set without flag `ASF_AUTHORIZED_NFTOKEN_MINTER`" + ) + # This check is only applicable if the flag belongs to the `flags` field inherited from base Transaction. + # For other cases such as `set_flag` or `clear_flag` field in account_info transaction, please fix accordingly. + if ( + self.has_flag(AccountSetFlag.ASF_AUTHORIZED_NFTOKEN_MINTER) + and self.nftoken_minter is not None + ): + errors["AccountSet"] = ( + "`nftoken_minter` must not be set with flag `ASF_AUTHORIZED_NFTOKEN_MINTER`" + ) + if self.domain is not None and self.domain.lower() != self.domain: + return f"domain {self.domain} is not lowercase" + if self.domain is not None and len(self.domain) > 256: + errors["AccountSet"] = ( + "Field `domain` must have a length less than or equal to 256" + ) + if self.transfer_rate is not None and self.transfer_rate != 0: + if self.transfer_rate < 1000000000: + errors["AccountSet"] = ( + "Field `transfer_rate` must have a value greater than or equal to 1000000000" + ) + if self.transfer_rate > 2000000000: + errors["AccountSet"] = ( + "Field `transfer_rate` must have a value less than or equal to 2000000000" + ) + if self.tick_size is not None and self.tick_size != 0: + if self.tick_size < 3: + errors["AccountSet"] = ( + "Field `tick_size` must have a value greater than or equal to 3" + ) + if self.tick_size > 15: + errors["AccountSet"] = ( + "Field `tick_size` must have a value less than or equal to 15" + ) + return errors + + +class AccountSetFlagInterface(FlagInterface): + """ + Enum for AccountSet Transaction Flags. + """ + + TF_REQUIRE_DEST_TAG: bool + TF_OPTIONAL_DEST_TAG: bool + TF_REQUIRE_AUTH: bool + TF_OPTIONAL_AUTH: bool + TF_DISALLOW_XRP: bool + TF_ALLOW_XRP: bool + + +class AccountSetFlag(int, Enum): + """ + Enum for AccountSet Transaction Flags. + """ + + TF_REQUIRE_DEST_TAG = 0x00010000 + """ + The same as SetFlag: asfRequireDest. + """ + + TF_OPTIONAL_DEST_TAG = 0x00020000 + """ + The same as ClearFlag: asfRequireDest. + """ + + TF_REQUIRE_AUTH = 0x00040000 + """ + The same as SetFlag: asfRequireAuth. + """ + + TF_OPTIONAL_AUTH = 0x00080000 + """ + The same as ClearFlag: asfRequireAuth. + """ + + TF_DISALLOW_XRP = 0x00100000 + """ + The same as SetFlag: asfDisallowXRP. + """ + + TF_ALLOW_XRP = 0x00200000 + """ + The same as ClearFlag: asfDisallowXRP. + """ + + +class AccountSetAsfFlag(int, Enum): + """ + Enum for AccountSet Flags. + """ + + ASF_ACCOUNT_TXN_ID = 5 + """ + Track the ID of this account's most recent transaction. Required for AccountTxnID. + """ + + ASF_ALLOW_TRUSTLINE_CLAWBACK = 16 + """ + Allow account to claw back tokens it has issued. (Requires the Clawback amendment.) + """ + + ASF_AUTHORIZED_NFTOKEN_MINTER = 10 + """ + Enable to allow another account to mint non-fungible tokens (NFTokens) on this account's behalf. + """ + + ASF_DEFAULT_RIPPLE = 8 + """ + Enable rippling on this account's trust lines by default. + """ + + ASF_DEPOSIT_AUTH = 9 + """ + Enable Deposit Authorization on this account. (Added by the DepositAuth amendment.) + """ + + ASF_DISABLE_MASTER = 4 + """ + Disallow use of the master key pair. Can only be enabled if the account has configured another way to sign transactions. + """ + + ASF_DISALLOW_INCOMING_CHECK = 13 + """ + Block incoming Checks. (Requires the DisallowIncoming amendment.) + """ + + ASF_DISALLOW_INCOMING_NFTOKEN_OFFER = 12 + """ + Block incoming NFTokenOffers. (Requires the DisallowIncoming amendment.) + """ + + ASF_DISALLOW_INCOMING_PAY_CHAN = 14 + """ + Block incoming Payment Channels. (Requires the DisallowIncoming amendment.) + """ + + ASF_DISALLOW_INCOMING_TRUSTLINE = 15 + """ + Block incoming trust lines. (Requires the DisallowIncoming amendment.) + """ + + ASF_DISALLOW_XRP = 3 + """ + XRP should not be sent to this account. (Advisory; not enforced by the XRP Ledger protocol.) + """ + + ASF_GLOBAL_FREEZE = 7 + """ + Freeze all assets issued by this account. + """ + + ASF_NO_FREEZE = 6 + """ + Permanently give up the ability to freeze individual trust lines or disable Global Freeze. + """ + + ASF_REQUIRE_AUTH = 2 + """ + Require authorization for users to hold balances issued by this address. + """ + + ASF_REQUIRE_DEST = 1 + """ + Require a destination tag to send transactions to this account. + """ diff --git a/xrpl/openapi-codegen/models/transactions/amm_bid.py b/xrpl/openapi-codegen/models/transactions/amm_bid.py new file mode 100644 index 000000000..cad8f8f4e --- /dev/null +++ b/xrpl/openapi-codegen/models/transactions/amm_bid.py @@ -0,0 +1,68 @@ +"""Model for AMMBid transaction type.""" + +from dataclasses import dataclass, field +from typing import Any, List, Optional +from xrpl.models.transactions.types import TransactionType +from xrpl.models.utils import REQUIRED +from xrpl.models.auth_account import AuthAccount +from xrpl.models.currency import Currency +from xrpl.models.transactions.transaction import Transaction +from xrpl.models.utils import require_kwargs_on_init + + +@require_kwargs_on_init +@dataclass(frozen=True) +class AMMBid(Transaction): + """ + Bid on an Automated Market Maker's (AMM's) auction slot. If you win, you can trade + against the AMM at a discounted fee until you are outbid or 24 hours have passed. If + you are outbid before 24 hours have passed, you are refunded part of the cost of your + bid based on how much time remains. If the AMM's trading fee is zero, you can still + bid, but the auction slot provides no benefit unless the trading fee changes. You bid + using the AMM's LP Tokens; the amount of a winning bid is returned to the AMM, + decreasing the outstanding balance of LP Tokens. + """ + + transaction_type: TransactionType = field( + default=TransactionType.AMM_BID, init=False + ) + + asset: Currency = REQUIRED + """ + (Required) The definition for one of the assets in the AMM's pool. In JSON, this is an + object with currency and issuer fields (omit issuer for XRP). + """ + + asset2: Currency = REQUIRED + """ + (Required) The definition for the other asset in the AMM's pool. In JSON, this is an + object with currency and issuer fields (omit issuer for XRP). + """ + + bid_min: Optional[Any] = None + """ + (Optional) Pay at least this amount for the slot. Setting this value higher makes it + harder for others to outbid you. If omitted, pay the minimum necessary to win the bid. + """ + + bid_max: Optional[Any] = None + """ + (Optional) Pay at most this amount for the slot. If the cost to win the bid is higher + than this amount, the transaction fails. If omitted, pay as much as necessary to win the + bid. + """ + + auth_accounts: Optional[List[AuthAccount]] = None + """ + (Optional) A list of up to 4 additional accounts that you allow to trade at the + discounted fee. This cannot include the address of the transaction sender. Each of these + objects should be an Auth Account object. + """ + + def _get_errors(self: AMMBid) -> Dict[str, str]: + errors = super._get_errors() + if self.auth_accounts is not None and len(self.auth_accounts) > 4: + errors["AMMBid"] = ( + "Field `auth_accounts` must have a length less than or equal to 4" + ) + return errors diff --git a/xrpl/openapi-codegen/models/transactions/amm_create.py b/xrpl/openapi-codegen/models/transactions/amm_create.py new file mode 100644 index 000000000..78d191ece --- /dev/null +++ b/xrpl/openapi-codegen/models/transactions/amm_create.py @@ -0,0 +1,55 @@ +"""Model for AMMCreate transaction type.""" + +from dataclasses import dataclass, field +from typing import Any, Optional +from xrpl.models.transactions.types import TransactionType +from xrpl.models.utils import REQUIRED +from xrpl.models.transactions.transaction import Transaction +from xrpl.models.utils import require_kwargs_on_init + + +@require_kwargs_on_init +@dataclass(frozen=True) +class AMMCreate(Transaction): + """ + Create a new Automated Market Maker (AMM) instance for trading a pair of assets + (fungible tokens or XRP). Creates both an AMM entry and a special AccountRoot entry to + represent the AMM. Also transfers ownership of the starting balance of both assets from + the sender to the created AccountRoot and issues an initial balance of liquidity + provider tokens (LP Tokens) from the AMM account to the sender. + """ + + transaction_type: TransactionType = field( + default=TransactionType.AMM_CREATE, init=False + ) + + amount: Optional[Any] = REQUIRED + """ + (Required) The first of the two assets to fund this AMM with. This must be a positive + amount. + """ + + amount2: Optional[Any] = REQUIRED + """ + (Required) The second of the two assets to fund this AMM with. This must be a positive + amount. + """ + + trading_fee: int = REQUIRED + """ + (Required) The fee to charge for trades against this AMM instance, in units of + 1/100,000; a value of 1 is equivalent to 0.001%. The maximum value is 1000, indicating a + 1% fee. The minimum value is 0. + """ + + def _get_errors(self: AMMCreate) -> Dict[str, str]: + errors = super._get_errors() + if self.trading_fee is not None and self.trading_fee < 0: + errors["AMMCreate"] = ( + "Field `trading_fee` must have a value greater than or equal to 0" + ) + if self.trading_fee is not None and self.trading_fee > 1000: + errors["AMMCreate"] = ( + "Field `trading_fee` must have a value less than or equal to 1000" + ) + return errors diff --git a/xrpl/openapi-codegen/models/transactions/amm_delete.py b/xrpl/openapi-codegen/models/transactions/amm_delete.py new file mode 100644 index 000000000..f2325c9ae --- /dev/null +++ b/xrpl/openapi-codegen/models/transactions/amm_delete.py @@ -0,0 +1,40 @@ +"""Model for AMMDelete transaction type.""" + +from dataclasses import dataclass, field +from typing import Optional +from xrpl.models.transactions.types import TransactionType +from xrpl.models.utils import REQUIRED +from xrpl.models.currency import Currency +from xrpl.models.transactions.transaction import Transaction +from xrpl.models.utils import require_kwargs_on_init + + +@require_kwargs_on_init +@dataclass(frozen=True) +class AMMDelete(Transaction): + """ + Delete an empty Automated Market Maker (AMM) instance that could not be fully deleted + automatically. Normally, an AMMWithdraw transaction automatically deletes an AMM and + all associated ledger entries when it withdraws all the assets from the AMM's pool. + However, if there are too many trust lines to the AMM account to remove in one + transaction, it may stop before fully removing the AMM. Similarly, an AMMDelete + transaction removes up to a maximum of 512 trust lines; it may take several AMMDelete + transactions to delete all the trust lines and the associated AMM. In all cases, only + the last such transaction deletes the AMM and AccountRoot ledger entries. + """ + + transaction_type: TransactionType = field( + default=TransactionType.AMM_DELETE, init=False + ) + + asset: Currency = REQUIRED + """ + (Required) The definition for one of the assets in the AMM's pool. In JSON, this is an + object with currency and issuer fields (omit issuer for XRP). + """ + + asset2: Currency = REQUIRED + """ + (Required) The definition for the other asset in the AMM's pool. In JSON, this is an + object with currency and issuer fields (omit issuer for XRP). + """ diff --git a/xrpl/openapi-codegen/models/transactions/amm_deposit.py b/xrpl/openapi-codegen/models/transactions/amm_deposit.py new file mode 100644 index 000000000..b12e22cb9 --- /dev/null +++ b/xrpl/openapi-codegen/models/transactions/amm_deposit.py @@ -0,0 +1,136 @@ +"""Model for AMMDeposit transaction type.""" + +from dataclasses import dataclass, field +from enum import Enum +from typing import Any, Optional +from xrpl.models.transactions.types import TransactionType +from xrpl.models.utils import REQUIRED +from xrpl.models.amm_deposit_flag import AMMDepositFlag +from xrpl.models.currency import Currency +from xrpl.models.transactions.transaction import Transaction +from xrpl.models.utils import require_kwargs_on_init + + +@require_kwargs_on_init +@dataclass(frozen=True) +class AMMDeposit(Transaction): + """ + Deposit funds into an Automated Market Maker (AMM) instance and receive the AMM's + liquidity provider tokens (LP Tokens) in exchange. You can deposit one or both of the + assets in the AMM's pool. If successful, this transaction creates a trust line to the + AMM Account (limit 0) to hold the LP Tokens. + """ + + transaction_type: TransactionType = field( + default=TransactionType.AMM_DEPOSIT, init=False + ) + + asset: Currency = REQUIRED + """ + (Required) The definition for one of the assets in the AMM's pool. In JSON, this is an + object with currency and issuer fields (omit issuer for XRP). + """ + + asset2: Currency = REQUIRED + """ + (Required) The definition for the other asset in the AMM's pool. In JSON, this is an + object with currency and issuer fields (omit issuer for XRP). + """ + + amount: Optional[Any] = None + """ + (Optional) The amount of one asset to deposit to the AMM. If present, this must match + the type of one of the assets (tokens or XRP) in the AMM's pool. + """ + + amount2: Optional[Any] = None + """ + (Optional) The amount of another asset to add to the AMM. If present, this must match + the type of the other asset in the AMM's pool and cannot be the same asset as Amount. + """ + + e_price: Optional[Any] = None + """ + (Optional) The maximum effective price, in the deposit asset, to pay for each LP Token + received. + """ + + lp_token_out: Optional[Any] = None + """ + (Optional) How many of the AMM's LP Tokens to buy. + """ + + trading_fee: Optional[int] = None + """ + (Optional) Submit a vote for the AMM's trading fee, in units of 1/100,000; a value of 1 + is equivalent to 0.001%. The maximum value is 1000, indicating a 1% fee. + """ + + def _get_errors(self: AMMDeposit) -> Dict[str, str]: + errors = super._get_errors() + if self.amount2 is not None and self.amount is None: + errors["AMMDeposit"] = "Must set `amount` with `amount2.`" + if self.e_price is not None and self.amount is None: + errors["AMMDeposit"] = "Must set `amount` with `e_price.`" + if self.lp_token_out is None and self.amount is None: + errors["AMMDeposit"] = ( + "At least one of `lp_token_out`, `amount` must be set." + ) + if self.trading_fee is not None and self.trading_fee < 0: + errors["AMMDeposit"] = ( + "Field `trading_fee` must have a value greater than or equal to 0" + ) + if self.trading_fee is not None and self.trading_fee > 1000: + errors["AMMDeposit"] = ( + "Field `trading_fee` must have a value less than or equal to 1000" + ) + return errors + + +class AMMDepositFlagInterface(FlagInterface): + """ + Enum for AMMDeposit Transaction Flags. + """ + + TF_LP_TOKEN: bool + TF_TWO_ASSET: bool + TF_TWO_ASSET_IF_EMPTY: bool + TF_SINGLE_ASSET: bool + TF_ONE_ASSET_LP_TOKEN: bool + TF_LIMIT_LP_TOKEN: bool + + +class AMMDepositFlag(int, Enum): + """ + Enum for AMMDeposit Transaction Flags. + """ + + TF_LP_TOKEN = 0x00010000 + """ + Deposit both of this AMM's assets, in amounts calculated so that you receive the specified amount of LP Tokens in return. The amounts deposited maintain the relative proportions of the two assets the AMM already holds. + """ + + TF_TWO_ASSET = 0x00100000 + """ + Deposit both of this AMM's assets, up to the specified amounts. The actual amounts deposited must maintain the same balance of assets as the AMM already holds, so the amount of either one deposited MAY be less than specified. The amount of LP Tokens you get in return is based on the total value deposited. + """ + + TF_TWO_ASSET_IF_EMPTY = 0x00800000 + """ + Deposit both of this AMM's assets, in exactly the specified amounts, to an AMM with an empty asset pool. The amount of LP Tokens you get in return is based on the total value deposited. + """ + + TF_SINGLE_ASSET = 0x00080000 + """ + Deposit exactly the specified amount of one asset, and receive an amount of LP Tokens based on the resulting share of the pool (minus fees). + """ + + TF_ONE_ASSET_LP_TOKEN = 0x00200000 + """ + Deposit up to the specified amount of one asset, so that you receive exactly the specified amount of LP Tokens in return (after fees). + """ + + TF_LIMIT_LP_TOKEN = 0x00400000 + """ + Deposit up to the specified amount of one asset, but pay no more than the specified effective price per LP Token (after fees). + """ diff --git a/xrpl/openapi-codegen/models/transactions/amm_vote.py b/xrpl/openapi-codegen/models/transactions/amm_vote.py new file mode 100644 index 000000000..056750de2 --- /dev/null +++ b/xrpl/openapi-codegen/models/transactions/amm_vote.py @@ -0,0 +1,53 @@ +"""Model for AMMVote transaction type.""" + +from dataclasses import dataclass, field +from typing import Optional +from xrpl.models.transactions.types import TransactionType +from xrpl.models.utils import REQUIRED +from xrpl.models.currency import Currency +from xrpl.models.transactions.transaction import Transaction +from xrpl.models.utils import require_kwargs_on_init + + +@require_kwargs_on_init +@dataclass(frozen=True) +class AMMVote(Transaction): + """ + Vote on the trading fee for an Automated Market Maker instance. Up to 8 accounts can + vote in proportion to the amount of the AMM's LP Tokens they hold. Each new vote + re-calculates the AMM's trading fee based on a weighted average of the votes. + """ + + transaction_type: TransactionType = field( + default=TransactionType.AMM_VOTE, init=False + ) + + asset: Currency = REQUIRED + """ + (Required) The definition for one of the assets in the AMM's pool. In JSON, this is an + object with currency and issuer fields (omit issuer for XRP). + """ + + asset2: Currency = REQUIRED + """ + (Required) The definition for the other asset in the AMM's pool. In JSON, this is an + object with currency and issuer fields (omit issuer for XRP). + """ + + trading_fee: int = REQUIRED + """ + (Required) The proposed fee to vote for, in units of 1/100,000; a value of 1 is + equivalent to 0.001%. The maximum value is 1000, indicating a 1% fee. + """ + + def _get_errors(self: AMMVote) -> Dict[str, str]: + errors = super._get_errors() + if self.trading_fee is not None and self.trading_fee < 0: + errors["AMMVote"] = ( + "Field `trading_fee` must have a value greater than or equal to 0" + ) + if self.trading_fee is not None and self.trading_fee > 1000: + errors["AMMVote"] = ( + "Field `trading_fee` must have a value less than or equal to 1000" + ) + return errors diff --git a/xrpl/openapi-codegen/models/transactions/amm_withdraw.py b/xrpl/openapi-codegen/models/transactions/amm_withdraw.py new file mode 100644 index 000000000..54836753e --- /dev/null +++ b/xrpl/openapi-codegen/models/transactions/amm_withdraw.py @@ -0,0 +1,123 @@ +"""Model for AMMWithdraw transaction type.""" + +from dataclasses import dataclass, field +from enum import Enum +from typing import Any, Optional +from xrpl.models.transactions.types import TransactionType +from xrpl.models.utils import REQUIRED +from xrpl.models.amm_withdraw_flag import AMMWithdrawFlag +from xrpl.models.currency import Currency +from xrpl.models.transactions.transaction import Transaction +from xrpl.models.utils import require_kwargs_on_init + + +@require_kwargs_on_init +@dataclass(frozen=True) +class AMMWithdraw(Transaction): + """ + Withdraw assets from an Automated Market Maker (AMM) instance by returning the AMM's + liquidity provider tokens (LP Tokens). + """ + + transaction_type: TransactionType = field( + default=TransactionType.AMM_WITHDRAW, init=False + ) + + asset: Currency = REQUIRED + """ + (Required) The definition for one of the assets in the AMM's pool. In JSON, this is an + object with currency and issuer fields (omit issuer for XRP). + """ + + asset2: Currency = REQUIRED + """ + (Required) The definition for the other asset in the AMM's pool. In JSON, this is an + object with currency and issuer fields (omit issuer for XRP). + """ + + amount: Optional[Any] = None + """ + (Optional) The amount of one asset to withdraw from the AMM. This must match the type of + one of the assets (tokens or XRP) in the AMM's pool. + """ + + amount2: Optional[Any] = None + """ + (Optional) The amount of another asset to withdraw from the AMM. If present, this must + match the type of the other asset in the AMM's pool and cannot be the same type as + Amount. + """ + + e_price: Optional[Any] = None + """ + (Optional) The minimum effective price, in LP Token returned, to pay per unit of the + asset to withdraw. + """ + + lp_token_in: Optional[Any] = None + """ + (Optional) How many of the AMM's LP Tokens to redeem. + """ + + def _get_errors(self: AMMWithdraw) -> Dict[str, str]: + errors = super._get_errors() + if self.amount2 is not None and self.amount is None: + errors["AMMWithdraw"] = "Must set `amount` with `amount2.`" + if self.e_price is not None and self.amount is None: + errors["AMMWithdraw"] = "Must set `amount` with `e_price.`" + return errors + + +class AMMWithdrawFlagInterface(FlagInterface): + """ + Enum for AMMWithdraw Transaction Flags. + """ + + TF_LP_TOKEN: bool + TF_WITHDRAW_ALL: bool + TF_ONE_ASSET_WITHDRAW_ALL: bool + TF_SINGLE_ASSET: bool + TF_TWO_ASSET: bool + TF_ONE_ASSET_LP_TOKEN: bool + TF_LIMIT_LP_TOKEN: bool + + +class AMMWithdrawFlag(int, Enum): + """ + Enum for AMMWithdraw Transaction Flags. + """ + + TF_LP_TOKEN = 0x00010000 + """ + Perform a double-asset withdrawal and receive the specified amount of LP Tokens. + """ + + TF_WITHDRAW_ALL = 0x00020000 + """ + Perform a double-asset withdrawal returning all your LP Tokens. + """ + + TF_ONE_ASSET_WITHDRAW_ALL = 0x00040000 + """ + Perform a single-asset withdrawal returning all of your LP Tokens. + """ + + TF_SINGLE_ASSET = 0x00080000 + """ + Perform a single-asset withdrawal with a specified amount of the asset to withdraw. + """ + + TF_TWO_ASSET = 0x00100000 + """ + Perform a double-asset withdrawal with specified amounts of both assets. + """ + + TF_ONE_ASSET_LP_TOKEN = 0x00200000 + """ + Perform a single-asset withdrawal and receive the specified amount of LP Tokens. + """ + + TF_LIMIT_LP_TOKEN = 0x00400000 + """ + Perform a single-asset withdrawal with a specified effective price. + """ diff --git a/xrpl/openapi-codegen/models/transactions/check_cancel.py b/xrpl/openapi-codegen/models/transactions/check_cancel.py new file mode 100644 index 000000000..6bb0e4137 --- /dev/null +++ b/xrpl/openapi-codegen/models/transactions/check_cancel.py @@ -0,0 +1,27 @@ +"""Model for CheckCancel transaction type.""" + +from dataclasses import dataclass, field +from typing import Optional +from xrpl.models.transactions.types import TransactionType +from xrpl.models.utils import REQUIRED +from xrpl.models.transactions.transaction import Transaction +from xrpl.models.utils import require_kwargs_on_init + + +@require_kwargs_on_init +@dataclass(frozen=True) +class CheckCancel(Transaction): + """ + Cancels an unredeemed Check, removing it from the ledger without sending any money. The + source or the destination of the check can cancel a Check at any time using this + transaction type. If the Check has expired, any address can cancel it. + """ + + transaction_type: TransactionType = field( + default=TransactionType.CHECK_CANCEL, init=False + ) + + check_id: str = REQUIRED + """ + The ID of the Check ledger object to cancel, as a 64-character hexadecimal string. + """ diff --git a/xrpl/openapi-codegen/models/transactions/check_cash.py b/xrpl/openapi-codegen/models/transactions/check_cash.py new file mode 100644 index 000000000..759693263 --- /dev/null +++ b/xrpl/openapi-codegen/models/transactions/check_cash.py @@ -0,0 +1,54 @@ +"""Model for CheckCash transaction type.""" + +from dataclasses import dataclass, field +from typing import Any, Optional +from xrpl.models.transactions.types import TransactionType +from xrpl.models.utils import REQUIRED +from xrpl.models.transactions.transaction import Transaction +from xrpl.models.utils import require_kwargs_on_init + + +@require_kwargs_on_init +@dataclass(frozen=True) +class CheckCash(Transaction): + """ + Attempts to redeem a Check object in the ledger to receive up to the amount authorized + by the corresponding CheckCreate transaction. Only the Destination address of a Check + can cash it with a CheckCash transaction. Cashing a check this way is similar to + executing a Payment initiated by the destination. Since the funds for a check are not + guaranteed, redeeming a Check can fail because the sender does not have a high enough + balance or because there is not enough liquidity to deliver the funds. If this happens, + the Check remains in the ledger and the destination can try to cash it again later, or + for a different amount. + """ + + transaction_type: TransactionType = field( + default=TransactionType.CHECK_CASH, init=False + ) + + check_id: str = REQUIRED + """ + The ID of the Check ledger object to cash, as a 64-character hexadecimal string. + """ + + amount: Optional[Any] = None + """ + (Optional) Redeem the Check for exactly this amount, if possible. The currency must + match that of the SendMax of the corresponding CheckCreate transaction. You must provide + either this field or DeliverMin. + """ + + deliver_min: Optional[Any] = None + """ + (Optional) Redeem the Check for at least this amount and for as much as possible. The + currency must match that of the SendMax of the corresponding CheckCreate transaction. + You must provide either this field or Amount. + """ + + def _get_errors(self: CheckCash) -> Dict[str, str]: + errors = super._get_errors() + if (self.amount is None) ^ (self.deliver_min is None): + errors["CheckCash"] = ( + "Either `amount` and `deliver_min` must be set but not both." + ) + return errors diff --git a/xrpl/openapi-codegen/models/transactions/check_create.py b/xrpl/openapi-codegen/models/transactions/check_create.py new file mode 100644 index 000000000..1e46ae91b --- /dev/null +++ b/xrpl/openapi-codegen/models/transactions/check_create.py @@ -0,0 +1,52 @@ +"""Model for CheckCreate transaction type.""" + +from dataclasses import dataclass, field +from typing import Any, Optional +from xrpl.models.transactions.types import TransactionType +from xrpl.models.utils import REQUIRED +from xrpl.models.transactions.transaction import Transaction +from xrpl.models.utils import require_kwargs_on_init + + +@require_kwargs_on_init +@dataclass(frozen=True) +class CheckCreate(Transaction): + """ + Create a Check object in the ledger, which is a deferred payment that can be cashed by + its intended destination. The sender of this transaction is the sender of the Check. + """ + + transaction_type: TransactionType = field( + default=TransactionType.CHECK_CREATE, init=False + ) + + destination: str = REQUIRED + """ + The unique address of the account that can cash the Check. + """ + + send_max: Optional[Any] = REQUIRED + """ + Maximum amount of source currency the Check is allowed to debit the sender, including + transfer fees on non-XRP currencies. The Check can only credit the destination with the + same currency (from the same issuer, for non-XRP currencies). For non-XRP amounts, the + nested field names MUST be lower-case. + """ + + destination_tag: Optional[int] = None + """ + (Optional) Arbitrary tag that identifies the reason for the Check, or a hosted recipient + to pay. + """ + + expiration: Optional[int] = None + """ + (Optional) Time after which the Check is no longer valid, in seconds since the Ripple + Epoch. + """ + + invoice_id: Optional[str] = None + """ + (Optional) Arbitrary 256-bit hash representing a specific reason or identifier for this + Check. + """ diff --git a/xrpl/openapi-codegen/models/transactions/clawback.py b/xrpl/openapi-codegen/models/transactions/clawback.py new file mode 100644 index 000000000..2c71a8f3d --- /dev/null +++ b/xrpl/openapi-codegen/models/transactions/clawback.py @@ -0,0 +1,48 @@ +"""Model for Clawback transaction type.""" + +from dataclasses import dataclass, field +from typing import Optional +from xrpl.models.transactions.types import TransactionType +from xrpl.models.utils import REQUIRED +from xrpl.models.token_amount import TokenAmount +from xrpl.models.transactions.transaction import Transaction +from xrpl.models.utils import require_kwargs_on_init + + +@require_kwargs_on_init +@dataclass(frozen=True) +class Clawback(Transaction): + """ + Claw back tokens issued by your account. Clawback is disabled by default. To use + clawback, you must send an AccountSet transaction to enable the Allow Trust Line + Clawback setting. An issuer with any existing tokens cannot enable Clawback. You can + only enable Allow Trust Line Clawback if you have a completely empty owner directory, + meaning you must do so before you set up any trust lines, offers, escrows, payment + channels, checks, or signer lists. After you enable Clawback, it cannot be reverted: the + account permanently gains the ability to claw back issued assets on trust lines. + """ + + transaction_type: TransactionType = field( + default=TransactionType.CLAWBACK, init=False + ) + + amount: TokenAmount = REQUIRED + """ + Indicates the amount being clawed back, as well as the counterparty from which the + amount is being clawed back. The quantity to claw back, in the value sub-field, must not + be zero. If this is more than the current balance, the transaction claws back the entire + balance. The sub-field issuer within Amount represents the token holder's account ID, + rather than the issuer's. + """ + + holder: Optional[str] = None + """ + (Optional) Specifies the holder's address from which to claw back. The holder must + already own an MPToken object with a non-zero balance. (Requires the MPToken amendment.) + """ + + def _get_errors(self: Clawback) -> Dict[str, str]: + errors = super._get_errors() + if self.account is not None and self.account == self.amount.issuer: + errors[Clawback] = "account must not be equal to amount.issuer." + return errors diff --git a/xrpl/openapi-codegen/models/transactions/credential_accept.py b/xrpl/openapi-codegen/models/transactions/credential_accept.py new file mode 100644 index 000000000..0b41f160a --- /dev/null +++ b/xrpl/openapi-codegen/models/transactions/credential_accept.py @@ -0,0 +1,44 @@ +"""Model for CredentialAccept transaction type.""" + +from dataclasses import dataclass, field +from typing import Optional +from xrpl.models.transactions.types import TransactionType +from xrpl.models.utils import REQUIRED +from xrpl.models.transactions.transaction import Transaction +from xrpl.models.utils import require_kwargs_on_init + + +@require_kwargs_on_init +@dataclass(frozen=True) +class CredentialAccept(Transaction): + """ + A CredentialAccept transaction accepts a credential, which makes the credential valid. + Only the subject of the credential can do this. + """ + + transaction_type: TransactionType = field( + default=TransactionType.CREDENTIAL_ACCEPT, init=False + ) + + credential_type: str = REQUIRED + """ + Arbitrary data defining the type of credential. The minimum size is 1 byte and the + maximum is 64 bytes. + """ + + issuer: str = REQUIRED + """ + The address of the issuer that created the credential. + """ + + def _get_errors(self: CredentialAccept) -> Dict[str, str]: + errors = super._get_errors() + if self.credential_type is not None and len(self.credential_type) < 1: + errors["CredentialAccept"] = ( + "Field `credential_type` must have a length greater than or equal to 1" + ) + if self.credential_type is not None and len(self.credential_type) > 128: + errors["CredentialAccept"] = ( + "Field `credential_type` must have a length less than or equal to 128" + ) + return errors diff --git a/xrpl/openapi-codegen/models/transactions/credential_create.py b/xrpl/openapi-codegen/models/transactions/credential_create.py new file mode 100644 index 000000000..f2cc54d32 --- /dev/null +++ b/xrpl/openapi-codegen/models/transactions/credential_create.py @@ -0,0 +1,67 @@ +"""Model for CredentialCreate transaction type.""" + +from dataclasses import dataclass, field +from pydantic import StrictFloat, StrictInt +from typing import Optional, Union +from xrpl.models.transactions.types import TransactionType +from xrpl.models.utils import REQUIRED +from xrpl.models.transactions.transaction import Transaction +from xrpl.models.utils import require_kwargs_on_init + + +@require_kwargs_on_init +@dataclass(frozen=True) +class CredentialCreate(Transaction): + """ + A CredentialCreate transaction creates a credential in the ledger. The issuer of the + credential uses this transaction to provisionally issue a credential. The credential is + not valid until the subject of the credential accepts it with a CredentialAccept + transaction. + """ + + transaction_type: TransactionType = field( + default=TransactionType.CREDENTIAL_CREATE, init=False + ) + + credential_type: str = REQUIRED + """ + Arbitrary data defining the type of credential this entry represents. The minimum length + is 1 byte and the maximum length is 64 bytes. + """ + + expiration: Union[StrictFloat, StrictInt] = REQUIRED + """ + Time after which this credential expires, in seconds since the Ripple Epoch. + """ + + subject: str = REQUIRED + """ + The subject of the credential. + """ + + uri: Optional[str] = None + """ + Arbitrary additional data about the credential, such as the URL where users can look up + an associated Verifiable Credential document. If present, the minimum length is 1 byte + and the maximum is 256 bytes. + """ + + def _get_errors(self: CredentialCreate) -> Dict[str, str]: + errors = super._get_errors() + if self.credential_type is not None and len(self.credential_type) < 1: + errors["CredentialCreate"] = ( + "Field `credential_type` must have a length greater than or equal to 1" + ) + if self.credential_type is not None and len(self.credential_type) > 128: + errors["CredentialCreate"] = ( + "Field `credential_type` must have a length less than or equal to 128" + ) + if self.uri is not None and len(self.uri) < 1: + errors["CredentialCreate"] = ( + "Field `uri` must have a length greater than or equal to 1" + ) + if self.uri is not None and len(self.uri) > 512: + errors["CredentialCreate"] = ( + "Field `uri` must have a length less than or equal to 512" + ) + return errors diff --git a/xrpl/openapi-codegen/models/transactions/credential_delete.py b/xrpl/openapi-codegen/models/transactions/credential_delete.py new file mode 100644 index 000000000..65a34185d --- /dev/null +++ b/xrpl/openapi-codegen/models/transactions/credential_delete.py @@ -0,0 +1,56 @@ +"""Model for CredentialDelete transaction type.""" + +from dataclasses import dataclass, field +from typing import Optional +from xrpl.models.transactions.types import TransactionType +from xrpl.models.utils import REQUIRED +from xrpl.models.transactions.transaction import Transaction +from xrpl.models.utils import require_kwargs_on_init + + +@require_kwargs_on_init +@dataclass(frozen=True) +class CredentialDelete(Transaction): + """ + A CredentialDelete transaction removes a credential from the ledger, effectively + revoking it. Users may also want to delete an unwanted credential to reduce their + reserve requirement. + """ + + transaction_type: TransactionType = field( + default=TransactionType.CREDENTIAL_DELETE, init=False + ) + + credential_type: str = REQUIRED + """ + Arbitrary data defining the type of credential to delete. The minimum length is 1 byte + and the maximum length is 256 bytes. + """ + + subject: Optional[str] = None + """ + The subject of the credential to delete. If omitted, use the Account (sender of the + transaction) as the subject of the credential. + """ + + issuer: Optional[str] = None + """ + The issuer of the credential to delete. If omitted, use the Account (sender of the + transaction) as the issuer of the credential. + """ + + def _get_errors(self: CredentialDelete) -> Dict[str, str]: + errors = super._get_errors() + if self.subject is None and self.issuer is None: + errors["CredentialDelete"] = ( + "At least one of `subject`, `issuer` must be set." + ) + if self.credential_type is not None and len(self.credential_type) < 1: + errors["CredentialDelete"] = ( + "Field `credential_type` must have a length greater than or equal to 1" + ) + if self.credential_type is not None and len(self.credential_type) > 128: + errors["CredentialDelete"] = ( + "Field `credential_type` must have a length less than or equal to 128" + ) + return errors diff --git a/xrpl/openapi-codegen/models/transactions/deposit_preauth.py b/xrpl/openapi-codegen/models/transactions/deposit_preauth.py new file mode 100644 index 000000000..c542ab037 --- /dev/null +++ b/xrpl/openapi-codegen/models/transactions/deposit_preauth.py @@ -0,0 +1,82 @@ +"""Model for DepositPreauth transaction type.""" + +from dataclasses import dataclass, field +from typing import List, Optional +from xrpl.models.transactions.types import TransactionType +from xrpl.models.authorize_credentials import AuthorizeCredentials +from xrpl.models.transactions.transaction import Transaction +from xrpl.models.utils import require_kwargs_on_init + + +@require_kwargs_on_init +@dataclass(frozen=True) +class DepositPreauth(Transaction): + """ + A DepositPreauth transaction grants preauthorization to deliver payments to your + account. This is only useful if you are using (or plan to use) Deposit Authorization. + """ + + transaction_type: TransactionType = field( + default=TransactionType.DEPOSIT_PREAUTH, init=False + ) + + authorize: Optional[str] = None + """ + (Optional) An account to preauthorize. + """ + + authorize_credentials: Optional[List[AuthorizeCredentials]] = None + """ + (Optional) A set of credentials to authorize. (Requires the Credentials amendment.) + """ + + unauthorize: Optional[str] = None + """ + (Optional) An account whose preauthorization should be revoked. + """ + + unauthorize_credentials: Optional[List[AuthorizeCredentials]] = None + """ + (Optional) A set of credentials whose preauthorization should be revoked. (Requires the + Credentials amendment.) + """ + + def _get_errors(self: DepositPreauth) -> Dict[str, str]: + errors = super._get_errors() + if ( + self.authorize_credentials is not None + and len(self.authorize_credentials) < 1 + ): + errors["DepositPreauth"] = ( + "Field `authorize_credentials` must have a length greater than or equal to 1" + ) + if ( + self.authorize_credentials is not None + and len(self.authorize_credentials) > 8 + ): + errors["DepositPreauth"] = ( + "Field `authorize_credentials` must have a length less than or equal to 8" + ) + if len(self.authorize_credentials) != len(set(self.authorize_credentials)): + errors["DepositPreauth"] = ( + "`authorize_credentials` list cannot contain duplicate values" + ) + if ( + self.unauthorize_credentials is not None + and len(self.unauthorize_credentials) < 1 + ): + errors["DepositPreauth"] = ( + "Field `unauthorize_credentials` must have a length greater than or equal to 1" + ) + if ( + self.unauthorize_credentials is not None + and len(self.unauthorize_credentials) > 8 + ): + errors["DepositPreauth"] = ( + "Field `unauthorize_credentials` must have a length less than or equal to 8" + ) + if len(self.unauthorize_credentials) != len(set(self.unauthorize_credentials)): + errors["DepositPreauth"] = ( + "`unauthorize_credentials` list cannot contain duplicate values" + ) + return errors diff --git a/xrpl/openapi-codegen/models/transactions/did_delete.py b/xrpl/openapi-codegen/models/transactions/did_delete.py new file mode 100644 index 000000000..1603562b5 --- /dev/null +++ b/xrpl/openapi-codegen/models/transactions/did_delete.py @@ -0,0 +1,19 @@ +"""Model for DIDDelete transaction type.""" + +from dataclasses import dataclass, field +from typing import Optional +from xrpl.models.transactions.types import TransactionType +from xrpl.models.transactions.transaction import Transaction +from xrpl.models.utils import require_kwargs_on_init + + +@require_kwargs_on_init +@dataclass(frozen=True) +class DIDDelete(Transaction): + """ + Delete the DID ledger entry associated with the specified Account field. + """ + + transaction_type: TransactionType = field( + default=TransactionType.DID_DELETE, init=False + ) diff --git a/xrpl/openapi-codegen/models/transactions/did_set.py b/xrpl/openapi-codegen/models/transactions/did_set.py new file mode 100644 index 000000000..b2b03abce --- /dev/null +++ b/xrpl/openapi-codegen/models/transactions/did_set.py @@ -0,0 +1,56 @@ +"""Model for DIDSet transaction type.""" + +from dataclasses import dataclass, field +from typing import Optional +from xrpl.models.transactions.types import TransactionType +from xrpl.models.transactions.transaction import Transaction +from xrpl.models.utils import require_kwargs_on_init + + +@require_kwargs_on_init +@dataclass(frozen=True) +class DIDSet(Transaction): + """ + Creates a new DID ledger entry or updates the fields of an existing one. To delete the + Data, DIDDocument, or URI field from an existing DID ledger entry, add the field as an + empty string. + """ + + transaction_type: TransactionType = field( + default=TransactionType.DID_SET, init=False + ) + + data: Optional[str] = None + """ + (Optional) The public attestations of identity credentials associated with the DID. + """ + + did_document: Optional[str] = None + """ + (Optional) The DID document associated with the DID. + """ + + uri: Optional[str] = None + """ + (Optional) The Universal Resource Identifier associated with the DID. + """ + + def _get_errors(self: DIDSet) -> Dict[str, str]: + errors = super._get_errors() + if self.data is None and self.did_document is None and self.uri is None: + errors["DIDSet"] = ( + "At least one of `data`, `did_document`, `uri` must be set." + ) + if self.data is not None and len(self.data) > 256: + errors["DIDSet"] = ( + "Field `data` must have a length less than or equal to 256" + ) + if self.did_document is not None and len(self.did_document) > 256: + errors["DIDSet"] = ( + "Field `did_document` must have a length less than or equal to 256" + ) + if self.uri is not None and len(self.uri) > 256: + errors["DIDSet"] = ( + "Field `uri` must have a length less than or equal to 256" + ) + return errors diff --git a/xrpl/openapi-codegen/models/transactions/escrow_cancel.py b/xrpl/openapi-codegen/models/transactions/escrow_cancel.py new file mode 100644 index 000000000..e46abbd99 --- /dev/null +++ b/xrpl/openapi-codegen/models/transactions/escrow_cancel.py @@ -0,0 +1,31 @@ +"""Model for EscrowCancel transaction type.""" + +from dataclasses import dataclass, field +from typing import Optional +from xrpl.models.transactions.types import TransactionType +from xrpl.models.utils import REQUIRED +from xrpl.models.transactions.transaction import Transaction +from xrpl.models.utils import require_kwargs_on_init + + +@require_kwargs_on_init +@dataclass(frozen=True) +class EscrowCancel(Transaction): + """ + Return escrowed XRP to the sender. + """ + + transaction_type: TransactionType = field( + default=TransactionType.ESCROW_CANCEL, init=False + ) + + owner: str = REQUIRED + """ + Address of the source account that funded the escrow payment. + """ + + offer_sequence: int = REQUIRED + """ + Transaction sequence (or Ticket number) of EscrowCreate transaction that created the + escrow to cancel. + """ diff --git a/xrpl/openapi-codegen/models/transactions/escrow_create.py b/xrpl/openapi-codegen/models/transactions/escrow_create.py new file mode 100644 index 000000000..8d5258f28 --- /dev/null +++ b/xrpl/openapi-codegen/models/transactions/escrow_create.py @@ -0,0 +1,69 @@ +"""Model for EscrowCreate transaction type.""" + +from dataclasses import dataclass, field +from typing import Optional +from xrpl.models.transactions.types import TransactionType +from xrpl.models.utils import REQUIRED +from xrpl.models.transactions.transaction import Transaction +from xrpl.models.utils import require_kwargs_on_init + + +@require_kwargs_on_init +@dataclass(frozen=True) +class EscrowCreate(Transaction): + """ + Sequester XRP until the escrow process either finishes or is canceled. + """ + + transaction_type: TransactionType = field( + default=TransactionType.ESCROW_CREATE, init=False + ) + + amount: str = REQUIRED + """ + Amount of XRP, in drops, to deduct from the sender's balance and escrow. Once escrowed, + the XRP can either go to the Destination address (after the FinishAfter time) or be + returned to the sender (after the CancelAfter time). + """ + + destination: str = REQUIRED + """ + Address to receive escrowed XRP. + """ + + cancel_after: Optional[int] = None + """ + (Optional) The time, in seconds since the Ripple Epoch, when this escrow expires. This + value is immutable; the funds can only be returned to the sender after this time. + """ + + finish_after: Optional[int] = None + """ + (Optional) The time, in seconds since the Ripple Epoch, when the escrowed XRP can be + released to the recipient. This value is immutable, and the funds can't be accessed + until this time. + """ + + condition: Optional[str] = None + """ + (Optional) Hex value representing a PREIMAGE-SHA-256 crypto-condition. The funds can + only be delivered to the recipient if this condition is fulfilled. If the condition is + not fulfilled before the expiration time specified in the CancelAfter field, the XRP can + only revert to the sender. + """ + + destination_tag: Optional[int] = None + """ + (Optional) Arbitrary tag to further specify the destination for this escrowed payment, + such as a hosted recipient at the destination address. + """ + + def _get_errors(self: EscrowCreate) -> Dict[str, str]: + errors = super._get_errors() + if ( + self.finish_after is not None + and self.cancel_after is not None + and self.finish_after >= self.cancel_after + ): + errors["EscrowCreate"] = "finish_after must be less than cancel_after" + return errors diff --git a/xrpl/openapi-codegen/models/transactions/escrow_finish.py b/xrpl/openapi-codegen/models/transactions/escrow_finish.py new file mode 100644 index 000000000..89c779c96 --- /dev/null +++ b/xrpl/openapi-codegen/models/transactions/escrow_finish.py @@ -0,0 +1,70 @@ +"""Model for EscrowFinish transaction type.""" + +from dataclasses import dataclass, field +from typing import List, Optional +from xrpl.models.transactions.types import TransactionType +from xrpl.models.utils import REQUIRED +from xrpl.models.transactions.transaction import Transaction +from xrpl.models.utils import require_kwargs_on_init + + +@require_kwargs_on_init +@dataclass(frozen=True) +class EscrowFinish(Transaction): + """ + Deliver XRP from an escrow (held payment) to the recipient. + """ + + transaction_type: TransactionType = field( + default=TransactionType.ESCROW_FINISH, init=False + ) + + owner: str = REQUIRED + """ + (Required) Address of the source account that funded the escrow. + """ + + offer_sequence: int = REQUIRED + """ + (Required) Transaction sequence of EscrowCreate transaction that created the escrow to + finish. + """ + + condition: Optional[str] = None + """ + (Optional) Hex value matching the previously-supplied PREIMAGE-SHA-256 crypto-condition + of the escrow. + """ + + credential_ids: Optional[List[str]] = None + """ + (Optional) Set of Credentials to authorize a deposit made by this transaction. Each + member of the array must be the ledger entry ID of a Credential entry in the ledger. For + details, see Credential IDs. + """ + + fulfillment: Optional[str] = None + """ + (Optional) Hex value of the PREIMAGE-SHA-256 crypto-condition fulfillment matching the + escrow's Condition. + """ + + def _get_errors(self: EscrowFinish) -> Dict[str, str]: + errors = super._get_errors() + if (self.condition is not None) != (self.fulfillment is not None): + errors["EscrowFinish"] = ( + "Both `condition` and `fulfillment` are required if any is presented." + ) + if self.credential_ids is not None and len(self.credential_ids) < 1: + errors["EscrowFinish"] = ( + "Field `credential_ids` must have a length greater than or equal to 1" + ) + if self.credential_ids is not None and len(self.credential_ids) > 8: + errors["EscrowFinish"] = ( + "Field `credential_ids` must have a length less than or equal to 8" + ) + if len(self.credential_ids) != len(set(self.credential_ids)): + errors["EscrowFinish"] = ( + "`credential_ids` list cannot contain duplicate values" + ) + return errors diff --git a/xrpl/openapi-codegen/models/transactions/mptoken_authorize.py b/xrpl/openapi-codegen/models/transactions/mptoken_authorize.py new file mode 100644 index 000000000..675cdc3df --- /dev/null +++ b/xrpl/openapi-codegen/models/transactions/mptoken_authorize.py @@ -0,0 +1,62 @@ +"""Model for MPTokenAuthorize transaction type.""" + +from dataclasses import dataclass, field +from enum import Enum +from typing import Optional +from xrpl.models.transactions.types import TransactionType +from xrpl.models.utils import REQUIRED +from xrpl.models.mptoken_authorize_flag import MPTokenAuthorizeFlag +from xrpl.models.transactions.transaction import Transaction +from xrpl.models.utils import require_kwargs_on_init + + +@require_kwargs_on_init +@dataclass(frozen=True) +class MPTokenAuthorize(Transaction): + """ + This transaction enables an account to hold an amount of a particular MPT issuance. When + applied successfully, it creates a new MPToken object with an initial zero balance, + owned by the holder account. If the issuer has set lsfMPTRequireAuth (allow-listing) on + the MPTokenIssuance, the issuer must submit an MPTokenAuthorize transaction as well in + order to give permission to the holder. If lsfMPTRequireAuth is not set and the issuer + attempts to submit this transaction, it will fail. + """ + + transaction_type: TransactionType = field( + default=TransactionType.MPTOKEN_AUTHORIZE, init=False + ) + + mp_token_issuance_id: str = REQUIRED + """ + Indicates the ID of the MPT involved. + """ + + holder: Optional[str] = None + """ + (Optional) Specifies the holder's address that the issuer wants to authorize. Only used + for authorization/allow-listing; must be empty if submitted by the holder. + """ + + +class MPTokenAuthorizeFlagInterface(FlagInterface): + """ + Enum for MPTokenAuthorize Transaction Flags. + """ + + TF_MPT_UNAUTHORIZE: bool + + +class MPTokenAuthorizeFlag(int, Enum): + """ + Enum for MPTokenAuthorize Transaction Flags. + """ + + TF_MPT_UNAUTHORIZE = 0x00000001 + """ + If set, and transaction is submitted by a holder, it indicates that the holder no longer wants to +hold the MPToken, which will be deleted as a result. If the holder's MPToken has a non-zero balance +while trying to set this flag, the transaction fails. On the other hand, if set, and transaction is +submitted by an issuer, it would mean that the issuer wants to unauthorize the holder (only applicable +for allow-listing), which would unset the lsfMPTAuthorized flag on the MPToken. + + """ diff --git a/xrpl/openapi-codegen/models/transactions/mptoken_issuance_create.py b/xrpl/openapi-codegen/models/transactions/mptoken_issuance_create.py new file mode 100644 index 000000000..3c765480d --- /dev/null +++ b/xrpl/openapi-codegen/models/transactions/mptoken_issuance_create.py @@ -0,0 +1,134 @@ +"""Model for MPTokenIssuanceCreate transaction type.""" + +from dataclasses import dataclass, field +from enum import Enum +from typing import Optional +from xrpl.models.transactions.types import TransactionType +from xrpl.models.mptoken_issuance_create_flag import MPTokenIssuanceCreateFlag +from xrpl.models.transactions.transaction import Transaction +from xrpl.models.utils import require_kwargs_on_init + + +@require_kwargs_on_init +@dataclass(frozen=True) +class MPTokenIssuanceCreate(Transaction): + """ + The MPTokenIssuanceCreate transaction creates an MPTokenIssuance object and adds it to + the relevant directory node of the creator account. This transaction is the only + opportunity an issuer has to specify any token fields that are defined as immutable (for + example, MPT Flags). If the transaction is successful, the newly created token is owned + by the account (the creator account) that executed the transaction. Whenever your query + returns an MPTokenIssuance transaction response, there will always be an mpt_issuance_id + field on the Transaction Metadata page. + """ + + transaction_type: TransactionType = field( + default=TransactionType.MPTOKEN_ISSUANCE_CREATE, init=False + ) + + asset_scale: Optional[int] = None + """ + (Optional) An asset scale is the difference, in orders of magnitude, between a standard + unit and a corresponding fractional unit. More formally, the asset scale is a + non-negative integer (0, 1, 2, …) such that one standard unit equals 10^(-scale) of a + corresponding fractional unit. If the fractional unit equals the standard unit, then the + asset scale is 0. Note that this value is optional, and will default to 0 if not + supplied. + """ + + transfer_fee: Optional[int] = None + """ + (Optional) The value specifies the fee to be charged by the issuer for secondary sales + of the Token, if such sales are allowed. Valid values for this field are between 0 and + 50,000 inclusive, allowing transfer rates of between 0.000% and 50.000% in increments of + 0.001. The field must not be present if the tfMPTCanTransfer flag is not set. If it is, + the transaction should fail and a fee should be claimed. + """ + + maximum_amount: Optional[str] = None + """ + (Optional) The maximum asset amount of this token that can ever be issued, as a base-10 + number encoded as a string. The current default maximum limit is + 9,223,372,036,854,775,807 (2^63-1). This limit may increase in the future. If an upper + limit is required, you must specify this field. + """ + + mp_token_metadata: Optional[str] = None + """ + Arbitrary metadata about this issuance, in hex format. The limit for this field is 1024 + bytes. + """ + + def _get_errors(self: MPTokenIssuanceCreate) -> Dict[str, str]: + errors = super._get_errors() + # This check is only applicable if the flag belongs to the `flags` field inherited from base Transaction. + # For other cases such as `set_flag` or `clear_flag` field in account_info transaction, please fix accordingly. + if ( + not self.has_flag(MPTokenIssuanceCreateFlag.TF_MPT_CAN_TRANSFER) + and self.transfer_fee is not None + ): + errors["MPTokenIssuanceCreate"] = ( + "`transfer_fee` must not be set without flag `TF_MPT_CAN_TRANSFER`" + ) + if self.transfer_fee is not None and self.transfer_fee < 0: + errors["MPTokenIssuanceCreate"] = ( + "Field `transfer_fee` must have a value greater than or equal to 0" + ) + if self.transfer_fee is not None and self.transfer_fee > 50000: + errors["MPTokenIssuanceCreate"] = ( + "Field `transfer_fee` must have a value less than or equal to 50000" + ) + if self.mp_token_metadata is not None and len(self.mp_token_metadata) < 1: + errors["MPTokenIssuanceCreate"] = ( + "Field `mp_token_metadata` must have a length greater than or equal to 1" + ) + return errors + + +class MPTokenIssuanceCreateFlagInterface(FlagInterface): + """ + Enum for MPTokenIssuanceCreate Transaction Flags. + """ + + TF_MPT_CAN_LOCK: bool + TF_MPT_REQUIRE_AUTH: bool + TF_MPT_CAN_ESCROW: bool + TF_MPT_CAN_TRADE: bool + TF_MPT_CAN_TRANSFER: bool + TF_MPT_CAN_CLAWBACK: bool + + +class MPTokenIssuanceCreateFlag(int, Enum): + """ + Enum for MPTokenIssuanceCreate Transaction Flags. + """ + + TF_MPT_CAN_LOCK = 0x00000002 + """ + If set, indicates that the MPT can be locked both individually and globally. If not set, the MPT cannot be locked in any way. + """ + + TF_MPT_REQUIRE_AUTH = 0x00000004 + """ + If set, indicates that individual holders must be authorized. This enables issuers to limit who can hold their assets. + """ + + TF_MPT_CAN_ESCROW = 0x00000008 + """ + If set, indicates that individual holders can place their balances into an escrow. + """ + + TF_MPT_CAN_TRADE = 0x00000010 + """ + If set, indicates that individual holders can trade their balances using the XRP Ledger DEX. + """ + + TF_MPT_CAN_TRANSFER = 0x00000020 + """ + If set, indicates that tokens can be transferred to other accounts that are not the issuer. + """ + + TF_MPT_CAN_CLAWBACK = 0x00000040 + """ + If set, indicates that the issuer can use the Clawback transaction to claw back value from individual holders. + """ diff --git a/xrpl/openapi-codegen/models/transactions/mptoken_issuance_destroy.py b/xrpl/openapi-codegen/models/transactions/mptoken_issuance_destroy.py new file mode 100644 index 000000000..0ca546475 --- /dev/null +++ b/xrpl/openapi-codegen/models/transactions/mptoken_issuance_destroy.py @@ -0,0 +1,29 @@ +"""Model for MPTokenIssuanceDestroy transaction type.""" + +from dataclasses import dataclass, field +from typing import Optional +from xrpl.models.transactions.types import TransactionType +from xrpl.models.utils import REQUIRED +from xrpl.models.transactions.transaction import Transaction +from xrpl.models.utils import require_kwargs_on_init + + +@require_kwargs_on_init +@dataclass(frozen=True) +class MPTokenIssuanceDestroy(Transaction): + """ + The MPTokenIssuanceDestroy transaction is used to remove an MPTokenIssuance object from + the directory node in which it is being held, effectively removing the token from the + ledger (\"destroying\" it). If this operation succeeds, the corresponding + MPTokenIssuance is removed and the owner’s reserve requirement is reduced by one. This + operation must fail if there are any holders of the MPT in question. + """ + + transaction_type: TransactionType = field( + default=TransactionType.MPTOKEN_ISSUANCE_DESTROY, init=False + ) + + mp_token_issuance_id: str = REQUIRED + """ + Identifies the MPTokenIssuance object to be removed by the transaction. + """ diff --git a/xrpl/openapi-codegen/models/transactions/mptoken_issuance_set.py b/xrpl/openapi-codegen/models/transactions/mptoken_issuance_set.py new file mode 100644 index 000000000..3b5dd1d14 --- /dev/null +++ b/xrpl/openapi-codegen/models/transactions/mptoken_issuance_set.py @@ -0,0 +1,68 @@ +"""Model for MPTokenIssuanceSet transaction type.""" + +from dataclasses import dataclass, field +from enum import Enum +from typing import Optional +from xrpl.models.transactions.types import TransactionType +from xrpl.models.utils import REQUIRED +from xrpl.models.mptoken_issuance_set_flag import MPTokenIssuanceSetFlag +from xrpl.models.transactions.transaction import Transaction +from xrpl.models.utils import require_kwargs_on_init + + +@require_kwargs_on_init +@dataclass(frozen=True) +class MPTokenIssuanceSet(Transaction): + """ + Use this transaction to update a mutable property for a Multi-purpose Token. + """ + + transaction_type: TransactionType = field( + default=TransactionType.MPTOKEN_ISSUANCE_SET, init=False + ) + + mp_token_issuance_id: str = REQUIRED + """ + The MPTokenIssuance identifier. + """ + + holder: Optional[str] = None + """ + (Optional) XRPL Address of an individual token holder balance to lock/unlock. If + omitted, this transaction applies to all any accounts holding MPTs. + """ + + def _get_errors(self: MPTokenIssuanceSet) -> Dict[str, str]: + errors = super._get_errors() + if self.has_flag(MPTokenIssuanceSetFlag.TF_MPT_LOCK) and self.has_flag( + MPTokenIssuanceSetFlag.TF_MPT_UNLOCK + ): + errors["MPTokenIssuanceSet"] = ( + "flag conflict: only of these flags `TF_MPT_LOCK`, `TF_MPT_UNLOCK` can be set" + ) + return errors + + +class MPTokenIssuanceSetFlagInterface(FlagInterface): + """ + Enum for MPTokenIssuanceSet Transaction Flags. + """ + + TF_MPT_LOCK: bool + TF_MPT_UNLOCK: bool + + +class MPTokenIssuanceSetFlag(int, Enum): + """ + Enum for MPTokenIssuanceSet Transaction Flags. + """ + + TF_MPT_LOCK = 0x00000001 + """ + If set, indicates that all MPT balances for this asset should be locked. + """ + + TF_MPT_UNLOCK = 0x00000002 + """ + If set, indicates that all MPT balances for this asset should be unlocked. + """ diff --git a/xrpl/openapi-codegen/models/transactions/nftoken_accept_offer.py b/xrpl/openapi-codegen/models/transactions/nftoken_accept_offer.py new file mode 100644 index 000000000..412ebc7a8 --- /dev/null +++ b/xrpl/openapi-codegen/models/transactions/nftoken_accept_offer.py @@ -0,0 +1,63 @@ +"""Model for NFTokenAcceptOffer transaction type.""" + +from dataclasses import dataclass, field +from typing import Any, Optional +from xrpl.models.amounts import get_amount_value +from xrpl.models.transactions.types import TransactionType +from xrpl.models.transactions.transaction import Transaction +from xrpl.models.utils import require_kwargs_on_init + + +@require_kwargs_on_init +@dataclass(frozen=True) +class NFTokenAcceptOffer(Transaction): + """ + The NFTokenAcceptOffer transaction is used to accept offers to buy or sell an NFToken. + It can either: - Allow one offer to be accepted. This is called direct mode. - Allow + two distinct offers, one offering to buy a given NFToken and the other offering to sell + the same NFToken, to be accepted in an atomic fashion. This is called brokered mode. + """ + + transaction_type: TransactionType = field( + default=TransactionType.NFTOKEN_ACCEPT_OFFER, init=False + ) + + nf_token_sell_offer: Optional[str] = None + """ + (Optional) Identifies the NFTokenOffer that offers to sell the NFToken. + """ + + nf_token_buy_offer: Optional[str] = None + """ + (Optional) Identifies the NFTokenOffer that offers to buy the NFToken. + """ + + nf_token_broker_fee: Optional[Any] = None + """ + (Optional) This field is only valid in brokered mode, and specifies the amount that the + broker keeps as part of their fee for bringing the two offers together; the remaining + amount is sent to the seller of the NFToken being bought. If specified, the fee must be + such that, before applying the transfer fee, the amount that the seller would receive is + at least as much as the amount indicated in the sell offer. + """ + + def _get_errors(self: NFTokenAcceptOffer) -> Dict[str, str]: + errors = super._get_errors() + if ( + self.nftoken_broker_fee is not None + and self.nftoken_buy_offer is None + and self.nftoken_sell_offer is None + ): + errors["NFTokenAcceptOffer"] = ( + "Must set `nftoken_buy_offer`, `nftoken_sell_offer` with `nftoken_broker_fee.`" + ) + if self.nftoken_sell_offer is None and self.nftoken_buy_offer is None: + errors["NFTokenAcceptOffer"] = ( + "At least one of `nftoken_sell_offer`, `nftoken_buy_offer` must be set." + ) + if ( + self.nf_token_broker_fee is not None + and get_amount_value(self.nf_token_broker_fee) < 0 + ): + return "`nf_token_broker_fee` value must be greater than 0" + return errors diff --git a/xrpl/openapi-codegen/models/transactions/nftoken_burn.py b/xrpl/openapi-codegen/models/transactions/nftoken_burn.py new file mode 100644 index 000000000..99a06c8e5 --- /dev/null +++ b/xrpl/openapi-codegen/models/transactions/nftoken_burn.py @@ -0,0 +1,39 @@ +"""Model for NFTokenBurn transaction type.""" + +from dataclasses import dataclass, field +from typing import Optional +from xrpl.models.transactions.types import TransactionType +from xrpl.models.utils import REQUIRED +from xrpl.models.transactions.transaction import Transaction +from xrpl.models.utils import require_kwargs_on_init + + +@require_kwargs_on_init +@dataclass(frozen=True) +class NFTokenBurn(Transaction): + """ + The NFTokenBurn transaction is used to remove a NFToken object from the NFTokenPage in + which it is being held, effectively removing the token from the ledger (burning it). + The sender of this transaction must be the owner of the NFToken to burn; or, if the + NFToken has the lsfBurnable flag enabled, can be the issuer or the issuer's authorized + NFTokenMinter account instead. If this operation succeeds, the corresponding NFToken is + removed. If this operation empties the NFTokenPage holding the NFToken or results in + consolidation, thus removing a NFTokenPage, the owner’s reserve requirement is reduced + by one. + """ + + transaction_type: TransactionType = field( + default=TransactionType.NFTOKEN_BURN, init=False + ) + + nf_token_id: str = REQUIRED + """ + The NFToken to be removed by this transaction. + """ + + owner: Optional[str] = None + """ + (Optional) The owner of the NFToken to burn. Only used if that owner is different than + the account sending this transaction. The issuer or authorized minter can use this field + to burn NFTs that have the lsfBurnable flag enabled. + """ diff --git a/xrpl/openapi-codegen/models/transactions/nftoken_cancel_offer.py b/xrpl/openapi-codegen/models/transactions/nftoken_cancel_offer.py new file mode 100644 index 000000000..28e27dc80 --- /dev/null +++ b/xrpl/openapi-codegen/models/transactions/nftoken_cancel_offer.py @@ -0,0 +1,36 @@ +"""Model for NFTokenCancelOffer transaction type.""" + +from dataclasses import dataclass, field +from typing import List, Optional +from xrpl.models.transactions.types import TransactionType +from xrpl.models.utils import REQUIRED +from xrpl.models.transactions.transaction import Transaction +from xrpl.models.utils import require_kwargs_on_init + + +@require_kwargs_on_init +@dataclass(frozen=True) +class NFTokenCancelOffer(Transaction): + """ + The NFTokenCancelOffer transaction can be used to cancel existing token offers created + using NFTokenCreateOffer. + """ + + transaction_type: TransactionType = field( + default=TransactionType.NFTOKEN_CANCEL_OFFER, init=False + ) + + nf_token_offers: List[str] = REQUIRED + """ + An array of IDs of the NFTokenOffer objects to cancel (not the IDs of NFToken objects, + but the IDs of the NFTokenOffer objects). Each entry must be a different object ID of an + NFTokenOffer object; the transaction is invalid if the array contains duplicate entries. + """ + + def _get_errors(self: NFTokenCancelOffer) -> Dict[str, str]: + errors = super._get_errors() + if self.nf_token_offers is not None and len(self.nf_token_offers) < 1: + errors["NFTokenCancelOffer"] = ( + "Field `nf_token_offers` must have a length greater than or equal to 1" + ) + return errors diff --git a/xrpl/openapi-codegen/models/transactions/nftoken_create_offer.py b/xrpl/openapi-codegen/models/transactions/nftoken_create_offer.py new file mode 100644 index 000000000..198f520b0 --- /dev/null +++ b/xrpl/openapi-codegen/models/transactions/nftoken_create_offer.py @@ -0,0 +1,105 @@ +"""Model for NFTokenCreateOffer transaction type.""" + +from dataclasses import dataclass, field +from enum import Enum +from typing import Any, Optional +from xrpl.models.transactions.types import TransactionType +from xrpl.models.utils import REQUIRED +from xrpl.models.nftoken_create_offer_flag import NFTokenCreateOfferFlag +from xrpl.models.transactions.transaction import Transaction +from xrpl.models.utils import require_kwargs_on_init + + +@require_kwargs_on_init +@dataclass(frozen=True) +class NFTokenCreateOffer(Transaction): + """ + Creates either a new Sell offer for an NFToken owned by the account executing the + transaction, or a new Buy offer for an NFToken owned by another account. If successful, + the transaction creates an NFTokenOffer object. Each offer counts as one object towards + the owner reserve of the account that placed the offer. + """ + + transaction_type: TransactionType = field( + default=TransactionType.NFTOKEN_CREATE_OFFER, init=False + ) + + owner: Optional[str] = None + """ + (Optional) Who owns the corresponding NFToken. If the offer is to buy a token, this + field must be present and it must be different than the Account field (since an offer to + buy a token one already holds is meaningless). If the offer is to sell a token, this + field must not be present, as the owner is, implicitly, the same as the Account (since + an offer to sell a token one doesn't already hold is meaningless). + """ + + nf_token_id: str = REQUIRED + """ + Identifies the NFToken object that the offer references. + """ + + amount: Optional[Any] = REQUIRED + """ + Indicates the amount expected or offered for the corresponding NFToken. The amount must + be non-zero, except where this is an offer to sell and the asset is XRP; then, it is + legal to specify an amount of zero, which means that the current owner of the token is + giving it away, gratis, either to anyone at all, or to the account identified by the + Destination field. + """ + + expiration: Optional[int] = None + """ + (Optional) Time after which the offer is no longer active, in seconds since the Ripple + Epoch. + """ + + destination: Optional[str] = None + """ + (Optional) If present, indicates that this offer may only be accepted by the specified + account. Attempts by other accounts to accept this offer MUST fail. + """ + + def _get_errors(self: NFTokenCreateOffer) -> Dict[str, str]: + errors = super._get_errors() + if self.destination is not None and self.destination == self.account: + errors[NFTokenCreateOffer] = "destination must not be equal to account." + if self.owner is not None and self.owner == self.account: + errors[NFTokenCreateOffer] = "owner must not be equal to account." + # This check is only applicable if the flag belongs to the `flags` field inherited from base Transaction. + # For other cases such as `set_flag` or `clear_flag` field in account_info transaction, please fix accordingly. + if ( + not self.has_flag(NFTokenCreateOfferFlag.TF_SELL_NFTOKEN) + and self.owner is None + ): + errors["NFTokenCreateOffer"] = ( + "`owner` must be set without flag `TF_SELL_NFTOKEN`" + ) + # This check is only applicable if the flag belongs to the `flags` field inherited from base Transaction. + # For other cases such as `set_flag` or `clear_flag` field in account_info transaction, please fix accordingly. + if ( + self.has_flag(NFTokenCreateOfferFlag.TF_SELL_NFTOKEN) + and self.owner is not None + ): + errors["NFTokenCreateOffer"] = ( + "`owner` must not be set with flag `TF_SELL_NFTOKEN`" + ) + return errors + + +class NFTokenCreateOfferFlagInterface(FlagInterface): + """ + Enum for NFTokenCreateOffer Transaction Flags. + """ + + TF_SELL_NFTOKEN: bool + + +class NFTokenCreateOfferFlag(int, Enum): + """ + Enum for NFTokenCreateOffer Transaction Flags. + """ + + TF_SELL_NFTOKEN = 0x00000001 + """ + If enabled, indicates that the offer is a sell offer. Otherwise, it is a buy offer. + """ diff --git a/xrpl/openapi-codegen/models/transactions/nftoken_mint.py b/xrpl/openapi-codegen/models/transactions/nftoken_mint.py new file mode 100644 index 000000000..9db420e98 --- /dev/null +++ b/xrpl/openapi-codegen/models/transactions/nftoken_mint.py @@ -0,0 +1,132 @@ +"""Model for NFTokenMint transaction type.""" + +from dataclasses import dataclass, field +from enum import Enum +from typing import Any, Optional +from xrpl.models.transactions.types import TransactionType +from xrpl.models.utils import REQUIRED +from xrpl.models.nftoken_mint_flag import NFTokenMintFlag +from xrpl.models.transactions.transaction import Transaction +from xrpl.models.utils import require_kwargs_on_init + + +@require_kwargs_on_init +@dataclass(frozen=True) +class NFTokenMint(Transaction): + """ + The NFTokenMint transaction creates a non-fungible token and adds it to the relevant + NFTokenPage object of the NFTokenMinter as an NFToken object. This transaction is the + only opportunity the NFTokenMinter has to specify any token fields that are defined as + immutable (for example, the TokenFlags). + """ + + transaction_type: TransactionType = field( + default=TransactionType.NFTOKEN_MINT, init=False + ) + + nf_token_taxon: int = REQUIRED + """ + An arbitrary taxon, or shared identifier, for a series or collection of related NFTs. To + mint a series of NFTs, give them all the same taxon. + """ + + issuer: Optional[str] = None + """ + (Optional) The issuer of the token, if the sender of the account is issuing it on behalf + of another account. This field must be omitted if the account sending the transaction is + the issuer of the NFToken. If provided, the issuer's AccountRoot object must have the + NFTokenMinter field set to the sender of this transaction (this transaction's Account + field). + """ + + transfer_fee: Optional[int] = None + """ + (Optional) The value specifies the fee charged by the issuer for secondary sales of the + NFToken, if such sales are allowed. Valid values for this field are between 0 and 50000 + inclusive, allowing transfer rates of between 0.00% and 50.00% in increments of 0.001. + If this field is provided, the transaction MUST have the tfTransferable flag enabled. + """ + + uri: Optional[str] = None + """ + (Optional) Up to 256 bytes of arbitrary data. In JSON, this should be encoded as a + string of hexadecimal. This is intended to be a URI that points to the data or metadata + associated with the NFT. + """ + + amount: Optional[Any] = None + """ + (Optional) Indicates the amount expected or offered for the corresponding NFToken. The + amount must be non-zero, except where the asset is XRP; then, it is legal to specify an + amount of zero. + """ + + expiration: Optional[int] = None + """ + (Optional) Time after which the offer is no longer active, in seconds since the Ripple + Epoch. Results in an error if the Amount field is not specified. + """ + + destination: Optional[str] = None + """ + (Optional) If present, indicates that this offer may only be accepted by the specified + account. Attempts by other accounts to accept this offer MUST fail. Results in an error + if the Amount field is not specified. + """ + + def _get_errors(self: NFTokenMint) -> Dict[str, str]: + errors = super._get_errors() + if self.issuer is not None and self.issuer == self.account: + errors[NFTokenMint] = "issuer must not be equal to account." + # This check is only applicable if the flag belongs to the `flags` field inherited from base Transaction. + # For other cases such as `set_flag` or `clear_flag` field in account_info transaction, please fix accordingly. + if self.has_flag(NFTokenMintFlag.TF_TRANSFERABLE) and self.transfer_fee is None: + errors["NFTokenMint"] = ( + "`transfer_fee` must be set with flag `TF_TRANSFERABLE`" + ) + if self.transfer_fee is not None and self.transfer_fee > 50000: + errors["NFTokenMint"] = ( + "Field `transfer_fee` must have a value less than or equal to 50000" + ) + if self.uri is not None and len(self.uri) > 512: + errors["NFTokenMint"] = ( + "Field `uri` must have a length less than or equal to 512" + ) + return errors + + +class NFTokenMintFlagInterface(FlagInterface): + """ + Enum for NFTokenMint Transaction Flags. + """ + + TF_BURNABLE: bool + TF_ONLY_XRP: bool + TF_TRUSTLINE: bool + TF_TRANSFERABLE: bool + + +class NFTokenMintFlag(int, Enum): + """ + Enum for NFTokenMint Transaction Flags. + """ + + TF_BURNABLE = 0x00000001 + """ + Allow the issuer (or an entity authorized by the issuer) to destroy the minted NFToken. (The NFToken's owner can always do so.) + """ + + TF_ONLY_XRP = 0x00000002 + """ + The minted NFToken can only be bought or sold for XRP. + """ + + TF_TRUSTLINE = 0x00000004 + """ + DEPRECATED Automatically create trust lines from the issuer to hold transfer fees received from transferring the minted NFToken. The fixRemoveNFTokenAutoTrustLine amendment makes it invalid to set this flag. + """ + + TF_TRANSFERABLE = 0x00000008 + """ + The minted NFToken can be transferred to others. If this flag is not enabled, the token can still be transferred from or to the issuer, but a transfer to the issuer must be made based on a buy offer from the issuer and not a sell offer from the NFT holder. + """ diff --git a/xrpl/openapi-codegen/models/transactions/offer_cancel.py b/xrpl/openapi-codegen/models/transactions/offer_cancel.py new file mode 100644 index 000000000..cc2019229 --- /dev/null +++ b/xrpl/openapi-codegen/models/transactions/offer_cancel.py @@ -0,0 +1,27 @@ +"""Model for OfferCancel transaction type.""" + +from dataclasses import dataclass, field +from typing import Optional +from xrpl.models.transactions.types import TransactionType +from xrpl.models.utils import REQUIRED +from xrpl.models.transactions.transaction import Transaction +from xrpl.models.utils import require_kwargs_on_init + + +@require_kwargs_on_init +@dataclass(frozen=True) +class OfferCancel(Transaction): + """ + An OfferCancel transaction removes an Offer object from the XRP Ledger. + """ + + transaction_type: TransactionType = field( + default=TransactionType.OFFER_CANCEL, init=False + ) + + offer_sequence: int = REQUIRED + """ + The sequence number (or Ticket number) of a previous OfferCreate transaction. If + specified, cancel any offer object in the ledger that was created by that transaction. + It is not considered an error if the offer specified does not exist. + """ diff --git a/xrpl/openapi-codegen/models/transactions/offer_create.py b/xrpl/openapi-codegen/models/transactions/offer_create.py new file mode 100644 index 000000000..eeb1d2650 --- /dev/null +++ b/xrpl/openapi-codegen/models/transactions/offer_create.py @@ -0,0 +1,80 @@ +"""Model for OfferCreate transaction type.""" + +from dataclasses import dataclass, field +from enum import Enum +from typing import Any, Optional +from xrpl.models.transactions.types import TransactionType +from xrpl.models.utils import REQUIRED +from xrpl.models.offer_create_flag import OfferCreateFlag +from xrpl.models.transactions.transaction import Transaction +from xrpl.models.utils import require_kwargs_on_init + + +@require_kwargs_on_init +@dataclass(frozen=True) +class OfferCreate(Transaction): + """ + An OfferCreate transaction places an Offer in the decentralized exchange. + """ + + transaction_type: TransactionType = field( + default=TransactionType.OFFER_CREATE, init=False + ) + + expiration: Optional[int] = None + """ + (Optional) Time after which the Offer is no longer active, in seconds since the Ripple + Epoch. + """ + + offer_sequence: Optional[int] = None + """ + (Optional) An Offer to delete first, specified in the same way as OfferCancel. + """ + + taker_gets: Optional[Any] = REQUIRED + """ + The amount and type of currency being sold. + """ + + taker_pays: Optional[Any] = REQUIRED + """ + The amount and type of currency being bought. + """ + + +class OfferCreateFlagInterface(FlagInterface): + """ + Enum for OfferCreate Transaction Flags. + """ + + TF_PASSIVE: bool + TF_IMMEDIATE_OR_CANCEL: bool + TF_FILL_OR_KILL: bool + TF_SELL: bool + + +class OfferCreateFlag(int, Enum): + """ + Enum for OfferCreate Transaction Flags. + """ + + TF_PASSIVE = 0x00010000 + """ + If enabled, the Offer does not consume Offers that exactly match it, and instead becomes an Offer object in the ledger. It still consumes Offers that cross it. + """ + + TF_IMMEDIATE_OR_CANCEL = 0x00020000 + """ + Treat the Offer as an Immediate or Cancel order. The Offer never creates an Offer object in the ledger: it only trades as much as it can by consuming existing Offers at the time the transaction is processed. If no Offers match, it executes "successfully" without trading anything. In this case, the transaction still uses the result code tesSUCCESS. + """ + + TF_FILL_OR_KILL = 0x00040000 + """ + Treat the offer as a Fill or Kill order. The Offer never creates an Offer object in the ledger, and is canceled if it cannot be fully filled at the time of execution. By default, this means that the owner must receive the full TakerPays amount; if the tfSell flag is enabled, the owner must be able to spend the entire TakerGets amount instead. + """ + + TF_SELL = 0x00080000 + """ + Exchange the entire TakerGets amount, even if it means obtaining more than the TakerPays amount in exchange. + """ diff --git a/xrpl/openapi-codegen/models/transactions/oracle_delete.py b/xrpl/openapi-codegen/models/transactions/oracle_delete.py new file mode 100644 index 000000000..9fba08f00 --- /dev/null +++ b/xrpl/openapi-codegen/models/transactions/oracle_delete.py @@ -0,0 +1,21 @@ +"""Model for OracleDelete transaction type.""" + +from dataclasses import dataclass, field +from typing import Optional +from xrpl.models.transactions.types import TransactionType +from xrpl.models.utils import REQUIRED +from xrpl.models.transactions.transaction import Transaction +from xrpl.models.utils import require_kwargs_on_init + + +@require_kwargs_on_init +@dataclass(frozen=True) +class OracleDelete(Transaction): + transaction_type: TransactionType = field( + default=TransactionType.ORACLE_DELETE, init=False + ) + + oracle_document_id: str = REQUIRED + """ + A unique identifier of the price oracle for the Account. + """ diff --git a/xrpl/openapi-codegen/models/transactions/oracle_set.py b/xrpl/openapi-codegen/models/transactions/oracle_set.py new file mode 100644 index 000000000..b59916717 --- /dev/null +++ b/xrpl/openapi-codegen/models/transactions/oracle_set.py @@ -0,0 +1,80 @@ +"""Model for OracleSet transaction type.""" + +from dataclasses import dataclass, field +from typing import List, Optional +from xrpl.models.transactions.types import TransactionType +from xrpl.models.utils import REQUIRED +from xrpl.models.price_data import PriceData +from xrpl.models.transactions.transaction import Transaction +from xrpl.models.utils import require_kwargs_on_init + + +@require_kwargs_on_init +@dataclass(frozen=True) +class OracleSet(Transaction): + transaction_type: TransactionType = field( + default=TransactionType.ORACLE_SET, init=False + ) + + oracle_document_id: int = REQUIRED + """ + A unique identifier of the price oracle for the Account. + """ + + provider: Optional[str] = None + """ + An arbitrary value identifying an oracle provider, such as Chainlink, Band, or DIA. + This field is a string, up to 256 ASCII hex-encoded characters (0x20-0x7E). Required + when creating a new Oracle ledger entry, but optional for updates. + """ + + uri: Optional[str] = None + """ + An optional Universal Resource Identifier (URI) to reference price data off-chain. + Limited to 256 bytes. + """ + + last_update_time: int = REQUIRED + """ + The timestamp indicating the last time the data was updated, in seconds since the UNIX + Epoch. + """ + + asset_class: Optional[str] = None + """ + Describes the type of asset, such as \"currency\", \"commodity\", or \"index\". This + field is a string, up to 16 ASCII hex-encoded characters (0x20-0x7E). Required when + creating a new Oracle ledger entry, but optional for updates. + """ + + price_data_series: List[PriceData] = REQUIRED + """ + An array of up to 10 PriceData objects, each representing price information for a token + pair. + """ + + def _get_errors(self: OracleSet) -> Dict[str, str]: + errors = super._get_errors() + if self.last_update_time is not None and self.last_update_time <= 946684799: + errors["OracleSet"] = "last_update_time must be greater than 946684799" + if self.provider is not None and len(self.provider) > 256: + errors["OracleSet"] = ( + "Field `provider` must have a length less than or equal to 256" + ) + if self.uri is not None and len(self.uri) > 256: + errors["OracleSet"] = ( + "Field `uri` must have a length less than or equal to 256" + ) + if self.asset_class is not None and len(self.asset_class) > 16: + errors["OracleSet"] = ( + "Field `asset_class` must have a length less than or equal to 16" + ) + if self.price_data_series is not None and len(self.price_data_series) < 1: + errors["OracleSet"] = ( + "Field `price_data_series` must have a length greater than or equal to 1" + ) + if self.price_data_series is not None and len(self.price_data_series) > 10: + errors["OracleSet"] = ( + "Field `price_data_series` must have a length less than or equal to 10" + ) + return errors diff --git a/xrpl/openapi-codegen/models/transactions/payment.py b/xrpl/openapi-codegen/models/transactions/payment.py new file mode 100644 index 000000000..536c53442 --- /dev/null +++ b/xrpl/openapi-codegen/models/transactions/payment.py @@ -0,0 +1,115 @@ +"""Model for Payment transaction type.""" + +from dataclasses import dataclass, field +from enum import Enum +from typing import Any, List, Optional +from xrpl.models.transactions.types import TransactionType +from xrpl.models.utils import REQUIRED +from xrpl.models.path_step import PathStep +from xrpl.models.payment_flag import PaymentFlag +from xrpl.models.transactions.transaction import Transaction +from xrpl.models.utils import require_kwargs_on_init + + +@require_kwargs_on_init +@dataclass(frozen=True) +class Payment(Transaction): + """ + A Payment transaction represents a transfer of value from one account to another. + (Depending on the path taken, this can involve additional exchanges of value, which + occur atomically.) This transaction type can be used for several types of payments. + Payments are also the only way to create accounts. + """ + + transaction_type: TransactionType = field( + default=TransactionType.PAYMENT, init=False + ) + + amount: Optional[Any] = REQUIRED + """ + The maximum amount of currency to deliver. Partial payments can deliver less than this + amount and still succeed; other payments fail unless they deliver the exact amount. + """ + + deliver_min: Optional[Any] = None + """ + (Optional) Minimum amount of destination currency this transaction should deliver. Only + valid if this is a partial payment. For non-XRP amounts, the nested field names are + lower-case. + """ + + destination: str = REQUIRED + """ + The unique address of the account receiving the payment. + """ + + destination_tag: Optional[int] = None + """ + (Optional) Arbitrary tag that identifies the reason for the payment to the destination, + or a hosted recipient to pay. + """ + + invoice_id: Optional[str] = None + """ + (Optional) Arbitrary 256-bit hash representing a specific reason or identifier for this + payment. + """ + + paths: Optional[List[List[PathStep]]] = None + """ + (Optional, auto-fillable) Array of payment paths to be used for this transaction. Must + be omitted for XRP-to-XRP transactions. + """ + + send_max: Optional[Any] = None + """ + (Optional) Highest amount of source currency this transaction is allowed to cost, + including transfer fees, exchange rates, and slippage. Does not include the XRP + destroyed as a cost for submitting the transaction. For non-XRP amounts, the nested + field names MUST be lower-case. Must be supplied for cross-currency/cross-issue + payments. Must be omitted for XRP-to-XRP payments. + """ + + def _get_errors(self: Payment) -> Dict[str, str]: + errors = super._get_errors() + # This check is only applicable if the flag belongs to the `flags` field inherited from base Transaction. + # For other cases such as `set_flag` or `clear_flag` field in account_info transaction, please fix accordingly. + if ( + not self.has_flag(PaymentFlag.TF_PARTIAL_PAYMENT) + and self.deliver_min is not None + ): + errors["Payment"] = ( + "`deliver_min` must not be set without flag `TF_PARTIAL_PAYMENT`" + ) + return errors + + +class PaymentFlagInterface(FlagInterface): + """ + Enum for Payment Transaction Flags. + """ + + TF_NO_RIPPLE_DIRECT: bool + TF_PARTIAL_PAYMENT: bool + TF_LIMIT_QUALITY: bool + + +class PaymentFlag(int, Enum): + """ + Enum for Payment Transaction Flags. + """ + + TF_NO_RIPPLE_DIRECT = 0x00010000 + """ + Do not use the default path; only use paths included in the Paths field. This is intended to force the transaction to take arbitrage opportunities. Most clients do not need this. + """ + + TF_PARTIAL_PAYMENT = 0x00020000 + """ + If the specified Amount cannot be sent without spending more than SendMax, reduce the received amount instead of failing outright. See Partial Payments for more details. + """ + + TF_LIMIT_QUALITY = 0x00040000 + """ + Only take paths where all the conversions have an input:output ratio that is equal or better than the ratio of Amount:SendMax. See Limit Quality for details. + """ diff --git a/xrpl/openapi-codegen/models/transactions/payment_channel_claim.py b/xrpl/openapi-codegen/models/transactions/payment_channel_claim.py new file mode 100644 index 000000000..c93e71a23 --- /dev/null +++ b/xrpl/openapi-codegen/models/transactions/payment_channel_claim.py @@ -0,0 +1,115 @@ +"""Model for PaymentChannelClaim transaction type.""" + +from dataclasses import dataclass, field +from enum import Enum +from typing import List, Optional +from xrpl.models.transactions.types import TransactionType +from xrpl.models.utils import REQUIRED +from xrpl.models.payment_channel_claim_flag import PaymentChannelClaimFlag +from xrpl.models.transactions.transaction import Transaction +from xrpl.models.utils import require_kwargs_on_init + + +@require_kwargs_on_init +@dataclass(frozen=True) +class PaymentChannelClaim(Transaction): + """ + Claim XRP from a payment channel, adjust the payment channel's expiration, or both. + This transaction can be used differently depending on the transaction sender's role in + the specified channel: The source address of a channel can: - Send XRP from the channel + to the destination with or without a signed Claim. - Set the channel to expire as soon + as the channel's SettleDelay has passed. - Clear a pending Expiration time. - Close a + channel immediately, with or without processing a claim first. The source address cannot + close the channel immediately if the channel has XRP remaining. The destination address + of a channel can: - Receive XRP from the channel using a signed Claim. - Close the + channel immediately after processing a Claim, refunding any unclaimed XRP to the + channel's source. Any address sending this transaction can: - Cause a channel to be + closed if its Expiration or CancelAfter time is older than the previous ledger's close + time. Any validly-formed PaymentChannelClaim transaction has this effect regardless of + the contents of the transaction. + """ + + transaction_type: TransactionType = field( + default=TransactionType.PAYMENT_CHANNEL_CLAIM, init=False + ) + + amount: Optional[str] = None + """ + (Optional) The amount of XRP, in drops, authorized by the Signature. This must match the + amount in the signed message. This is the cumulative amount of XRP that can be dispensed + by the channel, including XRP previously redeemed. + """ + + balance: Optional[str] = None + """ + (Optional) Total amount of XRP, in drops, delivered by this channel after processing + this claim. Required to deliver XRP. Must be more than the total amount delivered by the + channel so far, but not greater than the Amount of the signed claim. Must be provided + except when closing the channel. + """ + + channel: str = REQUIRED + """ + The unique ID of the channel, as a 64-character hexadecimal string. + """ + + credential_ids: Optional[List[str]] = None + """ + (Optional) Set of Credentials to authorize a deposit made by this transaction. Each + member of the array must be the ledger entry ID of a Credential entry in the ledger. + """ + + public_key: Optional[str] = None + """ + (Optional) The public key used for the signature, as hexadecimal. This must match the + PublicKey stored in the ledger for the channel. Required unless the sender of the + transaction is the source address of the channel and the Signature field is omitted. + """ + + signature: Optional[str] = None + """ + (Optional) The signature of this claim, as hexadecimal. The signed message contains the + channel ID and the amount of the claim. Required unless the sender of the transaction is + the source address of the channel. + """ + + def _get_errors(self: PaymentChannelClaim) -> Dict[str, str]: + errors = super._get_errors() + if self.credential_ids is not None and len(self.credential_ids) < 1: + errors["PaymentChannelClaim"] = ( + "Field `credential_ids` must have a length greater than or equal to 1" + ) + if self.credential_ids is not None and len(self.credential_ids) > 8: + errors["PaymentChannelClaim"] = ( + "Field `credential_ids` must have a length less than or equal to 8" + ) + if len(self.credential_ids) != len(set(self.credential_ids)): + errors["PaymentChannelClaim"] = ( + "`credential_ids` list cannot contain duplicate values" + ) + return errors + + +class PaymentChannelClaimFlagInterface(FlagInterface): + """ + Enum for PaymentChannelClaim Transaction Flags. + """ + + TF_RENEW: bool + TF_CLOSE: bool + + +class PaymentChannelClaimFlag(int, Enum): + """ + Enum for PaymentChannelClaim Transaction Flags. + """ + + TF_RENEW = 0x00010000 + """ + Clear the channel's Expiration time. Only the source address of the payment channel can use this flag. + """ + + TF_CLOSE = 0x00020000 + """ + Request to close the channel. Only the channel source and destination addresses can use this flag. This flag closes the channel immediately if it has no more XRP allocated after processing the current claim, or if the destination address uses it. If the source address uses this flag when the channel still holds XRP, this schedules the channel to close after SettleDelay seconds have passed. + """ diff --git a/xrpl/openapi-codegen/models/transactions/payment_channel_create.py b/xrpl/openapi-codegen/models/transactions/payment_channel_create.py new file mode 100644 index 000000000..a1afca5a6 --- /dev/null +++ b/xrpl/openapi-codegen/models/transactions/payment_channel_create.py @@ -0,0 +1,66 @@ +"""Model for PaymentChannelCreate transaction type.""" + +from dataclasses import dataclass, field +from typing import Optional +from xrpl.models.transactions.types import TransactionType +from xrpl.models.utils import REQUIRED +from xrpl.models.transactions.transaction import Transaction +from xrpl.models.utils import require_kwargs_on_init + + +@require_kwargs_on_init +@dataclass(frozen=True) +class PaymentChannelCreate(Transaction): + """ + Create a payment channel and fund it with XRP. The address sending this transaction + becomes the \"source address\" of the payment channel. + """ + + transaction_type: TransactionType = field( + default=TransactionType.PAYMENT_CHANNEL_CREATE, init=False + ) + + amount: str = REQUIRED + """ + Amount of XRP, in drops, to deduct from the sender's balance and set aside in this + channel. While the channel is open, the XRP can only go to the Destination address. When + the channel closes, any unclaimed XRP is returned to the source address's balance. + """ + + destination: str = REQUIRED + """ + Address to receive XRP claims against this channel. This is also known as the + \"destination address\" for the channel. Cannot be the same as the sender (Account). + """ + + settle_delay: int = REQUIRED + """ + Amount of time the source address must wait before closing the channel if it has + unclaimed XRP. + """ + + public_key: str = REQUIRED + """ + The 33-byte public key of the key pair the source will use to sign claims against this + channel, in hexadecimal. This can be any secp256k1 or Ed25519 public key. + """ + + cancel_after: Optional[int] = None + """ + (Optional) The time, in seconds since the Ripple Epoch, when this channel expires. Any + transaction that would modify the channel after this time closes the channel without + otherwise affecting it. This value is immutable; the channel can be closed earlier than + this time but cannot remain open after this time. + """ + + destination_tag: Optional[int] = None + """ + (Optional) Arbitrary tag to further specify the destination for this payment channel, + such as a hosted recipient at the destination address. + """ + + def _get_errors(self: PaymentChannelCreate) -> Dict[str, str]: + errors = super._get_errors() + if self.destination is not None and self.destination == self.account: + errors[PaymentChannelCreate] = "destination must not be equal to account." + return errors diff --git a/xrpl/openapi-codegen/models/transactions/payment_channel_fund.py b/xrpl/openapi-codegen/models/transactions/payment_channel_fund.py new file mode 100644 index 000000000..f409222f5 --- /dev/null +++ b/xrpl/openapi-codegen/models/transactions/payment_channel_fund.py @@ -0,0 +1,53 @@ +"""Model for PaymentChannelFund transaction type.""" + +from dataclasses import dataclass, field +from typing import Optional +from xrpl.models.amounts import get_amount_value +from xrpl.models.transactions.types import TransactionType +from xrpl.models.utils import REQUIRED +from xrpl.models.transactions.transaction import Transaction +from xrpl.models.utils import require_kwargs_on_init + + +@require_kwargs_on_init +@dataclass(frozen=True) +class PaymentChannelFund(Transaction): + """ + Add additional XRP to an open payment channel, and optionally update the expiration time + of the channel. Only the source address of the channel can use this transaction. + """ + + transaction_type: TransactionType = field( + default=TransactionType.PAYMENT_CHANNEL_FUND, init=False + ) + + channel: str = REQUIRED + """ + The unique ID of the channel to fund, as a 64-character hexadecimal string. + """ + + amount: str = REQUIRED + """ + Amount of XRP, in drops, to add to the channel. Must be a positive amount of XRP. + """ + + expiration: Optional[int] = None + """ + (Optional) New Expiration time to set for the channel, in seconds since the Ripple + Epoch. This must be later than either the current time plus the SettleDelay of the + channel, or the existing Expiration of the channel. After the Expiration time, any + transaction that would access the channel closes the channel without taking its normal + action. Any unspent XRP is returned to the source address when the channel closes. + """ + + def _get_errors(self: PaymentChannelFund) -> Dict[str, str]: + errors = super._get_errors() + if self.amount is not None and get_amount_value(self.amount) < 0: + return "`amount` value must be greater than 0" + if ( + self.amount is not None + and self.amount != REQUIRED + and not self.amount.isnumeric() + ): + errors["PaymentChannelFund"] = "`amount` must be numeric." + return errors diff --git a/xrpl/openapi-codegen/models/transactions/set_regular_key.py b/xrpl/openapi-codegen/models/transactions/set_regular_key.py new file mode 100644 index 000000000..73c7f2c5b --- /dev/null +++ b/xrpl/openapi-codegen/models/transactions/set_regular_key.py @@ -0,0 +1,22 @@ +"""Model for SetRegularKey transaction type.""" + +from dataclasses import dataclass, field +from typing import Optional +from xrpl.models.transactions.types import TransactionType +from xrpl.models.transactions.transaction import Transaction +from xrpl.models.utils import require_kwargs_on_init + + +@require_kwargs_on_init +@dataclass(frozen=True) +class SetRegularKey(Transaction): + transaction_type: TransactionType = field( + default=TransactionType.SET_REGULAR_KEY, init=False + ) + + regular_key: Optional[str] = None + """ + (Optional) A base-58-encoded Address that indicates the regular key pair to be assigned + to the account. If omitted, removes any existing regular key pair from the account. Must + not match the master key pair for the address. + """ diff --git a/xrpl/openapi-codegen/models/transactions/ticket_create.py b/xrpl/openapi-codegen/models/transactions/ticket_create.py new file mode 100644 index 000000000..ade5d7b74 --- /dev/null +++ b/xrpl/openapi-codegen/models/transactions/ticket_create.py @@ -0,0 +1,38 @@ +"""Model for TicketCreate transaction type.""" + +from dataclasses import dataclass, field +from typing import Optional +from xrpl.models.transactions.types import TransactionType +from xrpl.models.utils import REQUIRED +from xrpl.models.transactions.transaction import Transaction +from xrpl.models.utils import require_kwargs_on_init + + +@require_kwargs_on_init +@dataclass(frozen=True) +class TicketCreate(Transaction): + """ + A TicketCreate transaction sets aside one or more sequence numbers as Tickets. + """ + + transaction_type: TransactionType = field( + default=TransactionType.TICKET_CREATE, init=False + ) + + ticket_count: int = REQUIRED + """ + How many Tickets to create. This must be a positive number and cannot cause the account + to own more than 250 Tickets after executing this transaction. + """ + + def _get_errors(self: TicketCreate) -> Dict[str, str]: + errors = super._get_errors() + if self.ticket_count is not None and self.ticket_count < 1: + errors["TicketCreate"] = ( + "Field `ticket_count` must have a value greater than or equal to 1" + ) + if self.ticket_count is not None and self.ticket_count > 250: + errors["TicketCreate"] = ( + "Field `ticket_count` must have a value less than or equal to 250" + ) + return errors diff --git a/xrpl/openapi-codegen/models/transactions/transaction.py b/xrpl/openapi-codegen/models/transactions/transaction.py new file mode 100644 index 000000000..42f014266 --- /dev/null +++ b/xrpl/openapi-codegen/models/transactions/transaction.py @@ -0,0 +1,425 @@ +"""Model for Transaction.""" + +from dataclasses import dataclass +from hashlib import sha512 +from typing import Any, Dict, List, Optional, Type, Union +from typing_extensions import Final, Self +from xrpl.core.binarycodec import decode, encode +from xrpl.models.base_model import ABBREVIATIONS, BaseModel +from xrpl.models.exceptions import XRPLModelException +from xrpl.models.flags import check_false_flag_definition, interface_to_flag_list +from xrpl.models.types import XRPL_VALUE_TYPE +from xrpl.models.utils import REQUIRED +from xrpl.models.memo import Memo +from xrpl.models.path_step import PathStep +from xrpl.models.token_amount import TokenAmount + +_TRANSACTION_HASH_PREFIX: Final[int] = 0x54584E00 + + +def transaction_json_to_binary_codec_form( + dictionary: Dict[str, XRPL_VALUE_TYPE], +) -> Dict[str, XRPL_VALUE_TYPE]: + """ + Returns a new dictionary in which the keys have been formatted as CamelCase and + standardized to be serialized by the binary codec. + + Args: + dictionary: The dictionary to be reformatted. + + Returns: + A new dictionary object that has been reformatted. + """ + # This method should be made private when it is removed from `xrpl.transactions` + return { + _key_to_tx_json(key): _value_to_tx_json(value) + for (key, value) in dictionary.items() + } + + +def _key_to_tx_json(key: str) -> str: + """ + Transforms snake_case to PascalCase. For example: + 1. 'transaction_type' becomes 'TransactionType' + 2. 'URI' becomes 'uri' + + Known abbreviations (example 2 above) need to be enumerated in ABBREVIATIONS. + """ + return "".join( + [ + ABBREVIATIONS[word] if word in ABBREVIATIONS else word.capitalize() + for word in key.split("_") + ] + ) + + +def _value_to_tx_json(value: XRPL_VALUE_TYPE) -> XRPL_VALUE_TYPE: + # TokenAmount and PathStep are special cases and should not be snake cased + # and only contain primitive members + if isinstance(value, list) and all(PathStep.is_dict_of_model(v) for v in value): + return value + if TokenAmount.is_dict_of_model(value): + return value + if isinstance(value, dict): + return transaction_json_to_binary_codec_form(value) + if isinstance(value, list): + return [_value_to_tx_json(sub_value) for sub_value in value] + return value + + +from xrpl.models.utils import require_kwargs_on_init + + +@require_kwargs_on_init +@dataclass(frozen=True) +class Transaction(BaseModel): + account: str = REQUIRED + """ + The unique address of the account that initiated the transaction. + """ + + transaction_type: str = REQUIRED + """ + The type of transaction. Valid transaction types include: Payment, OfferCreate, + TrustSet, and many others. + """ + + fee: Optional[str] = None + """ + Integer amount of XRP, in drops, to be destroyed as a cost for distributing this + transaction to the network. Some transaction types have different minimum requirements. + See Transaction Cost for details. + """ + + sequence: Optional[int] = None + """ + The sequence number of the account sending the transaction. A transaction is only valid + if the Sequence number is exactly 1 greater than the previous transaction from the same + account. The special case 0 means the transaction is using a Ticket instead. + """ + + account_txn_id: Optional[str] = None + """ + Hash value identifying another transaction. If provided, this transaction is only valid + if the sending account's previously-sent transaction matches the provided hash. + """ + + flags: Optional[int] = None + """ + Set of bit-flags for this transaction. + """ + + last_ledger_sequence: Optional[int] = None + """ + Highest ledger index this transaction can appear in. Specifying this field places a + strict upper limit on how long the transaction can wait to be validated or rejected. + """ + + memos: Optional[List[Memo]] = None + """ + The Memos field includes arbitrary messaging data with the transaction. It is presented + as an array of objects. Each object has only one field, Memo, which in turn contains + another object. The Memos field is limited to no more than 1 KB in size (when serialized + in binary format). The MemoType and MemoFormat fields should only consist of the + following characters - + ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-._~:/?#[]@!$&'()*+,;=% + """ + + network_id: Optional[int] = None + """ + The network ID of the chain this transaction is intended for. MUST BE OMITTED for + Mainnet and some test networks. REQUIRED on chains whose network ID is 1025 or higher. + """ + + signers: Optional[List[Dict[str, Any]]] = None + """ + Array of objects that represent a multi-signature which authorizes this transaction. + """ + + source_tag: Optional[int] = None + """ + Arbitrary integer used to identify the reason for this payment, or a sender on whose + behalf this transaction is made. + """ + + signing_pub_key: Optional[str] = None + """ + Hex representation of the public key that corresponds to the private key used to sign + this transaction. If an empty string, indicates a multi-signature is present in the + Signers field instead. + """ + + ticket_sequence: Optional[int] = None + """ + The sequence number of the ticket to use in place of a Sequence number. If this is + provided, Sequence must be 0. Cannot be used with AccountTxnID. + """ + + txn_signature: Optional[str] = None + """ + The signature that verifies this transaction as originating from the account it says it + is from. + """ + + def _get_errors(self: Self) -> Dict[str, str]: + # import must be here to avoid circular dependencies + from xrpl.wallet.main import Wallet + + errors = super()._get_errors() + if self.ticket_sequence is not None and ( + (self.sequence is not None and self.sequence != 0) + or self.account_txn_id is not None + ): + errors[ + "Transaction" + ] = """If ticket_sequence is provided, + account_txn_id must be None and sequence must be None or 0""" + + if isinstance(self.account, Wallet): + errors["account"] = "Must pass in `wallet.address`, not `wallet`." + + return errors + + def to_dict(self: Self) -> Dict[str, Any]: + """ + Returns the dictionary representation of a Transaction. + + Returns: + The dictionary representation of a Transaction. + """ + # we need to override this because transaction_type is using ``field`` + # which will not include the value in the objects __dict__ + return { + **super().to_dict(), + "transaction_type": self.transaction_type.value, + "flags": self._flags_to_int(), + } + + def _iter_to_int( + self: Self, + lst: List[int], + ) -> int: + """Calculate flag as int.""" + accumulator = 0 + for flag in lst: + accumulator |= flag + return accumulator + + def _flags_to_int(self: Self) -> int: + if isinstance(self.flags, int): + return self.flags + check_false_flag_definition(tx_type=self.transaction_type, tx_flags=self.flags) + if isinstance(self.flags, dict): + return self._iter_to_int( + lst=interface_to_flag_list( + tx_type=self.transaction_type, + tx_flags=self.flags, + ) + ) + + return self._iter_to_int(lst=self.flags) + + def to_xrpl(self: Self) -> Dict[str, Any]: + """ + Creates a JSON-like dictionary in the JSON format used by the binary codec + based on the Transaction object. + + Returns: + A JSON-like dictionary in the JSON format used by the binary codec. + """ + return transaction_json_to_binary_codec_form(self.to_dict()) + + def blob(self: Self) -> str: + """ + Creates the canonical binary format of the Transaction object. + + Returns: + The binary-encoded object, as a hexadecimal string. + """ + return encode(self.to_xrpl()) + + @classmethod + def from_dict(cls: Type[Self], value: Dict[str, Any]) -> Self: + """ + Construct a new Transaction from a dictionary of parameters. + + Args: + value: The value to construct the Transaction from. + + Returns: + A new Transaction object, constructed using the given parameters. + + Raises: + XRPLModelException: If the dictionary provided is invalid. + """ + if cls.__name__ == "Transaction" or cls.__name__ == "PseudoTransaction": + # using `(Pseudo)Transaction.from_dict` and not a subclass + if "transaction_type" not in value: + raise XRPLModelException( + "Transaction does not include transaction_type." + ) + correct_type = cls.get_transaction_type(value["transaction_type"]) + return correct_type.from_dict(value) # type: ignore + else: + if "transaction_type" in value: + if value["transaction_type"] != cls.__name__: + transaction_type = value["transaction_type"] + raise XRPLModelException( + f"Using wrong constructor: using {cls.__name__} constructor " + f"with transaction type {transaction_type}." + ) + value = {**value} + del value["transaction_type"] + return super(Transaction, cls).from_dict(value) + + def has_flag(self: Self, flag: int) -> bool: + """ + Returns whether the transaction has the given flag value set. + + Args: + flag: The given flag value for which the function will determine whether it + is set. + + Returns: + Whether the transaction has the given flag value set. + """ + if isinstance(self.flags, int): + return self.flags & flag != 0 + elif isinstance(self.flags, dict): + return flag in interface_to_flag_list( + tx_type=self.transaction_type, + tx_flags=self.flags, + ) + else: # is List[int] + return flag in self.flags + + def is_signed(self: Self) -> bool: + """ + Checks if a transaction has been signed. + + Returns: + Whether the transaction has been signed + """ + if self.signers: + for signer in self.signers: + if ( + signer.signing_pub_key is None or len(signer.signing_pub_key) <= 0 + ) or (signer.txn_signature is None or len(signer.txn_signature) <= 0): + return False + return True + return ( + self.signing_pub_key is not None and len(self.signing_pub_key) > 0 + ) and (self.txn_signature is not None and len(self.txn_signature) > 0) + + def get_hash(self: Self) -> str: + """ + Hashes the Transaction object as the ledger does. Only valid for signed + Transaction objects. + + Returns: + The hash of the Transaction object. + + Raises: + XRPLModelException: if the Transaction is unsigned. + """ + if self.txn_signature is None and self.signers is None: + raise XRPLModelException( + "Cannot get the hash from an unsigned Transaction." + ) + prefix = hex(_TRANSACTION_HASH_PREFIX)[2:].upper() + encoded_str = bytes.fromhex(prefix + encode(self.to_xrpl())) + return sha512(encoded_str).digest().hex().upper()[:64] + + @classmethod + def get_transaction_type( + cls: Type[Self], transaction_type: str + ) -> Type[Transaction]: + """ + Returns the correct transaction type based on the string name. + + Args: + transaction_type: The String name of the Transaction object. + + Returns: + The transaction class with the given name. + + Raises: + XRPLModelException: If `transaction_type` is not a valid Transaction type. + """ + import xrpl.models.transactions as transaction_models + import xrpl.models.transactions.pseudo_transactions as pseudo_transaction_models + + transaction_types: Dict[str, Type[Transaction]] = { + t.value: getattr(transaction_models, t) + for t in transaction_models.types.TransactionType + } + if transaction_type in transaction_types: + return transaction_types[transaction_type] + + pseudo_transaction_types: Dict[str, Type[Transaction]] = { + t.value: getattr(pseudo_transaction_models, t) + for t in transaction_models.types.PseudoTransactionType + } + if transaction_type in pseudo_transaction_types: + return pseudo_transaction_types[transaction_type] + + raise XRPLModelException(f"{transaction_type} is not a valid Transaction type") + + @staticmethod + def from_blob(tx_blob: str) -> Transaction: + """ + Decodes a transaction blob. + + Args: + tx_blob: the tx blob to decode. + + Returns: + The formatted transaction. + """ + return Transaction.from_xrpl(decode(tx_blob)) + + @classmethod + def from_xrpl(cls: Type[Self], value: Union[str, Dict[str, Any]]) -> Self: + """ + Creates a Transaction object based on a JSON or JSON-string representation of + data + + In Payment transactions, the DeliverMax field is renamed to the Amount field. + + Args: + value: The dictionary or JSON string to be instantiated. + + Returns: + A Transaction object instantiated from the input. + + Raises: + XRPLModelException: If Payment transactions have different values for + amount and deliver_max fields + """ + processed_value = cls._process_xrpl_json(value) + + # handle the deliver_max alias in Payment transactions + if ( + "transaction_type" in processed_value + and processed_value["transaction_type"] == "Payment" + ) and "deliver_max" in processed_value: + if ( + "amount" in processed_value + and processed_value["amount"] != processed_value["deliver_max"] + ): + raise XRPLModelException( + "Error: amount and deliver_max fields must be equal if both are " + + "provided" + ) + else: + processed_value["amount"] = processed_value["deliver_max"] + + # deliver_max field is not recognised in the Payment Request format, + # nor is it supported in the serialization operations. + del processed_value["deliver_max"] + + return cls.from_dict(processed_value) + + def _get_errors(self: Transaction) -> Dict[str, str]: + errors = super._get_errors() + return errors diff --git a/xrpl/openapi-codegen/models/transactions/trust_set.py b/xrpl/openapi-codegen/models/transactions/trust_set.py new file mode 100644 index 000000000..1b3bc65e1 --- /dev/null +++ b/xrpl/openapi-codegen/models/transactions/trust_set.py @@ -0,0 +1,82 @@ +"""Model for TrustSet transaction type.""" + +from dataclasses import dataclass, field +from enum import Enum +from typing import Any, Optional +from xrpl.models.transactions.types import TransactionType +from xrpl.models.utils import REQUIRED +from xrpl.models.transactions.transaction import Transaction +from xrpl.models.trust_set_flag import TrustSetFlag +from xrpl.models.utils import require_kwargs_on_init + + +@require_kwargs_on_init +@dataclass(frozen=True) +class TrustSet(Transaction): + """ + Create or modify a trust line linking two accounts. + """ + + transaction_type: TransactionType = field( + default=TransactionType.TRUST_SET, init=False + ) + + limit_amount: Optional[Any] = REQUIRED + """ + Object defining the trust line to create or modify, in the format of a Currency Amount. + """ + + quality_in: Optional[int] = None + """ + (Optional) Value incoming balances on this trust line at the ratio of this number per + 1,000,000,000 units. A value of 0 is shorthand for treating balances at face value. + """ + + quality_out: Optional[int] = None + """ + (Optional) Value outgoing balances on this trust line at the ratio of this number per + 1,000,000,000 units. A value of 0 is shorthand for treating balances at face value. + """ + + +class TrustSetFlagInterface(FlagInterface): + """ + Enum for TrustSet Transaction Flags. + """ + + TF_SETF_AUTH: bool + TF_SET_NO_RIPPLE: bool + TF_CLEAR_NO_RIPPLE: bool + TF_SET_FREEZE: bool + TF_CLEAR_FREEZE: bool + + +class TrustSetFlag(int, Enum): + """ + Enum for TrustSet Transaction Flags. + """ + + TF_SETF_AUTH = 0x00010000 + """ + Authorize the other party to hold currency issued by this account. (No effect unless using the asfRequireAuth AccountSet flag.) Cannot be unset. + """ + + TF_SET_NO_RIPPLE = 0x00020000 + """ + Enable the No Ripple flag, which blocks rippling between two trust lines of the same currency if this flag is enabled on both. + """ + + TF_CLEAR_NO_RIPPLE = 0x00040000 + """ + Disable the No Ripple flag, allowing rippling on this trust line. + """ + + TF_SET_FREEZE = 0x00100000 + """ + Freeze the trust line. + """ + + TF_CLEAR_FREEZE = 0x00200000 + """ + Unfreeze the trust line. + """ diff --git a/xrpl/openapi-codegen/models/transactions/types/transaction_type.py b/xrpl/openapi-codegen/models/transactions/types/transaction_type.py new file mode 100644 index 000000000..d3862ada8 --- /dev/null +++ b/xrpl/openapi-codegen/models/transactions/types/transaction_type.py @@ -0,0 +1,56 @@ +"""Enum containing the different Transaction types.""" + +from enum import Enum + + +class TransactionType(str, Enum): + """Enum containing the different Transaction types.""" + + AMM_BID = "AMMBid" + AMM_CREATE = "AMMCreate" + AMM_DELETE = "AMMDelete" + AMM_DEPOSIT = "AMMDeposit" + AMM_VOTE = "AMMVote" + AMM_WITHDRAW = "AMMWithdraw" + ACCOUNT_DELETE = "AccountDelete" + ACCOUNT_SET = "AccountSet" + CHECK_CANCEL = "CheckCancel" + CHECK_CASH = "CheckCash" + CHECK_CREATE = "CheckCreate" + CLAWBACK = "Clawback" + CREDENTIAL_ACCEPT = "CredentialAccept" + CREDENTIAL_CREATE = "CredentialCreate" + CREDENTIAL_DELETE = "CredentialDelete" + DID_DELETE = "DIDDelete" + DID_SET = "DIDSet" + DEPOSIT_PREAUTH = "DepositPreauth" + ESCROW_CANCEL = "EscrowCancel" + ESCROW_CREATE = "EscrowCreate" + ESCROW_FINISH = "EscrowFinish" + MPTOKEN_AUTHORIZE = "MPTokenAuthorize" + MPTOKEN_ISSUANCE_CREATE = "MPTokenIssuanceCreate" + MPTOKEN_ISSUANCE_DESTROY = "MPTokenIssuanceDestroy" + MPTOKEN_ISSUANCE_SET = "MPTokenIssuanceSet" + NFTOKEN_ACCEPT_OFFER = "NFTokenAcceptOffer" + NFTOKEN_BURN = "NFTokenBurn" + NFTOKEN_CANCEL_OFFER = "NFTokenCancelOffer" + NFTOKEN_CREATE_OFFER = "NFTokenCreateOffer" + NFTOKEN_MINT = "NFTokenMint" + OFFER_CANCEL = "OfferCancel" + OFFER_CREATE = "OfferCreate" + ORACLE_DELETE = "OracleDelete" + ORACLE_SET = "OracleSet" + PAYMENT = "Payment" + PAYMENT_CHANNEL_CLAIM = "PaymentChannelClaim" + PAYMENT_CHANNEL_CREATE = "PaymentChannelCreate" + PAYMENT_CHANNEL_FUND = "PaymentChannelFund" + SET_REGULAR_KEY = "SetRegularKey" + TICKET_CREATE = "TicketCreate" + TRUST_SET = "TrustSet" + XCHAIN_ACCOUNT_CREATE_COMMIT = "XChainAccountCreateCommit" + XCHAIN_ADD_ACCOUNT_CREATE_ATTESTATION = "XChainAddAccountCreateAttestation" + XCHAIN_ADD_CLAIM_ATTESTATION = "XChainAddClaimAttestation" + XCHAIN_CLAIM = "XChainClaim" + XCHAIN_COMMIT = "XChainCommit" + XCHAIN_CREATE_BRIDGE = "XChainCreateBridge" + XCHAIN_MODIFY_BRIDGE = "XChainModifyBridge" diff --git a/xrpl/openapi-codegen/models/transactions/xchain_account_create_commit.py b/xrpl/openapi-codegen/models/transactions/xchain_account_create_commit.py new file mode 100644 index 000000000..6d26aee72 --- /dev/null +++ b/xrpl/openapi-codegen/models/transactions/xchain_account_create_commit.py @@ -0,0 +1,58 @@ +"""Model for XChainAccountCreateCommit transaction type.""" + +from dataclasses import dataclass, field +from typing import Optional +from xrpl.models.transactions.types import TransactionType +from xrpl.models.utils import REQUIRED +from xrpl.models.transactions.transaction import Transaction +from xrpl.models.xchain_bridge import XChainBridge +from xrpl.models.utils import require_kwargs_on_init + + +@require_kwargs_on_init +@dataclass(frozen=True) +class XChainAccountCreateCommit(Transaction): + """ + This transaction can only be used for XRP-XRP bridges. The XChainAccountCreateCommit + transaction creates a new account for a witness server to submit transactions on an + issuing chain. + """ + + transaction_type: TransactionType = field( + default=TransactionType.XCHAIN_ACCOUNT_CREATE_COMMIT, init=False + ) + + amount: str = REQUIRED + """ + The amount, in XRP, to use for account creation. This must be greater than or equal to + the MinAccountCreateAmount specified in the Bridge ledger object. + """ + + destination: str = REQUIRED + """ + The destination account on the destination chain. + """ + + signature_reward: Optional[str] = None + """ + (Optional) The amount, in XRP, to be used to reward the witness servers for providing + signatures. This must match the amount on the Bridge ledger object. + """ + + x_chain_bridge: XChainBridge = REQUIRED + + def _get_errors(self: XChainAccountCreateCommit) -> Dict[str, str]: + errors = super._get_errors() + if ( + self.amount is not None + and self.amount != REQUIRED + and not self.amount.isnumeric() + ): + errors["XChainAccountCreateCommit"] = "`amount` must be numeric." + if ( + self.signature_reward is not None + and self.signature_reward != REQUIRED + and not self.signature_reward.isnumeric() + ): + errors["XChainAccountCreateCommit"] = "`signature_reward` must be numeric." + return errors diff --git a/xrpl/openapi-codegen/models/transactions/xchain_add_account_create_attestation.py b/xrpl/openapi-codegen/models/transactions/xchain_add_account_create_attestation.py new file mode 100644 index 000000000..3fd8d03c3 --- /dev/null +++ b/xrpl/openapi-codegen/models/transactions/xchain_add_account_create_attestation.py @@ -0,0 +1,79 @@ +"""Model for XChainAddAccountCreateAttestation transaction type.""" + +from dataclasses import dataclass, field +from typing import Optional +from xrpl.models.transactions.types import TransactionType +from xrpl.models.utils import REQUIRED +from xrpl.models.transactions.transaction import Transaction +from xrpl.models.xchain_bridge import XChainBridge +from xrpl.models.utils import require_kwargs_on_init + + +@require_kwargs_on_init +@dataclass(frozen=True) +class XChainAddAccountCreateAttestation(Transaction): + """ + The XChainAddAccountCreateAttestation transaction provides an attestation from a witness + server that an XChainAccountCreateCommit transaction occurred on the other chain. The + signature must be from one of the keys on the door's signer list at the time the + signature was provided. If the signature list changes between the time the signature was + submitted and the quorum is reached, the new signature set is used and some of the + currently collected signatures may be removed. Any account can submit signatures. + """ + + transaction_type: TransactionType = field( + default=TransactionType.XCHAIN_ADD_ACCOUNT_CREATE_ATTESTATION, init=False + ) + + amount: str = REQUIRED + """ + The amount committed by the XChainAccountCreateCommit transaction on the source chain. + """ + + attestation_reward_account: str = REQUIRED + """ + The account that should receive this signer's share of the SignatureReward. + """ + + attestation_signer_account: str = REQUIRED + """ + The account on the door account's signer list that is signing the transaction. + """ + + destination: str = REQUIRED + """ + The destination account for the funds on the destination chain. + """ + + other_chain_source: str = REQUIRED + """ + The account on the source chain that submitted the XChainAccountCreateCommit transaction + that triggered the event associated with the attestation. + """ + + public_key: str = REQUIRED + """ + The public key used to verify the signature. + """ + + signature: str = REQUIRED + """ + The signature attesting to the event on the other chain. + """ + + signature_reward: str = REQUIRED + """ + The signature reward paid in the XChainAccountCreateCommit transaction. + """ + + was_locking_chain_send: int = REQUIRED + """ + A boolean representing the chain where the event occurred. + """ + + x_chain_account_create_count: str = REQUIRED + """ + The counter that represents the order that the claims must be processed in. + """ + + x_chain_bridge: XChainBridge = REQUIRED diff --git a/xrpl/openapi-codegen/models/transactions/xchain_add_claim_attestation.py b/xrpl/openapi-codegen/models/transactions/xchain_add_claim_attestation.py new file mode 100644 index 000000000..4199ae508 --- /dev/null +++ b/xrpl/openapi-codegen/models/transactions/xchain_add_claim_attestation.py @@ -0,0 +1,75 @@ +"""Model for XChainAddClaimAttestation transaction type.""" + +from dataclasses import dataclass, field +from typing import Optional +from xrpl.models.transactions.types import TransactionType +from xrpl.models.utils import REQUIRED +from xrpl.models.transactions.transaction import Transaction +from xrpl.models.xchain_bridge import XChainBridge +from xrpl.models.utils import require_kwargs_on_init + + +@require_kwargs_on_init +@dataclass(frozen=True) +class XChainAddClaimAttestation(Transaction): + """ + The XChainAddClaimAttestation transaction provides proof from a witness server, + attesting to an XChainCommit transaction. The signature must be from one of the keys on + the door's signer list at the time the signature was provided. However, if the signature + list changes between the time the signature was submitted and the quorum is reached, the + new signature set is used and some of the currently collected signatures may be removed. + Any account can submit signatures. + """ + + transaction_type: TransactionType = field( + default=TransactionType.XCHAIN_ADD_CLAIM_ATTESTATION, init=False + ) + + amount: str = REQUIRED + """ + The amount committed by the XChainCommit transaction on the source chain. + """ + + attestation_reward_account: str = REQUIRED + """ + The account that should receive this signer's share of the SignatureReward. + """ + + attestation_signer_account: str = REQUIRED + """ + The account on the door account's signer list that is signing the transaction. + """ + + destination: Optional[str] = None + """ + (Optional) The destination account for the funds on the destination chain (taken from + the XChainCommit transaction). + """ + + other_chain_source: str = REQUIRED + """ + The account on the source chain that submitted the XChainCommit transaction that + triggered the event associated with the attestation. + """ + + public_key: str = REQUIRED + """ + The public key used to verify the attestation signature. + """ + + signature: str = REQUIRED + """ + The signature attesting to the event on the other chain. + """ + + was_locking_chain_send: int = REQUIRED + """ + A boolean representing the chain where the event occurred. + """ + + x_chain_bridge: XChainBridge = REQUIRED + x_chain_claim_id: str = REQUIRED + """ + The XChainClaimID associated with the transfer, which was included in the XChainCommit + transaction. + """ diff --git a/xrpl/openapi-codegen/models/transactions/xchain_claim.py b/xrpl/openapi-codegen/models/transactions/xchain_claim.py new file mode 100644 index 000000000..e5e84d2d4 --- /dev/null +++ b/xrpl/openapi-codegen/models/transactions/xchain_claim.py @@ -0,0 +1,60 @@ +"""Model for XChainClaim transaction type.""" + +from dataclasses import dataclass, field +from typing import Any, Optional +from xrpl.models.transactions.types import TransactionType +from xrpl.models.utils import REQUIRED +from xrpl.models.transactions.transaction import Transaction +from xrpl.models.xchain_bridge import XChainBridge +from xrpl.models.utils import require_kwargs_on_init + + +@require_kwargs_on_init +@dataclass(frozen=True) +class XChainClaim(Transaction): + """ + The XChainClaim transaction completes a cross-chain transfer of value. It allows a user + to claim the value on the destination chain - the equivalent of the value locked on the + source chain. A user can only claim the value if they own the cross-chain claim ID + associated with the value locked on the source chain (the Account field). The user can + send the funds to anyone (the Destination field). This transaction is only needed if an + OtherChainDestination isn't specified in the XChainCommit transaction, or if something + goes wrong with the automatic transfer of funds. If the transaction succeeds in moving + funds, the referenced XChainOwnedClaimID ledger object will be destroyed. This prevents + transaction replay. If the transaction fails, the XChainOwnedClaimID won't be destroyed + and the transaction can be re-run with different parameters. + """ + + transaction_type: TransactionType = field( + default=TransactionType.XCHAIN_CLAIM, init=False + ) + + amount: Optional[Any] = REQUIRED + """ + The amount to claim on the destination chain. This must match the amount attested to on + the attestations associated with this XChainClaimID. + """ + + destination: str = REQUIRED + """ + The destination account on the destination chain. It must exist or the transaction will + fail. However, if the transaction fails in this case, the sequence number and collected + signatures won't be destroyed, and the transaction can be rerun with a different + destination. + """ + + destination_tag: Optional[int] = None + """ + (Optional) An integer destination tag. + """ + + x_chain_bridge: XChainBridge = REQUIRED + x_chain_claim_id: str = REQUIRED + """ + The unique integer ID for the cross-chain transfer that was referenced in the + corresponding XChainCommit transaction. + """ + + def _get_errors(self: XChainClaim) -> Dict[str, str]: + errors = super._get_errors() + return errors diff --git a/xrpl/openapi-codegen/models/transactions/xchain_commit.py b/xrpl/openapi-codegen/models/transactions/xchain_commit.py new file mode 100644 index 000000000..15d7eb587 --- /dev/null +++ b/xrpl/openapi-codegen/models/transactions/xchain_commit.py @@ -0,0 +1,46 @@ +"""Model for XChainCommit transaction type.""" + +from dataclasses import dataclass, field +from typing import Any, Optional +from xrpl.models.transactions.types import TransactionType +from xrpl.models.utils import REQUIRED +from xrpl.models.transactions.transaction import Transaction +from xrpl.models.xchain_bridge import XChainBridge +from xrpl.models.utils import require_kwargs_on_init + + +@require_kwargs_on_init +@dataclass(frozen=True) +class XChainCommit(Transaction): + """ + The XChainCommit is the second step in a cross-chain transfer. It puts assets into trust + on the locking chain so that they can be wrapped on the issuing chain, or burns wrapped + assets on the issuing chain so that they can be returned on the locking chain. + """ + + transaction_type: TransactionType = field( + default=TransactionType.XCHAIN_COMMIT, init=False + ) + + amount: Optional[Any] = REQUIRED + """ + The asset to commit, and the quantity. This must match the door account's + LockingChainIssue (if on the locking chain) or the door account's IssuingChainIssue (if + on the issuing chain). + """ + + other_chain_destination: Optional[str] = None + """ + (Optional) The destination account on the destination chain. If this is not specified, + the account that submitted the XChainCreateClaimID transaction on the destination chain + will need to submit a XChainClaim transaction to claim the funds. + """ + + x_chain_bridge: XChainBridge = REQUIRED + x_chain_claim_id: str = REQUIRED + """ + The unique integer ID for a cross-chain transfer. This must be acquired on the + destination chain (via a XChainCreateClaimID transaction) and checked from a validated + ledger before submitting this transaction. If an incorrect sequence number is specified, + the funds will be lost. + """ diff --git a/xrpl/openapi-codegen/models/transactions/xchain_create_bridge.py b/xrpl/openapi-codegen/models/transactions/xchain_create_bridge.py new file mode 100644 index 000000000..6be70ef15 --- /dev/null +++ b/xrpl/openapi-codegen/models/transactions/xchain_create_bridge.py @@ -0,0 +1,62 @@ +"""Model for XChainCreateBridge transaction type.""" + +from dataclasses import dataclass, field +from typing import Any, Optional +from xrpl.models.currencies import XRP +from xrpl.models.transactions.types import TransactionType +from xrpl.models.utils import REQUIRED +from xrpl.models.transactions.transaction import Transaction +from xrpl.models.xchain_bridge import XChainBridge +from xrpl.models.utils import require_kwargs_on_init + + +@require_kwargs_on_init +@dataclass(frozen=True) +class XChainCreateBridge(Transaction): + """ + The XChainCreateBridge transaction creates a new Bridge ledger object and defines a new + cross-chain bridge entrance on the chain that the transaction is submitted on. It + includes information about door accounts and assets for the bridge. The transaction + must be submitted first by the locking chain door account. To set up a valid bridge, + door accounts on both chains must submit this transaction, in addition to setting up + witness servers. The complete production-grade setup would also include a SignerListSet + transaction on the two door accounts for the witnesses’ signing keys, as well as + disabling the door accounts’ master key. This ensures that the witness servers are truly + in control of the funds. + """ + + transaction_type: TransactionType = field( + default=TransactionType.XCHAIN_CREATE_BRIDGE, init=False + ) + + min_account_create_amount: Optional[Any] = None + """ + (Optional) The minimum amount, in XRP, required for a XChainAccountCreateCommit + transaction. If this isn't present, the XChainAccountCreateCommit transaction will fail. + This field can only be present on XRP-XRP bridges. + """ + + signature_reward: Optional[Any] = REQUIRED + """ + The total amount to pay the witness servers for their signatures. This amount will be + split among the signers. + """ + + x_chain_bridge: XChainBridge = REQUIRED + + def _get_errors(self: XChainCreateBridge) -> Dict[str, str]: + errors = super._get_errors() + if self.account not in [ + self.xchain_bridge.issuing_chain_door, + self.xchain_bridge.locking_chain_door, + ]: + errors["XChainCreateBridge"] = ( + "`account` must be one of `xchain_bridge.issuing_chain_door`, or `xchain_bridge.locking_chain_door`" + ) + if (self.xchain_bridge.issuing_chain_issue == XRP()) != ( + self.xchain_bridge.locking_chain_issue == XRP() + ): + error["XChainCreateBridge"] = ( + "`xchain_bridge.issuing_chain_issue`, `xchain_bridge.locking_chain_issue` must be XRP-XRP or IOU-IOU" + ) + return errors diff --git a/xrpl/openapi-codegen/models/transactions/xchain_modify_bridge.py b/xrpl/openapi-codegen/models/transactions/xchain_modify_bridge.py new file mode 100644 index 000000000..0250ba86e --- /dev/null +++ b/xrpl/openapi-codegen/models/transactions/xchain_modify_bridge.py @@ -0,0 +1,71 @@ +"""Model for XChainModifyBridge transaction type.""" + +from dataclasses import dataclass, field +from enum import Enum +from typing import Any, Optional +from xrpl.models.transactions.types import TransactionType +from xrpl.models.utils import REQUIRED +from xrpl.models.transactions.transaction import Transaction +from xrpl.models.xchain_bridge import XChainBridge +from xrpl.models.xchain_modify_bridge_flag import XChainModifyBridgeFlag +from xrpl.models.utils import require_kwargs_on_init + + +@require_kwargs_on_init +@dataclass(frozen=True) +class XChainModifyBridge(Transaction): + """ + The XChainModifyBridge transaction allows bridge managers to modify the parameters of + the bridge. They can only change the SignatureReward and the MinAccountCreateAmount. + This transaction must be sent by the door account and requires the entities that control + the witness servers to coordinate and provide the signatures for this transaction. This + coordination happens outside the ledger. + """ + + transaction_type: TransactionType = field( + default=TransactionType.XCHAIN_MODIFY_BRIDGE, init=False + ) + + min_account_create_amount: Optional[Any] = None + """ + (Optional) The minimum amount, in XRP, required for a XChainAccountCreateCommit + transaction. If this is not present, the XChainAccountCreateCommit transaction will + fail. This field can only be present on XRP-XRP bridges. + """ + + signature_reward: Optional[Any] = None + """ + (Optional) The signature reward split between the witnesses for submitting attestations. + """ + + x_chain_bridge: XChainBridge = REQUIRED + + def _get_errors(self: XChainModifyBridge) -> Dict[str, str]: + errors = super._get_errors() + if self.account not in [ + self.xchain_bridge.issuing_chain_door, + self.xchain_bridge.locking_chain_door, + ]: + errors["XChainModifyBridge"] = ( + "`account` must be one of `xchain_bridge.issuing_chain_door`, or `xchain_bridge.locking_chain_door`" + ) + return errors + + +class XChainModifyBridgeFlagInterface(FlagInterface): + """ + Flags for the XChainModifyBridge transaction. + """ + + TF_CLEAR_ACCOUNT_CREATE_AMOUNT: bool + + +class XChainModifyBridgeFlag(int, Enum): + """ + Flags for the XChainModifyBridge transaction. + """ + + TF_CLEAR_ACCOUNT_CREATE_AMOUNT = 0x00010000 + """ + Clears the MinAccountCreateAmount of the bridge. + """ diff --git a/xrpl/openapi-codegen/models/xchain_bridge.py b/xrpl/openapi-codegen/models/xchain_bridge.py new file mode 100644 index 000000000..ef570dde4 --- /dev/null +++ b/xrpl/openapi-codegen/models/xchain_bridge.py @@ -0,0 +1,39 @@ +"""Model for XChainBridge.""" + +from dataclasses import dataclass +from xrpl.models.base_model import BaseModel +from xrpl.models.utils import REQUIRED +from xrpl.models.currency import Currency +from xrpl.models.utils import require_kwargs_on_init + + +@require_kwargs_on_init +@dataclass(frozen=True) +class XChainBridge(BaseModel): + """ + The bridge to create accounts for. + """ + + issuing_chain_door: str = REQUIRED + """ + The door account on the issuing chain. For an XRP-XRP bridge, this must be the genesis + account (the account that is created when the network is first started, which contains + all of the XRP). + """ + + issuing_chain_issue: Currency = REQUIRED + """ + The asset that is minted and burned on the issuing chain. For an IOU-IOU bridge, the + issuer of the asset must be the door account on the issuing chain, to avoid supply + issues. + """ + + locking_chain_door: str = REQUIRED + """ + The door account on the locking chain. + """ + + locking_chain_issue: Currency = REQUIRED + """ + The asset that is locked and unlocked on the locking chain. + """ diff --git a/xrpl/openapi-codegen/models/xrp.py b/xrpl/openapi-codegen/models/xrp.py new file mode 100644 index 000000000..0805816be --- /dev/null +++ b/xrpl/openapi-codegen/models/xrp.py @@ -0,0 +1,19 @@ +"""Model for XRP.""" + +from dataclasses import dataclass +from typing import Optional +from xrpl.models.base_model import BaseModel +from xrpl.models.utils import require_kwargs_on_init + + +@require_kwargs_on_init +@dataclass(frozen=True) +class XRP(BaseModel): + currency: Optional[str] = "XRP" + """ + ^ Specifies XRP as a currency, without a value. Normally, you will not use this model as + it does not specify an amount of XRP. In cases where you need to specify an amount of + XRP, you will use a string. However, for some book order requests where currencies are + specified without amounts, you may need to specify the use of XRP, without a value. In + these cases, you will use this object. + """ diff --git a/xrpl/openapi-codegen/test/transactions/test_account_delete.py b/xrpl/openapi-codegen/test/transactions/test_account_delete.py new file mode 100644 index 000000000..f72a65ece --- /dev/null +++ b/xrpl/openapi-codegen/test/transactions/test_account_delete.py @@ -0,0 +1,64 @@ +import unittest + +from xrpl.models.exceptions import XRPLModelException +from xrpl.models.transactions.account_delete import AccountDelete + + +class TestAccountDelete(unittest.TestCase): + def test_tx_invalid_missing_required_param_destination(self): + with self.assertRaises(XRPLModelException) as err: + AccountDelete( + account="rHb9CJAWyB4rj91VRWn96DkukG4bwdtyTh", + credential_ids=["AAAAA"], + destination_tag=5, + ) + self.assertIsNotNone(err.exception.args[0]) + + def test_tx_invalid_credential_ids_less_than_min_items(self): + with self.assertRaises(XRPLModelException) as err: + AccountDelete( + account="rHb9CJAWyB4rj91VRWn96DkukG4bwdtyTh", + credential_ids=[], + destination="AAAAA", + destination_tag=5, + ) + self.assertIsNotNone(err.exception.args[0]) + + def test_tx_invalid_credential_ids_more_than_max_items(self): + with self.assertRaises(XRPLModelException) as err: + AccountDelete( + account="rHb9CJAWyB4rj91VRWn96DkukG4bwdtyTh", + credential_ids=[ + "AAAAA", + "BBBBB", + "CCCCC", + "DDDDD", + "EEEEE", + "FFFFF", + "GGGGG", + "HHHHH", + "IIIII", + ], + destination="AAAAA", + destination_tag=5, + ) + self.assertIsNotNone(err.exception.args[0]) + + def test_tx_invalid_account_is_not_xrp_account(self): + with self.assertRaises(XRPLModelException) as err: + AccountDelete( + account="G5h7Dk92LmXqZtP3NvB8YrCfJ0W1AoUE", + credential_ids=["AAAAA"], + destination="AAAAA", + destination_tag=5, + ) + self.assertIsNotNone(err.exception.args[0]) + + def test_tx_valid_transaction(self): + tx = AccountDelete( + account="rHb9CJAWyB4rj91VRWn96DkukG4bwdtyTh", + credential_ids=["AAAAA"], + destination="AAAAA", + destination_tag=5, + ) + self.assertTrue(tx.is_valid()) diff --git a/xrpl/openapi-codegen/test/transactions/test_account_set.py b/xrpl/openapi-codegen/test/transactions/test_account_set.py new file mode 100644 index 000000000..e23e6220e --- /dev/null +++ b/xrpl/openapi-codegen/test/transactions/test_account_set.py @@ -0,0 +1,228 @@ +import unittest + +from xrpl.models.exceptions import XRPLModelException +from xrpl.models.transactions.account_set import AccountSet +from xrpl.models.transactions.account_set import AccountSetAsfFlag +from xrpl.models.transactions.account_set import AccountSetFlag + + +class TestAccountSet(unittest.TestCase): + def test_tx_invalid_transfer_rate_greater_than_max(self): + with self.assertRaises(XRPLModelException) as err: + AccountSet( + account="rHb9CJAWyB4rj91VRWn96DkukG4bwdtyTh", + clear_flag=AccountSetAsfFlag.ASF_ALLOW_TRUSTLINE_CLAWBACK, + domain="eee1865f2068c323ed13e569d12f8a77db2249d1be0dd0ed8afed6fd23f0221a", + email_hash="1280cff9a097213f011d9162251999e1", + flags=AccountSetFlag.TF_ALLOW_XRP, + message_key="AAAAA", + set_flag=AccountSetAsfFlag.ASF_ACCOUNT_TXN_ID, + tick_size=3, + transfer_rate=2000000001, + wallet_locator="2561865f2068c323ed13e569d12f8a77db2249d1be0dd0ed8afed6fd23f0221a", + wallet_size=5, + ) + self.assertIsNotNone(err.exception.args[0]) + + def test_tx_invalid_tick_size_greater_than_max(self): + with self.assertRaises(XRPLModelException) as err: + AccountSet( + account="rHb9CJAWyB4rj91VRWn96DkukG4bwdtyTh", + clear_flag=AccountSetAsfFlag.ASF_ALLOW_TRUSTLINE_CLAWBACK, + domain="eee1865f2068c323ed13e569d12f8a77db2249d1be0dd0ed8afed6fd23f0221a", + email_hash="1280cff9a097213f011d9162251999e1", + flags=AccountSetFlag.TF_ALLOW_XRP, + message_key="AAAAA", + set_flag=AccountSetAsfFlag.ASF_ACCOUNT_TXN_ID, + tick_size=16, + transfer_rate=1000000000, + wallet_locator="2561865f2068c323ed13e569d12f8a77db2249d1be0dd0ed8afed6fd23f0221a", + wallet_size=5, + ) + self.assertIsNotNone(err.exception.args[0]) + + def test_tx_invalid_transfer_rate_less_than_min(self): + with self.assertRaises(XRPLModelException) as err: + AccountSet( + account="rHb9CJAWyB4rj91VRWn96DkukG4bwdtyTh", + clear_flag=AccountSetAsfFlag.ASF_ALLOW_TRUSTLINE_CLAWBACK, + domain="eee1865f2068c323ed13e569d12f8a77db2249d1be0dd0ed8afed6fd23f0221a", + email_hash="1280cff9a097213f011d9162251999e1", + flags=AccountSetFlag.TF_ALLOW_XRP, + message_key="AAAAA", + set_flag=AccountSetAsfFlag.ASF_ACCOUNT_TXN_ID, + tick_size=3, + transfer_rate=999999999, + wallet_locator="2561865f2068c323ed13e569d12f8a77db2249d1be0dd0ed8afed6fd23f0221a", + wallet_size=5, + ) + self.assertIsNotNone(err.exception.args[0]) + + def test_tx_invalid_tick_size_less_than_min(self): + with self.assertRaises(XRPLModelException) as err: + AccountSet( + account="rHb9CJAWyB4rj91VRWn96DkukG4bwdtyTh", + clear_flag=AccountSetAsfFlag.ASF_ALLOW_TRUSTLINE_CLAWBACK, + domain="eee1865f2068c323ed13e569d12f8a77db2249d1be0dd0ed8afed6fd23f0221a", + email_hash="1280cff9a097213f011d9162251999e1", + flags=AccountSetFlag.TF_ALLOW_XRP, + message_key="AAAAA", + set_flag=AccountSetAsfFlag.ASF_ACCOUNT_TXN_ID, + tick_size=2, + transfer_rate=1000000000, + wallet_locator="2561865f2068c323ed13e569d12f8a77db2249d1be0dd0ed8afed6fd23f0221a", + wallet_size=5, + ) + self.assertIsNotNone(err.exception.args[0]) + + def test_tx_invalid_missing_required_param_account(self): + with self.assertRaises(XRPLModelException) as err: + AccountSet( + clear_flag=AccountSetAsfFlag.ASF_ALLOW_TRUSTLINE_CLAWBACK, + domain="eee1865f2068c323ed13e569d12f8a77db2249d1be0dd0ed8afed6fd23f0221a", + email_hash="1280cff9a097213f011d9162251999e1", + flags=AccountSetFlag.TF_ALLOW_XRP, + message_key="AAAAA", + set_flag=AccountSetAsfFlag.ASF_ACCOUNT_TXN_ID, + tick_size=3, + transfer_rate=1000000000, + wallet_locator="2561865f2068c323ed13e569d12f8a77db2249d1be0dd0ed8afed6fd23f0221a", + wallet_size=5, + ) + self.assertIsNotNone(err.exception.args[0]) + + def test_tx_invalid_duplicate_set_flag_and_clear_flag(self): + with self.assertRaises(XRPLModelException) as err: + AccountSet( + account="rHb9CJAWyB4rj91VRWn96DkukG4bwdtyTh", + clear_flag=AccountSetAsfFlag.ASF_ALLOW_TRUSTLINE_CLAWBACK, + domain="eee1865f2068c323ed13e569d12f8a77db2249d1be0dd0ed8afed6fd23f0221a", + email_hash="1280cff9a097213f011d9162251999e1", + flags=AccountSetFlag.TF_ALLOW_XRP, + message_key="AAAAA", + set_flag=AccountSetAsfFlag.ASF_ALLOW_TRUSTLINE_CLAWBACK, + tick_size=3, + transfer_rate=1000000000, + wallet_locator="2561865f2068c323ed13e569d12f8a77db2249d1be0dd0ed8afed6fd23f0221a", + wallet_size=5, + ) + self.assertIsNotNone(err.exception.args[0]) + + def test_tx_invalid_domain_too_long(self): + with self.assertRaises(XRPLModelException) as err: + AccountSet( + account="rHb9CJAWyB4rj91VRWn96DkukG4bwdtyTh", + clear_flag=AccountSetAsfFlag.ASF_ALLOW_TRUSTLINE_CLAWBACK, + domain="eee1865f2068c323ed13e569d12f8a77db2249d1be0dd0ed8afed6fd23f0221aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa", + email_hash="1280cff9a097213f011d9162251999e1", + flags=AccountSetFlag.TF_ALLOW_XRP, + message_key="AAAAA", + set_flag=AccountSetAsfFlag.ASF_ACCOUNT_TXN_ID, + tick_size=3, + transfer_rate=1000000000, + wallet_locator="2561865f2068c323ed13e569d12f8a77db2249d1be0dd0ed8afed6fd23f0221a", + wallet_size=5, + ) + self.assertIsNotNone(err.exception.args[0]) + + def test_tx_invalid_present_nftoken_minter_on_missing_asf_authorized_nftoken_minter( + self, + ): + with self.assertRaises(XRPLModelException) as err: + AccountSet( + account="rHb9CJAWyB4rj91VRWn96DkukG4bwdtyTh", + clear_flag=AccountSetAsfFlag.ASF_ALLOW_TRUSTLINE_CLAWBACK, + domain="eee1865f2068c323ed13e569d12f8a77db2249d1be0dd0ed8afed6fd23f0221a", + email_hash="1280cff9a097213f011d9162251999e1", + flags=AccountSetFlag.TF_ALLOW_XRP, + message_key="AAAAA", + set_flag=AccountSetAsfFlag.ASF_ACCOUNT_TXN_ID, + tick_size=3, + transfer_rate=1000000000, + wallet_locator="2561865f2068c323ed13e569d12f8a77db2249d1be0dd0ed8afed6fd23f0221a", + wallet_size=5, + nftoken_minter="AAAAA", + ) + self.assertIsNotNone(err.exception.args[0]) + + def test_tx_valid_special_value_tick_size(self): + tx = AccountSet( + account="rHb9CJAWyB4rj91VRWn96DkukG4bwdtyTh", + clear_flag=AccountSetAsfFlag.ASF_ALLOW_TRUSTLINE_CLAWBACK, + domain="eee1865f2068c323ed13e569d12f8a77db2249d1be0dd0ed8afed6fd23f0221a", + email_hash="1280cff9a097213f011d9162251999e1", + flags=AccountSetFlag.TF_ALLOW_XRP, + message_key="AAAAA", + set_flag=AccountSetAsfFlag.ASF_ACCOUNT_TXN_ID, + tick_size=0, + transfer_rate=1000000000, + wallet_locator="2561865f2068c323ed13e569d12f8a77db2249d1be0dd0ed8afed6fd23f0221a", + wallet_size=5, + ) + self.assertTrue(tx.is_valid()) + + def test_tx_valid_special_value_transfer_rate(self): + tx = AccountSet( + account="rHb9CJAWyB4rj91VRWn96DkukG4bwdtyTh", + clear_flag=AccountSetAsfFlag.ASF_ALLOW_TRUSTLINE_CLAWBACK, + domain="eee1865f2068c323ed13e569d12f8a77db2249d1be0dd0ed8afed6fd23f0221a", + email_hash="1280cff9a097213f011d9162251999e1", + flags=AccountSetFlag.TF_ALLOW_XRP, + message_key="AAAAA", + set_flag=AccountSetAsfFlag.ASF_ACCOUNT_TXN_ID, + tick_size=3, + transfer_rate=0, + wallet_locator="2561865f2068c323ed13e569d12f8a77db2249d1be0dd0ed8afed6fd23f0221a", + wallet_size=5, + ) + self.assertTrue(tx.is_valid()) + + def test_tx_invalid_domain_not_lower_case(self): + with self.assertRaises(XRPLModelException) as err: + AccountSet( + account="rHb9CJAWyB4rj91VRWn96DkukG4bwdtyTh", + clear_flag=AccountSetAsfFlag.ASF_ALLOW_TRUSTLINE_CLAWBACK, + domain="EEE1865F2068C323ED13E569D12F8A77DB2249D1BE0DD0ED8AFED6FD23F0221A", + email_hash="1280cff9a097213f011d9162251999e1", + flags=AccountSetFlag.TF_ALLOW_XRP, + message_key="AAAAA", + set_flag=AccountSetAsfFlag.ASF_ACCOUNT_TXN_ID, + tick_size=3, + transfer_rate=1000000000, + wallet_locator="2561865f2068c323ed13e569d12f8a77db2249d1be0dd0ed8afed6fd23f0221a", + wallet_size=5, + ) + self.assertIsNotNone(err.exception.args[0]) + + def test_tx_invalid_account_is_not_xrp_account(self): + with self.assertRaises(XRPLModelException) as err: + AccountSet( + account="G5h7Dk92LmXqZtP3NvB8YrCfJ0W1AoUE", + clear_flag=AccountSetAsfFlag.ASF_ALLOW_TRUSTLINE_CLAWBACK, + domain="eee1865f2068c323ed13e569d12f8a77db2249d1be0dd0ed8afed6fd23f0221a", + email_hash="1280cff9a097213f011d9162251999e1", + flags=AccountSetFlag.TF_ALLOW_XRP, + message_key="AAAAA", + set_flag=AccountSetAsfFlag.ASF_ACCOUNT_TXN_ID, + tick_size=3, + transfer_rate=1000000000, + wallet_locator="2561865f2068c323ed13e569d12f8a77db2249d1be0dd0ed8afed6fd23f0221a", + wallet_size=5, + ) + self.assertIsNotNone(err.exception.args[0]) + + def test_tx_valid_transaction(self): + tx = AccountSet( + account="rHb9CJAWyB4rj91VRWn96DkukG4bwdtyTh", + clear_flag=AccountSetAsfFlag.ASF_ALLOW_TRUSTLINE_CLAWBACK, + domain="eee1865f2068c323ed13e569d12f8a77db2249d1be0dd0ed8afed6fd23f0221a", + email_hash="1280cff9a097213f011d9162251999e1", + flags=AccountSetFlag.TF_ALLOW_XRP, + message_key="AAAAA", + set_flag=AccountSetAsfFlag.ASF_ACCOUNT_TXN_ID, + tick_size=3, + transfer_rate=1000000000, + wallet_locator="2561865f2068c323ed13e569d12f8a77db2249d1be0dd0ed8afed6fd23f0221a", + wallet_size=5, + ) + self.assertTrue(tx.is_valid()) diff --git a/xrpl/openapi-codegen/test/transactions/test_amm_bid.py b/xrpl/openapi-codegen/test/transactions/test_amm_bid.py new file mode 100644 index 000000000..9991c0496 --- /dev/null +++ b/xrpl/openapi-codegen/test/transactions/test_amm_bid.py @@ -0,0 +1,128 @@ +import unittest + +from xrpl.models.exceptions import XRPLModelException +from xrpl.models.transactions.amm_bid import AMMBid +from xrpl.models.transactions.amm_bid import AuthAccount +from xrpl.models.transactions.amm_bid import Currency + + +class TestAMMBid(unittest.TestCase): + def test_tx_invalid_missing_required_param_asset(self): + with self.assertRaises(XRPLModelException) as err: + AMMBid( + account="rHb9CJAWyB4rj91VRWn96DkukG4bwdtyTh", + asset2=Currency( + currency="USD", issuer="rHb9CJAWyB4rj91VRWn96DkukG4bwdtyTh" + ), + auth_accounts=[ + AuthAccount(account="rHb9CJAWyB4rj91VRWn96DkukG4bwdtyTh"), + AuthAccount(account="rHb9CJAWyB4rj91VRWn96DkukG4bwdtyTh"), + AuthAccount(account="rHb9CJAWyB4rj91VRWn96DkukG4bwdtyTh"), + AuthAccount(account="rHb9CJAWyB4rj91VRWn96DkukG4bwdtyTh"), + ], + bid_max="12345", + bid_min="12345", + ) + self.assertIsNotNone(err.exception.args[0]) + + def test_tx_invalid_missing_required_param_account(self): + with self.assertRaises(XRPLModelException) as err: + AMMBid( + account="rHb9CJAWyB4rj91VRWn96DkukG4bwdtyTh", + asset=Currency( + currency="USD", issuer="rHb9CJAWyB4rj91VRWn96DkukG4bwdtyTh" + ), + asset2=Currency( + currency="USD", issuer="rHb9CJAWyB4rj91VRWn96DkukG4bwdtyTh" + ), + auth_accounts=[ + AuthAccount(), + AuthAccount(), + AuthAccount(), + AuthAccount(), + ], + bid_max="12345", + bid_min="12345", + ) + self.assertIsNotNone(err.exception.args[0]) + + def test_tx_invalid_account_is_not_xrp_account(self): + with self.assertRaises(XRPLModelException) as err: + AMMBid( + account="G5h7Dk92LmXqZtP3NvB8YrCfJ0W1AoUE", + asset=Currency( + currency="USD", issuer="rHb9CJAWyB4rj91VRWn96DkukG4bwdtyTh" + ), + asset2=Currency( + currency="USD", issuer="rHb9CJAWyB4rj91VRWn96DkukG4bwdtyTh" + ), + auth_accounts=[ + AuthAccount(account="rHb9CJAWyB4rj91VRWn96DkukG4bwdtyTh"), + AuthAccount(account="rHb9CJAWyB4rj91VRWn96DkukG4bwdtyTh"), + AuthAccount(account="rHb9CJAWyB4rj91VRWn96DkukG4bwdtyTh"), + AuthAccount(account="rHb9CJAWyB4rj91VRWn96DkukG4bwdtyTh"), + ], + bid_max="12345", + bid_min="12345", + ) + self.assertIsNotNone(err.exception.args[0]) + + def test_tx_invalid_account_is_not_xrp_account(self): + with self.assertRaises(XRPLModelException) as err: + AMMBid( + account="rHb9CJAWyB4rj91VRWn96DkukG4bwdtyTh", + asset=Currency( + currency="USD", issuer="rHb9CJAWyB4rj91VRWn96DkukG4bwdtyTh" + ), + asset2=Currency( + currency="USD", issuer="rHb9CJAWyB4rj91VRWn96DkukG4bwdtyTh" + ), + auth_accounts=[ + AuthAccount(account="G5h7Dk92LmXqZtP3NvB8YrCfJ0W1AoUE"), + AuthAccount(account="G5h7Dk92LmXqZtP3NvB8YrCfJ0W1AoUE"), + AuthAccount(account="G5h7Dk92LmXqZtP3NvB8YrCfJ0W1AoUE"), + AuthAccount(account="G5h7Dk92LmXqZtP3NvB8YrCfJ0W1AoUE"), + ], + bid_max="12345", + bid_min="12345", + ) + self.assertIsNotNone(err.exception.args[0]) + + def test_tx_invalid_issuer_is_not_xrp_account(self): + with self.assertRaises(XRPLModelException) as err: + AMMBid( + account="rHb9CJAWyB4rj91VRWn96DkukG4bwdtyTh", + asset=Currency( + currency="USD", issuer="G5h7Dk92LmXqZtP3NvB8YrCfJ0W1AoUE" + ), + asset2=Currency( + currency="USD", issuer="G5h7Dk92LmXqZtP3NvB8YrCfJ0W1AoUE" + ), + auth_accounts=[ + AuthAccount(account="rHb9CJAWyB4rj91VRWn96DkukG4bwdtyTh"), + AuthAccount(account="rHb9CJAWyB4rj91VRWn96DkukG4bwdtyTh"), + AuthAccount(account="rHb9CJAWyB4rj91VRWn96DkukG4bwdtyTh"), + AuthAccount(account="rHb9CJAWyB4rj91VRWn96DkukG4bwdtyTh"), + ], + bid_max="12345", + bid_min="12345", + ) + self.assertIsNotNone(err.exception.args[0]) + + def test_tx_valid_transaction(self): + tx = AMMBid( + account="rHb9CJAWyB4rj91VRWn96DkukG4bwdtyTh", + asset=Currency(currency="USD", issuer="rHb9CJAWyB4rj91VRWn96DkukG4bwdtyTh"), + asset2=Currency( + currency="USD", issuer="rHb9CJAWyB4rj91VRWn96DkukG4bwdtyTh" + ), + auth_accounts=[ + AuthAccount(account="rHb9CJAWyB4rj91VRWn96DkukG4bwdtyTh"), + AuthAccount(account="rHb9CJAWyB4rj91VRWn96DkukG4bwdtyTh"), + AuthAccount(account="rHb9CJAWyB4rj91VRWn96DkukG4bwdtyTh"), + AuthAccount(account="rHb9CJAWyB4rj91VRWn96DkukG4bwdtyTh"), + ], + bid_max="12345", + bid_min="12345", + ) + self.assertTrue(tx.is_valid()) diff --git a/xrpl/openapi-codegen/test/transactions/test_amm_create.py b/xrpl/openapi-codegen/test/transactions/test_amm_create.py new file mode 100644 index 000000000..e169ea58d --- /dev/null +++ b/xrpl/openapi-codegen/test/transactions/test_amm_create.py @@ -0,0 +1,45 @@ +import unittest + +from xrpl.models.exceptions import XRPLModelException +from xrpl.models.transactions.amm_create import AMMCreate + + +class TestAMMCreate(unittest.TestCase): + def test_tx_invalid_trading_fee_greater_than_max(self): + with self.assertRaises(XRPLModelException) as err: + AMMCreate( + account="rHb9CJAWyB4rj91VRWn96DkukG4bwdtyTh", + amount="12345", + amount2="12345", + trading_fee=1001, + ) + self.assertIsNotNone(err.exception.args[0]) + + def test_tx_invalid_trading_fee_less_than_min(self): + with self.assertRaises(XRPLModelException) as err: + AMMCreate( + account="rHb9CJAWyB4rj91VRWn96DkukG4bwdtyTh", + amount="12345", + amount2="12345", + trading_fee=-1, + ) + self.assertIsNotNone(err.exception.args[0]) + + def test_tx_invalid_account_is_not_xrp_account(self): + with self.assertRaises(XRPLModelException) as err: + AMMCreate( + account="G5h7Dk92LmXqZtP3NvB8YrCfJ0W1AoUE", + amount="12345", + amount2="12345", + trading_fee=0, + ) + self.assertIsNotNone(err.exception.args[0]) + + def test_tx_valid_transaction(self): + tx = AMMCreate( + account="rHb9CJAWyB4rj91VRWn96DkukG4bwdtyTh", + amount="12345", + amount2="12345", + trading_fee=0, + ) + self.assertTrue(tx.is_valid()) diff --git a/xrpl/openapi-codegen/test/transactions/test_amm_delete.py b/xrpl/openapi-codegen/test/transactions/test_amm_delete.py new file mode 100644 index 000000000..2a48d3955 --- /dev/null +++ b/xrpl/openapi-codegen/test/transactions/test_amm_delete.py @@ -0,0 +1,53 @@ +import unittest + +from xrpl.models.exceptions import XRPLModelException +from xrpl.models.transactions.amm_delete import AMMDelete +from xrpl.models.transactions.amm_delete import Currency + + +class TestAMMDelete(unittest.TestCase): + def test_tx_invalid_missing_required_param_asset(self): + with self.assertRaises(XRPLModelException) as err: + AMMDelete( + account="rHb9CJAWyB4rj91VRWn96DkukG4bwdtyTh", + asset2=Currency( + currency="USD", issuer="rHb9CJAWyB4rj91VRWn96DkukG4bwdtyTh" + ), + ) + self.assertIsNotNone(err.exception.args[0]) + + def test_tx_invalid_account_is_not_xrp_account(self): + with self.assertRaises(XRPLModelException) as err: + AMMDelete( + account="G5h7Dk92LmXqZtP3NvB8YrCfJ0W1AoUE", + asset=Currency( + currency="USD", issuer="rHb9CJAWyB4rj91VRWn96DkukG4bwdtyTh" + ), + asset2=Currency( + currency="USD", issuer="rHb9CJAWyB4rj91VRWn96DkukG4bwdtyTh" + ), + ) + self.assertIsNotNone(err.exception.args[0]) + + def test_tx_invalid_issuer_is_not_xrp_account(self): + with self.assertRaises(XRPLModelException) as err: + AMMDelete( + account="rHb9CJAWyB4rj91VRWn96DkukG4bwdtyTh", + asset=Currency( + currency="USD", issuer="G5h7Dk92LmXqZtP3NvB8YrCfJ0W1AoUE" + ), + asset2=Currency( + currency="USD", issuer="G5h7Dk92LmXqZtP3NvB8YrCfJ0W1AoUE" + ), + ) + self.assertIsNotNone(err.exception.args[0]) + + def test_tx_valid_transaction(self): + tx = AMMDelete( + account="rHb9CJAWyB4rj91VRWn96DkukG4bwdtyTh", + asset=Currency(currency="USD", issuer="rHb9CJAWyB4rj91VRWn96DkukG4bwdtyTh"), + asset2=Currency( + currency="USD", issuer="rHb9CJAWyB4rj91VRWn96DkukG4bwdtyTh" + ), + ) + self.assertTrue(tx.is_valid()) diff --git a/xrpl/openapi-codegen/test/transactions/test_amm_deposit.py b/xrpl/openapi-codegen/test/transactions/test_amm_deposit.py new file mode 100644 index 000000000..0a9a1361a --- /dev/null +++ b/xrpl/openapi-codegen/test/transactions/test_amm_deposit.py @@ -0,0 +1,116 @@ +import unittest + +from xrpl.models.exceptions import XRPLModelException +from xrpl.models.transactions.amm_deposit import AMMDeposit +from xrpl.models.transactions.amm_deposit import AMMDepositFlag +from xrpl.models.transactions.amm_deposit import Currency + + +class TestAMMDeposit(unittest.TestCase): + def test_tx_invalid_trading_fee_greater_than_max(self): + with self.assertRaises(XRPLModelException) as err: + AMMDeposit( + account="rHb9CJAWyB4rj91VRWn96DkukG4bwdtyTh", + amount="12345", + amount2="12345", + asset=Currency( + currency="USD", issuer="rHb9CJAWyB4rj91VRWn96DkukG4bwdtyTh" + ), + asset2=Currency( + currency="USD", issuer="rHb9CJAWyB4rj91VRWn96DkukG4bwdtyTh" + ), + e_price="12345", + flags=AMMDepositFlag.TF_LIMIT_LP_TOKEN, + lp_token_out="12345", + trading_fee=1001, + ) + self.assertIsNotNone(err.exception.args[0]) + + def test_tx_invalid_trading_fee_less_than_min(self): + with self.assertRaises(XRPLModelException) as err: + AMMDeposit( + account="rHb9CJAWyB4rj91VRWn96DkukG4bwdtyTh", + amount="12345", + amount2="12345", + asset=Currency( + currency="USD", issuer="rHb9CJAWyB4rj91VRWn96DkukG4bwdtyTh" + ), + asset2=Currency( + currency="USD", issuer="rHb9CJAWyB4rj91VRWn96DkukG4bwdtyTh" + ), + e_price="12345", + flags=AMMDepositFlag.TF_LIMIT_LP_TOKEN, + lp_token_out="12345", + trading_fee=-1, + ) + self.assertIsNotNone(err.exception.args[0]) + + def test_tx_invalid_missing_required_param_asset(self): + with self.assertRaises(XRPLModelException) as err: + AMMDeposit( + account="rHb9CJAWyB4rj91VRWn96DkukG4bwdtyTh", + amount="12345", + amount2="12345", + asset2=Currency( + currency="USD", issuer="rHb9CJAWyB4rj91VRWn96DkukG4bwdtyTh" + ), + e_price="12345", + flags=AMMDepositFlag.TF_LIMIT_LP_TOKEN, + lp_token_out="12345", + trading_fee=0, + ) + self.assertIsNotNone(err.exception.args[0]) + + def test_tx_invalid_account_is_not_xrp_account(self): + with self.assertRaises(XRPLModelException) as err: + AMMDeposit( + account="G5h7Dk92LmXqZtP3NvB8YrCfJ0W1AoUE", + amount="12345", + amount2="12345", + asset=Currency( + currency="USD", issuer="rHb9CJAWyB4rj91VRWn96DkukG4bwdtyTh" + ), + asset2=Currency( + currency="USD", issuer="rHb9CJAWyB4rj91VRWn96DkukG4bwdtyTh" + ), + e_price="12345", + flags=AMMDepositFlag.TF_LIMIT_LP_TOKEN, + lp_token_out="12345", + trading_fee=0, + ) + self.assertIsNotNone(err.exception.args[0]) + + def test_tx_invalid_issuer_is_not_xrp_account(self): + with self.assertRaises(XRPLModelException) as err: + AMMDeposit( + account="rHb9CJAWyB4rj91VRWn96DkukG4bwdtyTh", + amount="12345", + amount2="12345", + asset=Currency( + currency="USD", issuer="G5h7Dk92LmXqZtP3NvB8YrCfJ0W1AoUE" + ), + asset2=Currency( + currency="USD", issuer="G5h7Dk92LmXqZtP3NvB8YrCfJ0W1AoUE" + ), + e_price="12345", + flags=AMMDepositFlag.TF_LIMIT_LP_TOKEN, + lp_token_out="12345", + trading_fee=0, + ) + self.assertIsNotNone(err.exception.args[0]) + + def test_tx_valid_transaction(self): + tx = AMMDeposit( + account="rHb9CJAWyB4rj91VRWn96DkukG4bwdtyTh", + amount="12345", + amount2="12345", + asset=Currency(currency="USD", issuer="rHb9CJAWyB4rj91VRWn96DkukG4bwdtyTh"), + asset2=Currency( + currency="USD", issuer="rHb9CJAWyB4rj91VRWn96DkukG4bwdtyTh" + ), + e_price="12345", + flags=AMMDepositFlag.TF_LIMIT_LP_TOKEN, + lp_token_out="12345", + trading_fee=0, + ) + self.assertTrue(tx.is_valid()) diff --git a/xrpl/openapi-codegen/test/transactions/test_amm_vote.py b/xrpl/openapi-codegen/test/transactions/test_amm_vote.py new file mode 100644 index 000000000..5a7285c74 --- /dev/null +++ b/xrpl/openapi-codegen/test/transactions/test_amm_vote.py @@ -0,0 +1,85 @@ +import unittest + +from xrpl.models.exceptions import XRPLModelException +from xrpl.models.transactions.amm_vote import AMMVote +from xrpl.models.transactions.amm_vote import Currency + + +class TestAMMVote(unittest.TestCase): + def test_tx_invalid_trading_fee_greater_than_max(self): + with self.assertRaises(XRPLModelException) as err: + AMMVote( + account="rHb9CJAWyB4rj91VRWn96DkukG4bwdtyTh", + asset=Currency( + currency="USD", issuer="rHb9CJAWyB4rj91VRWn96DkukG4bwdtyTh" + ), + asset2=Currency( + currency="USD", issuer="rHb9CJAWyB4rj91VRWn96DkukG4bwdtyTh" + ), + trading_fee=1001, + ) + self.assertIsNotNone(err.exception.args[0]) + + def test_tx_invalid_trading_fee_less_than_min(self): + with self.assertRaises(XRPLModelException) as err: + AMMVote( + account="rHb9CJAWyB4rj91VRWn96DkukG4bwdtyTh", + asset=Currency( + currency="USD", issuer="rHb9CJAWyB4rj91VRWn96DkukG4bwdtyTh" + ), + asset2=Currency( + currency="USD", issuer="rHb9CJAWyB4rj91VRWn96DkukG4bwdtyTh" + ), + trading_fee=-1, + ) + self.assertIsNotNone(err.exception.args[0]) + + def test_tx_invalid_missing_required_param_asset(self): + with self.assertRaises(XRPLModelException) as err: + AMMVote( + account="rHb9CJAWyB4rj91VRWn96DkukG4bwdtyTh", + asset2=Currency( + currency="USD", issuer="rHb9CJAWyB4rj91VRWn96DkukG4bwdtyTh" + ), + trading_fee=0, + ) + self.assertIsNotNone(err.exception.args[0]) + + def test_tx_invalid_account_is_not_xrp_account(self): + with self.assertRaises(XRPLModelException) as err: + AMMVote( + account="G5h7Dk92LmXqZtP3NvB8YrCfJ0W1AoUE", + asset=Currency( + currency="USD", issuer="rHb9CJAWyB4rj91VRWn96DkukG4bwdtyTh" + ), + asset2=Currency( + currency="USD", issuer="rHb9CJAWyB4rj91VRWn96DkukG4bwdtyTh" + ), + trading_fee=0, + ) + self.assertIsNotNone(err.exception.args[0]) + + def test_tx_invalid_issuer_is_not_xrp_account(self): + with self.assertRaises(XRPLModelException) as err: + AMMVote( + account="rHb9CJAWyB4rj91VRWn96DkukG4bwdtyTh", + asset=Currency( + currency="USD", issuer="G5h7Dk92LmXqZtP3NvB8YrCfJ0W1AoUE" + ), + asset2=Currency( + currency="USD", issuer="G5h7Dk92LmXqZtP3NvB8YrCfJ0W1AoUE" + ), + trading_fee=0, + ) + self.assertIsNotNone(err.exception.args[0]) + + def test_tx_valid_transaction(self): + tx = AMMVote( + account="rHb9CJAWyB4rj91VRWn96DkukG4bwdtyTh", + asset=Currency(currency="USD", issuer="rHb9CJAWyB4rj91VRWn96DkukG4bwdtyTh"), + asset2=Currency( + currency="USD", issuer="rHb9CJAWyB4rj91VRWn96DkukG4bwdtyTh" + ), + trading_fee=0, + ) + self.assertTrue(tx.is_valid()) diff --git a/xrpl/openapi-codegen/test/transactions/test_amm_withdraw.py b/xrpl/openapi-codegen/test/transactions/test_amm_withdraw.py new file mode 100644 index 000000000..52b21c729 --- /dev/null +++ b/xrpl/openapi-codegen/test/transactions/test_amm_withdraw.py @@ -0,0 +1,74 @@ +import unittest + +from xrpl.models.exceptions import XRPLModelException +from xrpl.models.transactions.amm_withdraw import AMMWithdraw +from xrpl.models.transactions.amm_withdraw import AMMWithdrawFlag +from xrpl.models.transactions.amm_withdraw import Currency + + +class TestAMMWithdraw(unittest.TestCase): + def test_tx_invalid_missing_required_param_asset(self): + with self.assertRaises(XRPLModelException) as err: + AMMWithdraw( + account="rHb9CJAWyB4rj91VRWn96DkukG4bwdtyTh", + amount="12345", + amount2="12345", + asset2=Currency( + currency="USD", issuer="rHb9CJAWyB4rj91VRWn96DkukG4bwdtyTh" + ), + e_price="12345", + flags=AMMWithdrawFlag.TF_LIMIT_LP_TOKEN, + lp_token_in="12345", + ) + self.assertIsNotNone(err.exception.args[0]) + + def test_tx_invalid_account_is_not_xrp_account(self): + with self.assertRaises(XRPLModelException) as err: + AMMWithdraw( + account="G5h7Dk92LmXqZtP3NvB8YrCfJ0W1AoUE", + amount="12345", + amount2="12345", + asset=Currency( + currency="USD", issuer="rHb9CJAWyB4rj91VRWn96DkukG4bwdtyTh" + ), + asset2=Currency( + currency="USD", issuer="rHb9CJAWyB4rj91VRWn96DkukG4bwdtyTh" + ), + e_price="12345", + flags=AMMWithdrawFlag.TF_LIMIT_LP_TOKEN, + lp_token_in="12345", + ) + self.assertIsNotNone(err.exception.args[0]) + + def test_tx_invalid_issuer_is_not_xrp_account(self): + with self.assertRaises(XRPLModelException) as err: + AMMWithdraw( + account="rHb9CJAWyB4rj91VRWn96DkukG4bwdtyTh", + amount="12345", + amount2="12345", + asset=Currency( + currency="USD", issuer="G5h7Dk92LmXqZtP3NvB8YrCfJ0W1AoUE" + ), + asset2=Currency( + currency="USD", issuer="G5h7Dk92LmXqZtP3NvB8YrCfJ0W1AoUE" + ), + e_price="12345", + flags=AMMWithdrawFlag.TF_LIMIT_LP_TOKEN, + lp_token_in="12345", + ) + self.assertIsNotNone(err.exception.args[0]) + + def test_tx_valid_transaction(self): + tx = AMMWithdraw( + account="rHb9CJAWyB4rj91VRWn96DkukG4bwdtyTh", + amount="12345", + amount2="12345", + asset=Currency(currency="USD", issuer="rHb9CJAWyB4rj91VRWn96DkukG4bwdtyTh"), + asset2=Currency( + currency="USD", issuer="rHb9CJAWyB4rj91VRWn96DkukG4bwdtyTh" + ), + e_price="12345", + flags=AMMWithdrawFlag.TF_LIMIT_LP_TOKEN, + lp_token_in="12345", + ) + self.assertTrue(tx.is_valid()) diff --git a/xrpl/openapi-codegen/test/transactions/test_check_cancel.py b/xrpl/openapi-codegen/test/transactions/test_check_cancel.py new file mode 100644 index 000000000..c9ff19691 --- /dev/null +++ b/xrpl/openapi-codegen/test/transactions/test_check_cancel.py @@ -0,0 +1,26 @@ +import unittest + +from xrpl.models.exceptions import XRPLModelException +from xrpl.models.transactions.check_cancel import CheckCancel + + +class TestCheckCancel(unittest.TestCase): + def test_tx_invalid_missing_required_param_check_id(self): + with self.assertRaises(XRPLModelException) as err: + CheckCancel(account="rHb9CJAWyB4rj91VRWn96DkukG4bwdtyTh") + self.assertIsNotNone(err.exception.args[0]) + + def test_tx_invalid_account_is_not_xrp_account(self): + with self.assertRaises(XRPLModelException) as err: + CheckCancel( + account="G5h7Dk92LmXqZtP3NvB8YrCfJ0W1AoUE", + check_id="2561865f2068c323ed13e569d12f8a77db2249d1be0dd0ed8afed6fd23f0221a", + ) + self.assertIsNotNone(err.exception.args[0]) + + def test_tx_valid_transaction(self): + tx = CheckCancel( + account="rHb9CJAWyB4rj91VRWn96DkukG4bwdtyTh", + check_id="2561865f2068c323ed13e569d12f8a77db2249d1be0dd0ed8afed6fd23f0221a", + ) + self.assertTrue(tx.is_valid()) diff --git a/xrpl/openapi-codegen/test/transactions/test_check_cash.py b/xrpl/openapi-codegen/test/transactions/test_check_cash.py new file mode 100644 index 000000000..cc8f69ba6 --- /dev/null +++ b/xrpl/openapi-codegen/test/transactions/test_check_cash.py @@ -0,0 +1,44 @@ +import unittest + +from xrpl.models.exceptions import XRPLModelException +from xrpl.models.transactions.check_cash import CheckCash + + +class TestCheckCash(unittest.TestCase): + def test_tx_invalid_missing_required_param_check_id(self): + with self.assertRaises(XRPLModelException) as err: + CheckCash( + account="rHb9CJAWyB4rj91VRWn96DkukG4bwdtyTh", + amount="12345", + deliver_min="12345", + ) + self.assertIsNotNone(err.exception.args[0]) + + def test_tx_invalid_both_amount_deliver_min_present(self): + with self.assertRaises(XRPLModelException) as err: + CheckCash( + account="rHb9CJAWyB4rj91VRWn96DkukG4bwdtyTh", + amount="12345", + check_id="2561865f2068c323ed13e569d12f8a77db2249d1be0dd0ed8afed6fd23f0221a", + deliver_min="12345", + ) + self.assertIsNotNone(err.exception.args[0]) + + def test_tx_invalid_account_is_not_xrp_account(self): + with self.assertRaises(XRPLModelException) as err: + CheckCash( + account="G5h7Dk92LmXqZtP3NvB8YrCfJ0W1AoUE", + amount="12345", + check_id="2561865f2068c323ed13e569d12f8a77db2249d1be0dd0ed8afed6fd23f0221a", + deliver_min="12345", + ) + self.assertIsNotNone(err.exception.args[0]) + + def test_tx_valid_transaction(self): + tx = CheckCash( + account="rHb9CJAWyB4rj91VRWn96DkukG4bwdtyTh", + amount="12345", + check_id="2561865f2068c323ed13e569d12f8a77db2249d1be0dd0ed8afed6fd23f0221a", + deliver_min="12345", + ) + self.assertTrue(tx.is_valid()) diff --git a/xrpl/openapi-codegen/test/transactions/test_check_create.py b/xrpl/openapi-codegen/test/transactions/test_check_create.py new file mode 100644 index 000000000..00f0efdba --- /dev/null +++ b/xrpl/openapi-codegen/test/transactions/test_check_create.py @@ -0,0 +1,40 @@ +import unittest + +from xrpl.models.exceptions import XRPLModelException +from xrpl.models.transactions.check_create import CheckCreate + + +class TestCheckCreate(unittest.TestCase): + def test_tx_invalid_missing_required_param_destination(self): + with self.assertRaises(XRPLModelException) as err: + CheckCreate( + account="rHb9CJAWyB4rj91VRWn96DkukG4bwdtyTh", + destination_tag=5, + expiration=5, + invoice_id="2561865f2068c323ed13e569d12f8a77db2249d1be0dd0ed8afed6fd23f0221a", + send_max="12345", + ) + self.assertIsNotNone(err.exception.args[0]) + + def test_tx_invalid_account_is_not_xrp_account(self): + with self.assertRaises(XRPLModelException) as err: + CheckCreate( + account="G5h7Dk92LmXqZtP3NvB8YrCfJ0W1AoUE", + destination="AAAAA", + destination_tag=5, + expiration=5, + invoice_id="2561865f2068c323ed13e569d12f8a77db2249d1be0dd0ed8afed6fd23f0221a", + send_max="12345", + ) + self.assertIsNotNone(err.exception.args[0]) + + def test_tx_valid_transaction(self): + tx = CheckCreate( + account="rHb9CJAWyB4rj91VRWn96DkukG4bwdtyTh", + destination="AAAAA", + destination_tag=5, + expiration=5, + invoice_id="2561865f2068c323ed13e569d12f8a77db2249d1be0dd0ed8afed6fd23f0221a", + send_max="12345", + ) + self.assertTrue(tx.is_valid()) diff --git a/xrpl/openapi-codegen/test/transactions/test_clawback.py b/xrpl/openapi-codegen/test/transactions/test_clawback.py new file mode 100644 index 000000000..65673e075 --- /dev/null +++ b/xrpl/openapi-codegen/test/transactions/test_clawback.py @@ -0,0 +1,63 @@ +import unittest + +from xrpl.models.amounts import IssuedCurrencyAmount +from xrpl.models.exceptions import XRPLModelException +from xrpl.models.transactions.clawback import Clawback + + +class TestClawback(unittest.TestCase): + def test_tx_invalid_missing_required_param_amount(self): + with self.assertRaises(XRPLModelException) as err: + Clawback(account="rHb9CJAWyB4rj91VRWn96DkukG4bwdtyTh", holder="AAAAA") + self.assertIsNotNone(err.exception.args[0]) + + def test_tx_invalid_value_not_numeric(self): + with self.assertRaises(XRPLModelException) as err: + Clawback( + account="rHb9CJAWyB4rj91VRWn96DkukG4bwdtyTh", + amount=IssuedCurrencyAmount( + currency="USD", + issuer="rHb9CJAWyB4rj91VRWn96DkukG4bwdtyTh", + value="AAAAA", + ), + holder="AAAAA", + ) + self.assertIsNotNone(err.exception.args[0]) + + def test_tx_invalid_account_is_not_xrp_account(self): + with self.assertRaises(XRPLModelException) as err: + Clawback( + account="G5h7Dk92LmXqZtP3NvB8YrCfJ0W1AoUE", + amount=IssuedCurrencyAmount( + currency="USD", + issuer="rHb9CJAWyB4rj91VRWn96DkukG4bwdtyTh", + value="12345", + ), + holder="AAAAA", + ) + self.assertIsNotNone(err.exception.args[0]) + + def test_tx_invalid_issuer_is_not_xrp_account(self): + with self.assertRaises(XRPLModelException) as err: + Clawback( + account="rHb9CJAWyB4rj91VRWn96DkukG4bwdtyTh", + amount=IssuedCurrencyAmount( + currency="USD", + issuer="G5h7Dk92LmXqZtP3NvB8YrCfJ0W1AoUE", + value="12345", + ), + holder="AAAAA", + ) + self.assertIsNotNone(err.exception.args[0]) + + def test_tx_valid_transaction(self): + tx = Clawback( + account="rHb9CJAWyB4rj91VRWn96DkukG4bwdtyTh", + amount=IssuedCurrencyAmount( + currency="USD", + issuer="rHb9CJAWyB4rj91VRWn96DkukG4bwdtyTh", + value="12345", + ), + holder="AAAAA", + ) + self.assertTrue(tx.is_valid()) diff --git a/xrpl/openapi-codegen/test/transactions/test_credential_accept.py b/xrpl/openapi-codegen/test/transactions/test_credential_accept.py new file mode 100644 index 000000000..843190ea6 --- /dev/null +++ b/xrpl/openapi-codegen/test/transactions/test_credential_accept.py @@ -0,0 +1,48 @@ +import unittest + +from xrpl.models.exceptions import XRPLModelException +from xrpl.models.transactions.credential_accept import CredentialAccept + + +class TestCredentialAccept(unittest.TestCase): + def test_tx_invalid_missing_required_param_credential_type(self): + with self.assertRaises(XRPLModelException) as err: + CredentialAccept( + account="rHb9CJAWyB4rj91VRWn96DkukG4bwdtyTh", issuer="AAAAA" + ) + self.assertIsNotNone(err.exception.args[0]) + + def test_tx_invalid_credential_type_too_long(self): + with self.assertRaises(XRPLModelException) as err: + CredentialAccept( + account="rHb9CJAWyB4rj91VRWn96DkukG4bwdtyTh", + credential_type="eee1865f2068c323ed13e569d12f8a77db2249d1be0dd0ed8afed6fd23f0221aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa", + issuer="AAAAA", + ) + self.assertIsNotNone(err.exception.args[0]) + + def test_tx_invalid_credential_type_too_short(self): + with self.assertRaises(XRPLModelException) as err: + CredentialAccept( + account="rHb9CJAWyB4rj91VRWn96DkukG4bwdtyTh", + credential_type="", + issuer="AAAAA", + ) + self.assertIsNotNone(err.exception.args[0]) + + def test_tx_invalid_account_is_not_xrp_account(self): + with self.assertRaises(XRPLModelException) as err: + CredentialAccept( + account="G5h7Dk92LmXqZtP3NvB8YrCfJ0W1AoUE", + credential_type="eee1865f2068c323ed13e569d12f8a77db2249d1be0dd0ed8afed6fd23f0221a", + issuer="AAAAA", + ) + self.assertIsNotNone(err.exception.args[0]) + + def test_tx_valid_transaction(self): + tx = CredentialAccept( + account="rHb9CJAWyB4rj91VRWn96DkukG4bwdtyTh", + credential_type="eee1865f2068c323ed13e569d12f8a77db2249d1be0dd0ed8afed6fd23f0221a", + issuer="AAAAA", + ) + self.assertTrue(tx.is_valid()) diff --git a/xrpl/openapi-codegen/test/transactions/test_credential_create.py b/xrpl/openapi-codegen/test/transactions/test_credential_create.py new file mode 100644 index 000000000..806852026 --- /dev/null +++ b/xrpl/openapi-codegen/test/transactions/test_credential_create.py @@ -0,0 +1,74 @@ +import unittest + +from xrpl.models.exceptions import XRPLModelException +from xrpl.models.transactions.credential_create import CredentialCreate + + +class TestCredentialCreate(unittest.TestCase): + def test_tx_invalid_missing_required_param_credential_type(self): + with self.assertRaises(XRPLModelException) as err: + CredentialCreate( + account="rHb9CJAWyB4rj91VRWn96DkukG4bwdtyTh", + subject="AAAAA", + uri="eee1865f2068c323ed13e569d12f8a77db2249d1be0dd0ed8afed6fd23f0221a", + ) + self.assertIsNotNone(err.exception.args[0]) + + def test_tx_invalid_credential_type_too_long(self): + with self.assertRaises(XRPLModelException) as err: + CredentialCreate( + account="rHb9CJAWyB4rj91VRWn96DkukG4bwdtyTh", + credential_type="eee1865f2068c323ed13e569d12f8a77db2249d1be0dd0ed8afed6fd23f0221aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa", + subject="AAAAA", + uri="eee1865f2068c323ed13e569d12f8a77db2249d1be0dd0ed8afed6fd23f0221a", + ) + self.assertIsNotNone(err.exception.args[0]) + + def test_tx_invalid_uri_too_long(self): + with self.assertRaises(XRPLModelException) as err: + CredentialCreate( + account="rHb9CJAWyB4rj91VRWn96DkukG4bwdtyTh", + credential_type="eee1865f2068c323ed13e569d12f8a77db2249d1be0dd0ed8afed6fd23f0221a", + subject="AAAAA", + uri="eee1865f2068c323ed13e569d12f8a77db2249d1be0dd0ed8afed6fd23f0221aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa", + ) + self.assertIsNotNone(err.exception.args[0]) + + def test_tx_invalid_credential_type_too_short(self): + with self.assertRaises(XRPLModelException) as err: + CredentialCreate( + account="rHb9CJAWyB4rj91VRWn96DkukG4bwdtyTh", + credential_type="", + subject="AAAAA", + uri="eee1865f2068c323ed13e569d12f8a77db2249d1be0dd0ed8afed6fd23f0221a", + ) + self.assertIsNotNone(err.exception.args[0]) + + def test_tx_invalid_uri_too_short(self): + with self.assertRaises(XRPLModelException) as err: + CredentialCreate( + account="rHb9CJAWyB4rj91VRWn96DkukG4bwdtyTh", + credential_type="eee1865f2068c323ed13e569d12f8a77db2249d1be0dd0ed8afed6fd23f0221a", + subject="AAAAA", + uri="", + ) + self.assertIsNotNone(err.exception.args[0]) + + def test_tx_invalid_account_is_not_xrp_account(self): + with self.assertRaises(XRPLModelException) as err: + CredentialCreate( + account="G5h7Dk92LmXqZtP3NvB8YrCfJ0W1AoUE", + credential_type="eee1865f2068c323ed13e569d12f8a77db2249d1be0dd0ed8afed6fd23f0221a", + subject="AAAAA", + uri="eee1865f2068c323ed13e569d12f8a77db2249d1be0dd0ed8afed6fd23f0221a", + ) + self.assertIsNotNone(err.exception.args[0]) + + def test_tx_valid_transaction(self): + tx = CredentialCreate( + account="rHb9CJAWyB4rj91VRWn96DkukG4bwdtyTh", + credential_type="eee1865f2068c323ed13e569d12f8a77db2249d1be0dd0ed8afed6fd23f0221a", + subject="AAAAA", + uri="eee1865f2068c323ed13e569d12f8a77db2249d1be0dd0ed8afed6fd23f0221a", + ) + self.assertTrue(tx.is_valid()) diff --git a/xrpl/openapi-codegen/test/transactions/test_credential_delete.py b/xrpl/openapi-codegen/test/transactions/test_credential_delete.py new file mode 100644 index 000000000..7b81c7d5e --- /dev/null +++ b/xrpl/openapi-codegen/test/transactions/test_credential_delete.py @@ -0,0 +1,62 @@ +import unittest + +from xrpl.models.exceptions import XRPLModelException +from xrpl.models.transactions.credential_delete import CredentialDelete + + +class TestCredentialDelete(unittest.TestCase): + def test_tx_invalid_missing_required_param_credential_type(self): + with self.assertRaises(XRPLModelException) as err: + CredentialDelete( + account="rHb9CJAWyB4rj91VRWn96DkukG4bwdtyTh", + issuer="AAAAA", + subject="AAAAA", + ) + self.assertIsNotNone(err.exception.args[0]) + + def test_tx_invalid_require_one_of_missing_subject_issuer(self): + with self.assertRaises(XRPLModelException) as err: + CredentialDelete( + account="rHb9CJAWyB4rj91VRWn96DkukG4bwdtyTh", + credential_type="eee1865f2068c323ed13e569d12f8a77db2249d1be0dd0ed8afed6fd23f0221a", + ) + self.assertIsNotNone(err.exception.args[0]) + + def test_tx_invalid_credential_type_too_long(self): + with self.assertRaises(XRPLModelException) as err: + CredentialDelete( + account="rHb9CJAWyB4rj91VRWn96DkukG4bwdtyTh", + credential_type="eee1865f2068c323ed13e569d12f8a77db2249d1be0dd0ed8afed6fd23f0221aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa", + issuer="AAAAA", + subject="AAAAA", + ) + self.assertIsNotNone(err.exception.args[0]) + + def test_tx_invalid_credential_type_too_short(self): + with self.assertRaises(XRPLModelException) as err: + CredentialDelete( + account="rHb9CJAWyB4rj91VRWn96DkukG4bwdtyTh", + credential_type="", + issuer="AAAAA", + subject="AAAAA", + ) + self.assertIsNotNone(err.exception.args[0]) + + def test_tx_invalid_account_is_not_xrp_account(self): + with self.assertRaises(XRPLModelException) as err: + CredentialDelete( + account="G5h7Dk92LmXqZtP3NvB8YrCfJ0W1AoUE", + credential_type="eee1865f2068c323ed13e569d12f8a77db2249d1be0dd0ed8afed6fd23f0221a", + issuer="AAAAA", + subject="AAAAA", + ) + self.assertIsNotNone(err.exception.args[0]) + + def test_tx_valid_transaction(self): + tx = CredentialDelete( + account="rHb9CJAWyB4rj91VRWn96DkukG4bwdtyTh", + credential_type="eee1865f2068c323ed13e569d12f8a77db2249d1be0dd0ed8afed6fd23f0221a", + issuer="AAAAA", + subject="AAAAA", + ) + self.assertTrue(tx.is_valid()) diff --git a/xrpl/openapi-codegen/test/transactions/test_deposit_preauth.py b/xrpl/openapi-codegen/test/transactions/test_deposit_preauth.py new file mode 100644 index 000000000..77ac3d497 --- /dev/null +++ b/xrpl/openapi-codegen/test/transactions/test_deposit_preauth.py @@ -0,0 +1,41 @@ +import unittest + +from xrpl.models.exceptions import XRPLModelException +from xrpl.models.transactions.deposit_preauth import Credential +from xrpl.models.transactions.deposit_preauth import DepositPreauth + + +class TestDepositPreauth(unittest.TestCase): + def test_tx_invalid_missing_required_param_account(self): + with self.assertRaises(XRPLModelException) as err: + DepositPreauth(authorize="AAAAA") + self.assertIsNotNone(err.exception.args[0]) + + def test_tx_invalid_require_exactly_one_authorize_authorize_credentials_unauthorize_unauthorize_credentials( + self, + ): + with self.assertRaises(XRPLModelException) as err: + DepositPreauth( + account="rHb9CJAWyB4rj91VRWn96DkukG4bwdtyTh", + authorize="AAAAA", + authorize_credentials=[ + Credential( + credential_type="eee1865f2068c323ed13e569d12f8a77db2249d1be0dd0ed8afed6fd23f0221a", + issuer="AAAAA", + ) + ], + ) + self.assertIsNotNone(err.exception.args[0]) + + def test_tx_invalid_account_is_not_xrp_account(self): + with self.assertRaises(XRPLModelException) as err: + DepositPreauth( + account="G5h7Dk92LmXqZtP3NvB8YrCfJ0W1AoUE", authorize="AAAAA" + ) + self.assertIsNotNone(err.exception.args[0]) + + def test_tx_valid_transaction(self): + tx = DepositPreauth( + account="rHb9CJAWyB4rj91VRWn96DkukG4bwdtyTh", authorize="AAAAA" + ) + self.assertTrue(tx.is_valid()) diff --git a/xrpl/openapi-codegen/test/transactions/test_did_delete.py b/xrpl/openapi-codegen/test/transactions/test_did_delete.py new file mode 100644 index 000000000..58d5b75f9 --- /dev/null +++ b/xrpl/openapi-codegen/test/transactions/test_did_delete.py @@ -0,0 +1,20 @@ +import unittest + +from xrpl.models.exceptions import XRPLModelException +from xrpl.models.transactions.did_delete import DIDDelete + + +class TestDIDDelete(unittest.TestCase): + def test_tx_invalid_missing_required_param_account(self): + with self.assertRaises(XRPLModelException) as err: + DIDDelete() + self.assertIsNotNone(err.exception.args[0]) + + def test_tx_invalid_account_is_not_xrp_account(self): + with self.assertRaises(XRPLModelException) as err: + DIDDelete(account="G5h7Dk92LmXqZtP3NvB8YrCfJ0W1AoUE") + self.assertIsNotNone(err.exception.args[0]) + + def test_tx_valid_transaction(self): + tx = DIDDelete(account="rHb9CJAWyB4rj91VRWn96DkukG4bwdtyTh") + self.assertTrue(tx.is_valid()) diff --git a/xrpl/openapi-codegen/test/transactions/test_did_set.py b/xrpl/openapi-codegen/test/transactions/test_did_set.py new file mode 100644 index 000000000..8b04cffea --- /dev/null +++ b/xrpl/openapi-codegen/test/transactions/test_did_set.py @@ -0,0 +1,69 @@ +import unittest + +from xrpl.models.exceptions import XRPLModelException +from xrpl.models.transactions.did_set import DIDSet + + +class TestDIDSet(unittest.TestCase): + def test_tx_invalid_missing_required_param_account(self): + with self.assertRaises(XRPLModelException) as err: + DIDSet( + data="eee1865f2068c323ed13e569d12f8a77db2249d1be0dd0ed8afed6fd23f0221a", + did_document="eee1865f2068c323ed13e569d12f8a77db2249d1be0dd0ed8afed6fd23f0221a", + uri="eee1865f2068c323ed13e569d12f8a77db2249d1be0dd0ed8afed6fd23f0221a", + ) + self.assertIsNotNone(err.exception.args[0]) + + def test_tx_invalid_require_one_of_missing_data_did_document_uri(self): + with self.assertRaises(XRPLModelException) as err: + DIDSet(account="rHb9CJAWyB4rj91VRWn96DkukG4bwdtyTh") + self.assertIsNotNone(err.exception.args[0]) + + def test_tx_invalid_did_document_too_long(self): + with self.assertRaises(XRPLModelException) as err: + DIDSet( + account="rHb9CJAWyB4rj91VRWn96DkukG4bwdtyTh", + data="eee1865f2068c323ed13e569d12f8a77db2249d1be0dd0ed8afed6fd23f0221a", + did_document="eee1865f2068c323ed13e569d12f8a77db2249d1be0dd0ed8afed6fd23f0221aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa", + uri="eee1865f2068c323ed13e569d12f8a77db2249d1be0dd0ed8afed6fd23f0221a", + ) + self.assertIsNotNone(err.exception.args[0]) + + def test_tx_invalid_data_too_long(self): + with self.assertRaises(XRPLModelException) as err: + DIDSet( + account="rHb9CJAWyB4rj91VRWn96DkukG4bwdtyTh", + data="eee1865f2068c323ed13e569d12f8a77db2249d1be0dd0ed8afed6fd23f0221aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa", + did_document="eee1865f2068c323ed13e569d12f8a77db2249d1be0dd0ed8afed6fd23f0221a", + uri="eee1865f2068c323ed13e569d12f8a77db2249d1be0dd0ed8afed6fd23f0221a", + ) + self.assertIsNotNone(err.exception.args[0]) + + def test_tx_invalid_uri_too_long(self): + with self.assertRaises(XRPLModelException) as err: + DIDSet( + account="rHb9CJAWyB4rj91VRWn96DkukG4bwdtyTh", + data="eee1865f2068c323ed13e569d12f8a77db2249d1be0dd0ed8afed6fd23f0221a", + did_document="eee1865f2068c323ed13e569d12f8a77db2249d1be0dd0ed8afed6fd23f0221a", + uri="eee1865f2068c323ed13e569d12f8a77db2249d1be0dd0ed8afed6fd23f0221aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa", + ) + self.assertIsNotNone(err.exception.args[0]) + + def test_tx_invalid_account_is_not_xrp_account(self): + with self.assertRaises(XRPLModelException) as err: + DIDSet( + account="G5h7Dk92LmXqZtP3NvB8YrCfJ0W1AoUE", + data="eee1865f2068c323ed13e569d12f8a77db2249d1be0dd0ed8afed6fd23f0221a", + did_document="eee1865f2068c323ed13e569d12f8a77db2249d1be0dd0ed8afed6fd23f0221a", + uri="eee1865f2068c323ed13e569d12f8a77db2249d1be0dd0ed8afed6fd23f0221a", + ) + self.assertIsNotNone(err.exception.args[0]) + + def test_tx_valid_transaction(self): + tx = DIDSet( + account="rHb9CJAWyB4rj91VRWn96DkukG4bwdtyTh", + data="eee1865f2068c323ed13e569d12f8a77db2249d1be0dd0ed8afed6fd23f0221a", + did_document="eee1865f2068c323ed13e569d12f8a77db2249d1be0dd0ed8afed6fd23f0221a", + uri="eee1865f2068c323ed13e569d12f8a77db2249d1be0dd0ed8afed6fd23f0221a", + ) + self.assertTrue(tx.is_valid()) diff --git a/xrpl/openapi-codegen/test/transactions/test_escrow_cancel.py b/xrpl/openapi-codegen/test/transactions/test_escrow_cancel.py new file mode 100644 index 000000000..6fa1026ac --- /dev/null +++ b/xrpl/openapi-codegen/test/transactions/test_escrow_cancel.py @@ -0,0 +1,28 @@ +import unittest + +from xrpl.models.exceptions import XRPLModelException +from xrpl.models.transactions.escrow_cancel import EscrowCancel + + +class TestEscrowCancel(unittest.TestCase): + def test_tx_invalid_missing_required_param_owner(self): + with self.assertRaises(XRPLModelException) as err: + EscrowCancel(account="rHb9CJAWyB4rj91VRWn96DkukG4bwdtyTh", offer_sequence=5) + self.assertIsNotNone(err.exception.args[0]) + + def test_tx_invalid_account_is_not_xrp_account(self): + with self.assertRaises(XRPLModelException) as err: + EscrowCancel( + account="G5h7Dk92LmXqZtP3NvB8YrCfJ0W1AoUE", + offer_sequence=5, + owner="AAAAA", + ) + self.assertIsNotNone(err.exception.args[0]) + + def test_tx_valid_transaction(self): + tx = EscrowCancel( + account="rHb9CJAWyB4rj91VRWn96DkukG4bwdtyTh", + offer_sequence=5, + owner="AAAAA", + ) + self.assertTrue(tx.is_valid()) diff --git a/xrpl/openapi-codegen/test/transactions/test_escrow_create.py b/xrpl/openapi-codegen/test/transactions/test_escrow_create.py new file mode 100644 index 000000000..25fa6fa34 --- /dev/null +++ b/xrpl/openapi-codegen/test/transactions/test_escrow_create.py @@ -0,0 +1,56 @@ +import unittest + +from xrpl.models.exceptions import XRPLModelException +from xrpl.models.transactions.escrow_create import EscrowCreate + + +class TestEscrowCreate(unittest.TestCase): + def test_tx_invalid_missing_required_param_amount(self): + with self.assertRaises(XRPLModelException) as err: + EscrowCreate( + account="rHb9CJAWyB4rj91VRWn96DkukG4bwdtyTh", + cancel_after=5, + condition="AAAAA", + destination="AAAAA", + destination_tag=5, + finish_after=5, + ) + self.assertIsNotNone(err.exception.args[0]) + + def test_tx_invalid_finish_after_larger_than_cancel_after(self): + with self.assertRaises(XRPLModelException) as err: + EscrowCreate( + account="rHb9CJAWyB4rj91VRWn96DkukG4bwdtyTh", + amount="AAAAA", + cancel_after=5, + condition="AAAAA", + destination="AAAAA", + destination_tag=5, + finish_after=6, + ) + self.assertIsNotNone(err.exception.args[0]) + + def test_tx_invalid_account_is_not_xrp_account(self): + with self.assertRaises(XRPLModelException) as err: + EscrowCreate( + account="G5h7Dk92LmXqZtP3NvB8YrCfJ0W1AoUE", + amount="AAAAA", + cancel_after=5, + condition="AAAAA", + destination="AAAAA", + destination_tag=5, + finish_after=5, + ) + self.assertIsNotNone(err.exception.args[0]) + + def test_tx_valid_transaction(self): + tx = EscrowCreate( + account="rHb9CJAWyB4rj91VRWn96DkukG4bwdtyTh", + amount="AAAAA", + cancel_after=5, + condition="AAAAA", + destination="AAAAA", + destination_tag=5, + finish_after=5, + ) + self.assertTrue(tx.is_valid()) diff --git a/xrpl/openapi-codegen/test/transactions/test_escrow_finish.py b/xrpl/openapi-codegen/test/transactions/test_escrow_finish.py new file mode 100644 index 000000000..c50c5d259 --- /dev/null +++ b/xrpl/openapi-codegen/test/transactions/test_escrow_finish.py @@ -0,0 +1,85 @@ +import unittest + +from xrpl.models.exceptions import XRPLModelException +from xrpl.models.transactions.escrow_finish import EscrowFinish + + +class TestEscrowFinish(unittest.TestCase): + def test_tx_invalid_missing_required_param_owner(self): + with self.assertRaises(XRPLModelException) as err: + EscrowFinish( + account="rHb9CJAWyB4rj91VRWn96DkukG4bwdtyTh", + condition="AAAAA", + credential_ids=["AAAAA"], + fulfillment="AAAAA", + offer_sequence=5, + ) + self.assertIsNotNone(err.exception.args[0]) + + def test_tx_invalid_mutual_presence_missing_condition(self): + with self.assertRaises(XRPLModelException) as err: + EscrowFinish( + account="rHb9CJAWyB4rj91VRWn96DkukG4bwdtyTh", + credential_ids=["AAAAA"], + fulfillment="AAAAA", + offer_sequence=5, + owner="AAAAA", + ) + self.assertIsNotNone(err.exception.args[0]) + + def test_tx_invalid_credential_ids_less_than_min_items(self): + with self.assertRaises(XRPLModelException) as err: + EscrowFinish( + account="rHb9CJAWyB4rj91VRWn96DkukG4bwdtyTh", + condition="AAAAA", + credential_ids=[], + fulfillment="AAAAA", + offer_sequence=5, + owner="AAAAA", + ) + self.assertIsNotNone(err.exception.args[0]) + + def test_tx_invalid_credential_ids_more_than_max_items(self): + with self.assertRaises(XRPLModelException) as err: + EscrowFinish( + account="rHb9CJAWyB4rj91VRWn96DkukG4bwdtyTh", + condition="AAAAA", + credential_ids=[ + "AAAAA", + "BBBBB", + "CCCCC", + "DDDDD", + "EEEEE", + "FFFFF", + "GGGGG", + "HHHHH", + "IIIII", + ], + fulfillment="AAAAA", + offer_sequence=5, + owner="AAAAA", + ) + self.assertIsNotNone(err.exception.args[0]) + + def test_tx_invalid_account_is_not_xrp_account(self): + with self.assertRaises(XRPLModelException) as err: + EscrowFinish( + account="G5h7Dk92LmXqZtP3NvB8YrCfJ0W1AoUE", + condition="AAAAA", + credential_ids=["AAAAA"], + fulfillment="AAAAA", + offer_sequence=5, + owner="AAAAA", + ) + self.assertIsNotNone(err.exception.args[0]) + + def test_tx_valid_transaction(self): + tx = EscrowFinish( + account="rHb9CJAWyB4rj91VRWn96DkukG4bwdtyTh", + condition="AAAAA", + credential_ids=["AAAAA"], + fulfillment="AAAAA", + offer_sequence=5, + owner="AAAAA", + ) + self.assertTrue(tx.is_valid()) diff --git a/xrpl/openapi-codegen/test/transactions/test_mptoken_authorize.py b/xrpl/openapi-codegen/test/transactions/test_mptoken_authorize.py new file mode 100644 index 000000000..35a74253f --- /dev/null +++ b/xrpl/openapi-codegen/test/transactions/test_mptoken_authorize.py @@ -0,0 +1,35 @@ +import unittest + +from xrpl.models.exceptions import XRPLModelException +from xrpl.models.transactions.mptoken_authorize import MPTokenAuthorize +from xrpl.models.transactions.mptoken_authorize import MPTokenAuthorizeFlag + + +class TestMPTokenAuthorize(unittest.TestCase): + def test_tx_invalid_missing_required_param_mptoken_issuance_id(self): + with self.assertRaises(XRPLModelException) as err: + MPTokenAuthorize( + account="rHb9CJAWyB4rj91VRWn96DkukG4bwdtyTh", + flags=MPTokenAuthorizeFlag.TF_MPT_UNAUTHORIZE, + holder="AAAAA", + ) + self.assertIsNotNone(err.exception.args[0]) + + def test_tx_invalid_account_is_not_xrp_account(self): + with self.assertRaises(XRPLModelException) as err: + MPTokenAuthorize( + account="G5h7Dk92LmXqZtP3NvB8YrCfJ0W1AoUE", + flags=MPTokenAuthorizeFlag.TF_MPT_UNAUTHORIZE, + holder="AAAAA", + mptoken_issuance_id="UNHANDLED_CASE", + ) + self.assertIsNotNone(err.exception.args[0]) + + def test_tx_valid_transaction(self): + tx = MPTokenAuthorize( + account="rHb9CJAWyB4rj91VRWn96DkukG4bwdtyTh", + flags=MPTokenAuthorizeFlag.TF_MPT_UNAUTHORIZE, + holder="AAAAA", + mptoken_issuance_id="UNHANDLED_CASE", + ) + self.assertTrue(tx.is_valid()) diff --git a/xrpl/openapi-codegen/test/transactions/test_mptoken_issuance_create.py b/xrpl/openapi-codegen/test/transactions/test_mptoken_issuance_create.py new file mode 100644 index 000000000..12413e933 --- /dev/null +++ b/xrpl/openapi-codegen/test/transactions/test_mptoken_issuance_create.py @@ -0,0 +1,61 @@ +import unittest + +from xrpl.models.exceptions import XRPLModelException +from xrpl.models.transactions.mptoken_issuance_create import MPTokenIssuanceCreate +from xrpl.models.transactions.mptoken_issuance_create import MPTokenIssuanceCreateFlag + + +class TestMPTokenIssuanceCreate(unittest.TestCase): + def test_tx_invalid_missing_required_param_account(self): + with self.assertRaises(XRPLModelException) as err: + MPTokenIssuanceCreate( + asset_scale=5, + flags=MPTokenIssuanceCreateFlag.TF_MPT_CAN_CLAWBACK, + maximum_amount="AAAAA", + mptoken_metadata="eee1865f2068c323ed13e569d12f8a77db2249d1be0dd0ed8afed6fd23f0221a", + ) + self.assertIsNotNone(err.exception.args[0]) + + def test_tx_invalid_mptoken_metadata_too_short(self): + with self.assertRaises(XRPLModelException) as err: + MPTokenIssuanceCreate( + account="rHb9CJAWyB4rj91VRWn96DkukG4bwdtyTh", + asset_scale=5, + flags=MPTokenIssuanceCreateFlag.TF_MPT_CAN_CLAWBACK, + maximum_amount="AAAAA", + mptoken_metadata="", + ) + self.assertIsNotNone(err.exception.args[0]) + + def test_tx_invalid_present_transfer_fee_on_missing_tf_mpt_can_transfer(self): + with self.assertRaises(XRPLModelException) as err: + MPTokenIssuanceCreate( + account="rHb9CJAWyB4rj91VRWn96DkukG4bwdtyTh", + asset_scale=5, + flags=MPTokenIssuanceCreateFlag.TF_MPT_CAN_CLAWBACK, + maximum_amount="AAAAA", + mptoken_metadata="eee1865f2068c323ed13e569d12f8a77db2249d1be0dd0ed8afed6fd23f0221a", + transfer_fee=0, + ) + self.assertIsNotNone(err.exception.args[0]) + + def test_tx_invalid_account_is_not_xrp_account(self): + with self.assertRaises(XRPLModelException) as err: + MPTokenIssuanceCreate( + account="G5h7Dk92LmXqZtP3NvB8YrCfJ0W1AoUE", + asset_scale=5, + flags=MPTokenIssuanceCreateFlag.TF_MPT_CAN_CLAWBACK, + maximum_amount="AAAAA", + mptoken_metadata="eee1865f2068c323ed13e569d12f8a77db2249d1be0dd0ed8afed6fd23f0221a", + ) + self.assertIsNotNone(err.exception.args[0]) + + def test_tx_valid_transaction(self): + tx = MPTokenIssuanceCreate( + account="rHb9CJAWyB4rj91VRWn96DkukG4bwdtyTh", + asset_scale=5, + flags=MPTokenIssuanceCreateFlag.TF_MPT_CAN_CLAWBACK, + maximum_amount="AAAAA", + mptoken_metadata="eee1865f2068c323ed13e569d12f8a77db2249d1be0dd0ed8afed6fd23f0221a", + ) + self.assertTrue(tx.is_valid()) diff --git a/xrpl/openapi-codegen/test/transactions/test_mptoken_issuance_destroy.py b/xrpl/openapi-codegen/test/transactions/test_mptoken_issuance_destroy.py new file mode 100644 index 000000000..fa73fd426 --- /dev/null +++ b/xrpl/openapi-codegen/test/transactions/test_mptoken_issuance_destroy.py @@ -0,0 +1,26 @@ +import unittest + +from xrpl.models.exceptions import XRPLModelException +from xrpl.models.transactions.mptoken_issuance_destroy import MPTokenIssuanceDestroy + + +class TestMPTokenIssuanceDestroy(unittest.TestCase): + def test_tx_invalid_missing_required_param_mptoken_issuance_id(self): + with self.assertRaises(XRPLModelException) as err: + MPTokenIssuanceDestroy(account="rHb9CJAWyB4rj91VRWn96DkukG4bwdtyTh") + self.assertIsNotNone(err.exception.args[0]) + + def test_tx_invalid_account_is_not_xrp_account(self): + with self.assertRaises(XRPLModelException) as err: + MPTokenIssuanceDestroy( + account="G5h7Dk92LmXqZtP3NvB8YrCfJ0W1AoUE", + mptoken_issuance_id="UNHANDLED_CASE", + ) + self.assertIsNotNone(err.exception.args[0]) + + def test_tx_valid_transaction(self): + tx = MPTokenIssuanceDestroy( + account="rHb9CJAWyB4rj91VRWn96DkukG4bwdtyTh", + mptoken_issuance_id="UNHANDLED_CASE", + ) + self.assertTrue(tx.is_valid()) diff --git a/xrpl/openapi-codegen/test/transactions/test_mptoken_issuance_set.py b/xrpl/openapi-codegen/test/transactions/test_mptoken_issuance_set.py new file mode 100644 index 000000000..5b82b59f8 --- /dev/null +++ b/xrpl/openapi-codegen/test/transactions/test_mptoken_issuance_set.py @@ -0,0 +1,35 @@ +import unittest + +from xrpl.models.exceptions import XRPLModelException +from xrpl.models.transactions.mptoken_issuance_set import MPTokenIssuanceSet +from xrpl.models.transactions.mptoken_issuance_set import MPTokenIssuanceSetFlag + + +class TestMPTokenIssuanceSet(unittest.TestCase): + def test_tx_invalid_missing_required_param_mptoken_issuance_id(self): + with self.assertRaises(XRPLModelException) as err: + MPTokenIssuanceSet( + account="rHb9CJAWyB4rj91VRWn96DkukG4bwdtyTh", + flags=MPTokenIssuanceSetFlag.TF_MPT_LOCK, + holder="AAAAA", + ) + self.assertIsNotNone(err.exception.args[0]) + + def test_tx_invalid_account_is_not_xrp_account(self): + with self.assertRaises(XRPLModelException) as err: + MPTokenIssuanceSet( + account="G5h7Dk92LmXqZtP3NvB8YrCfJ0W1AoUE", + flags=MPTokenIssuanceSetFlag.TF_MPT_LOCK, + holder="AAAAA", + mptoken_issuance_id="AAAAA", + ) + self.assertIsNotNone(err.exception.args[0]) + + def test_tx_valid_transaction(self): + tx = MPTokenIssuanceSet( + account="rHb9CJAWyB4rj91VRWn96DkukG4bwdtyTh", + flags=MPTokenIssuanceSetFlag.TF_MPT_LOCK, + holder="AAAAA", + mptoken_issuance_id="AAAAA", + ) + self.assertTrue(tx.is_valid()) diff --git a/xrpl/openapi-codegen/test/transactions/test_nftoken_accept_offer.py b/xrpl/openapi-codegen/test/transactions/test_nftoken_accept_offer.py new file mode 100644 index 000000000..3b438700b --- /dev/null +++ b/xrpl/openapi-codegen/test/transactions/test_nftoken_accept_offer.py @@ -0,0 +1,62 @@ +import unittest + +from xrpl.models.exceptions import XRPLModelException +from xrpl.models.transactions.nftoken_accept_offer import NFTokenAcceptOffer + + +class TestNFTokenAcceptOffer(unittest.TestCase): + def test_tx_invalid_missing_required_param_account(self): + with self.assertRaises(XRPLModelException) as err: + NFTokenAcceptOffer( + nftoken_broker_fee="12345", + nftoken_buy_offer="AAAAA", + nftoken_sell_offer="AAAAA", + ) + self.assertIsNotNone(err.exception.args[0]) + + def test_tx_invalid_dependent_presence_missing_nftoken_buy_offer(self): + with self.assertRaises(XRPLModelException) as err: + NFTokenAcceptOffer( + account="rHb9CJAWyB4rj91VRWn96DkukG4bwdtyTh", + nftoken_broker_fee="12345", + nftoken_sell_offer="AAAAA", + ) + self.assertIsNotNone(err.exception.args[0]) + + def test_tx_invalid_require_one_of_missing_nftoken_sell_offer_nftoken_buy_offer( + self, + ): + with self.assertRaises(XRPLModelException) as err: + NFTokenAcceptOffer( + account="rHb9CJAWyB4rj91VRWn96DkukG4bwdtyTh", nftoken_broker_fee="12345" + ) + self.assertIsNotNone(err.exception.args[0]) + + def test_tx_invalid_nftoken_broker_fee_not_greater_than_0(self): + with self.assertRaises(XRPLModelException) as err: + NFTokenAcceptOffer( + account="rHb9CJAWyB4rj91VRWn96DkukG4bwdtyTh", + nftoken_broker_fee="0", + nftoken_buy_offer="AAAAA", + nftoken_sell_offer="AAAAA", + ) + self.assertIsNotNone(err.exception.args[0]) + + def test_tx_invalid_account_is_not_xrp_account(self): + with self.assertRaises(XRPLModelException) as err: + NFTokenAcceptOffer( + account="G5h7Dk92LmXqZtP3NvB8YrCfJ0W1AoUE", + nftoken_broker_fee="12345", + nftoken_buy_offer="AAAAA", + nftoken_sell_offer="AAAAA", + ) + self.assertIsNotNone(err.exception.args[0]) + + def test_tx_valid_transaction(self): + tx = NFTokenAcceptOffer( + account="rHb9CJAWyB4rj91VRWn96DkukG4bwdtyTh", + nftoken_broker_fee="12345", + nftoken_buy_offer="AAAAA", + nftoken_sell_offer="AAAAA", + ) + self.assertTrue(tx.is_valid()) diff --git a/xrpl/openapi-codegen/test/transactions/test_nftoken_burn.py b/xrpl/openapi-codegen/test/transactions/test_nftoken_burn.py new file mode 100644 index 000000000..21e4de870 --- /dev/null +++ b/xrpl/openapi-codegen/test/transactions/test_nftoken_burn.py @@ -0,0 +1,28 @@ +import unittest + +from xrpl.models.exceptions import XRPLModelException +from xrpl.models.transactions.nftoken_burn import NFTokenBurn + + +class TestNFTokenBurn(unittest.TestCase): + def test_tx_invalid_missing_required_param_nftoken_id(self): + with self.assertRaises(XRPLModelException) as err: + NFTokenBurn(account="rHb9CJAWyB4rj91VRWn96DkukG4bwdtyTh", owner="AAAAA") + self.assertIsNotNone(err.exception.args[0]) + + def test_tx_invalid_account_is_not_xrp_account(self): + with self.assertRaises(XRPLModelException) as err: + NFTokenBurn( + account="G5h7Dk92LmXqZtP3NvB8YrCfJ0W1AoUE", + nftoken_id="AAAAA", + owner="AAAAA", + ) + self.assertIsNotNone(err.exception.args[0]) + + def test_tx_valid_transaction(self): + tx = NFTokenBurn( + account="rHb9CJAWyB4rj91VRWn96DkukG4bwdtyTh", + nftoken_id="AAAAA", + owner="AAAAA", + ) + self.assertTrue(tx.is_valid()) diff --git a/xrpl/openapi-codegen/test/transactions/test_nftoken_cancel_offer.py b/xrpl/openapi-codegen/test/transactions/test_nftoken_cancel_offer.py new file mode 100644 index 000000000..decbff3fd --- /dev/null +++ b/xrpl/openapi-codegen/test/transactions/test_nftoken_cancel_offer.py @@ -0,0 +1,31 @@ +import unittest + +from xrpl.models.exceptions import XRPLModelException +from xrpl.models.transactions.nftoken_cancel_offer import NFTokenCancelOffer + + +class TestNFTokenCancelOffer(unittest.TestCase): + def test_tx_invalid_missing_required_param_nftoken_offers(self): + with self.assertRaises(XRPLModelException) as err: + NFTokenCancelOffer(account="rHb9CJAWyB4rj91VRWn96DkukG4bwdtyTh") + self.assertIsNotNone(err.exception.args[0]) + + def test_tx_invalid_nftoken_offers_less_than_min_items(self): + with self.assertRaises(XRPLModelException) as err: + NFTokenCancelOffer( + account="rHb9CJAWyB4rj91VRWn96DkukG4bwdtyTh", nftoken_offers=[] + ) + self.assertIsNotNone(err.exception.args[0]) + + def test_tx_invalid_account_is_not_xrp_account(self): + with self.assertRaises(XRPLModelException) as err: + NFTokenCancelOffer( + account="G5h7Dk92LmXqZtP3NvB8YrCfJ0W1AoUE", nftoken_offers=["AAAAA"] + ) + self.assertIsNotNone(err.exception.args[0]) + + def test_tx_valid_transaction(self): + tx = NFTokenCancelOffer( + account="rHb9CJAWyB4rj91VRWn96DkukG4bwdtyTh", nftoken_offers=["AAAAA"] + ) + self.assertTrue(tx.is_valid()) diff --git a/xrpl/openapi-codegen/test/transactions/test_nftoken_create_offer.py b/xrpl/openapi-codegen/test/transactions/test_nftoken_create_offer.py new file mode 100644 index 000000000..89cc2ad07 --- /dev/null +++ b/xrpl/openapi-codegen/test/transactions/test_nftoken_create_offer.py @@ -0,0 +1,66 @@ +import unittest + +from xrpl.models.exceptions import XRPLModelException +from xrpl.models.transactions.nftoken_create_offer import NFTokenCreateOffer +from xrpl.models.transactions.nftoken_create_offer import NFTokenCreateOfferFlag + + +class TestNFTokenCreateOffer(unittest.TestCase): + def test_tx_invalid_missing_required_param_nftoken_id(self): + with self.assertRaises(XRPLModelException) as err: + NFTokenCreateOffer( + account="rJ73aumLPTQQmy5wnGhvrogqf5DDhjuzc9", + amount="12345", + destination="AAAAA", + expiration=5, + flags=NFTokenCreateOfferFlag.TF_SELL_NFTOKEN, + ) + self.assertIsNotNone(err.exception.args[0]) + + def test_tx_invalid_duplicate_destination_and_account(self): + with self.assertRaises(XRPLModelException) as err: + NFTokenCreateOffer( + account="rJ73aumLPTQQmy5wnGhvrogqf5DDhjuzc9", + amount="12345", + destination="rJ73aumLPTQQmy5wnGhvrogqf5DDhjuzc9", + expiration=5, + flags=NFTokenCreateOfferFlag.TF_SELL_NFTOKEN, + nftoken_id="AAAAA", + ) + self.assertIsNotNone(err.exception.args[0]) + + def test_tx_invalid_present_owner_on_present_tf_sell_nftoken(self): + with self.assertRaises(XRPLModelException) as err: + NFTokenCreateOffer( + account="rJ73aumLPTQQmy5wnGhvrogqf5DDhjuzc9", + amount="12345", + destination="AAAAA", + expiration=5, + flags=NFTokenCreateOfferFlag.TF_SELL_NFTOKEN, + nftoken_id="AAAAA", + owner="AAAAA", + ) + self.assertIsNotNone(err.exception.args[0]) + + def test_tx_invalid_account_is_not_xrp_account(self): + with self.assertRaises(XRPLModelException) as err: + NFTokenCreateOffer( + account="G5h7Dk92LmXqZtP3NvB8YrCfJ0W1AoUE", + amount="12345", + destination="AAAAA", + expiration=5, + flags=NFTokenCreateOfferFlag.TF_SELL_NFTOKEN, + nftoken_id="AAAAA", + ) + self.assertIsNotNone(err.exception.args[0]) + + def test_tx_valid_transaction(self): + tx = NFTokenCreateOffer( + account="rJ73aumLPTQQmy5wnGhvrogqf5DDhjuzc9", + amount="12345", + destination="AAAAA", + expiration=5, + flags=NFTokenCreateOfferFlag.TF_SELL_NFTOKEN, + nftoken_id="AAAAA", + ) + self.assertTrue(tx.is_valid()) diff --git a/xrpl/openapi-codegen/test/transactions/test_nftoken_mint.py b/xrpl/openapi-codegen/test/transactions/test_nftoken_mint.py new file mode 100644 index 000000000..2fdefd488 --- /dev/null +++ b/xrpl/openapi-codegen/test/transactions/test_nftoken_mint.py @@ -0,0 +1,95 @@ +import unittest + +from xrpl.models.exceptions import XRPLModelException +from xrpl.models.transactions.nftoken_mint import NFTokenMint +from xrpl.models.transactions.nftoken_mint import NFTokenMintFlag + + +class TestNFTokenMint(unittest.TestCase): + def test_tx_invalid_transfer_fee_greater_than_max(self): + with self.assertRaises(XRPLModelException) as err: + NFTokenMint( + account="rJ73aumLPTQQmy5wnGhvrogqf5DDhjuzc9", + amount="12345", + destination="AAAAA", + expiration=5, + flags=NFTokenMintFlag.TF_BURNABLE, + issuer="AAAAA", + nftoken_taxon=5, + transfer_fee=50001, + uri="AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA", + ) + self.assertIsNotNone(err.exception.args[0]) + + def test_tx_invalid_missing_required_param_nftoken_taxon(self): + with self.assertRaises(XRPLModelException) as err: + NFTokenMint( + account="rJ73aumLPTQQmy5wnGhvrogqf5DDhjuzc9", + amount="12345", + destination="AAAAA", + expiration=5, + flags=NFTokenMintFlag.TF_BURNABLE, + issuer="AAAAA", + transfer_fee=50000, + uri="AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA", + ) + self.assertIsNotNone(err.exception.args[0]) + + def test_tx_invalid_duplicate_issuer_and_account(self): + with self.assertRaises(XRPLModelException) as err: + NFTokenMint( + account="rJ73aumLPTQQmy5wnGhvrogqf5DDhjuzc9", + amount="12345", + destination="AAAAA", + expiration=5, + flags=NFTokenMintFlag.TF_BURNABLE, + issuer="rJ73aumLPTQQmy5wnGhvrogqf5DDhjuzc9", + nftoken_taxon=5, + transfer_fee=50000, + uri="AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA", + ) + self.assertIsNotNone(err.exception.args[0]) + + def test_tx_invalid_uri_too_long(self): + with self.assertRaises(XRPLModelException) as err: + NFTokenMint( + account="rJ73aumLPTQQmy5wnGhvrogqf5DDhjuzc9", + amount="12345", + destination="AAAAA", + expiration=5, + flags=NFTokenMintFlag.TF_BURNABLE, + issuer="AAAAA", + nftoken_taxon=5, + transfer_fee=50000, + uri="AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA", + ) + self.assertIsNotNone(err.exception.args[0]) + + def test_tx_invalid_account_is_not_xrp_account(self): + with self.assertRaises(XRPLModelException) as err: + NFTokenMint( + account="G5h7Dk92LmXqZtP3NvB8YrCfJ0W1AoUE", + amount="12345", + destination="AAAAA", + expiration=5, + flags=NFTokenMintFlag.TF_BURNABLE, + issuer="AAAAA", + nftoken_taxon=5, + transfer_fee=50000, + uri="AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA", + ) + self.assertIsNotNone(err.exception.args[0]) + + def test_tx_valid_transaction(self): + tx = NFTokenMint( + account="rJ73aumLPTQQmy5wnGhvrogqf5DDhjuzc9", + amount="12345", + destination="AAAAA", + expiration=5, + flags=NFTokenMintFlag.TF_BURNABLE, + issuer="AAAAA", + nftoken_taxon=5, + transfer_fee=50000, + uri="AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA", + ) + self.assertTrue(tx.is_valid()) diff --git a/xrpl/openapi-codegen/test/transactions/test_offer_cancel.py b/xrpl/openapi-codegen/test/transactions/test_offer_cancel.py new file mode 100644 index 000000000..ce2906386 --- /dev/null +++ b/xrpl/openapi-codegen/test/transactions/test_offer_cancel.py @@ -0,0 +1,20 @@ +import unittest + +from xrpl.models.exceptions import XRPLModelException +from xrpl.models.transactions.offer_cancel import OfferCancel + + +class TestOfferCancel(unittest.TestCase): + def test_tx_invalid_missing_required_param_offer_sequence(self): + with self.assertRaises(XRPLModelException) as err: + OfferCancel(account="rHb9CJAWyB4rj91VRWn96DkukG4bwdtyTh") + self.assertIsNotNone(err.exception.args[0]) + + def test_tx_invalid_account_is_not_xrp_account(self): + with self.assertRaises(XRPLModelException) as err: + OfferCancel(account="G5h7Dk92LmXqZtP3NvB8YrCfJ0W1AoUE", offer_sequence=5) + self.assertIsNotNone(err.exception.args[0]) + + def test_tx_valid_transaction(self): + tx = OfferCancel(account="rHb9CJAWyB4rj91VRWn96DkukG4bwdtyTh", offer_sequence=5) + self.assertTrue(tx.is_valid()) diff --git a/xrpl/openapi-codegen/test/transactions/test_offer_create.py b/xrpl/openapi-codegen/test/transactions/test_offer_create.py new file mode 100644 index 000000000..1ec6458a0 --- /dev/null +++ b/xrpl/openapi-codegen/test/transactions/test_offer_create.py @@ -0,0 +1,30 @@ +import unittest + +from xrpl.models.exceptions import XRPLModelException +from xrpl.models.transactions.offer_create import OfferCreate +from xrpl.models.transactions.offer_create import OfferCreateFlag + + +class TestOfferCreate(unittest.TestCase): + def test_tx_invalid_account_is_not_xrp_account(self): + with self.assertRaises(XRPLModelException) as err: + OfferCreate( + account="G5h7Dk92LmXqZtP3NvB8YrCfJ0W1AoUE", + expiration=5, + flags=OfferCreateFlag.TF_FILL_OR_KILL, + offer_sequence=5, + taker_gets="12345", + taker_pays="12345", + ) + self.assertIsNotNone(err.exception.args[0]) + + def test_tx_valid_transaction(self): + tx = OfferCreate( + account="rHb9CJAWyB4rj91VRWn96DkukG4bwdtyTh", + expiration=5, + flags=OfferCreateFlag.TF_FILL_OR_KILL, + offer_sequence=5, + taker_gets="12345", + taker_pays="12345", + ) + self.assertTrue(tx.is_valid()) diff --git a/xrpl/openapi-codegen/test/transactions/test_oracle_delete.py b/xrpl/openapi-codegen/test/transactions/test_oracle_delete.py new file mode 100644 index 000000000..07801c709 --- /dev/null +++ b/xrpl/openapi-codegen/test/transactions/test_oracle_delete.py @@ -0,0 +1,24 @@ +import unittest + +from xrpl.models.exceptions import XRPLModelException +from xrpl.models.transactions.oracle_delete import OracleDelete + + +class TestOracleDelete(unittest.TestCase): + def test_tx_invalid_missing_required_param_oracle_document_id(self): + with self.assertRaises(XRPLModelException) as err: + OracleDelete(account="rHb9CJAWyB4rj91VRWn96DkukG4bwdtyTh") + self.assertIsNotNone(err.exception.args[0]) + + def test_tx_invalid_account_is_not_xrp_account(self): + with self.assertRaises(XRPLModelException) as err: + OracleDelete( + account="G5h7Dk92LmXqZtP3NvB8YrCfJ0W1AoUE", oracle_document_id="AAAAA" + ) + self.assertIsNotNone(err.exception.args[0]) + + def test_tx_valid_transaction(self): + tx = OracleDelete( + account="rHb9CJAWyB4rj91VRWn96DkukG4bwdtyTh", oracle_document_id="AAAAA" + ) + self.assertTrue(tx.is_valid()) diff --git a/xrpl/openapi-codegen/test/transactions/test_oracle_set.py b/xrpl/openapi-codegen/test/transactions/test_oracle_set.py new file mode 100644 index 000000000..720c7b8cb --- /dev/null +++ b/xrpl/openapi-codegen/test/transactions/test_oracle_set.py @@ -0,0 +1,208 @@ +import unittest + +from xrpl.models.exceptions import XRPLModelException +from xrpl.models.transactions.oracle_set import OracleSet +from xrpl.models.transactions.oracle_set import PriceData + + +class TestOracleSet(unittest.TestCase): + def test_tx_invalid_scale_greater_than_max(self): + with self.assertRaises(XRPLModelException) as err: + OracleSet( + account="AAAAA", + asset_class="AAAAAAAAAAAAAAAA", + last_update_time=5, + oracle_document_id=5, + price_data_series=[ + PriceData( + asset_price="12345", + base_asset="AAAAA", + quote_asset="AAAAA", + scale=11, + ) + ], + provider="AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA", + uri="AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA", + ) + self.assertIsNotNone(err.exception.args[0]) + + def test_tx_invalid_scale_less_than_min(self): + with self.assertRaises(XRPLModelException) as err: + OracleSet( + account="AAAAA", + asset_class="AAAAAAAAAAAAAAAA", + last_update_time=5, + oracle_document_id=5, + price_data_series=[ + PriceData( + asset_price="12345", + base_asset="AAAAA", + quote_asset="AAAAA", + scale=-1, + ) + ], + provider="AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA", + uri="AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA", + ) + self.assertIsNotNone(err.exception.args[0]) + + def test_tx_invalid_missing_required_param_account(self): + with self.assertRaises(XRPLModelException) as err: + OracleSet( + asset_class="AAAAAAAAAAAAAAAA", + last_update_time=5, + oracle_document_id=5, + price_data_series=[ + PriceData( + asset_price="12345", + base_asset="AAAAA", + quote_asset="AAAAA", + scale=0, + ) + ], + provider="AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA", + uri="AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA", + ) + self.assertIsNotNone(err.exception.args[0]) + + def test_tx_invalid_missing_required_param_base_asset(self): + with self.assertRaises(XRPLModelException) as err: + OracleSet( + account="AAAAA", + asset_class="AAAAAAAAAAAAAAAA", + last_update_time=5, + oracle_document_id=5, + price_data_series=[ + PriceData(asset_price="12345", quote_asset="AAAAA", scale=0) + ], + provider="AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA", + uri="AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA", + ) + self.assertIsNotNone(err.exception.args[0]) + + def test_tx_invalid_mutual_presence_missing_asset_price(self): + with self.assertRaises(XRPLModelException) as err: + OracleSet( + account="AAAAA", + asset_class="AAAAAAAAAAAAAAAA", + last_update_time=5, + oracle_document_id=5, + price_data_series=[ + PriceData(base_asset="AAAAA", quote_asset="AAAAA", scale=0) + ], + provider="AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA", + uri="AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA", + ) + self.assertIsNotNone(err.exception.args[0]) + + def test_tx_invalid_asset_class_too_long(self): + with self.assertRaises(XRPLModelException) as err: + OracleSet( + account="AAAAA", + asset_class="AAAAAAAAAAAAAAAAA", + last_update_time=5, + oracle_document_id=5, + price_data_series=[ + PriceData( + asset_price="12345", + base_asset="AAAAA", + quote_asset="AAAAA", + scale=0, + ) + ], + provider="AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA", + uri="AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA", + ) + self.assertIsNotNone(err.exception.args[0]) + + def test_tx_invalid_provider_too_long(self): + with self.assertRaises(XRPLModelException) as err: + OracleSet( + account="AAAAA", + asset_class="AAAAAAAAAAAAAAAA", + last_update_time=5, + oracle_document_id=5, + price_data_series=[ + PriceData( + asset_price="12345", + base_asset="AAAAA", + quote_asset="AAAAA", + scale=0, + ) + ], + provider="AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA", + uri="AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA", + ) + self.assertIsNotNone(err.exception.args[0]) + + def test_tx_invalid_uri_too_long(self): + with self.assertRaises(XRPLModelException) as err: + OracleSet( + account="AAAAA", + asset_class="AAAAAAAAAAAAAAAA", + last_update_time=5, + oracle_document_id=5, + price_data_series=[ + PriceData( + asset_price="12345", + base_asset="AAAAA", + quote_asset="AAAAA", + scale=0, + ) + ], + provider="AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA", + uri="AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA", + ) + self.assertIsNotNone(err.exception.args[0]) + + def test_tx_invalid_asset_price_not_numeric(self): + with self.assertRaises(XRPLModelException) as err: + OracleSet( + account="AAAAA", + asset_class="AAAAAAAAAAAAAAAA", + last_update_time=5, + oracle_document_id=5, + price_data_series=[ + PriceData( + asset_price="AAAAA", + base_asset="AAAAA", + quote_asset="AAAAA", + scale=0, + ) + ], + provider="AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA", + uri="AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA", + ) + self.assertIsNotNone(err.exception.args[0]) + + def test_tx_invalid_price_data_series_less_than_min_items(self): + with self.assertRaises(XRPLModelException) as err: + OracleSet( + account="AAAAA", + asset_class="AAAAAAAAAAAAAAAA", + last_update_time=5, + oracle_document_id=5, + price_data_series=[], + provider="AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA", + uri="AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA", + ) + self.assertIsNotNone(err.exception.args[0]) + + def test_tx_valid_transaction(self): + tx = OracleSet( + account="AAAAA", + asset_class="AAAAAAAAAAAAAAAA", + last_update_time=5, + oracle_document_id=5, + price_data_series=[ + PriceData( + asset_price="12345", + base_asset="AAAAA", + quote_asset="AAAAA", + scale=0, + ) + ], + provider="AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA", + uri="AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA", + ) + self.assertTrue(tx.is_valid()) diff --git a/xrpl/openapi-codegen/test/transactions/test_payment.py b/xrpl/openapi-codegen/test/transactions/test_payment.py new file mode 100644 index 000000000..6d561ed0e --- /dev/null +++ b/xrpl/openapi-codegen/test/transactions/test_payment.py @@ -0,0 +1,32 @@ +import unittest + +from xrpl.models.exceptions import XRPLModelException +from xrpl.models.transactions.payment import Payment +from xrpl.models.transactions.payment import PaymentFlag + + +class TestPayment(unittest.TestCase): + def test_tx_invalid_account_is_not_xrp_account(self): + with self.assertRaises(XRPLModelException) as err: + Payment( + account="G5h7Dk92LmXqZtP3NvB8YrCfJ0W1AoUE", + amount="12345", + destination="AAAAA", + destination_tag=5, + flags=PaymentFlag.TF_LIMIT_QUALITY, + invoice_id="AAAAA", + send_max="12345", + ) + self.assertIsNotNone(err.exception.args[0]) + + def test_tx_valid_transaction(self): + tx = Payment( + account="rHb9CJAWyB4rj91VRWn96DkukG4bwdtyTh", + amount="12345", + destination="AAAAA", + destination_tag=5, + flags=PaymentFlag.TF_LIMIT_QUALITY, + invoice_id="AAAAA", + send_max="12345", + ) + self.assertTrue(tx.is_valid()) diff --git a/xrpl/openapi-codegen/test/transactions/test_payment_channel_claim.py b/xrpl/openapi-codegen/test/transactions/test_payment_channel_claim.py new file mode 100644 index 000000000..2fe908392 --- /dev/null +++ b/xrpl/openapi-codegen/test/transactions/test_payment_channel_claim.py @@ -0,0 +1,85 @@ +import unittest + +from xrpl.models.exceptions import XRPLModelException +from xrpl.models.transactions.payment_channel_claim import PaymentChannelClaim +from xrpl.models.transactions.payment_channel_claim import PaymentChannelClaimFlag + + +class TestPaymentChannelClaim(unittest.TestCase): + def test_tx_invalid_missing_required_param_channel(self): + with self.assertRaises(XRPLModelException) as err: + PaymentChannelClaim( + account="rHb9CJAWyB4rj91VRWn96DkukG4bwdtyTh", + amount="AAAAA", + balance="AAAAA", + credential_ids=["AAAAA"], + flags=PaymentChannelClaimFlag.TF_CLOSE, + public_key="AAAAA", + signature="AAAAA", + ) + self.assertIsNotNone(err.exception.args[0]) + + def test_tx_invalid_credential_ids_less_than_min_items(self): + with self.assertRaises(XRPLModelException) as err: + PaymentChannelClaim( + account="rHb9CJAWyB4rj91VRWn96DkukG4bwdtyTh", + amount="AAAAA", + balance="AAAAA", + channel="AAAAA", + credential_ids=[], + flags=PaymentChannelClaimFlag.TF_CLOSE, + public_key="AAAAA", + signature="AAAAA", + ) + self.assertIsNotNone(err.exception.args[0]) + + def test_tx_invalid_credential_ids_more_than_max_items(self): + with self.assertRaises(XRPLModelException) as err: + PaymentChannelClaim( + account="rHb9CJAWyB4rj91VRWn96DkukG4bwdtyTh", + amount="AAAAA", + balance="AAAAA", + channel="AAAAA", + credential_ids=[ + "AAAAA", + "BBBBB", + "CCCCC", + "DDDDD", + "EEEEE", + "FFFFF", + "GGGGG", + "HHHHH", + "IIIII", + ], + flags=PaymentChannelClaimFlag.TF_CLOSE, + public_key="AAAAA", + signature="AAAAA", + ) + self.assertIsNotNone(err.exception.args[0]) + + def test_tx_invalid_account_is_not_xrp_account(self): + with self.assertRaises(XRPLModelException) as err: + PaymentChannelClaim( + account="G5h7Dk92LmXqZtP3NvB8YrCfJ0W1AoUE", + amount="AAAAA", + balance="AAAAA", + channel="AAAAA", + credential_ids=["AAAAA"], + flags=PaymentChannelClaimFlag.TF_CLOSE, + public_key="AAAAA", + signature="AAAAA", + ) + self.assertIsNotNone(err.exception.args[0]) + + def test_tx_valid_transaction(self): + tx = PaymentChannelClaim( + account="rHb9CJAWyB4rj91VRWn96DkukG4bwdtyTh", + amount="AAAAA", + balance="AAAAA", + channel="AAAAA", + credential_ids=["AAAAA"], + flags=PaymentChannelClaimFlag.TF_CLOSE, + public_key="AAAAA", + signature="AAAAA", + ) + self.assertTrue(tx.is_valid()) diff --git a/xrpl/openapi-codegen/test/transactions/test_payment_channel_create.py b/xrpl/openapi-codegen/test/transactions/test_payment_channel_create.py new file mode 100644 index 000000000..0f84bbc0a --- /dev/null +++ b/xrpl/openapi-codegen/test/transactions/test_payment_channel_create.py @@ -0,0 +1,56 @@ +import unittest + +from xrpl.models.exceptions import XRPLModelException +from xrpl.models.transactions.payment_channel_create import PaymentChannelCreate + + +class TestPaymentChannelCreate(unittest.TestCase): + def test_tx_invalid_missing_required_param_amount(self): + with self.assertRaises(XRPLModelException) as err: + PaymentChannelCreate( + account="rJ73aumLPTQQmy5wnGhvrogqf5DDhjuzc9", + cancel_after=5, + destination="AAAAA", + destination_tag=5, + public_key="AAAAA", + settle_delay=5, + ) + self.assertIsNotNone(err.exception.args[0]) + + def test_tx_invalid_duplicate_destination_and_account(self): + with self.assertRaises(XRPLModelException) as err: + PaymentChannelCreate( + account="rJ73aumLPTQQmy5wnGhvrogqf5DDhjuzc9", + amount="AAAAA", + cancel_after=5, + destination="rJ73aumLPTQQmy5wnGhvrogqf5DDhjuzc9", + destination_tag=5, + public_key="AAAAA", + settle_delay=5, + ) + self.assertIsNotNone(err.exception.args[0]) + + def test_tx_invalid_account_is_not_xrp_account(self): + with self.assertRaises(XRPLModelException) as err: + PaymentChannelCreate( + account="G5h7Dk92LmXqZtP3NvB8YrCfJ0W1AoUE", + amount="AAAAA", + cancel_after=5, + destination="AAAAA", + destination_tag=5, + public_key="AAAAA", + settle_delay=5, + ) + self.assertIsNotNone(err.exception.args[0]) + + def test_tx_valid_transaction(self): + tx = PaymentChannelCreate( + account="rJ73aumLPTQQmy5wnGhvrogqf5DDhjuzc9", + amount="AAAAA", + cancel_after=5, + destination="AAAAA", + destination_tag=5, + public_key="AAAAA", + settle_delay=5, + ) + self.assertTrue(tx.is_valid()) diff --git a/xrpl/openapi-codegen/test/transactions/test_payment_channel_fund.py b/xrpl/openapi-codegen/test/transactions/test_payment_channel_fund.py new file mode 100644 index 000000000..2d16394aa --- /dev/null +++ b/xrpl/openapi-codegen/test/transactions/test_payment_channel_fund.py @@ -0,0 +1,52 @@ +import unittest + +from xrpl.models.exceptions import XRPLModelException +from xrpl.models.transactions.payment_channel_fund import PaymentChannelFund + + +class TestPaymentChannelFund(unittest.TestCase): + def test_tx_invalid_missing_required_param_channel(self): + with self.assertRaises(XRPLModelException) as err: + PaymentChannelFund( + account="rHb9CJAWyB4rj91VRWn96DkukG4bwdtyTh", amount="1", expiration=5 + ) + self.assertIsNotNone(err.exception.args[0]) + + def test_tx_invalid_amount_not_numeric(self): + with self.assertRaises(XRPLModelException) as err: + PaymentChannelFund( + account="rHb9CJAWyB4rj91VRWn96DkukG4bwdtyTh", + amount="AAAAA", + channel="AAAAA", + expiration=5, + ) + self.assertIsNotNone(err.exception.args[0]) + + def test_tx_invalid_amount_not_greater_than_0(self): + with self.assertRaises(XRPLModelException) as err: + PaymentChannelFund( + account="rHb9CJAWyB4rj91VRWn96DkukG4bwdtyTh", + amount="0", + channel="AAAAA", + expiration=5, + ) + self.assertIsNotNone(err.exception.args[0]) + + def test_tx_invalid_account_is_not_xrp_account(self): + with self.assertRaises(XRPLModelException) as err: + PaymentChannelFund( + account="G5h7Dk92LmXqZtP3NvB8YrCfJ0W1AoUE", + amount="1", + channel="AAAAA", + expiration=5, + ) + self.assertIsNotNone(err.exception.args[0]) + + def test_tx_valid_transaction(self): + tx = PaymentChannelFund( + account="rHb9CJAWyB4rj91VRWn96DkukG4bwdtyTh", + amount="1", + channel="AAAAA", + expiration=5, + ) + self.assertTrue(tx.is_valid()) diff --git a/xrpl/openapi-codegen/test/transactions/test_set_regular_key.py b/xrpl/openapi-codegen/test/transactions/test_set_regular_key.py new file mode 100644 index 000000000..9a9f968d7 --- /dev/null +++ b/xrpl/openapi-codegen/test/transactions/test_set_regular_key.py @@ -0,0 +1,24 @@ +import unittest + +from xrpl.models.exceptions import XRPLModelException +from xrpl.models.transactions.set_regular_key import SetRegularKey + + +class TestSetRegularKey(unittest.TestCase): + def test_tx_invalid_missing_required_param_account(self): + with self.assertRaises(XRPLModelException) as err: + SetRegularKey(regular_key="AAAAA") + self.assertIsNotNone(err.exception.args[0]) + + def test_tx_invalid_account_is_not_xrp_account(self): + with self.assertRaises(XRPLModelException) as err: + SetRegularKey( + account="G5h7Dk92LmXqZtP3NvB8YrCfJ0W1AoUE", regular_key="AAAAA" + ) + self.assertIsNotNone(err.exception.args[0]) + + def test_tx_valid_transaction(self): + tx = SetRegularKey( + account="rHb9CJAWyB4rj91VRWn96DkukG4bwdtyTh", regular_key="AAAAA" + ) + self.assertTrue(tx.is_valid()) diff --git a/xrpl/openapi-codegen/test/transactions/test_ticket_create.py b/xrpl/openapi-codegen/test/transactions/test_ticket_create.py new file mode 100644 index 000000000..50126c804 --- /dev/null +++ b/xrpl/openapi-codegen/test/transactions/test_ticket_create.py @@ -0,0 +1,30 @@ +import unittest + +from xrpl.models.exceptions import XRPLModelException +from xrpl.models.transactions.ticket_create import TicketCreate + + +class TestTicketCreate(unittest.TestCase): + def test_tx_invalid_ticket_count_greater_than_max(self): + with self.assertRaises(XRPLModelException) as err: + TicketCreate(account="rHb9CJAWyB4rj91VRWn96DkukG4bwdtyTh", ticket_count=251) + self.assertIsNotNone(err.exception.args[0]) + + def test_tx_invalid_ticket_count_less_than_min(self): + with self.assertRaises(XRPLModelException) as err: + TicketCreate(account="rHb9CJAWyB4rj91VRWn96DkukG4bwdtyTh", ticket_count=0) + self.assertIsNotNone(err.exception.args[0]) + + def test_tx_invalid_missing_required_param_ticket_count(self): + with self.assertRaises(XRPLModelException) as err: + TicketCreate(account="rHb9CJAWyB4rj91VRWn96DkukG4bwdtyTh") + self.assertIsNotNone(err.exception.args[0]) + + def test_tx_invalid_account_is_not_xrp_account(self): + with self.assertRaises(XRPLModelException) as err: + TicketCreate(account="G5h7Dk92LmXqZtP3NvB8YrCfJ0W1AoUE", ticket_count=1) + self.assertIsNotNone(err.exception.args[0]) + + def test_tx_valid_transaction(self): + tx = TicketCreate(account="rHb9CJAWyB4rj91VRWn96DkukG4bwdtyTh", ticket_count=1) + self.assertTrue(tx.is_valid()) diff --git a/xrpl/openapi-codegen/test/transactions/test_transaction.py b/xrpl/openapi-codegen/test/transactions/test_transaction.py new file mode 100644 index 000000000..d307a8c67 --- /dev/null +++ b/xrpl/openapi-codegen/test/transactions/test_transaction.py @@ -0,0 +1,74 @@ +import unittest + +from xrpl.models.exceptions import XRPLModelException +from xrpl.models.transactions.transaction import Memo +from xrpl.models.transactions.transaction import Transaction + + +class TestTransaction(unittest.TestCase): + def test_tx_invalid_missing_required_param_account(self): + with self.assertRaises(XRPLModelException) as err: + Transaction( + account_txn_id="AAAAA", + fee="AAAAA", + last_ledger_sequence=5, + memos=[ + Memo(memo_data="AAAAA", memo_format="AAAAA", memo_type="AAAAA"), + Memo(memo_data="AAAAA", memo_format="AAAAA", memo_type="AAAAA"), + Memo(memo_data="AAAAA", memo_format="AAAAA", memo_type="AAAAA"), + Memo(memo_data="AAAAA", memo_format="AAAAA", memo_type="AAAAA"), + Memo(memo_data="AAAAA", memo_format="AAAAA", memo_type="AAAAA"), + ], + network_id=5, + sequence=5, + signing_pub_key="AAAAA", + source_tag=5, + ticket_sequence=5, + txn_signature="AAAAA", + ) + self.assertIsNotNone(err.exception.args[0]) + + def test_tx_invalid_account_is_not_xrp_account(self): + with self.assertRaises(XRPLModelException) as err: + Transaction( + account="G5h7Dk92LmXqZtP3NvB8YrCfJ0W1AoUE", + account_txn_id="AAAAA", + fee="AAAAA", + last_ledger_sequence=5, + memos=[ + Memo(memo_data="AAAAA", memo_format="AAAAA", memo_type="AAAAA"), + Memo(memo_data="AAAAA", memo_format="AAAAA", memo_type="AAAAA"), + Memo(memo_data="AAAAA", memo_format="AAAAA", memo_type="AAAAA"), + Memo(memo_data="AAAAA", memo_format="AAAAA", memo_type="AAAAA"), + Memo(memo_data="AAAAA", memo_format="AAAAA", memo_type="AAAAA"), + ], + network_id=5, + sequence=5, + signing_pub_key="AAAAA", + source_tag=5, + ticket_sequence=5, + txn_signature="AAAAA", + ) + self.assertIsNotNone(err.exception.args[0]) + + def test_tx_valid_transaction(self): + tx = Transaction( + account="rHb9CJAWyB4rj91VRWn96DkukG4bwdtyTh", + account_txn_id="AAAAA", + fee="AAAAA", + last_ledger_sequence=5, + memos=[ + Memo(memo_data="AAAAA", memo_format="AAAAA", memo_type="AAAAA"), + Memo(memo_data="AAAAA", memo_format="AAAAA", memo_type="AAAAA"), + Memo(memo_data="AAAAA", memo_format="AAAAA", memo_type="AAAAA"), + Memo(memo_data="AAAAA", memo_format="AAAAA", memo_type="AAAAA"), + Memo(memo_data="AAAAA", memo_format="AAAAA", memo_type="AAAAA"), + ], + network_id=5, + sequence=5, + signing_pub_key="AAAAA", + source_tag=5, + ticket_sequence=5, + txn_signature="AAAAA", + ) + self.assertTrue(tx.is_valid()) diff --git a/xrpl/openapi-codegen/test/transactions/test_trust_set.py b/xrpl/openapi-codegen/test/transactions/test_trust_set.py new file mode 100644 index 000000000..92062cd43 --- /dev/null +++ b/xrpl/openapi-codegen/test/transactions/test_trust_set.py @@ -0,0 +1,38 @@ +import unittest + +from xrpl.models.exceptions import XRPLModelException +from xrpl.models.transactions.trust_set import TrustSet +from xrpl.models.transactions.trust_set import TrustSetFlag + + +class TestTrustSet(unittest.TestCase): + def test_tx_invalid_missing_required_param_limit_amount(self): + with self.assertRaises(XRPLModelException) as err: + TrustSet( + account="rHb9CJAWyB4rj91VRWn96DkukG4bwdtyTh", + flags=TrustSetFlag.TF_CLEAR_FREEZE, + quality_in=5, + quality_out=5, + ) + self.assertIsNotNone(err.exception.args[0]) + + def test_tx_invalid_account_is_not_xrp_account(self): + with self.assertRaises(XRPLModelException) as err: + TrustSet( + account="G5h7Dk92LmXqZtP3NvB8YrCfJ0W1AoUE", + flags=TrustSetFlag.TF_CLEAR_FREEZE, + limit_amount="12345", + quality_in=5, + quality_out=5, + ) + self.assertIsNotNone(err.exception.args[0]) + + def test_tx_valid_transaction(self): + tx = TrustSet( + account="rHb9CJAWyB4rj91VRWn96DkukG4bwdtyTh", + flags=TrustSetFlag.TF_CLEAR_FREEZE, + limit_amount="12345", + quality_in=5, + quality_out=5, + ) + self.assertTrue(tx.is_valid()) diff --git a/xrpl/openapi-codegen/test/transactions/test_xchain_account_create_commit.py b/xrpl/openapi-codegen/test/transactions/test_xchain_account_create_commit.py new file mode 100644 index 000000000..8cbc3291a --- /dev/null +++ b/xrpl/openapi-codegen/test/transactions/test_xchain_account_create_commit.py @@ -0,0 +1,147 @@ +import unittest + +from xrpl.models.exceptions import XRPLModelException +from xrpl.models.transactions.xchain_account_create_commit import Currency +from xrpl.models.transactions.xchain_account_create_commit import ( + XChainAccountCreateCommit, +) +from xrpl.models.transactions.xchain_account_create_commit import XChainBridge + + +class TestXChainAccountCreateCommit(unittest.TestCase): + def test_tx_invalid_missing_required_param_issuing_chain_door(self): + with self.assertRaises(XRPLModelException) as err: + XChainAccountCreateCommit( + account="rHb9CJAWyB4rj91VRWn96DkukG4bwdtyTh", + amount="12345", + destination="AAAAA", + signature_reward="12345", + xchain_bridge=XChainBridge( + issuing_chain_issue=Currency( + currency="USD", issuer="rHb9CJAWyB4rj91VRWn96DkukG4bwdtyTh" + ), + locking_chain_door="AAAAA", + locking_chain_issue=Currency( + currency="USD", issuer="rHb9CJAWyB4rj91VRWn96DkukG4bwdtyTh" + ), + ), + ) + self.assertIsNotNone(err.exception.args[0]) + + def test_tx_invalid_missing_required_param_amount(self): + with self.assertRaises(XRPLModelException) as err: + XChainAccountCreateCommit( + account="rHb9CJAWyB4rj91VRWn96DkukG4bwdtyTh", + destination="AAAAA", + signature_reward="12345", + xchain_bridge=XChainBridge( + issuing_chain_door="AAAAA", + issuing_chain_issue=Currency( + currency="USD", issuer="rHb9CJAWyB4rj91VRWn96DkukG4bwdtyTh" + ), + locking_chain_door="AAAAA", + locking_chain_issue=Currency( + currency="USD", issuer="rHb9CJAWyB4rj91VRWn96DkukG4bwdtyTh" + ), + ), + ) + self.assertIsNotNone(err.exception.args[0]) + + def test_tx_invalid_amount_not_numeric(self): + with self.assertRaises(XRPLModelException) as err: + XChainAccountCreateCommit( + account="rHb9CJAWyB4rj91VRWn96DkukG4bwdtyTh", + amount="AAAAA", + destination="AAAAA", + signature_reward="12345", + xchain_bridge=XChainBridge( + issuing_chain_door="AAAAA", + issuing_chain_issue=Currency( + currency="USD", issuer="rHb9CJAWyB4rj91VRWn96DkukG4bwdtyTh" + ), + locking_chain_door="AAAAA", + locking_chain_issue=Currency( + currency="USD", issuer="rHb9CJAWyB4rj91VRWn96DkukG4bwdtyTh" + ), + ), + ) + self.assertIsNotNone(err.exception.args[0]) + + def test_tx_invalid_signature_reward_not_numeric(self): + with self.assertRaises(XRPLModelException) as err: + XChainAccountCreateCommit( + account="rHb9CJAWyB4rj91VRWn96DkukG4bwdtyTh", + amount="12345", + destination="AAAAA", + signature_reward="AAAAA", + xchain_bridge=XChainBridge( + issuing_chain_door="AAAAA", + issuing_chain_issue=Currency( + currency="USD", issuer="rHb9CJAWyB4rj91VRWn96DkukG4bwdtyTh" + ), + locking_chain_door="AAAAA", + locking_chain_issue=Currency( + currency="USD", issuer="rHb9CJAWyB4rj91VRWn96DkukG4bwdtyTh" + ), + ), + ) + self.assertIsNotNone(err.exception.args[0]) + + def test_tx_invalid_account_is_not_xrp_account(self): + with self.assertRaises(XRPLModelException) as err: + XChainAccountCreateCommit( + account="G5h7Dk92LmXqZtP3NvB8YrCfJ0W1AoUE", + amount="12345", + destination="AAAAA", + signature_reward="12345", + xchain_bridge=XChainBridge( + issuing_chain_door="AAAAA", + issuing_chain_issue=Currency( + currency="USD", issuer="rHb9CJAWyB4rj91VRWn96DkukG4bwdtyTh" + ), + locking_chain_door="AAAAA", + locking_chain_issue=Currency( + currency="USD", issuer="rHb9CJAWyB4rj91VRWn96DkukG4bwdtyTh" + ), + ), + ) + self.assertIsNotNone(err.exception.args[0]) + + def test_tx_invalid_issuer_is_not_xrp_account(self): + with self.assertRaises(XRPLModelException) as err: + XChainAccountCreateCommit( + account="rHb9CJAWyB4rj91VRWn96DkukG4bwdtyTh", + amount="12345", + destination="AAAAA", + signature_reward="12345", + xchain_bridge=XChainBridge( + issuing_chain_door="AAAAA", + issuing_chain_issue=Currency( + currency="USD", issuer="G5h7Dk92LmXqZtP3NvB8YrCfJ0W1AoUE" + ), + locking_chain_door="AAAAA", + locking_chain_issue=Currency( + currency="USD", issuer="G5h7Dk92LmXqZtP3NvB8YrCfJ0W1AoUE" + ), + ), + ) + self.assertIsNotNone(err.exception.args[0]) + + def test_tx_valid_transaction(self): + tx = XChainAccountCreateCommit( + account="rHb9CJAWyB4rj91VRWn96DkukG4bwdtyTh", + amount="12345", + destination="AAAAA", + signature_reward="12345", + xchain_bridge=XChainBridge( + issuing_chain_door="AAAAA", + issuing_chain_issue=Currency( + currency="USD", issuer="rHb9CJAWyB4rj91VRWn96DkukG4bwdtyTh" + ), + locking_chain_door="AAAAA", + locking_chain_issue=Currency( + currency="USD", issuer="rHb9CJAWyB4rj91VRWn96DkukG4bwdtyTh" + ), + ), + ) + self.assertTrue(tx.is_valid()) diff --git a/xrpl/openapi-codegen/test/transactions/test_xchain_add_account_create_attestation.py b/xrpl/openapi-codegen/test/transactions/test_xchain_add_account_create_attestation.py new file mode 100644 index 000000000..2e8e6cac6 --- /dev/null +++ b/xrpl/openapi-codegen/test/transactions/test_xchain_add_account_create_attestation.py @@ -0,0 +1,142 @@ +import unittest + +from xrpl.models.exceptions import XRPLModelException +from xrpl.models.transactions.xchain_add_account_create_attestation import Currency +from xrpl.models.transactions.xchain_add_account_create_attestation import ( + XChainAddAccountCreateAttestation, +) +from xrpl.models.transactions.xchain_add_account_create_attestation import XChainBridge + + +class TestXChainAddAccountCreateAttestation(unittest.TestCase): + def test_tx_invalid_missing_required_param_amount(self): + with self.assertRaises(XRPLModelException) as err: + XChainAddAccountCreateAttestation( + account="rHb9CJAWyB4rj91VRWn96DkukG4bwdtyTh", + attestation_reward_account="AAAAA", + attestation_signer_account="AAAAA", + destination="AAAAA", + other_chain_source="AAAAA", + public_key="AAAAA", + signature="AAAAA", + signature_reward="AAAAA", + was_locking_chain_send=5, + xchain_account_create_count="AAAAA", + xchain_bridge=XChainBridge( + issuing_chain_door="AAAAA", + issuing_chain_issue=Currency( + currency="USD", issuer="rHb9CJAWyB4rj91VRWn96DkukG4bwdtyTh" + ), + locking_chain_door="AAAAA", + locking_chain_issue=Currency( + currency="USD", issuer="rHb9CJAWyB4rj91VRWn96DkukG4bwdtyTh" + ), + ), + ) + self.assertIsNotNone(err.exception.args[0]) + + def test_tx_invalid_missing_required_param_issuing_chain_door(self): + with self.assertRaises(XRPLModelException) as err: + XChainAddAccountCreateAttestation( + account="rHb9CJAWyB4rj91VRWn96DkukG4bwdtyTh", + amount="AAAAA", + attestation_reward_account="AAAAA", + attestation_signer_account="AAAAA", + destination="AAAAA", + other_chain_source="AAAAA", + public_key="AAAAA", + signature="AAAAA", + signature_reward="AAAAA", + was_locking_chain_send=5, + xchain_account_create_count="AAAAA", + xchain_bridge=XChainBridge( + issuing_chain_issue=Currency( + currency="USD", issuer="rHb9CJAWyB4rj91VRWn96DkukG4bwdtyTh" + ), + locking_chain_door="AAAAA", + locking_chain_issue=Currency( + currency="USD", issuer="rHb9CJAWyB4rj91VRWn96DkukG4bwdtyTh" + ), + ), + ) + self.assertIsNotNone(err.exception.args[0]) + + def test_tx_invalid_account_is_not_xrp_account(self): + with self.assertRaises(XRPLModelException) as err: + XChainAddAccountCreateAttestation( + account="G5h7Dk92LmXqZtP3NvB8YrCfJ0W1AoUE", + amount="AAAAA", + attestation_reward_account="AAAAA", + attestation_signer_account="AAAAA", + destination="AAAAA", + other_chain_source="AAAAA", + public_key="AAAAA", + signature="AAAAA", + signature_reward="AAAAA", + was_locking_chain_send=5, + xchain_account_create_count="AAAAA", + xchain_bridge=XChainBridge( + issuing_chain_door="AAAAA", + issuing_chain_issue=Currency( + currency="USD", issuer="rHb9CJAWyB4rj91VRWn96DkukG4bwdtyTh" + ), + locking_chain_door="AAAAA", + locking_chain_issue=Currency( + currency="USD", issuer="rHb9CJAWyB4rj91VRWn96DkukG4bwdtyTh" + ), + ), + ) + self.assertIsNotNone(err.exception.args[0]) + + def test_tx_invalid_issuer_is_not_xrp_account(self): + with self.assertRaises(XRPLModelException) as err: + XChainAddAccountCreateAttestation( + account="rHb9CJAWyB4rj91VRWn96DkukG4bwdtyTh", + amount="AAAAA", + attestation_reward_account="AAAAA", + attestation_signer_account="AAAAA", + destination="AAAAA", + other_chain_source="AAAAA", + public_key="AAAAA", + signature="AAAAA", + signature_reward="AAAAA", + was_locking_chain_send=5, + xchain_account_create_count="AAAAA", + xchain_bridge=XChainBridge( + issuing_chain_door="AAAAA", + issuing_chain_issue=Currency( + currency="USD", issuer="G5h7Dk92LmXqZtP3NvB8YrCfJ0W1AoUE" + ), + locking_chain_door="AAAAA", + locking_chain_issue=Currency( + currency="USD", issuer="G5h7Dk92LmXqZtP3NvB8YrCfJ0W1AoUE" + ), + ), + ) + self.assertIsNotNone(err.exception.args[0]) + + def test_tx_valid_transaction(self): + tx = XChainAddAccountCreateAttestation( + account="rHb9CJAWyB4rj91VRWn96DkukG4bwdtyTh", + amount="AAAAA", + attestation_reward_account="AAAAA", + attestation_signer_account="AAAAA", + destination="AAAAA", + other_chain_source="AAAAA", + public_key="AAAAA", + signature="AAAAA", + signature_reward="AAAAA", + was_locking_chain_send=5, + xchain_account_create_count="AAAAA", + xchain_bridge=XChainBridge( + issuing_chain_door="AAAAA", + issuing_chain_issue=Currency( + currency="USD", issuer="rHb9CJAWyB4rj91VRWn96DkukG4bwdtyTh" + ), + locking_chain_door="AAAAA", + locking_chain_issue=Currency( + currency="USD", issuer="rHb9CJAWyB4rj91VRWn96DkukG4bwdtyTh" + ), + ), + ) + self.assertTrue(tx.is_valid()) diff --git a/xrpl/openapi-codegen/test/transactions/test_xchain_add_claim_attestation.py b/xrpl/openapi-codegen/test/transactions/test_xchain_add_claim_attestation.py new file mode 100644 index 000000000..7f06d4483 --- /dev/null +++ b/xrpl/openapi-codegen/test/transactions/test_xchain_add_claim_attestation.py @@ -0,0 +1,137 @@ +import unittest + +from xrpl.models.exceptions import XRPLModelException +from xrpl.models.transactions.xchain_add_claim_attestation import Currency +from xrpl.models.transactions.xchain_add_claim_attestation import ( + XChainAddClaimAttestation, +) +from xrpl.models.transactions.xchain_add_claim_attestation import XChainBridge + + +class TestXChainAddClaimAttestation(unittest.TestCase): + def test_tx_invalid_missing_required_param_amount(self): + with self.assertRaises(XRPLModelException) as err: + XChainAddClaimAttestation( + account="rHb9CJAWyB4rj91VRWn96DkukG4bwdtyTh", + attestation_reward_account="AAAAA", + attestation_signer_account="AAAAA", + destination="AAAAA", + other_chain_source="AAAAA", + public_key="AAAAA", + signature="AAAAA", + was_locking_chain_send=5, + xchain_bridge=XChainBridge( + issuing_chain_door="AAAAA", + issuing_chain_issue=Currency( + currency="USD", issuer="rHb9CJAWyB4rj91VRWn96DkukG4bwdtyTh" + ), + locking_chain_door="AAAAA", + locking_chain_issue=Currency( + currency="USD", issuer="rHb9CJAWyB4rj91VRWn96DkukG4bwdtyTh" + ), + ), + xchain_claim_id="AAAAA", + ) + self.assertIsNotNone(err.exception.args[0]) + + def test_tx_invalid_missing_required_param_issuing_chain_door(self): + with self.assertRaises(XRPLModelException) as err: + XChainAddClaimAttestation( + account="rHb9CJAWyB4rj91VRWn96DkukG4bwdtyTh", + amount="AAAAA", + attestation_reward_account="AAAAA", + attestation_signer_account="AAAAA", + destination="AAAAA", + other_chain_source="AAAAA", + public_key="AAAAA", + signature="AAAAA", + was_locking_chain_send=5, + xchain_bridge=XChainBridge( + issuing_chain_issue=Currency( + currency="USD", issuer="rHb9CJAWyB4rj91VRWn96DkukG4bwdtyTh" + ), + locking_chain_door="AAAAA", + locking_chain_issue=Currency( + currency="USD", issuer="rHb9CJAWyB4rj91VRWn96DkukG4bwdtyTh" + ), + ), + xchain_claim_id="AAAAA", + ) + self.assertIsNotNone(err.exception.args[0]) + + def test_tx_invalid_account_is_not_xrp_account(self): + with self.assertRaises(XRPLModelException) as err: + XChainAddClaimAttestation( + account="G5h7Dk92LmXqZtP3NvB8YrCfJ0W1AoUE", + amount="AAAAA", + attestation_reward_account="AAAAA", + attestation_signer_account="AAAAA", + destination="AAAAA", + other_chain_source="AAAAA", + public_key="AAAAA", + signature="AAAAA", + was_locking_chain_send=5, + xchain_bridge=XChainBridge( + issuing_chain_door="AAAAA", + issuing_chain_issue=Currency( + currency="USD", issuer="rHb9CJAWyB4rj91VRWn96DkukG4bwdtyTh" + ), + locking_chain_door="AAAAA", + locking_chain_issue=Currency( + currency="USD", issuer="rHb9CJAWyB4rj91VRWn96DkukG4bwdtyTh" + ), + ), + xchain_claim_id="AAAAA", + ) + self.assertIsNotNone(err.exception.args[0]) + + def test_tx_invalid_issuer_is_not_xrp_account(self): + with self.assertRaises(XRPLModelException) as err: + XChainAddClaimAttestation( + account="rHb9CJAWyB4rj91VRWn96DkukG4bwdtyTh", + amount="AAAAA", + attestation_reward_account="AAAAA", + attestation_signer_account="AAAAA", + destination="AAAAA", + other_chain_source="AAAAA", + public_key="AAAAA", + signature="AAAAA", + was_locking_chain_send=5, + xchain_bridge=XChainBridge( + issuing_chain_door="AAAAA", + issuing_chain_issue=Currency( + currency="USD", issuer="G5h7Dk92LmXqZtP3NvB8YrCfJ0W1AoUE" + ), + locking_chain_door="AAAAA", + locking_chain_issue=Currency( + currency="USD", issuer="G5h7Dk92LmXqZtP3NvB8YrCfJ0W1AoUE" + ), + ), + xchain_claim_id="AAAAA", + ) + self.assertIsNotNone(err.exception.args[0]) + + def test_tx_valid_transaction(self): + tx = XChainAddClaimAttestation( + account="rHb9CJAWyB4rj91VRWn96DkukG4bwdtyTh", + amount="AAAAA", + attestation_reward_account="AAAAA", + attestation_signer_account="AAAAA", + destination="AAAAA", + other_chain_source="AAAAA", + public_key="AAAAA", + signature="AAAAA", + was_locking_chain_send=5, + xchain_bridge=XChainBridge( + issuing_chain_door="AAAAA", + issuing_chain_issue=Currency( + currency="USD", issuer="rHb9CJAWyB4rj91VRWn96DkukG4bwdtyTh" + ), + locking_chain_door="AAAAA", + locking_chain_issue=Currency( + currency="USD", issuer="rHb9CJAWyB4rj91VRWn96DkukG4bwdtyTh" + ), + ), + xchain_claim_id="AAAAA", + ) + self.assertTrue(tx.is_valid()) diff --git a/xrpl/openapi-codegen/test/transactions/test_xchain_claim.py b/xrpl/openapi-codegen/test/transactions/test_xchain_claim.py new file mode 100644 index 000000000..d987d6da9 --- /dev/null +++ b/xrpl/openapi-codegen/test/transactions/test_xchain_claim.py @@ -0,0 +1,110 @@ +import unittest + +from xrpl.models.exceptions import XRPLModelException +from xrpl.models.transactions.xchain_claim import Currency +from xrpl.models.transactions.xchain_claim import XChainBridge +from xrpl.models.transactions.xchain_claim import XChainClaim + + +class TestXChainClaim(unittest.TestCase): + def test_tx_invalid_missing_required_param_issuing_chain_door(self): + with self.assertRaises(XRPLModelException) as err: + XChainClaim( + account="rHb9CJAWyB4rj91VRWn96DkukG4bwdtyTh", + amount="12345", + destination="AAAAA", + destination_tag=5, + xchain_bridge=XChainBridge( + issuing_chain_issue=Currency( + currency="USD", issuer="rHb9CJAWyB4rj91VRWn96DkukG4bwdtyTh" + ), + locking_chain_door="AAAAA", + locking_chain_issue=Currency( + currency="USD", issuer="rHb9CJAWyB4rj91VRWn96DkukG4bwdtyTh" + ), + ), + xchain_claim_id="AAAAA", + ) + self.assertIsNotNone(err.exception.args[0]) + + def test_tx_invalid_missing_required_param_amount(self): + with self.assertRaises(XRPLModelException) as err: + XChainClaim( + account="rHb9CJAWyB4rj91VRWn96DkukG4bwdtyTh", + destination="AAAAA", + destination_tag=5, + xchain_bridge=XChainBridge( + issuing_chain_door="AAAAA", + issuing_chain_issue=Currency( + currency="USD", issuer="rHb9CJAWyB4rj91VRWn96DkukG4bwdtyTh" + ), + locking_chain_door="AAAAA", + locking_chain_issue=Currency( + currency="USD", issuer="rHb9CJAWyB4rj91VRWn96DkukG4bwdtyTh" + ), + ), + xchain_claim_id="AAAAA", + ) + self.assertIsNotNone(err.exception.args[0]) + + def test_tx_invalid_account_is_not_xrp_account(self): + with self.assertRaises(XRPLModelException) as err: + XChainClaim( + account="G5h7Dk92LmXqZtP3NvB8YrCfJ0W1AoUE", + amount="12345", + destination="AAAAA", + destination_tag=5, + xchain_bridge=XChainBridge( + issuing_chain_door="AAAAA", + issuing_chain_issue=Currency( + currency="USD", issuer="rHb9CJAWyB4rj91VRWn96DkukG4bwdtyTh" + ), + locking_chain_door="AAAAA", + locking_chain_issue=Currency( + currency="USD", issuer="rHb9CJAWyB4rj91VRWn96DkukG4bwdtyTh" + ), + ), + xchain_claim_id="AAAAA", + ) + self.assertIsNotNone(err.exception.args[0]) + + def test_tx_invalid_issuer_is_not_xrp_account(self): + with self.assertRaises(XRPLModelException) as err: + XChainClaim( + account="rHb9CJAWyB4rj91VRWn96DkukG4bwdtyTh", + amount="12345", + destination="AAAAA", + destination_tag=5, + xchain_bridge=XChainBridge( + issuing_chain_door="AAAAA", + issuing_chain_issue=Currency( + currency="USD", issuer="G5h7Dk92LmXqZtP3NvB8YrCfJ0W1AoUE" + ), + locking_chain_door="AAAAA", + locking_chain_issue=Currency( + currency="USD", issuer="G5h7Dk92LmXqZtP3NvB8YrCfJ0W1AoUE" + ), + ), + xchain_claim_id="AAAAA", + ) + self.assertIsNotNone(err.exception.args[0]) + + def test_tx_valid_transaction(self): + tx = XChainClaim( + account="rHb9CJAWyB4rj91VRWn96DkukG4bwdtyTh", + amount="12345", + destination="AAAAA", + destination_tag=5, + xchain_bridge=XChainBridge( + issuing_chain_door="AAAAA", + issuing_chain_issue=Currency( + currency="USD", issuer="rHb9CJAWyB4rj91VRWn96DkukG4bwdtyTh" + ), + locking_chain_door="AAAAA", + locking_chain_issue=Currency( + currency="USD", issuer="rHb9CJAWyB4rj91VRWn96DkukG4bwdtyTh" + ), + ), + xchain_claim_id="AAAAA", + ) + self.assertTrue(tx.is_valid()) diff --git a/xrpl/openapi-codegen/test/transactions/test_xchain_commit.py b/xrpl/openapi-codegen/test/transactions/test_xchain_commit.py new file mode 100644 index 000000000..2b84d9e40 --- /dev/null +++ b/xrpl/openapi-codegen/test/transactions/test_xchain_commit.py @@ -0,0 +1,105 @@ +import unittest + +from xrpl.models.exceptions import XRPLModelException +from xrpl.models.transactions.xchain_commit import Currency +from xrpl.models.transactions.xchain_commit import XChainBridge +from xrpl.models.transactions.xchain_commit import XChainCommit + + +class TestXChainCommit(unittest.TestCase): + def test_tx_invalid_missing_required_param_issuing_chain_door(self): + with self.assertRaises(XRPLModelException) as err: + XChainCommit( + account="rHb9CJAWyB4rj91VRWn96DkukG4bwdtyTh", + amount="12345", + other_chain_destination="AAAAA", + xchain_bridge=XChainBridge( + issuing_chain_issue=Currency( + currency="USD", issuer="rHb9CJAWyB4rj91VRWn96DkukG4bwdtyTh" + ), + locking_chain_door="AAAAA", + locking_chain_issue=Currency( + currency="USD", issuer="rHb9CJAWyB4rj91VRWn96DkukG4bwdtyTh" + ), + ), + xchain_claim_id="AAAAA", + ) + self.assertIsNotNone(err.exception.args[0]) + + def test_tx_invalid_missing_required_param_amount(self): + with self.assertRaises(XRPLModelException) as err: + XChainCommit( + account="rHb9CJAWyB4rj91VRWn96DkukG4bwdtyTh", + other_chain_destination="AAAAA", + xchain_bridge=XChainBridge( + issuing_chain_door="AAAAA", + issuing_chain_issue=Currency( + currency="USD", issuer="rHb9CJAWyB4rj91VRWn96DkukG4bwdtyTh" + ), + locking_chain_door="AAAAA", + locking_chain_issue=Currency( + currency="USD", issuer="rHb9CJAWyB4rj91VRWn96DkukG4bwdtyTh" + ), + ), + xchain_claim_id="AAAAA", + ) + self.assertIsNotNone(err.exception.args[0]) + + def test_tx_invalid_account_is_not_xrp_account(self): + with self.assertRaises(XRPLModelException) as err: + XChainCommit( + account="G5h7Dk92LmXqZtP3NvB8YrCfJ0W1AoUE", + amount="12345", + other_chain_destination="AAAAA", + xchain_bridge=XChainBridge( + issuing_chain_door="AAAAA", + issuing_chain_issue=Currency( + currency="USD", issuer="rHb9CJAWyB4rj91VRWn96DkukG4bwdtyTh" + ), + locking_chain_door="AAAAA", + locking_chain_issue=Currency( + currency="USD", issuer="rHb9CJAWyB4rj91VRWn96DkukG4bwdtyTh" + ), + ), + xchain_claim_id="AAAAA", + ) + self.assertIsNotNone(err.exception.args[0]) + + def test_tx_invalid_issuer_is_not_xrp_account(self): + with self.assertRaises(XRPLModelException) as err: + XChainCommit( + account="rHb9CJAWyB4rj91VRWn96DkukG4bwdtyTh", + amount="12345", + other_chain_destination="AAAAA", + xchain_bridge=XChainBridge( + issuing_chain_door="AAAAA", + issuing_chain_issue=Currency( + currency="USD", issuer="G5h7Dk92LmXqZtP3NvB8YrCfJ0W1AoUE" + ), + locking_chain_door="AAAAA", + locking_chain_issue=Currency( + currency="USD", issuer="G5h7Dk92LmXqZtP3NvB8YrCfJ0W1AoUE" + ), + ), + xchain_claim_id="AAAAA", + ) + self.assertIsNotNone(err.exception.args[0]) + + def test_tx_valid_transaction(self): + tx = XChainCommit( + account="rHb9CJAWyB4rj91VRWn96DkukG4bwdtyTh", + amount="12345", + other_chain_destination="AAAAA", + xchain_bridge=XChainBridge( + issuing_chain_door="AAAAA", + issuing_chain_issue=Currency( + currency="USD", issuer="rHb9CJAWyB4rj91VRWn96DkukG4bwdtyTh" + ), + locking_chain_door="AAAAA", + locking_chain_issue=Currency( + currency="USD", issuer="rHb9CJAWyB4rj91VRWn96DkukG4bwdtyTh" + ), + ), + xchain_claim_id="AAAAA", + ) + self.assertTrue(tx.is_valid()) diff --git a/xrpl/openapi-codegen/test/transactions/test_xchain_create_bridge.py b/xrpl/openapi-codegen/test/transactions/test_xchain_create_bridge.py new file mode 100644 index 000000000..7ae40f1ea --- /dev/null +++ b/xrpl/openapi-codegen/test/transactions/test_xchain_create_bridge.py @@ -0,0 +1,82 @@ +import unittest + +from xrpl.models.exceptions import XRPLModelException +from xrpl.models.transactions.xchain_create_bridge import Currency +from xrpl.models.transactions.xchain_create_bridge import XChainBridge +from xrpl.models.transactions.xchain_create_bridge import XChainCreateBridge + + +class TestXChainCreateBridge(unittest.TestCase): + def test_tx_invalid_missing_required_param_issuing_chain_door(self): + with self.assertRaises(XRPLModelException) as err: + XChainCreateBridge( + account="rHb9CJAWyB4rj91VRWn96DkukG4bwdtyTh", + min_account_create_amount="12345", + signature_reward="12345", + xchain_bridge=XChainBridge( + issuing_chain_issue=Currency( + currency="USD", issuer="rHb9CJAWyB4rj91VRWn96DkukG4bwdtyTh" + ), + locking_chain_door="AAAAA", + locking_chain_issue=Currency( + currency="USD", issuer="rHb9CJAWyB4rj91VRWn96DkukG4bwdtyTh" + ), + ), + ) + self.assertIsNotNone(err.exception.args[0]) + + def test_tx_invalid_account_is_not_xrp_account(self): + with self.assertRaises(XRPLModelException) as err: + XChainCreateBridge( + account="G5h7Dk92LmXqZtP3NvB8YrCfJ0W1AoUE", + min_account_create_amount="12345", + signature_reward="12345", + xchain_bridge=XChainBridge( + issuing_chain_door="AAAAA", + issuing_chain_issue=Currency( + currency="USD", issuer="rHb9CJAWyB4rj91VRWn96DkukG4bwdtyTh" + ), + locking_chain_door="AAAAA", + locking_chain_issue=Currency( + currency="USD", issuer="rHb9CJAWyB4rj91VRWn96DkukG4bwdtyTh" + ), + ), + ) + self.assertIsNotNone(err.exception.args[0]) + + def test_tx_invalid_issuer_is_not_xrp_account(self): + with self.assertRaises(XRPLModelException) as err: + XChainCreateBridge( + account="rHb9CJAWyB4rj91VRWn96DkukG4bwdtyTh", + min_account_create_amount="12345", + signature_reward="12345", + xchain_bridge=XChainBridge( + issuing_chain_door="AAAAA", + issuing_chain_issue=Currency( + currency="USD", issuer="G5h7Dk92LmXqZtP3NvB8YrCfJ0W1AoUE" + ), + locking_chain_door="AAAAA", + locking_chain_issue=Currency( + currency="USD", issuer="G5h7Dk92LmXqZtP3NvB8YrCfJ0W1AoUE" + ), + ), + ) + self.assertIsNotNone(err.exception.args[0]) + + def test_tx_valid_transaction(self): + tx = XChainCreateBridge( + account="rHb9CJAWyB4rj91VRWn96DkukG4bwdtyTh", + min_account_create_amount="12345", + signature_reward="12345", + xchain_bridge=XChainBridge( + issuing_chain_door="AAAAA", + issuing_chain_issue=Currency( + currency="USD", issuer="rHb9CJAWyB4rj91VRWn96DkukG4bwdtyTh" + ), + locking_chain_door="AAAAA", + locking_chain_issue=Currency( + currency="USD", issuer="rHb9CJAWyB4rj91VRWn96DkukG4bwdtyTh" + ), + ), + ) + self.assertTrue(tx.is_valid()) diff --git a/xrpl/openapi-codegen/test/transactions/test_xchain_modify_bridge.py b/xrpl/openapi-codegen/test/transactions/test_xchain_modify_bridge.py new file mode 100644 index 000000000..45e94c393 --- /dev/null +++ b/xrpl/openapi-codegen/test/transactions/test_xchain_modify_bridge.py @@ -0,0 +1,97 @@ +import unittest + +from xrpl.models.exceptions import XRPLModelException +from xrpl.models.transactions.xchain_modify_bridge import Currency +from xrpl.models.transactions.xchain_modify_bridge import XChainBridge +from xrpl.models.transactions.xchain_modify_bridge import XChainModifyBridge +from xrpl.models.transactions.xchain_modify_bridge import XChainModifyBridgeFlag + + +class TestXChainModifyBridge(unittest.TestCase): + def test_tx_invalid_missing_required_param_xchain_bridge(self): + with self.assertRaises(XRPLModelException) as err: + XChainModifyBridge( + account="rHb9CJAWyB4rj91VRWn96DkukG4bwdtyTh", + flags=XChainModifyBridgeFlag.TF_CLEAR_ACCOUNT_CREATE_AMOUNT, + min_account_create_amount="12345", + signature_reward="12345", + ) + self.assertIsNotNone(err.exception.args[0]) + + def test_tx_invalid_missing_required_param_issuing_chain_door(self): + with self.assertRaises(XRPLModelException) as err: + XChainModifyBridge( + account="rHb9CJAWyB4rj91VRWn96DkukG4bwdtyTh", + flags=XChainModifyBridgeFlag.TF_CLEAR_ACCOUNT_CREATE_AMOUNT, + min_account_create_amount="12345", + signature_reward="12345", + xchain_bridge=XChainBridge( + issuing_chain_issue=Currency( + currency="USD", issuer="rHb9CJAWyB4rj91VRWn96DkukG4bwdtyTh" + ), + locking_chain_door="AAAAA", + locking_chain_issue=Currency( + currency="USD", issuer="rHb9CJAWyB4rj91VRWn96DkukG4bwdtyTh" + ), + ), + ) + self.assertIsNotNone(err.exception.args[0]) + + def test_tx_invalid_account_is_not_xrp_account(self): + with self.assertRaises(XRPLModelException) as err: + XChainModifyBridge( + account="G5h7Dk92LmXqZtP3NvB8YrCfJ0W1AoUE", + flags=XChainModifyBridgeFlag.TF_CLEAR_ACCOUNT_CREATE_AMOUNT, + min_account_create_amount="12345", + signature_reward="12345", + xchain_bridge=XChainBridge( + issuing_chain_door="AAAAA", + issuing_chain_issue=Currency( + currency="USD", issuer="rHb9CJAWyB4rj91VRWn96DkukG4bwdtyTh" + ), + locking_chain_door="AAAAA", + locking_chain_issue=Currency( + currency="USD", issuer="rHb9CJAWyB4rj91VRWn96DkukG4bwdtyTh" + ), + ), + ) + self.assertIsNotNone(err.exception.args[0]) + + def test_tx_invalid_issuer_is_not_xrp_account(self): + with self.assertRaises(XRPLModelException) as err: + XChainModifyBridge( + account="rHb9CJAWyB4rj91VRWn96DkukG4bwdtyTh", + flags=XChainModifyBridgeFlag.TF_CLEAR_ACCOUNT_CREATE_AMOUNT, + min_account_create_amount="12345", + signature_reward="12345", + xchain_bridge=XChainBridge( + issuing_chain_door="AAAAA", + issuing_chain_issue=Currency( + currency="USD", issuer="G5h7Dk92LmXqZtP3NvB8YrCfJ0W1AoUE" + ), + locking_chain_door="AAAAA", + locking_chain_issue=Currency( + currency="USD", issuer="G5h7Dk92LmXqZtP3NvB8YrCfJ0W1AoUE" + ), + ), + ) + self.assertIsNotNone(err.exception.args[0]) + + def test_tx_valid_transaction(self): + tx = XChainModifyBridge( + account="rHb9CJAWyB4rj91VRWn96DkukG4bwdtyTh", + flags=XChainModifyBridgeFlag.TF_CLEAR_ACCOUNT_CREATE_AMOUNT, + min_account_create_amount="12345", + signature_reward="12345", + xchain_bridge=XChainBridge( + issuing_chain_door="AAAAA", + issuing_chain_issue=Currency( + currency="USD", issuer="rHb9CJAWyB4rj91VRWn96DkukG4bwdtyTh" + ), + locking_chain_door="AAAAA", + locking_chain_issue=Currency( + currency="USD", issuer="rHb9CJAWyB4rj91VRWn96DkukG4bwdtyTh" + ), + ), + ) + self.assertTrue(tx.is_valid())