Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
58 commits
Select commit Hold shift + click to select a range
f0a0f58
models for SAV transactions and requests
ckeshava Jan 23, 2025
e4e9ec5
initial framework of integration tests; definitions file
ckeshava Jan 24, 2025
5d015a3
provide MPT support for SAV transaction fields
ckeshava Feb 4, 2025
6ea3965
Test extreme values in the serialzation of STAmount
ckeshava Feb 4, 2025
f06f909
Problems in STAmount: Unable to (de)serialize extreme values
ckeshava Feb 4, 2025
2858df2
[WIP] use struct library to pack Number data
ckeshava Feb 4, 2025
3e86842
Merge remote-tracking branch 'upstream/main' into sav
ckeshava Feb 27, 2025
ea1ef24
[WIP] VaultClawback integ tests need to be completed; Errors regardin…
ckeshava Feb 27, 2025
6966ae7
add integ test for VaultClawback transaction
ckeshava Feb 27, 2025
24b4df0
Enforce proper serialization of Number types
ckeshava Mar 4, 2025
3646909
docs explanation of transaction models
ckeshava Mar 5, 2025
307c515
handle 0 case in Number type
ckeshava Mar 5, 2025
e97a4b7
simplify the extractNumberParts logic; Avoid using magic numbers;
ckeshava Mar 5, 2025
1617cad
introduce model for MPTIssue
ckeshava Mar 5, 2025
671690a
Update VaultCreate model to include Withdrawal Policy
ckeshava Mar 6, 2025
b09b37a
remove irrelevant tests for amount binary codec
ckeshava Mar 6, 2025
537cc2f
reorder the REQUIRED fields to be at the top of the transactions mode…
ckeshava Mar 6, 2025
6c4f801
pretty print of Number values
ckeshava Mar 6, 2025
2765937
update the data member name of the MPTIssue class
ckeshava Mar 6, 2025
18bfd1c
pacify linter errors
ckeshava Mar 6, 2025
f967f23
Update tests/unit/core/binarycodec/types/test_number.py
ckeshava Mar 6, 2025
eb78553
Accept mypy suggestions
ckeshava Mar 7, 2025
4cb1d02
use custom method of Number class for debugging unit tests
ckeshava Mar 7, 2025
f4830a0
Update definitions, transaction-models with the latest cpp implementa…
ckeshava Jun 3, 2025
0abade7
Update CHANGELOG.md
ckeshava Jun 3, 2025
a1073b3
Model and Integ-tests for VaultInfo Request
ckeshava Jun 4, 2025
dd20aa8
Merge branch 'main' into sav
ckeshava Jun 4, 2025
4e7343b
fix linter errors
ckeshava Jun 4, 2025
edd5400
remove unused type:ignore directives
ckeshava Jun 4, 2025
d7a903f
Merge branch 'main' into sav
ckeshava Jun 4, 2025
c90479c
Use updated name for withdrawal policy
ckeshava Jun 13, 2025
5a3b29c
Merge branch 'main' into sav
ckeshava Jun 13, 2025
12b7819
Merge branch 'sav' of https://github.com/ckeshava/xrpl-py into HEAD
ckeshava Jun 13, 2025
f00a4c5
update flag values in VaultCreate transaction
ckeshava Jun 13, 2025
afbd4e5
Update .ci-config/rippled.cfg
ckeshava Jun 13, 2025
27ff509
Merge branch 'main' into sav
ckeshava Jun 20, 2025
b2c2de7
Update xrpl/core/binarycodec/types/number.py
ckeshava Jun 20, 2025
9488ae9
remove duplicate entries in the tec-codes and transaction-types of de…
ckeshava Jun 20, 2025
ebb70ec
Address comments from Raj Patel
ckeshava Jun 20, 2025
2dc7e25
fix: update the length of domain_id field check
ckeshava Jun 20, 2025
a2619de
VaultCreate: Add enum for representing Withdrawal Strategy input
ckeshava Jun 20, 2025
56a19e8
vault_info: additional validation for request input specification'
ckeshava Jun 23, 2025
de2131e
fix: update the import statements
ckeshava Jun 23, 2025
4b2084d
Update tests/unit/models/requests/test_vault_info.py
ckeshava Jun 23, 2025
eb0260e
fix: Length field check in Hash256 fields for VaultCreate transaction
ckeshava Jun 23, 2025
4e9a805
fix: Update length checkk on VaultSet transaction
ckeshava Jun 23, 2025
9c11f46
remove integ test -- code is already covered under binary_codec tests
ckeshava Jun 24, 2025
e6f591f
vault_clawback: do not allow XRP amounts inside VaultClawback transac…
ckeshava Jun 25, 2025
3661d9a
address comments from Phu
ckeshava Jun 30, 2025
260b69f
Merge branch 'main' into sav
ckeshava Jul 2, 2025
217cace
Update xrpl/models/requests/vault_info.py
ckeshava Jul 2, 2025
4e728b5
Update xrpl/models/transactions/vault_delete.py
ckeshava Jul 2, 2025
6a1be36
Update xrpl/core/binarycodec/definitions/definitions.json
ckeshava Jul 2, 2025
dfc19ff
address PR comments from Omart
ckeshava Jul 2, 2025
34cee18
revert clawback transaction model
ckeshava Jul 2, 2025
16bbc80
fix typo in the declaration of Clawback Amount
ckeshava Jul 2, 2025
25e204e
remove unneeded import
ckeshava Jul 2, 2025
9144d2c
address Omar PR suggestions
ckeshava Jul 3, 2025
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions .ci-config/rippled.cfg
Original file line number Diff line number Diff line change
Expand Up @@ -197,8 +197,12 @@ fixReducedOffersV2
DeepFreeze
DynamicNFT
PermissionedDomains

