# SSV SDK tech spec overview v2 ## Motivation Purpose of this SDK is to allow developers build blazing **fast** and super **safe** staking apps. ## Problem to address The problem with development of staking apps is two fold. **Complexity:** There are many moving parts developers need to take care of and the final chain of data transformation in the system is. data transformation: ``` create_secret -> create_validator -> split_validator -> encrypt shares -> create_fn_inputs ``` **Safety:** Devs need to safely store and handle secret from which the validator keys are generated split it and encrypt in a safe way. They also need to handle safe & secure backup of this secret. ## Design Design of this SDK aims to address both Complexity and Safety issues, while making the SDK easily composable with other user generated functions and modules. It aims to do so by logically separating the SDK into internal module which is handling the secret and external module which provides good developer experience. The language of choice is `python`. The main reason for this is that the main library for creating validator keys [wagyu-key-gen](https://github.com/stake-house/wagyu-key-gen/tree/main) which is audited and battle tested is already build in it. This module makes up roughly half of code that is needed for the creation of the internal module, which we will get for free here. Also the separation between internal & external module allows devs to integrate just internal module of the SDK as a binary while building the external module in their language of choice. Since the internal module is not leaking any secrets, bugs in the implementation of the external module will not lead to leakage of the validator key to any outside program or attacker. This allows devs to have a very high expressivity of their systems without worrying about its security. It is also cost efficient solution since only the internal module needs to be audited. #### internal The design goal of the internal module is to be as lightweight and general as possible. Both due to the security considerations and easy audits but also to allow for high expressivity and easy integration with other languages & functions & systems developers may want to use. If devs use the SDK as is, they will not interact with this module at all. #### external The design goal of external module is to provide seamless developer experience for anyone building a staking app. After developer has set up his environment, he will be able to get input for ssv-network contract function without worrying about secret creation, key creation, splitting or any other transformation mentioned above. **example use** ```python import ssv_network_sdk import user_config # whole payload needed to call registerValidator function # @Notice no secret is passed to the function input_for_registerValidator = ssv_network_sdk.get_input_registerValidator(validator_index=0, operator_ids=[1,2,3,4]) ``` ### Design Goals - logically separate module handling secrets from rest - reasons - allow for internal module to be audited separately - allow for the rest of the SDK to be agnostic, also developed in GO, JS or other languages - allow for separation of external and internal part - have a `read_config()` run at the beginning of the script - reasons - error handeling - only necessary inputs must be in config - easier to reason about fns - devs see what inputs it usese - easier for grantees to use only specific functions from the SDK, agnostic to config structure, let them handle inputs in any way ## internal module All the internal module of the SSV sdk can be converted into a library which takes input in the functions and gives necessary output. ### Principles - minimal code required to get shares + keys from secret. - should return only publicly sharable encrypted data - with minimal external dependencies - future proof - functions in this module need to be design in a general manner - working even if the structure of the encrypted share changes in the future(nonce has different format or owner address or different data field is added) - for safety this module does not take validator keys as inputs as no secrets are passed in or out, however, some grantees use validator keys directly and not mnemonic in their system, does it make sense to create a specific function for this which takes this as input? probably better than incorporate into existing ones for clarity.. - do we want the be opinionated in this or not? ### modules - validator creation + handeling - ssv share handeling #### functionioality - Validator Creation - Requires: - Mnemonic - Index of Validators - Number of Validators - Network - Outputs: - keystore files for the validators - KeyShare Creation - Requires: - keystore file or mnemonic and index - Node operator public keys - Owner Address - Owner Nonce - Outputs - keyshare file for the SSV node operators - Validator Exits - Requires - keystore file or mnemonic and index - beacon chain api - Outputs - exit file with exit message As mentioned above mnemonic and index is the major part that is needed for all the operations. Though, it can be omitted but a backup should be stored in the case when validator keys goes missing. There are different ways to store them as required by the system - **memory** : Passing the mnemonic when running the files stores them in memory and when the script stops will delete the memory. This will only give access to the script when it is running. - **vaults** : There are many kind of vaults and these is one of the safest way to store any confidential information. This gives more granular access to the mnemonic and only the instance running the script can access it. Ex. Hashicorp vault or vaults provided by cloud providers like AWS vault - **keystore** : Third option can be using the system keystore. Most of the systems have inbuilt keystores which can be used to store sensitive information and can be accessed by scripts with right priviliges - **enclaves** : This option is also quite famous now-a-days. It involves creating a trusted environment and running your processes there. The enclave just takes the input from the user and outputs results and the files are not accessible. - **config file** : This is the least secure option to store the mnemonic. The security depends on the system on which config is stored The decision to use any of the above depends on the team using the library. - validator mapping // should be in external - validator_key => validator_index - functions - init function - creates mnemonic - print mnenmonic on the screen - backup - print mnenmonic on the screen - ### example functions **validator functions** ```python def get_deposit_data(mnemonic=dot_env, validator_index=0): ... return deposit_data def get_exit_cred(mnemonic=dot_env, validator_index=0): ... return exit_cred ``` **ssv functions** ```python def get_encrypted_shares(mnemonic=dot_env, validator_index=0, operator_public_keys) ... return encrypted_shares ``` ## external module everything else needed manage validators + get inputs + format outputs for ssv_network contracts ### parts - config file - functions - ? validator database / operator regitry ### example functions **validator functions** ```python def get_input_exit_validator(validator_index=0, bc_rpc): # only index is inputed, # secrets are not passed outside internal module ... return True def get_input_deposit_validator(deposit_data): ... return True def get_validator_index(pub_key): ... return validator_index ``` **ssv functions** ```python def get_input_registerValidator( validator_index=0, operator_ids, rpc_url): ... return registerValidator_inputs # to be pluggable straight to the function # this SDK should also provide human readable output for functions def format_output_operatorFee(tx_output, scale=years): ... return operatorFee_human_readable def format_output_networkFee(tx_output, scale=years): ... return networkFee_human_readable ```