Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
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
7 changes: 7 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,12 @@
# CDP Python SDK Changelog

## Unreleased

## [0.19.0] - 2025-02-21

### Added
- Ability to create a SmartWallet and send a user operation.

## [0.18.1] - 2025-02-13

## Fixed
Expand Down
12 changes: 12 additions & 0 deletions cdp/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,16 +5,20 @@
from cdp.balance_map import BalanceMap
from cdp.cdp import Cdp
from cdp.contract_invocation import ContractInvocation
from cdp.evm_call_types import EncodedCall, FunctionCall
from cdp.external_address import ExternalAddress
from cdp.faucet_transaction import FaucetTransaction
from cdp.hash_utils import hash_message, hash_typed_data_message
from cdp.mnemonic_seed_phrase import MnemonicSeedPhrase
from cdp.network import Network, SupportedChainId
from cdp.payload_signature import PayloadSignature
from cdp.smart_contract import SmartContract
from cdp.smart_wallet import SmartWallet, to_smart_wallet
from cdp.sponsored_send import SponsoredSend
from cdp.trade import Trade
from cdp.transaction import Transaction
from cdp.transfer import Transfer
from cdp.user_operation import UserOperation
from cdp.wallet import Wallet
from cdp.wallet_address import WalletAddress
from cdp.wallet_data import WalletData
Expand All @@ -40,7 +44,15 @@
"WalletAddress",
"WalletData",
"Webhook",
"to_smart_wallet",
"SmartWallet",
"__version__",
"hash_message",
"hash_typed_data_message",
"Network",
"SupportedChainId",
"EncodedCall",
"FunctionCall",
"UserOperation",
"Network",
]
2 changes: 1 addition & 1 deletion cdp/__version__.py
Original file line number Diff line number Diff line change
@@ -1 +1 @@
__version__ = "0.18.1"
__version__ = "0.19.0"
18 changes: 18 additions & 0 deletions cdp/api_clients.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
from cdp.client.api.fund_api import FundApi
from cdp.client.api.networks_api import NetworksApi
from cdp.client.api.smart_contracts_api import SmartContractsApi
from cdp.client.api.smart_wallets_api import SmartWalletsApi
from cdp.client.api.trades_api import TradesApi
from cdp.client.api.transaction_history_api import TransactionHistoryApi
from cdp.client.api.transfers_api import TransfersApi
Expand All @@ -24,6 +25,7 @@ class ApiClients:
Attributes:
_cdp_client (CdpApiClient): The CDP API client used to initialize individual API clients.
_wallets (Optional[WalletsApi]): The WalletsApi client instance.
_smart_wallets (Optional[SmartWalletsApi]): The SmartWalletsApi client instance.
_webhooks (Optional[WebhooksApi]): The WebhooksApi client instance.
_addresses (Optional[AddressesApi]): The AddressesApi client instance.
_external_addresses (Optional[ExternalAddressesApi]): The ExternalAddressesApi client instance.
Expand All @@ -44,6 +46,7 @@ def __init__(self, cdp_client: CdpApiClient) -> None:
"""
self._cdp_client: CdpApiClient = cdp_client
self._wallets: WalletsApi | None = None
self._smart_wallets: SmartWalletsApi | None = None
self._webhooks: WebhooksApi | None = None
self._addresses: AddressesApi | None = None
self._external_addresses: ExternalAddressesApi | None = None
Expand Down Expand Up @@ -73,6 +76,21 @@ def wallets(self) -> WalletsApi:
self._wallets = WalletsApi(api_client=self._cdp_client)
return self._wallets

@property
def smart_wallets(self) -> SmartWalletsApi:
"""Get the SmartWalletsApi client instance.

Returns:
SmartWalletsApi: The SmartWalletsApi client instance.

Note:
This property lazily initializes the SmartWalletsApi client on first access.