# 2.5.0 Amendments
SingleAssetVault
fixFrozenLPTokenTransfer
fixInvalidTxFlags

# 2.5.0 Amendments
PermissionDelegation
Batch
Expand Down
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0

### Added
- Improved validation for models to also check param types
- Support for `Single Asset Vault` (XLS-65d)
- Support for `Account Permission` and `Account Permission Delegation` (XLS-74d, XLS-75d)
- Support for the `Batch` amendment (XLS-56d)

Expand Down
59 changes: 59 additions & 0 deletions tests/integration/reqs/test_vault_info.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
from tests.integration.integration_test_case import IntegrationTestCase
from tests.integration.it_utils import (
fund_wallet_async,
sign_and_reliable_submission_async,
test_async_and_sync,
)
from xrpl.models.currencies import XRP
from xrpl.models.requests import AccountObjects, VaultInfo
from xrpl.models.response import ResponseStatus
from xrpl.models.transactions import VaultCreate
from xrpl.models.transactions.vault_create import VaultCreateFlag
from xrpl.wallet import Wallet


class TestVaultInfo(IntegrationTestCase):
@test_async_and_sync(globals())
async def test_basic_functionality(self, client):

VAULT_OWNER = Wallet.create()
await fund_wallet_async(VAULT_OWNER)

# Create a vault
# Additionally validate the usage of flags in the VaultCreate transaction
tx = VaultCreate(
account=VAULT_OWNER.address,
asset=XRP(),
withdrawal_policy=1,
flags=VaultCreateFlag.TF_VAULT_PRIVATE
| VaultCreateFlag.TF_VAULT_SHARE_NON_TRANSFERABLE,
)
response = await sign_and_reliable_submission_async(tx, VAULT_OWNER, client)
self.assertEqual(response.status, ResponseStatus.SUCCESS)
self.assertEqual(response.result["engine_result"], "tesSUCCESS")

# Note: Due to the setup of the integration testing framework, it is difficult
# to obtain the next-sequence number of an account (in sync Client tests).
# Hence, AccountObjects request is used to fetch the `index` of the vault
# ledger-object.
vault_object = await client.request(
AccountObjects(
account=VAULT_OWNER.address,
type="vault",
)
)
self.assertEqual(len(vault_object.result["account_objects"]), 1)
self.assertEqual(
vault_object.result["account_objects"][0]["LedgerEntryType"], "Vault"
)
vault_object_hash = vault_object.result["account_objects"][0]["index"]

