diff --git a/README.md b/README.md index 8c032de..c2b2f9e 100644 --- a/README.md +++ b/README.md @@ -3,7 +3,7 @@ ## About This repository contains the official Python SDK for Fireblocks API. -For the complete API reference, go to the [API reference](https://docs.fireblocks.com/api). +For the complete API reference, go to the [API reference](https://developers.fireblocks.com/). ## Usage ### Before You Begin diff --git a/fireblocks_sdk/api_types.py b/fireblocks_sdk/api_types.py index fa029a1..3cea1ce 100644 --- a/fireblocks_sdk/api_types.py +++ b/fireblocks_sdk/api_types.py @@ -1,6 +1,5 @@ from enum import Enum -from typing import Optional, List, Union - +from typing import Optional, List, Union, Dict def snake_to_camel(snake_case: str): words = snake_case.split('_') @@ -9,13 +8,13 @@ def snake_to_camel(snake_case: str): def convert_class_to_dict(class_dict: dict): output_dict = {} - for key, value in class_dict.items(): + for key, value in class_dict.items: if isinstance(value, list): output_dict[snake_to_camel(key)] = [item.to_dict() if hasattr(item, 'to_dict') else item for item in value] elif hasattr(value, 'to_dict') and callable(getattr(value, 'to_dict')): output_dict[snake_to_camel(key)] = value.to_dict() - else: + elif value is not None: output_dict[snake_to_camel(key)] = value return output_dict @@ -387,30 +386,141 @@ class TimePeriod(str, Enum): DAY = "DAY" WEEK = "WEEK" +class StellarRippleCreateParams: + def __init__( + self, + issuerAddress: Optional[str] = None + ): + self.issuerAddress = issuerAddress -class IssueTokenRequest: - symbol: str - name: str - blockchain_id: str - eth_contract_address: Optional[str] - issuer_address: Optional[str] - decimals: int + def to_dict(self): + return convert_class_to_dict(self.__dict__) - def serialize(self) -> dict: - obj = { - 'symbol': self.symbol, - 'name': self.name, - 'blockchainId': self.blockchain_id, - 'decimals': self.decimals, - } +class Parameter: + def __init__( + self, + name: str, + type: str, + internalType: str, + description: Optional[str] = None, + components: Optional[List['Parameter']] = None + ): + self.name = name + self.type = type + self.internalType = internalType + self.description = description + self.components = components + + def to_dict(self): + return convert_class_to_dict(self.__dict__) + +class ParameterWithValue(Parameter): + def __init__( + self, + name: str, + type: str, + internalType: str, + value: Union[str, int, float, bool], + description: Optional[str] = None, + components: Optional[List['Parameter']] = None + ): + super().__init__(name, type, internalType, description, components) + self.value = value + + def to_dict(self): + return convert_class_to_dict(self.__dict__) + +class EVMTokenCreateParams: + def __init__( + self, + contractId: str, + constructorParams: Optional[List[ParameterWithValue]] = None + ): + self.contractId = contractId + self.constructorParams = constructorParams + + def to_dict(self): + return convert_class_to_dict(self.__dict__) + +class CreateTokenRequest: + def __init__( + self, + symbol: str, + name: str, + blockchainId: str, + vaultAccountId: str, + createParams: Union[EVMTokenCreateParams, StellarRippleCreateParams] + ): + self.symbol = symbol + self.name = name + self.blockchainId = blockchainId + self.vaultAccountId = vaultAccountId + self.createParams = createParams + + def to_dict(self): + return convert_class_to_dict(self.__dict__) + +class ContractDeployRequest: + def __init__( + self, + asset_id: str, + vault_account_id: str, + constructorParameters: Optional[List[ParameterWithValue]] = None + ): + self.asset_id = asset_id + self.vault_account_id = vault_account_id + self.constructorParameters = constructorParameters + + def to_dict(self): + return convert_class_to_dict(self.__dict__) + +class AbiFunction: + def __init__( + self, + name: str, + type: str, + stateMutability: str, + inputs: List[Parameter], + outputs: Optional[List[Parameter]] = None, + description: Optional[str] = None, + returns: Optional[Dict[str, str]] = None + ): + self.name = name + self.type = type + self.stateMutability = stateMutability + self.inputs = inputs + self.outputs = outputs + self.description = description + self.returns = returns - if self.eth_contract_address: - obj.update({'ethContractAddress': self.eth_contract_address}) + def to_dict(self): + return convert_class_to_dict(self.__dict__) - if self.issuer_address: - obj.update({'issuerAddress': self.issuer_address}) +class ContractUploadRequest: + def __init__( + self, + name: str, + description: str, + bytecode: str, + sourcecode: str, + abi: Optional[List[AbiFunction]] = None, + vendorId: Optional[str] = None, + compilerOutputMetadata: Optional[object] = None, + docs: Optional[object] = None, + attributes: Optional[Dict[str, str]] = None, + ): + self.name = name + self.description = description + self.bytecode = bytecode + self.sourcecode = sourcecode + self.abi = abi + self.vendorId = vendorId + self.compilerOutputMetadata = compilerOutputMetadata + self.docs = docs + self.attributes = attributes - return obj + def to_dict(self): + return convert_class_to_dict(self.__dict__) class PolicyTransactionType(str, Enum): ANY = "*" diff --git a/fireblocks_sdk/sdk.py b/fireblocks_sdk/sdk.py index 09a78eb..dbfe3f0 100644 --- a/fireblocks_sdk/sdk.py +++ b/fireblocks_sdk/sdk.py @@ -20,19 +20,21 @@ FEE_LEVEL, PagedVaultAccountsRequestFilters, TransactionDestination, - NFTOwnershipStatusValues, - IssueTokenRequest, GetAssetWalletsFilters, TimePeriod, GetOwnedCollectionsSortValue, - GetOwnedNftsSortValues, - GetNftsSortValues, OrderValues, GetOwnedAssetsSortValues, PolicyRule, GetSmartTransferFilters, + NFTOwnershipStatusValues, + GetOwnedNftsSortValues, + GetNftsSortValues, NFTsWalletTypeValues, NFTOwnershipStatusUpdatedPayload, + CreateTokenRequest, + ContractUploadRequest, + ContractDeployRequest, PagedExchangeAccountRequestFilters, ) from .sdk_token_provider import SdkTokenProvider @@ -98,11 +100,10 @@ def __init__( def get_linked_tokens(self, limit: int = 100, offset: int = 0): request_filter = {"limit": limit, "offset": offset} - url = f"/v1/tokenization/tokens" - return self._get_request(url, query_params=request_filter) + return self._get_request(f"/v1/tokenization/tokens", query_params=request_filter) - def issue_new_token(self, request: IssueTokenRequest): - return self._post_request("/v1/tokenization/tokens", request.serialize()) + def issue_new_token(self, request: CreateTokenRequest): + return self._post_request("/v1/tokenization/tokens", request) def get_linked_token(self, asset_id: str): return self._get_request(f"/v1/tokenization/tokens/{asset_id}") @@ -148,6 +149,28 @@ def approve_staking_provider(self, validator_provider_id: int): return self._post_request(f"/v1/staking/providers/approveTermsOfService", body={"validatorProviderId": validator_provider_id}) + def get_contract_templates(self, limit: int = 100, offset: int = 0): + request_filter = { + "limit": limit, + "offset": offset + } + return self._get_request(f"/v1/contract-registry/contracts", query_params=request_filter) + + def upload_contract_template(self, request: ContractUploadRequest): + return self._post_request(f"/v1/contract-registry/contracts", request.serialize()) + + def get_contract_template(self, contract_id: str): + return self._get_request(f"/v1/contract-registry/contracts/{contract_id}") + + def get_contract_template_constructor(self, contract_id: str, with_docs: bool=False): + return self._get_request(f"/v1/contract-registry/contracts/{contract_id}/constructor?withDocs=${with_docs}`") + + def delete_contract_template(self, contract_id: str): + return self._delete_request(f"/v1/contract-registry/contracts/{contract_id}") + + def deploy_contract(self, contract_id: str, request: ContractDeployRequest): + return self._post_request(f"/v1/contract-registry/contracts/{contract_id}/deploy", request.serialize()) + def get_nft(self, id: str): url = "/v1/nfts/tokens/" + id