# @blockswaplab/stakehouse-sdk
The Stakehouse SDK is a NPM Package which can be used to carry out everything from depositing 32ETH to the Ethereum Deposit Contract to leaving Stakehouse. The SDK supports Goerli Testnet and Ethereum Mainnet.

## Installation
To install the package use the command `npm i @blockswaplab/stakehouse-sdk`  

## Using stakehouse-sdk
One of the ways to import and initialise the SDK is:
```js
const { StakehouseSDK } = require('@blockswaplab/stakehouse-sdk');

const provider = new ethers.providers.InfuraProvider("goerli", {
    projectId: INFURA_PROJECT_ID,
    projectSecret: INFURA_PROJECT_SECRET
});
const signer = new ethers.Wallet(PRIV_KEY, provider);

const sdk = new StakehouseSDK(signer);
```
> Please note that the SDK is an `ethers.js` based SDK and hence requires `ethers` based signer. It also returns values in `ethers.js` supported format. For example, it returns `BigNumbers` for the smart contract view functions that might return `uint`.

The SDK exposes various sub-classes:  
* [utils](./utils-README.md)  
* [subgraph](./subgraph-README.md)  
* [multipartyRageQuit](./multipartyRagequit-README.md)  
* [cip](./cip-README.md)  
* [balanceReport](./balanceReport-README.md)  
* [constants](./constants-README.md)  
* [contractInstance](./contract-README.md)  

The following is a list of functionalities, their usage and directions to use them.

## reportBalanceIncrease function
This function allows validators to report their updated ETH balance to the Deposit Router. Reporting a balance increase allows users to self report that a KNOT has received consensus rewards for performing duties which is reflected in dETH.  

### Input Parameters
stakehouseAddress: Address of the Stakehouse  
authenticatedReport: Deposit Router response obtained from the `authenticateReport` function 

### Using reportBalanceIncrease function
```js
await sdk.reportBalanceIncrease(stakehouseAddress, authenticatedReport);
```

### Return Parameter
Returns the transaction data  

## balanceReport function
This function combines the `reportBalanceIncrease` and the `slash` function. If the validator's balance has increased, it calls the `reportBalanceIncrease`. Otherwise, it slashes the validator.  

### Input Parameters
beaconNodeURL: Consensus layer node URL  
blsPublicKey: BLS Public Key of the validator  
stakehouseAddress: Address of the Stakehouse  

### Using balanceReport function
```js
await sdk.balanceReport(beaconNodeURL, blsPublicKey, stakehouseAddress);
```

### Return Parameter
Returns the transaction data  

## registerValidatorInitials function
This function allows users to register their validator's initials i.e. execution layer address, BLS Public Key and BLS Signature. This helps Stakehouse to maintain the data of all the validators registered via the protocol.  

### Input Parameters
userAddress: Address of the user  
blsPublicKey: User's BLS Public Key  
blsSignature: BLS Signature  

### Using registerValidatorInitials function
```js
await sdk.registerValidatorInitials(userAddress, blsPublicKey, blsSignature);
```

### Return Parameter
Returns the transaction data  

## registerValidator function
This function allows users to register their validator. After the validator's initials are registered by the protocol, this step sends 32ETH to the Ethereum Foundation's deposit contract to stake the validator. Please be very careful while using this function as this requires ETH.  

### Input Parameters
userAddress: Execution layer address of the user  
authenticationPackage: Return paramter of the `BLSAuthentication` function  

### Using registerValidator function
```js
await sdk.registerValidator(userAddress, authenticationPackage);
```

### Return Parameter
Returns the transaction data  

## createStakehouse function
This function allows users to create a Stakehouse with their validator credentials  

### Input Parameters
userAddress: Address of the user  
ticker: String name of ticker (3-5 characters)  
savETHIndexId: ID of SavETH Index. Set this to zero to auto-create a new savETH index that the depositor will own.  
authenticatedReport: report obtained from `authenticateReport` function