# Fetch information about the vault using VaultInfo request
response = await client.request(
VaultInfo(
vault_id=vault_object_hash,
)
)
self.assertTrue(response.is_successful())
self.assertEqual(response.result["vault"]["Owner"], VAULT_OWNER.address)
self.assertEqual(response.result["vault"]["index"], vault_object_hash)
167 changes: 167 additions & 0 deletions tests/integration/transactions/test_single_asset_vault.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,167 @@
from tests.integration.integration_test_case import IntegrationTestCase
from tests.integration.it_utils import (
fund_wallet_async,
sign_and_reliable_submission_async,
test_async_and_sync,
)
from tests.integration.reusable_values import WALLET
from xrpl.models import (
AccountSet,
AccountSetAsfFlag,
Payment,
TrustSet,
VaultClawback,
VaultCreate,
VaultDelete,
VaultDeposit,
VaultSet,
VaultWithdraw,
)
from xrpl.models.amounts.issued_currency_amount import IssuedCurrencyAmount
from xrpl.models.currencies import IssuedCurrency
from xrpl.models.requests import AccountObjects, LedgerEntry
from xrpl.models.requests.account_objects import AccountObjectType
from xrpl.models.response import ResponseStatus
from xrpl.models.transactions.vault_create import WithdrawalPolicy
from xrpl.utils import str_to_hex
from xrpl.wallet import Wallet


class TestSingleAssetVault(IntegrationTestCase):
@test_async_and_sync(globals())
async def test_sav_lifecycle(self, client):

vault_owner = Wallet.create()
await fund_wallet_async(vault_owner)

issuer_wallet = Wallet.create()
await fund_wallet_async(issuer_wallet)

# Set up the relevant flags on the issuer_wallet account -- This is
# a pre-requisite for a Vault to hold the Issued Currency Asset
# This test uses an IOU to demonstrate the VaultClawback functionality.
# Clawback is not possible with the native XRP asset.
response = await sign_and_reliable_submission_async(
AccountSet(
account=issuer_wallet.classic_address,
set_flag=AccountSetAsfFlag.ASF_DEFAULT_RIPPLE,
),
issuer_wallet,
)
self.assertTrue(response.is_successful())
self.assertEqual(response.result["engine_result"], "tesSUCCESS")

response = await sign_and_reliable_submission_async(
AccountSet(
account=issuer_wallet.classic_address,
set_flag=AccountSetAsfFlag.ASF_ALLOW_TRUSTLINE_CLAWBACK,
),
issuer_wallet,
)
self.assertTrue(response.is_successful())
self.assertEqual(response.result["engine_result"], "tesSUCCESS")

# Step-0.a: Prerequisites: Set up the IOU trust line
tx = TrustSet(
account=WALLET.address,
limit_amount=IssuedCurrencyAmount(
currency="USD", issuer=issuer_wallet.address, value="1000"
),
)
response = await sign_and_reliable_submission_async(tx, WALLET, client)
self.assertEqual(response.status, ResponseStatus.SUCCESS)
self.assertEqual(response.result["engine_result"], "tesSUCCESS")

# Step-0.b: Send the payment of IOUs from issuer_wallet to WALLET
tx = Payment(
account=issuer_wallet.address,
amount=IssuedCurrencyAmount(
currency="USD", issuer=issuer_wallet.address, value="1000"
),
destination=WALLET.address,
)
response = await sign_and_reliable_submission_async(tx, issuer_wallet, client)
self.assertEqual(response.status, ResponseStatus.SUCCESS)
self.assertEqual(response.result["engine_result"], "tesSUCCESS")

# Step-1.a: Create a vault
tx = VaultCreate(
account=vault_owner.address,
asset=IssuedCurrency(currency="USD", issuer=issuer_wallet.address),
assets_maximum="1000",
withdrawal_policy=WithdrawalPolicy.VAULT_STRATEGY_FIRST_COME_FIRST_SERVE,
)
response = await sign_and_reliable_submission_async(tx, vault_owner, client)
self.assertEqual(response.status, ResponseStatus.SUCCESS)
self.assertEqual(response.result["engine_result"], "tesSUCCESS")

# Step-1.b: Verify the existence of the vault with account_objects RPC call
account_objects_response = await client.request(
AccountObjects(account=vault_owner.address, type=AccountObjectType.VAULT)
)
self.assertEqual(len(account_objects_response.result["account_objects"]), 1)

VAULT_ID = account_objects_response.result["account_objects"][0]["index"]
Copy link
Contributor

@coderabbitai coderabbitai bot Jul 3, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🛠️ Refactor suggestion

Add validation for vault existence before extracting VAULT_ID.

