diff --git a/packages/huma-sdk/API.md b/packages/huma-sdk/API.md
index f07efb6..c9c0573 100644
--- a/packages/huma-sdk/API.md
+++ b/packages/huma-sdk/API.md
@@ -474,6 +474,7 @@ in Huma's pools that can be drawn down by the borrower.
* [.getCreditEventsForUser(userAddress, chainId, poolName, poolType, event)](#SubgraphService.getCreditEventsForUser) ⇒ Promise.<Array.<CreditEventPayload>>
* [.getLastFactorizedAmountFromPool(userAddress, chainId, poolName, poolType)](#SubgraphService.getLastFactorizedAmountFromPool) ⇒ Promise.<number>
* [.getRWReceivableInfo(userAddress, chainId, poolName, poolType, pagination)](#SubgraphService.getRWReceivableInfo) ⇒ Promise.<RealWorldReceivableInfoBase>
+ * [.getPoolStats(chainId, pool)](#SubgraphService.getPoolStats) ⇒ Promise.<{PoolStats}>
@@ -534,6 +535,19 @@ in Huma's pools that can be drawn down by the borrower.
| poolType | POOL\_TYPE
| The type of the pool.
|
| pagination | [Pagination
](#Pagination) | The pagination option.
|
+
+
+### SubgraphService.getPoolStats(chainId, pool) ⇒ Promise.<{PoolStats}>
+Returns the pool's stats.
+
+**Kind**: static method of [SubgraphService
](#SubgraphService)
+**Returns**: Promise.<{PoolStats}>
- The pool's stats info.
+
+| Param | Type | Description |
+| --- | --- | --- |
+| chainId | number
| The ID of the chain.
|
+| pool | string
| The address of the pool.
|
+
## defaultWrapper()
diff --git a/packages/huma-sdk/src/services/SubgraphService.ts b/packages/huma-sdk/src/services/SubgraphService.ts
index 42a52e9..5e3f822 100644
--- a/packages/huma-sdk/src/services/SubgraphService.ts
+++ b/packages/huma-sdk/src/services/SubgraphService.ts
@@ -196,6 +196,56 @@ function getRWReceivableInfo(
})
}
+type PoolStats = {
+ id: string
+ totalPoolAssets: number
+ amountCreditOriginated: number
+ amountCreditRepaid: number
+ amountCreditDefaulted: number
+}
+
+/**
+ * Returns the pool's stats.
+ *
+ * @memberof SubgraphService
+ * @param {number} chainId - The ID of the chain.
+ * @param {string} pool - The address of the pool.
+ * @returns {Promise<{PoolStats}>} The pool's stats info.
+ */
+function getPoolStats(
+ chainId: number,
+ pool: string,
+): Promise {
+ const url = PoolSubgraphMap[chainId]?.subgraph
+ if (!url) {
+ return Promise.resolve(undefined)
+ }
+
+ const PoolStatsQuery = `
+ query {
+ poolStat(id:"${pool?.toLowerCase()}") {
+ id
+ amountCreditOriginated
+ amountCreditRepaid
+ amountCreditDefaulted
+ totalPoolAssets
+ }
+ }`
+
+ return requestPost<{
+ errors?: unknown
+ data: { poolStat: PoolStats }
+ }>(url, JSON.stringify({ query: PoolStatsQuery }), {
+ withCredentials: false,
+ }).then((res) => {
+ if (res.errors) {
+ console.error(res.errors)
+ return undefined
+ }
+ return res.data.poolStat
+ })
+}
+
/**
* An object that contains functions to interact with Huma's Subgraph storage.
* @namespace SubgraphService
@@ -205,4 +255,5 @@ export const SubgraphService = {
getCreditEventsForUser,
getLastFactorizedAmountFromPool,
getRWReceivableInfo,
+ getPoolStats,
}
diff --git a/packages/huma-sdk/tests/services/SubgraphService.test.ts b/packages/huma-sdk/tests/services/SubgraphService.test.ts
index 0341fd5..3e862be 100644
--- a/packages/huma-sdk/tests/services/SubgraphService.test.ts
+++ b/packages/huma-sdk/tests/services/SubgraphService.test.ts
@@ -192,3 +192,47 @@ describe('getRWReceivableInfo', () => {
expect(result).toStrictEqual(rwreceivables)
})
})
+
+describe('getPoolStats', () => {
+ beforeEach(() => {
+ jest.resetAllMocks()
+ })
+
+ it('should return undefined if no subgraph url is found', async () => {
+ const chainId = 12 // ChainId without receivables Subgraph url
+ const pool = '0xc866A11cf6A3D178624Ff46B8A49202206A7c51B'
+
+ const result = await SubgraphService.getPoolStats(chainId, pool)
+ expect(result).toStrictEqual(undefined)
+ })
+
+ it('should return undefined if requestPost returns error', async () => {
+ ;(requestPost as jest.Mock).mockResolvedValue({ errors: 'errors' })
+
+ const chainId = ChainEnum.Goerli
+ const pool = '0xc866A11cf6A3D178624Ff46B8A49202206A7c51B'
+
+ const result = await SubgraphService.getPoolStats(chainId, pool)
+ expect(result).toStrictEqual(undefined)
+ })
+
+ it('should return pool stats', async () => {
+ const pool = '0xc866A11cf6A3D178624Ff46B8A49202206A7c51B'
+ const poolStat = {
+ id: pool,
+ amountCreditOriginated: 300,
+ amountCreditRepaid: 400,
+ amountCreditDefaulted: 500,
+ }
+ ;(requestPost as jest.Mock).mockResolvedValue({
+ data: {
+ poolStat,
+ },
+ })
+
+ const chainId = ChainEnum.Goerli
+
+ const result = await SubgraphService.getPoolStats(chainId, pool)
+ expect(result).toStrictEqual(poolStat)
+ })
+})
diff --git a/packages/huma-shared/src/utils/number.ts b/packages/huma-shared/src/utils/number.ts
index 829a794..f7975da 100644
--- a/packages/huma-shared/src/utils/number.ts
+++ b/packages/huma-shared/src/utils/number.ts
@@ -2,15 +2,12 @@ import { BigNumber, ethers } from 'ethers'
import { isEmpty } from './common'
import { scientificToDecimal } from './scientificToDecimal'
-const moneyFormatter = new Intl.NumberFormat('en-US', {
- style: 'currency',
- currency: 'USD',
- minimumFractionDigits: 0,
-})
-
const numberFormatter = new Intl.NumberFormat('en-US')
-export const formatMoney = (num: number | string | undefined) => {
+export const formatMoney = (
+ num: number | string | undefined,
+ notation?: Intl.NumberFormatOptions['notation'],
+) => {
if (isEmpty(num) || Number.isNaN(num)) {
return num
}
@@ -20,6 +17,14 @@ export const formatMoney = (num: number | string | undefined) => {
if (numCast > 1_000) {
numCast = Math.round(numCast)
}
+
+ const moneyFormatter = new Intl.NumberFormat('en-US', {
+ style: 'currency',
+ currency: 'USD',
+ minimumFractionDigits: 0,
+ notation,
+ })
+
return moneyFormatter.format(numCast)
}
@@ -55,13 +60,15 @@ export const downScale = (
}
export const upScale = (
- num: string | number,
+ num: string | number | BigNumber,
decimals?: number,
): T => {
if (isEmpty(num) || isEmpty(decimals)) {
return num as T
}
- const result = Number(num) * 10 ** decimals!
+ const result = BigNumber.isBigNumber(num)
+ ? num.mul(10 ** decimals!)
+ : Number(num) * 10 ** decimals!
if (typeof num === 'string') {
return String(result) as T
}