### Using createStakehouse function
```js
await sdk.createStakehouse(userAddress, ticker, savETHIndexId, authenticatedReport);
```

### Return Parameter
Returns the transaction data  

## joinStakehouse function
This function allows users to join a Stakehouse with their validator credentials  

### Input Parameters
userAddress: Address of the user  
stakehouseAddress: Address of Stakehouse  
brandTokenId: Token ID of Brand  
savETHIndexId: ID of SavETH Index. Set this to zero to auto-create a new savETH index that the depositor will own.  
authenticatedReport: report obtained from `authenticateReport` function

### Using joinStakehouse function
```js
await sdk.joinStakehouse(userAddress, stakehouseAddress, brandTokenId, savETHIndexId, authenticatedReport);
```

### Return Parameter
Returns the transaction data  

## addKnotToOpenIndexAndWithdraw function
This function allows users to move their KNOT to the Open Index and withdraw their dETH.  

### Input Parameters
stakehouseAddress: Address of Stakehouse  
memberID: Member ID of the KNOT in the Stakehouse  
recipientAddress: Address of Recipient who receives the dETH  

### Using addKnotToOpenIndexAndWithdraw function
```js
await sdk.addKnotToOpenIndexAndWithdraw(stakehouseAddress, memberID, recipientAddress);
```

### Return Parameter
Returns the transaction data  

## batchAddKnotToOpenIndexAndWithdraw function
This function allows users to move a batch of KNOTs to the Open Index and withdraw their dETH.  

### Input Parameters
stakehouses: Array of stakehouse addresses  
memberIDs: Array of member ID of the KNOTs in the stakehouses  
recipient: Address of recipient who receives the dETH  

### Using batchAddKnotToOpenIndexAndWithdraw function
```js
await sdk.batchAddKnotToOpenIndexAndWithdraw(stakehouses, memberIDs, recipient);
```

### Return Parameter
Returns the transaction data  