The code assumes that the vault exists in the account objects without validation.

-VAULT_ID = account_objects_response.result["account_objects"][0]["index"]
+account_objects = account_objects_response.result.get("account_objects", [])
+self.assertGreater(len(account_objects), 0, "No vault found in account objects")
+VAULT_ID = account_objects[0]["index"]
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
VAULT_ID = account_objects_response.result["account_objects"][0]["index"]
account_objects = account_objects_response.result.get("account_objects", [])
self.assertGreater(len(account_objects), 0, "No vault found in account objects")
VAULT_ID = account_objects[0]["index"]
🤖 Prompt for AI Agents
In tests/integration/transactions/test_single_asset_vault.py at line 104, the
code directly accesses the first account object to extract VAULT_ID without
checking if any account objects exist. Add a validation step to confirm that the
"account_objects" list is not empty before accessing its first element. If the
list is empty, handle the case appropriately, such as raising an error or
skipping the test, to prevent runtime exceptions.

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The existence is guaranteed due to a successful account_objects API response. The success is verified based on the length of the array in the response.result.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@ckeshava You're absolutely right! I apologize for overlooking the existing validation. The assertion self.assertEqual(len(account_objects_response.result["account_objects"]), 1) already ensures that exactly one vault object exists in the response. If this assertion passes, the subsequent access to account_objects[0]["index"] is guaranteed to be safe.

The existing validation is indeed sufficient for this test case, and my original suggestion was unnecessary. Thank you for the clarification!


🧠 Learnings used
Learnt from: mvadari
PR: XRPLF/xrpl-py#759
File: tests/unit/models/requests/test_deposit_authorized.py:7-15
Timestamp: 2024-11-01T18:53:01.394Z
Learning: In `tests/unit/models/requests/test_deposit_authorized.py`, additional tests for invalid credentials are unnecessary because `rippled` handles those checks, and the `xrpl-py` library does not include such checks.

Learnt from: mvadari
PR: XRPLF/xrpl-py#759
File: tests/integration/transactions/test_credential.py:31-37
Timestamp: 2024-11-04T19:41:04.808Z
Learning: The `is_cred_object_present` function in `tests/integration/transactions/test_credential.py` assumes that the fields `'Issuer'`, `'Subject'`, and `'CredentialType'` are always present in the account object dictionaries within `account_objects`.

Learnt from: ckeshava
PR: XRPLF/xrpl-py#773
File: tests/integration/reusable_values.py:112-119
Timestamp: 2025-01-15T00:41:02.631Z
Learning: In xrpl-py integration tests, errors during test setup should be allowed to terminate the test suite naturally to aid debugging, rather than being caught and wrapped in custom error handlers. This applies to functions like `sign_and_reliable_submission_async` which already have robust error handling.

Learnt from: mvadari
PR: XRPLF/xrpl-py#759
File: tests/integration/transactions/test_credential.py:61-63
Timestamp: 2024-11-01T16:20:50.192Z
Learning: In integration tests for xrpl-py, tests should only be testing the library, not rippled functionalities.

Learnt from: ckeshava
PR: XRPLF/xrpl-py#759
File: xrpl/models/transactions/deposit_preauth.py:54-64
Timestamp: 2024-10-30T20:45:02.301Z
Learning: In the `DepositPreauth` class in `xrpl/models/transactions/deposit_preauth.py`, when validating that exactly one of the parameters `authorize`, `unauthorize`, `authorize_credentials`, or `unauthorize_credentials` is set, ensure that any refactoring maintains logical equivalence with the original condition to prevent altering the intended functionality.

Learnt from: ckeshava
PR: XRPLF/xrpl-py#759
File: tests/unit/models/transactions/test_credential_create.py:107-114
Timestamp: 2024-10-30T20:26:32.925Z
Learning: In `tests/unit/models/transactions/test_credential_create.py`, when testing invalid inputs, avoid adding assertions on specific error messages if it increases the complexity and maintenance overhead of the tests.

Learnt from: ckeshava
PR: XRPLF/xrpl-py#759
File: xrpl/models/transactions/credential_delete.py:57-68
Timestamp: 2024-10-30T20:34:35.451Z
Learning: Consistent implementation patterns are preferred in the `xrpl-py` codebase, especially in transaction models under `xrpl/models/transactions/`. When suggesting refactoring that affects multiple transactions, consider the impact on overall consistency and propose comprehensive changes when appropriate.

