UNPKG

@collabland/staking-contracts

Version:
189 lines 7.78 kB
// 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