## batchTransferKnotsToSingleIndex function
This function allows users to move a batch of KNOTs to an index. Read more about savETH Indexes [here](https://help.joinstakehouse.com/en/articles/6499763-what-is-saveth)  

### Input Parameters
stakehouses: Array of stakehouse addresses  
memberIDs: Array of member ID of the KNOTs in the stakehouses  
targetSavETHIndexID: savETH Index where the KNOTs will be transferred  

### Using batchAddKnotToOpenIndexAndWithdraw function
```js
await sdk.batchTransferKnotsToSingleIndex(stakehouses, memberIDs, targetSavETHIndexID);
```

### Return Parameter
Returns the transaction data  

## BLSAuthentication function
This function allows users to authenticate their BLS Public Key. The authentication makes sure that the generated credentials are valid and belong to the correct network. The successful response is then used as a parameter to send 32 ETH to the Ethereum Deposit Contract.  

### Input Parameters
keystorePassword: Password of the Keystore file  
keystore: Contents of the Keystore file  
depositData: Deposit Data obtained when generating credentials  
depositorSignaturePayload: Signature payload obtained from `getPersonalSignInitials` function  

### Using BLSAuthentication function
```js
await sdk.BLSAuthentication(keystorePassword, keystore, depositData, depositorSignaturePayload);
```

### Return Parameter
Returns the BLS Auth response  

## rageQuitKnot function
This function allows users to call Rage Quit without any pre-condition checks. A validator must still meet all the conditions prior to exiting.  

### Input Parameters
stakehouseAddress: Stakehouse Address of the KNOT  
authenticatedReport: Report obtained from the `authenticateReport` function  
topUpAmountInWei: amount of top-up required to Rage Quit.

### Using rageQuitKnot function
```js
await sdk.rageQuitKnot(stakehouseAddress, authenticatedReport, topUpAmountInWei);
```

### Return Parameter
Returns the transaction data

## rageQuit function
This funciton allows users to Rage Quit. The function also checks if all the conditions are satisfied for the KNOT to Rage Quit.

### Input Parameters
stakehouseAddress: Stakehouse Address of the KNOT  
userAddress: Execution layer address of the user
authenticatedReport: Report obtained from the `authenticateReport` function  

### Using rageQuit function
```js
await sdk.rageQuit(stakehouseAddress, userAddress, authenticatedReport);
```

### Return Parameter
Returns the transaction data

## depositIntoSavETHRegistry function
This function allows users to deposit dETH into the savETH registry

### Input Parameters
savETHRecipient: savETH receiver of the funds  
amount: amount of funds being deposited into savETH

### Using depositIntoSavETHRegistry function
```js
await sdk.depositIntoSavETHRegistry(savETHRecipient, amount);
```

### Return Parameter
Returns transaction data  

## depositAndIsolateKnotIntoIndex function
This function allows users to deposit funds and isolate the KNOT into an index.

### Input Parameters
stakehouseAddress: Stakehouse address of the user  
blsPublicKey: BLS Public Key of the KNOT  
indexID: index ID in which the KNOT is to be isolated

### Using depositAndIsolateKnotIntoIndex function
```js
await sdk.depositAndIsolateKnotIntoIndex(stakehouseAddress, blsPublicKey, indexID);
```

### Return Parameter
Returns the transaction data.  

## slash function
This function allows the user to slash any KNOT if their balance falls below the last reported balance to the Stakehouse.

### Input Parameters
stakehouseAddress: Stakehouse address of the KNOT being slashed  
authenticatedReport: report obtained from the `authenticateReport` function  

### Using slash function
```js
await sdk.slash(stakehouseAddress, authenticatedReport);
```

### Return Parameter
Returns the transaction data.  

## slashAndTopUpSlot function
This function allows a user to slash a KNOT with balance a below 32 ETH and then top-up the slashed SLOT tokens. The user who calls the function then becomes a collateralized owner of the slashed KNOT. A KNOT can be slashed only if the current balance has gone below the last reported balance.  

### Input Parameters
stakehouseAddress: Stakehouse address of the KNOT to be slashed  
slasherAddress: Execution layer address of the user calling the function. This address also receives the collateralized SLOTs.  
buyAmount: amount of slashed SLOT tokens that the slasher wants to top-up denominated in WEI  
ethValue: ETH to be sent along with the transaction. This amount can be higher than the top up amount (the top up amount is always capped at the amount of SLOT that is slashed) in the event that a user wishes to flush the queue by reaching the minimum amount of ETH required to send transactions to the Ethereum Deposit Contract (1 ETH).  
authenticatedReport: The Report obtained from the `authenticateReport` function  

### Using slashAndTopUpSlot function
```js
await sdk.slashAndTopUpSlot(stakehouseAddress, slasherAddress, buyAmount, ethValue, authenticatedReport);
```

### Return Parameter
Returns the transaction data

## createIndex function
This function allows the user to create a new index and become its owner. This allows users to create savETH index portfolios for curating savETH and dETH from any KNOT in any stakehouse. Read more about savETH [here](https://help.joinstakehouse.com/en/articles/6499763-what-is-saveth).  

### Input Parameters
ownerAddress: Address of the creator of the index  

### Using createIndex function
```js
await sdk.createIndex(ownerAddress);
```

### Return Parameter
Returns the transaction data  

## approveTransferOfIndexOwnership function
This function allows user to approve the transfer of ownership of their savETH index  

### Input Parameters
indexID: index ID of the savETH index to be transferred  
spender: receiver of the savETH index

### Using approveTransferOfIndexOwnership function
```js
await sdk.approveTransferOfIndexOwnership(indexID, spender);
```

### Return Parameter
Returns the transaction data

## transferIndexOwnership function
This function allows user to transfer the owner of their index

### Input Parameters
indexID: index ID of the index being transferred  
recipient: new owner of the index  

### Using transferIndexOwnership function
```js
await sdk.transferIndexOwnership(indexID, recipient);
```

### Return Parameter
Returns the transaction data

## transferKnotToAnotherIndex function
This function allows users to move their KNOT to a new index.  

### Input Parameters
stakehouseAddress: Stakehouse address of the KNOT  
blsPublicKey: BLS Public Key of the KNOT  
newIndexID: index ID of the index that the KNOT is being transferred to

### Using transferKnotToAnotherIndex function
```js
await sdk.transferKnotToAnotherIndex(stakehouseAddress, blsPublicKey, newIndexID);
```

### Return Parameter
Returns the transaction data

## approveSpendingOfKnotInIndex function

### Input Parameters
stakehouseAddress: Stakehouse address of the KNOT  
blsPublicKey: BLS Public Key of the KNOT  
spender: Ethereum execution layer address of the user allowed to spend dETH of the KNOT  

### Using approveSpendingOfKnotInIndex function
```js
await sdk.approveSpendingOfKnotInIndex(stakehouseAddress, blsPublicKey, spender);
```

### Return Parameter
Returns the transaction data

## joinStakeHouseAndCreateBrand function
This function allows the user to join an existing Stakehouse and create a brand.

### Input Parameters
userAddress: Ethereum execution layer address of the user  
brandTicker: String input for the brand name  
stakehouseAddress: Stakehouse address that the KNOT wants to join  
savETHIndexId: savETH Index ID. A default value of `0` will auto-create the index  
authenticatedReport: report obtained from the `authenticateReport` function

### Using joinStakeHouseAndCreateBrand function
```js
await sdk.joinStakeHouseAndCreateBrand(userAddress, brandTicker, stakehouseAddress, savETHIndexId, authenticatedReport);
```

### Return Parameter
Returns the transaction data

## authorizeRepresentative function
This function allows the user to authorize a representative to stake 32ETH and carry out other functions on behalf of them.

### Input Parameters
representative: Execution layer address of the representative  
enable: Boolean. Can be set to `true` to authorize representative or `false` to revoke privileges  

### Using authorizeRepresentative function
```js
await sdk.authorizeRepresentative(representative, enable);
```

### Return Parameter
Returns transaction data

## isRepresentativeAuthorized function
This function allows anyone to check whether a representative and a representee have a valid relationship.

### Input Parameters
representative: Execution layer address of the representative  
representee: Execution layer address of the representee (the user being represented)

### Using isRepresentativeAuthorized function
```js
await sdk.isRepresentativeAuthorized(representative, representee);
```

### Return Parameter
Returns boolean. `true` if a valid relationship exists, `false` otherwise.

## deposit function
This function allows the user to deposit their 32ETH to the Ethereum Foundation deposit contract via the Stakehouse Protocol. The function does all the heavy-lifting for the user, such as registering validator's initials, signing personal initials (to be signed by the user), authenticating the BLS credentials and registering the validator. A user can go through all of these steps individually with the help of the SDK, but the `deposit` function does it all in a single step. The function can either be called by the user themselves or by their representative. If the representative calls the function, they will receive an `encoded` data which should be signed and sent by the user to the transaction router to deposit the 32ETH.

### Input Parameters
keystore: BLS keystore of the KNOT  
password: password of the keystore  
depositData: deposit data file of the KNOT  
privateKey: Optional parameter. The user/representative can provide their privateKey to directly sign a transaction. If no value is provided, the transaction should be signed using the ECDSA wallet  
user: Optional parameter. If the representative calls the function, they should specify the execution layer address of the `representee`. Otherwise, if the user themselves are calling the function, then the parameter can be `null`.

### Using deposit function
```js
await sdk.deposit(keystore, password, depositData, privateKey=null, user=null);
```

### Return Parameter
Returns transaction data if the user called the function. Otherwise, returns the `encoded` data if the representative calls the function.