"""
if self._smart_wallets is None:
self._smart_wallets = SmartWalletsApi(api_client=self._cdp_client)
return self._smart_wallets

@property
def webhooks(self) -> WebhooksApi:
"""Get the WebhooksApi client instance.
Expand Down
64 changes: 32 additions & 32 deletions cdp/client/api/smart_wallets_api.py
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,7 @@ def __init__(self, api_client=None) -> None:
def broadcast_user_operation(
self,
smart_wallet_address: Annotated[StrictStr, Field(description="The address of the smart wallet to broadcast the user operation from.")],
user_operation_id: Annotated[StrictStr, Field(description="The ID of the user operation to broadcast.")],
user_op_hash: Annotated[StrictStr, Field(description="The hash of the user operation to broadcast")],
broadcast_user_operation_request: Optional[BroadcastUserOperationRequest] = None,
_request_timeout: Union[
None,
Expand All @@ -69,8 +69,8 @@ def broadcast_user_operation(

:param smart_wallet_address: The address of the smart wallet to broadcast the user operation from. (required)
:type smart_wallet_address: str
:param user_operation_id: The ID of the user operation to broadcast. (required)
:type user_operation_id: str
:param user_op_hash: The hash of the user operation to broadcast (required)
:type user_op_hash: str
:param broadcast_user_operation_request:
:type broadcast_user_operation_request: BroadcastUserOperationRequest
:param _request_timeout: timeout setting for this request. If one
Expand All @@ -97,7 +97,7 @@ def broadcast_user_operation(

_param = self._broadcast_user_operation_serialize(
smart_wallet_address=smart_wallet_address,
user_operation_id=user_operation_id,
user_op_hash=user_op_hash,
broadcast_user_operation_request=broadcast_user_operation_request,
_request_auth=_request_auth,
_content_type=_content_type,
Expand All @@ -123,7 +123,7 @@ def broadcast_user_operation(
def broadcast_user_operation_with_http_info(
self,
smart_wallet_address: Annotated[StrictStr, Field(description="The address of the smart wallet to broadcast the user operation from.")],
user_operation_id: Annotated[StrictStr, Field(description="The ID of the user operation to broadcast.")],
user_op_hash: Annotated[StrictStr, Field(description="The hash of the user operation to broadcast")],
broadcast_user_operation_request: Optional[BroadcastUserOperationRequest] = None,
_request_timeout: Union[
None,
Expand All @@ -144,8 +144,8 @@ def broadcast_user_operation_with_http_info(

:param smart_wallet_address: The address of the smart wallet to broadcast the user operation from. (required)
:type smart_wallet_address: str
:param user_operation_id: The ID of the user operation to broadcast. (required)
:type user_operation_id: str
:param user_op_hash: The hash of the user operation to broadcast (required)
:type user_op_hash: str
:param broadcast_user_operation_request:
:type broadcast_user_operation_request: BroadcastUserOperationRequest
:param _request_timeout: timeout setting for this request. If one
Expand All @@ -172,7 +172,7 @@ def broadcast_user_operation_with_http_info(

_param = self._broadcast_user_operation_serialize(
smart_wallet_address=smart_wallet_address,
user_operation_id=user_operation_id,
user_op_hash=user_op_hash,
broadcast_user_operation_request=broadcast_user_operation_request,
_request_auth=_request_auth,
_content_type=_content_type,
Expand All @@ -198,7 +198,7 @@ def broadcast_user_operation_with_http_info(
def broadcast_user_operation_without_preload_content(
self,
smart_wallet_address: Annotated[StrictStr, Field(description="The address of the smart wallet to broadcast the user operation from.")],
user_operation_id: Annotated[StrictStr, Field(description="The ID of the user operation to broadcast.")],
user_op_hash: Annotated[StrictStr, Field(description="The hash of the user operation to broadcast")],
broadcast_user_operation_request: Optional[BroadcastUserOperationRequest] = None,
_request_timeout: Union[
None,
Expand All @@ -219,8 +219,8 @@ def broadcast_user_operation_without_preload_content(

:param smart_wallet_address: The address of the smart wallet to broadcast the user operation from. (required)
:type smart_wallet_address: str
:param user_operation_id: The ID of the user operation to broadcast. (required)
:type user_operation_id: str
:param user_op_hash: The hash of the user operation to broadcast (required)
:type user_op_hash: str
:param broadcast_user_operation_request:
:type broadcast_user_operation_request: BroadcastUserOperationRequest
:param _request_timeout: timeout setting for this request. If one
Expand All @@ -247,7 +247,7 @@ def broadcast_user_operation_without_preload_content(

_param = self._broadcast_user_operation_serialize(
smart_wallet_address=smart_wallet_address,
user_operation_id=user_operation_id,
user_op_hash=user_op_hash,
broadcast_user_operation_request=broadcast_user_operation_request,
_request_auth=_request_auth,
_content_type=_content_type,
Expand All @@ -268,7 +268,7 @@ def broadcast_user_operation_without_preload_content(
def _broadcast_user_operation_serialize(
self,
smart_wallet_address,
user_operation_id,
user_op_hash,
broadcast_user_operation_request,
_request_auth,
_content_type,
Expand All @@ -293,8 +293,8 @@ def _broadcast_user_operation_serialize(
# process the path parameters
if smart_wallet_address is not None:
_path_params['smart_wallet_address'] = smart_wallet_address
if user_operation_id is not None:
_path_params['user_operation_id'] = user_operation_id
if user_op_hash is not None:
_path_params['user_op_hash'] = user_op_hash
# process the query parameters
# process the header parameters
# process the form parameters
Expand Down Expand Up @@ -332,7 +332,7 @@ def _broadcast_user_operation_serialize(

return self.api_client.param_serialize(
method='POST',
resource_path='/v1/smart_wallets/{smart_wallet_address}/user_operations/{user_operation_id}/broadcast',
resource_path='/v1/smart_wallets/{smart_wallet_address}/user_operations/{user_op_hash}/broadcast',
path_params=_path_params,
query_params=_query_params,
header_params=_header_params,
Expand Down Expand Up @@ -1192,7 +1192,7 @@ def _get_smart_wallet_serialize(
def get_user_operation(
self,
smart_wallet_address: Annotated[StrictStr, Field(description="The address of the smart wallet the user operation belongs to.")],
user_operation_id: Annotated[StrictStr, Field(description="The ID of the user operation to fetch.")],
user_op_hash: Annotated[StrictStr, Field(description="The hash of the user operation to fetch")],
_request_timeout: Union[
None,
Annotated[StrictFloat, Field(gt=0)],
Expand All @@ -1212,8 +1212,8 @@ def get_user_operation(

:param smart_wallet_address: The address of the smart wallet the user operation belongs to. (required)
:type smart_wallet_address: str
:param user_operation_id: The ID of the user operation to fetch. (required)
:type user_operation_id: str
:param user_op_hash: The hash of the user operation to fetch (required)
:type user_op_hash: str
:param _request_timeout: timeout setting for this request. If one
number provided, it will be total request
timeout. It can also be a pair (tuple) of
Expand All @@ -1238,7 +1238,7 @@ def get_user_operation(

_param = self._get_user_operation_serialize(
smart_wallet_address=smart_wallet_address,
user_operation_id=user_operation_id,
user_op_hash=user_op_hash,
_request_auth=_request_auth,
_content_type=_content_type,
_headers=_headers,
Expand All @@ -1263,7 +1263,7 @@ def get_user_operation(
def get_user_operation_with_http_info(
self,
smart_wallet_address: Annotated[StrictStr, Field(description="The address of the smart wallet the user operation belongs to.")],
user_operation_id: Annotated[StrictStr, Field(description="The ID of the user operation to fetch.")],
user_op_hash: Annotated[StrictStr, Field(description="The hash of the user operation to fetch")],
_request_timeout: Union[
None,
Annotated[StrictFloat, Field(gt=0)],
Expand All @@ -1283,8 +1283,8 @@ def get_user_operation_with_http_info(

:param smart_wallet_address: The address of the smart wallet the user operation belongs to. (required)
:type smart_wallet_address: str
:param user_operation_id: The ID of the user operation to fetch. (required)
:type user_operation_id: str
:param user_op_hash: The hash of the user operation to fetch (required)
:type user_op_hash: str
:param _request_timeout: timeout setting for this request. If one
number provided, it will be total request
timeout. It can also be a pair (tuple) of
Expand All @@ -1309,7 +1309,7 @@ def get_user_operation_with_http_info(

_param = self._get_user_operation_serialize(
smart_wallet_address=smart_wallet_address,
user_operation_id=user_operation_id,
user_op_hash=user_op_hash,
_request_auth=_request_auth,
_content_type=_content_type,
_headers=_headers,
Expand All @@ -1334,7 +1334,7 @@ def get_user_operation_with_http_info(
def get_user_operation_without_preload_content(
self,
smart_wallet_address: Annotated[StrictStr, Field(description="The address of the smart wallet the user operation belongs to.")],
user_operation_id: Annotated[StrictStr, Field(description="The ID of the user operation to fetch.")],
user_op_hash: Annotated[StrictStr, Field(description="The hash of the user operation to fetch")],
_request_timeout: Union[
None,
Annotated[StrictFloat, Field(gt=0)],
Expand All @@ -1354,8 +1354,8 @@ def get_user_operation_without_preload_content(

:param smart_wallet_address: The address of the smart wallet the user operation belongs to. (required)
:type smart_wallet_address: str
:param user_operation_id: The ID of the user operation to fetch. (required)
:type user_operation_id: str
:param user_op_hash: The hash of the user operation to fetch (required)
:type user_op_hash: str
:param _request_timeout: timeout setting for this request. If one
number provided, it will be total request
timeout. It can also be a pair (tuple) of
Expand All @@ -1380,7 +1380,7 @@ def get_user_operation_without_preload_content(

_param = self._get_user_operation_serialize(
smart_wallet_address=smart_wallet_address,
user_operation_id=user_operation_id,
user_op_hash=user_op_hash,
_request_auth=_request_auth,
_content_type=_content_type,
_headers=_headers,
Expand All @@ -1400,7 +1400,7 @@ def get_user_operation_without_preload_content(
def _get_user_operation_serialize(
self,
smart_wallet_address,
user_operation_id,
user_op_hash,
_request_auth,
_content_type,
_headers,
Expand All @@ -1424,8 +1424,8 @@ def _get_user_operation_serialize(
# process the path parameters
if smart_wallet_address is not None:
_path_params['smart_wallet_address'] = smart_wallet_address
if user_operation_id is not None:
_path_params['user_operation_id'] = user_operation_id
if user_op_hash is not None:
_path_params['user_op_hash'] = user_op_hash
# process the query parameters
# process the header parameters
# process the form parameters
Expand All @@ -1449,7 +1449,7 @@ def _get_user_operation_serialize(

return self.api_client.param_serialize(
method='GET',
resource_path='/v1/smart_wallets/{smart_wallet_address}/user_operations/{user_operation_id}',
resource_path='/v1/smart_wallets/{smart_wallet_address}/user_operations/{user_op_hash}',
path_params=_path_params,
query_params=_query_params,
header_params=_header_params,
Expand Down
10 changes: 6 additions & 4 deletions cdp/client/models/create_user_operation_request.py
Original file line number Diff line number Diff line change
Expand Up @@ -17,8 +17,8 @@
import re # noqa: F401
import json

from pydantic import BaseModel, ConfigDict, Field
from typing import Any, ClassVar, Dict, List
from pydantic import BaseModel, ConfigDict, Field, StrictStr
from typing import Any, ClassVar, Dict, List, Optional
from cdp.client.models.call import Call
from typing import Optional, Set
from typing_extensions import Self
Expand All @@ -28,7 +28,8 @@ class CreateUserOperationRequest(BaseModel):
CreateUserOperationRequest
""" # noqa: E501
calls: List[Call] = Field(description="The list of calls to make from the smart wallet.")
__properties: ClassVar[List[str]] = ["calls"]
paymaster_url: Optional[StrictStr] = Field(default=None, description="The URL of the paymaster to use for the user operation.")
__properties: ClassVar[List[str]] = ["calls", "paymaster_url"]

model_config = ConfigDict(
populate_by_name=True,
Expand Down Expand Up @@ -88,7 +89,8 @@ def from_dict(cls, obj: Optional[Dict[str, Any]]) -> Optional[Self]:
return cls.model_validate(obj)

_obj = cls.model_validate({
"calls": [Call.from_dict(_item) for _item in obj["calls"]] if obj.get("calls") is not None else None
"calls": [Call.from_dict(_item) for _item in obj["calls"]] if obj.get("calls") is not None else None,
"paymaster_url": obj.get("paymaster_url")
})
return _obj

Expand Down
4 changes: 3 additions & 1 deletion cdp/client/models/user_operation.py
Original file line number Diff line number Diff line change
Expand Up @@ -30,11 +30,12 @@ class UserOperation(BaseModel):
id: StrictStr = Field(description="The ID of the user operation.")
network_id: StrictStr = Field(description="The ID of the network the user operation is being created on.")
calls: List[Call] = Field(description="The list of calls to make from the smart wallet.")
user_op_hash: StrictStr = Field(description="The unique identifier for the user operation onchain. This is the payload that must be signed by one of the owners of the smart wallet to send the user operation.")
unsigned_payload: StrictStr = Field(description="The hex-encoded hash that must be signed by the user.")
signature: Optional[StrictStr] = Field(default=None, description="The hex-encoded signature of the user operation.")
transaction_hash: Optional[StrictStr] = Field(default=None, description="The hash of the transaction that was broadcast.")
status: StrictStr = Field(description="The status of the user operation.")
__properties: ClassVar[List[str]] = ["id", "network_id", "calls", "unsigned_payload", "signature", "transaction_hash", "status"]
__properties: ClassVar[List[str]] = ["id", "network_id", "calls", "user_op_hash", "unsigned_payload", "signature", "transaction_hash", "status"]

@field_validator('status')
def status_validate_enum(cls, value):
Expand Down Expand Up @@ -104,6 +105,7 @@ def from_dict(cls, obj: Optional[Dict[str, Any]]) -> Optional[Self]:
"id": obj.get("id"),
"network_id": obj.get("network_id"),
"calls": [Call.from_dict(_item) for _item in obj["calls"]] if obj.get("calls") is not None else None,
"user_op_hash": obj.get("user_op_hash"),
"unsigned_payload": obj.get("unsigned_payload"),
"signature": obj.get("signature"),
"transaction_hash": obj.get("transaction_hash"),
Expand Down
Loading
Loading