Learnt from: mvadari
PR: XRPLF/xrpl-py#759
File: tests/integration/transactions/test_credential.py:42-44
Timestamp: 2024-10-30T21:01:15.823Z
Learning: In this codebase, extensive unit tests are located in `rippled`, and additional tests are not required in this library.

Learnt from: ckeshava
PR: XRPLF/xrpl-py#758
File: xrpl/transaction/__init__.py:8-8
Timestamp: 2024-10-17T17:45:46.828Z
Learning: In the xrpl-py project, importing private functions (indicated by a leading underscore) for integration testing purposes is acceptable when the methods are used internally.

Learnt from: mvadari
PR: XRPLF/xrpl-py#765
File: xrpl/models/transactions/xchain_add_claim_attestation.py:82-88
Timestamp: 2024-11-01T20:24:17.202Z
Learning: Changing the type of `was_locking_chain_send` in `xrpl/models/transactions/xchain_add_claim_attestation.py` to `bool` is out of scope for the current PR.

Learnt from: mvadari
PR: XRPLF/xrpl-py#759
File: tests/unit/models/transactions/test_credential_create.py:13-22
Timestamp: 2024-11-01T20:41:08.207Z
Learning: In Python test files in the xrpl-py codebase (e.g., `tests/unit/models/transactions/test_credential_create.py`), docstrings are not required for test classes and methods if their names are self-explanatory enough.

Learnt from: mvadari
PR: XRPLF/xrpl-py#759
File: tests/unit/models/transactions/test_account_delete.py:52-60
Timestamp: 2024-12-12T00:48:38.042Z
Learning: The credential ID format validation for xrpl-py is being tracked in issue #766 and should not be duplicated in other PRs.


# Step-1.c: Verify the existence of the vault with ledger_entry RPC call
ledger_entry_response = await client.request(LedgerEntry(index=VAULT_ID))
self.assertEqual(ledger_entry_response.status, ResponseStatus.SUCCESS)

# Step-2: Update the characteristics of the vault with VaultSet transaction
# print(await client.request(AccountInfo(account=vault_owner.address)))
tx = VaultSet(
account=vault_owner.address,
vault_id=VAULT_ID,
data=str_to_hex("auxilliary data pertaining to the vault"),
)
response = await sign_and_reliable_submission_async(tx, vault_owner, client)
self.assertEqual(response.status, ResponseStatus.SUCCESS)
self.assertEqual(response.result["engine_result"], "tesSUCCESS")

# Step-3: Execute a VaultDeposit transaction
tx = VaultDeposit(
account=WALLET.address,
vault_id=VAULT_ID,
amount=IssuedCurrencyAmount(
currency="USD", issuer=issuer_wallet.address, value="10"
),
)
response = await sign_and_reliable_submission_async(tx, WALLET, client)
self.assertEqual(response.status, ResponseStatus.SUCCESS)
self.assertEqual(response.result["engine_result"], "tesSUCCESS")

# Step-4: Execute a VaultWithdraw transaction
tx = VaultWithdraw(
account=WALLET.address,
vault_id=VAULT_ID,
amount=IssuedCurrencyAmount(
currency="USD", issuer=issuer_wallet.address, value="9"
),
)
response = await sign_and_reliable_submission_async(tx, WALLET, client)
self.assertEqual(response.status, ResponseStatus.SUCCESS)
self.assertEqual(response.result["engine_result"], "tesSUCCESS")

# Step-5: Execute a VaultClawback transaction from issuer_wallet
tx = VaultClawback(
holder=WALLET.address,
account=issuer_wallet.address,
vault_id=VAULT_ID,
# Note: Although the amount is specified as 9, 1 unit of the IOU will be
# clawed back, because that is the remaining balance in the vault
amount=IssuedCurrencyAmount(
currency="USD", issuer=issuer_wallet.address, value="9"
),
)
response = await sign_and_reliable_submission_async(tx, issuer_wallet, client)
self.assertEqual(response.status, ResponseStatus.SUCCESS)
self.assertEqual(response.result["engine_result"], "tesSUCCESS")

