Skip to content

Commit

Permalink
feat(staking): expose staking API
Browse files Browse the repository at this point in the history
  • Loading branch information
JGiter committed Jul 13, 2021
1 parent aaadb57 commit 6d6936f
Show file tree
Hide file tree
Showing 3 changed files with 145 additions and 2 deletions.
1 change: 1 addition & 0 deletions src/iam-client-lib.ts
Expand Up @@ -93,3 +93,4 @@ export {

export { GnosisIam as SafeIam } from "./GnosisIam";
export * from "./utils/did";
export * from "./staking";
7 changes: 5 additions & 2 deletions src/iam/chainConfig.ts
Expand Up @@ -5,7 +5,8 @@ import {
VOLTA_PUBLIC_RESOLVER_ADDRESS,
VOLTA_RESOLVER_V1_ADDRESS,
VOLTA_IDENTITY_MANAGER_ADDRESS,
VOLTA_CLAIM_MANAGER_ADDRESS
VOLTA_CLAIM_MANAGER_ADDRESS,
VOLTA_STAKING_POOL_FACTORY_ADDRESS
} from "@energyweb/iam-contracts";
import { CacheServerClientOptions } from "../cacheServerClient/cacheServerClient";
import { MessagingMethod } from "../utils/constants";
Expand All @@ -20,6 +21,7 @@ export interface ChainConfig {
assetManagerAddress: string;
didContractAddress: string;
claimManagerAddress: string;
stakingPoolFactoryAddress: string;
}

export interface MessagingOptions {
Expand All @@ -40,7 +42,8 @@ export const chainConfigs: Record<number, ChainConfig> = {
domainNotifierAddress: VOLTA_DOMAIN_NOTIFER_ADDRESS,
assetManagerAddress: VOLTA_IDENTITY_MANAGER_ADDRESS,
didContractAddress: VoltaAddress1056,
claimManagerAddress: VOLTA_CLAIM_MANAGER_ADDRESS
claimManagerAddress: VOLTA_CLAIM_MANAGER_ADDRESS,
stakingPoolFactoryAddress: VOLTA_STAKING_POOL_FACTORY_ADDRESS
}
};

Expand Down
139 changes: 139 additions & 0 deletions src/staking/index.ts
@@ -0,0 +1,139 @@
import { DomainReader, StakingPoolFactory__factory, StakingPool__factory, } from "@energyweb/iam-contracts";
import { StakingPool as StakingPoolContract } from "@energyweb/iam-contracts/dist/ethers-v4/StakingPool";
import { StakingPoolFactory } from "@energyweb/iam-contracts/dist/ethers-v4/StakingPoolFactory";
import { Signer, utils } from "ethers";
import { chainConfigs } from "../iam/chainConfig";

const { namehash } = utils;

export enum StakeStatus { NONSTAKING = 0, STAKING = 1, WITHDRAWING = 2 }

export type Service = {
/** organization ENS name */
org: string;
/** pool address */
pool: string;
/** provider address */
provider: string
}

export type Stake = {
amount: utils.BigNumber;
start: utils.BigNumber;
withdrawalRequested: utils.BigNumber;
status: StakeStatus;
}

export class StakingPoolService {
private constructor(private _stakingPoolFactory: StakingPoolFactory, private _domainReader: DomainReader, private _signer) { }

static async init(signer: Required<Signer>) {
const { chainId } = await signer.provider.getNetwork();
const { stakingPoolFactoryAddress, ensRegistryAddress } = chainConfigs[chainId];
const stakingPoolFactory = new StakingPoolFactory__factory(signer).attach(stakingPoolFactoryAddress);
const domainReader = new DomainReader({ ensRegistryAddress, provider: signer.provider });
return new StakingPoolService(stakingPoolFactory, domainReader, signer);
}

/**
* @description Deployes organization staking pool
* @emits StakingPoolFactory.StakingPoolLaunched
*/
async launchStakingPool(
{ org, minStakingPeriod, patronRewardPortion, patronRoles, principal }:
{
/** organization ENS name */
org: string,
/** minimum staking period in seconds */
minStakingPeriod: number | utils.BigNumber,
/** patron's part of the reward in fractions of thousandth */
patronRewardPortion: number,
/** roles required to stake */
patronRoles: string[],
/** stake put by service provider when pool is launched */
principal: utils.BigNumber
}
): Promise<void> {
(await this._stakingPoolFactory.launchStakingPool(
namehash(org),
minStakingPeriod,
patronRewardPortion,
patronRoles.map((r) => namehash(r))
,
{ value: principal.toHexString() }
)).wait();
}


async allServices(): Promise<Service[]> {
const orgs = await this._stakingPoolFactory.orgsList();
return Promise.all(
orgs.map(
(org) => this._stakingPoolFactory.services(org)
.then((service) => ({ ...service, org }))
.then((service) => this._domainReader.readName(service.org)
.then((org) => ({ ...service, org }))
)));
}

async getPool(org: string): Promise<StakingPool> {
const service = await this._stakingPoolFactory.services(namehash(org));
const pool = new StakingPool__factory(this._signer).attach(service.pool);
return new StakingPool(pool);
}
}

export class StakingPool {
constructor(private pool: StakingPoolContract) { }

/**
* @description Locks stake and starts accumulating reward
* @emits StakingPool.StakePut
*/
async putStake(
/** stake amount */
stake: utils.BigNumber,
): Promise<void> {
(await this.pool.putStake({
value: stake.toHexString()
})).wait();
}

/**
*
*/
async checkReward(): Promise<utils.BigNumber> {
return this.pool.checkReward();
}

/**
*
* @param patron
*/
async getStake(patron?: string): Promise<Stake> {
if (!patron) {
patron = await this.pool.signer.getAddress();
}
return this.pool.stakes(patron);
}

/**
* @description Stops accumulating of the reward and prepars stake to withdraw after withdraw delay.
* Withdraw request unavailable until minimum staking period ends
*/
async requestWithdraw(): Promise<void> {
(await this.pool.requestWithdraw()).wait();
}

/**
* @description pays back stake with accumulated reward. Withdrawn unavailable until withdrawn delay ends
* @emits StakingPool.StakeWithdrawn
*/
async withdraw(): Promise<void> {
(await this.pool.withdraw()).wait();
}

connect(signer: Signer): StakingPool {
return new StakingPool(this.pool.connect(signer));
}
}

0 comments on commit 6d6936f

Please sign in to comment.