diff --git a/CHANGELOG.md b/CHANGELOG.md index b208b01..cf8ab2d 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,15 @@ # CDP Python SDK Changelog +## [0.16.0] - 2025-01-28 + +### Added + +- Add E2E test for gasless transfers `Wallet.createTransfer({..., gasless: true})` + +### Fixed + +- Fixed a bug where non-checksummed asset IDs were throwing an error. + ## [0.15.0] - 2025-01-17 ### Added diff --git a/cdp/__version__.py b/cdp/__version__.py index 9da2f8f..5a313cc 100644 --- a/cdp/__version__.py +++ b/cdp/__version__.py @@ -1 +1 @@ -__version__ = "0.15.0" +__version__ = "0.16.0" diff --git a/cdp/asset.py b/cdp/asset.py index d03a35d..3ec3073 100644 --- a/cdp/asset.py +++ b/cdp/asset.py @@ -41,14 +41,18 @@ def from_model(cls, model: AssetModel, asset_id: str | None = None) -> "Asset": """ decimals = model.decimals - if asset_id and asset_id != model.asset_id: - match asset_id: - case "gwei": - decimals = GWEI_DECIMALS - case "wei": - decimals = 0 - case _: - raise ValueError(f"Unsupported asset ID: {asset_id}") + if asset_id and model.asset_id: + normalized_asset_id = asset_id.lower() + normalized_model_asset_id = model.asset_id.lower() + + if normalized_asset_id != normalized_model_asset_id: + match normalized_asset_id: + case "gwei": + decimals = GWEI_DECIMALS + case "wei": + decimals = 0 + case _: + raise ValueError(f"Unsupported asset ID: {asset_id}") return cls( network_id=model.network_id, diff --git a/docs/conf.py b/docs/conf.py index 98b4802..af613b0 100644 --- a/docs/conf.py +++ b/docs/conf.py @@ -14,7 +14,7 @@ project = 'CDP SDK' author = 'Coinbase Developer Platform' -release = '0.15.0' +release = '0.16.0' # -- General configuration --------------------------------------------------- # https://www.sphinx-doc.org/en/master/usage/configuration.html#general-configuration diff --git a/pyproject.toml b/pyproject.toml index 05d0d4b..220674a 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -1,6 +1,6 @@ [tool.poetry] name = "cdp-sdk" -version = "0.15.0" +version = "0.16.0" description = "CDP Python SDK" authors = ["John Peterson "] license = "LICENSE.md" diff --git a/tests/test_asset.py b/tests/test_asset.py index 2cea01b..b9ed48a 100644 --- a/tests/test_asset.py +++ b/tests/test_asset.py @@ -52,6 +52,22 @@ def test_asset_from_model_with_invalid_asset_id(asset_model_factory): with pytest.raises(ValueError, match="Unsupported asset ID: invalid"): Asset.from_model(asset_model, asset_id="invalid") +def test_asset_from_model_with_non_checksummed_address(asset_model_factory): + """Test asset from model with non-checksummed address.""" + asset_model = asset_model_factory(asset_id="0x8309fbdF021eDF768DC13195741940ba544dEa98", decimals=18) + + asset = Asset.from_model(asset_model, asset_id="0x8309fbdf021edf768dc13195741940ba544dea98") + assert asset.asset_id == "0x8309fbdf021edf768dc13195741940ba544dea98" + assert asset.decimals == 18 + +def test_asset_from_model_with_checksummed_address(asset_model_factory): + """Test asset from model with checksummed address.""" + asset_model = asset_model_factory(asset_id="0x8309fbdF021eDF768DC13195741940ba544dEa98", decimals=18) + + asset = Asset.from_model(asset_model, asset_id="0x8309fbdF021eDF768DC13195741940ba544dEa98") + assert asset.asset_id == "0x8309fbdF021eDF768DC13195741940ba544dEa98" + assert asset.decimals == 18 + @patch("cdp.Cdp.api_clients") def test_asset_fetch(mock_api_clients, asset_model_factory): diff --git a/tests/test_e2e.py b/tests/test_e2e.py index ab74f88..04ba70a 100644 --- a/tests/test_e2e.py +++ b/tests/test_e2e.py @@ -170,3 +170,27 @@ def test_historical_balances(imported_wallet): balances = list(imported_wallet.default_address.historical_balances("eth")) assert balances assert all(balance.amount > 0 for balance in balances) + + +@pytest.mark.skip(reason="Gasless transfers have unpredictable latency") +def test_gasless_transfer(imported_wallet): + """Test gasless transfer.""" + destination_wallet = Wallet.create() + + initial_source_balance = imported_wallet.balance("usdc") + initial_dest_balance = destination_wallet.balance("usdc") + + transfer = imported_wallet.transfer( + amount=Decimal("0.000001"), asset_id="usdc", gasless=True, destination=destination_wallet + ).wait() + + time.sleep(20) + + assert transfer.status.value == "complete" + + final_source_balance = imported_wallet.balance("usdc") + final_dest_balance = destination_wallet.balance("usdc") + + assert final_source_balance < initial_source_balance + assert final_dest_balance > initial_dest_balance + assert final_dest_balance == Decimal("0.000001")