Skip to content

Commit

Permalink
feat: add dynamic check to see if an asset type is supported
Browse files Browse the repository at this point in the history
Signed-off-by: Raymond Feng <[email protected]>
  • Loading branch information
raymondfeng committed Nov 3, 2022
1 parent fa0286f commit 15cdbc2
Show file tree
Hide file tree
Showing 5 changed files with 106 additions and 12 deletions.
2 changes: 1 addition & 1 deletion .mocharc.json
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
{
"exit": true,
"recursive": true,
"timeout": 60000
"timeout": 120000
}
12 changes: 12 additions & 0 deletions src/__tests__/acceptance/staking-contracts-service.acceptance.ts
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,18 @@ describe('Staking contracts service', () => {
});
});

it.skip('gets staked token ids by asset type', async () => {
const contracts = service.stakingContracts;
await pMap(contracts, async contract => {
const staked = await service.getStakedTokenIdsByAssetType(
'0x9abbf7218c65c4d22c8483b5d6be93075a3c159c',
1,
contract.supportedAssets[0].asset,
);
expect(staked).to.be.Array();
});
});

it('gets staked token balances', async () => {
const contracts = service.stakingContracts;
await pMap(contracts, async contract => {
Expand Down
10 changes: 8 additions & 2 deletions src/adapters/ririsu.adapter.ts
Original file line number Diff line number Diff line change
Expand Up @@ -40,12 +40,18 @@ export class RirisuStakingContractAdapter extends BaseStakingContractAdapter {
},
];

getStakedTokenIds(owner: string, assetType = 'Ririsu'): Promise<BigNumber[]> {
async getStakedTokenIds(
owner: string,
assetType = 'Ririsu',
): Promise<BigNumber[]> {
const asset = this.getStakingAsset(assetType);
if (asset == null) return [];

const contract = RirisuStaking__factory.connect(
this.contractAddress,
this.provider,
);
if (assetType.toLowerCase() === 'sanctum') {
if (asset.name?.toLowerCase() === 'sanctum') {
return contract.stakedSanctums(owner);
}
return contract.stakedRiris(owner);
Expand Down
58 changes: 56 additions & 2 deletions src/services/staking-contracts.service.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,14 +9,14 @@ import {
AssetType,
AssetTypeParams,
} from '@collabland/chain';
import {debugFactory} from '@collabland/common';
import {debugFactory, pMap} from '@collabland/common';
import {
BindingScope,
ContextTags,
extensions,
injectable,
} from '@loopback/core';
import {utils} from 'ethers';
import {BigNumber, utils} from 'ethers';
import {
STAKING_ADAPTERS_EXTENSION_POINT,
STAKING_CONTRACTS_SERVICE,
Expand Down Expand Up @@ -107,6 +107,60 @@ export class StakingContractsService {
return adapter;
}

private async getAdaptersByAssetType(chainId = 1, assetName: string) {
const adapters = this.adapters.filter(a => a.chainId ?? 1 === chainId);
const list: StackingContractAdapter[] = [];
for (const a of adapters) {
const supported = await a.isAssetSupported(assetName);
if (supported) {
list.push(a);
}
}
return list;
}

/**
* Get staked token ids for the given asset type
* @param owner - Owner address
* @param chainId - Chain id
* @param assetName - Asset name of the original token
* @returns
*/
async getStakedTokenIdsByAssetType(
owner: string,
chainId = 1,
assetName: string,
) {
const adapters = await this.getAdaptersByAssetType(chainId, assetName);
const ids = await pMap(adapters, a => {
return a.getStakedTokenIds(owner, assetName);
});
return ids.flat();
}

/**
* Get staked token balance for the given asset type
* @param owner - Owner address
* @param chainId - Chain id
* @param assetName - Asset name of the original token
* @returns
*/
async getStakedBalanceByAssetType(
owner: string,
chainId = 1,
assetName: string,
) {
const adapters = await this.getAdaptersByAssetType(chainId, assetName);
const balances = await pMap(adapters, a => {
return a.getStakedTokenBalance(owner, assetName);
});
let total = BigNumber.from(0);
for (const bal of balances) {
total = total.add(bal);
}
return total;
}

/**
* Get a list of token ids staked by the owner
* @param owner - Owner's wallet address
Expand Down
36 changes: 29 additions & 7 deletions src/staking.ts
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,12 @@ export interface StackingContractAdapter {
*/
supportedAssets: StakingAsset[];

/**
* Check if the given asset name is supported by this staking contract
* @param asset - Asset name such as `ERC721:0x...`
*/
isAssetSupported(assetName: string): Promise<boolean>;

/**
* Get asset type that can be staked to the contract
* @param assetName - Name of the asset if the staking contract allows multiple
Expand Down Expand Up @@ -78,6 +84,8 @@ const defaultEthersProviderService = {
export abstract class BaseStakingContractAdapter
implements StackingContractAdapter
{
contractName?: string | undefined;

@inject(ETHERS_PROVIDER_SERVICE, {optional: true})
providerService: EthersProviderService = defaultEthersProviderService;

Expand All @@ -94,14 +102,28 @@ export abstract class BaseStakingContractAdapter
return this.provider;
}

async isAssetSupported(assetName: string): Promise<boolean> {
return this.supportedAssets.some(
a => a.asset.toLowerCase() === assetName.toLowerCase(),
);
}

getStakingAsset(nameOrAssetType?: string) {
const assetType = nameOrAssetType?.toLowerCase();
let asset = this.supportedAssets.find(
a =>
a.name?.toLowerCase() === assetType ||
a.asset.toLowerCase() === assetType,
);
if (asset != null) return asset;
// Find the asset that doesn't have a name
asset = this.supportedAssets.find(a => a.name == null);
if (asset != null) return asset;
return this.supportedAssets[0];
}

getStakingAssetType(name?: string) {
let asset = this.supportedAssets.find(a => a.name === name);
if (asset == null) {
asset = this.supportedAssets.find(a => a.name == null);
if (asset == null) {
asset = this.supportedAssets[0];
}
}
const asset = this.getStakingAsset(name);
if (asset == null) return undefined;
return new AssetType({
chainId: {
Expand Down

0 comments on commit 15cdbc2

Please sign in to comment.