---
# System prepended metadata

title: Keys API

---

# Keys API

## Introduction 

### Modules

The current NO registry will be replaced by the Staking router and the registry itself will become part of it. In Staking router the following modules are now expected, but their number may vary:

* Pro (the current registry or a modified version of it)
* Solo
* DVT

We consider the situation that modules can store keys onchain, offchain, on L2 or in any other way.

```mermaid
flowchart TB
    SR[Staking Router]

		SR --> Pro[Pro module]
		SR --> Solo[Solo module]
		SR --> DVT[DVT module]

		subgraph PM[ ]
			Pro --> OP1[Operator 1]
			Pro --> OPN[Operator N]
		
			OP1 --> OP1K1[Key 1]
			OP1 --> OP1KN[Key N]
			OPN --> OPNK[...]
		end

		subgraph SM[ ]
			Solo --> OS1[Operator 1]
			Solo --> OSN[Operator N]
		
			OS1 --> OS1K1[Key 1]
			OS1 --> OS1KN[Key N]
			OSN --> OSNK[...]
		end

		subgraph DM[ ]
			DVT --> OD1[Operator 1]
			DVT --> ODN[Operator N]
		
			OD1 --> OD1K1[Key 1]
			OD1 --> OD1KN[Key N]
			ODN --> ODNK[...]
		end
```

### Keys

Currently keys can have the following statuses:

* not approved – a key submitted by NO but not confirmed by DAO
* approved – key approved by DAO
* used keys – key used for depositing (it's probably active validator)
* exited – validator with this key was exited
* active = used - exited

There are no exited keys yet, but this functionality will be needed after the implementation of withdrawals.

### Meta

It's extremely important to have all the data for each module on a one certain block (by hash) since we will use this data in DSM. `blockNumber`, `blockHash` and `keysOpIndex` must be stored and returned when keys are requested.

```ts
// Pseudo code example

interface KeysResponse {
	// ...
	meta: {
		blockNumber: number;
		blockHash: string;
	},
}
```

// TODO: modules in response and their keysOpIndexes

## Interfaces

### DepositData

https://github.com/ethereum/consensus-specs/blob/dev/specs/phase0/beacon-chain.md#depositdata

```ts
interface DepositData {
	pubkey: BLSPubkey;
	signature: BLSSignature;
	withdrawal_credentials: Bytes32;
	amount: Gwei;
}
```

:::warning
Now we have fixed fields `withdrawal_credentials` and `amount` in the contract, but the situation may change with the launch of the Solo module.
:::

### Key

```ts
interface Key {
	pubkey: string;
	signature: string;
	used: boolean;
	operator_index: number;
}
```

:::warning
We will probably want to see additional statuses here: `exited`, `pending_exit` or others.
:::

### Operator

```ts
interface Operator {
	index: number;
	active: boolean;
	name: string;
	rewardAddress: string;
	stakingLimit: number;
	stoppedValidators: number;
	totalSigningKeys: number;
	usedSigningKeys: number;
}
```


### Module

```
interface Module {
	name: string;
	contractAddress: string;
}
```

:::warning
We will probably want to see additional fields here, like: `fee`, `limit` or others.
:::

## Endpoints 

### Keys

* `/v1/keys/`

<!-- * `/v1/keys/status/all`
* `/v1/keys/status/approved`
* `/v1/keys/status/used`
* `/v1/keys/status/exited`
* `/v1/keys/status/active` -->

:::warning
Response could be very large but we can't have a pagination here since data could be updated in the process
:::

// TODO: need some fitlers (by status?)

### Validators

* `/v1/validators/status/active`
* ...

// TODO: need some fitlers (by status?)

<!-- 
### Keys by module and operator

* `/v1/keys/${module}`
* `/v1/keys/${module}/${operator_index}`
* `/v1/keys/${module}/${operator_index}/${key_id}`
 -->

### Key by pubkey

* `/v1/keys/search/${pubkey}`

Used by https://operators.lido.fi/finder

<!-- 
### Operators by status

* `/v1/operators/status/all`
* `/v1/operators/status/active`
* `/v1/operators/status/inactive` -->
<!-- 
### Operators by module

* `/v1/operators/${module}`
* `/v1/operators/${module}/${id}` -->

### Modules

* `/v1/modules`
* `/v1/modules/${address_or_name}`

#### Registry

* `/v1/modules/pro/operators`
* `/v1/modules/pro/keys`
* ...

## Additional thoughts

### Validators vs keys

API can be used together with other services within one docker compose file. Some services need only active keys (validators), while others may need all keys, including unapproved keys. Perhaps we can foresee some flag that will disable some of the functionality or have two different services.

### Statefull vs stateless

Should the service store the entire state of the keys or can we get the keys to a certain block height?


### How it could work

1. Run cron task
2. Get latest block from EL
3. ... 
4. Get blockHash and do updates for each module by blockHash
5. Need to check this case whether we need to block db

### TODO

1. Iterations
2. DSM - think about data consistance
3. Some apps use validators, some use all keys
4. We could use microservices (grpc)
