Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

tokenization and contract registry endpoints #127

Merged
merged 11 commits into from
Nov 13, 2023
Merged
Show file tree
Hide file tree
Changes from 1 commit
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
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
207 changes: 192 additions & 15 deletions fireblocks_sdk/api_types.py
Original file line number Diff line number Diff line change
@@ -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('_')
Expand Down Expand Up @@ -317,31 +316,209 @@ class TimePeriod(str, Enum):
DAY = "DAY"
WEEK = "WEEK"

class StellarRippleCreateParams:
def __init__(
self,
issuerAddress: Optional[str] = None
):
self.issuerAddress = issuerAddress

def serialize(self) -> dict:
obj = {}
or109 marked this conversation as resolved.
Show resolved Hide resolved

if self.issuerAddress:
obj.update({'issuerAddress': self.issuerAddress})
or109 marked this conversation as resolved.
Show resolved Hide resolved

class IssueTokenRequest:
symbol: str
name: str
blockchain_id: str
eth_contract_address: Optional[str]
issuer_address: Optional[str]
decimals: int
return obj

class Parameter:
aviba marked this conversation as resolved.
Show resolved Hide resolved
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 serialize(self) -> dict:
obj = {
or109 marked this conversation as resolved.
Show resolved Hide resolved
'name': self.name,
'type': self.type,
'internalType': self.internalType,
}

if self.description:
obj.update({'description': self.description})
or109 marked this conversation as resolved.
Show resolved Hide resolved
if self.components:
obj.update({'components': self.components})

return obj

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 serialize(self) -> dict:
obj = super().serialize()
obj.update({'value': self.value})
or109 marked this conversation as resolved.
Show resolved Hide resolved

return obj

class EVMTokenCreateParams:
def __init__(
self,
contractId: str,
constructorParams: Optional[List[ParameterWithValue]] = []
or109 marked this conversation as resolved.
Show resolved Hide resolved
):
self.contractId = contractId
self.constructorParams = constructorParams

def serialize(self) -> dict:
return {
'contractId': self.contractId,
'constructorParams': self.constructorParams,
}

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 serialize(self) -> dict:
return {
'symbol': self.symbol,
'name': self.name,
'blockchainId': self.blockchain_id,
'decimals': self.decimals,
'blockchainId': self.blockchainId,
'vaultAccountId': self.vaultAccountId,
'createParams': self.createParams
}

if self.eth_contract_address:
obj.update({'ethContractAddress': self.eth_contract_address})
class ContractDeployRequest(object):
def __init__(
self,
asset_id: str,
vault_account_id: str,
constructorParameters: Optional[List[ParameterWithValue]] = []
or109 marked this conversation as resolved.
Show resolved Hide resolved
):
self.asset_id = asset_id
self.vault_account_id = vault_account_id
self.constructorParameters = constructorParameters

if self.issuer_address:
obj.update({'issuerAddress': self.issuer_address})
def serialize(self) -> dict:
obj = {
'assetId': self.asset_id,
'vaultAccountId': self.vault_account_id,
}

if self.constructorParameters:
obj.update({'constructorParameters': self.constructorParameters})

return obj

class AbiFunction(object):
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

def serialize(self) -> dict:
obj = {
'name': self.name,
'type': self.type,
'stateMutability': self.stateMutability,
'inputs': self.inputs,
}

if self.outputs is not None:
obj.update({'outputs': self.outputs})

if self.description:
obj.update({'description': self.description})

if self.returns:
obj.update({'returns': self.returns})

return obj

class ContractUploadRequest(object):
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

def serialize(self) -> dict:
obj = {
'name': self.name,
'description': self.description,
'bytecode': self.bytecode,
'sourcecode': self.sourcecode,
}

if self.compilerOutputMetadata:
obj.update({'compilerOutputMetadata': self.compilerOutputMetadata})

if self.attributes:
obj.update({'attributes': self.attributes})

if self.vendorId:
obj.update({'vendorId': self.vendorId})

return obj

class PolicyTransactionType(str, Enum):
ANY = "*"
Expand Down
35 changes: 28 additions & 7 deletions fireblocks_sdk/sdk.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,9 +9,9 @@

from .api_types import FireblocksApiException, TRANSACTION_TYPES, TRANSACTION_STATUS_TYPES, TransferPeerPath, \
DestinationTransferPeerPath, TransferTicketTerm, TRANSACTION_TRANSFER, SIGNING_ALGORITHM, UnsignedMessage, \
FEE_LEVEL, PagedVaultAccountsRequestFilters, TransactionDestination, NFTOwnershipStatusValues, IssueTokenRequest, \
FEE_LEVEL, PagedVaultAccountsRequestFilters, TransactionDestination, NFTOwnershipStatusValues, RawMessage, \
GetAssetWalletsFilters, TimePeriod, GetOwnedCollectionsSortValue, GetOwnedNftsSortValues, GetNftsSortValues, OrderValues, \
GetOwnedAssetsSortValues, PolicyRule
GetOwnedAssetsSortValues, PolicyRule, CreateTokenRequest, ContractUploadRequest, ContractDeployRequest
from .sdk_token_provider import SdkTokenProvider


Expand Down Expand Up @@ -61,11 +61,10 @@ def get_linked_tokens(self, limit: int = 100, offset: int = 0):
"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}")
Expand All @@ -76,6 +75,28 @@ def link_token(self, asset_id: str):
def unlink_token(self, asset_id: str):
return self._delete_request(f"/v1/tokenization/tokens/{asset_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

Expand Down Expand Up @@ -1592,7 +1613,7 @@ def get_vault_balance_by_asset(self, asset_id=None):

return self._get_request(url)

def create_raw_transaction(self, raw_message, source=None, asset_id=None, note=None):
def create_raw_transaction(self, raw_message: RawMessage, source=None, asset_id=None, note=None):
"""Creates a new raw transaction with the specified parameters

Args:
Expand Down