@collabland/staking-contracts
Version:
Staking contracts supported by Collab.Land
189 lines • 7.78 kB
JavaScript
// Copyright Abridged, Inc. 2022. All Rights Reserved.
// Node module: @collabland/staking-contracts
// This file is licensed under the MIT License.
// License text available at https://opensource.org/licenses/MIT
import { __decorate, __metadata, __param } from "tslib";
import { asCaipId, AssetName, } from '@collabland/chain';
import { debugFactory, pMap } from '@collabland/common';
import { BindingScope, ContextTags, extensions, injectable, } from '@loopback/core';
import { BigNumber, utils } from 'ethers';
import { STAKING_ADAPTERS_EXTENSION_POINT, STAKING_CONTRACTS_SERVICE, } from '../keys.js';
const debug = debugFactory('collabland:staking-contracts');
let StakingContractsService = class StakingContractsService {
constructor(adapters) {
this.adapters = adapters;
this.stakingContracts = this.getStakingContracts();
}
getStakingContracts() {
return this.adapters.map(a => ({
chainId: a.chainId ?? 1,
contractAddress: utils.getAddress(a.contractAddress),
supportedAssets: a.supportedAssets,
contractName: a.contractName ??
a.constructor.name.replace('StakingContractAdapter', ''),
}));
}
/**
* Check if a given contract address is a supported staking contract
* @param contractAddress - Contract address
* @param chainId - Chain id, default to `1`
* @returns
*/
isStakingContract(contractAddress, chainId = 1) {
contractAddress = utils.getAddress(contractAddress);
return this.adapters.some(a => (a.chainId ?? 1) === chainId &&
utils.getAddress(a.contractAddress) === contractAddress);
}
getStakingAssetTypes(contractAddress, chainId = 1) {
contractAddress = utils.getAddress(contractAddress);
const adapters = this.adapters.filter(a => (a.chainId ?? 1) === chainId &&
utils.getAddress(a.contractAddress) === contractAddress);
if (adapters.length === 0)
return [];
const types = adapters.map(adapter => adapter.supportedAssets.map(a => new AssetName(a.asset).namespace.toUpperCase()));
return Array.from(new Set(types.flat()));
}
/**
* Find staking contracts that support the given asset type to be staked
* @param assetType - CAIP asset type
* @returns
*/
findStakingContractByAssetType(assetType) {
const asset = asCaipId(assetType);
const stakingContracts = this.getStakingContracts();
return stakingContracts.filter(c => {
c.supportedAssets.some(a => a.asset.toString() === asset.toString());
});
}
getAdapter(address, chainId = 1, name) {
address = utils.getAddress(address);
const adapter = this.adapters.find(a => (a.chainId ?? 1 === chainId) &&
utils.getAddress(a.contractAddress) === address);
if (adapter == null)
return adapter;
return adapter;
}
async getAdaptersByAssetType(chainId = 1, assetName) {
const adapters = this.adapters.filter(a => a.chainId ?? 1 === chainId);
const list = [];
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, chainId = 1, assetName) {
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, chainId = 1, assetName) {
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
* @param contractAddress - Contract address of the staking contract
* @param chainId - Chain id, default to `1`
* @param name - Optional name of the asset if the staking contract
* supports multiple assets
* @returns
*/
async getStakedTokenIds(owner, contractAddress, chainId = 1, name) {
const adapter = this.getAdapter(contractAddress, chainId);
if (adapter == null)
return undefined;
try {
const ids = await adapter.getStakedTokenIds(owner, name);
debug('Staked token ids from contract %s for account %s: %O', contractAddress, owner, ids);
return ids;
}
catch (err) {
debug('Fail to get staked token ids from contract %s:%s for account %s', adapter.chainId, contractAddress, owner, err);
throw err;
}
}
/**
* Get the number of token ids staked by the owner
* @param owner - Owner's wallet address
* @param contractAddress - Contract address of the staking contract
* @param chainId - Chain id, default to `1`
* @param name - Optional name of the asset if the staking contract
* supports multiple assets
* @returns
*/
async getStakedTokenBalance(owner, contractAddress, chainId = 1, name) {
const adapter = this.getAdapter(contractAddress, chainId);
if (adapter == null)
return undefined;
try {
const balance = await adapter.getStakedTokenBalance(owner, name);
debug('Staked token balance from contract %s for account %s: %O', contractAddress, owner, balance);
return balance;
}
catch (err) {
debug('Fail to get staked token balance from contract %s:%s for account %s', adapter.chainId, contractAddress, owner, err);
throw err;
}
}
/**
* Get the staking asset type for a given staking contract and asset name
* @param contractAddress - Staking contract address
* @param chainId - Chain id, default to `11
* @param name - Optional name of the asset if the staking contract
* supports multiple assets
* @returns
*/
getStakingAssetType(contractAddress, chainId = 1, name) {
const adapter = this.getAdapter(contractAddress, chainId);
if (adapter == null)
return undefined;
try {
const assetType = adapter.getStakingAssetType(name);
debug('Staking asset types from contract %s: %O', contractAddress, assetType);
return assetType;
}
catch (err) {
debug('Fail to get staking asset types from contract %s:%s', adapter.chainId, contractAddress, err);
throw err;
}
}
};
StakingContractsService = __decorate([
injectable({
scope: BindingScope.SINGLETON,
tags: {
[ContextTags.KEY]: STAKING_CONTRACTS_SERVICE,
},
}),
__param(0, extensions.list(STAKING_ADAPTERS_EXTENSION_POINT)),
__metadata("design:paramtypes", [Array])
], StakingContractsService);
export { StakingContractsService };
//# sourceMappingURL=staking-contracts.service.js.map