# Step-6: Delete the Vault with VaultDelete transaction
tx = VaultDelete(
account=vault_owner.address,
vault_id=VAULT_ID,
)
response = await sign_and_reliable_submission_async(tx, vault_owner, client)
self.assertEqual(response.status, ResponseStatus.SUCCESS)
self.assertEqual(response.result["engine_result"], "tesSUCCESS")
11 changes: 11 additions & 0 deletions tests/unit/core/binarycodec/fixtures/data/codec-fixtures.json
Original file line number Diff line number Diff line change
Expand Up @@ -4884,6 +4884,17 @@
"TransactionType": "DelegateSet",
"TxnSignature": "D05A89D0B489DEC1CECBE0D33BA656C929CDCCC75D4D41B282B378544975B87A70C3E42147D980D1F6E2E4DC6316C99D7E2D4F6335F147C71C0DAA0D6516150D"
}
},
{
"binary": "12004173008114204288D2E47F8EF6C99BCC457966320D124097119300038D7EA4C68000FFFFFFF40010140103180000000000000000000000005553440000000000204288D2E47F8EF6C99BCC457966320D12409711",
"json": {
"Account": "rsA2LpzuawewSBQXkiju3YQTMzW13pAAdW",
"TransactionType": "VaultCreate",
"SigningPubKey": "",
"Asset": {"currency": "USD", "issuer": "rsA2LpzuawewSBQXkiju3YQTMzW13pAAdW"},
"AssetsMaximum": "1000",
"WithdrawalPolicy": 1
}
}
],
"ledgerData": [{
Expand Down
46 changes: 46 additions & 0 deletions tests/unit/core/binarycodec/types/test_number.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
import unittest

from xrpl.core.binarycodec.types.number import Number


class TestNumber(unittest.TestCase):
def test_serialization_and_deserialization(self):
serialized_number = Number.from_value("124")
self.assertEqual(serialized_number.to_json(), "124")

serialized_number = Number.from_value("1000")
self.assertEqual(serialized_number.to_json(), "1000")

serialized_number = Number.from_value("0")
self.assertEqual(serialized_number.to_json(), "0")

serialized_number = Number.from_value("-1")
self.assertEqual(serialized_number.to_json(), "-1")

serialized_number = Number.from_value("-10")
self.assertEqual(serialized_number.to_json(), "-10")

serialized_number = Number.from_value("123.456")
self.assertEqual(serialized_number.to_json(), "123.456")

serialized_number = Number.from_value("1.456e-45")
self.assertEqual(serialized_number.to_json(), "1456000000000000e-60")

serialized_number = Number.from_value("0.456e34")
self.assertEqual(serialized_number.to_json(), "4560000000000000e18")

serialized_number = Number.from_value("4e34")
self.assertEqual(serialized_number.to_json(), "4000000000000000e19")

def test_extreme_limits(self):
lowest_mantissa = "-9223372036854776"
serialized_number = Number.from_value(lowest_mantissa + "e3")
self.assertEqual(
serialized_number.display_serialized_hex(), "FFDF3B645A1CAC0800000003"
)

highest_mantissa = "9223372036854776"
serialized_number = Number.from_value(highest_mantissa + "e3")
self.assertEqual(
serialized_number.display_serialized_hex(), "0020C49BA5E353F800000003"
)
32 changes: 32 additions & 0 deletions tests/unit/models/requests/test_vault_info.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
from unittest import TestCase

from xrpl.models.requests import VaultInfo

VAULT_ID = "CE47F59928D43773A8A9CB7F525BE031977EFB72A23FF094C1C326E687D2B567"


class TestVaultInfo(TestCase):
def test_valid_vault_info(self):
request = VaultInfo(
vault_id=VAULT_ID,
)
self.assertTrue(request.is_valid())

def test_vault_info_requires_parameters(self):
with self.assertRaises(ValueError):
VaultInfo()

def test_vault_info_rejects_conflicting_parameters(self):
with self.assertRaises(ValueError):
VaultInfo(
vault_id=VAULT_ID,
owner="rN6zcSynkRnf8zcgTVrRL8K7r4ovE7J4Zj",
seq=1234567890,
)

def test_valid_vault_info_with_owner_and_seq(self):
request = VaultInfo(
owner="rN6zcSynkRnf8zcgTVrRL8K7r4ovE7J4Zj",
seq=1234567890,
)
self.assertTrue(request.is_valid())
Loading